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 java.lang.reflect.Method; 021 import java.rmi.Remote; 022 import java.util.EventListener; 023 import java.util.HashSet; 024 import java.util.Iterator; 025 import java.util.Set; 026 027 /** 028 * A simple metadata strategy which uses POJO naming conventions. 029 * 030 * By default all method invocations are synchronous to avoid surprising users of Spring Remoting. However 031 * if you set the {@link #setOneWayForVoidMethods(boolean)} value to true then all void methods which do 032 * not throw checked exceptions become asynchronous one way methods. 033 * 034 * <p/> 035 * Also any object which implements the {@link Remote} interface or the {@link EventListener} 036 * are assumed to be remote and so a remote proxy is used to allow remote notifications and asynchronous 037 * messaging. 038 * 039 * @version $Revision: 1.2 $ 040 */ 041 public class SimpleMetadataStrategy implements MetadataStrategy { 042 private boolean oneWayForVoidMethods; 043 private Set remoteTypes; 044 045 public SimpleMetadataStrategy() { 046 } 047 048 public SimpleMetadataStrategy(boolean oneWayForVoidMethods) { 049 this.oneWayForVoidMethods = oneWayForVoidMethods; 050 } 051 052 public MethodMetadata getMethodMetadata(Method method) { 053 boolean oneway = false; 054 if (oneWayForVoidMethods) { 055 oneway = method.getReturnType().equals(void.class) && method.getExceptionTypes().length == 0; 056 } 057 boolean[] remoteParams = null; 058 Class[] parameterTypes = method.getParameterTypes(); 059 int size = parameterTypes.length; 060 if (size > 0) { 061 remoteParams = new boolean[size]; 062 for (int i = 0; i < size; i++) { 063 remoteParams[i] = isRemoteParameter(method, parameterTypes[i], i); 064 } 065 } 066 return new MethodMetadata(oneway, remoteParams); 067 } 068 069 public boolean isOneWayForVoidMethods() { 070 return oneWayForVoidMethods; 071 } 072 073 public void setOneWayForVoidMethods(boolean oneWayForVoidMethods) { 074 this.oneWayForVoidMethods = oneWayForVoidMethods; 075 } 076 077 public Set getRemoteTypes() { 078 if (remoteTypes == null) { 079 remoteTypes = new HashSet(); 080 populateDefaultRemoteTypes(remoteTypes); 081 } 082 return remoteTypes; 083 } 084 085 086 public void setRemoteTypes(Set remoteTypes) { 087 this.remoteTypes = remoteTypes; 088 } 089 090 protected boolean isRemoteParameter(Method method, Class parameterType, int index) { 091 for (Iterator iter = getRemoteTypes().iterator(); iter.hasNext();) { 092 Class type = (Class) iter.next(); 093 if (type.isAssignableFrom(parameterType)) { 094 return true; 095 } 096 } 097 return false; 098 } 099 100 protected void populateDefaultRemoteTypes(Set remoteTypes) { 101 remoteTypes.add(Remote.class); 102 remoteTypes.add(EventListener.class); 103 } 104 }