001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2005-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;
017:
018: // J2SE dependencies
019: import java.io.BufferedReader;
020: import java.io.File;
021: import java.io.FileNotFoundException;
022: import java.io.FileOutputStream;
023: import java.io.IOException;
024: import java.io.InputStream;
025: import java.io.LineNumberReader;
026: import java.io.OutputStream;
027: import java.net.URL;
028: import java.nio.channels.ReadableByteChannel;
029:
030: /**
031: * Provides access to the common {@code test-data} directories provided in the
032: * {@code sample-data} module. This directory is shared by test suites in other
033: * modules.
034: * <p>
035: * This file has to live in the {@code org.geotools} root package in order to
036: * get access to the {@code org/geotools/test-data} directory. If you don't
037: * need this directory, then use the {@link org.geotools.test.TestData}
038: * class provided in the {@code org.geotools.resources} directory.
039: *
040: * @since 2.2
041: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/sample-data/src/main/java/org/geotools/TestData.java $
042: * @version $Id: TestData.java 24085 2007-01-27 21:19:05Z desruisseaux $
043: * @author Martin Desruisseaux
044: *
045: * @tutorial http://www.geotools.org/display/GEOT/5.8+Test+Data
046: */
047: public final class TestData extends org.geotools.test.TestData {
048: /**
049: * Do not allow instantiation of this class.
050: */
051: private TestData() {
052: }
053:
054: /**
055: * Access to <code>{@linkplain #getResource getResource}(name)</code> as a non-null
056: * {@link URL}. At the difference of {@code getResource}, this method throws an exception if
057: * the resource is not found. This provides a more explicit explanation about the failure
058: * reason than the infamous {@link NullPointerException}.
059: *
060: * @param name Path to file in {@code org/geotools/test-data}.
061: * @return The URL to the {@code test-data} resource.
062: * @throws FileNotFoundException if the resource is not found.
063: */
064: public static URL url(final String name)
065: throws FileNotFoundException {
066: return url(TestData.class, name);
067: }
068:
069: /**
070: * Access to <code>{@linkplain #getResource getResource}(name)</code> as a non-null
071: * {@link File}. You can access the {@code test-data} directory with:
072: *
073: * <blockquote><pre>
074: * TestData.file(null);
075: * </pre></blockquote>
076: *
077: * @param name Path to file in {@code org/geotools/test-data}.
078: * @return The file to the {@code test-data} resource.
079: * @throws FileNotFoundException if the file is not found.
080: * @throws IOException if the resource can't be fetched for an other reason.
081: */
082: public static File file(final String name) throws IOException {
083: return file(TestData.class, name);
084: }
085:
086: /**
087: * Provides a non-null {@link InputStream} for named test data.
088: * It is the caller responsability to close this stream after usage.
089: *
090: * @param name Path to file in {@code org/geotools/test-data}.
091: * @return The input stream.
092: * @throws FileNotFoundException if the resource is not found.
093: * @throws IOException if an error occurs during an input operation.
094: */
095: public static InputStream openStream(final String name)
096: throws IOException {
097: return openStream(TestData.class, name);
098: }
099:
100: /**
101: * Provides a {@link BufferedReader} for named test data. The buffered reader is provided as
102: * an {@link LineNumberReader} instance, which is useful for displaying line numbers where
103: * error occur. It is the caller responsability to close this reader after usage.
104: *
105: * @param name Path to file in {@code org/geotools/test-data}.
106: * @return The buffered reader.
107: * @throws FileNotFoundException if the resource is not found.
108: * @throws IOException if an error occurs during an input operation.
109: */
110: public static LineNumberReader openReader(final String name)
111: throws IOException {
112: return openReader(TestData.class, name);
113: }
114:
115: /**
116: * Provides a channel for named test data. It is the caller responsability to close this
117: * chanel after usage.
118: *
119: * @param name Path to file in {@code org/geotools/test-data}.
120: * @return The chanel.
121: * @throws FileNotFoundException if the resource is not found.
122: * @throws IOException if an error occurs during an input operation.
123: */
124: public static ReadableByteChannel openChannel(final String name)
125: throws IOException {
126: return openChannel(TestData.class, name);
127: }
128:
129: /**
130: * Copies the named resources from the {@code sample-data} module to the {@code test-data}
131: * directory in an other module. For example if {@code TestData.copy(this, "foo.txt")} is
132: * invoked inside a test suite in the {@code org.geotools.foo} package, then this method
133: * copies {@code org/geotools/test-data/foo.txt} (from {@code sample-data} module) to
134: * {@code org/geotools/foo/test-data/foo.txt} (in the {@code foo} module).
135: * <p>
136: * This method is useful when a test case needs to access a resource through a {@link File},
137: * for example because it want to open it using {@link java.io.RandomAccess}. Because the
138: * resources provided in the {@code sample-data} module are available to other modules as
139: * a JAR file, other modules can only access them through an {@link URL} unless they copy
140: * them in their own {@code test-data} directory.
141: * <p>
142: * If the named file already exists in the caller {@code test-data} directory, then this
143: * method does nothing. It make it safe to invoke this method many time in a test suite,
144: * since this method should not copy the file more than once for a given JVM execution.
145: * <p>
146: * The file will be {@linkplain File#deleteOnExit deleted on exit} if and only if it has
147: * been modified. Callers don't need to worry about cleanup, because the files are copied
148: * in the {@code target/.../test-data} directory, which is not versionned by SVN and is
149: * cleaned by Maven on {@code mvn clean} execution.
150: *
151: * @param caller Calling class or object used to locate the destination {@code test-data}.
152: * @param name Path to file in {@code org/geotools/test-data}.
153: * @return The file to the <code>org/geotools/<strong>caller-package</strong>/test-data</code>
154: * resource copy, returned for convenience.
155: * @throws FileNotFoundException if the file is not found.
156: * @throws IOException if the resource can't be fetched for an other reason.
157: */
158: public static File copy(final Object caller, final String name)
159: throws IOException {
160: final File path = new File(name);
161: final File directory = new File(file(caller, null), path
162: .getParent());
163: final File file = new File(directory, path.getName());
164: if (!file.exists()) {
165: if (directory.mkdirs()) {
166: deleteOnExit(directory, false);
167: }
168: final InputStream in = openStream(name);
169: final OutputStream out = new FileOutputStream(file);
170: final byte[] buffer = new byte[4096];
171: deleteOnExit(file, false);
172: int count;
173: while ((count = in.read(buffer)) >= 0) {
174: out.write(buffer, 0, count);
175: }
176: out.close();
177: in.close();
178: }
179: return file;
180: }
181: }
|