Source Code Cross Referenced for TestData.java in  » GIS » GeoTools-2.4.1 » org » geotools » test » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » GIS » GeoTools 2.4.1 » org.geotools.test 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *    GeoTools - OpenSource mapping toolkit
003:         *    http://geotools.org
004:         *    (C) 2003-2006, Geotools Project Managment Committee (PMC)
005:         *
006:         *    This library is free software; you can redistribute it and/or
007:         *    modify it under the terms of the GNU Lesser General Public
008:         *    License as published by the Free Software Foundation; either
009:         *    version 2.1 of the License, or (at your option) any later version.
010:         *
011:         *    This library is distributed in the hope that it will be useful,
012:         *    but WITHOUT ANY WARRANTY; without even the implied warranty of
013:         *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014:         *    Lesser General Public License for more details.
015:         */
016:        package org.geotools.test;
017:
018:        // J2SE dependencies
019:        import java.io.BufferedInputStream;
020:        import java.io.BufferedReader;
021:        import java.io.File;
022:        import java.io.FileNotFoundException;
023:        import java.io.FileOutputStream;
024:        import java.io.IOException;
025:        import java.io.InputStream;
026:        import java.io.InputStreamReader;
027:        import java.io.LineNumberReader;
028:        import java.io.OutputStream;
029:        import java.io.RandomAccessFile;
030:        import java.net.URL;
031:        import java.net.URLDecoder;
032:        import java.nio.channels.Channels;
033:        import java.nio.channels.ReadableByteChannel;
034:        import java.util.Enumeration;
035:        import java.util.Iterator;
036:        import java.util.LinkedList;
037:        import java.util.logging.Logger;
038:        import java.util.zip.ZipEntry;
039:        import java.util.zip.ZipFile;
040:
041:        /**
042:         * Provides access to {@code test-data} directories associated with JUnit tests.
043:         * <p>
044:         * We have chosen "{@code test-data}" to follow the javadoc "{@code doc-files}" convention
045:         * of ensuring that data directories don't look anything like normal java packages.
046:         * <p>
047:         * Example:
048:         * <pre>
049:         * class MyClass {
050:         *     public void example() {
051:         *         Image testImage = new ImageIcon(TestData.url(this, "test.png")).getImage();
052:         *         Reader reader = TestData.openReader(this, "script.xml");
053:         *         // ... do some process
054:         *         reader.close();
055:         *     }
056:         * }
057:         * </pre>
058:         * Where the directory structure goes as bellow:
059:         * <ul>
060:         *   <li>{@code MyClass.java}<li>
061:         *   <li>{@code test-data/test.png}</li>
062:         *   <li>{@code test-data/script.xml}</li>
063:         * </ul>
064:         * <p>
065:         * By convention you should try and locate {@code test-data} near the JUnit test
066:         * cases that uses it. If you need an access to shared test data, import the
067:         * {@link org.geotools.TestData} class from the {@code sample-module} instead
068:         * of this one.
069:         *
070:         * @since 2.4
071:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/sample-data/src/main/java/org/geotools/test/TestData.java $
072:         * @version $Id: TestData.java 27862 2007-11-12 19:51:19Z desruisseaux $
073:         * @author James McGill
074:         * @author Simone Giannecchiin
075:         * @author Martin Desruisseaux
076:         *
077:         * @tutorial http://www.geotools.org/display/GEOT/5.8+Test+Data
078:         */
079:        public class TestData implements  Runnable {
080:            /**
081:             * The test data directory.
082:             */
083:            private static final String DIRECTORY = "test-data";
084:
085:            /**
086:             * Encoding of URL path.
087:             */
088:            private static final String ENCODING = "UTF-8";
089:
090:            /**
091:             * The {@linkplain System#getProperty(String) system property} key for more extensive test
092:             * suite. The value for this key is returned by the {@link #isExtensiveTest} method. Some
093:             * test suites will perform more extensive test coverage if this property is set to
094:             * {@code true}. The value for this property is typically defined on the command line as a
095:             * <code>-D{@value}=true</code> option at Java or Maven starting time.
096:             */
097:            public static final String EXTENSIVE_TEST_KEY = "org.geotools.test.extensive";
098:
099:            /**
100:             * The {@linkplain System#getProperty(String) system property} key for interactive tests. 
101:             * The value for this key is returned by the {@link #isInteractiveTest} method. Some
102:             * test suites will show windows with maps and other artifacts related to testing 
103:             * if this property is set to {@code true}. 
104:             * The value for this property is typically defined on the command line as a
105:             * <code>-D{@value}=true</code> option at Java or Maven starting time.
106:             */
107:            public static final String INTERACTIVE_TEST_KEY = "org.geotools.test.interactive";
108:
109:            /**
110:             * The files to delete at shutdown time. {@link File#deleteOnExit} alone doesn't seem
111:             * suffisient since it will preserve any overwritten files.
112:             */
113:            private static final LinkedList toDelete = new LinkedList();
114:
115:            /**
116:             * {@code true} if JAI media lib is available.
117:             */
118:            private static final boolean mediaLibAvailable;
119:            static {
120:                Class mediaLibImage = null;
121:                try {
122:                    mediaLibImage = Class
123:                            .forName("com.sun.medialib.mlib.Image");
124:                } catch (ClassNotFoundException e) {
125:                }
126:                mediaLibAvailable = (mediaLibImage != null);
127:            }
128:
129:            /**
130:             * Register the thread to be automatically executed at shutdown time.
131:             * This thread will delete all temporary files registered in {@link #toDelete}.
132:             */
133:            static {
134:                Runtime.getRuntime().addShutdownHook(
135:                        new Thread(new TestData(), "Test data cleaner"));
136:            }
137:
138:            /**
139:             * Do not allow instantiation of this class, except for extending it.
140:             */
141:            protected TestData() {
142:            }
143:
144:            /**
145:             * Get a property as a boolean value. If the property can't be
146:             * fetch for security reason, then default to {@code false}.
147:             */
148:            private static boolean getBoolean(final String name) {
149:                try {
150:                    return Boolean.getBoolean(name);
151:                } catch (SecurityException exception) {
152:                    // Note: we use Java Logger instead of Geotools Logging because this module
153:                    // do not depends on the module that defines Logging. This class is used for
154:                    // test purpose only anyway, so it should not be an issue.
155:                    Logger.getLogger("org.geotools").warning(
156:                            exception.getLocalizedMessage());
157:                    return false;
158:                }
159:            }
160:
161:            /**
162:             * Returns {@code true} if the running Java virtual machine is 1.4. This is the lowest
163:             * Java version currently supported by Geotools. This version will increase in future
164:             * Geotools version.
165:             * <p>
166:             * This method is used for some broken JUnit test that are know to run on JSE 1.4 but
167:             * not on JSE 1.6 for example.
168:             */
169:            public static boolean isBaseJavaPlatform() {
170:                return System.getProperty("java.version").startsWith("1.4");
171:            }
172:
173:            /**
174:             * Returns {@code true} if JAI MediaLib acceleration is available.
175:             * <p>
176:             * This method is used to disable some checks in unit tests that fail when JAI is
177:             * run in pure java mode.
178:             */
179:            public static boolean isMediaLibAvailable() {
180:                return mediaLibAvailable;
181:            }
182:
183:            /**
184:             * Returns {@code true} if {@value #EXTENSIVE_TEST_KEY} system property is set to
185:             * {@code true}. Test suites should check this value before to perform lengthly tests.
186:             */
187:            public static boolean isExtensiveTest() {
188:                return getBoolean(EXTENSIVE_TEST_KEY);
189:            }
190:
191:            /**
192:             * Returns {@code true} if {@value #INTERACTIVE_TEST_KEY} system property is set to {@code true}.
193:             * Test suites should check this value before showing any kind of graphical window to the user.
194:             */
195:            public static boolean isInteractiveTest() {
196:                return getBoolean(INTERACTIVE_TEST_KEY);
197:            }
198:
199:            /**
200:             * Locates named test-data resource for caller. <strong>Note:</strong> Consider using the
201:             * <code>{@link #url url}(caller, name)</code> method instead if the resource should always
202:             * exists.
203:             *
204:             * @param  caller Calling class or object used to locate {@code test-data}.
205:             * @param  name resource name in {@code test-data} directory.
206:             * @return URL or {@code null} if the named test-data could not be found.
207:             *
208:             * @see #url
209:             */
210:            public static URL getResource(final Object caller, String name) {
211:                if (name == null || (name = name.trim()).length() == 0) {
212:                    name = DIRECTORY;
213:                } else {
214:                    name = DIRECTORY + '/' + name;
215:                }
216:                if (caller != null) {
217:                    final Class c = (caller instanceof  Class) ? (Class) caller
218:                            : caller.getClass();
219:                    return c.getResource(name);
220:                } else {
221:                    return Thread.currentThread().getContextClassLoader()
222:                            .getResource(name);
223:                }
224:            }
225:
226:            /**
227:             * Access to <code>{@linkplain #getResource getResource}(caller, path)</code> as a non-null
228:             * {@link URL}. At the difference of {@code getResource}, this method throws an exception if
229:             * the resource is not found. This provides a more explicit explanation about the failure
230:             * reason than the infamous {@link NullPointerException}.
231:             *
232:             * @param  caller Calling class or object used to locate {@code test-data}.
233:             * @param  path Path to file in {@code test-data}.
234:             * @return The URL to the {@code test-data} resource.
235:             * @throws FileNotFoundException if the resource is not found.
236:             *
237:             * @since 2.2
238:             */
239:            public static URL url(final Object caller, final String path)
240:                    throws FileNotFoundException {
241:                final URL url = getResource(caller, path);
242:                if (url == null) {
243:                    throw new FileNotFoundException(
244:                            "Could not locate test-data: " + path);
245:                }
246:                return url;
247:            }
248:
249:            /**
250:             * Access to <code>{@linkplain #getResource getResource}(caller, path)</code> as a non-null
251:             * {@link File}. You can access the {@code test-data} directory with:
252:             *
253:             * <blockquote><pre>
254:             * TestData.file(MyClass.class, null);
255:             * </pre></blockquote>
256:             *
257:             * @param  caller Calling class or object used to locate {@code test-data}.
258:             * @param  path Path to file in {@code test-data}.
259:             * @return The file to the {@code test-data} resource.
260:             * @throws FileNotFoundException if the file is not found.
261:             * @throws IOException if the resource can't be fetched for an other reason.
262:             */
263:            public static File file(final Object caller, final String path)
264:                    throws IOException {
265:                final URL url = url(caller, path);
266:                final File file = new File(URLDecoder.decode(url.getPath(),
267:                        ENCODING));
268:                if (!file.exists()) {
269:                    throw new FileNotFoundException(
270:                            "Could not locate test-data: " + path);
271:                }
272:                return file;
273:            }
274:
275:            /**
276:             * Creates a temporary file with the given name. The file will be created in the
277:             * {@code test-data} directory and will be deleted on exit.
278:             *
279:             * @param  caller Calling class or object used to locate {@code test-data}.
280:             * @param  A base name for the temporary file.
281:             * @return The temporary file in the {@code test-data} directory.
282:             * @throws IOException if the file can't be created.
283:             */
284:            public static File temp(final Object caller, final String name)
285:                    throws IOException {
286:                final File testData = file(caller, null);
287:                final int split = name.lastIndexOf('.');
288:                final String prefix = (split < 0) ? name : name.substring(0,
289:                        split);
290:                final String suffix = (split < 0) ? "tmp" : name
291:                        .substring(split + 1);
292:                final File tmp = File.createTempFile(prefix, '.' + suffix,
293:                        testData);
294:                deleteOnExit(tmp);
295:                return tmp;
296:            }
297:
298:            /**
299:             * Provides a non-null {@link InputStream} for named test data.
300:             * It is the caller responsability to close this stream after usage.
301:             *
302:             * @param  caller Calling class or object used to locate {@code test-data}.
303:             * @param  name of test data to load.
304:             * @return The input stream.
305:             * @throws FileNotFoundException if the resource is not found.
306:             * @throws IOException if an error occurs during an input operation.
307:             *
308:             * @since 2.2
309:             */
310:            public static InputStream openStream(final Object caller,
311:                    final String name) throws IOException {
312:                return new BufferedInputStream(url(caller, name).openStream());
313:            }
314:
315:            /**
316:             * Provides a {@link BufferedReader} for named test data. The buffered reader is provided as
317:             * an {@link LineNumberReader} instance, which is useful for displaying line numbers where
318:             * error occur. It is the caller responsability to close this reader after usage.
319:             *
320:             * @param  caller The class of the object associated with named data.
321:             * @param  name of test data to load.
322:             * @return The buffered reader.
323:             * @throws FileNotFoundException if the resource is not found.
324:             * @throws IOException if an error occurs during an input operation.
325:             *
326:             * @since 2.2
327:             */
328:            public static LineNumberReader openReader(final Object caller,
329:                    final String name) throws IOException {
330:                return new LineNumberReader(new InputStreamReader(url(caller,
331:                        name).openStream()));
332:            }
333:
334:            /**
335:             * Provides a {@link java.io.BufferedReader} for named test data.
336:             * It is the caller responsability to close this reader after usage.
337:             *
338:             * @param  caller The class of the object associated with named data.
339:             * @param  name of test data to load.
340:             * @return The reader, or {@code null} if the named test data are not found.
341:             * @throws IOException if an error occurs during an input operation.
342:             *
343:             * @deprecated Use {@link #openReader} instead. The {@code openReader} method throws an
344:             *  exception if the resource is not found, instead of returning null. This make debugging
345:             *  easier, since it replaces infamous {@link NullPointerException} by a more explicit error
346:             *  message during tests. Furthermore, the {@code openReader} name make it more obvious that
347:             *  the stream is not closed automatically and is also consistent with other method names in
348:             *  this class.
349:             */
350:            public static BufferedReader getReader(final Object caller,
351:                    final String name) throws IOException {
352:                final URL url = getResource(caller, name);
353:                if (url == null) {
354:                    return null; // echo handling of getResource( ... )
355:                }
356:                return new BufferedReader(new InputStreamReader(url
357:                        .openStream()));
358:            }
359:
360:            /**
361:             * Provides a channel for named test data. It is the caller responsability to close this
362:             * chanel after usage.
363:             *
364:             * @param  caller The class of the object associated with named data.
365:             * @param  name of test data to load.
366:             * @return The chanel.
367:             * @throws FileNotFoundException if the resource is not found.
368:             * @throws IOException if an error occurs during an input operation.
369:             *
370:             * @since 2.2
371:             */
372:            public static ReadableByteChannel openChannel(final Object caller,
373:                    final String name) throws IOException {
374:                final URL url = url(caller, name);
375:                final File file = new File(URLDecoder.decode(url.getPath(),
376:                        ENCODING));
377:                if (file.exists()) {
378:                    return new RandomAccessFile(file, "r").getChannel();
379:                }
380:                return Channels.newChannel(url.openStream());
381:            }
382:
383:            /**
384:             * Unzip a file in the {@code test-data} directory. The zip file content is inflated in place,
385:             * i.e. inflated files are written in the same {@code test-data} directory. If a file to be
386:             * inflated already exists in the {@code test-data} directory, then the existing file is left
387:             * untouched and the corresponding ZIP entry is silently skipped. This approach avoid the
388:             * overhead of inflating the same files many time if this {@code unzipFile} method is invoked
389:             * before every tests.
390:             * <p>
391:             * Inflated files will be automatically {@linkplain File#deleteOnExit deleted on exit}
392:             * if and only if they have been modified. Callers don't need to worry about cleanup,
393:             * because the files are inflated in the {@code target/.../test-data} directory, which
394:             * is not versionned by SVN and is cleaned by Maven on {@code mvn clean} execution.
395:             *
396:             * @param  caller The class of the object associated with named data.
397:             * @param  name The file name to unzip in place.
398:             * @throws FileNotFoundException if the specified zip file is not found.
399:             * @throws IOException if an error occurs during an input or output operation.
400:             *
401:             * @since 2.2
402:             */
403:            public static void unzipFile(final Object caller, final String name)
404:                    throws IOException {
405:                final File file = file(caller, name);
406:                final File parent = file.getParentFile().getAbsoluteFile();
407:                final ZipFile zipFile = new ZipFile(file);
408:                final Enumeration entries = zipFile.entries();
409:                final byte[] buffer = new byte[4096];
410:                while (entries.hasMoreElements()) {
411:                    final ZipEntry entry = (ZipEntry) entries.nextElement();
412:                    if (entry.isDirectory()) {
413:                        continue;
414:                    }
415:                    final File path = new File(parent, entry.getName());
416:                    if (path.exists()) {
417:                        continue;
418:                    }
419:                    final File directory = path.getParentFile();
420:                    if (directory != null && !directory.exists()) {
421:                        directory.mkdirs();
422:                    }
423:                    // Copy the file. Note: no need for a BufferedOutputStream,
424:                    // since we are already using a buffer of type byte[4096].
425:                    final InputStream in = zipFile.getInputStream(entry);
426:                    final OutputStream out = new FileOutputStream(path);
427:                    int len;
428:                    while ((len = in.read(buffer)) >= 0) {
429:                        out.write(buffer, 0, len);
430:                    }
431:                    out.close();
432:                    in.close();
433:                    // Call 'deleteOnExit' only after after we closed the file,
434:                    // because this method will save the modification time.
435:                    deleteOnExit(path, false);
436:                }
437:                zipFile.close();
438:            }
439:
440:            /**
441:             * Requests that the file or directory denoted by the specified
442:             * pathname be deleted when the virtual machine terminates.
443:             */
444:            protected static void deleteOnExit(final File file) {
445:                deleteOnExit(file, true);
446:            }
447:
448:            /**
449:             * Requests that the file or directory denoted by the specified pathname be deleted
450:             * when the virtual machine terminates. This method can optionnaly delete the file
451:             * only if it has been modified, thus giving a chance for test suites to copy their
452:             * resources only once.
453:             * 
454:             * @param file The file to delete.
455:             * @param force If {@code true}, delete the file in all cases. If {@code false},
456:             *        delete the file if and only if it has been modified. The default value
457:             *        if {@code true}.
458:             *
459:             * @since 2.4
460:             */
461:            protected static void deleteOnExit(final File file,
462:                    final boolean force) {
463:                if (force) {
464:                    file.deleteOnExit();
465:                }
466:                final Deletable entry = new Deletable(file, force);
467:                synchronized (toDelete) {
468:                    if (file.isFile()) {
469:                        toDelete.addFirst(entry);
470:                    } else {
471:                        toDelete.addLast(entry);
472:                    }
473:                }
474:            }
475:
476:            /**
477:             * A file that may be deleted on JVM shutdown.
478:             */
479:            private static final class Deletable {
480:                /**
481:                 * The file to delete.
482:                 */
483:                private final File file;
484:
485:                /**
486:                 * The initial timestamp. Used in order to determine if the file has been modified.
487:                 */
488:                private final long timestamp;
489:
490:                /**
491:                 * Constructs an entry for a file to be deleted.
492:                 */
493:                public Deletable(final File file, final boolean force) {
494:                    this .file = file;
495:                    timestamp = force ? Long.MIN_VALUE : file.lastModified();
496:                }
497:
498:                /**
499:                 * Returns {@code true} if failure to delete this file can be ignored.
500:                 */
501:                public boolean canIgnore() {
502:                    return timestamp != Long.MIN_VALUE && file.isDirectory();
503:                }
504:
505:                /**
506:                 * Deletes this file, if modified. Returns {@code false} only
507:                 * if the file should be deleted but the operation failed.
508:                 */
509:                public boolean delete() {
510:                    if (!file.exists() || file.lastModified() <= timestamp) {
511:                        return true;
512:                    }
513:                    return file.delete();
514:                }
515:
516:                /**
517:                 * Returns the filepath.
518:                 */
519:                public String toString() {
520:                    return String.valueOf(file);
521:                }
522:            }
523:
524:            /**
525:             * Deletes all temporary files. This method is invoked automatically at shutdown time and
526:             * should not be invoked directly. It is public only as an implementation side effect.
527:             */
528:            public void run() {
529:                int iteration = 5; // Maximum number of iterations
530:                synchronized (toDelete) {
531:                    while (!toDelete.isEmpty()) {
532:                        if (--iteration < 0) {
533:                            break;
534:                        }
535:                        /*
536:                         * Before to try to delete the files, invokes the finalizers in a hope to close
537:                         * any input streams that the user didn't explicitly closed. Leaving streams open
538:                         * seems to occurs way too often in our test suite...
539:                         */
540:                        System.gc();
541:                        System.runFinalization();
542:                        for (final Iterator it = toDelete.iterator(); it
543:                                .hasNext();) {
544:                            final Deletable f = (Deletable) it.next();
545:                            try {
546:                                if (f.delete()) {
547:                                    it.remove();
548:                                    continue;
549:                                }
550:                            } catch (SecurityException e) {
551:                                if (iteration == 0) {
552:                                    System.err.print(e.getClass().getName());
553:                                    System.err.print(": ");
554:                                }
555:                            }
556:                            // Can't use logging, since logger are not available anymore at shutdown time.
557:                            if (iteration == 0 && !f.canIgnore()) {
558:                                System.err.print("Can't delete ");
559:                                System.err.println(f);
560:                            }
561:                        }
562:                    }
563:                }
564:            }
565:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.