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