1 package org.codehaus.xfire.java;
2
3 import java.lang.reflect.Method;
4 import java.lang.reflect.Modifier;
5 import java.util.ArrayList;
6 import java.util.Collection;
7 import java.util.Hashtable;
8 import java.util.List;
9 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
10 import org.codehaus.xfire.SOAPConstants;
11 import org.codehaus.xfire.XFireRuntimeException;
12 import org.codehaus.xfire.fault.FaultHandler;
13 import org.codehaus.xfire.java.mapping.TypeMapping;
14 import org.codehaus.xfire.java.mapping.TypeMappingRegistry;
15 import org.codehaus.xfire.plexus.PlexusService;
16
17 /***
18 * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a>
19 */
20 public abstract class AbstractJavaService
21 extends PlexusService
22 implements JavaService
23 {
24 private TypeMapping typeMapping;
25
26 private List allowedMethods;
27
28 private Class serviceClass;
29
30 private Hashtable operations;
31
32 protected static final String SERVICE_CLASS = "serviceClass";
33
34 protected static final String ALLOWED_METHODS= "allowedMethods";
35
36 private boolean autoTyped = false;
37
38 public AbstractJavaService()
39 {
40 super();
41 allowedMethods = new ArrayList();
42 operations = new Hashtable();
43 }
44
45 /***
46 * @param className
47 * @param string
48 */
49 public void setServiceClass( String className )
50 throws ClassNotFoundException
51 {
52 serviceClass = getClass().getClassLoader().loadClass( className );
53
54 initializeOperations();
55 }
56
57 /***
58 * @param serviceClass2
59 */
60 private void initializeOperations()
61 {
62 Method[] methods = serviceClass.getDeclaredMethods();
63
64
65
66 for ( int i = 0; i < methods.length; i++ )
67 {
68 Method method = methods[i];
69
70 String methodName = method.getName();
71
72 int modifiers = method.getModifiers();
73 if ( isAllowed( methodName )
74 &&
75 Modifier.isPublic(modifiers)
76 &&
77 !Modifier.isStatic(modifiers) )
78 {
79 addOperation( method );
80 }
81 }
82 }
83
84 /***
85 * @param i
86 * @param method
87 * @param methodName
88 */
89 private void addOperation( Method method )
90 {
91 Operation op = new Operation(method, this);
92
93 operations.put( method.getName(), op );
94 }
95
96 /***
97 * Determines whether or not to expose the specified method.
98 *
99 * @param methodName
100 * @return
101 */
102 private boolean isAllowed(String methodName)
103 {
104 return ( allowedMethods.size() == 0 || allowedMethods.contains(methodName) );
105 }
106
107 /***
108 * @see org.codehaus.xfire.java.JavaService#getOperation(java.lang.String, java.lang.String)
109 */
110 public Operation getOperation( String localName, String namespace )
111 {
112 return (Operation) operations.get( localName );
113 }
114
115 /***
116 * @see org.codehaus.xfire.java.JavaService#getOperations()
117 */
118 public Collection getOperations()
119 {
120 return operations.values();
121 }
122
123 /***
124 * @return Returns the allowedMethods.
125 */
126 public List getAllowedMethods()
127 {
128 return allowedMethods;
129 }
130
131 /***
132 * @param allowedMethods The allowedMethods to set.
133 */
134 public void setAllowedMethods(List allowedMethods)
135 {
136 this.allowedMethods = allowedMethods;
137 }
138
139 /***
140 * @return Returns the typeMapping.
141 */
142 public TypeMapping getTypeMapping()
143 {
144 return typeMapping;
145 }
146
147 /***
148 * @param typeMapping The typeMapping to set.
149 */
150 public void setTypeMapping(TypeMapping typeMapping)
151 {
152 this.typeMapping = typeMapping;
153 }
154
155 /***
156 * @return
157 */
158 public Class getServiceClass()
159 {
160 return serviceClass;
161 }
162
163 /***
164 * Load a class from the class loader.
165 *
166 * @param className The name of the class.
167 * @return The class.
168 * @throws Exception
169 */
170 protected Class loadClass( String className )
171 throws Exception
172 {
173
174 if ( className.endsWith("[]") )
175 {
176 className = "[L" + className.substring(0, className.length() - 2 ) + ";";
177 }
178
179 return getClass().getClassLoader().loadClass( className );
180 }
181
182 /***
183 * @see org.apache.avalon.framework.activity.Initializable#initialize()
184 */
185 public void initialize() throws Exception
186 {
187 TypeMapping tm = null;
188
189
190 if ( getUse().equals(SOAPConstants.USE_ECNODED) )
191 {
192 tm = getTypeMappingRegistry().createTypeMapping( SOAPConstants.SOAP11_ENCODED, autoTyped );
193 }
194 else
195 {
196 tm = getTypeMappingRegistry().createTypeMapping( SOAPConstants.XSD, autoTyped );
197 }
198
199 setTypeMapping( tm );
200 getTypeMappingRegistry().register( getDefaultNamespace(), tm );
201
202 super.initialize();
203 }
204
205 public TypeMappingRegistry getTypeMappingRegistry()
206 {
207 try
208 {
209 return (TypeMappingRegistry) getServiceLocator().lookup( TypeMappingRegistry.ROLE );
210 }
211 catch (ComponentLookupException e)
212 {
213 throw new RuntimeException( "There is no type mapping registry!", e );
214 }
215 }
216
217 public FaultHandler getFaultHandler()
218 {
219 try
220 {
221 return (FaultHandler) getServiceLocator().lookup( FaultHandler.ROLE, getFaultHandlerHint() );
222 }
223 catch (ComponentLookupException e)
224 {
225 throw new XFireRuntimeException( "Couldn't find fault handler!", e );
226 }
227 }
228
229 public boolean isAutoTyped()
230 {
231 return autoTyped;
232 }
233
234 public void setAutoTyped(boolean autoTyped)
235 {
236 this.autoTyped = autoTyped;
237 }
238 }