001    /** 
002     * 
003     * Copyright 2004 Protique Ltd
004     * 
005     * Licensed under the Apache License, Version 2.0 (the "License"); 
006     * you may not use this file except in compliance with the License. 
007     * 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     **/
018    
019    package org.activemq.jndi;
020    
021    import org.apache.commons.logging.Log;
022    import org.apache.commons.logging.LogFactory;
023    
024    import javax.naming.Context;
025    import javax.naming.Name;
026    import javax.naming.NamingException;
027    import javax.naming.Reference;
028    import javax.naming.StringRefAddr;
029    import javax.naming.spi.ObjectFactory;
030    import java.util.Enumeration;
031    import java.util.Hashtable;
032    import java.util.Properties;
033    
034    /**
035     * Converts objects implementing JNDIStorable into a property fields so they can
036     * be stored and regenerated from JNDI
037     */
038    public class JNDIReferenceFactory implements ObjectFactory {
039    
040        static Log log = LogFactory.getLog(JNDIReferenceFactory.class);
041    
042        /**
043         * This will be called by a JNDIprovider when a Reference is retrieved from
044         * a JNDI store - and generates the orignal instance
045         *
046         * @param object      the Reference object
047         * @param name        the JNDI name
048         * @param nameCtx     the context
049         * @param environment the environment settings used by JNDI
050         * @return the instance built from the Reference object
051         * @throws Exception if building the instance from Reference fails (usually class
052         *                   not found)
053         */
054        public Object getObjectInstance(Object object, Name name, Context nameCtx, Hashtable environment) throws Exception {
055            Object result = null;
056            if (object instanceof Reference) {
057                Reference reference = (Reference) object;
058    
059                if (log.isTraceEnabled()) {
060                    log.trace("Getting instance of " + reference.getClassName());
061                }
062    
063                Class theClass = loadClass(this, reference.getClassName());
064                if (JNDIStorableInterface.class.isAssignableFrom(theClass)) {
065    
066                    JNDIStorableInterface store = (JNDIStorableInterface) theClass.newInstance();
067                    Properties properties = new Properties();
068                    for (Enumeration iter = reference.getAll(); iter.hasMoreElements();) {
069    
070                        StringRefAddr addr = (StringRefAddr) iter.nextElement();
071                        properties.put(addr.getType(), (addr.getContent() == null) ? "" : addr.getContent());
072    
073                    }
074                    store.setProperties(properties);
075                    result = store;
076                }
077            }
078            else {
079                log.error("Object " + object + " is not a reference - cannot load");
080                throw new RuntimeException("Object " + object + " is not a reference");
081            }
082            return result;
083        }
084    
085        /**
086         * Create a Reference instance from a JNDIStorable object
087         *
088         * @param instanceClassName
089         * @param po
090         * @return @throws
091         *         NamingException
092         */
093    
094        public static Reference createReference(String instanceClassName, JNDIStorableInterface po) throws NamingException {
095            if (log.isTraceEnabled()) {
096                log.trace("Creating reference: " + instanceClassName + "," + po);
097            }
098            Reference result = new Reference(instanceClassName, JNDIReferenceFactory.class.getName(), null);
099            try {
100                Properties props = po.getProperties();
101                for (Enumeration iter = props.propertyNames(); iter.hasMoreElements();) {
102                    String key = (String) iter.nextElement();
103                    String value = props.getProperty(key);
104                    javax.naming.StringRefAddr addr = new javax.naming.StringRefAddr(key, value);
105                    result.add(addr);
106                }
107            }
108            catch (Exception e) {
109                log.error(e.getMessage(), e);
110                throw new NamingException(e.getMessage());
111            }
112            return result;
113        }
114    
115        /**
116         * Retrieve the class loader for a named class
117         *
118         * @param thisObj
119         * @param className
120         * @return @throws
121         *         ClassNotFoundException
122         */
123    
124        public static Class loadClass(Object thisObj, String className) throws ClassNotFoundException {
125            // tryu local ClassLoader first.
126            ClassLoader loader = thisObj.getClass().getClassLoader();
127            Class theClass;
128            if (loader != null) {
129                theClass = loader.loadClass(className);
130            }
131            else {
132                // Will be null in jdk1.1.8
133                // use default classLoader
134                theClass = Class.forName(className);
135            }
136            return theClass;
137        }
138    
139    }
140