001    /*
002     @license.text@
003     */
004    package biz.hammurapi.config;
005    
006    import java.util.Hashtable;
007    
008    import javax.naming.InitialContext;
009    import javax.naming.NamingException;
010    
011    import org.w3c.dom.Element;
012    import org.w3c.dom.Node;
013    import org.w3c.dom.NodeList;
014    
015    import biz.hammurapi.convert.ConvertingService;
016    import biz.hammurapi.xml.dom.DOMUtils;
017    
018    /** 
019     * Binds object from jndi to pv. 
020     * Configuration:<BR/> 
021     * Attribute: <code>jndi-name</code><BR> 
022     * Nested elements: <code>environment-property</code> with attribute <code>name</code>. 
023     * Example:<PRE>&lt;topicConnectionFactory type="biz.hammurapi.config.JndiWrapper" jndi-name="TopicConnectionFactory"&gt; 
024    
025     &nbsp;&nbsp;&nbsp;&nbsp;&lt;environment-property name="java.naming.factory.initial"&gt;<I>factory class</I>&lt;/environment-property&gt;
026    
027     &nbsp;&nbsp;&nbsp;&nbsp;&lt;environment-property name="java.naming.provider.url"&gt;<I>provider urle</I>&lt;/environment-property&gt;
028    
029     &lt;/topicConnectionFactory&gt; 
030     </PRE> 
031     * Environment properties are passed to the constructor of initial JNDI context. 
032     * If <code>jndi-name</code> attribute is not set then this class returns InitialContext as its master. 
033     * 
034     * If jndi-name is not set or master object is instance of javax.naming.Context then this component acts as a JNDI bridge.
035     * @author Pavel Vlasov 
036     * @revision $Revision$ 
037     */
038    public class JndiWrapper extends ComponentBase implements DomConfigurable, Wrapper {
039            
040            private Hashtable ctxProps = new Hashtable();
041    
042            private Object master;
043    
044            private String name;
045    
046            public JndiWrapper() {
047                    super();
048            }
049    
050            /** 
051             * Looks up master in JNDI. 
052             */
053            public void start() throws ConfigurationException {
054                    try {
055                            InitialContext jndiContext = new InitialContext(ctxProps);
056                            master = name == null ? jndiContext : jndiContext.lookup(name);
057                    } catch (NamingException e) {
058                            throw new ConfigurationException(e);
059                    }
060            }
061    
062            public void stop() throws ConfigurationException {
063                    // Nothing 
064            }
065    
066            public void configure(Node configNode, Context context, ClassLoader classLoader)        throws ConfigurationException {
067                    try {
068                            NodeList nl = DOMUtils.selectNodeList(configNode, "environment-property");
069                            for (int i=0, l=nl.getLength(); i<l; ++i) {
070                                    Element e = (Element) nl.item(i);
071                                    Object value = DOMUtils.getNonBlankElementText(e);
072                                    if (e.hasAttribute("type")) {
073                                            value = ConvertingService.convert(value, Class.forName(e.getAttribute("type")));
074                                    }
075                                    ctxProps.put(e.getAttribute("name"), value);
076                            }
077                            
078                            Element ce = (Element) configNode;
079                            if (ce.hasAttribute("jndi-name")) {
080                                    name = ce.getAttribute("jndi-name");
081                            }
082                    } catch (Exception e) {
083                            throw new ConfigurationException(e);
084                    }
085            }
086    
087            public Object getMaster() {
088                    return master;
089            }
090    
091            protected Object getChild(String name) {
092                    if (master instanceof javax.naming.Context) {
093                            try {
094                                    return ((javax.naming.Context) master).lookup(name);
095                            } catch (NamingException e) {
096                                    throw new RuntimeConfigurationException("Lookup failed: "+e, e);
097                            }
098                    }
099                    return super.getChild(name);
100            }
101    }