/*********************************************************************
* WSIFOperation_EJOE.java
* created on 13.07.2006 by netseeker
* $Source$
* $Date$
* $Revision$
*
* ====================================================================
*
* Copyright 2006 netseeker aka Michael Manske
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*
* This file is part of the EJOE framework.
* For more information on the author, please see
* <http://www.manskes.de/>.
*
*********************************************************************/
package de.netseeker.ejoe.ext.wsif;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import javax.wsdl.BindingOperation;
import javax.wsdl.BindingOutput;
import javax.wsdl.Operation;
import javax.wsdl.OperationType;
import javax.wsdl.Part;
import org.apache.wsif.WSIFException;
import org.apache.wsif.WSIFMessage;
import org.apache.wsif.WSIFPort;
import org.apache.wsif.base.WSIFDefaultOperation;
import org.apache.wsif.logging.Trc;
import de.netseeker.ejoe.EJClient;
import de.netseeker.ejoe.ext.wsif.wsdl.EJOEOperation;
import de.netseeker.ejoe.request.RemotingRequest;
import de.netseeker.ejoe.util.ContentStringBuilder;
/**
* WSIF operation for EJOE
*
* @author netseeker
* @since 0.3.9.1
*/
public class WSIFOperation_EJOE extends WSIFDefaultOperation
{
private static final long serialVersionUID = 1L;
protected javax.wsdl.Port fieldPortModel;
protected WSIFPort_EJOE fieldPort;
protected javax.wsdl.BindingOperation fieldBindingOperationModel;
protected EJOEOperation fieldEJOEOperationModel;
protected Operation wsdlOperation;
protected String[] fieldInParameterNames;
protected String[] fieldOutParameterNames;
protected String fieldOutputMessageName;
private WSIFOperation_EJOE(javax.wsdl.Port portModel, BindingOperation bindingOperationModel, WSIFPort_EJOE port,
EJOEOperation ejoeOperation)
{
fieldPortModel = portModel;
fieldBindingOperationModel = bindingOperationModel;
fieldPort = port;
fieldEJOEOperationModel = ejoeOperation;
initialize();
}
/**
* @param portModel
* @param bindingOperationModel
* @param port
* @throws WSIFException
*/
public WSIFOperation_EJOE(javax.wsdl.Port portModel, BindingOperation bindingOperationModel, WSIFPort_EJOE port)
throws WSIFException
{
Trc.entry( this, portModel, bindingOperationModel, port );
fieldPortModel = portModel;
fieldBindingOperationModel = bindingOperationModel;
fieldPort = port;
try
{
fieldEJOEOperationModel = (EJOEOperation) fieldBindingOperationModel.getExtensibilityElements().get( 0 );
}
catch ( Exception e )
{
Trc.exception( e );
throw new WSIFException( "Unable to resolve Java binding for operation '" + bindingOperationModel.getName()
+ '\'' );
}
initialize();
if ( Trc.ON ) Trc.exit( deep() );
}
/**
* Create a new copy of this object. This is not a clone, since it does not copy the referenced objects as well.
*/
public WSIFOperation_EJOE copy() throws WSIFException
{
Trc.entry( this );
WSIFOperation_EJOE woj = new WSIFOperation_EJOE( fieldPortModel, fieldBindingOperationModel, fieldPort,
fieldEJOEOperationModel );
woj.wsdlOperation = wsdlOperation;
Trc.exit( woj.deep() );
return woj;
}
/*
* (non-Javadoc)
*
* @see org.apache.wsif.base.WSIFDefaultOperation#getOperation()
*/
protected Operation getOperation()
{
Trc.entry( this );
if ( wsdlOperation == null )
{
// <input> and <output> tags in binding operations are not mandatory
// so deal with null BindingInputs or BindingOutputs
String inputName = null;
if ( fieldBindingOperationModel.getBindingInput() != null )
{
inputName = fieldBindingOperationModel.getBindingInput().getName();
}
String outputName = null;
if ( fieldBindingOperationModel.getBindingOutput() != null )
{
outputName = fieldBindingOperationModel.getBindingOutput().getName();
}
// Build the parts list
// this.fieldBindingOperationModel.getBindingInput().getName(),
wsdlOperation = this.fieldPortModel.getBinding().getPortType()
.getOperation( this.fieldBindingOperationModel.getName(), inputName, outputName );
}
Trc.exit( wsdlOperation );
return wsdlOperation;
}
/*
* (non-Javadoc)
*
* @see org.apache.wsif.base.WSIFDefaultOperation#executeRequestResponseOperation(org.apache.wsif.WSIFMessage,
* org.apache.wsif.WSIFMessage, org.apache.wsif.WSIFMessage)
*/
public boolean executeRequestResponseOperation( WSIFMessage input, WSIFMessage output, WSIFMessage fault )
throws WSIFException
{
Trc.entry( this, input, output, fault );
EJClient client = this.fieldPort.getEJClient();
try
{
Object[] arguments = null;
Object part = null;
Object result = null;
if ( (fieldInParameterNames != null) && (fieldInParameterNames.length > 0) )
{
arguments = new Object[fieldInParameterNames.length];
for ( int i = 0; i < fieldInParameterNames.length; i++ )
{
try
{
part = input.getObjectPart( fieldInParameterNames[i] );
arguments[i] = part;
}
catch ( WSIFException e )
{
Trc.exception( e );
arguments[i] = null;
}
}
}
try
{
if ( fieldEJOEOperationModel.getInvocationType().equalsIgnoreCase( "reflection" ) )
{
RemotingRequest request = new RemotingRequest( fieldEJOEOperationModel.getClassName(),
fieldEJOEOperationModel.getMethodName(), arguments );
Trc.event( this, "Processing remoting request ", request );
result = client.execute( request );
}
else
{
Trc.event( this, "Processing default request with arguments ", ContentStringBuilder
.toString( arguments ) );
result = client.execute( arguments );
}
Trc.event( this, "Result from EJOE server is ", result );
}
catch ( Exception e )
{
Trc.exception( e );
throw new WSIFException( "Exception occured while processing WSIF-Request!", e );
}
// Deal with the output message
String outParameterName = null;
if ( fieldOutParameterNames.length == 1 )
{
// Only one output part - it must be the object returned by the
// remote service invocation
output.setName( getOutputMessageName() );
outParameterName = fieldOutParameterNames[0];
if ( outParameterName != null )
{
output.setObjectPart( outParameterName, result );
}
}
else if ( fieldOutParameterNames.length > 1 )
{
if ( Map.class.isAssignableFrom( result.getClass() ) )
{
// Method should have returned a Map
if ( !(result instanceof Map) )
{
throw new WSIFException( "Operation " + getOperation().getName()
+ " defined as returning multiple parts "
+ "and the ServerHandler did not return an instance of java.util.Map" );
}
Map returnedMap = (Map) result;
output.setName( getOutputMessageName() );
// Get multiple output parts from the map
for ( int p = 0; p < fieldOutParameterNames.length; p++ )
{
String pName = fieldOutParameterNames[p];
if ( returnedMap.containsKey( pName ) )
{
Object outPart = returnedMap.get( pName );
output.setObjectPart( pName, outPart );
}
else
{
throw new WSIFException( "Operation " + getOperation().getName()
+ " defined as returning multiple parts." + " Part " + pName
+ " was missing from the Map returned by " + "the remote ServerHandler" );
}
}
}
else
{
// Backwards compatiblity - method returns just the output
// part specified by returnPart
output.setName( getOutputMessageName() );
outParameterName = fieldOutParameterNames[0];
if ( outParameterName != null )
{
output.setObjectPart( outParameterName, result );
}
}
}
}
finally
{
if ( client != null )
{
this.fieldPort.returnEJClient( client );
}
}
Trc.exit();
return true;
}
/*
* (non-Javadoc)
*
* @see org.apache.wsif.base.WSIFDefaultOperation#executeInputOnlyOperation(org.apache.wsif.WSIFMessage)
*/
public void executeInputOnlyOperation( WSIFMessage input ) throws WSIFException
{
Trc.entry( this, input );
executeRequestResponseOperation( input, null, null );
Trc.exit();
}
/**
*
*/
protected void initialize()
{
Trc.entry( this );
try
{
if ( fieldOutputMessageName == null )
{
BindingOutput bindingOutputModel = fieldBindingOperationModel.getBindingOutput();
if ( bindingOutputModel != null )
{
fieldOutputMessageName = bindingOutputModel.getName();
}
}
Operation operation = getOperation();
List parameterOrder = null;
parameterOrder = fieldEJOEOperationModel.getParameterOrder();
if ( parameterOrder == null )
{
parameterOrder = operation.getParameterOrdering();
}
if ( parameterOrder == null )
{
List partList = operation.getInput().getMessage().getOrderedParts( null );
parameterOrder = new Vector();
Iterator partListIterator = partList.iterator();
while ( partListIterator.hasNext() )
{
Part part = (Part) partListIterator.next();
parameterOrder.add( part.getName() );
}
}
ArrayList argNames = new ArrayList();
Iterator parameterIterator = parameterOrder.iterator();
while ( parameterIterator.hasNext() )
{
String param = (String) parameterIterator.next();
Part part = operation.getInput().getMessage().getPart( param );
if ( part == null )
{
part = operation.getOutput().getMessage().getPart( param );
}
if ( part == null )
throw new Exception( "Part '" + param
+ "' from parameterOrder not found in input or output message" );
argNames.add( part.getName() );
}
fieldInParameterNames = new String[argNames.size()];
for ( int i = 0; i < argNames.size(); i++ )
{
fieldInParameterNames[i] = (String) argNames.get( i );
}
// Deal with output parts if operation is Request-Response
if ( operation.getStyle().equals( OperationType.REQUEST_RESPONSE ) )
{
argNames = new ArrayList();
// Get the returnPart attribute if it exists
String returnPart = fieldEJOEOperationModel.getReturnPart();
Iterator outputPartsIterator = operation.getOutput().getMessage().getOrderedParts( null ).iterator();
while ( outputPartsIterator.hasNext() )
{
Part part = (Part) outputPartsIterator.next();
String partName = part.getName();
if ( partName != null && returnPart != null && partName.equals( returnPart ) )
{
// Put return part first in the list of output parts
argNames.add( 0, partName );
}
else
{
argNames.add( part.getName() );
}
}
// Populate an array of output message part names
fieldOutParameterNames = new String[argNames.size()];
for ( int i = 0; i < argNames.size(); i++ )
{
fieldOutParameterNames[i] = (String) argNames.get( i );
}
}
else
{
fieldOutParameterNames = new String[0];
}
}
catch ( Exception ex )
{
Trc.exception( ex );
}
Trc.exit( ContentStringBuilder.toString( fieldInParameterNames ) + ':'
+ ContentStringBuilder.toString( fieldOutParameterNames ) );
}
/*
* (non-Javadoc)
*
* @see org.apache.wsif.base.WSIFDefaultOperation#getWSIFPort()
*/
public WSIFPort getWSIFPort()
{
Trc.entry( this );
Trc.exit( fieldPort );
return fieldPort;
}
protected String getOutputMessageName() throws WSIFException
{
Trc.entry( this );
if ( fieldOutputMessageName == null )
{
BindingOutput bindingOutputModel = fieldBindingOperationModel.getBindingOutput();
if ( bindingOutputModel != null )
{
fieldOutputMessageName = bindingOutputModel.getName();
}
}
Trc.exit( fieldOutputMessageName );
return fieldOutputMessageName;
}
/**
* @return
*/
public String deep()
{
StringBuffer buff = new StringBuffer();
try
{
buff.append( super.toString() + ":\n" );
buff.append( "portModel:" + Trc.brief( fieldPortModel ) );
buff.append( " wsifPort_EJOE:" + fieldPort );
buff.append( " bindingOperationModel:" + Trc.brief( fieldBindingOperationModel ) );
buff.append( " EJOEOperation:" + fieldEJOEOperationModel );
buff.append( Trc.brief( "inParameterNames", fieldInParameterNames ) );
buff.append( Trc.brief( "outParameterNames", fieldOutParameterNames ) );
buff.append( " outputMessageName:" + fieldOutputMessageName );
}
catch ( Exception e )
{
Trc.exceptionInTrace( e );
}
return buff.toString();
}
}