    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    }