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