Package org.apache.geronimo.naming.enc

Source Code of org.apache.geronimo.naming.enc.EnterpriseNamingContext$Node

/**
*
* Copyright 2003-2004 The Apache Software Foundation
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/

package org.apache.geronimo.naming.enc;

import javax.naming.Context;
import javax.naming.LinkRef;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.Reference;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
* @version $Rev: 355877 $ $Date: 2005-12-11 03:48:27 +0100 (Sun, 11 Dec 2005) $
*/
public final class EnterpriseNamingContext extends AbstractReadOnlyContext {
    private final Map localBindings;

    private final Map globalBindings;

    public static Context createEnterpriseNamingContext(Map context) throws NamingException {
        return new EnterpriseNamingContext(context);
    }

    public EnterpriseNamingContext(Map context) throws NamingException {
        super("");
        validateBindings(context);
        preprocessBindings(context);

        Node rootContext = buildTree(context);

        Map localBindings = new HashMap(rootContext.size());
        for (Iterator iterator = rootContext.entrySet().iterator(); iterator.hasNext();) {
            Map.Entry entry = (Map.Entry) iterator.next();
            String name = (String) entry.getKey();
            Object value = entry.getValue();
            if (value instanceof Node) {
                Context nestedContext = new NestedEnterpriseNamingContext(name, (Node) value);
                localBindings.put(name, nestedContext);
            } else {
                localBindings.put(name, value);
            }
        }
        this.localBindings = Collections.unmodifiableMap(localBindings);


        Map globalBindings = buildGlobalBindings("", localBindings);
        this.globalBindings = Collections.unmodifiableMap(globalBindings);
    }

    private static void validateBindings(Map bindings) {
        for (Iterator iterator = bindings.entrySet().iterator(); iterator.hasNext();) {
            Map.Entry entry = (Map.Entry) iterator.next();
            String name = (String) entry.getKey();
            Object value = entry.getValue();
            if (value instanceof Context) {
                throw new IllegalArgumentException("EnterpriseNamingContext can not contain a nested Context object: name=" + name);
            }
            if (value instanceof LinkRef) {
                throw new IllegalArgumentException("EnterpriseNamingContext can not contain a nested LinkRef object: name=" + name);
            }
        }
    }

    private static void preprocessBindings(Map bindings) {
        for (Iterator iterator = new HashMap(bindings).entrySet().iterator(); iterator.hasNext();) {
            Map.Entry entry = (Map.Entry) iterator.next();
            String name = (String) entry.getKey();
            Object value = entry.getValue();
            if (value instanceof Reference) {
                bindings.put(name, new CachingReference(name, (Reference)value));
            }
        }
    }

    private static Node buildTree(Map context) throws NamingException {
        Node rootContext = new Node();

        // ENC must always contain an env context
        rootContext.put("env", new Node());

        for (Iterator iterator = context.entrySet().iterator(); iterator.hasNext();) {
            Map.Entry entry = (Map.Entry) iterator.next();
            String name = (String) entry.getKey();
            Object value = entry.getValue();

            Node parentContext = rootContext;

            Name compoundName = EnterpriseNamingContextNameParser.INSTANCE.parse(name);
            for (Enumeration parts = compoundName.getAll(); parts.hasMoreElements(); ) {
                String part = (String) parts.nextElement();
                // the last element in the path is the name of the value
                if (parts.hasMoreElements()) {
                    // nest context into parent
                    Node bindings = (Node) parentContext.get(part);
                    if (bindings == null) {
                        bindings = new Node();
                        parentContext.put(part, bindings);
                    }

                    parentContext = bindings;
                }
            }

            parentContext.put(compoundName.get(compoundName.size() - 1), value);
        }
        return rootContext;
    }

    private static Map buildGlobalBindings(String nameInNamespace, Map context) {
        String path = nameInNamespace;
        if (path.length() > 0) {
            path += "/";
        }

        Map globalBindings = new HashMap();
        for (Iterator iterator = context.entrySet().iterator(); iterator.hasNext();) {
            Map.Entry entry = (Map.Entry) iterator.next();
            String name = (String) entry.getKey();
            Object value = entry.getValue();
            if (value instanceof NestedEnterpriseNamingContext) {
                NestedEnterpriseNamingContext nestedContext = (NestedEnterpriseNamingContext)value;
                globalBindings.putAll(buildGlobalBindings(nestedContext.getNameInNamespace(), nestedContext.localBindings));
            }
            globalBindings.put(path + name, value);
        }
        return globalBindings;
    }

    protected Map getGlobalBindings() {
        return globalBindings;
    }

    protected Map getLocalBindings() {
        return localBindings;
    }

    /**
     * Nested context which shares the global bindings map.
     */
    public final class NestedEnterpriseNamingContext extends AbstractReadOnlyContext {
        private final Map localBindings;

        public NestedEnterpriseNamingContext(String nameInNamespace, Node bindings) {
            super(nameInNamespace);
            if (nameInNamespace.length() == 0) throw new IllegalArgumentException("nameInNamespace is empty");

            Map localBindings = new HashMap(bindings.size());
            for (Iterator iterator = bindings.entrySet().iterator(); iterator.hasNext();) {
                Map.Entry entry = (Map.Entry) iterator.next();
                String name = (String) entry.getKey();
                Object value = entry.getValue();
                if (value instanceof Node) {
                    Context context = new NestedEnterpriseNamingContext(nameInNamespace + "/" + name, (Node) value);
                    localBindings.put(name, context);
                } else {
                    localBindings.put(name, value);
                }
            }
            this.localBindings = Collections.unmodifiableMap(localBindings);
        }

        protected Map getGlobalBindings() {
            return globalBindings;
        }

        protected Map getLocalBindings() {
            return localBindings;
        }
    }

    /**
     * Lame subclass of hashmap used to differentiate between a Map in the context an a nested element during tree building
     */
    private static final class Node extends HashMap {
    }
}
TOP

Related Classes of org.apache.geronimo.naming.enc.EnterpriseNamingContext$Node

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.