View Javadoc

1   /**********************************************************************
2    * WSIFOperation_EJOE.java
3    * created on 13.07.2006 by netseeker
4    * $Source$
5    * $Date$
6    * $Revision$
7    *
8    * ====================================================================
9    *
10   *  Copyright 2006 netseeker aka Michael Manske
11   *
12   *  Licensed under the Apache License, Version 2.0 (the "License");
13   *  you may not use this file except in compliance with the License.
14   *  You may obtain a copy of the License at
15   *
16   *      http://www.apache.org/licenses/LICENSE-2.0
17   *
18   *  Unless required by applicable law or agreed to in writing, software
19   *  distributed under the License is distributed on an "AS IS" BASIS,
20   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21   *  See the License for the specific language governing permissions and
22   *  limitations under the License.
23   * ====================================================================
24   *
25   * This file is part of the EJOE framework.
26   * For more information on the author, please see
27   * <http://www.manskes.de/>.
28   *
29   *********************************************************************/
30  
31  package de.netseeker.ejoe.ext.wsif;
32  
33  import java.util.ArrayList;
34  import java.util.Iterator;
35  import java.util.List;
36  import java.util.Map;
37  import java.util.Vector;
38  
39  import javax.wsdl.BindingOperation;
40  import javax.wsdl.BindingOutput;
41  import javax.wsdl.Operation;
42  import javax.wsdl.OperationType;
43  import javax.wsdl.Part;
44  
45  import org.apache.wsif.WSIFException;
46  import org.apache.wsif.WSIFMessage;
47  import org.apache.wsif.WSIFPort;
48  import org.apache.wsif.base.WSIFDefaultOperation;
49  import org.apache.wsif.logging.Trc;
50  
51  import de.netseeker.ejoe.EJClient;
52  import de.netseeker.ejoe.ext.wsif.wsdl.EJOEOperation;
53  import de.netseeker.ejoe.request.RemotingRequest;
54  import de.netseeker.ejoe.util.ContentStringBuilder;
55  
56  /***
57   * WSIF operation for EJOE
58   * 
59   * @author netseeker
60   * @since 0.3.9.1
61   */
62  public class WSIFOperation_EJOE extends WSIFDefaultOperation
63  {
64      private static final long             serialVersionUID = 1L;
65  
66      protected javax.wsdl.Port             fieldPortModel;
67  
68      protected WSIFPort_EJOE               fieldPort;
69  
70      protected javax.wsdl.BindingOperation fieldBindingOperationModel;
71  
72      protected EJOEOperation               fieldEJOEOperationModel;
73  
74      protected Operation                   wsdlOperation;
75  
76      protected String[]                    fieldInParameterNames;
77  
78      protected String[]                    fieldOutParameterNames;
79  
80      protected String                      fieldOutputMessageName;
81  
82      private WSIFOperation_EJOE(javax.wsdl.Port portModel, BindingOperation bindingOperationModel, WSIFPort_EJOE port,
83                                 EJOEOperation ejoeOperation)
84      {
85          fieldPortModel = portModel;
86          fieldBindingOperationModel = bindingOperationModel;
87          fieldPort = port;
88          fieldEJOEOperationModel = ejoeOperation;
89          initialize();
90      }
91  
92      /***
93       * @param portModel
94       * @param bindingOperationModel
95       * @param port
96       * @throws WSIFException
97       */
98      public WSIFOperation_EJOE(javax.wsdl.Port portModel, BindingOperation bindingOperationModel, WSIFPort_EJOE port)
99              throws WSIFException
100     {
101         Trc.entry( this, portModel, bindingOperationModel, port );
102 
103         fieldPortModel = portModel;
104         fieldBindingOperationModel = bindingOperationModel;
105         fieldPort = port;
106 
107         try
108         {
109             fieldEJOEOperationModel = (EJOEOperation) fieldBindingOperationModel.getExtensibilityElements().get( 0 );
110         }
111         catch ( Exception e )
112         {
113             Trc.exception( e );
114             throw new WSIFException( "Unable to resolve Java binding for operation '" + bindingOperationModel.getName()
115                     + '\'' );
116         }
117 
118         initialize();
119 
120         if ( Trc.ON ) Trc.exit( deep() );
121     }
122 
123     /***
124      * Create a new copy of this object. This is not a clone, since it does not copy the referenced objects as well.
125      */
126     public WSIFOperation_EJOE copy() throws WSIFException
127     {
128         Trc.entry( this );
129         WSIFOperation_EJOE woj = new WSIFOperation_EJOE( fieldPortModel, fieldBindingOperationModel, fieldPort,
130                                                          fieldEJOEOperationModel );
131         woj.wsdlOperation = wsdlOperation;
132 
133         Trc.exit( woj.deep() );
134         return woj;
135     }
136 
137     /*
138      * (non-Javadoc)
139      * 
140      * @see org.apache.wsif.base.WSIFDefaultOperation#getOperation()
141      */
142     protected Operation getOperation()
143     {
144         Trc.entry( this );
145 
146         if ( wsdlOperation == null )
147         {
148 
149             // <input> and <output> tags in binding operations are not mandatory
150             // so deal with null BindingInputs or BindingOutputs
151             String inputName = null;
152             if ( fieldBindingOperationModel.getBindingInput() != null )
153             {
154                 inputName = fieldBindingOperationModel.getBindingInput().getName();
155             }
156 
157             String outputName = null;
158             if ( fieldBindingOperationModel.getBindingOutput() != null )
159             {
160                 outputName = fieldBindingOperationModel.getBindingOutput().getName();
161             }
162 
163             // Build the parts list
164             // this.fieldBindingOperationModel.getBindingInput().getName(),
165             wsdlOperation = this.fieldPortModel.getBinding().getPortType()
166                     .getOperation( this.fieldBindingOperationModel.getName(), inputName, outputName );
167         }
168 
169         Trc.exit( wsdlOperation );
170 
171         return wsdlOperation;
172     }
173 
174     /*
175      * (non-Javadoc)
176      * 
177      * @see org.apache.wsif.base.WSIFDefaultOperation#executeRequestResponseOperation(org.apache.wsif.WSIFMessage,
178      *      org.apache.wsif.WSIFMessage, org.apache.wsif.WSIFMessage)
179      */
180     public boolean executeRequestResponseOperation( WSIFMessage input, WSIFMessage output, WSIFMessage fault )
181             throws WSIFException
182     {
183         Trc.entry( this, input, output, fault );
184 
185         EJClient client = this.fieldPort.getEJClient();
186 
187         try
188         {
189             Object[] arguments = null;
190             Object part = null;
191             Object result = null;
192 
193             if ( (fieldInParameterNames != null) && (fieldInParameterNames.length > 0) )
194             {
195                 arguments = new Object[fieldInParameterNames.length];
196                 for ( int i = 0; i < fieldInParameterNames.length; i++ )
197                 {
198                     try
199                     {
200                         part = input.getObjectPart( fieldInParameterNames[i] );
201                         arguments[i] = part;
202                     }
203                     catch ( WSIFException e )
204                     {
205                         Trc.exception( e );
206                         arguments[i] = null;
207                     }
208                 }
209             }
210 
211             try
212             {
213                 if ( fieldEJOEOperationModel.getInvocationType().equalsIgnoreCase( "reflection" ) )
214                 {
215                     RemotingRequest request = new RemotingRequest( fieldEJOEOperationModel.getClassName(),
216                                                                    fieldEJOEOperationModel.getMethodName(), arguments );
217                     Trc.event( this, "Processing remoting request ", request );
218                     result = client.execute( request );
219                 }
220                 else
221                 {
222                     Trc.event( this, "Processing default request with arguments ", ContentStringBuilder
223                             .toString( arguments ) );
224                     result = client.execute( arguments );
225                 }
226                 Trc.event( this, "Result from EJOE server is ", result );
227 
228             }
229             catch ( Exception e )
230             {
231                 Trc.exception( e );
232                 throw new WSIFException( "Exception occured while processing WSIF-Request!", e );
233             }
234 
235             // Deal with the output message
236             String outParameterName = null;
237             if ( fieldOutParameterNames.length == 1 )
238             {
239                 // Only one output part - it must be the object returned by the
240                 // remote service invocation
241                 output.setName( getOutputMessageName() );
242                 outParameterName = fieldOutParameterNames[0];
243                 if ( outParameterName != null )
244                 {
245                     output.setObjectPart( outParameterName, result );
246                 }
247             }
248             else if ( fieldOutParameterNames.length > 1 )
249             {
250                 if ( Map.class.isAssignableFrom( result.getClass() ) )
251                 {
252                     // Method should have returned a Map
253                     if ( !(result instanceof Map) )
254                     {
255                         throw new WSIFException( "Operation " + getOperation().getName()
256                                 + " defined as returning multiple parts "
257                                 + "and the ServerHandler did not return an instance of java.util.Map" );
258                     }
259 
260                     Map returnedMap = (Map) result;
261                     output.setName( getOutputMessageName() );
262 
263                     // Get multiple output parts from the map
264                     for ( int p = 0; p < fieldOutParameterNames.length; p++ )
265                     {
266                         String pName = fieldOutParameterNames[p];
267                         if ( returnedMap.containsKey( pName ) )
268                         {
269                             Object outPart = returnedMap.get( pName );
270                             output.setObjectPart( pName, outPart );
271                         }
272                         else
273                         {
274                             throw new WSIFException( "Operation " + getOperation().getName()
275                                     + " defined as returning multiple parts." + " Part " + pName
276                                     + " was missing from the Map returned by " + "the remote ServerHandler" );
277                         }
278                     }
279                 }
280                 else
281                 {
282                     // Backwards compatiblity - method returns just the output
283                     // part specified by returnPart
284                     output.setName( getOutputMessageName() );
285                     outParameterName = fieldOutParameterNames[0];
286                     if ( outParameterName != null )
287                     {
288                         output.setObjectPart( outParameterName, result );
289                     }
290                 }
291             }
292         }
293         finally
294         {
295             if ( client != null )
296             {
297                 this.fieldPort.returnEJClient( client );
298             }
299         }
300 
301         Trc.exit();
302         return true;
303     }
304 
305     /*
306      * (non-Javadoc)
307      * 
308      * @see org.apache.wsif.base.WSIFDefaultOperation#executeInputOnlyOperation(org.apache.wsif.WSIFMessage)
309      */
310     public void executeInputOnlyOperation( WSIFMessage input ) throws WSIFException
311     {
312         Trc.entry( this, input );
313         executeRequestResponseOperation( input, null, null );
314         Trc.exit();
315     }
316 
317     /***
318      * 
319      */
320     protected void initialize()
321     {
322         Trc.entry( this );
323         try
324         {
325             if ( fieldOutputMessageName == null )
326             {
327                 BindingOutput bindingOutputModel = fieldBindingOperationModel.getBindingOutput();
328                 if ( bindingOutputModel != null )
329                 {
330                     fieldOutputMessageName = bindingOutputModel.getName();
331                 }
332             }
333 
334             Operation operation = getOperation();
335             List parameterOrder = null;
336 
337             parameterOrder = fieldEJOEOperationModel.getParameterOrder();
338 
339             if ( parameterOrder == null )
340             {
341                 parameterOrder = operation.getParameterOrdering();
342             }
343 
344             if ( parameterOrder == null )
345             {
346                 List partList = operation.getInput().getMessage().getOrderedParts( null );
347                 parameterOrder = new Vector();
348                 Iterator partListIterator = partList.iterator();
349                 while ( partListIterator.hasNext() )
350                 {
351                     Part part = (Part) partListIterator.next();
352                     parameterOrder.add( part.getName() );
353                 }
354             }
355 
356             ArrayList argNames = new ArrayList();
357 
358             Iterator parameterIterator = parameterOrder.iterator();
359             while ( parameterIterator.hasNext() )
360             {
361                 String param = (String) parameterIterator.next();
362                 Part part = operation.getInput().getMessage().getPart( param );
363                 if ( part == null )
364                 {
365                     part = operation.getOutput().getMessage().getPart( param );
366                 }
367                 if ( part == null )
368                     throw new Exception( "Part '" + param
369                             + "' from parameterOrder not found in input or output message" );
370                 argNames.add( part.getName() );
371             }
372 
373             fieldInParameterNames = new String[argNames.size()];
374             for ( int i = 0; i < argNames.size(); i++ )
375             {
376                 fieldInParameterNames[i] = (String) argNames.get( i );
377             }
378 
379             // Deal with output parts if operation is Request-Response
380             if ( operation.getStyle().equals( OperationType.REQUEST_RESPONSE ) )
381             {
382                 argNames = new ArrayList();
383                 // Get the returnPart attribute if it exists
384                 String returnPart = fieldEJOEOperationModel.getReturnPart();
385                 Iterator outputPartsIterator = operation.getOutput().getMessage().getOrderedParts( null ).iterator();
386                 while ( outputPartsIterator.hasNext() )
387                 {
388                     Part part = (Part) outputPartsIterator.next();
389                     String partName = part.getName();
390                     if ( partName != null && returnPart != null && partName.equals( returnPart ) )
391                     {
392                         // Put return part first in the list of output parts
393                         argNames.add( 0, partName );
394                     }
395                     else
396                     {
397                         argNames.add( part.getName() );
398                     }
399                 }
400 
401                 // Populate an array of output message part names
402                 fieldOutParameterNames = new String[argNames.size()];
403                 for ( int i = 0; i < argNames.size(); i++ )
404                 {
405                     fieldOutParameterNames[i] = (String) argNames.get( i );
406                 }
407             }
408             else
409             {
410                 fieldOutParameterNames = new String[0];
411             }
412         }
413         catch ( Exception ex )
414         {
415             Trc.exception( ex );
416         }
417 
418         Trc.exit( ContentStringBuilder.toString( fieldInParameterNames ) + ':'
419                 + ContentStringBuilder.toString( fieldOutParameterNames ) );
420     }
421 
422     /*
423      * (non-Javadoc)
424      * 
425      * @see org.apache.wsif.base.WSIFDefaultOperation#getWSIFPort()
426      */
427     public WSIFPort getWSIFPort()
428     {
429         Trc.entry( this );
430         Trc.exit( fieldPort );
431         return fieldPort;
432     }
433 
434     protected String getOutputMessageName() throws WSIFException
435     {
436         Trc.entry( this );
437         if ( fieldOutputMessageName == null )
438         {
439             BindingOutput bindingOutputModel = fieldBindingOperationModel.getBindingOutput();
440             if ( bindingOutputModel != null )
441             {
442                 fieldOutputMessageName = bindingOutputModel.getName();
443             }
444         }
445         Trc.exit( fieldOutputMessageName );
446         return fieldOutputMessageName;
447     }
448 
449     /***
450      * @return
451      */
452     public String deep()
453     {
454         StringBuffer buff = new StringBuffer();
455         try
456         {
457             buff.append( super.toString() + ":\n" );
458             buff.append( "portModel:" + Trc.brief( fieldPortModel ) );
459             buff.append( " wsifPort_EJOE:" + fieldPort );
460             buff.append( " bindingOperationModel:" + Trc.brief( fieldBindingOperationModel ) );
461             buff.append( " EJOEOperation:" + fieldEJOEOperationModel );
462 
463             buff.append( Trc.brief( "inParameterNames", fieldInParameterNames ) );
464             buff.append( Trc.brief( "outParameterNames", fieldOutParameterNames ) );
465 
466             buff.append( " outputMessageName:" + fieldOutputMessageName );
467         }
468         catch ( Exception e )
469         {
470             Trc.exceptionInTrace( e );
471         }
472 
473         return buff.toString();
474     }
475 }