Changeset 33613 in osm for applications/editors
- Timestamp:
- 2017-09-16T01:37:46+02:00 (7 years ago)
- Location:
- applications/editors/josm/plugins/opendata
- Files:
-
- 4 added
- 1 deleted
- 3 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/OdPlugin.java
r33518 r33613 63 63 instance = this; 64 64 } else { 65 throw new Illegal AccessError("Cannot instantiate plugin twice !");65 throw new IllegalStateException("Cannot instantiate plugin twice !"); 66 66 } 67 67 // Allow JOSM to import more files -
applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/MifTabImporter.java
r32545 r33613 33 33 return TabReader.parseDataSet(in, file, handler, instance); 34 34 } 35 } catch (IOException e) {35 } catch (IOException | IllegalArgumentException e) { 36 36 throw new IllegalDataException(e); 37 37 } -
applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/TabFiles.java
r33609 r33613 1 // JOSM opendata plugin. 2 // Copyright (C) 2011-2012 Don-vip 3 // 4 // This program is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // This program is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with this program. If not, see <http://www.gnu.org/licenses/>. 16 package org.geotools.data.shapefile.files; 1 // License: GPL. For details, see LICENSE file. 2 package org.openstreetmap.josm.plugins.opendata.core.io.geographic; 17 3 18 4 import static org.geotools.data.shapefile.files.ShpFileType.SHP; 19 5 20 6 import java.io.File; 21 import java.io.FileOutputStream;22 7 import java.io.FilenameFilter; 23 import java.io.FilterInputStream; 24 import java.io.FilterOutputStream; 25 import java.io.IOException; 26 import java.io.InputStream; 27 import java.io.OutputStream; 28 import java.io.RandomAccessFile; 8 import java.lang.reflect.Field; 29 9 import java.net.MalformedURLException; 30 10 import java.net.URL; 31 import java.net.URLConnection;32 import java.nio.MappedByteBuffer;33 import java.nio.channels.Channels;34 import java.nio.channels.FileChannel;35 import java.nio.channels.FileChannel.MapMode;36 import java.nio.channels.ReadableByteChannel;37 import java.nio.channels.WritableByteChannel;38 import java.util.ArrayList;39 import java.util.Collection;40 11 import java.util.HashMap; 41 12 import java.util.Map; 42 13 import java.util.Map.Entry; 43 14 import java.util.Set; 44 import java.util.concurrent.ConcurrentHashMap;45 import java.util.concurrent.locks.ReentrantReadWriteLock;46 import java.util.logging.Level;47 15 48 16 import org.geotools.data.DataUtilities; 17 import org.geotools.data.shapefile.files.ShpFileType; 18 import org.geotools.data.shapefile.files.ShpFiles; 19 import org.openstreetmap.josm.tools.JosmRuntimeException; 49 20 import org.openstreetmap.josm.tools.Logging; 21 import org.openstreetmap.josm.tools.Utils; 50 22 51 23 /** 52 * Ugly copy of ShpFilesclass modified to fit MapInfo TAB needs.24 * Extension of {@link ShpFiles} class modified to fit MapInfo TAB needs. 53 25 */ 54 26 public class TabFiles extends ShpFiles { … … 58 30 * key is the type of file 59 31 */ 60 private final Map<ShpFileType, URL> urls = new ConcurrentHashMap<>(); 61 62 /** 63 * A read/write lock, so that we can have concurrent readers 64 */ 65 private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(); 66 67 /** 68 * The set of locker sources per thread. Used as a debugging aid and to upgrade/downgrade 69 * the locks 70 */ 71 private final Map<Thread, Collection<ShpFilesLocker>> lockers = new ConcurrentHashMap<>(); 72 73 /** 74 * A cache for read only memory mapped buffers 75 */ 76 private final MemoryMapCache mapCache = new MemoryMapCache(); 77 78 private boolean memoryMapCacheEnabled; 79 32 private final Map<ShpFileType, URL> urls; 80 33 81 34 //////////////////////////////////////////////////// 82 35 36 @SuppressWarnings("unchecked") 83 37 public TabFiles(File headerFile, File dataFile) throws IllegalArgumentException { 84 38 super(fakeShpFile(headerFile)); // Useless but necessary 39 40 try { 41 Field furls = ShpFiles.class.getDeclaredField("urls"); 42 Utils.setObjectsAccessible(furls); 43 urls = (Map<ShpFileType, URL>) furls.get(this); 44 } catch (ReflectiveOperationException e) { 45 throw new JosmRuntimeException(e); 46 } 47 85 48 init(DataUtilities.fileToURL(headerFile)); 86 49 urls.put(ShpFileType.DBF, DataUtilities.fileToURL(dataFile)); … … 88 51 89 52 /** 90 * This is really ugly.Used only to give a fake shp file to ShpFiles constructor to avoid IllegalArgument at initialization.53 * Used only to give a fake shp file to ShpFiles constructor to avoid IllegalArgument at initialization. 91 54 */ 92 55 private static URL fakeShpFile(File headerFile) { … … 143 106 // different cases that the extension can be made up of. 144 107 // IE Shp, SHP, Shp, ShP etc... 145 if (isLocal Tab()) {108 if (isLocal()) { 146 109 Set<Entry<ShpFileType, URL>> entries = urls.entrySet(); 147 110 Map<ShpFileType, URL> toUpdate = new HashMap<>(); 148 111 for (Entry<ShpFileType, URL> entry : entries) { 149 if ( !existsTab(entry.getKey()) ){112 if (!exists(entry.getKey())) { 150 113 url = findExistingFile(entry.getKey(), entry.getValue()); 151 if ( url!=null ){114 if (url != null) { 152 115 toUpdate.put(entry.getKey(), url); 153 116 } … … 161 124 final File file = DataUtilities.urlToFile(value); 162 125 File directory = file.getParentFile(); 163 if( directory==null || !directory.exists() ) { 164 // doesn't exist 165 return null; 166 } 167 File[] files = directory.listFiles(new FilenameFilter(){ 168 169 @Override 170 public boolean accept(File dir, String name) { 171 return file.getName().equalsIgnoreCase(name); 172 } 173 174 }); 175 if( files.length>0 ){ 176 try { 177 return files[0].toURI().toURL(); 178 } catch (MalformedURLException e) { 179 Logging.error(e); 126 if (directory != null && directory.exists()) { 127 File[] files = directory.listFiles((FilenameFilter) (dir, name) -> file.getName().equalsIgnoreCase(name)); 128 if (files.length > 0) { 129 try { 130 return files[0].toURI().toURL(); 131 } catch (MalformedURLException e) { 132 Logging.error(e); 133 } 180 134 } 181 135 } … … 193 147 194 148 @Override 195 public void dispose() {196 if (numberOfLocks() != 0) {197 logCurrentLockers(Level.SEVERE);198 lockers.clear(); // so as not to get this log again.199 }200 mapCache.clean();201 }202 203 /**204 * Writes to the log all the lockers and when they were constructed.205 *206 * @param logLevel207 * the level at which to log.208 */209 @Override210 public void logCurrentLockers(Level logLevel) {211 for (Collection<ShpFilesLocker> lockerList : lockers.values()) {212 for (ShpFilesLocker locker : lockerList) {213 StringBuilder sb = new StringBuilder("The following locker still has a lock: ");214 sb.append(locker);215 Logging.error(sb.toString());216 }217 }218 }219 220 /**221 * Returns the URLs (in string form) of all the files for the shapefile222 * datastore.223 *224 * @return the URLs (in string form) of all the files for the shapefile225 * datastore.226 */227 @Override228 public Map<ShpFileType, String> getFileNames() {229 Map<ShpFileType, String> result = new HashMap<>();230 Set<Entry<ShpFileType, URL>> entries = urls.entrySet();231 232 for (Entry<ShpFileType, URL> entry : entries) {233 result.put(entry.getKey(), entry.getValue().toExternalForm());234 }235 236 return result;237 }238 239 /**240 * Returns the string form of the url that identifies the file indicated by241 * the type parameter or null if it is known that the file does not exist.242 *243 * <p>244 * Note: a URL should NOT be constructed from the string instead the URL245 * should be obtained through calling one of the aquireLock methods.246 *247 * @param type248 * indicates the type of file the caller is interested in.249 *250 * @return the string form of the url that identifies the file indicated by251 * the type parameter or null if it is known that the file does not252 * exist.253 */254 @Override255 public String get(ShpFileType type) {256 return urls.get(type).toExternalForm();257 }258 259 /**260 * Returns the number of locks on the current set of shapefile files. This261 * is not thread safe so do not count on it to have a completely accurate262 * picture but it can be useful debugging263 *264 * @return the number of locks on the current set of shapefile files.265 */266 @Override267 public int numberOfLocks() {268 int count = 0;269 for (Collection<ShpFilesLocker> lockerList : lockers.values()) {270 count += lockerList.size();271 }272 return count;273 }274 /**275 * Acquire a File for read only purposes. It is recommended that get*Stream or276 * get*Channel methods are used when reading or writing to the file is277 * desired.278 *279 *280 * @see #getInputStream(ShpFileType, FileReader)281 * @see #getReadChannel(ShpFileType, FileReader)282 * @see #getWriteChannel(ShpFileType, FileReader)283 *284 * @param type285 * the type of the file desired.286 * @param requestor287 * the object that is requesting the File. The same object288 * must release the lock and is also used for debugging.289 * @return the File type requested290 */291 @Override292 public File acquireReadFile(ShpFileType type,293 FileReader requestor) {294 if(!isLocalTab() ){295 throw new IllegalStateException("This method only applies if the files are local");296 }297 URL url = acquireRead(type, requestor);298 return DataUtilities.urlToFile(url);299 }300 301 /**302 * Acquire a URL for read only purposes. It is recommended that get*Stream or303 * get*Channel methods are used when reading or writing to the file is304 * desired.305 *306 *307 * @see #getInputStream(ShpFileType, FileReader)308 * @see #getReadChannel(ShpFileType, FileReader)309 * @see #getWriteChannel(ShpFileType, FileReader)310 *311 * @param type312 * the type of the file desired.313 * @param requestor314 * the object that is requesting the URL. The same object315 * must release the lock and is also used for debugging.316 * @return the URL to the file of the type requested317 */318 @Override319 public URL acquireRead(ShpFileType type, FileReader requestor) {320 URL url = urls.get(type);321 if (url == null)322 return null;323 324 readWriteLock.readLock().lock();325 Collection<ShpFilesLocker> threadLockers = getCurrentThreadLockers();326 threadLockers.add(new ShpFilesLocker(url, requestor));327 return url;328 }329 330 /**331 * Tries to acquire a URL for read only purposes. Returns null if the332 * acquire failed or if the file does not.333 * <p> It is recommended that get*Stream or334 * get*Channel methods are used when reading or writing to the file is335 * desired.336 * </p>337 *338 * @see #getInputStream(ShpFileType, FileReader)339 * @see #getReadChannel(ShpFileType, FileReader)340 * @see #getWriteChannel(ShpFileType, FileReader)341 *342 * @param type343 * the type of the file desired.344 * @param requestor345 * the object that is requesting the URL. The same object346 * must release the lock and is also used for debugging.347 * @return A result object containing the URL or the reason for the failure.348 */349 @Override350 public Result<URL, State> tryAcquireRead(ShpFileType type,351 FileReader requestor) {352 URL url = urls.get(type);353 if (url == null) {354 return new Result<>(null, State.NOT_EXIST);355 }356 357 boolean locked = readWriteLock.readLock().tryLock();358 if (!locked) {359 return new Result<>(null, State.LOCKED);360 }361 362 getCurrentThreadLockers().add(new ShpFilesLocker(url, requestor));363 364 return new Result<>(url, State.GOOD);365 }366 367 /**368 * Unlocks a read lock. The file and requestor must be the the same as the369 * one of the lockers.370 *371 * @param file372 * file that was locked373 * @param requestor374 * the class that requested the file375 */376 @Override377 public void unlockRead(File file, FileReader requestor) {378 Collection<URL> allURLS = urls.values();379 for (URL url : allURLS) {380 if (DataUtilities.urlToFile(url).equals(file)) {381 unlockRead(url, requestor);382 }383 }384 }385 386 /**387 * Unlocks a read lock. The url and requestor must be the the same as the388 * one of the lockers.389 *390 * @param url391 * url that was locked392 * @param requestor393 * the class that requested the url394 */395 @Override396 public void unlockRead(URL url, FileReader requestor) {397 if (url == null) {398 throw new NullPointerException("url cannot be null");399 }400 if (requestor == null) {401 throw new NullPointerException("requestor cannot be null");402 }403 404 Collection<ShpFilesLocker> threadLockers = getCurrentThreadLockers();405 boolean removed = threadLockers.remove(new ShpFilesLocker(url, requestor));406 if (!removed) {407 throw new IllegalArgumentException(408 "Expected requestor "409 + requestor410 + " to have locked the url but it does not hold the lock for the URL");411 }412 if(threadLockers.size() == 0)413 lockers.remove(Thread.currentThread());414 readWriteLock.readLock().unlock();415 }416 417 /**418 * Acquire a File for read and write purposes.419 * <p> It is recommended that get*Stream or420 * get*Channel methods are used when reading or writing to the file is421 * desired.422 * </p>423 *424 * @see #getInputStream(ShpFileType, FileReader)425 * @see #getReadChannel(ShpFileType, FileReader)426 * @see #getWriteChannel(ShpFileType, FileReader)427 428 *429 * @param type430 * the type of the file desired.431 * @param requestor432 * the object that is requesting the File. The same object433 * must release the lock and is also used for debugging.434 * @return the File to the file of the type requested435 */436 @Override437 public File acquireWriteFile(ShpFileType type,438 FileWriter requestor) {439 if(!isLocalTab() ){440 throw new IllegalStateException("This method only applies if the files are local");441 }442 URL url = acquireWrite(type, requestor);443 return DataUtilities.urlToFile(url);444 }445 /**446 * Acquire a URL for read and write purposes.447 * <p> It is recommended that get*Stream or448 * get*Channel methods are used when reading or writing to the file is449 * desired.450 * </p>451 *452 * @see #getInputStream(ShpFileType, FileReader)453 * @see #getReadChannel(ShpFileType, FileReader)454 * @see #getWriteChannel(ShpFileType, FileReader)455 456 *457 * @param type458 * the type of the file desired.459 * @param requestor460 * the object that is requesting the URL. The same object461 * must release the lock and is also used for debugging.462 * @return the URL to the file of the type requested463 */464 @Override465 public URL acquireWrite(ShpFileType type, FileWriter requestor) {466 URL url = urls.get(type);467 if (url == null) {468 return null;469 }470 471 // we need to give up all read locks before getting the write one472 Collection<ShpFilesLocker> threadLockers = getCurrentThreadLockers();473 relinquishReadLocks(threadLockers);474 readWriteLock.writeLock().lock();475 threadLockers.add(new ShpFilesLocker(url, requestor));476 mapCache.cleanFileCache(url);477 return url;478 }479 480 /**481 * Tries to acquire a URL for read/write purposes. Returns null if the482 * acquire failed or if the file does not exist483 * <p> It is recommended that get*Stream or484 * get*Channel methods are used when reading or writing to the file is485 * desired.486 * </p>487 *488 * @see #getInputStream(ShpFileType, FileReader)489 * @see #getReadChannel(ShpFileType, FileReader)490 * @see #getWriteChannel(ShpFileType, FileReader)491 492 *493 * @param type494 * the type of the file desired.495 * @param requestor496 * the object that is requesting the URL. The same object497 * must release the lock and is also used for debugging.498 * @return A result object containing the URL or the reason for the failure.499 */500 @Override501 public Result<URL, State> tryAcquireWrite(ShpFileType type,502 FileWriter requestor) {503 504 URL url = urls.get(type);505 if (url == null) {506 return new Result<>(null, State.NOT_EXIST);507 }508 509 Collection<ShpFilesLocker> threadLockers = getCurrentThreadLockers();510 boolean locked = readWriteLock.writeLock().tryLock();511 if (!locked && threadLockers.size() > 1) {512 // hum, it may be be because we are holding a read lock513 relinquishReadLocks(threadLockers);514 locked = readWriteLock.writeLock().tryLock();515 if(locked == false) {516 regainReadLocks(threadLockers);517 return new Result<>(null, State.LOCKED);518 }519 }520 521 threadLockers.add(new ShpFilesLocker(url, requestor));522 return new Result<>(url, State.GOOD);523 }524 525 /**526 * Unlocks a read lock. The file and requestor must be the the same as the527 * one of the lockers.528 *529 * @param file530 * file that was locked531 * @param requestor532 * the class that requested the file533 */534 @Override535 public void unlockWrite(File file, FileWriter requestor) {536 Collection<URL> allURLS = urls.values();537 for (URL url : allURLS) {538 if (DataUtilities.urlToFile(url).equals(file)) {539 unlockWrite(url, requestor);540 }541 }542 }543 544 /**545 * Unlocks a read lock. The requestor must be have previously obtained a546 * lock for the url.547 *548 *549 * @param url550 * url that was locked551 * @param requestor552 * the class that requested the url553 */554 @Override555 public void unlockWrite(URL url, FileWriter requestor) {556 if (url == null) {557 throw new NullPointerException("url cannot be null");558 }559 if (requestor == null) {560 throw new NullPointerException("requestor cannot be null");561 }562 Collection<ShpFilesLocker> threadLockers = getCurrentThreadLockers();563 boolean removed = threadLockers.remove(new ShpFilesLocker(url, requestor));564 if (!removed) {565 throw new IllegalArgumentException(566 "Expected requestor "567 + requestor568 + " to have locked the url but it does not hold the lock for the URL");569 }570 571 if(threadLockers.size() == 0) {572 lockers.remove(Thread.currentThread());573 } else {574 // get back read locks before giving up the write one575 regainReadLocks(threadLockers);576 }577 readWriteLock.writeLock().unlock();578 }579 580 /**581 * Returns the list of lockers attached to a given thread, or creates it if missing582 * @return583 */584 private Collection<ShpFilesLocker> getCurrentThreadLockers() {585 Collection<ShpFilesLocker> threadLockers = lockers.get(Thread.currentThread());586 if(threadLockers == null) {587 threadLockers = new ArrayList<>();588 lockers.put(Thread.currentThread(), threadLockers);589 }590 return threadLockers;591 }592 593 /**594 * Gives up all read locks in preparation for lock upgade595 * @param threadLockers596 */597 private void relinquishReadLocks(Collection<ShpFilesLocker> threadLockers) {598 for (ShpFilesLocker shpFilesLocker : threadLockers) {599 if(shpFilesLocker.reader != null && !shpFilesLocker.upgraded) {600 readWriteLock.readLock().unlock();601 shpFilesLocker.upgraded = true;602 }603 }604 }605 606 /**607 * Re-takes the read locks in preparation for lock downgrade608 * @param threadLockers609 */610 private void regainReadLocks(Collection<ShpFilesLocker> threadLockers) {611 for (ShpFilesLocker shpFilesLocker : threadLockers) {612 if(shpFilesLocker.reader != null && shpFilesLocker.upgraded) {613 readWriteLock.readLock().lock();614 shpFilesLocker.upgraded = false;615 }616 }617 }618 619 /**620 * Determine if the location of this shapefile is local or remote.621 *622 * @return true if local, false if remote623 */624 public boolean isLocalTab() {625 return urls.get(ShpFileType.SHP).toExternalForm().toLowerCase().startsWith("file:");626 }627 628 /**629 * Delete all the shapefile files. If the files are not local or the one630 * files cannot be deleted return false.631 */632 @Override633 public boolean delete() {634 BasicShpFileWriter requestor = new BasicShpFileWriter("ShpFiles for deleting all files");635 URL writeLockURL = acquireWrite(SHP, requestor);636 boolean retVal = true;637 try {638 if (isLocalTab()) {639 Collection<URL> values = urls.values();640 for (URL url : values) {641 File f = DataUtilities.urlToFile(url);642 if (!f.delete()) {643 retVal = false;644 }645 }646 } else {647 retVal = false;648 }649 } finally {650 unlockWrite(writeLockURL, requestor);651 }652 return retVal;653 }654 655 /**656 * Opens a input stream for the indicated file. A read lock is requested at657 * the method call and released on close.658 *659 * @param type660 * the type of file to open the stream to.661 * @param requestor662 * the object requesting the stream663 * @return an input stream664 *665 * @throws IOException666 * if a problem occurred opening the stream.667 */668 @Override669 public InputStream getInputStream(ShpFileType type,670 final FileReader requestor) throws IOException {671 final URL url = acquireRead(type, requestor);672 673 try {674 FilterInputStream input = new FilterInputStream(url.openStream()) {675 676 private volatile boolean closed = false;677 678 @Override679 public void close() throws IOException {680 try {681 super.close();682 } finally {683 if (!closed) {684 closed = true;685 unlockRead(url, requestor);686 }687 }688 }689 690 };691 return input;692 } catch (Throwable e) {693 unlockRead(url, requestor);694 if (e instanceof IOException) {695 throw (IOException) e;696 } else if( e instanceof RuntimeException) {697 throw (RuntimeException) e;698 } else if( e instanceof Error ) {699 throw (Error) e;700 } else {701 throw new RuntimeException(e);702 }703 }704 }705 706 /**707 * Opens a output stream for the indicated file. A write lock is requested at708 * the method call and released on close.709 *710 * @param type711 * the type of file to open the stream to.712 * @param requestor713 * the object requesting the stream714 * @return an output stream715 *716 * @throws IOException717 * if a problem occurred opening the stream.718 */719 @SuppressWarnings("resource")720 @Override721 public OutputStream getOutputStream(ShpFileType type,722 final FileWriter requestor) throws IOException {723 final URL url = acquireWrite(type, requestor);724 725 try {726 727 OutputStream out;728 if (isLocalTab()) {729 File file = DataUtilities.urlToFile(url);730 out = new FileOutputStream(file);731 } else {732 URLConnection connection = url.openConnection();733 connection.setDoOutput(true);734 out = connection.getOutputStream();735 }736 737 FilterOutputStream output = new FilterOutputStream(out) {738 739 private volatile boolean closed = false;740 741 @Override742 public void close() throws IOException {743 try {744 super.close();745 } finally {746 if (!closed) {747 closed = true;748 unlockWrite(url, requestor);749 }750 }751 }752 753 };754 755 return output;756 } catch (Throwable e) {757 unlockWrite(url, requestor);758 if (e instanceof IOException) {759 throw (IOException) e;760 } else if (e instanceof RuntimeException) {761 throw (RuntimeException) e;762 } else if (e instanceof Error) {763 throw (Error) e;764 } else {765 throw new RuntimeException(e);766 }767 }768 }769 770 /**771 * Obtain a ReadableByteChannel from the given URL. If the url protocol is772 * file, a FileChannel will be returned. Otherwise a generic channel will be773 * obtained from the urls input stream.774 * <p>775 * A read lock is obtained when this method is called and released when the776 * channel is closed.777 * </p>778 *779 * @param type780 * the type of file to open the channel to.781 * @param requestor782 * the object requesting the channel783 *784 */785 @Override786 public ReadableByteChannel getReadChannel(ShpFileType type,787 FileReader requestor) throws IOException {788 URL url = acquireRead(type, requestor);789 ReadableByteChannel channel = null;790 try {791 if (isLocalTab()) {792 793 File file = DataUtilities.urlToFile(url);794 795 @SuppressWarnings("resource")796 RandomAccessFile raf = new RandomAccessFile(file, "r");797 channel = new FileChannelDecorator(raf.getChannel(), this, url,798 requestor);799 800 } else {801 InputStream in = url.openConnection().getInputStream();802 channel = new ReadableByteChannelDecorator(Channels803 .newChannel(in), this, url, requestor);804 }805 } catch (Throwable e) {806 unlockRead(url, requestor);807 if (e instanceof IOException) {808 throw (IOException) e;809 } else if (e instanceof RuntimeException) {810 throw (RuntimeException) e;811 } else if (e instanceof Error) {812 throw (Error) e;813 } else {814 throw new RuntimeException(e);815 }816 }817 return channel;818 }819 820 /**821 * Obtain a WritableByteChannel from the given URL. If the url protocol is822 * file, a FileChannel will be returned. Currently, this method will return823 * a generic channel for remote urls, however both shape and dbf writing can824 * only occur with a local FileChannel channel.825 *826 * <p>827 * A write lock is obtained when this method is called and released when the828 * channel is closed.829 * </p>830 *831 *832 * @param type833 * the type of file to open the stream to.834 * @param requestor835 * the object requesting the stream836 *837 * @return a WritableByteChannel for the provided file type838 *839 * @throws IOException840 * if there is an error opening the stream841 */842 @Override843 public WritableByteChannel getWriteChannel(ShpFileType type,844 FileWriter requestor) throws IOException {845 846 URL url = acquireWrite(type, requestor);847 848 try {849 WritableByteChannel channel;850 if (isLocalTab()) {851 852 File file = DataUtilities.urlToFile(url);853 854 @SuppressWarnings("resource")855 RandomAccessFile raf = new RandomAccessFile(file, "rw");856 channel = new FileChannelDecorator(raf.getChannel(), this, url,857 requestor);858 859 ((FileChannel) channel).lock();860 861 } else {862 OutputStream out = url.openConnection().getOutputStream();863 channel = new WritableByteChannelDecorator(Channels864 .newChannel(out), this, url, requestor);865 }866 867 return channel;868 } catch (Throwable e) {869 unlockWrite(url, requestor);870 if (e instanceof IOException) {871 throw (IOException) e;872 } else if (e instanceof RuntimeException) {873 throw (RuntimeException) e;874 } else if (e instanceof Error) {875 throw (Error) e;876 } else {877 throw new RuntimeException(e);878 }879 }880 }881 882 /**883 * Obtains a Storage file for the type indicated. An id is provided so that884 * the same file can be obtained at a later time with just the id885 *886 * @param type887 * the type of file to create and return888 *889 * @return StorageFile890 * @throws IOException891 * if temporary files cannot be created892 */893 @Override894 public StorageFile getStorageFile(ShpFileType type) throws IOException {895 String baseName = getTypeName();896 if (baseName.length() < 3) { // min prefix length for createTempFile897 baseName = baseName + "___".substring(0, 3 - baseName.length());898 }899 File tmp = File.createTempFile(baseName, type.extensionWithPeriod);900 return new StorageFile(this, tmp, type);901 }902 903 @Override904 149 public String getTypeName() { 905 150 String path = SHP.toBase(urls.get(SHP)); … … 913 158 return path.substring(slash, dot); 914 159 } 915 916 /**917 * Internal method that the file channel decorators will call to allow reuse of the memory mapped buffers918 * @param wrapped919 * @param url920 * @param mode921 * @param position922 * @param size923 * @return924 * @throws IOException925 */926 @Override927 MappedByteBuffer map(FileChannel wrapped, URL url, MapMode mode, long position, long size) throws IOException {928 if(memoryMapCacheEnabled) {929 return mapCache.map(wrapped, url, mode, position, size);930 } else {931 return wrapped.map(mode, position, size);932 }933 }934 935 /**936 * Returns the status of the memory map cache. When enabled the memory mapped portions of the files are cached and shared937 * (giving each thread a clone of it)938 * @param memoryMapCacheEnabled939 */940 @Override941 public boolean isMemoryMapCacheEnabled() {942 return memoryMapCacheEnabled;943 }944 945 /**946 * Enables the memory map cache. When enabled the memory mapped portions of the files are cached and shared947 * (giving each thread a clone of it)948 * @param memoryMapCacheEnabled949 */950 @Override951 public void setMemoryMapCacheEnabled(boolean memoryMapCacheEnabled) {952 this.memoryMapCacheEnabled = memoryMapCacheEnabled;953 if (!memoryMapCacheEnabled) {954 mapCache.clean();955 }956 }957 958 /**959 * Returns true if the file exists. Throws an exception if the file is not960 * local.961 *962 * @param fileType963 * the type of file to check existance for.964 *965 * @return true if the file exists.966 *967 * @throws IllegalArgumentException968 * if the files are not local.969 */970 public boolean existsTab(ShpFileType fileType) throws IllegalArgumentException {971 if (!isLocalTab()) {972 throw new IllegalArgumentException(973 "This method only makes sense if the files are local");974 }975 URL url = urls.get(fileType);976 if (url == null) {977 return false;978 }979 980 File file = DataUtilities.urlToFile(url);981 return file.exists();982 }983 160 } -
applications/editors/josm/plugins/opendata/src/org/openstreetmap/josm/plugins/opendata/core/io/geographic/TabReader.java
r33518 r33613 15 15 import org.geotools.data.shapefile.dbf.DbaseFileReader; 16 16 import org.geotools.data.shapefile.dbf.DbaseFileReader.Row; 17 import org.geotools.data.shapefile.files.TabFiles;18 17 import org.openstreetmap.josm.data.osm.DataSet; 19 18 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
Note:
See TracChangeset
for help on using the changeset viewer.