1 /*
2  * Created on Jun 17, 2003
3  *
4  * To change the template for this generated file go to
5  * Window>Preferences>Java>Code Generation>Code and Comments
6  */
7 //TODO this class should impl interface so that it can be plug-in
8 //  impl of behavior that gets event(s) of type "data created"
9 //  transportd from client to the PO. PO then inspects contents
10//  of what came up over the wire and reacts by forwarding the 
11//  raw data or by useing the transported event to "PULL" the 
12//  data from the client or maybe even trigger a 3rd party 
13//  P2P session(s) amoung all subscribers and the producer.
14package com.borneo.net.soap;
15
16import java.io.File;
17import java.net.MalformedURLException;
18import java.net.URL;
19import java.rmi.RemoteException;
20import java.util.ArrayList;
21import java.util.Collection;
22import java.util.Iterator;
23import java.util.LinkedList;
24import java.util.Vector;
25
26import javax.activation.DataHandler;
27import javax.activation.FileDataSource;
28
29import javax.xml.namespace.QName;
30import javax.xml.rpc.ParameterMode;
31import javax.xml.rpc.ServiceException;
32import javax.xml.soap.AttachmentPart;
33import javax.xml.soap.Name;
34import javax.xml.soap.SOAPBody;
35import javax.xml.soap.SOAPBodyElement;
36import javax.xml.soap.SOAPConnection;
37import javax.xml.soap.SOAPElement;
38import javax.xml.soap.SOAPException;
39import javax.xml.soap.SOAPMessage;
40
41import org.apache.axis.AxisFault;
42import org.apache.axis.Constants;
43import org.apache.axis.Message;
44import org.apache.axis.MessageContext;
45import org.apache.axis.client.Call;
46import org.apache.axis.client.Service;
47import org.apache.axis.description.ParameterDesc;
48import org.apache.axis.encoding.TypeMapping;
49import org.apache.axis.encoding.TypeMappingRegistry;
50import org.apache.axis.encoding.TypeMappingRegistryImpl;
51import org.apache.axis.encoding.XMLType;
52import org.apache.axis.message.RPCElement;
53import org.apache.axis.message.RPCParam;
54import org.apache.axis.message.SOAPEnvelope;
55import org.apache.axis.soap.MessageFactoryImpl;
56import org.apache.axis.soap.SOAPConnectionFactoryImpl;
57import org.apache.log4j.Logger;
58import org.apache.log4j.PropertyConfigurator;
59
60import com.borneo.util.FileSelector;
61import com.borneo.util.POProperty;
62
63/** 
64 * This implementation uses following API's to PUSH data to Remote Node:
65 *   HTTP, SOAP, Apache AXIS, JAX-RPC, SAAJ or SwA.  
66 * Manager class for API's in above list. This class sits between the client app.
67 * where data is being created and the entire API collection that implements
68 * connectivity for distributing files in a data-interchange or PostOffice.
69 * @author r
70 * <p>CLIENT-SIDE uses SAAJ API for Web Services and "Soap with Attachments"
71 * 4 options for WS connections designated by property file key="ws.invocation.typ"
72 *   - diicall "invoke" supports parm "ArrayOFDataHandler" dynamic req'd
73 *       std msg call won't support the array ... had to patch w/ dii
74 *   - SoapMsg "call" single File supports non-array type DataHandlers in parms
75 *   - SoapMsg "call" FileSet supports array-OF-DataHandlers in parms 
76 * </p><p>
77 * According to SAAJ API rules, the client formats a SOAP msg that will
78 * get to the proper WS endpt and that will meet the signature of the
79 * requested method at that endpt. 
80 * see WSDL "service", "port", "operation" elements.
81 * </p><p>
82 * The Server is according to JAX-RPC so, according to SAAJ, the SOAP message
83 * constructed here in the client needs to conform to the server-side JAX-RPC signature.
84 * 
85 * The properties file has following directives:
86 * - 3 for "wsdl" concat these for the service Endpoint
87 * - 1 for "soap" operation or method called by RPC on server 
88 * - 1 for "ws" "connect" type  (dynamic or static msg call) 
89 *  - for the method called on the service class handling that endpt
90 *    useing these, go chek the method and it's argList... 
91 * The "service" element of the wsdd file, relates the URL from the 
92 * client's endpt. to the actual Service class and list of allowed methods...
93 * Well, what is the link you use to coordinate Client and Server?
94 * * Ans: get the endpt. URL and query the WSDL via browser link belo
95 *  <host><port>/axis/services/urn:EchoAttachmentsService?wsdl 
96 * </p><p>
97 * If you want to extend the signature you have to make correlated changes to:
98 *  - wsdd.   then redeploy to AXIS container
99 *  - Client methods <this> to format the SOAP Envelope's elements
00 *  - server implementation and method's parameters and parm order
01 *  - without the server being up, you can test revision...
02 *     use TCPMON to trap the client message and inspect
03 *    the child element of <soapenv:Body>. Child's name should =
04 *    method name on the server .. follow the rules outlined in the SOAP
05 *    spec under "RPC and SOAP Body"
06 * </p>
07 * To change the template for this generated type comment go to
08 * Window>Preferences>Java>Code Generation>Code and Comments
09 */
10
11public class SAAJCallMgr {
12    
13    SOAPConnection soapConnection;
14//  SOAPMessage message;
15    Message reqMessage;
16    Message resMessage;
17    
18    SOAPEnvelope requestEnvelope; 
19    SOAPElement elementRpcOp;
20    protected static Logger log;
21    private MessageContext     msgContext      = null ;
22
23
24//TODO what is the proper duration of the connection belo??
25//    where is the connection killed    
26    public void setConnection(SOAPConnection conn){
27        log.debug("beg. getconn ");     
28            soapConnection = conn;
29        }
30    public SOAPConnection getConnection(){
31        return soapConnection;
32        }
33//TODO need an interface for the SOAP struct setters
34//    they are always the same ( env, body, method, parmSet )       
35
36// wrong should be addMessageAttachment (impl, File)
37//  
38    public void putFile(File afile, String wsdlURL){
39        AttachmentPart attachment =
40            getReqMessage().createAttachmentPart(
41                new DataHandler(
42                    new FileDataSource(
43                        afile               
44                    )
45                )
46            );
47        getReqMessage().addAttachmentPart(attachment);
48        try{
49            elementRpcOp.addAttribute(
50                requestEnvelope.createName("href")
51                , "cid:" + attachment.getContentId()
52            );
53            log.debug("making SOAP call to " +wsdlURL);
54            javax.xml.soap.SOAPMessage returnedSOAPMessage =
55                getConnection().call(getReqMessage(), wsdlURL);
56        } catch (SOAPException e) {
57        // TODO Auto-generated catch block
58        e.printStackTrace();
59        }   
60    }
61    public void putFile(Collection fileset){
62        for ( 
63            Iterator i = fileset.iterator();i.hasNext();
64        ){
65            putFile( 
66                (File)i.next()
67                ,
68                POProperty.get(
69                    "wsdl.service.addr.host"
70                ) 
71                + "/" 
72                + POProperty.get(
73                    "wsdl.service.addr.axis.webapp"
74                )
75                + "/" 
76                + POProperty.get(
77                    "wsdl.service.addr.port.name"
78                )                               
79            );
80        }   
81    }
82    public void putFile(String name, String wsdlURL){
83    // better signature(s) ( File, Endpt ) ( FileSet, Endpt )
84    // Set above just delegates to singleFile   
85    // not used because the instantiantion of the collection
86    // should be closer to the client making call of the service
87    // if you parm a string then you should also do a boolean parm
88    // for a "use name as regex pattern" to drive collection of files   
89    // fixme wrap the url
90    //"http://localhost:" +opts.getPort() + "/axis/services/urn:EchoAttachmentsService";
91    /*String wsdlURLString =  
92    POProperty.get(             
93        "file.io.output.rpc.attachment"                                 
94    );
95    */
96    System.out.println("beg. put fnm , endptURL : "
97        +name
98        +" "
99        +wsdlURL
00    );
01    try {
02                        
03
04//aset
05        
06      for ( Iterator i = 
07              FileSelector.getFiles(name).iterator() ;
08          i.hasNext();
09      ){
10                AttachmentPart attachment =
11                    getReqMessage().createAttachmentPart(
12                        new DataHandler(
13                            new FileDataSource(
14                                (File)i.next()              
15                            )
16                        )
17                    );                  
18                getReqMessage().addAttachmentPart(attachment);
19                elementRpcOp.addAttribute(
20                    requestEnvelope.createName("href")
21                    , "cid:" + attachment.getContentId()
22                );
23            }   //endFor
24            log.debug("making SOAP call to " +wsdlURL);
25            javax.xml.soap.SOAPMessage returnedSOAPMessage =
26                getConnection().call(getReqMessage(), wsdlURL);
27        } catch (SOAPException e) {
28        // TODO Auto-generated catch block
29        e.printStackTrace();
30    }
31    }
32    public MessageContext getMessageContext(){
33        return msgContext;
34    }
35    
36    public void setMessageContext(MessageContext msgC){
37         msgContext = msgC;
38    }   
39    
40    public Message getReqMessage(){
41        return reqMessage;
42    }
43    
44    /**
45     * Get the "SOAPMessage" portion of the soap message via calls
46     * to the appropriate Obj. Factory. Meant to be used by client 
47     * that is NOT in a container.
48     * @return javax.xml.soap.SOAPMessage
49     */ 
50    public void setReqMessage(Message msg){
51        log.debug("beg. getmsg ");
52    
53            reqMessage = msg;
54        
55    }
56
57    /**
58     * Get the "SOAPEnvelope" portion of the soap message.
59     * @return SOAPEnvelope
60     */ 
61    public SOAPEnvelope getRequestEnvelope(){           
62            return requestEnvelope;
63    }
64
65    public SOAPEnvelope getRequestEnvelope(Message msg){
66        try {
67            return msg.getSOAPEnvelope();
68            
69//          return this.getReqMessage().getSOAPEnvelope();
70//          return this.getMessage().getSOAPPart().getEnvelope();
71
72        } catch (AxisFault e) {
73            // TODO Auto-generated catch block
74            e.printStackTrace();
75            return null;
76        }
77    }
78
79    public void setRequestEnvelope(SOAPEnvelope env){
80
81        requestEnvelope = env;
82    }
83
84/**
85 * Get the "SOAPBody" portion of the soap message.
86 * @return javax.xml.soap.SOAPBody
87 */ 
88    public SOAPBody getBody(){
89        try {           
90            return  getRequestEnvelope(this.getReqMessage()).getBody();
91        } catch (SOAPException e) {
92            // TODO Auto-generated catch block
93            e.printStackTrace();
94            return null;
95        }
96    }
97    /** 
98     * This is the ROOT element of the XML content portion of the
99     * SoapBody obj. The name of this element is also the RPC Operation name
00     * that's called via JAX-RPC on the server.
01     */
02    public SOAPElement getElementRpcOp(){
03        return elementRpcOp;
04    }
05
06/**
07 * This needs to be set as part of the creation of the SOAPMESSAGe and 
08 * its contents. This is the ROOT element of the XML content portion of the
09 * SoapBody obj. The name of this element is also the RPC Operation name
10 * that's called via JAX-RPC on the server.
11 * @param element javax.xml.soap.SOAPElement
12 */ 
13    public void setElementRpcOp(SOAPElement element){
14        elementRpcOp = element;
15    }
16    
17    /**
18     * Use the appropriate Soap entry from the property file to create
19     * the QNAME whose value should be the corresponding WSDL entry for 
20     * "operation name" of the bound web service. The "port" and "service"
21     * sections ofthe WSDL should contain this value. 
22     * @return the QName for the Root Node of the XML content inside 
23     * the SOAPBODY. 
24     */
25    public Name setQName(String name){
26        try {
27            return getRequestEnvelope(this.getReqMessage())
28            .createName(name
29//              POProperty.get(
30//                  "soap.rpc.methodname.attachment"
31//              )
32            );
33        } catch (SOAPException e) {
34            // TODO Auto-generated catch block
35            e.printStackTrace();
36            return null;
37        }
38    }
39    public Name setQName(String name, String prefix, String uri){
40        try {
41            return getRequestEnvelope(this.getReqMessage())
42            .createName(
43                name, prefix, uri
44            );
45        } catch (SOAPException e) {
46            // TODO Auto-generated catch block
47            e.printStackTrace();
48            return null;
49        }
50    }   
51/**
52 * 
53 * @return the XML node that corresponds to the Root in the SOAPBODY.
54 * Also, according to SOAP Protocol, this is the 
55 * WSDL Binding sectn's "operation name".
56 */ 
57    public SOAPElement addMethod(String name){
58        try {
59            return
60             getBody()
61            .addBodyElement(
62                setQName(name)              
63            );
64        } catch (SOAPException e) {
65            // TODO Auto-generated catch block
66            e.printStackTrace();
67            return null;
68        }
69    }
70
71
72/**
73 * The mid-ware symantic is hey "i created some data on this client,
74 * in the clients file system, and it's data that is of interest to remote
75 * subscribers." All the SOAP message stuff is to satisfy the protocol but,
76 * this is where the meat and potatoes are because this is where the file 
77 * or the encoded version of the file will be hooked to the SAAJ envelope
78 * for its trip over-the-wire with the message.
79 * @param afile, part of the Collection from the client's call to 
80 * "FileSelector.getFiles."
81 * @return
82 */
83    public AttachmentPart createFileAttachment(File afile){
84        return
85        getReqMessage().createAttachmentPart(
86            new DataHandler(
87                new FileDataSource(
88                    afile               
89                )
90            )
91        );  
92    }
93    
94    /**
95     * <p>The SOAPBody hasa entity, (property with an attibute whose value
96     * is a reference to the actual "DataHandler" attached to the SOAP msg.
97     * according to the rules of JAX-RPC, SOAP, and SAAJ API). The name of 
98     * the property in the xml message is also a parm name in the signature
99     * of the RPC operation over on the server.</p><p>
00     * In addition to this, the message hasa Attachment part which is the
01     * encoded version of the client's file that will be transported to the
02     * Post Office where a different sub-system meets the needs of 
03     * subscribers on the topic associated with the message.</p><p>
04     * For each file that is new, create the xml node holding the refernce
05     * and also create the attachment. Connect the attachment to the message.
06     * @param fil java.io.File
07     */
08//TODO on anymore than 1 file , the "createName' won't be unique in NS
09// you should parm the element that attach ref will be added? 
10// its now hardcode as "getElementRpcOP' so you can only attach the refids here
11// get rid of hard-coded "dh"   
12    public void addAttachment(File fil){
13        AttachmentPart myAttachment = createFileAttachment(fil);
14        getReqMessage().addAttachmentPart(myAttachment);
15        try {
16            getElementRpcOp()
17            .addChildElement(
18                getRequestEnvelope(this.getReqMessage()).createName("dh")
19            )
20            .addAttribute(
21                getRequestEnvelope(this.getReqMessage()).createName("href")
22                , "cid:" + myAttachment.getContentId()
23            );
24        } catch (SOAPException e) {
25            // TODO Auto-generated catch block
26            e.printStackTrace();
27        }
28    }
29    public void addAttachment(File fil, String parm){
30        AttachmentPart myAttachment = createFileAttachment(fil);
31        getReqMessage().addAttachmentPart(myAttachment);
32        try {
33            getElementRpcOp()
34            .addChildElement(
35                getRequestEnvelope(this.getReqMessage()).createName(parm)
36            )
37            .addAttribute(
38                getRequestEnvelope(this.getReqMessage()).createName("href")
39                , "cid:" + myAttachment.getContentId()
40            );
41        } catch (SOAPException e) {
42            // TODO Auto-generated catch block
43            e.printStackTrace();
44        }
45    }
46    
47// pass in file, parent elem "attachments"
48// file to DH
49    
50    public void addAttachment(File fil, SOAPBodyElement element){
51//      AttachmentPart myAttachment = createFileAttachment(fil);
52        addAttachment(
53            new DataHandler(
54                new FileDataSource( 
55                    fil
56                )
57            )
58            ,
59            element
60        );
61    
62    }   
63/**
64 * According to the rules of SOAP, SAAJ, JAXRPC, create the XML node in the
65 * SOAP body that holds a value reference to the actual SAAJ attachment part.
66 * The xml node and its name will be treated as RPC parm by the server-side
67 * interface of the Operation specified in the Root element. A DataHandler obj.
68 * is being used to get the attachment file over-the-wire. So, for now,
69 * this element name is dh. 
70 * NOTE: only one dh is allowed at this point. 
71 * @param name the parm name used by the server-side operation's 
72 *
73 * @param nameVal the "href" to the actual attachment
74 */ 
75    public void addRPCParm ( String name, String nameVal){
76//      SOAPElement ele = getElementRpcOp()     
77        try {
78            getElementRpcOp()
79            .addChildElement(
80                getRequestEnvelope(this.getReqMessage())
81                .createName(name)
82            )
83            .addTextNode(nameVal);
84        } catch (SOAPException e) {
85            // TODO Auto-generated catch block
86            e.printStackTrace();
87        }
88    }
89
90    
91    /**
92     * Post the request that Wraps the SOAP message.  Explain??
93     * Using the AXIS runtime (client-side impl) that uses HTTP/SOAP to 
94     * connect to the URL endpt. on the Server. Server hosts the interface impl. 
95     * of the RPC method or operation.
96     * See 3 property file properties with name like "wsdl.service.addr."
97     * @param message SOAPMessage
98     * @return
99     */
00    public SOAPMessage call ( SOAPMessage message ){
01        try {
02            return getConnection().call(
03                message                             
04                ,
05                    POProperty.get(
06                        "wsdl.service.addr.host"
07                    ) 
08                    + "/" 
09                    + POProperty.get(
10                        "wsdl.service.addr.axis.webapp"
11                    )
12                    + "/" 
13                    + POProperty.get(
14                        "wsdl.service.addr.port.name"
15                    ) 
16            );
17        } catch (SOAPException e) {
18            // TODO Auto-generated catch block
19            e.printStackTrace();
20            return null;
21        }
22    }
23// get the param, set it's ParmDesc
24//   then load it into Array
25    public Object[] setParam(DataHandler[] dh){
26        RPCParam rpcParam = new RPCParam(
27            ""
28            , "attachments"
29            ,dh
30        );
31        rpcParam.setParamDesc(
32        new ParameterDesc(new QName("attachments"),
33                             ParameterDesc.IN,
34                             XMLType.SOAP_ARRAY)
35        );
36        Vector result = new Vector();
37        result.add(rpcParam);       
38        return ( result.toArray() );
39    }
40
41    public DataHandler[] setDH(Collection fileset){
42        LinkedList dhList = new LinkedList();       
43            for ( 
44                Iterator i = fileset.iterator();i.hasNext();
45            ){          
46                dhList.add(
47                    new DataHandler(
48                        new FileDataSource( 
49                            (File)i.next()
50                        )
51                    )
52                );                                      
53            }               
54        DataHandler[] dharray = new DataHandler[0];                 
55        return 
56            (DataHandler[])new ArrayList(dhList).toArray(dharray);      
57    }
58// call this w/     setDHArray(SelectFiles(), attachments    as parms
59// AttachmentPart caution subcls
60//   javax.xml.soap.AttachmentPart
61//      org.apache.axis.attachments | a subcls
62//  addchild "item" to attachments
63//  addattr href cid to item
64//  addattachment dh to message
65
66    public void addAttachment(DataHandler dh, SOAPBodyElement element){
67//      AttachmentPart myAttachment = getMessage()
68//      .createAttachmentPart();
69
70        org.apache.axis.attachments.AttachmentPart 
71        myAttachment = new org.apache.axis.attachments.AttachmentPart(
72            new DataHandler(
73                dh 
74                ,"text/plain"
75            )
76        );
77        getReqMessage().addAttachmentPart(myAttachment);
78        try {
79            element
80            .addChildElement(
81                getRequestEnvelope(this.getReqMessage()).createName("item")
82            )
83            .addAttribute(
84                getRequestEnvelope(this.getReqMessage()).createName("href")
85                , "cid:" + myAttachment.getContentId()
86            );
87        } catch (SOAPException e) {
88        // TODO Auto-generated catch block
89            e.printStackTrace();
90        }   
91        }   
92    /**
93     * what other way is there to handle DataHandler[] as parm??
94     * this seems to work with the attachment sample's "echoDir" operation
95     * where a parm encapsulates ArrayofDataHandlers...
96     * The key was removing the explicit Typ Registration for encoding the
97     * DH array. Just let it default and it seems to work OK on client...
98     * @return
99     */
00    public Call getCall(){
01        try {
02            Call call = (Call)(new Service().createCall());
03            /*Un comment the below statement to do HTTP/1.1 protocol*/
04            //call.setScopedProperty(MessageContext.HTTP_TRANSPORT_VERSION,HTTPConstants.HEADER_PROTOCOL_V11);
05/* rcr removed 5 lines as extraneous
06
07            Hashtable myhttp = new Hashtable();
08            myhttp.put("dddd", "yyy");     //Send extra soap headers
09            myhttp.put("SOAPAction", "dyyy");
10            myhttp.put("SOAPActions", "prova");
11            call.setProperty(HTTPConstants.REQUEST_HEADERS, myhttp);
12            */
13            
14            /*Un comment the below to do http chunking to avoid the need to calculate content-length. (Needs HTTP/1.1)*/
15            //myhttp.put(HTTPConstants.HEADER_TRANSFER_ENCODING, HTTPConstants.HEADER_TRANSFER_ENCODING_CHUNKED);
16
17            /*Un comment the below to force a 100-Continue... This will cause  httpsender to wait for
18             * this response on a post.  If HTTP 1.1 and this is not set, *SOME* servers *MAY* reply with this anyway.
19             *  Currently httpsender won't handle this situation, this will require the resp. which it will handle.
20             */
21            //myhttp.put(HTTPConstants.HEADER_EXPECT, HTTPConstants.HEADER_EXPECT_100_Continue);
22
23            //Set the target service host and service location,
24            call.setTargetEndpointAddress(
25                new URL(                        
26                    POProperty.get(
27                        "wsdl.service.addr.host"
28                    ) 
29                    + "/" 
30                    + POProperty.get(
31                        "wsdl.service.addr.axis.webapp"
32                    )
33                    + "/" 
34                    + POProperty.get(
35                        "wsdl.service.addr.port.name"
36                    )                       
37                )
38            );
39            //This is the target services method to invoke.
40//TODO hardcode removal use wsdl.service.addr.port.name for valueOf
41//     urn:EchoAttach...            
42            call.setOperationName(
43                new QName(
44                    "urn:EchoAttachmentsService"
45                    , 
46                    POProperty.get(
47                        "soap.rpc.methodname.attachment"
48                    )
49                )
50            );
51                        
52//          Add serializer for attachment.
53/* rcr tst byp          call.registerTypeMapping(
54                Class.forName(
55                    "javax.activation.DataHandler"
56                )
57                ,  
58                new QName(
59                    "urn:EchoAttachmentsService"
60                    , "DataHandler"
61                )                                    
62                , JAFDataHandlerSerializerFactory.class
63                , JAFDataHandlerDeserializerFactory.class
64            ); // end registerType
65            */
66            // argname for serverside method is the parm here
67            call.addParameter(
68                "attachments"
69                , XMLType.SOAP_ARRAY // new XMLType(qnameAttachment),
70                ,ParameterMode.IN
71            ); //Add the file.
72            call.setReturnType(XMLType.SOAP_ARRAY); // new XMLType(qnameAttachment));
73/* rcr tst byp          call.setProperty(
74                Call.ATTACHMENT_ENCAPSULATION_FORMAT
75                , Call.ATTACHMENT_ENCAPSULATION_FORMAT_DIME
76            );
77            */
78            return call;                                         
79            
80        } catch (ServiceException e) {
81            // TODO Auto-generated catch block
82            e.printStackTrace();
83        }
84        catch (MalformedURLException e) {
85            // TODO Auto-generated catch block
86            e.printStackTrace();
87        }
88        return null;
89    }
90    /**
91     * <p>Make the call to the WS endpt and operation specified in the props
92     * file directives ( soap.wsdl.url, soap.rpc.methodname )
93     * Note that serverside method "echoDir" expects a DataHandler[] typ parm.
94     * </p><p>Using an intermediate List form , convert collection of file(s)
95     *  returned by an earlier call to "FileSelector.getFiles()" to an Array  
96     * of DataHandlers because this is acceptible struct. for auto-encoding 
97     * by JAX-RPC runtime...
98     * Invoke the Service...
99     * @param fileset Collection of files that will be loaded in Array of DH's
00     * @param argcal The DII "call" that will get invoked
01     * @return the "Response type" of the WS and the return type of the operation
02     *   that's being invoked...
03     */
04    public Object diiCall(Collection fileset, Call argcal){
05                                
06        LinkedList dhList = new java.util.LinkedList();     
07        for ( 
08            Iterator i = fileset.iterator();i.hasNext();
09        ){          
10            dhList.add(
11                new DataHandler(
12                    new FileDataSource( 
13                        (File)i.next()
14                    )
15                )
16            );                                      
17        }
18        try {
19            DataHandler[] dharray = new DataHandler[0]; 
20            return argcal.invoke(
21                new Object[]{
22                   new ArrayList(dhList).toArray(dharray)
23                }
24            );
25        } catch (RemoteException e) {
26            // TODO Auto-generated catch block
27            e.printStackTrace();
28        }
29        return new Object();
30    }
31    
32    public void close(){
33        try {
34            getConnection().close();
35        } catch (SOAPException e) {
36            // TODO Auto-generated catch block
37            e.printStackTrace();
38        }   
39    }
40
41    public void setTypeMappingRegistry() {
42         TypeMappingRegistry tmr = null;
43         TypeMapping tm = null;
44  
45      
46        tmr = new TypeMappingRegistryImpl();
47
48        // Gets / Creates the TypeMapping instance
49        String encodingStyle = Constants.URI_DEFAULT_SOAP_ENC;
50        tm = (TypeMapping) tmr.getTypeMapping(encodingStyle);
51        TypeMapping df = (TypeMapping) tmr.getDefaultTypeMapping();
52        
53        Class[] myclass = df.getAllClasses();
54    
55        for ( int j = 0
56            ;j < myclass.length ;
57            j++
58            ){
59                log.debug(
60                    "mapd : "
61                    + myclass[j].getName()
62                    + " "
63                    +df.getTypeQName(myclass[j]).toString()
64                    + " "
65                    +df.getSerializer(myclass[j])
66                    )
67                ;               
68            }   
69        
70    /*  if (tm == null || tm == df) {
71          tm = (TypeMapping) tmr.createTypeMapping();
72          tm.setSupportedEncodings(new String[] {encodingStyle});
73          tmr.register(encodingStyle, tm);
74        }
75        */
76      
77    }
78
79    
80    
81    //TODO need to get the 4 modes of connection split out in seperate
82    // classes , all impls. of the same interface
83    //  soapsingleImpl, diiImpl, soapArrayImpl 
84    //A point-to-point connection SoapConnection - soapconnection
85    //JAXRPC Dynamic Invoation Interface implementation of the Service - diiservice
86    //#ws.invocation.typ=soapconnection
87    //ws.invocation.typ=diiservice  arg0=tm1*
88    // file name and endpt are the args
89    // F:\\axis-1_1RC2\\samples\\attachments\\build.xml
90    //http://localhost:8080/axis/services/urn:EchoAttachmentsService
91    // use diiservice for operation with DataHandler[] as parm
92    public static void main(String[] args) {
93        SAAJCallMgr myMgr= new SAAJCallMgr();
94//      myMgr.setMessageContext(
95//          MessageContext.getCurrentContext()
96//      );
97        myMgr.setMessageContext(
98            new MessageContext(
99                new Service().getEngine()
00                )
01        );
02        
03        if (
04            POProperty.get(
05                "ws.invocation.typ"
06            ).equalsIgnoreCase("soapconnection")
07        ) {
08        try {
09            myMgr.setConnection(
10                SOAPConnectionFactoryImpl.newInstance()
11                .createConnection()
12            );
13            myMgr.setReqMessage(
14
15                (Message)MessageFactoryImpl.newInstance().createMessage()
16            );
17        } catch (UnsupportedOperationException e) {
18            // TODO Auto-generated catch block
19            e.printStackTrace();
20        } catch (SOAPException e) {
21            // TODO Auto-generated catch block
22            e.printStackTrace();
23        }
24
25        myMgr.setElementRpcOp(myMgr.addMethod("echo"));
26        log.debug("RpcOp as element " + myMgr.getElementRpcOp().toString());
27//      myMgr.addRPCParm("topicaction","publish");
28//      myMgr.addRPCParm("topicname","testattachment");     
29        for ( Iterator i = 
30                FileSelector.getFiles(args[0]).iterator() ;
31            i.hasNext();
32        ){
33            myMgr.addAttachment(
34                (File)i.next()
35                , "dh"
36            );              
37        }
38//TODO remove 2nd file name for test of dh2 and 2nd parm
39  for ( Iterator i = 
40          FileSelector.getFiles(args[1]).iterator() ;
41      i.hasNext();
42  ){
43      myMgr.addAttachment(
44          (File)i.next()
45          , "dh2"
46      );                
47  }     
48        myMgr.call(myMgr.getReqMessage());
49        myMgr.close();
50    }else if (
51        POProperty.get(
52            "ws.invocation.typ"
53        ).equalsIgnoreCase("diiservice")
54    )
55    {
56        Object ret = myMgr.diiCall(
57            FileSelector.getFiles(args[0])
58            ,
59            myMgr.getCall()
60        );
61//      myMgr.close();  rcr causing error 6/29
62    }
63    // this option doesn't work due to illegal parm being thrown at
64    // mysoapmessage.createAttachmentPart(dhset[] , cType)
65    else if (
66            POProperty.get(
67                "ws.invocation.typ"
68            ).equalsIgnoreCase("soaparrayofdhattach") 
69        )
70        {
71            // rcr test check typemapping for default serialization
72            myMgr.setTypeMappingRegistry();
73            try {
74                myMgr.setConnection(
75                    SOAPConnectionFactoryImpl.newInstance()
76                    .createConnection()
77                );
78                myMgr.setReqMessage(
79                    (Message)MessageFactoryImpl.newInstance().createMessage()
80                );
81                    
82            
83//              myMgr.setElementRpcOp(myMgr.addMethod("echoDir"));
84                RPCElement myRpcEl =    
85                new RPCElement(
86                    "urn:EchoAttachmentsService"
87                    ,"echoDir"
88                    ,myMgr.setDH(
89                        FileSelector.getFiles(
90                            args[0]
91                        )
92                    )
93                );
94                log.debug("using encd styl : "+
95                myMgr.getMessageContext(                        
96                    ).getSOAPConstants().getEncodingURI());
97                myRpcEl.setEncodingStyle(
98                    myMgr.getMessageContext(                        
99                    ).getSOAPConstants().getEncodingURI()
00                );
01                myRpcEl.setParentElement(myMgr.getBody());
02//              ).setParentElement(myMgr.getElementRpcOp());
03
04            } catch (SOAPException e) {
05                // TODO Auto-generated catch block
06                e.printStackTrace();
07            }                                                                               
08            myMgr.call(myMgr.getReqMessage());
09            myMgr.close();          
10        }
11        
12// in order to replace diiCall with a more static form of:
13// getConnection().call(amessage
14// provide re-impl of the code found in cls=
15//      org.apache.axis.client.Call.invoke(RPCElement) and in
16//      org.apache.axis.client.Call.invoke()
17//Note that the key to re-impl is using the RPCElement 
18//   built from Array of RPCParams
19// Note that this array contains the parameter(s) expected by the operation
20//  that is the target of the Service Call ie the server side method...
21        
22        else if (
23                POProperty.get(
24                    "ws.invocation.typ"
25                ).equalsIgnoreCase("soapconnparms") 
26            )
27// get new  envelope that will hold all attachments
28            myMgr.setRequestEnvelope(
29                new SOAPEnvelope(
30                    myMgr.getMessageContext().getSOAPConstants()
31                    ,myMgr.getMessageContext().getSchemaVersion()
32                )
33            );
34 
35// get new element with FileSet to DataHandler[] to RPCParam[]
36            RPCElement myRpcEl =    
37            new RPCElement(
38                "urn:EchoAttachmentsService"
39                ,"echoDir"
40                ,myMgr.setParam(                
41                    myMgr.setDH(
42                        FileSelector.getFiles(
43                            args[0]
44                        )
45                    )
46                )               
47            );          
48            log.debug("using encd styl : "+
49            myMgr.getMessageContext(                        
50                ).getSOAPConstants().getEncodingURI());
51            try {
52                myRpcEl.setEncodingStyle(
53                    myMgr.getMessageContext(                        
54                    ).getSOAPConstants().getEncodingURI()
55                );
56            } catch (SOAPException e) {
57                // TODO Auto-generated catch block
58                e.printStackTrace();
59            }
60// add attachments to envelope
61            myMgr.getRequestEnvelope().addBodyElement(myRpcEl);
62            myMgr.getRequestEnvelope().setMessageType(Message.REQUEST);         
63            try {
64                myMgr.getMessageContext().setTargetService(
65                    myMgr.getRequestEnvelope()
66                    .getFirstBody()
67                    .getNamespaceURI()
68                );              
69                myMgr.setConnection(
70                    SOAPConnectionFactoryImpl.newInstance()
71                    .createConnection()
72                );              
73            } catch (AxisFault e1) {
74                // TODO Auto-generated catch block
75                e1.printStackTrace();
76            } catch (UnsupportedOperationException e) {
77                // TODO Auto-generated catch block
78                e.printStackTrace();
79            } catch (SOAPException e) {
80                // TODO Auto-generated catch block
81                e.printStackTrace();
82            }
83//  call on the connection with parm of new message
84            myMgr.setReqMessage(
85                new Message(
86                    myMgr.getRequestEnvelope()
87                )
88            );
89            myMgr.getReqMessage().setMessageContext(
90                myMgr.getMessageContext()
91            );
92            myMgr.call(myMgr.getReqMessage());
93            myMgr.close();          
94            }
95        
96    static 
97    {
98        log = Logger.getLogger((SAAJCallMgr.class).getName());  
99        ClassLoader cl = SAAJCallMgr.class.getClassLoader();
00        PropertyConfigurator.configure(cl.getResource(
01            "config/log4j.properties"));
02    }
03    }
04