1 /*
   2  * $Id$
   3  *
   4  * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
   5  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   6  *
   7  * This code is free software; you can redistribute it and/or modify it
   8  * under the terms of the GNU General Public License version 2 only, as
   9  * published by the Free Software Foundation.  Oracle designates this
  10  * particular file as subject to the "Classpath" exception as provided
  11  * by Oracle in the LICENSE file that accompanied this code.
  12  *
  13  * This code is distributed in the hope that it will be useful, but WITHOUT
  14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16  * version 2 for more details (a copy is included in the LICENSE file that
  17  * accompanied this code).
  18  *
  19  * You should have received a copy of the GNU General Public License version
  20  * 2 along with this work; if not, write to the Free Software Foundation,
  21  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  22  *
  23  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  24  * or visit www.oracle.com if you need additional information or have any
  25  * questions.
  26  */
  27 
  28 package com.sun.javatest;
  29 
  30 import java.io.File;
  31 import java.io.IOException;
  32 import java.io.InputStream;
  33 import java.net.MalformedURLException;
  34 import java.net.URL;
  35 import java.net.URLClassLoader;
  36 import java.security.AccessController;
  37 import java.security.PrivilegedAction;
  38 import java.util.Enumeration;
  39 import java.util.Locale;
  40 import java.util.ResourceBundle;
  41 import java.util.StringTokenizer;
  42 import java.util.Vector;
  43 
  44 import com.sun.javatest.util.DynamicArray;
  45 
  46 public class ResourceLoader {
  47 
  48     public static Enumeration<URL> getResources(String name, Class<?> ownClass) throws IOException  {
  49         URL extResource = getExtResource(name, null);
  50         if (extResource != null) {
  51             Vector<URL> r = new Vector<>();
  52             r.add(extResource);
  53             return r.elements();
  54         }
  55         return ownClass.getClassLoader().getResources(name);
  56     }
  57 
  58     public static InputStream getResourceAsStream(final String name, final Class<?> ownClass) {
  59         URL url = getExtResource(name, ownClass);
  60         try {
  61             if (url != null) {
  62                 return url.openStream();
  63             } else {
  64                 InputStream is = AccessController.doPrivileged(
  65                         new PrivilegedAction<InputStream>() {
  66                             @Override
  67                             public InputStream run() {
  68                                 return ownClass.getResourceAsStream(name);
  69                             }
  70                         });
  71                 return is;
  72             }
  73         } catch (IOException e) {
  74             return null;
  75         }
  76     }
  77 
  78     public static File getResourceFile(String name, Class<?> ownClass) {
  79         File f = getExtResourceFile(name, ownClass);
  80         if (f != null) {
  81             return f;
  82         } else {
  83             return new File(ownClass.getResource(name).getFile());
  84         }
  85     }
  86 
  87     public static URL getExtUrl(File filename) {
  88         URL url;
  89         File f = filename;
  90         try {
  91             if (!f.isAbsolute()) {
  92                 f = new File(ResourceLoader.getExt().getAbsoluteFile(),
  93                             filename.getPath());
  94             }
  95 
  96             url = f.toURI().toURL();
  97         } catch (MalformedURLException e2) {
  98             url = null;
  99         }   // catch
 100 
 101         return url;
 102     }
 103 
 104     private static URL getExtResource(String name, Class<?> ownClass) {
 105         URL ret = null;
 106         File rf = getExtResourceFile(name, ownClass);
 107         if (rf != null) {
 108             try {
 109                 ret = rf.toURI().toURL();
 110             } catch (MalformedURLException ex) {
 111                 // it's ok
 112             }
 113         }
 114         return ret;
 115     }
 116 
 117     private static File getExtResourceFile(String name, Class<?> ownClass) {
 118         if (ext != null) {
 119             String relName;
 120             if (ownClass == null) {
 121                 relName = name;
 122             } else {
 123                 relName = resolveName(name, ownClass);
 124             }
 125 
 126             File resFile = new File(getExt(), relName);
 127             if (resFile.exists()) {
 128                 return resFile;
 129             }
 130         }
 131         return null;
 132     }
 133 
 134 
 135     // get from java.lang.Class with minimal changes
 136     private static String resolveName(String name, Class<?> baseClass) {
 137         if (name == null || baseClass == null) {
 138             return name;
 139         }
 140 
 141         if (!name.startsWith("/")) {
 142             String baseName = baseClass.getName();
 143             int index = baseName.lastIndexOf('.');
 144             if (index != -1) {
 145                 name = baseName.substring(0, index).replace('.', '/')
 146                     +"/"+name;
 147             }
 148         } else {
 149             name = name.substring(1);
 150         }
 151         return name;
 152     }
 153 
 154     private static final String EXT_DIR_NAME = "jtExt";
 155     private static File ext = null;
 156 
 157     static {
 158         String jcp = System.getProperty("java.class.path");
 159         String psep = System.getProperty("path.separator");
 160         File altRoot = null;
 161         if (jcp != null && psep != null) {
 162             StringTokenizer tokenizer = new StringTokenizer(jcp, psep);
 163             while (tokenizer.hasMoreTokens()) {
 164                 // component is javatest.jar (or similar jar) or
 165                 // build/classes in case of netbeans project
 166                 File component = new File(tokenizer.nextToken());
 167                 if (component.exists()) {
 168                     if (component.isDirectory()) {
 169                         altRoot = component;
 170                     } else {
 171                         altRoot = component.getParentFile();
 172                     }
 173                     File extTmp = new File(altRoot, EXT_DIR_NAME);
 174                     if (extTmp.exists()) {
 175                         ext = extTmp;
 176                         break;
 177                     }
 178                 }
 179             }
 180         }
 181     }
 182 
 183     static File getExt() {
 184         return ext;
 185     }
 186 
 187     static void setExt(File aExt) {
 188         ext = aExt;
 189     }
 190 
 191     public static ResourceBundle getBundle(String name, Locale aDefault, ClassLoader classLoader) {
 192         if (ext != null) {
 193             initAltClassLoader();
 194             ResourceBundle altB = getSBundle(name, aDefault, altClassLoader);
 195             if (altB.getKeys().hasMoreElements()) {
 196                 return altB;
 197             }
 198         }
 199         return getSBundle(name, aDefault, classLoader);
 200     }
 201 
 202     public static ResourceBundle getBundle(String name) {
 203         if (ext != null) {
 204             initAltClassLoader();
 205             ResourceBundle altB = getSBundle(name, Locale.getDefault(), altClassLoader);
 206             if (altB.getKeys().hasMoreElements()) {
 207                 return altB;
 208             }
 209         }
 210         return getSBundle(name, Locale.getDefault(), ResourceLoader.class.getClassLoader());
 211     }
 212 
 213     private static ResourceBundle getSBundle(final String name, final Locale locale, final ClassLoader cl) {
 214         ResourceBundle bundle = AccessController.doPrivileged(
 215                 new PrivilegedAction<ResourceBundle>() {
 216                     public ResourceBundle run() {
 217                         return ResourceBundle.getBundle(name, locale, cl);
 218                     }
 219                 });
 220         return bundle;
 221     }
 222 
 223     private static ClassLoader altClassLoader;
 224 
 225     private synchronized static void initAltClassLoader() {
 226         if (ext != null && altClassLoader == null) {
 227             try {
 228                 altClassLoader = new URLClassLoader(new URL[]{ext.toURI().toURL()});
 229             } catch (MalformedURLException ex) {
 230                 // nothing
 231             }
 232         }
 233     }
 234 
 235 
 236 }