001 /*****************************************************************************
002 * Copyright (c) PicoContainer Organization. All rights reserved. *
003 * ------------------------------------------------------------------------- *
004 * The software in this package is published under the terms of the BSD *
005 * style license a copy of which has been included with this distribution in *
006 * the LICENSE.txt file. *
007 * *
008 *****************************************************************************/
009
010 package org.picocontainer.gems.jndi;
011
012 import java.io.IOException;
013 import java.io.Serializable;
014
015 import javax.naming.Context;
016 import javax.naming.InitialContext;
017 import javax.naming.Name;
018 import javax.naming.NameNotFoundException;
019 import javax.naming.NamingException;
020
021 import org.picocontainer.ObjectReference;
022 import org.picocontainer.PicoCompositionException;
023
024 /**
025 * object reference to store and retrieve objects from JNDI
026 *
027 * @author ko5tik
028 *
029 */
030 @SuppressWarnings("serial")
031 public class JNDIObjectReference<T> implements ObjectReference<T> , Serializable{
032
033
034 String name;
035
036 transient Context context;
037
038 public JNDIObjectReference(final String name, final Context ctx) {
039 super();
040 this.name = name;
041 this.context = ctx;
042 }
043
044 public JNDIObjectReference(final String jndiName) throws NamingException {
045 this(jndiName,new InitialContext());
046 }
047
048 /**
049 * retrieve object from JNDI if possible
050 */
051 public T get() {
052 try {
053 return (T) context.lookup(name);
054 } catch(NameNotFoundException e) {
055 // this is not error, but normal situation - nothing
056 // was stored yet
057 return null;
058 } catch (NamingException e) {
059 throw new PicoCompositionException("unable to resolve jndi name:"
060 + name, e);
061 }
062 }
063
064 /**
065 * store object in JNDI under specified name
066 */
067 public void set(final T item) {
068 try {
069 if (item == null) {
070 context.unbind(name);
071 } else {
072
073 Context ctx = context;
074 Name n = ctx.getNameParser("").parse(name);
075 while (n.size() > 1) {
076 String ctxName = n.get(0);
077 try {
078 ctx = (Context) ctx.lookup(ctxName);
079 } catch (NameNotFoundException e) {
080 ctx = ctx.createSubcontext(ctxName);
081 }
082 n = n.getSuffix(1);
083 }
084 // unbind name just in case
085 try {
086 if (ctx.lookup(n) != null) {
087 ctx.unbind(n);
088 }
089 } catch (NameNotFoundException e) {
090 // that's ok
091 }
092 ctx.bind(n, item);
093 }
094 } catch (NamingException e) {
095 throw new PicoCompositionException("unable to bind to jndi name:"
096 + name, e);
097 }
098 }
099
100 /**
101 * name of this reference
102 *
103 * @return
104 */
105 public String getName() {
106 return name;
107 }
108
109 /**
110 * here we try to capture (eventual) deserealisation of this reference by
111 * some container (notably JBoss) and restore context as initial context
112 * I hope this will be sufficient for most puproses
113 *
114 * @param in
115 * @throws IOException
116 * @throws ClassNotFoundException
117 */
118 private void readObject(final java.io.ObjectInputStream in)throws IOException, ClassNotFoundException {
119 try {
120 context = new InitialContext();
121 } catch (NamingException e) {
122 throw new IOException("unable to create initial context");
123 }
124 in.defaultReadObject();
125 }
126
127
128 @Override
129 public String toString() {
130 return "(" + getName() + ")";
131 }
132 }