View Javadoc

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          // TODO: go through superclasses, stopping at Object.class
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         // Handle array'd types.
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         // If we are a enocded, use the encoded type mapping, else just use XSD
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 }