1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.xmlhammer;
22
23 import java.io.File;
24 import java.io.FileFilter;
25 import java.net.URI;
26 import java.util.ArrayList;
27 import java.util.List;
28 import java.util.regex.Matcher;
29 import java.util.regex.Pattern;
30
31 import javax.swing.event.EventListenerList;
32
33 import org.apache.log4j.Logger;
34 import org.bounce.util.URIUtils;
35 import org.xmlhammer.gui.status.StatusModel;
36 import org.xmlhammer.gui.util.WildcardFileFilter;
37 import org.xmlhammer.model.project.Document;
38 import org.xmlhammer.model.project.Filter;
39 import org.xmlhammer.model.project.Input;
40
41 /***
42 * Put comment...
43 *
44 * @version $Revision$, $Date$
45 * @author Edwin Dankert <edankert@gmail.com>
46 */
47
48 public class ModuleThread extends Thread {
49 private EventListenerList listeners = null;
50 private ResultModel result = null;
51 private Logger logger = null;
52 private Module module = null;
53 private Input input = null;
54 private StatusModel status = null;
55
56 private boolean cancelled = false;
57
58 /***
59 * Constructs a module runner.
60 *
61 * @param logger
62 * @param status
63 * @param result
64 * @param input
65 * @param module
66 */
67 public ModuleThread( Logger logger, StatusModel status, ResultModel result, Input input, Module module) {
68 listeners = new EventListenerList();
69
70 this.module = module;
71 this.logger = logger;
72 this.input = input;
73 this.result = result;
74 this.status = status;
75
76
77 }
78
79 private List<URI> getURIs() {
80 if (input.getFilter() != null) {
81 return getURIs(input.getFilter());
82 }
83
84 return getURIs(input.getSourceOrSourceAndResult());
85 }
86
87 @Override
88 public void run() {
89 if (status != null) {
90 status.reset();
91 }
92
93 fireThreadStarted();
94
95 try {
96 if (status != null) {
97 status.setStatus( "Resolving URIs ...");
98 }
99 List<URI> uris = getURIs();
100
101 long time = System.currentTimeMillis();
102
103 for ( int i = 0; !cancelled && i < uris.size(); i++) {
104 URI sourceURI = uris.get(i);
105
106 if (module.isResultEnabled()) {
107 if (status != null) {
108 status.setProgress((i/2)+1, uris.size()/2);
109 status.setStatus( "Processing "+URIUtils.getName(sourceURI)+" ...");
110 }
111
112 i++;
113
114 URI resultURI = uris.get(i);
115
116 module.execute(status, result, sourceURI, resultURI);
117 } else {
118 if (status != null) {
119 status.setProgress( i+1, uris.size());
120 status.setStatus( "Processing "+URIUtils.getName(sourceURI)+" ...");
121 }
122
123 module.execute(status, result, sourceURI);
124 }
125 }
126
127
128 if (cancelled && status != null) {
129 status.setStatus( "Cancelled");
130 } else {
131 time = System.currentTimeMillis() - time;
132
133 if ( time > 60000) {
134 long seconds = time/1000;
135 long minutes = seconds/60;
136 seconds = seconds - (minutes * 60);
137 logger.info( "Total time: "+minutes+" minutes "+seconds+" seconds");
138
139 if (status != null) {
140 status.setStatus( "Done ("+minutes+" minutes "+seconds+" seconds)");
141 }
142 } else if ( time > 1000) {
143 logger.info( "Total time: "+time/1000+" seconds");
144
145 if (status != null) {
146 status.setStatus( "Done ("+time/1000+" seconds)");
147 }
148 } else {
149 logger.info( "Total time: "+time+" milliseconds");
150
151 if (status != null) {
152 status.setStatus( "Done ("+time+" milliseconds)");
153 }
154 }
155 }
156
157 } catch ( Exception e) {
158 if (status != null) {
159 status.setStatus("Execution Error");
160 }
161
162 logger.error("Module Execution Error", e);
163 } finally {
164 fireThreadFinished();
165 }
166 }
167
168 public synchronized void cancel() {
169 cancelled = true;
170 }
171
172 private List<URI> getURIs( List<Document> list) {
173 ArrayList<URI> uris = new ArrayList<URI>();
174
175 for ( Document document : list) {
176 uris.add( URIUtils.createURI(document.getSrc()));
177 }
178
179 return uris;
180 }
181
182 private List<URI> getURIs(Filter filter) {
183 ArrayList<URI> uris = new ArrayList<URI>();
184 FileFilter fileFilter = null;
185
186 String expression = filter.getPattern();
187
188 if (filter.isRegex()) {
189 fileFilter = new RegexNameFileFilter(expression);
190 } else {
191 fileFilter = new WildcardFileFilter(expression);
192 }
193
194 URI uri = URIUtils.createURI(filter.getDir());
195 File file = null;
196
197 if (uri.isAbsolute()) {
198 file = URIUtils.toFile(uri);
199 }
200
201 if ( file != null) {
202 if (!file.exists()) {
203 throw new IllegalArgumentException("Filter directory \""+file.toString()+"\" does not exist!");
204 }
205
206 addURIs(uris, filter, file, fileFilter, filter.isIncludeSubdirectories());
207 }
208
209 return uris;
210 }
211
212 private void addURIs(ArrayList<URI> uris, Filter filter, File dir, FileFilter fileFilter, boolean subdirs) {
213 if (cancelled) {
214 return;
215 }
216
217 for (File file : dir.listFiles( fileFilter)) {
218 if (cancelled) {
219 return;
220 }
221
222 addURI(uris, filter, file);
223 }
224
225 if (subdirs) {
226 for (File file : dir.listFiles()) {
227 if (file.isDirectory()) {
228 addURIs(uris, filter, file, fileFilter, subdirs);
229 }
230 }
231 }
232 }
233
234 private void addURI(ArrayList<URI> uris, Filter filter, File inputFile) {
235 uris.add(inputFile.toURI());
236
237 if (module.isResultEnabled()) {
238 URI inputURI = URIUtils.createURI(filter.getDir());
239 File inputDir = null;
240 File outputDir = null;
241
242 if (inputURI.isAbsolute()) {
243 inputDir = new File(inputURI);
244 }
245
246 URI uri = URIUtils.createURI(filter.getOutDir());
247
248 if (uri.isAbsolute()) {
249 outputDir = new File(uri);
250 }
251
252 if (outputDir == null) {
253 outputDir = inputDir;
254 }
255
256 if (outputDir != null) {
257 if (!outputDir.exists()) {
258 throw new IllegalArgumentException("Filter output directory \""+outputDir.toString()+"\" does not exist!");
259 }
260
261 String f1 = inputFile.toString();
262 f1 = f1.substring(inputDir.toString().length()+1);
263
264 if (filter.getExtension() != null && filter.getExtension().trim().length() > 0) {
265 int dotIndex = f1.lastIndexOf('.');
266
267 if (dotIndex > 0) {
268 f1 = f1.substring(0, f1.lastIndexOf('.'));
269 }
270
271 f1 = f1 + "." + filter.getExtension();
272 }
273
274 File outputFile = new File(outputDir, f1);
275 uris.add(outputFile.toURI());
276 }
277 }
278 }
279
280 private class RegexNameFileFilter implements FileFilter {
281 private Pattern pattern = null;
282
283 public RegexNameFileFilter( String pattern) {
284 this.pattern = Pattern.compile( pattern);
285 }
286
287
288
289
290
291
292 public boolean accept( File pathname) {
293 if ( pathname != null && pathname.isFile()) {
294 String name = pathname.getName();
295 Matcher matcher = pattern.matcher( name);
296 return matcher.matches();
297 }
298
299 return false;
300 }
301 }
302
303 /***
304 * Notifies the listeners about the deletion of this document.
305 */
306 protected void fireThreadFinished() {
307
308 Object[] list = listeners.getListenerList();
309
310
311
312 for ( int i = list.length-2; i >= 0; i -= 2) {
313 if ( list[i] == ModuleThreadListener.class) {
314 ((ModuleThreadListener)list[i+1]).threadFinished( this);
315 }
316 }
317 }
318
319 protected void fireThreadStarted() {
320
321 Object[] list = listeners.getListenerList();
322
323
324
325 for ( int i = list.length-2; i >= 0; i -= 2) {
326 if ( list[i] == ModuleThreadListener.class) {
327 ((ModuleThreadListener)list[i+1]).threadStarted( this);
328 }
329 }
330 }
331
332 /***
333 * Adds a thread listener to the module.
334 */
335 public void addListener( ModuleThreadListener listener) {
336 listeners.add( ModuleThreadListener.class, listener);
337 }
338
339 /***
340 * Removes a thread listener from the module.
341 */
342 public void removeListener( ModuleThreadListener listener) {
343 listeners.remove( ModuleThreadListener.class, listener);
344 }
345 }