1 /*
   2  * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.naming.internal;
  27 
  28 import java.io.InputStream;
  29 import java.io.IOException;
  30 import java.net.MalformedURLException;
  31 import java.net.URLClassLoader;
  32 import java.net.URL;
  33 import java.security.AccessController;
  34 import java.security.PrivilegedAction;
  35 import java.security.PrivilegedActionException;
  36 import java.security.PrivilegedExceptionAction;
  37 import java.util.Enumeration;
  38 import java.util.Hashtable;
  39 import java.util.NoSuchElementException;
  40 import java.util.Properties;
  41 
  42 import javax.naming.*;
  43 
  44 /**
  45  * VersionHelper was used by JNDI to accommodate differences between
  46  * JDK 1.1.x and the Java 2 platform. As this is no longer necessary
  47  * since JNDI's inclusion in the platform, this class currently
  48  * serves as a set of utilities for performing system-level things,
  49  * such as class-loading and reading system properties.
  50  *
  51  * @author Rosanna Lee
  52  * @author Scott Seligman
  53  */
  54 
  55 final class VersionHelper12 extends VersionHelper {
  56 
  57     private boolean getSystemPropsFailed = false;
  58 
  59     VersionHelper12() {} // Disallow external from creating one of these.
  60 
  61     public Class loadClass(String className) throws ClassNotFoundException {
  62         ClassLoader cl = getContextClassLoader();
  63         return Class.forName(className, true, cl);
  64     }
  65 
  66     /**
  67       * Package private.
  68       */
  69     Class loadClass(String className, ClassLoader cl)
  70         throws ClassNotFoundException {
  71         return Class.forName(className, true, cl);
  72     }
  73 
  74     /**
  75      * @param className A non-null fully qualified class name.
  76      * @param codebase A non-null, space-separated list of URL strings.
  77      */
  78     public Class loadClass(String className, String codebase)
  79         throws ClassNotFoundException, MalformedURLException {
  80         ClassLoader cl;
  81 
  82         ClassLoader parent = getContextClassLoader();
  83         cl = URLClassLoader.newInstance(getUrlArray(codebase), parent);
  84 
  85         return Class.forName(className, true, cl);
  86     }
  87 
  88     String getJndiProperty(final int i) {
  89         return (String) AccessController.doPrivileged(
  90             new PrivilegedAction() {
  91                 public Object run() {
  92                     try {
  93                         return System.getProperty(PROPS[i]);
  94                     } catch (SecurityException e) {
  95                         return null;
  96                     }
  97                 }
  98             }
  99         );
 100     }
 101 
 102     String[] getJndiProperties() {
 103         if (getSystemPropsFailed) {
 104             return null;        // after one failure, don't bother trying again
 105         }
 106         Properties sysProps = (Properties) AccessController.doPrivileged(
 107             new PrivilegedAction() {
 108                 public Object run() {
 109                     try {
 110                         return System.getProperties();
 111                     } catch (SecurityException e) {
 112                         getSystemPropsFailed = true;
 113                         return null;
 114                     }
 115                 }
 116             }
 117         );
 118         if (sysProps == null) {
 119             return null;
 120         }
 121         String[] jProps = new String[PROPS.length];
 122         for (int i = 0; i < PROPS.length; i++) {
 123             jProps[i] = sysProps.getProperty(PROPS[i]);
 124         }
 125         return jProps;
 126     }
 127 
 128     InputStream getResourceAsStream(final Class c, final String name) {
 129         return (InputStream) AccessController.doPrivileged(
 130             new PrivilegedAction() {
 131                 public Object run() {
 132                     return c.getResourceAsStream(name);
 133                 }
 134             }
 135         );
 136     }
 137 
 138     InputStream getJavaHomeLibStream(final String filename) {
 139         return (InputStream) AccessController.doPrivileged(
 140             new PrivilegedAction() {
 141                 public Object run() {
 142                     try {
 143                         String javahome = System.getProperty("java.home");
 144                         if (javahome == null) {
 145                             return null;
 146                         }
 147                         String pathname = javahome + java.io.File.separator +
 148                             "lib" + java.io.File.separator + filename;
 149                         return new java.io.FileInputStream(pathname);
 150                     } catch (Exception e) {
 151                         return null;
 152                     }
 153                 }
 154             }
 155         );
 156     }
 157 
 158     NamingEnumeration getResources(final ClassLoader cl, final String name)
 159             throws IOException
 160     {
 161         Enumeration urls;
 162         try {
 163             urls = (Enumeration) AccessController.doPrivileged(
 164                 new PrivilegedExceptionAction() {
 165                     public Object run() throws IOException {
 166                         return (cl == null)
 167                             ? ClassLoader.getSystemResources(name)
 168                             : cl.getResources(name);
 169                     }
 170                 }
 171             );
 172         } catch (PrivilegedActionException e) {
 173             throw (IOException)e.getException();
 174         }
 175         return new InputStreamEnumeration(urls);
 176     }
 177 
 178     ClassLoader getContextClassLoader() {
 179         return (ClassLoader) AccessController.doPrivileged(
 180             new PrivilegedAction() {
 181                 public Object run() {
 182                     return Thread.currentThread().getContextClassLoader();
 183                 }
 184             }
 185         );
 186     }
 187 
 188 
 189     /**
 190      * Given an enumeration of URLs, an instance of this class represents
 191      * an enumeration of their InputStreams.  Each operation on the URL
 192      * enumeration is performed within a doPrivileged block.
 193      * This is used to enumerate the resources under a foreign codebase.
 194      * This class is not MT-safe.
 195      */
 196     class InputStreamEnumeration implements NamingEnumeration {
 197 
 198         private final Enumeration urls;
 199 
 200         private Object nextElement = null;
 201 
 202         InputStreamEnumeration(Enumeration urls) {
 203             this.urls = urls;
 204         }
 205 
 206         /*
 207          * Returns the next InputStream, or null if there are no more.
 208          * An InputStream that cannot be opened is skipped.
 209          */
 210         private Object getNextElement() {
 211             return AccessController.doPrivileged(
 212                 new PrivilegedAction() {
 213                     public Object run() {
 214                         while (urls.hasMoreElements()) {
 215                             try {
 216                                 return ((URL)urls.nextElement()).openStream();
 217                             } catch (IOException e) {
 218                                 // skip this URL
 219                             }
 220                         }
 221                         return null;
 222                     }
 223                 }
 224             );
 225         }
 226 
 227         public boolean hasMore() {
 228             if (nextElement != null) {
 229                 return true;
 230             }
 231             nextElement = getNextElement();
 232             return (nextElement != null);
 233         }
 234 
 235         public boolean hasMoreElements() {
 236             return hasMore();
 237         }
 238 
 239         public Object next() {
 240             if (hasMore()) {
 241                 Object res = nextElement;
 242                 nextElement = null;
 243                 return res;
 244             } else {
 245                 throw new NoSuchElementException();
 246             }
 247         }
 248 
 249         public Object nextElement() {
 250             return next();
 251         }
 252 
 253         public void close() {
 254         }
 255     }
 256 }