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 }