1
//$Id: SessionFactoryObjectFactory.java 11338 2007-03-22 22:43:13Z epbernard $
2
package org.hibernate.impl;
4
import java.util.Hashtable;
5
import java.util.Iterator;
6
import java.util.Properties;
8
import javax.naming.Context;
9
import javax.naming.InvalidNameException;
10
import javax.naming.Name;
11
import javax.naming.NamingException;
12
import javax.naming.Reference;
13
import javax.naming.event.EventContext;
14
import javax.naming.event.NamespaceChangeListener;
15
import javax.naming.event.NamingEvent;
16
import javax.naming.event.NamingExceptionEvent;
17
import javax.naming.event.NamingListener;
18
import javax.naming.spi.ObjectFactory;
20
import org.hibernate.SessionFactory;
21
import org.hibernate.util.FastHashMap;
22
import org.hibernate.util.NamingHelper;
24
import org.apache.commons.logging.Log;
25
import org.apache.commons.logging.LogFactory;
28
* Resolves <tt>SessionFactory</tt> JNDI lookups and deserialization
30
public class SessionFactoryObjectFactory implements ObjectFactory {
32
private static final SessionFactoryObjectFactory INSTANCE; //to stop the class from being unloaded
34
private static final Log log;
37
log = LogFactory.getLog(SessionFactoryObjectFactory.class);
38
INSTANCE = new SessionFactoryObjectFactory();
39
log.debug("initializing class SessionFactoryObjectFactory");
42
private static final FastHashMap INSTANCES = new FastHashMap();
43
private static final FastHashMap NAMED_INSTANCES = new FastHashMap();
45
private static final NamingListener LISTENER = new NamespaceChangeListener() {
46
public void objectAdded(NamingEvent evt) {
47
log.debug( "A factory was successfully bound to name: " + evt.getNewBinding().getName() );
49
public void objectRemoved(NamingEvent evt) {
50
String name = evt.getOldBinding().getName();
51
log.info("A factory was unbound from name: " + name);
52
Object instance = NAMED_INSTANCES.remove(name);
53
Iterator iter = INSTANCES.values().iterator();
54
while ( iter.hasNext() ) {
55
if ( iter.next()==instance ) iter.remove();
58
public void objectRenamed(NamingEvent evt) {
59
String name = evt.getOldBinding().getName();
60
log.info("A factory was renamed from name: " + name);
61
NAMED_INSTANCES.put( evt.getNewBinding().getName(), NAMED_INSTANCES.remove(name) );
63
public void namingExceptionThrown(NamingExceptionEvent evt) {
64
log.warn( "Naming exception occurred accessing factory: " + evt.getException() );
68
public Object getObjectInstance(Object reference, Name name, Context ctx, Hashtable env) throws Exception {
69
log.debug("JNDI lookup: " + name);
70
String uid = (String) ( (Reference) reference ).get(0).getContent();
71
return getInstance(uid);
74
public static void addInstance(String uid, String name, SessionFactory instance, Properties properties) {
76
log.debug("registered: " + uid + " (" + ( (name==null) ? "unnamed" : name ) + ')');
77
INSTANCES.put(uid, instance);
78
if (name!=null) NAMED_INSTANCES.put(name, instance);
80
//must add to JNDI _after_ adding to HashMaps, because some JNDI servers use serialization
82
log.info("Not binding factory to JNDI, no JNDI name configured");
86
log.info("Factory name: " + name);
89
Context ctx = NamingHelper.getInitialContext(properties);
90
NamingHelper.bind(ctx, name, instance);
91
log.info("Bound factory to JNDI name: " + name);
92
( (EventContext) ctx ).addNamingListener(name, EventContext.OBJECT_SCOPE, LISTENER);
94
catch (InvalidNameException ine) {
95
log.error("Invalid JNDI name: " + name, ine);
97
catch (NamingException ne) {
98
log.warn("Could not bind factory to JNDI", ne);
100
catch(ClassCastException cce) {
101
log.warn("InitialContext did not implement EventContext");
108
public static void removeInstance(String uid, String name, Properties properties) {
109
//TODO: theoretically non-threadsafe...
112
log.info("Unbinding factory from JNDI name: " + name);
115
Context ctx = NamingHelper.getInitialContext(properties);
117
log.info("Unbound factory from JNDI name: " + name);
119
catch (InvalidNameException ine) {
120
log.error("Invalid JNDI name: " + name, ine);
122
catch (NamingException ne) {
123
log.warn("Could not unbind factory from JNDI", ne);
126
NAMED_INSTANCES.remove(name);
130
INSTANCES.remove(uid);
134
public static Object getNamedInstance(String name) {
135
log.debug("lookup: name=" + name);
136
Object result = NAMED_INSTANCES.get(name);
138
log.debug("Not found: " + name);
139
log.debug(NAMED_INSTANCES);
144
public static Object getInstance(String uid) {
145
log.debug("lookup: uid=" + uid);
146
Object result = INSTANCES.get(uid);
148
log.debug("Not found: " + uid);
149
log.debug(INSTANCES);