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.apache.xpath.XPathAPI;
012 import org.w3c.dom.Element;
013 import org.w3c.dom.Node;
014 import org.w3c.dom.traversal.NodeIterator;
015
016 import biz.hammurapi.convert.CompositeConverter;
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><topicConnectionFactory type="biz.hammurapi.config.JndiWrapper" jndi-name="TopicConnectionFactory">
025
026 <environment-property name="java.naming.factory.initial"><I>factory class</I></environment-property>
027
028 <environment-property name="java.naming.provider.url"><I>provider urle</I></environment-property>
029
030 </topicConnectionFactory>
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 NodeIterator nit = XPathAPI.selectNodeIterator(configNode, "environment-property");
070 Element e;
071 while ((e = (Element) nit.nextNode()) != null) {
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 }