| /* |
| * Copyright (c) 2006, 2018 Oracle and/or its affiliates. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0, which is available at |
| * http://www.eclipse.org/legal/epl-2.0. |
| * |
| * This Source Code may also be made available under the following Secondary |
| * Licenses when the conditions for such availability set forth in the |
| * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, |
| * version 2 with the GNU Classpath Exception, which is available at |
| * https://www.gnu.org/software/classpath/license.html. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 |
| */ |
| |
| package com.sun.enterprise.naming.impl; |
| |
| import org.glassfish.api.admin.ProcessEnvironment; |
| import org.glassfish.api.admin.ProcessEnvironment.ProcessType; |
| import org.glassfish.api.naming.ComponentNamingUtil; |
| import org.glassfish.internal.api.Globals; |
| import org.glassfish.hk2.api.ServiceLocator; |
| |
| import javax.naming.*; |
| import java.util.Hashtable; |
| import java.util.logging.Level; |
| |
| import static com.sun.enterprise.naming.util.LogFacade.logger; |
| |
| /** |
| * This class is a context implementation for the java:comp namespace. |
| * The context determines the component id from the invocation manager |
| * of the component that is invoking the method and then looks up the |
| * object in that component's local namespace. |
| */ |
| public final class JavaURLContext implements Context, Cloneable { |
| private static GlassfishNamingManagerImpl namingManager; |
| |
| private Hashtable myEnv; |
| //private Context ctx; XXX not needed ? |
| private String myName = ""; |
| |
| private SerialContext serialContext = null; |
| |
| /** |
| * Create a context with the specified environment. |
| */ |
| public JavaURLContext(Hashtable environment) throws NamingException { |
| myEnv = (environment != null) ? (Hashtable) (environment.clone()) |
| : null; |
| } |
| |
| /** |
| * Create a context with the specified name+environment. |
| * Called only from GlassfishNamingManager. |
| */ |
| public JavaURLContext(String name, Hashtable env) |
| throws NamingException { |
| this(env); |
| this.myName = name; |
| } |
| |
| /** |
| * this constructor is called from SerialContext class |
| */ |
| public JavaURLContext(Hashtable env, SerialContext serialContext) |
| throws NamingException { |
| this(env); |
| this.serialContext = serialContext; |
| } |
| |
| public JavaURLContext( JavaURLContext ctx, SerialContext sctx ) { |
| this.myName = ctx.myName ; |
| this.myEnv = ctx.myEnv ; |
| this.serialContext = sctx ; |
| } |
| |
| static void setNamingManager(GlassfishNamingManagerImpl mgr) { |
| namingManager = mgr; |
| } |
| |
| /** |
| * add SerialContext to preserve stickiness to cloned instance |
| * why clone() : to avoid the case of multiple threads modifying |
| * the context returned for ctx.lookup("java:com/env/ejb") |
| */ |
| /** STICKY context not enabled |
| public JavaURLContext addStickyContext(SerialContext serialContext) |
| throws NamingException { |
| try { |
| JavaURLContext jCtx = (JavaURLContext) this.clone(); |
| jCtx.serialContext = serialContext; |
| return jCtx; |
| } catch (java.lang.CloneNotSupportedException ex) { |
| NamingException ne = new NamingException( |
| "problem with cloning javaURLContext instance"); |
| ne.initCause(ex); |
| throw ne; |
| } |
| } |
| **/ |
| |
| /** |
| * Lookup an object in the serial context. |
| * |
| * @return the object that is being looked up. |
| * @throws NamingException if there is a naming exception. |
| */ |
| @Override |
| public Object lookup(String name) throws NamingException { |
| if (name.equals("")) { |
| /** |
| * javadocs for Context.lookup: If name is empty, returns a new |
| * instance of this context (which represents the same naming |
| * context as this context, but its environment may be modified |
| * independently and it may be accessed concurrently). |
| */ |
| return new JavaURLContext(myName, myEnv); |
| } |
| |
| String fullName = name; |
| if (!myName.equals("")) { |
| if (myName.equals("java:")) |
| fullName = myName + name; |
| else |
| fullName = myName + "/" + name; |
| } |
| |
| try { |
| Object obj = null; |
| // If we know for sure it's an entry within an environment namespace |
| if (isLookingUpEnv(fullName)) { |
| // refers to a dependency defined by the application |
| obj = namingManager.lookup(fullName, serialContext); |
| } else { |
| // It's either an application-defined dependency in a java: |
| // namespace or a special EE platform object. |
| // Check for EE platform objects first to prevent overriding. |
| obj = NamedNamingObjectManager.tryNamedProxies(name); |
| if (obj == null) { |
| // try GlassfishNamingManager |
| obj = namingManager.lookup(fullName, serialContext); |
| } |
| } |
| |
| if( obj == null ) { |
| throw new NamingException("No object found for " + name); |
| } |
| |
| return obj; |
| } catch (NamingException ex) { |
| |
| ServiceLocator services = Globals.getDefaultHabitat(); |
| ProcessEnvironment processEnv = services.getService(ProcessEnvironment.class); |
| if( fullName.startsWith("java:app/") && |
| processEnv.getProcessType() == ProcessType.ACC ) { |
| |
| // This could either be an attempt by an app client to access a portable |
| // remote session bean JNDI name via the java:app namespace or a lookup of |
| // an application-defined java:app environment dependency. Try them in |
| // that order. |
| |
| Context ic = namingManager.getInitialContext(); |
| String appName = (String) namingManager.getInitialContext().lookup("java:app/AppName"); |
| |
| Object obj = null; |
| |
| if (!fullName.startsWith("java:app/env/") |
| || !"java:app/env".equals(fullName)) { |
| try { |
| |
| // Translate the java:app name into the equivalent java:global name so that |
| // the lookup will be resolved by the server. |
| String newPrefix = "java:global/" + appName + "/"; |
| |
| int javaAppLength = "java:app/".length(); |
| String globalLookup = newPrefix + fullName.substring(javaAppLength); |
| |
| obj = ic.lookup(globalLookup); |
| |
| } catch(NamingException javaappenvne) { |
| logger.log(Level.FINE, "Trying global version of java:app ejb lookup", javaappenvne); |
| } |
| } |
| |
| if( obj == null ) { |
| ComponentNamingUtil compNamingUtil = services.getService(ComponentNamingUtil.class); |
| String internalGlobalJavaAppName = |
| compNamingUtil.composeInternalGlobalJavaAppName(appName, fullName); |
| |
| obj = ic.lookup(internalGlobalJavaAppName); |
| } |
| |
| if( obj == null ) { |
| throw new NamingException("No object found for " + name); |
| } |
| |
| return obj; |
| |
| } |
| |
| throw ex; |
| } catch (Exception ex) { |
| throw (NamingException) (new NameNotFoundException( |
| "No object bound for " + fullName)).initCause(ex); |
| } |
| } |
| |
| /** |
| * Lookup a name in either the cosnaming or serial context. |
| * |
| * @return the object that is being looked up. |
| * @throws NamingException if there is a naming exception. |
| */ |
| @Override |
| public Object lookup(Name name) throws NamingException { |
| // Flat namespace; no federation; just call string version |
| return lookup(name.toString()); |
| } |
| |
| /** |
| * Bind an object in the namespace. Binds the reference to the |
| * actual object in either the cosnaming or serial context. |
| * |
| * @throws NamingException if there is a naming exception. |
| */ |
| @Override |
| public void bind(String name, Object obj) throws NamingException { |
| throw new NamingException("java:comp namespace cannot be modified"); |
| } |
| |
| /** |
| * Bind an object in the namespace. Binds the reference to the |
| * actual object in either the cosnaming or serial context. |
| * |
| * @throws NamingException if there is a naming exception. |
| */ |
| @Override |
| public void bind(Name name, Object obj) throws NamingException { |
| throw new NamingException("java:comp namespace cannot be modified"); |
| } |
| |
| /** |
| * Rebind an object in the namespace. Rebinds the reference to the |
| * actual object in either the cosnaming or serial context. |
| * |
| * @throws NamingException if there is a naming exception. |
| */ |
| @Override |
| public void rebind(String name, Object obj) throws NamingException { |
| throw new NamingException("java:comp namespace cannot be modified"); |
| } |
| |
| /** |
| * Rebind an object in the namespace. Rebinds the reference to the |
| * actual object in either the cosnaming or serial context. |
| * |
| * @throws NamingException if there is a naming exception. |
| */ |
| @Override |
| public void rebind(Name name, Object obj) throws NamingException { |
| throw new NamingException("java:comp namespace cannot be modified"); |
| } |
| |
| /** |
| * Unbind an object from the namespace. |
| * |
| * @throws NamingException if there is a naming exception. |
| */ |
| @Override |
| public void unbind(String name) throws NamingException { |
| throw new NamingException("java:comp namespace cannot be modified"); |
| } |
| |
| /** |
| * Unbind an object from the namespace. |
| * |
| * @throws NamingException if there is a naming exception. |
| */ |
| @Override |
| public void unbind(Name name) throws NamingException { |
| throw new NamingException("java:comp namespace cannot be modified"); |
| } |
| |
| /** |
| * The rename operation is not supported by this context. It throws |
| * an OperationNotSupportedException. |
| */ |
| @Override |
| public void rename(String oldname, String newname) throws NamingException { |
| throw new NamingException("java:comp namespace cannot be modified"); |
| } |
| |
| /** |
| * The rename operation is not supported by this context. It throws |
| * an OperationNotSupportedException. |
| */ |
| @Override |
| public void rename(Name oldname, Name newname) |
| throws NamingException { |
| throw new NamingException("java:comp namespace cannot be modified"); |
| } |
| |
| /** |
| * The destroySubcontext operation is not supported by this context. |
| * It throws an OperationNotSupportedException. |
| */ |
| @Override |
| public void destroySubcontext(String name) throws NamingException { |
| throw new NamingException("java:comp namespace cannot be modified"); |
| } |
| |
| /** |
| * The destroySubcontext operation is not supported by this context. |
| * It throws an OperationNotSupportedException. |
| */ |
| @Override |
| public void destroySubcontext(Name name) throws NamingException { |
| throw new NamingException("java:comp namespace cannot be modified"); |
| } |
| |
| @Override |
| public Context createSubcontext(String name) throws NamingException { |
| throw new NamingException("java:comp namespace cannot be modified"); |
| } |
| |
| @Override |
| public Context createSubcontext(Name name) throws NamingException { |
| throw new NamingException("java:comp namespace cannot be modified"); |
| } |
| |
| |
| /** |
| * Lists the contents of a context or subcontext. The operation is |
| * delegated to the serial context. |
| * |
| * @return an enumeration of the contents of the context. |
| * @throws NamingException if there is a naming exception. |
| */ |
| @Override |
| public NamingEnumeration<NameClassPair> list(String name) |
| throws NamingException { |
| if (name.equals("")) { |
| // listing this context |
| if (namingManager == null) |
| throw new NamingException(); |
| return namingManager.list(myName); |
| } |
| |
| // Check if 'name' names a context |
| Object target = lookup(name); |
| if (target instanceof Context) { |
| return ((Context) target).list(""); |
| } |
| throw new NotContextException(name + " cannot be listed"); |
| } |
| |
| /** |
| * Lists the contents of a context or subcontext. The operation is |
| * delegated to the serial context. |
| * |
| * @return an enumeration of the contents of the context. |
| * @throws NamingException if there is a naming exception. |
| */ |
| @Override |
| public NamingEnumeration<NameClassPair> list(Name name) |
| throws NamingException { |
| // Flat namespace; no federation; just call string version |
| return list(name.toString()); |
| } |
| |
| /** |
| * Lists the bindings of a context or subcontext. The operation is |
| * delegated to the serial context. |
| * |
| * @return an enumeration of the bindings of the context. |
| * @throws NamingException if there is a naming exception. |
| */ |
| @Override |
| public NamingEnumeration<Binding> listBindings(String name) |
| throws NamingException { |
| if (name.equals("")) { |
| // listing this context |
| if (namingManager == null) |
| throw new NamingException(); |
| return namingManager.listBindings(myName); |
| } |
| |
| // Perhaps 'name' names a context |
| Object target = lookup(name); |
| if (target instanceof Context) { |
| return ((Context) target).listBindings(""); |
| } |
| throw new NotContextException(name + " cannot be listed"); |
| } |
| |
| /** |
| * Lists the bindings of a context or subcontext. The operation is |
| * delegated to the serial context. |
| * |
| * @return an enumeration of the bindings of the context. |
| * @throws NamingException if there is a naming exception. |
| */ |
| @Override |
| public NamingEnumeration<Binding> listBindings(Name name) |
| throws NamingException { |
| // Flat namespace; no federation; just call string version |
| return listBindings(name.toString()); |
| } |
| |
| /** |
| * This context does not treat links specially. A lookup operation is |
| * performed. |
| */ |
| @Override |
| public Object lookupLink(String name) throws NamingException { |
| // This flat context does not treat links specially |
| return lookup(name); |
| } |
| |
| /** |
| * This context does not treat links specially. A lookup operation is |
| * performed. |
| */ |
| @Override |
| public Object lookupLink(Name name) throws NamingException { |
| // Flat namespace; no federation; just call string version |
| return lookupLink(name.toString()); |
| } |
| |
| /** |
| * Return the name parser for the specified name. |
| * |
| * @return the NameParser instance. |
| * @throws NamingException if there is an exception. |
| */ |
| @Override |
| public NameParser getNameParser(String name) |
| throws NamingException { |
| if (namingManager == null) |
| throw new NamingException(); |
| return namingManager.getNameParser(); |
| } |
| |
| /** |
| * Return the name parser for the specified name. |
| * |
| * @return the NameParser instance. |
| * @throws NamingException if there is an exception. |
| */ |
| @Override |
| public NameParser getNameParser(Name name) throws NamingException { |
| // Flat namespace; no federation; just call string version |
| return getNameParser(name.toString()); |
| } |
| |
| @Override |
| public String composeName(String name, String prefix) |
| throws NamingException { |
| Name result = composeName(new CompositeName(name), |
| new CompositeName(prefix)); |
| return result.toString(); |
| } |
| |
| @Override |
| public Name composeName(Name name, Name prefix) |
| throws NamingException { |
| Name result = (Name) (prefix.clone()); |
| result.addAll(name); |
| return result; |
| } |
| |
| /** |
| * Add a property to the environment. |
| */ |
| @Override |
| public Object addToEnvironment(String propName, Object propVal) |
| throws NamingException { |
| if (myEnv == null) { |
| myEnv = new Hashtable(5, 0.75f); |
| } |
| return myEnv.put(propName, propVal); |
| } |
| |
| /** |
| * Remove a property from the environment. |
| */ |
| @Override |
| public Object removeFromEnvironment(String propName) |
| throws NamingException { |
| if (myEnv == null) { |
| return null; |
| } |
| return myEnv.remove(propName); |
| } |
| |
| /** |
| * Get the context's environment. |
| */ |
| @Override |
| public Hashtable getEnvironment() throws NamingException { |
| if (myEnv == null) { |
| // Must return non-null |
| myEnv = new Hashtable(3, 0.75f); |
| } |
| return myEnv; |
| } |
| |
| /** |
| * New JNDI 1.2 operation. |
| */ |
| @Override |
| public void close() throws NamingException { |
| myEnv = null; |
| } |
| |
| /** |
| * Return the name of this context within the namespace. The name |
| * can be passed as an argument to (new InitialContext()).lookup() |
| * to reproduce this context. |
| */ |
| @Override |
| public String getNameInNamespace() throws NamingException { |
| return myName; |
| } |
| |
| |
| private boolean isLookingUpEnv(String fullName) { |
| boolean result = false; |
| if (fullName.startsWith("java:comp/env/") |
| || fullName.startsWith("java:module/env/") |
| || fullName.startsWith("java:app/env/")) { |
| result = true; |
| } else if ("java:comp/env".equals(fullName) |
| || "java:module/env".equals(fullName) |
| || "java:app/env".equals(fullName)) { |
| result = true; |
| } |
| return result; |
| } |
| |
| } |
| |
| |