001: /*
002: * This file is part of PFIXCORE.
003: *
004: * PFIXCORE is free software; you can redistribute it and/or modify
005: * it under the terms of the GNU Lesser General Public License as published by
006: * the Free Software Foundation; either version 2 of the License, or
007: * (at your option) any later version.
008: *
009: * PFIXCORE is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public License
015: * along with PFIXCORE; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */
018:
019: package de.schlund.pfixxml.resources;
020:
021: import java.io.FileNotFoundException;
022: import java.io.IOException;
023: import java.io.InputStream;
024: import java.io.OutputStream;
025: import java.net.URI;
026: import java.net.URISyntaxException;
027:
028: import de.schlund.pfixxml.config.GlobalConfig;
029:
030: /**
031: * Provides access to resources on the filesystem.
032: * For most of the functionality, {@link de.schlund.pfixxml.config.GlobalConfig}
033: * is required and has to be configured through {@link de.schlund.pfixxml.config.GlobalConfigurator}
034: * before this class is used.
035: *
036: * @author Sebastian Marsching <sebastian.marsching@1und1.de>
037: */
038: public class ResourceUtil {
039: /**
040: * Creates a resource object using the given uri.
041: * At the moment only absolute URIs with the "file" or
042: * "pfixroot" scheme are supported.
043: *
044: * @param uri URI denoting the resource to access
045: * @return Resource object for the given URI
046: * @throws IllegalArgumentException if given URI
047: * uses a scheme that is not supported or is
048: * not absolute
049: * @see #getFileResource(String)
050: */
051: public static FileResource getFileResource(URI uri) {
052: String scheme = uri.getScheme();
053: if (scheme == null || scheme.equals("")) {
054: throw new IllegalArgumentException(
055: "Cannot handle URIs without a scheme");
056: }
057:
058: String path = uri.getPath();
059: if (path == null || path.equals("")) {
060: throw new IllegalArgumentException(
061: "Cannot handle URIs without a path");
062: }
063:
064: if (scheme.equals("pfixroot")) {
065: return GlobalConfig.getDocrootResourceProvider()
066: .getDocrootResource(uri);
067: } else if (scheme.equals("file")) {
068: return new FileSystemResourceImpl(uri);
069: } else {
070: throw new IllegalArgumentException(
071: "Cannot handle URI with scheme '" + scheme + "'");
072: }
073: }
074:
075: /**
076: * Returns a resource interpreting the supplied string as
077: * an URI. Special characters in the URI have to be escaped
078: * as the supplied string is directly passed to the constructor
079: * {@link URI#URI(java.lang.String)}.
080: *
081: * @param uri String specifying a full URI
082: * @return Resource for the specified URI
083: * @throws IllegalArgumentException if supplied does not
084: * represent a valid URI
085: * @see #getFileResource(URI)
086: */
087: public static FileResource getFileResource(String uri) {
088: // Replace spaces in URI with %20
089: // URIs must not contain spaces, however
090: // there is plenty of code that doesn't check for
091: // spaces when calling this method
092: uri = fixURI(uri);
093: try {
094: return getFileResource(new URI(uri));
095: } catch (URISyntaxException e) {
096: throw new IllegalArgumentException("URI \"" + uri
097: + "\" is not well-formed", e);
098: }
099: }
100:
101: /**
102: * Returns a resource resolving the given name relative to the
103: * given parent. The parent is always treated as a directory
104: * even if its URI does not end with a "/"
105: *
106: * @param parent directory to look for resource in
107: * @param name filename or relative path
108: * @return resource specified by the concatenation of the given parent
109: * and name
110: * @throws IllegalArgumentException if name is not relative
111: */
112: public static FileResource getFileResource(FileResource parent,
113: String name) {
114: name = fixURI(name);
115: if (name.startsWith("/")) {
116: throw new IllegalArgumentException(
117: "Relative name may not start with a '/'");
118: }
119:
120: URI parent_uri = parent.toURI();
121: String parent_path = parent_uri.getPath();
122: if (!parent_path.endsWith("/")) {
123: parent_path = parent_path + "/";
124: }
125:
126: try {
127: return getFileResource(new URI(parent_uri.getScheme(),
128: parent_uri.getAuthority(), parent_path + name,
129: parent_uri.getQuery(), parent_uri.getFragment()));
130: } catch (URISyntaxException e) {
131: throw new RuntimeException(e);
132: }
133: }
134:
135: /**
136: * Returns a resource interpreting the given path relative
137: * to Pustefix's docroot.
138: *
139: * @param path path of the resource relative to the docroot
140: * @return Resource from the docroot
141: */
142: public static DocrootResource getFileResourceFromDocroot(String path) {
143: path = fixURI(path);
144: if (!path.startsWith("/")) {
145: path = "/" + path;
146: }
147: try {
148: return (DocrootResource) getFileResource(new URI(
149: "pfixroot", null, path, null, null));
150: } catch (URISyntaxException e) {
151: throw new IllegalArgumentException("Path \"" + path
152: + "\" is not well-formed", e);
153: }
154: }
155:
156: /**
157: * Copies a resource's content to another resource.
158: *
159: * @param source resource to read from
160: * @param target resource to write to
161: * @throws IOException if content cannot be copied
162: */
163: public static void copy(FileResource source, FileResource target)
164: throws IOException {
165: if (!source.isFile() || target.isDirectory()) {
166: throw new FileNotFoundException(
167: "Either source is not existing or target or source is a directory");
168: }
169: InputStream in = source.getInputStream();
170: OutputStream out = target.getOutputStream();
171: int len = 0;
172: byte[] buffer = new byte[512];
173: while ((len = in.read(buffer)) != -1) {
174: out.write(buffer, 0, len);
175: }
176: in.close();
177: out.close();
178: }
179:
180: /**
181: * Takes a URI as a string and converts it into a valid URI
182: * string (e.g. replaces spaces) on a best effort basis.
183: *
184: * @param uri URI to do fixes for
185: * @return URI in correct format
186: */
187: private static String fixURI(String uri) {
188: uri = uri.replace(" ", "%20");
189: return uri;
190: }
191: }
|