View Javadoc

1   /*
2    * Copyright 1999-2006 Faculty of Mathematics, Physics and Informatics, Comenius
3    * University, Bratislava. This file is protected by the Mozilla Public License
4    * version 1.1 (the License); you may not use this file except in compliance
5    * with the License. You may obtain a copy of the License at
6    * http://euromath2.sourceforge.net/license.html Unless required by applicable
7    * law or agreed to in writing, software distributed under the License is
8    * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
9    * KIND, either express or implied. See the License for the specific language
10   * governing permissions and limitations under the License.
11   */
12  package sk.uniba.euromath.tools;
13  import java.io.File;
14  import java.net.MalformedURLException;
15  import java.net.URI;
16  import java.net.URISyntaxException;
17  import java.net.URL;
18  import org.apache.commons.lang.StringUtils;
19  /***
20   * Representation of directory, denoted by given URL.
21   * @author Martin Vysny
22   */
23  public final class URLDir {
24  	/***
25  	 * Returns an URL object, that is represented by this object. This URL is
26  	 * always absolute, and ends with '/'.
27  	 */
28  	private URL url;
29  	/***
30  	 * Returns an URI object, that is represented by this object. This URI is
31  	 * always absolute, never opaque, and ends with '/'.
32  	 */
33  	private URI uri;
34  	/***
35  	 * Creates instance of object with given url. If URL is relative, then it is
36  	 * rooted in current directory.
37  	 * @param url url. Must denote a directory.
38  	 * @throws MalformedURLException if url is invalid.
39  	 * @throws URISyntaxException if url is invalid.
40  	 */
41  	public URLDir(String url) throws MalformedURLException, URISyntaxException {
42  		this(new URI(url.replaceAll(" ", "%20"))); //$NON-NLS-1$ //$NON-NLS-2$
43  	}
44  	/***
45  	 * Creates object pointing onto given directory. The file must point into an
46  	 * existing directory in the local filesystem.
47  	 * @param file the file
48  	 * @return the object pointing into the directory denoted by the file
49  	 * parameter.
50  	 */
51  	public static URLDir create(File file) {
52  		if (!file.isDirectory())
53  			throw new IllegalArgumentException(file.toString()
54  					+ " is not a valid directory"); //$NON-NLS-1$
55  		try {
56  			return new URLDir(file.toURI().toURL());
57  		} catch (MalformedURLException ex) {
58  			throw new Error(ex);
59  		}
60  	}
61  	/***
62  	 * Creates instance of object with given url. If URL is relative, then it is
63  	 * rooted in current directory.
64  	 * @param url url. Must denote a directory.
65  	 */
66  	public URLDir(URL url) {
67  		super();
68  		try {
69  			init(toURI(format(url)));
70  		} catch (MalformedURLException ex) {
71  			throw new Error("Unexpected URL exception.", ex); //$NON-NLS-1$
72  		}
73  	}
74  	/***
75  	 * Creates instance of object with given uri. If uri is relative, then it is
76  	 * rooted in current directory.
77  	 * @param uri uri. Must denote a directory.
78  	 * @throws MalformedURLException if given uri is not a valid URI
79  	 */
80  	public URLDir(URI uri) throws MalformedURLException {
81  		super();
82  		init(uri);
83  	}
84  	private void init(URI uri) throws MalformedURLException {
85  		// if (uri.isOpaque())
86  		// throw new IllegalArgumentException(
87  		// "Given URI must not be opaque. [" + uri + "]");
88  		if (!uri.isAbsolute()) {
89  			// root it in current directory.
90  			uri = toURI(getCurrentDir()).resolve(uri);
91  		}
92  		uri = format(uri);
93  		this.uri = uri;
94  		this.url = new URL(uri.toString());
95  	}
96  	/***
97  	 * Creates instance of object with current directory.
98  	 */
99  	public URLDir() {
100 		super();
101 		url = getCurrentDir();
102 		uri = toURI(url);
103 	}
104 	/***
105 	 * Correctly formats given URL. If it doesn't end with slash, then trailing
106 	 * slash is added. Every space is converted to a %20 string.
107 	 * @param url url to format, should denote a directory.
108 	 * @return formatted uri.
109 	 */
110 	private static URL format(URL url) {
111 		String sUrl = url.toString();
112 		boolean changed = false;
113 		if (!sUrl.endsWith("/")) { //$NON-NLS-1$
114 			changed = true;
115 			sUrl = sUrl + "/"; //$NON-NLS-1$
116 		}
117 		String sUrlNew = sUrl.replaceAll(" ", "%20"); //$NON-NLS-1$ //$NON-NLS-2$
118 		if (!sUrlNew.equals(sUrl)) {
119 			changed = true;
120 			sUrl = sUrlNew;
121 		}
122 		return changed ? createURL(sUrl) : url;
123 	}
124 	/***
125 	 * Correctly formats given URI. If it doesn't end with slash, then trailing
126 	 * slash is added.
127 	 * @param uri uri to format, should denote a directory.
128 	 * @return formatted uri.
129 	 */
130 	private static URI format(URI uri) {
131 		String sUrl = uri.toString();
132 		boolean changed = false;
133 		if (!sUrl.endsWith("/")) { //$NON-NLS-1$
134 			changed = true;
135 			sUrl = sUrl + "/"; //$NON-NLS-1$
136 		}
137 		String sUrlNew = sUrl.replaceAll(" ", "%20"); //$NON-NLS-1$ //$NON-NLS-2$
138 		if (!sUrlNew.equals(sUrl)) {
139 			changed = true;
140 			sUrl = sUrlNew;
141 		}
142 		return changed ? URI.create(sUrl) : uri;
143 	}
144 	/***
145 	 * Returns current dir, as an URL object.
146 	 * @return current dir. The URL ends with slash.
147 	 */
148 	public static URL getCurrentDir() {
149 		try {
150 			return format(new File("").toURL()); //$NON-NLS-1$
151 		} catch (MalformedURLException e) {
152 			throw new Error("Unexpected URL exception.", e); //$NON-NLS-1$
153 		}
154 	}
155 	/***
156 	 * Resolves given uri against this object. See <code>URI.resolve</code>
157 	 * for details.
158 	 * @param uri uri to resolve.
159 	 * @return resolved url
160 	 * @throws MalformedURLException if given uri is not a valid URI
161 	 * @throws URISyntaxException if given uri is not a valid URI
162 	 */
163 	public URL resolve(String uri) throws MalformedURLException,
164 			URISyntaxException {
165 		uri = uri.replaceAll("%", "%25"); //$NON-NLS-1$ //$NON-NLS-2$
166 		uri = uri.replaceAll(" ", "%20"); //$NON-NLS-1$ //$NON-NLS-2$
167 		return resolve(new URI(uri));
168 	}
169 	/***
170 	 * Resolves given uri against this object. See <code>URI.resolve</code>
171 	 * for details.
172 	 * @param uri uri to resolve.
173 	 * @return resolved url
174 	 * @throws MalformedURLException if given uri is not a valid URI
175 	 */
176 	public URL resolve(URI uri) throws MalformedURLException {
177 		return new URL(this.uri.resolve(uri).toString());
178 	}
179 	/***
180 	 * Resolves given uri against this object. See <code>URI.resolve</code>
181 	 * for details.
182 	 * @param uri uri to resolve. Must be a directory.
183 	 * @return resolved url
184 	 * @throws MalformedURLException if given uri is not a valid URI
185 	 * @throws URISyntaxException if given uri is not a valid URI
186 	 */
187 	public URLDir resolveDir(String uri) throws MalformedURLException,
188 			URISyntaxException {
189 		return new URLDir(resolve(uri));
190 	}
191 	/*
192 	 * (non-Javadoc)
193 	 * @see java.lang.Object#toString()
194 	 */
195 	@Override
196 	public String toString() {
197 		return url.toString();
198 	}
199 	/***
200 	 * From given URL creates an URI instance.
201 	 * @param url this string will be converted to URI object.
202 	 * @return URI object, representing given url.
203 	 */
204 	public static URI toURI(URL url) {
205 		return URI.create(url.toString());
206 	}
207 	/***
208 	 * From given string creates an URL instance. It doesn't expect error, so
209 	 * <code>MalformedURLException</code> is thrown as an
210 	 * <code>IllegalArgumentException</code>.
211 	 * @param url this string will be converted to URL object.
212 	 * @return URL object, representing given url.
213 	 */
214 	public static URL createURL(String url) {
215 		try {
216 			return new URL(url);
217 		} catch (MalformedURLException ex) {
218 			throw new IllegalArgumentException(ex.getMessage());
219 		}
220 	}
221 	/***
222 	 * Returns this instance as URI.
223 	 * @return URI representation.
224 	 */
225 	public URI getURI() {
226 		return uri;
227 	}
228 	/***
229 	 * Returns this instance as URL.
230 	 * @return URL representation.
231 	 */
232 	public URL getURL() {
233 		return url;
234 	}
235 	/***
236 	 * Returns the last path part from given url, without the query and fragment
237 	 * parts.
238 	 * @param url
239 	 * @return the file name, or <code>null</code> if none can be obtained.
240 	 */
241 	public static String getFileName(String url) {
242 		int lastSlash = url.lastIndexOf('/');
243 		if (lastSlash >= 0)
244 			url = url.substring(lastSlash + 1);
245 		int first = url.indexOf('?');
246 		if (first < 0)
247 			first = url.indexOf('#');
248 		if (first >= 0)
249 			url = url.substring(0, first);
250 		return StringUtils.defaultIfEmpty(url, null);
251 	}
252 }