001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.xbean.naming.global;
018    
019    import org.apache.xbean.naming.context.ContextFlyweight;
020    
021    import javax.naming.Context;
022    import javax.naming.Name;
023    import javax.naming.OperationNotSupportedException;
024    import javax.naming.NoInitialContextException;
025    import javax.naming.spi.InitialContextFactory;
026    import javax.naming.spi.ObjectFactory;
027    import java.util.Hashtable;
028    
029    /**
030     * The GlobalContextManager contains the static global context object.  JNDI effectively requires a single global static
031     * to resolve the root context, and this class manages that static.  This class is also an URLContextFactory and
032     * an InitialContextFactory which returns the registered global context.
033     *
034     * To use this factory simply set the following system property or pass the property in the environment to new InitialContext:
035     *
036     * java.naming.factory.initial = org.apache.xbean.naming.global.GlobalContextManager
037     *
038     * @version $Rev$ $Date$
039     */
040    public class GlobalContextManager implements ObjectFactory, InitialContextFactory {
041        private static Context DEFAULT_CONTEXT = new DefaultGlobalContext();
042        private static Context globalContext;
043    
044        /**
045         * Gets the global context.  This context is the root of all contexts and will contain entries such as "java:comp".
046         * @return the global context
047         */
048        public static synchronized Context getGlobalContext() {
049            if (globalContext == null) return DEFAULT_CONTEXT;
050            return globalContext;
051        }
052    
053        /**
054         * Sets the global context. To invoke this method the calling code must have "setFactory" RuntimePermission.
055         * @param globalContext the new global context
056         */
057        public static synchronized void setGlobalContext(Context globalContext) {
058            SecurityManager security = System.getSecurityManager();
059            if (security != null) {
060                security.checkSetFactory();
061            }
062            GlobalContextManager.globalContext = globalContext;
063        }
064    
065        /**
066         * Returns the Context registered with the GlobalManager. This method is equivalent to:
067         *
068         * return GlobalContextManager.getGlobalContext();
069         *
070         * @param obj must be null
071         * @param name ignored
072         * @param nameCtx ignored
073         * @param environment ignored
074         * @return GlobalManager.getGlobalContext()
075         * @throws javax.naming.OperationNotSupportedException if obj is not null
076         */
077        public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) throws Exception {
078            if (obj == null) {
079                return GlobalContextManager.getGlobalContext();
080            } else {
081                throw new OperationNotSupportedException();
082            }
083        }
084    
085    
086        /**
087         * Returns the Context registered with the GlobalManager. This method is equivalent to:
088         *
089         * return GlobalContextManager.getGlobalContext();
090         *
091         * @param environment ignored
092         * @return GlobalContextManager.getGlobalContext()
093         */
094        public Context getInitialContext(Hashtable environment) {
095            return GlobalContextManager.getGlobalContext();
096        }
097    
098        private static class DefaultGlobalContext extends ContextFlyweight {
099            protected Context getContext() throws NoInitialContextException {
100                synchronized (GlobalContextManager.class) {
101                    if (globalContext == null) throw new NoInitialContextException("Global context has not been set");
102                    return globalContext;
103                }
104            }
105        }
106    }