KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > samples > attachments > TestRef


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package samples.attachments;
18
19
20 import org.apache.axis.AxisFault;
21 import org.apache.axis.attachments.AttachmentPart;
22 import org.apache.axis.client.Call;
23 import org.apache.axis.client.Service;
24 import org.apache.axis.message.SOAPBodyElement;
25 import org.apache.axis.transport.http.HTTPConstants;
26 import org.apache.axis.utils.Options;
27 import org.w3c.dom.Document JavaDoc;
28 import org.w3c.dom.Element JavaDoc;
29 import org.w3c.dom.Node JavaDoc;
30
31 import javax.activation.DataHandler JavaDoc;
32 import javax.activation.FileDataSource JavaDoc;
33 import java.io.ByteArrayInputStream JavaDoc;
34 import java.net.URL JavaDoc;
35 import java.util.Hashtable JavaDoc;
36 import java.util.Vector JavaDoc;
37
38
39 /**
40  *
41  * @author Rick Rineholt
42  */

43
44 /**
45  * An example of sending an attachment via messages.
46  * The main purpose is to validate the different types of attachment references
47  * by content Id, content location both absolute and relative.
48  *
49  * Creates 5 separate attachments referenced differently by a SOAP document.
50  * Each attachment contains a string that is assembled and tested to see if
51  * if the attachments are correctly sent and referenced. Each attachment also
52  * contains a mime header indicating its position and validated on the server
53  * to see if mime headers are correctly sent with attachments.
54  *
55  * Sends the same message again however the second attachments are placed in the
56  * stream in reverse to see if they are still referenced ok.
57  *
58  *
59  * The return SOAP document references a single attachment which is the a Java
60  * serialized vector holding strings to the individual attachments sent.
61  *
62  * Demos using attachments directly.
63  *
64  */

65 public class TestRef {
66
67     Options opts = null;
68     public static final String JavaDoc positionHTTPHeader="Ordinal";
69     public static final String JavaDoc TheKey= "Now is the time for all good men to come to the aid of their country.";
70
71
72     public TestRef( Options opts) {
73         this.opts = opts;
74     }
75
76
77     /**
78      * This method sends all the files in a directory.
79      * @param The directory that is the source to send.
80      * @return True if sent and compared.
81      */

82     public boolean testit() throws Exception JavaDoc {
83         boolean rc = true;
84         String JavaDoc baseLoc= "http://axis.org/attachTest";
85         Vector JavaDoc refs= new Vector JavaDoc(); //holds a string of references to attachments.
86

87         Service service = new Service(); //A new axis Service.
88

89         Call call = (Call) service.createCall(); //Create a call to the service.
90

91         /*Un comment the below statement to do HTTP/1.1 protocol*/
92       //call.setScopedProperty(MessageContext.HTTP_TRANSPORT_VERSION,HTTPConstants.HEADER_PROTOCOL_V11);
93
Hashtable JavaDoc myhttp= new Hashtable JavaDoc();
94         myhttp.put(HTTPConstants.HEADER_CONTENT_LOCATION, baseLoc); //Send extra soap headers
95

96         /*Un comment the below to do http chunking to avoid the need to calculate content-length. (Needs HTTP/1.1)*/
97       //myhttp.put(HTTPConstants.HEADER_TRANSFER_ENCODING, HTTPConstants.HEADER_TRANSFER_ENCODING_CHUNKED);
98

99         /*Un comment the below to force a 100-Continue... This will cause httpsender to wait for
100          * this response on a post. If HTTP 1.1 and this is not set, *SOME* servers *MAY* reply with this anyway.
101          * Currently httpsender won't handle this situation, this will require the resp. which it will handle.
102          */

103       //myhttp.put(HTTPConstants.HEADER_EXPECT, HTTPConstants.HEADER_EXPECT_100_Continue);
104
call.setProperty(HTTPConstants.REQUEST_HEADERS,myhttp);
105
106         call.setTargetEndpointAddress( new URL JavaDoc(opts.getURL()) ); //Set the target service host and service location,
107

108         java.util.Stack JavaDoc rev= new java.util.Stack JavaDoc();
109         //Create an attachment referenced by a generated contentId.
110
AttachmentPart ap= new AttachmentPart(new javax.activation.DataHandler JavaDoc(
111           "Now is the time", "text/plain" ));
112          refs.add(ap.getContentIdRef()); //reference the attachment by contentId.
113
ap.setMimeHeader(positionHTTPHeader, ""+refs.size() ); //create a MIME header indicating postion.
114
call.addAttachmentPart(ap);
115         rev.push(ap);
116
117         //Create an attachment referenced by a set contentId.
118
String JavaDoc setContentId="rick_did_this";
119         ap= new AttachmentPart(new DataHandler JavaDoc(" for all good", "text/plain" ));
120           //new MemoryOnlyDataSource(
121
ap.setContentId(setContentId);
122          refs.add("cid:" + setContentId); //reference the attachment by contentId.
123
ap.setMimeHeader(positionHTTPHeader, ""+refs.size() ); //create a MIME header indicating postion.
124
call.addAttachmentPart(ap);
125         rev.push(ap);
126
127         //Create an attachment referenced by a absolute contentLocation.
128
ap= new AttachmentPart(new DataHandler JavaDoc( " men to", "text/plain" ));
129           //new MemoryOnlyDataSource( " men to", "text/plain" )));
130
ap.setContentLocation(baseLoc+ "/firstLoc");
131          refs.add(baseLoc+ "/firstLoc"); //reference the attachment by contentId.
132
ap.setMimeHeader(positionHTTPHeader, ""+refs.size() ); //create a MIME header indicating postion.
133
call.addAttachmentPart(ap);
134         rev.push(ap);
135
136         //Create an attachment referenced by relative location to a absolute location.
137
ap= new AttachmentPart(new DataHandler JavaDoc( " come to", "text/plain" ));
138           // new MemoryOnlyDataSource( " come to", "text/plain" )));
139
ap.setContentLocation(baseLoc+ "/secondLoc");
140         refs.add("secondLoc"); //reference the attachment by contentId.
141
ap.setMimeHeader(positionHTTPHeader, ""+refs.size() ); //create a MIME header indicating postion.
142
call.addAttachmentPart(ap);
143         rev.push(ap);
144
145         //Create an attachment referenced by relative location to a relative location.
146
ap= new AttachmentPart(new DataHandler JavaDoc( " the aid of their country.", "text/plain" ));
147           // new MemoryOnlyDataSource( " the aid of their country.", "text/plain" )));
148
ap.setContentLocation("thirdLoc");
149         refs.add("thirdLoc"); //reference the attachment by contentId.
150
ap.setMimeHeader(positionHTTPHeader, ""+refs.size() ); //create a MIME header indicating postion.
151
call.addAttachmentPart(ap);
152         rev.push(ap);
153
154
155         //Now build the message....
156
String JavaDoc namespace="urn:attachmentsTestRef"; //needs to match name of service.
157

158         StringBuffer JavaDoc msg = new StringBuffer JavaDoc("\n<attachments xmlns=\"" +namespace +"\">\n");
159         for (java.util.Iterator JavaDoc i = refs.iterator(); i.hasNext() ; )
160           msg.append(" <attachment HREF=\"" + (String JavaDoc) i.next() + "\"/>\n");
161
162         msg.append( "</attachments>");
163
164         call.setUsername( opts.getUser());
165
166         call.setPassword( opts.getPassword() );
167
168         call.setOperationStyle("document");
169         call.setOperationUse("literal");
170
171         //Now do the call....
172
Object JavaDoc ret = call.invoke(new Object JavaDoc[]{
173            new SOAPBodyElement(new ByteArrayInputStream JavaDoc(msg.toString().getBytes("UTF-8"))) } );
174
175         validate(ret, call, "12345");
176
177         //Note: that even though the attachments are sent in reverse they are still
178
// retreived by reference so the ordinal will still match.
179
int revc=1;
180         for( ap= (AttachmentPart)rev.pop(); ap!=null ;ap= rev.empty()? null : (AttachmentPart)rev.pop()){
181           call.addAttachmentPart(ap);
182         }
183
184         //Now do the call....
185
ret = call.invoke(new Object JavaDoc[]{
186            new SOAPBodyElement(new ByteArrayInputStream JavaDoc(msg.toString().getBytes("UTF-8"))) } );
187
188         validate(ret, call, "54321");
189
190
191         return rc;
192     }
193
194     void validate(Object JavaDoc ret, Call call, final String JavaDoc expOrdPattern) throws Exception JavaDoc{
195         if (null == ret) {
196             System.out.println("Received null ");
197             throw new AxisFault("", "Received null", null, null);
198         }
199
200         if (ret instanceof String JavaDoc) {
201             System.out.println("Received problem response from server: " + ret);
202             throw new AxisFault("", (String JavaDoc) ret, null, null);
203         }
204
205         Vector JavaDoc vret= (Vector JavaDoc) ret;
206
207         if (!(ret instanceof java.util.Vector JavaDoc )) {
208             //The wrong type of object that what was expected.
209
System.out.println("Received unexpected type :" +
210                 ret.getClass().getName());
211             throw new AxisFault("", "Received unexpected type:" +
212                     ret.getClass().getName(), null, null);
213
214         }
215
216         org.apache.axis.message.RPCElement retrpc= (org.apache.axis.message.RPCElement )
217           ((Vector JavaDoc)ret).elementAt(0);
218
219         Document JavaDoc retDoc= org.apache.axis.utils.XMLUtils.newDocument(
220           new org.xml.sax.InputSource JavaDoc(new java.io.ByteArrayInputStream JavaDoc(
221             retrpc.toString().getBytes())));
222
223         //get at the attachments.
224
org.apache.axis.attachments.Attachments attachments=
225           call.getResponseMessage().getAttachmentsImpl();
226
227         //Still here, so far so good.
228
Element rootEl= retDoc.getDocumentElement();
229
230         Element caEl= getNextFirstChildElement(rootEl);
231         //this should be the only child element with the ref to our attachment
232
// response.
233
String JavaDoc HREF= caEl.getAttribute("href");
234         org.apache.axis.Part p= attachments.getAttachmentByReference(href);
235         if(null == p)
236          throw new org.apache.axis.AxisFault("Attachment for ref='"+href+"' not found." );
237
238          //Check to see the the attachment were sent in order
239
String JavaDoc ordPattern= caEl.getAttribute("ordinalPattern");
240         if(!expOrdPattern.equals(ordPattern))
241           throw new org.apache.axis.AxisFault(
242            "Attachments sent out of order expected:'" +expOrdPattern + "', got:'"+ordPattern+"'." );
243
244          //now get at the data...
245
DataHandler JavaDoc dh= ((org.apache.axis.attachments.AttachmentPart)p).getDataHandler();
246          System.err.println("content-type:" + dh.getContentType());
247
248        java.util.Vector JavaDoc rspVector= null;
249        Object JavaDoc rspObject = dh.getContent();//This SHOULD just return the vector but reality strikes...
250
if(rspObject == null)
251            throw new AxisFault("", "Received unexpected object:null", null, null);
252        else if(rspObject instanceof java.util.Vector JavaDoc) rspVector= (java.util.Vector JavaDoc)rspObject;
253        else if(rspObject instanceof java.io.InputStream JavaDoc)
254           rspVector= (java.util.Vector JavaDoc)
255            new java.io.ObjectInputStream JavaDoc((java.io.InputStream JavaDoc)rspObject ).readObject();
256        else
257            throw new AxisFault("", "Received unexpected object:" +
258                     rspObject.getClass().getName(), null, null);
259
260       StringBuffer JavaDoc fullmsg= new StringBuffer JavaDoc();
261       for(java.util.Iterator JavaDoc ri= rspVector.iterator(); ri.hasNext();){
262         String JavaDoc part= (String JavaDoc)ri.next();
263         fullmsg.append(part);
264         System.out.print(part);
265       }
266       System.out.println("");
267
268       if(!(TheKey.equals (fullmsg.toString())))
269         throw new org.apache.axis.AxisFault("Fullmsg not correct'"+fullmsg +"'." );
270     }
271
272     Element getNextFirstChildElement(Node JavaDoc n) {
273         if(n== null) return null;
274         n= n.getFirstChild();
275         for(; n!= null && !(n instanceof Element); n= n.getNextSibling());
276         return (Element)n;
277     }
278
279     Element getNextSiblingElement(Node JavaDoc n) {
280         if(n== null) return null;
281         n= n.getNextSibling();
282         for(; n!= null && !(n instanceof Element); n= n.getNextSibling());
283         return (Element)n;
284     }
285
286     /**
287      * Give a single file to send or name a directory
288      * to send an array of attachments of the files in
289      * that directory.
290      */

291     public static void main(String JavaDoc args[]) {
292         try {
293
294             Options opts = new Options(args);
295             TestRef echoattachment = new TestRef(opts);
296
297             args = opts.getRemainingArgs();
298             int argpos=0;
299
300             if (echoattachment.testit()) {
301                 System.out.println("Attachments sent and received ok!");
302                 System.exit(0);
303             }
304         }
305         catch ( Exception JavaDoc e ) {
306             System.err.println(e);
307              e.printStackTrace();
308         }
309         System.exit(18);
310     }
311
312
313     /**
314      * Return an array of datahandlers for each file in the dir.
315      * @param the name of the directory
316      * @return return an array of datahandlers.
317      */

318
319     protected DataHandler JavaDoc[] getAttachmentsFromDir(String JavaDoc dirName) {
320         java.util.LinkedList JavaDoc retList = new java.util.LinkedList JavaDoc();
321         DataHandler JavaDoc[] ret = new DataHandler JavaDoc[0];// empty
322

323         java.io.File JavaDoc sourceDir = new java.io.File JavaDoc(dirName);
324
325         java.io.File JavaDoc[] files = sourceDir.listFiles();
326
327         for ( int i = files.length - 1; i >= 0; --i) {
328             java.io.File JavaDoc cf = files[i];
329
330             if (cf.isFile() && cf.canRead()) {
331                 String JavaDoc fname = null;
332
333                 try {
334                     fname = cf.getAbsoluteFile().getCanonicalPath();
335                 }
336                 catch ( java.io.IOException JavaDoc e) {
337                     System.err.println("Couldn't get file \"" + fname + "\" skipping...");
338                     continue;
339                 }
340                 retList.add( new DataHandler JavaDoc( new FileDataSource JavaDoc( fname )));
341             }
342         }
343         if (!retList.isEmpty()) {
344             ret = new DataHandler JavaDoc[ retList.size()];
345             ret = (DataHandler JavaDoc[]) retList.toArray(ret);
346         }
347
348         return ret;
349     }
350
351     /**This class should store all attachment data in memory */
352     static class MemoryOnlyDataSource extends org.apache.axis.attachments.ManagedMemoryDataSource{
353     
354        MemoryOnlyDataSource( byte [] in, String JavaDoc contentType) throws java.io.IOException JavaDoc{
355          super( new java.io.ByteArrayInputStream JavaDoc( in) , Integer.MAX_VALUE -2, contentType, true);
356        }
357        MemoryOnlyDataSource( String JavaDoc in, String JavaDoc contentType)throws java.io.IOException JavaDoc{
358          this( in.getBytes() , contentType);
359        }
360     }
361 }
362
Popular Tags