
import java.util.*;
import java.io.*;
import java.net.*;
import java.rmi.*;

import javax.mail.*;
import javax.mail.internet.*;

import org.apache.soap.*;
import org.apache.soap.rpc.*;
import org.apache.soap.util.*;
import org.w3c.dom.*;
import javax.mail.*;

import org.apache.soap.transport.http.SOAPHTTPConnection;

public class Client4 {

    final static int STRING_TYPE      = 0;
    final static int STRINGS_TYPE     = 1;
    final static int BOOL_TYPE        = 2;
    final static int XML_LITERAL_TYPE = 3;
    final static int MIME_TYPE        = 4;

    public Client4() {
	/*
	 * In case of using proxy, set proxy host and port, please!
	 */
	/*
	SOAPHTTPConnection conn = new SOAPHTTPConnection();
	conn.setProxyHost("***************");
	conn.setProxyPort(8080);
	call.setSOAPTransport(conn);
	*/
    }
    
    // Apache-Soap Access point
    private static String serviceUrlString="http://pdbjs8.protein.osaka-u.ac.jp/soap/servlet/messagerouter";

    // PDBjSOAPService€Îurn
    private static String taminoSoapUrl="urn:PDBjSOAPServiceX";

    // PDBjSOAPService Databse URL
    private static String dbURL = "http://pdbjs8.protein.osaka-u.ac.jp/tamino/pdbMLplus";

    // PDBjSOAPService Database Collection name
    private static String colName = "pdbMLplus_Collection";

    private static URL serviceUrl=null;
    private Call call = new Call ();

    public static void printUsage()
    {
        System.out.println("Usage:java Client4 [options] (parameter...)");
	System.err.println("options: ");
	System.err.println("------- api version & echo -------");
	System.err.println(" 0 : call method is getapiversion");
	System.err.println(" 1 : call method is getserverapiversion");
	System.err.println(" 2 : call method is getserverversion");
	System.err.println(" 3 : call method is getserverecho");
	System.err.println(" 4 : call method is getservertime");
	System.err.println(" 5 : call method is isserveralive");
	System.err.println("------- metadata access -------");
	System.err.println(" 6                   : call method is getcollectionnames");
	System.err.println(" 7  (collectionname) : call method is getschmenames");
	System.err.println(" 8  (collectionname, schemaname) : call method is getdoctypenames");
	System.err.println(" 9  (collectionname, schemaname) : call method is getschema");
	System.err.println("");
    }


    public static void main(String[] args) 
	throws SOAPException, MalformedURLException 
    {
	String funcName = "";
	int flg         = 0;
	Object[] parms  = null;

	if (args.length == 0) {
	    printUsage();
	    System.exit(0);
	}

	for (int i = 0 ; i < args.length ; ++i) {
            if (args[i].equalsIgnoreCase("-h") ||
                args[i].equalsIgnoreCase("-help")) {
                if (args[0].equals("-h") == true ||
                    args[0].equals("-help") == true) {
                    printUsage();
                    System.exit(0);
                }
            } else {
		int opt = Integer.parseInt(args[i]);
		switch(opt) {
		case 0:   
		    funcName = "getapiversion";	     
		    flg      = STRING_TYPE;
		    break;
		case 1:   
		    funcName = "getserverapiversion";
		    flg      = STRING_TYPE;
		    break;
		case 2:   
		    funcName = "getserverversion";
		    flg      = STRING_TYPE;
		    break;
		case 3:   
		    funcName = "getserverecho";
		    flg      = STRINGS_TYPE;
		    break;
		case 4:   
		    funcName = "getservertime";
		    flg      = STRINGS_TYPE;
		    break;
		case 5:   
		    funcName = "isserveralive";
		    flg      = BOOL_TYPE;
		    break;
		case 6:   
		    funcName = "getcollectionnames";
		    flg      = STRINGS_TYPE;
		    break;
		case 7:   
		    funcName = "getschemanames";
		    flg      = STRINGS_TYPE;
		    if (++i == args.length) {
			System.err.println("error: Missing argument to " 
					   + args[i-1] + " option.");
			printUsage();
			System.exit(0);
		    }
		    parms = new String[] { args[i] };
		    break;
		case 8:   
		    funcName = "getdoctypenames";
		    flg      = STRINGS_TYPE;
		    ++i;
		    if ((i == args.length) || ((i+1) == args.length)) {
			System.err.println("error: Missing argument to " 
					   + args[i-1] + " option.");
			printUsage();
			System.exit(0);
		    }
		    parms = new String[] { args[i++], args[i] };
		    break;
		case 9:
		    funcName = "getschema";
		    flg      = XML_LITERAL_TYPE;
		    ++i;
		    if ((i == args.length) || ((i+1) == args.length)) {
			System.err.println("error: Missing argument to " 
					   + args[i-1] + " option.");
			printUsage();
			System.exit(0);
		    }
		    parms = new String[] { args[i++], args[i] };
		    break;
		default:  
		    printUsage();
		    System.exit(0);
		    break;
		}
	    }
        }
	
	Client4 cl = new Client4();

	// Database connect
	cl.start();

	if (funcName.length() > 0) {
	    cl.exec_func(funcName, flg, parms);
	}

	// Database disconnect
	cl.end();

    }

