1 /* 2 * Copyright (c) 1999, 2011, 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.NoSuchElementException; 39 import java.util.Properties; 40 41 import javax.naming.*; 42 43 /** 44 * VersionHelper was used by JNDI to accommodate differences between 45 * JDK 1.1.x and the Java 2 platform. As this is no longer necessary 46 * since JNDI's inclusion in the platform, this class currently 47 * serves as a set of utilities for performing system-level things, 48 * such as class-loading and reading system properties. 49 * 50 * @author Rosanna Lee 51 * @author Scott Seligman 52 */ 53 54 final class VersionHelper12 extends VersionHelper { 55 56 // Disallow external from creating one of these. VersionHelper12()57 VersionHelper12() { 58 } 59 loadClass(String className)60 public Class<?> loadClass(String className) throws ClassNotFoundException { 61 return loadClass(className, getContextClassLoader()); 62 } 63 loadClassWithoutInit(String className)64 public Class<?> loadClassWithoutInit(String className) throws ClassNotFoundException { 65 return loadClass(className, false, getContextClassLoader()); 66 } 67 68 /** 69 * Determines whether classes may be loaded from an arbitrary URL code base. 70 */ 71 private static final String TRUST_URL_CODEBASE_PROPERTY = 72 "com.sun.jndi.ldap.object.trustURLCodebase"; 73 private static final String trustURLCodebase = 74 AccessController.doPrivileged( 75 new PrivilegedAction<String>() { 76 public String run() { 77 try { 78 return System.getProperty(TRUST_URL_CODEBASE_PROPERTY, 79 "false"); 80 } catch (SecurityException e) { 81 return "false"; 82 } 83 } 84 } 85 ); 86 87 /** 88 * Package private. 89 * 90 * This internal method is used with Thread Context Class Loader (TCCL), 91 * please don't expose this method as public. 92 */ loadClass(String className, boolean initialize, ClassLoader cl)93 Class<?> loadClass(String className, boolean initialize, ClassLoader cl) 94 throws ClassNotFoundException { 95 Class<?> cls = Class.forName(className, initialize, cl); 96 return cls; 97 } 98 loadClass(String className, ClassLoader cl)99 Class<?> loadClass(String className, ClassLoader cl) 100 throws ClassNotFoundException { 101 return loadClass(className, true, cl); 102 } 103 104 /** 105 * @param className A non-null fully qualified class name. 106 * @param codebase A non-null, space-separated list of URL strings. 107 */ loadClass(String className, String codebase)108 public Class<?> loadClass(String className, String codebase) 109 throws ClassNotFoundException, MalformedURLException { 110 if ("true".equalsIgnoreCase(trustURLCodebase)) { 111 ClassLoader parent = getContextClassLoader(); 112 ClassLoader cl = 113 URLClassLoader.newInstance(getUrlArray(codebase), parent); 114 115 return loadClass(className, cl); 116 } else { 117 return null; 118 } 119 } 120 getJndiProperty(final int i)121 String getJndiProperty(final int i) { 122 return AccessController.doPrivileged( 123 new PrivilegedAction<String>() { 124 public String run() { 125 try { 126 return System.getProperty(PROPS[i]); 127 } catch (SecurityException e) { 128 return null; 129 } 130 } 131 } 132 ); 133 } 134 135 String[] getJndiProperties() { 136 Properties sysProps = AccessController.doPrivileged( 137 new PrivilegedAction<Properties>() { 138 public Properties run() { 139 try { 140 return System.getProperties(); 141 } catch (SecurityException e) { 142 return null; 143 } 144 } 145 } 146 ); 147 if (sysProps == null) { 148 return null; 149 } 150 String[] jProps = new String[PROPS.length]; 151 for (int i = 0; i < PROPS.length; i++) { 152 jProps[i] = sysProps.getProperty(PROPS[i]); 153 } 154 return jProps; 155 } 156 157 InputStream getResourceAsStream(final Class<?> c, final String name) { 158 return AccessController.doPrivileged( 159 new PrivilegedAction<InputStream>() { 160 public InputStream run() { 161 return c.getResourceAsStream(name); 162 } 163 } 164 ); 165 } 166 167 InputStream getJavaHomeLibStream(final String filename) { 168 return AccessController.doPrivileged( 169 new PrivilegedAction<InputStream>() { 170 public InputStream run() { 171 try { 172 String javahome = System.getProperty("java.home"); 173 if (javahome == null) { 174 return null; 175 } 176 String pathname = javahome + java.io.File.separator + 177 "lib" + java.io.File.separator + filename; 178 return new java.io.FileInputStream(pathname); 179 } catch (Exception e) { 180 return null; 181 } 182 } 183 } 184 ); 185 } 186 187 NamingEnumeration<InputStream> getResources(final ClassLoader cl, 188 final String name) throws IOException { 189 Enumeration<URL> urls; 190 try { 191 urls = AccessController.doPrivileged( 192 new PrivilegedExceptionAction<Enumeration<URL>>() { 193 public Enumeration<URL> run() throws IOException { 194 return (cl == null) 195 ? ClassLoader.getSystemResources(name) 196 : cl.getResources(name); 197 } 198 } 199 ); 200 } catch (PrivilegedActionException e) { 201 throw (IOException)e.getException(); 202 } 203 return new InputStreamEnumeration(urls); 204 } 205 206 /** 207 * Package private. 208 * 209 * This internal method returns Thread Context Class Loader (TCCL), 210 * if null, returns the system Class Loader. 211 * 212 * Please don't expose this method as public. 213 */ 214 ClassLoader getContextClassLoader() { 215 216 return AccessController.doPrivileged( 217 new PrivilegedAction<ClassLoader>() { 218 public ClassLoader run() { 219 ClassLoader loader = 220 Thread.currentThread().getContextClassLoader(); 221 if (loader == null) { 222 // Don't use bootstrap class loader directly! 223 loader = ClassLoader.getSystemClassLoader(); 224 } 225 226 return loader; 227 } 228 } 229 ); 230 } 231 232 /** 233 * Given an enumeration of URLs, an instance of this class represents 234 * an enumeration of their InputStreams. Each operation on the URL 235 * enumeration is performed within a doPrivileged block. 236 * This is used to enumerate the resources under a foreign codebase. 237 * This class is not MT-safe. 238 */ 239 class InputStreamEnumeration implements NamingEnumeration<InputStream> { 240 241 private final Enumeration<URL> urls; 242 243 private InputStream nextElement = null; 244 245 InputStreamEnumeration(Enumeration<URL> urls) { 246 this.urls = urls; 247 } 248 249 /* 250 * Returns the next InputStream, or null if there are no more. 251 * An InputStream that cannot be opened is skipped. 252 */ 253 private InputStream getNextElement() { 254 return AccessController.doPrivileged( 255 new PrivilegedAction<InputStream>() { 256 public InputStream run() { 257 while (urls.hasMoreElements()) { 258 try { 259 return urls.nextElement().openStream(); 260 } catch (IOException e) { 261 // skip this URL 262 } 263 } 264 return null; 265 } 266 } 267 ); 268 } 269 270 public boolean hasMore() { 271 if (nextElement != null) { 272 return true; 273 } 274 nextElement = getNextElement(); 275 return (nextElement != null); 276 } 277 278 public boolean hasMoreElements() { 279 return hasMore(); 280 } 281 282 public InputStream next() { 283 if (hasMore()) { 284 InputStream res = nextElement; 285 nextElement = null; 286 return res; 287 } else { 288 throw new NoSuchElementException(); 289 } 290 } 291 292 public InputStream nextElement() { 293 return next(); 294 } 295 296 public void close() { 297 } 298 } 299 } 300