View Javadoc
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 net.logAnalyzer;
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