001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.camel.impl;
018
019import java.util.Hashtable;
020import java.util.LinkedHashMap;
021import java.util.LinkedHashSet;
022import java.util.Map;
023import java.util.Set;
024import javax.naming.Context;
025import javax.naming.InitialContext;
026import javax.naming.NameClassPair;
027import javax.naming.NameNotFoundException;
028import javax.naming.NamingEnumeration;
029import javax.naming.NamingException;
030
031import org.apache.camel.NoSuchBeanException;
032import org.apache.camel.RuntimeCamelException;
033import org.apache.camel.spi.Registry;
034
035/**
036 * A {@link Registry} implementation which looks up the objects in JNDI
037 */
038public class JndiRegistry implements Registry {
039    private Context context;
040
041    public JndiRegistry() {
042    }
043
044    public JndiRegistry(Context context) {
045        this.context = context;
046    }
047
048    public <T> T lookupByNameAndType(String name, Class<T> type) {
049        Object answer = lookupByName(name);
050
051        // just to be safe
052        if (answer == null) {
053            return null;
054        }
055
056        try {
057            return type.cast(answer);
058        } catch (Throwable e) {
059            String msg = "Found bean: " + name + " in JNDI Context: " + context
060                    + " of type: " + answer.getClass().getName() + " expected type was: " + type;
061            throw new NoSuchBeanException(name, msg, e);
062        }
063    }
064
065    public Object lookupByName(String name) {
066        try {
067            return getContext().lookup(name);
068        } catch (NameNotFoundException e) {
069            return null;
070        } catch (NamingException e) {
071            return null;
072        }
073    }
074
075    public <T> Map<String, T> findByTypeWithName(Class<T> type) {
076        Map<String, T> answer = new LinkedHashMap<String, T>();
077        try {
078            NamingEnumeration<NameClassPair> list = getContext().list("");
079            while (list.hasMore()) {
080                NameClassPair pair = list.next();
081                Object instance = context.lookup(pair.getName());
082                if (type.isInstance(instance)) {
083                    answer.put(pair.getName(), type.cast(instance));
084                }
085            }
086        } catch (NamingException e) {
087            // ignore
088        }
089
090        return answer;
091    }
092
093    public <T> Set<T> findByType(Class<T> type) {
094        Set<T> answer = new LinkedHashSet<T>();
095        try {
096            NamingEnumeration<NameClassPair> list = getContext().list("");
097            while (list.hasMore()) {
098                NameClassPair pair = list.next();
099                Object instance = context.lookup(pair.getName());
100                if (type.isInstance(instance)) {
101                    answer.add(type.cast(instance));
102                }
103            }
104        } catch (NamingException e) {
105            // ignore
106        }
107        return answer;
108    }
109
110    public Object lookup(String name) {
111        return lookupByName(name);
112    }
113
114    public <T> T lookup(String name, Class<T> type) {
115        return lookupByNameAndType(name, type);
116    }
117
118    public <T> Map<String, T> lookupByType(Class<T> type) {
119        return findByTypeWithName(type);
120    }
121
122    public void bind(String name, Object object) {
123        try {
124            getContext().bind(name, object);
125        } catch (NamingException e) {
126            throw new RuntimeCamelException(e);
127        }
128    }
129
130    public void close() throws NamingException {
131        if (context != null) {
132            context.close();
133        }
134    }
135
136    public Context getContext() throws NamingException {
137        if (context == null) {
138            context = createContext();
139        }
140        return context;
141    }
142
143    public void setContext(Context context) {
144        this.context = context;
145    }
146
147    protected Context createContext() throws NamingException {
148        Hashtable<?, ?> properties = new Hashtable<Object, Object>(System.getProperties());
149        return new InitialContext(properties);
150    }
151}