1 package org.apache.maven.continuum.xmlrpc.server;
2
3 import java.lang.reflect.InvocationTargetException;
4 import java.lang.reflect.Method;
5
6 import org.apache.xmlrpc.XmlRpcException;
7 import org.apache.xmlrpc.XmlRpcHandler;
8 import org.apache.xmlrpc.XmlRpcRequest;
9 import org.apache.xmlrpc.common.TypeConverter;
10 import org.apache.xmlrpc.common.TypeConverterFactory;
11 import org.apache.xmlrpc.common.XmlRpcNotAuthorizedException;
12 import org.apache.xmlrpc.metadata.Util;
13 import org.apache.xmlrpc.server.AbstractReflectiveHandlerMapping;
14 import org.apache.xmlrpc.server.RequestProcessorFactoryFactory;
15 import org.codehaus.plexus.PlexusContainer;
16 import org.codehaus.plexus.component.repository.exception.ComponentLifecycleException;
17
18
19
20
21
22 public class ContinuumXmlRpcMetaDataHandler
23 implements XmlRpcHandler
24 {
25 private static class MethodData
26 {
27 final Method method;
28
29 final TypeConverter[] typeConverters;
30
31 MethodData( Method pMethod, TypeConverterFactory pTypeConverterFactory )
32 {
33 method = pMethod;
34 Class[] paramClasses = method.getParameterTypes();
35 typeConverters = new TypeConverter[paramClasses.length];
36 for ( int i = 0; i < paramClasses.length; i++ )
37 {
38 typeConverters[i] = pTypeConverterFactory.getTypeConverter( paramClasses[i] );
39 }
40 }
41 }
42
43 private final AbstractReflectiveHandlerMapping mapping;
44
45 private final MethodData[] methods;
46
47 private final Class clazz;
48
49 private final RequestProcessorFactoryFactory.RequestProcessorFactory requestProcessorFactory;
50
51 private final String[][] signatures;
52
53 private final String methodHelp;
54
55 private final PlexusContainer container;
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 public ContinuumXmlRpcMetaDataHandler( AbstractReflectiveHandlerMapping pMapping,
74 TypeConverterFactory pTypeConverterFactory, Class pClass,
75 RequestProcessorFactoryFactory.RequestProcessorFactory pFactory,
76 Method[] pMethods, String[][] signatures, String methodHelp,
77 PlexusContainer container )
78 {
79 mapping = pMapping;
80 clazz = pClass;
81 methods = new MethodData[pMethods.length];
82 requestProcessorFactory = pFactory;
83 for ( int i = 0; i < methods.length; i++ )
84 {
85 methods[i] = new MethodData( pMethods[i], pTypeConverterFactory );
86 }
87 this.signatures = signatures;
88 this.methodHelp = methodHelp;
89 this.container = container;
90 }
91
92 private Object getInstance( XmlRpcRequest pRequest )
93 throws XmlRpcException
94 {
95 return requestProcessorFactory.getRequestProcessor( pRequest );
96 }
97
98 public Object execute( XmlRpcRequest pRequest )
99 throws XmlRpcException
100 {
101 AbstractReflectiveHandlerMapping.AuthenticationHandler authHandler = mapping.getAuthenticationHandler();
102 if ( authHandler != null && !authHandler.isAuthorized( pRequest ) )
103 {
104 throw new XmlRpcNotAuthorizedException( "Not authorized" );
105 }
106 Object[] args = new Object[pRequest.getParameterCount()];
107 for ( int j = 0; j < args.length; j++ )
108 {
109 args[j] = pRequest.getParameter( j );
110 }
111 Object instance = getInstance( pRequest );
112 for ( MethodData methodData : methods )
113 {
114 TypeConverter[] converters = methodData.typeConverters;
115 if ( args.length == converters.length )
116 {
117 boolean matching = true;
118 for ( int j = 0; j < args.length; j++ )
119 {
120 if ( !converters[j].isConvertable( args[j] ) )
121 {
122 matching = false;
123 break;
124 }
125 }
126 if ( matching )
127 {
128 for ( int j = 0; j < args.length; j++ )
129 {
130 args[j] = converters[j].convert( args[j] );
131 }
132 return invoke( instance, methodData.method, args );
133 }
134 }
135 }
136 throw new XmlRpcException( "No method matching arguments: " + Util.getSignature( args ) );
137 }
138
139 private Object invoke( Object pInstance, Method pMethod, Object[] pArgs )
140 throws XmlRpcException
141 {
142 try
143 {
144 return pMethod.invoke( pInstance, pArgs );
145 }
146 catch ( IllegalAccessException e )
147 {
148 throw new XmlRpcException( "Illegal access to method " + pMethod.getName() + " in class " + clazz.getName(),
149 e );
150 }
151 catch ( IllegalArgumentException e )
152 {
153 throw new XmlRpcException(
154 "Illegal argument for method " + pMethod.getName() + " in class " + clazz.getName(), e );
155 }
156 catch ( InvocationTargetException e )
157 {
158 Throwable t = e.getTargetException();
159 if ( t instanceof XmlRpcException )
160 {
161 throw (XmlRpcException) t;
162 }
163 throw new XmlRpcException(
164 "Failed to invoke method " + pMethod.getName() + " in class " + clazz.getName() + ": " + t.getMessage(),
165 t );
166 }
167 finally
168 {
169 try
170 {
171 container.release( pInstance );
172 }
173 catch ( ComponentLifecycleException e )
174 {
175
176 }
177 }
178 }
179
180 public String[][] getSignatures()
181 throws XmlRpcException
182 {
183 return signatures;
184 }
185
186 public String getMethodHelp()
187 throws XmlRpcException
188 {
189 return methodHelp;
190 }
191
192 }