001: //$Id: SessionFactoryObjectFactory.java 11338 2007-03-22 22:43:13Z epbernard $
002: package org.hibernate.impl;
003:
004: import java.util.Hashtable;
005: import java.util.Iterator;
006: import java.util.Properties;
007:
008: import javax.naming.Context;
009: import javax.naming.InvalidNameException;
010: import javax.naming.Name;
011: import javax.naming.NamingException;
012: import javax.naming.Reference;
013: import javax.naming.event.EventContext;
014: import javax.naming.event.NamespaceChangeListener;
015: import javax.naming.event.NamingEvent;
016: import javax.naming.event.NamingExceptionEvent;
017: import javax.naming.event.NamingListener;
018: import javax.naming.spi.ObjectFactory;
019:
020: import org.hibernate.SessionFactory;
021: import org.hibernate.util.FastHashMap;
022: import org.hibernate.util.NamingHelper;
023:
024: import org.apache.commons.logging.Log;
025: import org.apache.commons.logging.LogFactory;
026:
027: /**
028: * Resolves <tt>SessionFactory</tt> JNDI lookups and deserialization
029: */
030: public class SessionFactoryObjectFactory implements ObjectFactory {
031:
032: private static final SessionFactoryObjectFactory INSTANCE; //to stop the class from being unloaded
033:
034: private static final Log log;
035:
036: static {
037: log = LogFactory.getLog(SessionFactoryObjectFactory.class);
038: INSTANCE = new SessionFactoryObjectFactory();
039: log.debug("initializing class SessionFactoryObjectFactory");
040: }
041:
042: private static final FastHashMap INSTANCES = new FastHashMap();
043: private static final FastHashMap NAMED_INSTANCES = new FastHashMap();
044:
045: private static final NamingListener LISTENER = new NamespaceChangeListener() {
046: public void objectAdded(NamingEvent evt) {
047: log.debug("A factory was successfully bound to name: "
048: + evt.getNewBinding().getName());
049: }
050:
051: public void objectRemoved(NamingEvent evt) {
052: String name = evt.getOldBinding().getName();
053: log.info("A factory was unbound from name: " + name);
054: Object instance = NAMED_INSTANCES.remove(name);
055: Iterator iter = INSTANCES.values().iterator();
056: while (iter.hasNext()) {
057: if (iter.next() == instance)
058: iter.remove();
059: }
060: }
061:
062: public void objectRenamed(NamingEvent evt) {
063: String name = evt.getOldBinding().getName();
064: log.info("A factory was renamed from name: " + name);
065: NAMED_INSTANCES.put(evt.getNewBinding().getName(),
066: NAMED_INSTANCES.remove(name));
067: }
068:
069: public void namingExceptionThrown(NamingExceptionEvent evt) {
070: log.warn("Naming exception occurred accessing factory: "
071: + evt.getException());
072: }
073: };
074:
075: public Object getObjectInstance(Object reference, Name name,
076: Context ctx, Hashtable env) throws Exception {
077: log.debug("JNDI lookup: " + name);
078: String uid = (String) ((Reference) reference).get(0)
079: .getContent();
080: return getInstance(uid);
081: }
082:
083: public static void addInstance(String uid, String name,
084: SessionFactory instance, Properties properties) {
085:
086: log.debug("registered: " + uid + " ("
087: + ((name == null) ? "unnamed" : name) + ')');
088: INSTANCES.put(uid, instance);
089: if (name != null)
090: NAMED_INSTANCES.put(name, instance);
091:
092: //must add to JNDI _after_ adding to HashMaps, because some JNDI servers use serialization
093: if (name == null) {
094: log
095: .info("Not binding factory to JNDI, no JNDI name configured");
096: } else {
097:
098: log.info("Factory name: " + name);
099:
100: try {
101: Context ctx = NamingHelper
102: .getInitialContext(properties);
103: NamingHelper.bind(ctx, name, instance);
104: log.info("Bound factory to JNDI name: " + name);
105: ((EventContext) ctx).addNamingListener(name,
106: EventContext.OBJECT_SCOPE, LISTENER);
107: } catch (InvalidNameException ine) {
108: log.error("Invalid JNDI name: " + name, ine);
109: } catch (NamingException ne) {
110: log.warn("Could not bind factory to JNDI", ne);
111: } catch (ClassCastException cce) {
112: log
113: .warn("InitialContext did not implement EventContext");
114: }
115:
116: }
117:
118: }
119:
120: public static void removeInstance(String uid, String name,
121: Properties properties) {
122: //TODO: theoretically non-threadsafe...
123:
124: if (name != null) {
125: log.info("Unbinding factory from JNDI name: " + name);
126:
127: try {
128: Context ctx = NamingHelper
129: .getInitialContext(properties);
130: ctx.unbind(name);
131: log.info("Unbound factory from JNDI name: " + name);
132: } catch (InvalidNameException ine) {
133: log.error("Invalid JNDI name: " + name, ine);
134: } catch (NamingException ne) {
135: log.warn("Could not unbind factory from JNDI", ne);
136: }
137:
138: NAMED_INSTANCES.remove(name);
139:
140: }
141:
142: INSTANCES.remove(uid);
143:
144: }
145:
146: public static Object getNamedInstance(String name) {
147: log.debug("lookup: name=" + name);
148: Object result = NAMED_INSTANCES.get(name);
149: if (result == null) {
150: log.debug("Not found: " + name);
151: log.debug(NAMED_INSTANCES);
152: }
153: return result;
154: }
155:
156: public static Object getInstance(String uid) {
157: log.debug("lookup: uid=" + uid);
158: Object result = INSTANCES.get(uid);
159: if (result == null) {
160: log.debug("Not found: " + uid);
161: log.debug(INSTANCES);
162: }
163: return result;
164: }
165:
166: }
|