| Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
| Locator |
|
| 5.846153846153846;5.846 | ||||
| Locator$1 |
|
| 5.846153846153846;5.846 |
| 1 | /* | |
| 2 | * Licensed to the Apache Software Foundation (ASF) under one or more | |
| 3 | * contributor license agreements. See the NOTICE file distributed with | |
| 4 | * this work for additional information regarding copyright ownership. | |
| 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 | |
| 6 | * (the "License"); you may not use this file except in compliance with | |
| 7 | * the License. You may obtain a copy of the License at | |
| 8 | * | |
| 9 | * http://www.apache.org/licenses/LICENSE-2.0 | |
| 10 | * | |
| 11 | * Unless required by applicable law or agreed to in writing, software | |
| 12 | * distributed under the License is distributed on an "AS IS" BASIS, | |
| 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 14 | * See the License for the specific language governing permissions and | |
| 15 | * limitations under the License. | |
| 16 | * | |
| 17 | */ | |
| 18 | package org.owasp.dependencycheck.org.apache.tools.ant.launch; | |
| 19 | ||
| 20 | import java.net.MalformedURLException; | |
| 21 | import java.net.URL; | |
| 22 | import java.io.File; | |
| 23 | import java.io.FilenameFilter; | |
| 24 | import java.io.ByteArrayOutputStream; | |
| 25 | import java.io.UnsupportedEncodingException; | |
| 26 | import java.text.CharacterIterator; | |
| 27 | import java.text.StringCharacterIterator; | |
| 28 | import java.util.Locale; | |
| 29 | ||
| 30 | import org.owasp.dependencycheck.org.apache.tools.ant.util.FileUtils; | |
| 31 | ||
| 32 | // CheckStyle:LineLengthCheck OFF - urls are long! | |
| 33 | /** | |
| 34 | * The Locator is a utility class which is used to find certain items | |
| 35 | * in the environment. | |
| 36 | * | |
| 37 | * It is used at boot time in the launcher, and cannot make use of any of Ant's other classes. | |
| 38 | * | |
| 39 | * This is a surprisingly brittle piece of code, and has had lots of bugs filed against it. | |
| 40 | * {@link <a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=42275">running ant off a network share can cause Ant to fail</a>} | |
| 41 | * {@link <a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=8031">use File.toURI().toURL().toExternalForm()</a>} | |
| 42 | * {@link <a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=42222">Locator implementation not encoding URI strings properly: spaces in paths</a>} | |
| 43 | * It also breaks Eclipse 3.3 Betas | |
| 44 | * {@link <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=183283">Exception if installation path has spaces</a>} | |
| 45 | * | |
| 46 | * Be very careful when making changes to this class, as a break will upset a lot of people. | |
| 47 | * @since Ant 1.6 | |
| 48 | */ | |
| 49 | // CheckStyle:LineLengthCheck ON - urls are long! | |
| 50 | public final class Locator { | |
| 51 | ||
| 52 | private static final int NIBBLE = 4; | |
| 53 | private static final int NIBBLE_MASK = 0xF; | |
| 54 | ||
| 55 | private static final int ASCII_SIZE = 128; | |
| 56 | ||
| 57 | private static final int BYTE_SIZE = 256; | |
| 58 | ||
| 59 | private static final int WORD = 16; | |
| 60 | ||
| 61 | private static final int SPACE = 0x20; | |
| 62 | private static final int DEL = 0x7F; | |
| 63 | ||
| 64 | /** | |
| 65 | * encoding used to represent URIs | |
| 66 | */ | |
| 67 | public static final String URI_ENCODING = "UTF-8"; | |
| 68 | // stolen from org.apache.xerces.impl.XMLEntityManager#getUserDir() | |
| 69 | // of the Xerces-J team | |
| 70 | // which ASCII characters need to be escaped | |
| 71 | 0 | private static boolean[] gNeedEscaping = new boolean[ASCII_SIZE]; |
| 72 | // the first hex character if a character needs to be escaped | |
| 73 | 0 | private static char[] gAfterEscaping1 = new char[ASCII_SIZE]; |
| 74 | // the second hex character if a character needs to be escaped | |
| 75 | 0 | private static char[] gAfterEscaping2 = new char[ASCII_SIZE]; |
| 76 | 0 | private static char[] gHexChs = {'0', '1', '2', '3', '4', '5', '6', '7', |
| 77 | '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; | |
| 78 | /** Error string used when an invalid uri is seen */ | |
| 79 | public static final String ERROR_NOT_FILE_URI | |
| 80 | = "Can only handle valid file: URIs, not "; | |
| 81 | ||
| 82 | // initialize the above 3 arrays | |
| 83 | static { | |
| 84 | 0 | for (int i = 0; i < SPACE; i++) { |
| 85 | 0 | gNeedEscaping[i] = true; |
| 86 | 0 | gAfterEscaping1[i] = gHexChs[i >> NIBBLE]; |
| 87 | 0 | gAfterEscaping2[i] = gHexChs[i & NIBBLE_MASK]; |
| 88 | } | |
| 89 | 0 | gNeedEscaping[DEL] = true; |
| 90 | 0 | gAfterEscaping1[DEL] = '7'; |
| 91 | 0 | gAfterEscaping2[DEL] = 'F'; |
| 92 | 0 | char[] escChs = {' ', '<', '>', '#', '%', '"', '{', '}', |
| 93 | '|', '\\', '^', '~', '[', ']', '`'}; | |
| 94 | 0 | int len = escChs.length; |
| 95 | char ch; | |
| 96 | 0 | for (int i = 0; i < len; i++) { |
| 97 | 0 | ch = escChs[i]; |
| 98 | 0 | gNeedEscaping[ch] = true; |
| 99 | 0 | gAfterEscaping1[ch] = gHexChs[ch >> NIBBLE]; |
| 100 | 0 | gAfterEscaping2[ch] = gHexChs[ch & NIBBLE_MASK]; |
| 101 | } | |
| 102 | 0 | } |
| 103 | /** | |
| 104 | * Not instantiable | |
| 105 | */ | |
| 106 | 0 | private Locator() { |
| 107 | 0 | } |
| 108 | ||
| 109 | /** | |
| 110 | * Find the directory or jar file the class has been loaded from. | |
| 111 | * | |
| 112 | * @param c the class whose location is required. | |
| 113 | * @return the file or jar with the class or null if we cannot | |
| 114 | * determine the location. | |
| 115 | * | |
| 116 | * @since Ant 1.6 | |
| 117 | */ | |
| 118 | public static File getClassSource(Class<?> c) { | |
| 119 | 0 | String classResource = c.getName().replace('.', '/') + ".class"; |
| 120 | 0 | return getResourceSource(c.getClassLoader(), classResource); |
| 121 | } | |
| 122 | ||
| 123 | /** | |
| 124 | * Find the directory or jar a given resource has been loaded from. | |
| 125 | * | |
| 126 | * @param c the classloader to be consulted for the source. | |
| 127 | * @param resource the resource whose location is required. | |
| 128 | * | |
| 129 | * @return the file with the resource source or null if | |
| 130 | * we cannot determine the location. | |
| 131 | * | |
| 132 | * @since Ant 1.6 | |
| 133 | */ | |
| 134 | public static File getResourceSource(ClassLoader c, String resource) { | |
| 135 | 0 | if (c == null) { |
| 136 | 0 | c = Locator.class.getClassLoader(); |
| 137 | } | |
| 138 | 0 | URL url = null; |
| 139 | 0 | if (c == null) { |
| 140 | 0 | url = ClassLoader.getSystemResource(resource); |
| 141 | } else { | |
| 142 | 0 | url = c.getResource(resource); |
| 143 | } | |
| 144 | 0 | if (url != null) { |
| 145 | 0 | String u = url.toString(); |
| 146 | try { | |
| 147 | 0 | if (u.startsWith("jar:file:")) { |
| 148 | 0 | return new File(fromJarURI(u)); |
| 149 | 0 | } else if (u.startsWith("file:")) { |
| 150 | 0 | int tail = u.indexOf(resource); |
| 151 | 0 | String dirName = u.substring(0, tail); |
| 152 | 0 | return new File(fromURI(dirName)); |
| 153 | } | |
| 154 | 0 | } catch (IllegalArgumentException e) { |
| 155 | //unable to determine the URI for reasons unknown. | |
| 156 | 0 | return null; |
| 157 | 0 | } |
| 158 | } | |
| 159 | 0 | return null; |
| 160 | } | |
| 161 | ||
| 162 | ||
| 163 | ||
| 164 | /** | |
| 165 | * Constructs a file path from a <code>file:</code> URI. | |
| 166 | * | |
| 167 | * <p>Will be an absolute path if the given URI is absolute.</p> | |
| 168 | * | |
| 169 | * <p>Prior to Java 1.4,<!-- TODO is JDK version actually relevant? --> | |
| 170 | * swallows '%' that are not followed by two characters.</p> | |
| 171 | * | |
| 172 | * See <a href="http://www.w3.org/TR/xml11/#dt-sysid">dt-sysid</a> | |
| 173 | * which makes some mention of how | |
| 174 | * characters not supported by URI Reference syntax should be escaped. | |
| 175 | * | |
| 176 | * @param uri the URI designating a file in the local filesystem. | |
| 177 | * @return the local file system path for the file. | |
| 178 | * @throws IllegalArgumentException if the URI is malformed or not a legal file: URL | |
| 179 | * @since Ant 1.6 | |
| 180 | */ | |
| 181 | public static String fromURI(String uri) { | |
| 182 | 0 | return fromURIJava13(uri); |
| 183 | // #buzilla8031: first try Java 1.4. | |
| 184 | // TODO should use java.net.URI now that we can rely on 1.4... | |
| 185 | // but check for UNC-related regressions, e.g. #42275 | |
| 186 | // (and remember that \\server\share\file -> file:////server/share/file | |
| 187 | // rather than -> file://server/share/file as it should; | |
| 188 | // fixed only in JDK 7's java.nio.file.Path.toUri) | |
| 189 | // return fromUriJava14(uri); | |
| 190 | } | |
| 191 | ||
| 192 | /** | |
| 193 | * Java1.4+ code to extract the path from the URI. | |
| 194 | * @param uri | |
| 195 | * @return null if a conversion was not possible | |
| 196 | */ | |
| 197 | /* currently unused: | |
| 198 | private static String fromUriJava14(String uri) { | |
| 199 | // Also check for properly formed URIs. Ant formerly recommended using | |
| 200 | // nonsense URIs such as "file:./foo.xml" in XML includes. You shouldn't | |
| 201 | // do that (just "foo.xml" is correct) but for compatibility we special-case | |
| 202 | // things when the path is not absolute, and fall back to the old parsing behavior. | |
| 203 | if (uri.startsWith("file:/")) { | |
| 204 | try { | |
| 205 | File f = new File(URI.create(encodeURI(uri))); | |
| 206 | //bug #42227 forgot to decode before returning | |
| 207 | return decodeUri(f.getAbsolutePath()); | |
| 208 | } catch (IllegalArgumentException e) { | |
| 209 | // Bad URI, pass this on. | |
| 210 | // no, this is downgraded to a warning after various | |
| 211 | // JRE bugs surfaced. Hand off | |
| 212 | // to our built in code on a failure | |
| 213 | //throw new IllegalArgumentException( | |
| 214 | // "Bad URI " + uri + ":" + e.getMessage(), e); | |
| 215 | e.printStackTrace(); | |
| 216 | } catch (Exception e) { | |
| 217 | // Unexpected exception? Should not happen. | |
| 218 | e.printStackTrace(); | |
| 219 | } | |
| 220 | } | |
| 221 | return null; | |
| 222 | } | |
| 223 | */ | |
| 224 | ||
| 225 | /** | |
| 226 | * @param uri uri to expand | |
| 227 | * @return the decoded URI | |
| 228 | * @since Ant1.7.1 | |
| 229 | */ | |
| 230 | private static String fromURIJava13(String uri) { | |
| 231 | // Fallback method for Java 1.3 or earlier. | |
| 232 | ||
| 233 | 0 | URL url = null; |
| 234 | try { | |
| 235 | 0 | url = new URL(uri); |
| 236 | 0 | } catch (MalformedURLException emYouEarlEx) { |
| 237 | // Ignore malformed exception | |
| 238 | 0 | } |
| 239 | 0 | if (url == null || !("file".equals(url.getProtocol()))) { |
| 240 | 0 | throw new IllegalArgumentException(ERROR_NOT_FILE_URI + uri); |
| 241 | } | |
| 242 | 0 | StringBuffer buf = new StringBuffer(url.getHost()); |
| 243 | 0 | if (buf.length() > 0) { |
| 244 | 0 | buf.insert(0, File.separatorChar).insert(0, File.separatorChar); |
| 245 | } | |
| 246 | 0 | String file = url.getFile(); |
| 247 | 0 | int queryPos = file.indexOf('?'); |
| 248 | 0 | buf.append((queryPos < 0) ? file : file.substring(0, queryPos)); |
| 249 | ||
| 250 | 0 | uri = buf.toString().replace('/', File.separatorChar); |
| 251 | ||
| 252 | 0 | if (File.pathSeparatorChar == ';' && uri.startsWith("\\") && uri.length() > 2 |
| 253 | && Character.isLetter(uri.charAt(1)) && uri.lastIndexOf(':') > -1) { | |
| 254 | 0 | uri = uri.substring(1); |
| 255 | } | |
| 256 | 0 | String path = null; |
| 257 | try { | |
| 258 | 0 | path = decodeUri(uri); |
| 259 | //consider adding the current directory. This is not done when | |
| 260 | //the path is a UNC name | |
| 261 | 0 | String cwd = System.getProperty("user.dir"); |
| 262 | 0 | int posi = cwd.indexOf(':'); |
| 263 | 0 | boolean pathStartsWithFileSeparator = path.startsWith(File.separator); |
| 264 | 0 | boolean pathStartsWithUNC = path.startsWith("" + File.separator + File.separator); |
| 265 | 0 | if ((posi > 0) && pathStartsWithFileSeparator && !pathStartsWithUNC) { |
| 266 | 0 | path = cwd.substring(0, posi + 1) + path; |
| 267 | } | |
| 268 | 0 | } catch (UnsupportedEncodingException exc) { |
| 269 | // not sure whether this is clean, but this method is | |
| 270 | // declared not to throw exceptions. | |
| 271 | 0 | throw new IllegalStateException( |
| 272 | "Could not convert URI " + uri + " to path: " | |
| 273 | + exc.getMessage()); | |
| 274 | 0 | } |
| 275 | 0 | return path; |
| 276 | } | |
| 277 | ||
| 278 | /** | |
| 279 | * Crack a JAR URI. | |
| 280 | * This method is public for testing; we may delete it without any warning -it is not part of Ant's stable API. | |
| 281 | * @param uri uri to expand; contains jar: somewhere in it | |
| 282 | * @return the decoded URI | |
| 283 | * @since Ant1.7.1 | |
| 284 | */ | |
| 285 | public static String fromJarURI(String uri) { | |
| 286 | 0 | int pling = uri.indexOf("!/"); |
| 287 | 0 | String jarName = uri.substring("jar:".length(), pling); |
| 288 | 0 | return fromURI(jarName); |
| 289 | } | |
| 290 | ||
| 291 | /** | |
| 292 | * Decodes an Uri with % characters. | |
| 293 | * The URI is escaped | |
| 294 | * @param uri String with the uri possibly containing % characters. | |
| 295 | * @return The decoded Uri | |
| 296 | * @throws UnsupportedEncodingException if UTF-8 is not available | |
| 297 | * @since Ant 1.7 | |
| 298 | */ | |
| 299 | public static String decodeUri(String uri) throws UnsupportedEncodingException { | |
| 300 | 0 | if (uri.indexOf('%') == -1) { |
| 301 | 0 | return uri; |
| 302 | } | |
| 303 | 0 | ByteArrayOutputStream sb = new ByteArrayOutputStream(uri.length()); |
| 304 | 0 | CharacterIterator iter = new StringCharacterIterator(uri); |
| 305 | 0 | for (char c = iter.first(); c != CharacterIterator.DONE; |
| 306 | 0 | c = iter.next()) { |
| 307 | 0 | if (c == '%') { |
| 308 | 0 | char c1 = iter.next(); |
| 309 | 0 | if (c1 != CharacterIterator.DONE) { |
| 310 | 0 | int i1 = Character.digit(c1, WORD); |
| 311 | 0 | char c2 = iter.next(); |
| 312 | 0 | if (c2 != CharacterIterator.DONE) { |
| 313 | 0 | int i2 = Character.digit(c2, WORD); |
| 314 | 0 | sb.write((char) ((i1 << NIBBLE) + i2)); |
| 315 | } | |
| 316 | } | |
| 317 | 0 | } else if (c >= 0x0000 && c < 0x0080) { |
| 318 | 0 | sb.write(c); |
| 319 | } else { // #50543 | |
| 320 | 0 | byte[] bytes = String.valueOf(c).getBytes(URI_ENCODING); |
| 321 | 0 | sb.write(bytes, 0, bytes.length); |
| 322 | } | |
| 323 | } | |
| 324 | 0 | return sb.toString(URI_ENCODING); |
| 325 | } | |
| 326 | ||
| 327 | /** | |
| 328 | * Encodes an Uri with % characters. | |
| 329 | * The URI is escaped | |
| 330 | * @param path String to encode. | |
| 331 | * @return The encoded string, according to URI norms | |
| 332 | * @throws UnsupportedEncodingException if UTF-8 is not available | |
| 333 | * @since Ant 1.7 | |
| 334 | */ | |
| 335 | public static String encodeURI(String path) throws UnsupportedEncodingException { | |
| 336 | 0 | int i = 0; |
| 337 | 0 | int len = path.length(); |
| 338 | 0 | int ch = 0; |
| 339 | 0 | StringBuffer sb = null; |
| 340 | 0 | for (; i < len; i++) { |
| 341 | 0 | ch = path.charAt(i); |
| 342 | // if it's not an ASCII character, break here, and use UTF-8 encoding | |
| 343 | 0 | if (ch >= ASCII_SIZE) { |
| 344 | 0 | break; |
| 345 | } | |
| 346 | 0 | if (gNeedEscaping[ch]) { |
| 347 | 0 | if (sb == null) { |
| 348 | 0 | sb = new StringBuffer(path.substring(0, i)); |
| 349 | } | |
| 350 | 0 | sb.append('%'); |
| 351 | 0 | sb.append(gAfterEscaping1[ch]); |
| 352 | 0 | sb.append(gAfterEscaping2[ch]); |
| 353 | // record the fact that it's escaped | |
| 354 | 0 | } else if (sb != null) { |
| 355 | 0 | sb.append((char) ch); |
| 356 | } | |
| 357 | } | |
| 358 | ||
| 359 | // we saw some non-ascii character | |
| 360 | 0 | if (i < len) { |
| 361 | 0 | if (sb == null) { |
| 362 | 0 | sb = new StringBuffer(path.substring(0, i)); |
| 363 | } | |
| 364 | // get UTF-8 bytes for the remaining sub-string | |
| 365 | 0 | byte[] bytes = null; |
| 366 | byte b; | |
| 367 | 0 | bytes = path.substring(i).getBytes(URI_ENCODING); |
| 368 | 0 | len = bytes.length; |
| 369 | ||
| 370 | // for each byte | |
| 371 | 0 | for (i = 0; i < len; i++) { |
| 372 | 0 | b = bytes[i]; |
| 373 | // for non-ascii character: make it positive, then escape | |
| 374 | 0 | if (b < 0) { |
| 375 | 0 | ch = b + BYTE_SIZE; |
| 376 | 0 | sb.append('%'); |
| 377 | 0 | sb.append(gHexChs[ch >> NIBBLE]); |
| 378 | 0 | sb.append(gHexChs[ch & NIBBLE_MASK]); |
| 379 | 0 | } else if (gNeedEscaping[b]) { |
| 380 | 0 | sb.append('%'); |
| 381 | 0 | sb.append(gAfterEscaping1[b]); |
| 382 | 0 | sb.append(gAfterEscaping2[b]); |
| 383 | } else { | |
| 384 | 0 | sb.append((char) b); |
| 385 | } | |
| 386 | } | |
| 387 | } | |
| 388 | 0 | return sb == null ? path : sb.toString(); |
| 389 | } | |
| 390 | ||
| 391 | /** | |
| 392 | * Convert a File to a URL. | |
| 393 | * File.toURL() does not encode characters like #. | |
| 394 | * File.toURI() has been introduced in java 1.4, so | |
| 395 | * Ant cannot use it (except by reflection) <!-- TODO no longer true --> | |
| 396 | * FileUtils.toURI() cannot be used by Locator.java | |
| 397 | * Implemented this way. | |
| 398 | * File.toURL() adds file: and changes '\' to '/' for dos OSes | |
| 399 | * encodeURI converts characters like ' ' and '#' to %DD | |
| 400 | * @param file the file to convert | |
| 401 | * @return URL the converted File | |
| 402 | * @throws MalformedURLException on error | |
| 403 | * @deprecated since 1.9, use {@link FileUtils#getFileURL(File)} | |
| 404 | */ | |
| 405 | @Deprecated | |
| 406 | public static URL fileToURL(File file) | |
| 407 | throws MalformedURLException { | |
| 408 | 0 | return new URL(file.toURI().toASCIIString()); |
| 409 | } | |
| 410 | ||
| 411 | /** | |
| 412 | * Get the File necessary to load the Sun compiler tools. If the classes | |
| 413 | * are available to this class, then no additional URL is required and | |
| 414 | * null is returned. This may be because the classes are explicitly in the | |
| 415 | * class path or provided by the JVM directly. | |
| 416 | * | |
| 417 | * @return the tools jar as a File if required, null otherwise. | |
| 418 | */ | |
| 419 | public static File getToolsJar() { | |
| 420 | // firstly check if the tools jar is already in the classpath | |
| 421 | 0 | boolean toolsJarAvailable = false; |
| 422 | try { | |
| 423 | // just check whether this throws an exception | |
| 424 | 0 | Class.forName("com.sun.tools.javac.Main"); |
| 425 | 0 | toolsJarAvailable = true; |
| 426 | 0 | } catch (Exception e) { |
| 427 | try { | |
| 428 | 0 | Class.forName("sun.tools.javac.Main"); |
| 429 | 0 | toolsJarAvailable = true; |
| 430 | 0 | } catch (Exception e2) { |
| 431 | // ignore | |
| 432 | 0 | } |
| 433 | 0 | } |
| 434 | 0 | if (toolsJarAvailable) { |
| 435 | 0 | return null; |
| 436 | } | |
| 437 | // couldn't find compiler - try to find tools.jar | |
| 438 | // based on java.home setting | |
| 439 | 0 | String libToolsJar |
| 440 | = File.separator + "lib" + File.separator + "tools.jar"; | |
| 441 | 0 | String javaHome = System.getProperty("java.home"); |
| 442 | 0 | File toolsJar = new File(javaHome + libToolsJar); |
| 443 | 0 | if (toolsJar.exists()) { |
| 444 | // Found in java.home as given | |
| 445 | 0 | return toolsJar; |
| 446 | } | |
| 447 | 0 | if (javaHome.toLowerCase(Locale.ENGLISH).endsWith(File.separator + "jre")) { |
| 448 | 0 | javaHome = javaHome.substring( |
| 449 | 0, javaHome.length() - "/jre".length()); | |
| 450 | 0 | toolsJar = new File(javaHome + libToolsJar); |
| 451 | } | |
| 452 | 0 | if (!toolsJar.exists()) { |
| 453 | 0 | System.out.println("Unable to locate tools.jar. " |
| 454 | + "Expected to find it in " + toolsJar.getPath()); | |
| 455 | 0 | return null; |
| 456 | } | |
| 457 | 0 | return toolsJar; |
| 458 | } | |
| 459 | ||
| 460 | /** | |
| 461 | * Get an array of URLs representing all of the jar files in the | |
| 462 | * given location. If the location is a file, it is returned as the only | |
| 463 | * element of the array. If the location is a directory, it is scanned for | |
| 464 | * jar files. | |
| 465 | * | |
| 466 | * @param location the location to scan for Jars. | |
| 467 | * | |
| 468 | * @return an array of URLs for all jars in the given location. | |
| 469 | * | |
| 470 | * @exception MalformedURLException if the URLs for the jars cannot be | |
| 471 | * formed. | |
| 472 | */ | |
| 473 | public static URL[] getLocationURLs(File location) | |
| 474 | throws MalformedURLException { | |
| 475 | 0 | return getLocationURLs(location, new String[]{".jar"}); |
| 476 | } | |
| 477 | ||
| 478 | /** | |
| 479 | * Get an array of URLs representing all of the files of a given set of | |
| 480 | * extensions in the given location. If the location is a file, it is | |
| 481 | * returned as the only element of the array. If the location is a | |
| 482 | * directory, it is scanned for matching files. | |
| 483 | * | |
| 484 | * @param location the location to scan for files. | |
| 485 | * @param extensions an array of extension that are to match in the | |
| 486 | * directory search. | |
| 487 | * | |
| 488 | * @return an array of URLs of matching files. | |
| 489 | * @exception MalformedURLException if the URLs for the files cannot be | |
| 490 | * formed. | |
| 491 | */ | |
| 492 | public static URL[] getLocationURLs(File location, | |
| 493 | final String[] extensions) | |
| 494 | throws MalformedURLException { | |
| 495 | 0 | URL[] urls = new URL[0]; |
| 496 | ||
| 497 | 0 | if (!location.exists()) { |
| 498 | 0 | return urls; |
| 499 | } | |
| 500 | 0 | if (!location.isDirectory()) { |
| 501 | 0 | urls = new URL[1]; |
| 502 | 0 | String path = location.getPath(); |
| 503 | 0 | String littlePath = path.toLowerCase(Locale.ENGLISH); |
| 504 | 0 | for (int i = 0; i < extensions.length; ++i) { |
| 505 | 0 | if (littlePath.endsWith(extensions[i])) { |
| 506 | 0 | urls[0] = fileToURL(location); |
| 507 | 0 | break; |
| 508 | } | |
| 509 | } | |
| 510 | 0 | return urls; |
| 511 | } | |
| 512 | 0 | File[] matches = location.listFiles( |
| 513 | 0 | new FilenameFilter() { |
| 514 | public boolean accept(File dir, String name) { | |
| 515 | 0 | String littleName = name.toLowerCase(Locale.ENGLISH); |
| 516 | 0 | for (int i = 0; i < extensions.length; ++i) { |
| 517 | 0 | if (littleName.endsWith(extensions[i])) { |
| 518 | 0 | return true; |
| 519 | } | |
| 520 | } | |
| 521 | 0 | return false; |
| 522 | } | |
| 523 | }); | |
| 524 | 0 | urls = new URL[matches.length]; |
| 525 | 0 | for (int i = 0; i < matches.length; ++i) { |
| 526 | 0 | urls[i] = fileToURL(matches[i]); |
| 527 | } | |
| 528 | 0 | return urls; |
| 529 | } | |
| 530 | } |