2 Copyright (C) 2001, 2006 United States Government as represented by
3 the Administrator of the National Aeronautics and Space Administration.
6 package gov
.nasa
.worldwind
.formats
.rpf
;
8 import gov
.nasa
.worldwind
.*;
12 import java
.util
.concurrent
.locks
.*;
13 import static java
.util
.logging
.Level
.*;
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
);
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;
52 rpfTocFile
= RpfTocFile
.load(tocFile
);
56 WorldWind
.logger().log(FINE
, e
.getMessage());
59 if (rpfTocFile
== null)
62 String firstFrameFilename
= findFirstRpfFrameFilename(rpfTocFile
);
63 if (firstFrameFilename
== null)
66 RpfFrameProperties firstFrameProperties
= null;
69 firstFrameProperties
= RpfFrameFilenameUtil
.parseFilename(firstFrameFilename
);
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
;
103 this.context
.process(this.directory
, listener
, true);
104 this.context
.threadLock
.lock();
107 if (this.context
.thread
!= this.context
.deadThread
)
110 this.context
.thread
= this.context
.deadThread
;
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
)
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();
149 private void process(File file
, RpfTocCrawlerListener listener
, boolean inOwnThread
)
151 this.threadLock
.lock();
154 if (inOwnThread
&& this.thread
== deadThread
)
159 this.threadLock
.unlock();
162 File
[] children
= file
.listFiles();
163 if (children
== null)
165 if (RPF_DIRECTORY
.compareToIgnoreCase(file
.getName()) == 0)
166 this.processRpfDirectory(children
, listener
, inOwnThread
);
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
)
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
)
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
)
223 public void finished()
227 File
[] tocFileArray
= new File
[results
.size()];
228 results
.toArray(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
));
255 this.threadLock
.unlock();
261 this.threadLock
.lock();
264 this.thread
= deadThread
;
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
);