001    /**
002     *
003     * Copyright 2005 LogicBlaze, Inc.
004     *
005     * Licensed under the Apache License, Version 2.0 (the "License");
006     * you may not use this file except in compliance with the License.
007     * 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     *
017     **/
018    package org.logicblaze.lingo;
019    
020    import org.springframework.remoting.support.RemoteInvocationFactory;
021    import org.springframework.remoting.support.RemoteInvocation;
022    import org.aopalliance.intercept.MethodInvocation;
023    
024    import java.util.Map;
025    import java.util.HashMap;
026    import java.lang.reflect.Method;
027    
028    /**
029     * A factory of remote invocation instances which includes the extra
030     * Lingo metadata.
031     *
032     * @version $Revision: 1.1 $
033     */
034    public class LingoRemoteInvocationFactory implements RemoteInvocationFactory {
035        private static final MethodMetadata DEFAULT_METHOD_METADATA = new MethodMetadata(false);
036    
037        private MetadataStrategy metadataStrategy;
038        private Map cache = new HashMap();
039    
040        public LingoRemoteInvocationFactory(MetadataStrategy metadataStrategy) {
041            this.metadataStrategy = metadataStrategy;
042        }
043    
044        public RemoteInvocation createRemoteInvocation(MethodInvocation methodInvocation) {
045            MethodMetadata metadata = getMethodMetadata(methodInvocation);
046            return new LingoInvocation(methodInvocation, metadata);
047        }
048    
049        protected synchronized MethodMetadata getMethodMetadata(MethodInvocation methodInvocation) {
050            Method method = methodInvocation.getMethod();
051            MethodMetadata answer = (MethodMetadata) cache.get(method);
052            if (answer == null) {
053                if (metadataStrategy == null) {
054                    // TODO we could use a singleton here
055                    answer = DEFAULT_METHOD_METADATA;
056                }
057                else {
058                    answer = metadataStrategy.getMethodMetadata(method);
059                }
060                cache.put(method, answer);
061            }
062            return answer;
063        }
064        
065    }