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. 57 VersionHelper12() { 58 } 59 60 public Class<?> loadClass(String className) throws ClassNotFoundException { 61 return loadClass(className, getContextClassLoader()); 62 } 63 64 /** 65 * Package private. 66 * 67 * This internal method is used with Thread Context Class Loader (TCCL), 68 * please don't expose this method as public. 69 */ 70 Class<?> loadClass(String className, ClassLoader cl) 71 throws ClassNotFoundException { 72 Class<?> cls = Class.forName(className, true, cl); 73 return cls; 74 } 75 76 /** 77 * @param className A non-null fully qualified class name. 78 * @param codebase A non-null, space-separated list of URL strings. 79 */ 80 public Class<?> loadClass(String className, String codebase) 81 throws ClassNotFoundException, MalformedURLException { 82 83 ClassLoader parent = getContextClassLoader(); 84 ClassLoader cl = 85 URLClassLoader.newInstance(getUrlArray(codebase), parent); 86 87 return loadClass(className, cl); 88 } 89 90 String getJndiProperty(final int i) { 91 return AccessController.doPrivileged( 92 new PrivilegedAction<String>() { 93 public String run() { 94 try { 95 return System.getProperty(PROPS[i]); 96 } catch (SecurityException e) { 97 return null; 98 } 99 } 100 } 101 ); 102 } 103 104 String[] getJndiProperties() { 105 Properties sysProps = AccessController.doPrivileged( 106 new PrivilegedAction<Properties>() { 107 public Properties run() { 108 try { 109 return System.getProperties(); 110 } catch (SecurityException e) { 111 return null; 112 } 113 } 114 } 115 ); 116 if (sysProps == null) { 117 return null; 118 } 119 String[] jProps = new String[PROPS.length]; 120 for (int i = 0; i < PROPS.length; i++) { 121 jProps[i] = sysProps.getProperty(PROPS[i]); 122 } 123 return jProps; 124 } 125 126 InputStream getResourceAsStream(final Class<?> c, final String name) { 127 return AccessController.doPrivileged( 128 new PrivilegedAction<InputStream>() { 129 public InputStream run() { 130 return c.getResourceAsStream(name); 131 } 132 } 133 ); 134 } 135 136 InputStream getJavaHomeLibStream(final String filename) { 137 return AccessController.doPrivileged( 138 new PrivilegedAction<InputStream>() { 139 public InputStream run() { 140 try { 141 String javahome = System.getProperty("java.home"); 142 if (javahome == null) { 143 return null; 144 } 145 String pathname = javahome + java.io.File.separator + 146 "lib" + java.io.File.separator + filename; 147 return new java.io.FileInputStream(pathname); 148 } catch (Exception e) { 149 return null; 150 } 151 } 152 } 153 ); 154 } 155 156 NamingEnumeration<InputStream> getResources(final ClassLoader cl, 157 final String name) throws IOException { 158 Enumeration<URL> urls; 159 try { 160 urls = AccessController.doPrivileged( 161 new PrivilegedExceptionAction<Enumeration<URL>>() { 162 public Enumeration<URL> run() throws IOException { 163 return (cl == null) 164 ? ClassLoader.getSystemResources(name) 165 : cl.getResources(name); 166 } 167 } 168 ); 169 } catch (PrivilegedActionException e) { 170 throw (IOException)e.getException(); 171 } 172 return new InputStreamEnumeration(urls); 173 } 174 175 /** 176 * Package private. 177 * 178 * This internal method returns Thread Context Class Loader (TCCL), 179 * if null, returns the system Class Loader. 180 * 181 * Please don't expose this method as public. 182 */ 183 ClassLoader getContextClassLoader() { 184 185 return AccessController.doPrivileged( 186 new PrivilegedAction<ClassLoader>() { 187 public ClassLoader run() { 188 ClassLoader loader = 189 Thread.currentThread().getContextClassLoader(); 190 if (loader == null) { 191 // Don't use bootstrap class loader directly! 192 loader = ClassLoader.getSystemClassLoader(); 193 } 194 195 return loader; 196 } 197 } 198 ); 199 } 200 201 /** 202 * Given an enumeration of URLs, an instance of this class represents 203 * an enumeration of their InputStreams. Each operation on the URL 204 * enumeration is performed within a doPrivileged block. 205 * This is used to enumerate the resources under a foreign codebase. 206 * This class is not MT-safe. 207 */ 208 class InputStreamEnumeration implements NamingEnumeration<InputStream> { 209 210 private final Enumeration<URL> urls; 211 212 private InputStream nextElement = null; 213 214 InputStreamEnumeration(Enumeration<URL> urls) { 215 this.urls = urls; 216 } 217 218 /* 219 * Returns the next InputStream, or null if there are no more. 220 * An InputStream that cannot be opened is skipped. 221 */ 222 private InputStream getNextElement() { 223 return AccessController.doPrivileged( 224 new PrivilegedAction<InputStream>() { 225 public InputStream run() { 226 while (urls.hasMoreElements()) { 227 try { 228 return urls.nextElement().openStream(); 229 } catch (IOException e) { 230 // skip this URL 231 } 232 } 233 return null; 234 } 235 } 236 ); 237 } 238 239 public boolean hasMore() { 240 if (nextElement != null) { 241 return true; 242 } 243 nextElement = getNextElement(); 244 return (nextElement != null); 245 } 246 247 public boolean hasMoreElements() { 248 return hasMore(); 249 } 250 251 public InputStream next() { 252 if (hasMore()) { 253 InputStream res = nextElement; 254 nextElement = null; 255 return res; 256 } else { 257 throw new NoSuchElementException(); 258 } 259 } 260 261 public InputStream nextElement() { 262 return next(); 263 } 264 265 public void close() { 266 } 267 } 268 }