mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8290368: Introduce LDAP and RMI protocol-specific object factory filters to JNDI implementation
Reviewed-by: dfuchs, rriggs, jpai
This commit is contained in:
parent
21aeb9e794
commit
d37ce4cdd1
22 changed files with 1263 additions and 355 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -25,13 +25,13 @@
|
|||
|
||||
package javax.naming.spi;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.*;
|
||||
|
||||
import javax.naming.*;
|
||||
|
||||
import com.sun.naming.internal.NamingManagerHelper;
|
||||
import com.sun.naming.internal.ObjectFactoriesFilter;
|
||||
import com.sun.naming.internal.VersionHelper;
|
||||
import com.sun.naming.internal.ResourceManager;
|
||||
|
@ -78,11 +78,6 @@ public class NamingManager {
|
|||
|
||||
// --------- object factory stuff
|
||||
|
||||
/**
|
||||
* Package-private; used by DirectoryManager and NamingManager.
|
||||
*/
|
||||
private static ObjectFactoryBuilder object_factory_builder = null;
|
||||
|
||||
private static final ClassLoaderValue<InitialContextFactory> FACTORIES_CACHE =
|
||||
new ClassLoaderValue<>();
|
||||
|
||||
|
@ -111,110 +106,16 @@ public class NamingManager {
|
|||
* @see ObjectFactoryBuilder
|
||||
* @see java.lang.SecurityManager#checkSetFactory
|
||||
*/
|
||||
public static synchronized void setObjectFactoryBuilder(
|
||||
public static void setObjectFactoryBuilder(
|
||||
ObjectFactoryBuilder builder) throws NamingException {
|
||||
if (object_factory_builder != null)
|
||||
throw new IllegalStateException("ObjectFactoryBuilder already set");
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
security.checkSetFactory();
|
||||
}
|
||||
object_factory_builder = builder;
|
||||
NamingManagerHelper.setObjectFactoryBuilder(builder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for accessing object factory builder.
|
||||
*/
|
||||
static synchronized ObjectFactoryBuilder getObjectFactoryBuilder() {
|
||||
return object_factory_builder;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the ObjectFactory for the object identified by a reference,
|
||||
* using the reference's factory class name and factory codebase
|
||||
* to load in the factory's class.
|
||||
* @param ref The non-null reference to use.
|
||||
* @param factoryName The non-null class name of the factory.
|
||||
* @return The object factory for the object identified by ref; null
|
||||
* if unable to load the factory.
|
||||
*/
|
||||
static ObjectFactory getObjectFactoryFromReference(
|
||||
Reference ref, String factoryName)
|
||||
throws IllegalAccessException,
|
||||
InstantiationException,
|
||||
MalformedURLException {
|
||||
Class<?> clas = null;
|
||||
|
||||
// Try to use current class loader
|
||||
try {
|
||||
clas = helper.loadClassWithoutInit(factoryName);
|
||||
// Validate factory's class with the objects factory serial filter
|
||||
if (!ObjectFactoriesFilter.canInstantiateObjectsFactory(clas)) {
|
||||
return null;
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
// ignore and continue
|
||||
// e.printStackTrace();
|
||||
}
|
||||
// All other exceptions are passed up.
|
||||
|
||||
// Not in class path; try to use codebase
|
||||
String codebase;
|
||||
if (clas == null &&
|
||||
(codebase = ref.getFactoryClassLocation()) != null) {
|
||||
try {
|
||||
clas = helper.loadClass(factoryName, codebase);
|
||||
// Validate factory's class with the objects factory serial filter
|
||||
if (clas == null ||
|
||||
!ObjectFactoriesFilter.canInstantiateObjectsFactory(clas)) {
|
||||
return null;
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation") // Class.newInstance
|
||||
ObjectFactory result = (clas != null) ? (ObjectFactory) clas.newInstance() : null;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates an object using the factories specified in the
|
||||
* {@code Context.OBJECT_FACTORIES} property of the environment
|
||||
* or of the provider resource file associated with {@code nameCtx}.
|
||||
*
|
||||
* @return factory created; null if cannot create
|
||||
*/
|
||||
private static Object createObjectFromFactories(Object obj, Name name,
|
||||
Context nameCtx, Hashtable<?,?> environment) throws Exception {
|
||||
|
||||
FactoryEnumeration factories = ResourceManager.getFactories(
|
||||
Context.OBJECT_FACTORIES, environment, nameCtx);
|
||||
|
||||
if (factories == null)
|
||||
return null;
|
||||
|
||||
// Try each factory until one succeeds
|
||||
ObjectFactory factory;
|
||||
Object answer = null;
|
||||
while (answer == null && factories.hasMore()) {
|
||||
factory = (ObjectFactory)factories.next();
|
||||
answer = factory.getObjectInstance(obj, name, nameCtx, environment);
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
private static String getURLScheme(String str) {
|
||||
int colon_posn = str.indexOf(':');
|
||||
int slash_posn = str.indexOf('/');
|
||||
|
||||
if (colon_posn > 0 && (slash_posn == -1 || colon_posn < slash_posn))
|
||||
return str.substring(0, colon_posn);
|
||||
return null;
|
||||
static ObjectFactoryBuilder getObjectFactoryBuilder() {
|
||||
return NamingManagerHelper.getObjectFactoryBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -308,124 +209,11 @@ public class NamingManager {
|
|||
public static Object
|
||||
getObjectInstance(Object refInfo, Name name, Context nameCtx,
|
||||
Hashtable<?,?> environment)
|
||||
throws Exception
|
||||
{
|
||||
|
||||
ObjectFactory factory;
|
||||
|
||||
// Use builder if installed
|
||||
ObjectFactoryBuilder builder = getObjectFactoryBuilder();
|
||||
if (builder != null) {
|
||||
// builder must return non-null factory
|
||||
factory = builder.createObjectFactory(refInfo, environment);
|
||||
return factory.getObjectInstance(refInfo, name, nameCtx,
|
||||
environment);
|
||||
}
|
||||
|
||||
// Use reference if possible
|
||||
Reference ref = null;
|
||||
if (refInfo instanceof Reference) {
|
||||
ref = (Reference) refInfo;
|
||||
} else if (refInfo instanceof Referenceable) {
|
||||
ref = ((Referenceable)(refInfo)).getReference();
|
||||
}
|
||||
|
||||
Object answer;
|
||||
|
||||
if (ref != null) {
|
||||
String f = ref.getFactoryClassName();
|
||||
if (f != null) {
|
||||
// if reference identifies a factory, use exclusively
|
||||
|
||||
factory = getObjectFactoryFromReference(ref, f);
|
||||
if (factory != null) {
|
||||
return factory.getObjectInstance(ref, name, nameCtx,
|
||||
environment);
|
||||
}
|
||||
// No factory found, so return original refInfo.
|
||||
// Will reach this point if factory class is not in
|
||||
// class path and reference does not contain a URL for it
|
||||
return refInfo;
|
||||
|
||||
} else {
|
||||
// if reference has no factory, check for addresses
|
||||
// containing URLs
|
||||
|
||||
answer = processURLAddrs(ref, name, nameCtx, environment);
|
||||
if (answer != null) {
|
||||
return answer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// try using any specified factories
|
||||
answer =
|
||||
createObjectFromFactories(refInfo, name, nameCtx, environment);
|
||||
return (answer != null) ? answer : refInfo;
|
||||
throws Exception {
|
||||
return NamingManagerHelper.getObjectInstance(refInfo, name, nameCtx,
|
||||
environment, ObjectFactoriesFilter::checkGlobalFilter);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ref has no factory. For each address of type "URL", try its URL
|
||||
* context factory. Returns null if unsuccessful in creating and
|
||||
* invoking a factory.
|
||||
*/
|
||||
static Object processURLAddrs(Reference ref, Name name, Context nameCtx,
|
||||
Hashtable<?,?> environment)
|
||||
throws NamingException {
|
||||
|
||||
for (int i = 0; i < ref.size(); i++) {
|
||||
RefAddr addr = ref.get(i);
|
||||
if (addr instanceof StringRefAddr &&
|
||||
addr.getType().equalsIgnoreCase("URL")) {
|
||||
|
||||
String url = (String)addr.getContent();
|
||||
Object answer = processURL(url, name, nameCtx, environment);
|
||||
if (answer != null) {
|
||||
return answer;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Object processURL(Object refInfo, Name name,
|
||||
Context nameCtx, Hashtable<?,?> environment)
|
||||
throws NamingException {
|
||||
Object answer;
|
||||
|
||||
// If refInfo is a URL string, try to use its URL context factory
|
||||
// If no context found, continue to try object factories.
|
||||
if (refInfo instanceof String) {
|
||||
String url = (String)refInfo;
|
||||
String scheme = getURLScheme(url);
|
||||
if (scheme != null) {
|
||||
answer = getURLObject(scheme, refInfo, name, nameCtx,
|
||||
environment);
|
||||
if (answer != null) {
|
||||
return answer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If refInfo is an array of URL strings,
|
||||
// try to find a context factory for any one of its URLs.
|
||||
// If no context found, continue to try object factories.
|
||||
if (refInfo instanceof String[]) {
|
||||
String[] urls = (String[])refInfo;
|
||||
for (int i = 0; i <urls.length; i++) {
|
||||
String scheme = getURLScheme(urls[i]);
|
||||
if (scheme != null) {
|
||||
answer = getURLObject(scheme, refInfo, name, nameCtx,
|
||||
environment);
|
||||
if (answer != null)
|
||||
return answer;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a context identified by {@code obj}, using the specified
|
||||
* environment.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue