package tutorial.sample27;

import java.io.IOException;

import java.net.URL;

import java.util.Iterator;

import java.rmi.RemoteException;

import javax.xml.soap.SOAPElementFactory;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;

import javax.xml.soap.SOAPConstants;
import javax.xml.rpc.ServiceFactory;
import javax.xml.rpc.Service;
import javax.xml.rpc.Call;
import javax.xml.rpc.ParameterMode;
import javax.xml.rpc.ServiceException;

import javax.xml.namespace.QName;

import javax.xml.rpc.encoding.TypeMapping;
import javax.xml.rpc.encoding.TypeMappingRegistry;

import weblogic.webservice.encoding.GenericTypeMapping;
import weblogic.webservice.extensions.WLCall;


public class Main{
  
  public static void main( String[] args ){
    try{
      new Main().invoke( args[0] );
    }catch( Exception e ){
      e.printStackTrace();
    }
  }

  public void invoke( String url ) 
    throws RemoteException, ServiceException, IOException, SOAPException{

    System.setProperty( "javax.xml.rpc.ServiceFactory",
        "weblogic.webservice.core.rpc.ServiceFactoryImpl" );

    ServiceFactory factory = ServiceFactory.newInstance();

    QName serviceName = new QName( "http://soapinterop.org/", "SimpleTest" );

    Service service = factory.createService( new URL( url ), serviceName );

    TypeMappingRegistry registry = service.getTypeMappingRegistry(); 
    registry.registerDefault( new GenericTypeMapping() ); 

    System.out.println( "+ Service: " + service.getServiceName() );

    for( Iterator it = service.getPorts(); it.hasNext(); ){
      QName portName = (QName)it.next();
      System.out.println( "  + Port: " + portName );
      Call[] calls = service.getCalls( portName );
      printCalls( calls );
    }

    callEchoStruct( service );
  }

  private void callEchoStruct( Service service ) 
    throws ServiceException, SOAPException, RemoteException{

    QName portName = new QName( "http://soapinterop.org/", "SimpleTestSoap" );
    QName operationName = new QName( "http://soapinterop.org/", "echoStruct" );

    Call call = service.createCall( portName, operationName );

    SOAPElementFactory soapFactory = SOAPElementFactory.newInstance();
    SOAPElement input = soapFactory.create( "inputStruct" );
    input.addChildElement( "varInt" ).addTextNode( "1234" );
    input.addChildElement( "varString" ).addTextNode( "hi there" );
    input.addChildElement( "varFloat" ).addTextNode( "123.456" );

    SOAPElement output = (SOAPElement)call.invoke( new Object[]{input} );

    System.out.println( "Result got from server:" + output );
  }

  private void printCalls( Call[] calls ){
    for( int i=0; i<calls.length; i++ ){
      Call call = calls[i];
      System.out.println( "    + Operation :" + call.getOperationName() ); 
      printParameters( (WLCall)call );
      
      if( call.getReturnType() != null ){
        System.out.println( "      + Return Type:" + call.getReturnType() ); 
      }

      System.out.println( "" ); 
    }
  }

  private void printParameters( WLCall call ){
    for( Iterator it = call.getParameterNames(); it.hasNext(); ){
      String name = (String)it.next();
      System.out.println( "      + Part :" + name ); 

      System.out.println( "        - Java Type :" + 
          call.getParameterJavaType( name ) ); 

      System.out.println( "        - Mode :" + 
          call.getParameterMode( name ) ); 

      System.out.println( "        - XML Type :" + 
          call.getParameterTypeByName( name ) ); 
    }
  }
}


