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.URL; 32 import java.util.StringTokenizer; 33 import java.util.Vector; 34 35 import javax.naming.NamingEnumeration; 36 37 /** 38 * VersionHelper was used by JNDI to accommodate differences between 39 * JDK 1.1.x and the Java 2 platform. As this is no longer necessary 40 * since JNDI's inclusion in the platform, this class currently 41 * serves as a set of utilities for performing system-level things, 42 * such as class-loading and reading system properties. 43 * 44 * @author Rosanna Lee 45 * @author Scott Seligman 46 */ 47 48 public abstract class VersionHelper { 49 private static VersionHelper helper = null; 50 51 final static String[] PROPS = new String[] { 52 javax.naming.Context.INITIAL_CONTEXT_FACTORY, 53 javax.naming.Context.OBJECT_FACTORIES, 54 javax.naming.Context.URL_PKG_PREFIXES, 55 javax.naming.Context.STATE_FACTORIES, 56 javax.naming.Context.PROVIDER_URL, 57 javax.naming.Context.DNS_URL, 58 // The following shouldn't create a runtime dependence on ldap package. 59 javax.naming.ldap.LdapContext.CONTROL_FACTORIES 60 }; 61 62 public final static int INITIAL_CONTEXT_FACTORY = 0; 63 public final static int OBJECT_FACTORIES = 1; 64 public final static int URL_PKG_PREFIXES = 2; 65 public final static int STATE_FACTORIES = 3; 66 public final static int PROVIDER_URL = 4; 67 public final static int DNS_URL = 5; 68 public final static int CONTROL_FACTORIES = 6; 69 70 VersionHelper() {} // Disallow anyone from creating one of these. 71 72 static { 73 helper = new VersionHelper12(); 74 } 75 76 public static VersionHelper getVersionHelper() { 77 return helper; 78 } 79 80 public abstract Class<?> loadClass(String className) 81 throws ClassNotFoundException; 82 83 abstract Class<?> loadClass(String className, ClassLoader cl) 84 throws ClassNotFoundException; 85 86 public abstract Class<?> loadClass(String className, String codebase) 87 throws ClassNotFoundException, MalformedURLException; 88 89 /* 90 * Returns a JNDI property from the system properties. Returns 91 * null if the property is not set, or if there is no permission 92 * to read it. 93 */ 94 abstract String getJndiProperty(int i); 95 96 /* 97 * Reads each property in PROPS from the system properties, and 98 * returns their values -- in order -- in an array. For each 99 * unset property, the corresponding array element is set to null. 100 * Returns null if there is no permission to call System.getProperties(). 101 */ 102 abstract String[] getJndiProperties(); 103 104 /* 105 * Returns the resource of a given name associated with a particular 106 * class (never null), or null if none can be found. 107 */ 108 abstract InputStream getResourceAsStream(Class<?> c, String name); 109 110 /* 111 * Returns an input stream for a file in <java.home>/lib, 112 * or null if it cannot be located or opened. 113 * 114 * @param filename The file name, sans directory. 115 */ 116 abstract InputStream getJavaHomeLibStream(String filename); 117 118 /* 119 * Returns an enumeration (never null) of InputStreams of the 120 * resources of a given name associated with a particular class 121 * loader. Null represents the bootstrap class loader in some 122 * Java implementations. 123 */ 124 abstract NamingEnumeration<InputStream> getResources( 125 ClassLoader cl, String name) 126 throws IOException; 127 128 /* 129 * Returns the context class loader associated with the current thread. 130 * Null indicates the bootstrap class loader in some Java implementations. 131 * 132 * @throws SecurityException if the class loader is not accessible. 133 */ 134 abstract ClassLoader getContextClassLoader(); 135 136 static protected URL[] getUrlArray(String codebase) 137 throws MalformedURLException { 138 // Parse codebase into separate URLs 139 StringTokenizer parser = new StringTokenizer(codebase); 140 Vector<String> vec = new Vector<>(10); 141 while (parser.hasMoreTokens()) { 142 vec.addElement(parser.nextToken()); 143 } 144 String[] url = new String[vec.size()]; 145 for (int i = 0; i < url.length; i++) { 146 url[i] = vec.elementAt(i); 147 } 148 149 URL[] urlArray = new URL[url.length]; 150 for (int i = 0; i < urlArray.length; i++) { 151 urlArray[i] = new URL(url[i]); 152 } 153 return urlArray; 154 } 155 } | 1 /* 2 * Copyright (c) 1999, 2014, 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.io.File; 31 import java.io.FileInputStream; 32 import java.net.MalformedURLException; 33 import java.net.URL; 34 import java.util.StringTokenizer; 35 import java.util.Vector; 36 import java.util.NoSuchElementException; 37 import java.util.Enumeration; 38 import java.util.Properties; 39 import java.net.URLClassLoader; 40 import java.security.AccessController; 41 import java.security.PrivilegedAction; 42 import java.security.PrivilegedActionException; 43 import java.security.PrivilegedExceptionAction; 44 45 import javax.naming.NamingEnumeration; 46 47 /** 48 * VersionHelper was used by JNDI to accommodate differences between 49 * JDK 1.1.x and the Java 2 platform. As this is no longer necessary 50 * since JNDI's inclusion in the platform, this class currently 51 * serves as a set of utilities for performing system-level things, 52 * such as class-loading and reading system properties. 53 * 54 * @author Rosanna Lee 55 * @author Scott Seligman 56 */ 57 58 public final class VersionHelper { 59 private static VersionHelper helper = new VersionHelper(); 60 61 final static String[] PROPS = new String[]{ 62 javax.naming.Context.INITIAL_CONTEXT_FACTORY, 63 javax.naming.Context.OBJECT_FACTORIES, 64 javax.naming.Context.URL_PKG_PREFIXES, 65 javax.naming.Context.STATE_FACTORIES, 66 javax.naming.Context.PROVIDER_URL, 67 javax.naming.Context.DNS_URL, 68 // The following shouldn't create a runtime dependence on ldap package. 69 javax.naming.ldap.LdapContext.CONTROL_FACTORIES 70 }; 71 72 public final static int INITIAL_CONTEXT_FACTORY = 0; 73 public final static int OBJECT_FACTORIES = 1; 74 public final static int URL_PKG_PREFIXES = 2; 75 public final static int STATE_FACTORIES = 3; 76 public final static int PROVIDER_URL = 4; 77 public final static int DNS_URL = 5; 78 public final static int CONTROL_FACTORIES = 6; 79 80 VersionHelper() {} // Disallow anyone from creating one of these. 81 82 public static VersionHelper getVersionHelper() { 83 return helper; 84 } 85 86 public Class<?> loadClass(String className) 87 throws ClassNotFoundException { 88 return loadClass(className, getContextClassLoader()); 89 } 90 91 /** 92 * Package private. 93 * <p> 94 * This internal method is used with Thread Context Class Loader (TCCL), 95 * please don't expose this method as public. 96 */ 97 Class<?> loadClass(String className, ClassLoader cl) 98 throws ClassNotFoundException { 99 Class<?> cls = Class.forName(className, true, cl); 100 return cls; 101 } 102 103 /** 104 * @param className A non-null fully qualified class name. 105 * @param codebase A non-null, space-separated list of URL strings. 106 */ 107 public Class<?> loadClass(String className, String codebase) 108 throws ClassNotFoundException, MalformedURLException { 109 ClassLoader parent = getContextClassLoader(); 110 ClassLoader cl = 111 URLClassLoader.newInstance(getUrlArray(codebase), parent); 112 return loadClass(className, cl); 113 } 114 115 /* 116 * Returns a JNDI property from the system properties. Returns 117 * null if the property is not set, or if there is no permission 118 * to read it. 119 */ 120 String getJndiProperty(int i) { 121 PrivilegedAction<String> act = () -> { 122 try { 123 return System.getProperty(PROPS[i]); 124 } catch (SecurityException e) { 125 return null; 126 } 127 }; 128 return AccessController.doPrivileged(act); 129 } 130 131 /* 132 * Reads each property in PROPS from the system properties, and 133 * returns their values -- in order -- in an array. For each 134 * unset property, the corresponding array element is set to null. 135 * Returns null if there is no permission to call System.getProperties(). 136 */ 137 String[] getJndiProperties() { 138 PrivilegedAction<Properties> act = () -> { 139 try { 140 return System.getProperties(); 141 } catch (SecurityException e) { 142 return null; 143 } 144 }; 145 Properties sysProps = AccessController.doPrivileged(act); 146 if (sysProps == null) { 147 return null; 148 } 149 String[] jProps = new String[PROPS.length]; 150 for (int i = 0; i < PROPS.length; i++) { 151 jProps[i] = sysProps.getProperty(PROPS[i]); 152 } 153 return jProps; 154 } 155 156 /* 157 * Returns the resource of a given name associated with a particular 158 * class (never null), or null if none can be found. 159 */ 160 InputStream getResourceAsStream(Class<?> c, String name) { 161 PrivilegedAction<InputStream> act = () -> c.getResourceAsStream(name); 162 return AccessController.doPrivileged(act); 163 } 164 165 /* 166 * Returns an input stream for a file in <java.home>/lib, 167 * or null if it cannot be located or opened. 168 * 169 * @param filename The file name, sans directory. 170 */ 171 InputStream getJavaHomeLibStream(String filename) { 172 PrivilegedAction<InputStream> act = () -> { 173 try { 174 String javahome = System.getProperty("java.home"); 175 if (javahome == null) { 176 return null; 177 } 178 String pathname = javahome + File.separator + 179 "lib" + File.separator + filename; 180 return new FileInputStream(pathname); 181 } catch (Exception e) { 182 return null; 183 } 184 }; 185 return AccessController.doPrivileged(act); 186 } 187 188 /* 189 * Returns an enumeration (never null) of InputStreams of the 190 * resources of a given name associated with a particular class 191 * loader. Null represents the bootstrap class loader in some 192 * Java implementations. 193 */ 194 NamingEnumeration<InputStream> getResources( 195 ClassLoader cl, String name) 196 throws IOException { 197 Enumeration<URL> urls; 198 PrivilegedExceptionAction<Enumeration<URL>> act = () -> 199 (cl == null) 200 ? ClassLoader.getSystemResources(name) 201 : cl.getResources(name); 202 try { 203 urls = AccessController.doPrivileged(act); 204 } catch (PrivilegedActionException e) { 205 throw (IOException) e.getException(); 206 } 207 return new InputStreamEnumeration(urls); 208 } 209 210 /* 211 * Package private. 212 * <p> 213 * This internal method returns Thread Context Class Loader (TCCL), 214 * if null, returns the system Class Loader. 215 * <p> 216 * Please don't expose this method as public. 217 * @throws SecurityException if the class loader is not accessible. 218 */ 219 ClassLoader getContextClassLoader() { 220 221 PrivilegedAction<ClassLoader> act = () -> { 222 ClassLoader loader = Thread.currentThread().getContextClassLoader(); 223 if (loader == null) { 224 // Don't use bootstrap class loader directly! 225 loader = ClassLoader.getSystemClassLoader(); 226 } 227 return loader; 228 }; 229 return AccessController.doPrivileged(act); 230 } 231 232 static protected URL[] getUrlArray(String codebase) 233 throws MalformedURLException { 234 // Parse codebase into separate URLs 235 StringTokenizer parser = new StringTokenizer(codebase); 236 Vector<String> vec = new Vector<>(10); 237 while (parser.hasMoreTokens()) { 238 vec.addElement(parser.nextToken()); 239 } 240 String[] url = new String[vec.size()]; 241 for (int i = 0; i < url.length; i++) { 242 url[i] = vec.elementAt(i); 243 } 244 245 URL[] urlArray = new URL[url.length]; 246 for (int i = 0; i < urlArray.length; i++) { 247 urlArray[i] = new URL(url[i]); 248 } 249 return urlArray; 250 } 251 252 /** 253 * Given an enumeration of URLs, an instance of this class represents 254 * an enumeration of their InputStreams. Each operation on the URL 255 * enumeration is performed within a doPrivileged block. 256 * This is used to enumerate the resources under a foreign codebase. 257 * This class is not MT-safe. 258 */ 259 private class InputStreamEnumeration implements 260 NamingEnumeration<InputStream> { 261 262 private final Enumeration<URL> urls; 263 264 private InputStream nextElement; 265 266 InputStreamEnumeration(Enumeration<URL> urls) { 267 this.urls = urls; 268 } 269 270 /* 271 * Returns the next InputStream, or null if there are no more. 272 * An InputStream that cannot be opened is skipped. 273 */ 274 private InputStream getNextElement() { 275 PrivilegedAction<InputStream> act = () -> { 276 while (urls.hasMoreElements()) { 277 try { 278 return urls.nextElement().openStream(); 279 } catch (IOException e) { 280 // skip this URL 281 } 282 } 283 return null; 284 }; 285 return AccessController.doPrivileged(act); 286 } 287 288 public boolean hasMore() { 289 if (nextElement != null) { 290 return true; 291 } 292 nextElement = getNextElement(); 293 return (nextElement != null); 294 } 295 296 public boolean hasMoreElements() { 297 return hasMore(); 298 } 299 300 public InputStream next() { 301 if (hasMore()) { 302 InputStream res = nextElement; 303 nextElement = null; 304 return res; 305 } else { 306 throw new NoSuchElementException(); 307 } 308 } 309 310 public InputStream nextElement() { 311 return next(); 312 } 313 314 public void close() { 315 } 316 } 317 } |