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