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.xbean.naming.reference;
018
019import java.util.LinkedHashMap;
020import java.util.Map;
021
022import javax.naming.NamingException;
023import javax.naming.Reference;
024import javax.naming.Context;
025
026import org.apache.xbean.naming.context.ContextUtil;
027
028/**
029 * @version $Rev: 355877 $ $Date: 2005-12-10 18:48:27 -0800 (Sat, 10 Dec 2005) $
030 */
031public class CachingReference extends SimpleReference {
032
033    public static Object wrapReference(String fullName, Object value, Context context) {
034        if (value instanceof Reference && !(value instanceof CachingReference)) {
035            return new CachingReference(fullName, (Reference)value, context);
036        }
037        return value;
038    }
039
040    public static Map<String, Object> wrapReferences(Map<String, Object> bindings, Context context) {
041        LinkedHashMap<String, Object> newBindings = new LinkedHashMap<String, Object>(bindings);
042        for (Map.Entry<String, Object> entry : bindings.entrySet()) {
043            String name = entry.getKey();
044            Object value = entry.getValue();
045            if (value instanceof Reference && !(value instanceof CachingReference)) {
046                newBindings.put(name, new CachingReference(name, (Reference) value, context));
047            }
048        }
049        return newBindings;
050    }
051
052    private final Object lock = new Object();
053    private final String stringName;
054    private final Context context;
055    private final Reference reference;
056    private final String className;
057    private Object value;
058
059    public CachingReference(String fullName, Reference reference, Context context) {
060        this.stringName = fullName;
061        this.reference = reference;
062        className = reference.getClassName();
063        this.context = context;
064    }
065
066    public Object getContent() throws NamingException {
067        synchronized(lock) {
068            if (value == null) {
069                value = ContextUtil.resolve(reference, stringName, null, context);
070            }
071            return value;
072        }
073    }
074
075    public String getClassName() {
076        return className;
077    }
078}