1 | /*
|
---|
2 | * Copyright 2003-2005 The Apache Software Foundation
|
---|
3 | *
|
---|
4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
---|
5 | * you may not use this file except in compliance with the License.
|
---|
6 | * You may obtain a copy of the License at
|
---|
7 | *
|
---|
8 | * http://www.apache.org/licenses/LICENSE-2.0
|
---|
9 | *
|
---|
10 | * Unless required by applicable law or agreed to in writing, software
|
---|
11 | * distributed under the License is distributed on an "AS IS" BASIS,
|
---|
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
---|
13 | * See the License for the specific language governing permissions and
|
---|
14 | * limitations under the License.
|
---|
15 | *
|
---|
16 | */
|
---|
17 | package org.apache.tools.ant.launch;
|
---|
18 |
|
---|
19 | import java.net.MalformedURLException;
|
---|
20 |
|
---|
21 | import java.net.URL;
|
---|
22 | import java.io.File;
|
---|
23 | import java.io.FilenameFilter;
|
---|
24 | import java.text.CharacterIterator;
|
---|
25 | import java.text.StringCharacterIterator;
|
---|
26 | import java.util.Locale;
|
---|
27 |
|
---|
28 | /**
|
---|
29 | * The Locator is a utility class which is used to find certain items
|
---|
30 | * in the environment
|
---|
31 | *
|
---|
32 | * @since Ant 1.6
|
---|
33 | */
|
---|
34 | public final class Locator {
|
---|
35 | /**
|
---|
36 | * Not instantiable
|
---|
37 | */
|
---|
38 | private Locator() {
|
---|
39 | }
|
---|
40 |
|
---|
41 | /**
|
---|
42 | * Find the directory or jar file the class has been loaded from.
|
---|
43 | *
|
---|
44 | * @param c the class whose location is required.
|
---|
45 | * @return the file or jar with the class or null if we cannot
|
---|
46 | * determine the location.
|
---|
47 | *
|
---|
48 | * @since Ant 1.6
|
---|
49 | */
|
---|
50 | public static File getClassSource(Class c) {
|
---|
51 | String classResource = c.getName().replace('.', '/') + ".class";
|
---|
52 | return getResourceSource(c.getClassLoader(), classResource);
|
---|
53 | }
|
---|
54 |
|
---|
55 | /**
|
---|
56 | * Find the directory or jar a give resource has been loaded from.
|
---|
57 | *
|
---|
58 | * @param c the classloader to be consulted for the source
|
---|
59 | * @param resource the resource whose location is required.
|
---|
60 | *
|
---|
61 | * @return the file with the resource source or null if
|
---|
62 | * we cannot determine the location.
|
---|
63 | *
|
---|
64 | * @since Ant 1.6
|
---|
65 | */
|
---|
66 | public static File getResourceSource(ClassLoader c, String resource) {
|
---|
67 | if (c == null) {
|
---|
68 | c = Locator.class.getClassLoader();
|
---|
69 | }
|
---|
70 |
|
---|
71 | URL url = null;
|
---|
72 | if (c == null) {
|
---|
73 | url = ClassLoader.getSystemResource(resource);
|
---|
74 | } else {
|
---|
75 | url = c.getResource(resource);
|
---|
76 | }
|
---|
77 | if (url != null) {
|
---|
78 | String u = url.toString();
|
---|
79 | if (u.startsWith("jar:file:")) {
|
---|
80 | int pling = u.indexOf("!");
|
---|
81 | String jarName = u.substring(4, pling);
|
---|
82 | return new File(fromURI(jarName));
|
---|
83 | } else if (u.startsWith("file:")) {
|
---|
84 | int tail = u.indexOf(resource);
|
---|
85 | String dirName = u.substring(0, tail);
|
---|
86 | return new File(fromURI(dirName));
|
---|
87 | }
|
---|
88 | }
|
---|
89 | return null;
|
---|
90 | }
|
---|
91 |
|
---|
92 | /**
|
---|
93 | * Constructs a file path from a <code>file:</code> URI.
|
---|
94 | *
|
---|
95 | * <p>Will be an absolute path if the given URI is absolute.</p>
|
---|
96 | *
|
---|
97 | * <p>Swallows '%' that are not followed by two characters,
|
---|
98 | * doesn't deal with non-ASCII characters.</p>
|
---|
99 | *
|
---|
100 | * @param uri the URI designating a file in the local filesystem.
|
---|
101 | * @return the local file system path for the file.
|
---|
102 | * @since Ant 1.6
|
---|
103 | */
|
---|
104 | public static String fromURI(String uri) {
|
---|
105 | URL url = null;
|
---|
106 | try {
|
---|
107 | url = new URL(uri);
|
---|
108 | } catch (MalformedURLException emYouEarlEx) {
|
---|
109 | }
|
---|
110 | if (url == null || !("file".equals(url.getProtocol()))) {
|
---|
111 | throw new IllegalArgumentException("Can only handle valid file: URIs");
|
---|
112 | }
|
---|
113 | StringBuffer buf = new StringBuffer(url.getHost());
|
---|
114 | if (buf.length() > 0) {
|
---|
115 | buf.insert(0, File.separatorChar).insert(0, File.separatorChar);
|
---|
116 | }
|
---|
117 |
|
---|
118 | String file = url.getFile();
|
---|
119 | int queryPos = file.indexOf('?');
|
---|
120 | buf.append((queryPos < 0) ? file : file.substring(0, queryPos));
|
---|
121 |
|
---|
122 | uri = buf.toString().replace('/', File.separatorChar);
|
---|
123 |
|
---|
124 | if (File.pathSeparatorChar == ';' && uri.startsWith("\\") && uri.length() > 2
|
---|
125 | && Character.isLetter(uri.charAt(1)) && uri.lastIndexOf(':') > -1) {
|
---|
126 | uri = uri.substring(1);
|
---|
127 | }
|
---|
128 |
|
---|
129 | String path = decodeUri(uri);
|
---|
130 | return path;
|
---|
131 | }
|
---|
132 |
|
---|
133 | /**
|
---|
134 | * Decodes an Uri with % characters.
|
---|
135 | * @param uri String with the uri possibly containing % characters.
|
---|
136 | * @return The decoded Uri
|
---|
137 | */
|
---|
138 | private static String decodeUri(String uri) {
|
---|
139 | if (uri.indexOf('%') == -1)
|
---|
140 | {
|
---|
141 | return uri;
|
---|
142 | }
|
---|
143 | StringBuffer sb = new StringBuffer();
|
---|
144 | CharacterIterator iter = new StringCharacterIterator(uri);
|
---|
145 | for (char c = iter.first(); c != CharacterIterator.DONE;
|
---|
146 | c = iter.next()) {
|
---|
147 | if (c == '%') {
|
---|
148 | char c1 = iter.next();
|
---|
149 | if (c1 != CharacterIterator.DONE) {
|
---|
150 | int i1 = Character.digit(c1, 16);
|
---|
151 | char c2 = iter.next();
|
---|
152 | if (c2 != CharacterIterator.DONE) {
|
---|
153 | int i2 = Character.digit(c2, 16);
|
---|
154 | sb.append((char) ((i1 << 4) + i2));
|
---|
155 | }
|
---|
156 | }
|
---|
157 | } else {
|
---|
158 | sb.append(c);
|
---|
159 | }
|
---|
160 | }
|
---|
161 | String path = sb.toString();
|
---|
162 | return path;
|
---|
163 | }
|
---|
164 |
|
---|
165 | /**
|
---|
166 | * Get the File necessary to load the Sun compiler tools. If the classes
|
---|
167 | * are available to this class, then no additional URL is required and
|
---|
168 | * null is returned. This may be because the classes are explicitly in the
|
---|
169 | * class path or provided by the JVM directly
|
---|
170 | *
|
---|
171 | * @return the tools jar as a File if required, null otherwise
|
---|
172 | */
|
---|
173 | public static File getToolsJar() {
|
---|
174 | // firstly check if the tools jar is already in the classpath
|
---|
175 | boolean toolsJarAvailable = false;
|
---|
176 |
|
---|
177 | try {
|
---|
178 | // just check whether this throws an exception
|
---|
179 | Class.forName("com.sun.tools.javac.Main");
|
---|
180 | toolsJarAvailable = true;
|
---|
181 | } catch (Exception e) {
|
---|
182 | try {
|
---|
183 | Class.forName("sun.tools.javac.Main");
|
---|
184 | toolsJarAvailable = true;
|
---|
185 | } catch (Exception e2) {
|
---|
186 | // ignore
|
---|
187 | }
|
---|
188 | }
|
---|
189 |
|
---|
190 | if (toolsJarAvailable) {
|
---|
191 | return null;
|
---|
192 | }
|
---|
193 |
|
---|
194 | // couldn't find compiler - try to find tools.jar
|
---|
195 | // based on java.home setting
|
---|
196 | String javaHome = System.getProperty("java.home");
|
---|
197 | if (javaHome.toLowerCase(Locale.US).endsWith("jre")) {
|
---|
198 | javaHome = javaHome.substring(0, javaHome.length() - 4);
|
---|
199 | }
|
---|
200 | File toolsJar = new File(javaHome + "/lib/tools.jar");
|
---|
201 | if (!toolsJar.exists()) {
|
---|
202 | System.out.println("Unable to locate tools.jar. "
|
---|
203 | + "Expected to find it in " + toolsJar.getPath());
|
---|
204 | return null;
|
---|
205 | }
|
---|
206 | return toolsJar;
|
---|
207 | }
|
---|
208 |
|
---|
209 | /**
|
---|
210 | * Get an array or URLs representing all of the jar files in the
|
---|
211 | * given location. If the location is a file, it is returned as the only
|
---|
212 | * element of the array. If the location is a directory, it is scanned for
|
---|
213 | * jar files
|
---|
214 | *
|
---|
215 | * @param location the location to scan for Jars
|
---|
216 | *
|
---|
217 | * @return an array of URLs for all jars in the given location.
|
---|
218 | *
|
---|
219 | * @exception MalformedURLException if the URLs for the jars cannot be
|
---|
220 | * formed
|
---|
221 | */
|
---|
222 | public static URL[] getLocationURLs(File location)
|
---|
223 | throws MalformedURLException {
|
---|
224 | return getLocationURLs(location, new String[]{".jar"});
|
---|
225 | }
|
---|
226 |
|
---|
227 | /**
|
---|
228 | * Get an array or URLs representing all of the files of a given set of
|
---|
229 | * extensions in the given location. If the location is a file, it is
|
---|
230 | * returned as the only element of the array. If the location is a
|
---|
231 | * directory, it is scanned for matching files
|
---|
232 | *
|
---|
233 | * @param location the location to scan for files
|
---|
234 | * @param extensions an array of extension that are to match in the
|
---|
235 | * directory search
|
---|
236 | *
|
---|
237 | * @return an array of URLs of matching files
|
---|
238 | * @exception MalformedURLException if the URLs for the files cannot be
|
---|
239 | * formed
|
---|
240 | */
|
---|
241 | public static URL[] getLocationURLs(File location,
|
---|
242 | final String[] extensions)
|
---|
243 | throws MalformedURLException {
|
---|
244 | URL[] urls = new URL[0];
|
---|
245 |
|
---|
246 | if (!location.exists()) {
|
---|
247 | return urls;
|
---|
248 | }
|
---|
249 |
|
---|
250 | if (!location.isDirectory()) {
|
---|
251 | urls = new URL[1];
|
---|
252 | String path = location.getPath();
|
---|
253 | for (int i = 0; i < extensions.length; ++i) {
|
---|
254 | if (path.toLowerCase().endsWith(extensions[i])) {
|
---|
255 | urls[0] = location.toURL();
|
---|
256 | break;
|
---|
257 | }
|
---|
258 | }
|
---|
259 | return urls;
|
---|
260 | }
|
---|
261 |
|
---|
262 | File[] matches = location.listFiles(
|
---|
263 | new FilenameFilter() {
|
---|
264 | public boolean accept(File dir, String name) {
|
---|
265 | for (int i = 0; i < extensions.length; ++i) {
|
---|
266 | if (name.toLowerCase().endsWith(extensions[i])) {
|
---|
267 | return true;
|
---|
268 | }
|
---|
269 | }
|
---|
270 | return false;
|
---|
271 | }
|
---|
272 | });
|
---|
273 |
|
---|
274 | urls = new URL[matches.length];
|
---|
275 | for (int i = 0; i < matches.length; ++i) {
|
---|
276 | urls[i] = matches[i].toURL();
|
---|
277 | }
|
---|
278 | return urls;
|
---|
279 | }
|
---|
280 | }
|
---|
281 |
|
---|