001/*
002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 * 
016 * Contributors:
017 */
018package org.nuxeo.runtime.test.runner;
019
020import javax.naming.Context;
021import javax.naming.Name;
022import javax.naming.NameNotFoundException;
023import javax.naming.NamingException;
024
025import org.apache.commons.logging.Log;
026import org.apache.commons.logging.LogFactory;
027
028/**
029 * helper for common jndi operations copied from jboss Util class
030 */
031public class JndiHelper {
032
033    private static final Log log = LogFactory.getLog(JndiHelper.class);
034
035    /**
036     * Create a subcontext including any intermediate contexts.
037     *
038     * @param ctx the parent JNDI Context under which value will be bound
039     * @param name the name relative to ctx of the subcontext.
040     * @return The new or existing JNDI subcontext
041     * @throws javax.naming.NamingException on any JNDI failure
042     */
043    public static Context createSubcontext(Context ctx, String name) throws NamingException {
044        Name n = ctx.getNameParser("").parse(name);
045        return createSubcontext(ctx, n);
046    }
047
048    /**
049     * Create a subcontext including any intermediate contexts.
050     *
051     * @param ctx the parent JNDI Context under which value will be bound
052     * @param name the name relative to ctx of the subcontext.
053     * @return The new or existing JNDI subcontext
054     * @throws NamingException on any JNDI failure
055     */
056    public static Context createSubcontext(Context ctx, Name name) throws NamingException {
057        Context subctx = ctx;
058        for (int pos = 0; pos < name.size(); pos++) {
059            String ctxName = name.get(pos);
060            try {
061                subctx = (Context) ctx.lookup(ctxName);
062            } catch (NameNotFoundException e) {
063                subctx = ctx.createSubcontext(ctxName);
064            }
065            // The current subctx will be the ctx for the next name component
066            ctx = subctx;
067        }
068        return subctx;
069    }
070
071    /**
072     * Bind val to name in ctx, and make sure that all intermediate contexts exist
073     *
074     * @param ctx the parent JNDI Context under which value will be bound
075     * @param name the name relative to ctx where value will be bound
076     * @param value the value to bind.
077     * @throws NamingException for any error
078     */
079    public static void bind(Context ctx, String name, Object value) throws NamingException {
080        Name n = ctx.getNameParser("").parse(name);
081        bind(ctx, n, value);
082    }
083
084    /**
085     * Bind val to name in ctx, and make sure that all intermediate contexts exist
086     *
087     * @param ctx the parent JNDI Context under which value will be bound
088     * @param name the name relative to ctx where value will be bound
089     * @param value the value to bind.
090     * @throws NamingException for any error
091     */
092    public static void bind(Context ctx, Name name, Object value) throws NamingException {
093        int size = name.size();
094        String atom = name.get(size - 1);
095        Context parentCtx = createSubcontext(ctx, name.getPrefix(size - 1));
096        parentCtx.bind(atom, value);
097    }
098
099    /**
100     * Rebind val to name in ctx, and make sure that all intermediate contexts exist
101     *
102     * @param ctx the parent JNDI Context under which value will be bound
103     * @param name the name relative to ctx where value will be bound
104     * @param value the value to bind.
105     * @throws NamingException for any error
106     */
107    public static void rebind(Context ctx, String name, Object value) throws NamingException {
108        Name n = ctx.getNameParser("").parse(name);
109        rebind(ctx, n, value);
110    }
111
112    /**
113     * Rebind val to name in ctx, and make sure that all intermediate contexts exist
114     *
115     * @param ctx the parent JNDI Context under which value will be bound
116     * @param name the name relative to ctx where value will be bound
117     * @param value the value to bind.
118     * @throws NamingException for any error
119     */
120    public static void rebind(Context ctx, Name name, Object value) throws NamingException {
121        int size = name.size();
122        String atom = name.get(size - 1);
123        Context parentCtx = createSubcontext(ctx, name.getPrefix(size - 1));
124        parentCtx.rebind(atom, value);
125    }
126
127    /**
128     * Unbinds a name from ctx, and removes parents if they are empty
129     *
130     * @param ctx the parent JNDI Context under which the name will be unbound
131     * @param name The name to unbind
132     * @throws NamingException for any error
133     */
134    public static void unbind(Context ctx, String name) throws NamingException {
135        unbind(ctx, ctx.getNameParser("").parse(name));
136    }
137
138    /**
139     * Unbinds a name from ctx, and removes parents if they are empty
140     *
141     * @param ctx the parent JNDI Context under which the name will be unbound
142     * @param name The name to unbind
143     * @throws NamingException for any error
144     */
145    public static void unbind(Context ctx, Name name) throws NamingException {
146        ctx.unbind(name); // unbind the end node in the name
147        int sz = name.size();
148        // walk the tree backwards, stopping at the domain
149        while (--sz > 0) {
150            Name pname = name.getPrefix(sz);
151            try {
152                ctx.destroySubcontext(pname);
153            } catch (NamingException e) {
154                log.error(e, e);
155                break;
156            }
157        }
158    }
159
160}