Updated to worldwind release 20070817
[worldwind-tracker.git] / gov / nasa / worldwind / formats / rpf / RpfTocCrawler.java
blobbbba63d86f07dcb2b04d56b00eb0658bb6eea8ea
1 /*
2 Copyright (C) 2001, 2006 United States Government as represented by
3 the Administrator of the National Aeronautics and Space Administration.
4 All Rights Reserved.
5 */
6 package gov.nasa.worldwind.formats.rpf;
8 import gov.nasa.worldwind.*;
10 import java.io.*;
11 import java.util.*;
12 import java.util.concurrent.locks.*;
13 import static java.util.logging.Level.*;
15 /**
16 * @author dcollins
17 * @version $Id: RpfTocCrawler.java 1762 2007-05-07 19:43:55Z dcollins $
19 public class RpfTocCrawler
21 public static final String RPF_DIRECTORY = "RPF";
22 public static final String RPF_OVERVIEW_EXTENSION = ".OVR";
23 public static final String RPF_TOC_EXTENSION = ".TOC";
25 public static interface RpfTocCrawlerListener
27 void fileFound(File tocFile);
29 void finished();
32 public abstract static class RpfTocGrouper implements RpfTocCrawlerListener
34 private final RpfFramePropertyType groupType;
36 public RpfTocGrouper(RpfFramePropertyType groupType)
38 if (groupType == null)
40 String message = WorldWind.retrieveErrMsg("nullValue.RpfFramePropertyTypeIsNull");
41 WorldWind.logger().log(FINE, message);
42 throw new IllegalArgumentException(message);
44 this.groupType = groupType;
47 public void fileFound(File tocFile)
49 RpfTocFile rpfTocFile = null;
50 try
52 rpfTocFile = RpfTocFile.load(tocFile);
54 catch (IOException e)
56 WorldWind.logger().log(FINE, e.getMessage());
59 if (rpfTocFile == null)
60 return;
62 String firstFrameFilename = findFirstRpfFrameFilename(rpfTocFile);
63 if (firstFrameFilename == null)
64 return;
66 RpfFrameProperties firstFrameProperties = null;
67 try
69 firstFrameProperties = RpfFrameFilenameUtil.parseFilename(firstFrameFilename);
71 catch (Exception e)
73 String message = WorldWind.retrieveErrMsg("RpfTocCrawler.ExceptionParsingFilename");
74 WorldWind.logger().log(FINE, message, e);
77 if (firstFrameProperties != null)
78 this.addToGroup(this.groupType.getInstance(firstFrameProperties), rpfTocFile);
81 public void finished()
85 public abstract void addToGroup(Object groupKey, RpfTocFile rpfTocFile);
88 private static class RpfTocRunner implements Runnable
90 private final RpfTocCrawler context;
91 private final File directory;
92 private final RpfTocCrawlerListener listener;
94 public RpfTocRunner(RpfTocCrawler context, File directory, RpfTocCrawlerListener listener)
96 this.context = context;
97 this.directory = directory;
98 this.listener = listener;
101 public void run()
103 this.context.process(this.directory, listener, true);
104 this.context.threadLock.lock();
107 if (this.context.thread != this.context.deadThread)
109 listener.finished();
110 this.context.thread = this.context.deadThread;
113 finally
115 this.context.threadLock.unlock();
120 private final Thread deadThread = new Thread();
121 private final Lock threadLock = new ReentrantLock();
122 private volatile Thread thread = null;
124 public RpfTocCrawler()
128 public static String findFirstRpfFrameFilename(RpfTocFile tocFile)
130 if (tocFile != null
131 && tocFile.getFrameFileIndexSection() != null
132 && tocFile.getFrameFileIndexSection().getFrameFileIndexTable() != null
133 && tocFile.getFrameFileIndexSection().getFrameFileIndexTable().size() > 0)
135 for (RpfFrameFileIndexSection.RpfFrameFileIndexRecord frameFileIndexRecord
136 : tocFile.getFrameFileIndexSection().getFrameFileIndexTable())
138 if (frameFileIndexRecord != null
139 && frameFileIndexRecord.getFrameFileName() != null
140 && !frameFileIndexRecord.getFrameFileName().toUpperCase().endsWith(RPF_OVERVIEW_EXTENSION))
142 return frameFileIndexRecord.getFrameFileName();
146 return null;
149 private void process(File file, RpfTocCrawlerListener listener, boolean inOwnThread)
151 this.threadLock.lock();
154 if (inOwnThread && this.thread == deadThread)
155 return;
157 finally
159 this.threadLock.unlock();
162 File[] children = file.listFiles();
163 if (children == null)
164 return;
165 if (RPF_DIRECTORY.compareToIgnoreCase(file.getName()) == 0)
166 this.processRpfDirectory(children, listener, inOwnThread);
167 else
168 this.processUnknownDirectory(children, listener, inOwnThread);
171 private void processRpfDirectory(File[] contents, RpfTocCrawlerListener listener, boolean inOwnThread)
173 for (File file : contents)
175 this.threadLock.lock();
178 if (inOwnThread && this.thread == deadThread)
179 return;
181 finally
183 this.threadLock.unlock();
186 if (file.getName().toUpperCase().endsWith(RPF_TOC_EXTENSION))
187 listener.fileFound(file);
191 private void processUnknownDirectory(File[] contents, RpfTocCrawlerListener listener, boolean inOwnThread)
193 for (File file : contents)
195 this.threadLock.lock();
198 if (inOwnThread && this.thread == deadThread)
199 return;
201 finally
203 this.threadLock.unlock();
206 if (file.isDirectory())
207 this.process(file, listener, inOwnThread);
211 public File[] invoke(File directory)
213 File validDir = this.validateDirectory(directory);
214 final Collection<File> results = new ArrayList<File>();
215 this.process(validDir, new RpfTocCrawlerListener()
217 public void fileFound(File file)
219 if (file.exists())
220 results.add(file);
223 public void finished()
226 }, false);
227 File[] tocFileArray = new File[results.size()];
228 results.toArray(tocFileArray);
229 return tocFileArray;
232 public void invoke(File directory, RpfTocCrawlerListener listener)
234 File validDir = this.validateDirectory(directory);
235 this.process(validDir, listener, false);
238 public void start(File directory, RpfTocCrawlerListener listener)
240 this.threadLock.lock();
243 if (this.thread != null || this.thread == deadThread)
245 String message = WorldWind.retrieveErrMsg("RpfTocCrawler.BadStart");
246 WorldWind.logger().log(FINE, message);
247 throw new IllegalStateException(message);
249 File validDir = this.validateDirectory(directory);
250 this.thread = new Thread(new RpfTocRunner(this, validDir, listener));
251 this.thread.start();
253 finally
255 this.threadLock.unlock();
259 public void stop()
261 this.threadLock.lock();
264 this.thread = deadThread;
266 finally
268 this.threadLock.unlock();
272 private File validateDirectory(File directory)
274 if (directory == null)
276 String message = WorldWind.retrieveErrMsg("nullValue.FileIsNull");
277 WorldWind.logger().log(FINE, message);
278 throw new IllegalArgumentException(message);
280 String path = directory.getAbsolutePath();
281 if (!path.endsWith("/") && !path.endsWith("\\"))
283 path = path + File.separatorChar;
284 directory = new File(path);
286 if (!directory.exists())
288 String message = WorldWind.retrieveErrMsg("generic.fileNotFound");
289 WorldWind.logger().log(FINE, message);
290 throw new IllegalArgumentException(message);
292 return directory;