| 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 DataHandler[] setDH(Collection fileset){
67 LinkedList dhList = new LinkedList();
68 for (
69 Iterator i = fileset.iterator();i.hasNext();
70 ){
71 dhList.add(
72 new DataHandler(
73 new FileDataSource(
74 (File)i.next()
75 )
76 )
77 );
78 }
79 DataHandler[] dharray = new DataHandler[0];
80 return
81 (DataHandler[])new ArrayList(dhList).toArray(dharray);
82 }
83// call this w/ setDHArray(SelectFiles(), attachments as parms
84// AttachmentPart caution subcls
85// javax.xml.soap.AttachmentPart
86// org.apache.axis.attachments | a subcls
87// addchild "item" to attachments
88// addattr href cid to item
89// addattachment dh to message
90
91 public void addAttachment(DataHandler dh, SOAPBodyElement element){
92// AttachmentPart myAttachment = getMessage()
93// .createAttachmentPart();
94
95 org.apache.axis.attachments.AttachmentPart
96 myAttachment = new org.apache.axis.attachments.AttachmentPart(
97 new DataHandler(
98 dh
99 ,"text/plain"
00 )
01 );
02 getReqMessage().addAttachmentPart(myAttachment);
03 try {
04 element
05 .addChildElement(
06 getRequestEnvelope(this.getReqMessage()).createName("item")
07 )
08 .addAttribute(
09 getRequestEnvelope(this.getReqMessage()).createName("href")
10 , "cid:" + myAttachment.getContentId()
11 );
12 } catch (SOAPException e) {
13 // TODO Auto-generated catch block
14 e.printStackTrace();
15 }
16 }
17 /**
18 * what other way is there to handle DataHandler[] as parm??
19 * this seems to work with the attachment sample's "echoDir" operation
20 * where a parm encapsulates ArrayofDataHandlers...
21 * The key was removing the explicit Typ Registration for encoding the
22 * DH array. Just let it default and it seems to work OK on client...
23 * @return
24 */
25 public Call getCall(){
26 try {
27 Call call = (Call)(new Service().createCall());
28 /*Un comment the below statement to do HTTP/1.1 protocol*/
29 //call.setScopedProperty(MessageContext.HTTP_TRANSPORT_VERSION,HTTPConstants.HEADER_PROTOCOL_V11);
30/* rcr removed 5 lines as extraneous
31
32 Hashtable myhttp = new Hashtable();
33 myhttp.put("dddd", "yyy"); //Send extra soap headers
34 myhttp.put("SOAPAction", "dyyy");
35 myhttp.put("SOAPActions", "prova");
36 call.setProperty(HTTPConstants.REQUEST_HEADERS, myhttp);
37 */
38
39 /*Un comment the below to do http chunking to avoid the need to calculate content-length. (Needs HTTP/1.1)*/
40 //myhttp.put(HTTPConstants.HEADER_TRANSFER_ENCODING, HTTPConstants.HEADER_TRANSFER_ENCODING_CHUNKED);
41
42 /*Un comment the below to force a 100-Continue... This will cause httpsender to wait for
43 * this response on a post. If HTTP 1.1 and this is not set, *SOME* servers *MAY* reply with this anyway.
44 * Currently httpsender won't handle this situation, this will require the resp. which it will handle.
45 */
46 //myhttp.put(HTTPConstants.HEADER_EXPECT, HTTPConstants.HEADER_EXPECT_100_Continue);
47
48 //Set the target service host and service location,
49 call.setTargetEndpointAddress(
50 new URL(
51 POProperty.get(
52 "wsdl.service.addr.host"
53 )
54 + "/"
55 + POProperty.get(
56 "wsdl.service.addr.axis.webapp"
57 )
58 + "/"
59 + POProperty.get(
60 "wsdl.service.addr.port.name"
61 )
62 )
63 );
64 //This is the target services method to invoke.
65//TODO hardcode removal use wsdl.service.addr.port.name for valueOf
66// urn:EchoAttach...
67 call.setOperationName(
68 new QName(
69 "urn:EchoAttachmentsService"
70 ,
71 POProperty.get(
72 "soap.rpc.methodname.attachment"
73 )
74 )
75 );
76
77// Add serializer for attachment.
78/* rcr tst byp call.registerTypeMapping(
79 Class.forName(
80 "javax.activation.DataHandler"
81 )
82 ,
83 new QName(
84 "urn:EchoAttachmentsService"
85 , "DataHandler"
86 )
87 , JAFDataHandlerSerializerFactory.class
88 , JAFDataHandlerDeserializerFactory.class
89 ); // end registerType
90 */
91 // argname for serverside method is the parm here
92 call.addParameter(
93 "attachments"
94 , XMLType.SOAP_ARRAY // new XMLType(qnameAttachment),
95 ,ParameterMode.IN
96 ); //Add the file.
97 call.setReturnType(XMLType.SOAP_ARRAY); // new XMLType(qnameAttachment));
98/* rcr tst byp call.setProperty(
99 Call.ATTACHMENT_ENCAPSULATION_FORMAT
00 , Call.ATTACHMENT_ENCAPSULATION_FORMAT_DIME
01 );
02 */
03 return call;
04
05 } catch (ServiceException e) {
06 // TODO Auto-generated catch block
07 e.printStackTrace();
08 }
09 catch (MalformedURLException e) {
10 // TODO Auto-generated catch block
11 e.printStackTrace();
12 }
13 return null;
14 }
15 /**
16 * <p>Make the call to the WS endpt and operation specified in the props
17 * file directives ( soap.wsdl.url, soap.rpc.methodname )
18 * Note that serverside method "echoDir" expects a DataHandler[] typ parm.
19 * </p><p>Using an intermediate List form , convert collection of file(s)
20 * returned by an earlier call to "FileSelector.getFiles()" to an Array
21 * of DataHandlers because this is acceptible struct. for auto-encoding
22 * by JAX-RPC runtime...
23 * Invoke the Service...
24 * @param fileset Collection of files that will be loaded in Array of DH's
25 * @param argcal The DII "call" that will get invoked
26 * @return the "Response type" of the WS and the return type of the operation
27 * that's being invoked...
28 */
29 public Object diiCall(Collection fileset, Call argcal){
30
31 LinkedList dhList = new java.util.LinkedList();
32 for (
33 Iterator i = fileset.iterator();i.hasNext();
34 ){
35 dhList.add(
36 new DataHandler(
37 new FileDataSource(
38 (File)i.next()
39 )
40 )
41 );
42 }
43 try {
44 DataHandler[] dharray = new DataHandler[0];
45 return argcal.invoke(
46 new Object[]{
47 new ArrayList(dhList).toArray(dharray)
48 }
49 );
50 } catch (RemoteException e) {
51 // TODO Auto-generated catch block
52 e.printStackTrace();
53 }
54 return new Object();
55 }
56
57 public void close(){
58 try {
59 getConnection().close();
60 } catch (SOAPException e) {
61 // TODO Auto-generated catch block
62 e.printStackTrace();
63 }
64 }
65
66 public void setTypeMappingRegistry() {
67 TypeMappingRegistry tmr = null;
68 TypeMapping tm = null;
69
70
71 tmr = new TypeMappingRegistryImpl();
72
73 // Gets / Creates the TypeMapping instance
74 String encodingStyle = Constants.URI_DEFAULT_SOAP_ENC;
75 tm = (TypeMapping) tmr.getTypeMapping(encodingStyle);
76 TypeMapping df = (TypeMapping) tmr.getDefaultTypeMapping();
77
78 Class[] myclass = df.getAllClasses();
79
80 for ( int j = 0
81 ;j < myclass.length ;
82 j++
83 ){
84 log.debug(
85 "mapd : "
86 + myclass[j].getName()
87 + " "
88 +df.getTypeQName(myclass[j]).toString()
89 + " "
90 +df.getSerializer(myclass[j])
91 )
92 ;
93 }
94
95 /* if (tm == null || tm == df) {
96 tm = (TypeMapping) tmr.createTypeMapping();
97 tm.setSupportedEncodings(new String[] {encodingStyle});
98 tmr.register(encodingStyle, tm);
99 }
00 */
01
02 }
03 private OctetStream setOctet(InputStream is){
04 BufferedInputStream bis = new BufferedInputStream(is);
05 OctetStream out = new OctetStream();
06
07 byte[] buf = new byte[20 * 1024]; // 20K buffer for .xls in j/1_2/docs
08 int bytesRead;
09 try {
10 while ((bytesRead = bis.read(buf)) != -1) {
11 out.setBytes(buf);
12 }
13 } catch (IOException e) {
14 // TODO Auto-generated catch block
15 e.printStackTrace();
16 }
17 return out;
18 }
19
20
21 //TODO need to get the 4 modes of connection split out in seperate
22 // classes , all impls. of the same interface
23 // soapsingleImpl, diiImpl, soapArrayImpl
24 //A point-to-point connection SoapConnection - soapconnection
25 //JAXRPC Dynamic Invoation Interface implementation of the Service - diiservice
26 //#ws.invocation.typ=soapconnection
27 //ws.invocation.typ=diiservice arg0=tm1*
28 // file name and endpt are the args
29 // F:\\axis-1_1RC2\\samples\\attachments\\build.xml
30 //http://localhost:8080/axis/services/urn:EchoAttachmentsService
31 // use diiservice for operation with DataHandler[] as parm
32 public static void main(String[] args) {
33 SAAJCallMgr myMgr= new SAAJCallMgr();
34// myMgr.setMessageContext(
35// MessageContext.getCurrentContext()
36// );
37 myMgr.setMessageContext(
38 new MessageContext(
39 new Service().getEngine()
40 )
41 );
42
43 if (
44 POProperty.get(
45 "ws.invocation.typ"
46 ).equalsIgnoreCase("soapconnection")
47 ) {
48 try {
49 myMgr.setConnection(
50 SOAPConnectionFactoryImpl.newInstance()
51 .createConnection()
52 );
53 myMgr.setReqMessage(
54
55 (Message)MessageFactoryImpl.newInstance().createMessage()
56 );
57 } catch (UnsupportedOperationException e) {
58 // TODO Auto-generated catch block
59 e.printStackTrace();
60 } catch (SOAPException e) {
61 // TODO Auto-generated catch block
62 e.printStackTrace();
63 }
64
65 myMgr.setElementRpcOp(myMgr.addMethod("echo"));
66 log.debug("RpcOp as element " + myMgr.getElementRpcOp().toString());
67// myMgr.addRPCParm("topicaction","publish");
68// myMgr.addRPCParm("topicname","testattachment");
69 for ( Iterator i =
70 FileSelector.getFiles(args[0]).iterator() ;
71 i.hasNext();
72 ){
73 myMgr.addAttachment(
74 (File)i.next()
75 , "dh"
76 );
77 }
78//TODO remove 2nd file name for test of dh2 and 2nd parm
79 for ( Iterator i =
80 FileSelector.getFiles(args[1]).iterator() ;
81 i.hasNext();
82 ){
83 myMgr.addAttachment(
84 (File)i.next()
85 , "dh2"
86 );
87 }
88 myMgr.call(myMgr.getReqMessage());
89 myMgr.close();
90 }else if (
91 POProperty.get(
92 "ws.invocation.typ"
93 ).equalsIgnoreCase("diiservice")
94 )
95 {
96 Object ret = myMgr.diiCall(
97 FileSelector.getFiles(args[0])
98 ,
99 myMgr.getCall()
00 );
01// myMgr.close(); rcr causing error 6/29
02 }
03 // this option doesn't work due to illegal parm being thrown at
04 // mysoapmessage.createAttachmentPart(dhset[] , cType)
05 else if (
06 POProperty.get(
07 "ws.invocation.typ"
08 ).equalsIgnoreCase("soaparrayofdhattach")
09 )
10 {
11 // rcr test check typemapping for default serialization
12 myMgr.setTypeMappingRegistry();
13 try {
14 myMgr.setConnection(
15 SOAPConnectionFactoryImpl.newInstance()
16 .createConnection()
17 );
18 myMgr.setReqMessage(
19 (Message)MessageFactoryImpl.newInstance().createMessage()
20 );
21
22
23// myMgr.setElementRpcOp(myMgr.addMethod("echoDir"));
24 RPCElement myRpcEl =
25 new RPCElement(
26 "urn:EchoAttachmentsService"
27 ,"echoDir"
28 ,myMgr.setDH(
29 FileSelector.getFiles(
30 args[0]
31 )
32 )
33 );
34 log.debug("using encd styl : "+
35 myMgr.getMessageContext(
36 ).getSOAPConstants().getEncodingURI());
37 myRpcEl.setEncodingStyle(
38 myMgr.getMessageContext(
39 ).getSOAPConstants().getEncodingURI()
40 );
41 myRpcEl.setParentElement(myMgr.getBody());
42// ).setParentElement(myMgr.getElementRpcOp());
43
44 } catch (SOAPException e) {
45 // TODO Auto-generated catch block
46 e.printStackTrace();
47 }
48 myMgr.call(myMgr.getReqMessage());
49 myMgr.close();
50 }
51
52// in order to replace diiCall with a more static form of:
53// getConnection().call(amessage
54// provide re-impl of the code found in cls=
55// org.apache.axis.client.Call.invoke(RPCElement) and in
56// org.apache.axis.client.Call.invoke()
57//Note that the key to re-impl is using the RPCElement
58// built from Array of RPCParams
59// Note that this array contains the parameter(s) expected by the operation
60// that is the target of the Service Call ie the server side method...
61
62 else if (
63 POProperty.get(
64 "ws.invocation.typ"
65 ).equalsIgnoreCase("soapconnparms")
66 )
67// get new envelope that will hold all attachments
68 myMgr.setRequestEnvelope(
69 new SOAPEnvelope(
70 myMgr.getMessageContext().getSOAPConstants()
71 ,myMgr.getMessageContext().getSchemaVersion()
72 )
73 );
74
75// get new element with FileSet to DataHandler[] to RPCParam[]
76 RPCElement myRpcEl =
77 new RPCElement(
78 "urn:EchoAttachmentsService"
79 ,"echoDir"
80 ,myMgr.setParam(
81 myMgr.setDH(
82 FileSelector.getFiles(
83 args[0]
84 )
85 )
86 )
87 );
88 log.debug("using encd styl : "+
89 myMgr.getMessageContext(
90 ).getSOAPConstants().getEncodingURI());
91 try {
92 myRpcEl.setEncodingStyle(
93 myMgr.getMessageContext(
94 ).getSOAPConstants().getEncodingURI()
95 );
96 } catch (SOAPException e) {
97 // TODO Auto-generated catch block
98 e.printStackTrace();
99 }
00// add attachments to envelope
01 myMgr.getRequestEnvelope().addBodyElement(myRpcEl);
02 myMgr.getRequestEnvelope().setMessageType(Message.REQUEST);
03 try {
04 myMgr.getMessageContext().setTargetService(
05 myMgr.getRequestEnvelope()
06 .getFirstBody()
07 .getNamespaceURI()
08 );
09 myMgr.setConnection(
10 SOAPConnectionFactoryImpl.newInstance()
11 .createConnection()
12 );
13 } catch (AxisFault e1) {
14 // TODO Auto-generated catch block
15 e1.printStackTrace();
16 } catch (UnsupportedOperationException e) {
17 // TODO Auto-generated catch block
18 e.printStackTrace();
19 } catch (SOAPException e) {
20 // TODO Auto-generated catch block
21 e.printStackTrace();
22 }
23// call on the connection with parm of new message
24 myMgr.setReqMessage(
25 new Message(
26 myMgr.getRequestEnvelope()
27 )
28 );
29 myMgr.getReqMessage().setMessageContext(
30 myMgr.getMessageContext()
31 );
32 myMgr.call(myMgr.getReqMessage());
33 myMgr.close();
34 }
35
36 static
37 {
38 log = Logger.getLogger((SAAJCallMgr.class).getName());
39 ClassLoader cl = SAAJCallMgr.class.getClassLoader();
40 PropertyConfigurator.configure(cl.getResource(
41 "config/log4j.properties"));
42 }
43 }
44