    /*
     * Database connect
     */
    public void start()
	throws SOAPException, MalformedURLException 
    {
	serviceUrl=new URL(serviceUrlString);
	Vector response=new Vector();
	
        // Database connect
	invoke("connect", new String[] { dbURL, "", "" }, response);
	
        // Set Collection name
	invoke("setaccesslocation", new String[]{ colName }, response);
    }

    void exec_func(String funcName, int ret_flg, Object[] parms)
	throws SOAPException, MalformedURLException 
    {
	Vector response=new Vector();
	System.out.println("------ func name [" + funcName + "] -------");
	invoke(funcName, 
	       parms, 
	       response);

	switch(ret_flg) {
	case STRING_TYPE:
	    String retStr = (String)response.get(0);
	    System.out.println("     [" + retStr + "]");
	    break;
	case STRINGS_TYPE:
	    String[] sList=(String[])(response.get(0));
	    if (sList != null) {
		if (funcName.equals("getcollectionnames")) {
		    System.out.println(" ret [0] = [" + sList[sList.length-1] + "]");
		} else {
		    for (int i = 0 ; i < sList.length ; ++i) {
			System.out.println(" ret [" + i + "] = [" + sList[i] + "]");
		    }
		}
	    }
	    break;
	case BOOL_TYPE:
	    Boolean bRet = (Boolean)response.get(0);
	    System.out.println("     [" + bRet + "]");
	    break;
	case XML_LITERAL_TYPE:
	    Node node =(Element)response.get(0);
	    System.out.println(org.apache.soap.util.xml.DOMWriter.nodeToString(node));
	    break;
	case MIME_TYPE:
	    for (int i=0;i<response.size();i++) {
		System.out.println(((StringBuffer)response.get(i)).toString());
	    }
	    break;
	}
    }

    /**
     * Database disconnect
     */
    public void end()
	throws SOAPException, MalformedURLException 
    {
	Vector response=new Vector();

	// Database disconnect
	invoke("disconnect", null, response);
    }
	
    /*
     * SOAP Service call
     */
    public void invoke(String method, Object [] parms, Vector vec)
	throws SOAPException 
    {
    	// Set Target URI
        call.setTargetObjectURI (taminoSoapUrl);

	// Set Soap method
        call.setMethodName (method);

	// Set Encoding Style
        call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);

	// Set Parameter
        call.setParams(null);
        if (parms!=null) {
	    Vector vecParms = new Vector ();
            for (int i=0;i<parms.length;i++) {

            	if ((parms[i] instanceof Element)) {
		    call.setEncodingStyleURI(Constants.NS_URI_LITERAL_XML);
            	}
            	Class parmClass=parms[i].getClass();

		if (parms[i] instanceof Element)
		    parmClass=Element.class;
		vecParms.addElement (new Parameter("parm", parmClass, parms[i], null));
            }
            // Set 
            call.setParams (vecParms);
        }
        
        // Service call
        Response resp = call.invoke (serviceUrl, "");
        // error
        if (resp.generatedFault ()) {
          Fault fault = resp.getFault ();
          throw new SOAPException(fault.getFaultCode(),
				  fault.getFaultString());
        }

        vec.clear();
        
        // set return value
        Parameter result = resp.getReturnValue ();
        if (result!=null && result.getValue()!=null) {
	    vec.add(result.getValue());
        }
	
        Vector internal=resp.getParams();
        if (internal!=null) {
	    for (int i=0;i<internal.size();i++) {
		vec.add(((Parameter)internal.get(i)).getValue());
	    }
        }
    	// copy multipart entries
        try {
	    for (int i=0;i<resp.getPartCount();i++) {
		// get the mimebodypart
		MimeBodyPart mbp=(MimeBodyPart)resp.getBodyPart(i);
		// and if it is not the same as the root (which is ignored, because it is already processed above)
		if (i==0)
		    continue;
		// add the bodypart as StringBuffer to the list
		// all StringBuffers can later be identified as Mime simply by their object type
		StringBuffer sb=new StringBuffer((String)mbp.getContent());
		vec.add(sb);
	    }
        }catch (Exception e) {System.err.println(e);}
        return;
    }
}

