Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/apache/axis/attachments/MultiPartDimeInputStream.java


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 org.apache.axis.attachments;
18  
19  
20  import org.apache.axis.Part;
21  import org.apache.axis.components.logger.LogFactory;
22  import org.apache.axis.transport.http.HTTPConstants;
23  import org.apache.axis.utils.Messages;
24  import org.apache.commons.logging.Log;
25  
26  import javax.activation.DataHandler;
27  
28  
29  /**
30   * This simulates the multipart stream.
31   *
32   * @author Rick Rineholt
33   */
34  public class MultiPartDimeInputStream extends  MultiPartInputStream {
35      protected static Log log =
36          LogFactory.getLog(MultiPartDimeInputStream.class.getName());
37  
38      protected java.util.HashMap parts = new java.util.HashMap();
39      protected java.util.LinkedList orderedParts = new java.util.LinkedList();
40      protected int rootPartLength = 0;
41      protected boolean closed = false; //If true the stream has been closed.
42      protected boolean eos = false;  //This is set once the SOAP packet has reached the end of stream.
43      //This stream controls and manages the  boundary.
44      protected DimeDelimitedInputStream dimeDelimitedStream = null;
45      protected java.io.InputStream soapStream = null; //Set the soap stream once found.
46      protected byte[] boundary = null;
47      protected java.io.ByteArrayInputStream cachedSOAPEnvelope = null; //Caches the soap stream if it is
48      //Still open and a reference to read data in a later attachment occurs.
49      protected String contentId = null;
50  
51      /**
52       * Create a new Multipart stream from an input stream.
53       *
54       * @param is the true input stream that is read from
55       * @throws java.io.IOException if it was not possible to build the Multipart
56       */
57      public MultiPartDimeInputStream (java.io.InputStream is)
58        throws java.io.IOException {
59          super(null); //don't cache this stream.
60          soapStream = dimeDelimitedStream = new DimeDelimitedInputStream(is); //The Soap stream must always be first
61          contentId = dimeDelimitedStream.getContentId();
62      }
63  
64      public Part getAttachmentByReference(final String[] id)
65        throws org.apache.axis.AxisFault {
66          //First see if we have read it in yet.
67          Part ret = null;
68  
69          try {
70              for (int i = id.length - 1; ret == null && i > -1; --i) {
71                  ret = (AttachmentPart) parts.get(id[i]);
72              }
73  
74              if (null == ret) {
75                  ret = readTillFound(id);
76              }
77              log.debug(Messages.getMessage("return02",
78                      "getAttachmentByReference(\"" + id + "\"",
79                      (ret == null ? "null" : ret.toString())));
80          } catch (java.io.IOException e) {
81              throw new org.apache.axis.AxisFault(e.getClass().getName()
82                + e.getMessage());
83          }
84          return ret;
85      }
86  
87      protected void addPart(String contentId, String locationId,
88       AttachmentPart  ap) {
89       //For DIME streams Content-Location is ignored.
90          if (contentId != null && contentId.trim().length() != 0)
91            parts.put(contentId, ap);
92          orderedParts.add(ap);
93      }
94  
95      //Shouldn't never match
96      protected static final String[] READ_ALL = { " * \0 ".intern()};
97  
98      protected void readAll() throws org.apache.axis.AxisFault {
99          try {
100             readTillFound(READ_ALL);
101         } catch (Exception e) {
102             throw org.apache.axis.AxisFault.makeFault(e);
103         }
104     }
105 
106     public java.util.Collection getAttachments()
107       throws org.apache.axis.AxisFault {
108         readAll();
109         return new java.util.LinkedList(orderedParts);
110     }
111 
112     /**
113      * This will read streams in till the one that is needed is found.
114      *
115      * @param id is the stream being sought
116      * @return a <code>Part</code> matching the ids
117      */
118     protected Part readTillFound(final String[] id)
119       throws java.io.IOException {
120         if (dimeDelimitedStream == null) {
121             //The whole stream has been consumed already
122             return null;
123         }
124         Part ret = null;
125 
126         try {
127 
128             if (soapStream != null) { //Still on the SOAP stream.
129                 if (!eos) { //The SOAP packet has not been fully read yet. Need to store it away.
130 
131                     java.io.ByteArrayOutputStream soapdata =
132                       new java.io.ByteArrayOutputStream(1024 * 8);
133 
134                     byte[] buf = new byte[1024 * 16];
135                     int byteread = 0;
136 
137                     do {
138                         byteread = soapStream.read(buf);
139                         if (byteread > 0) {
140                             soapdata.write(buf, 0, byteread);
141                         }
142 
143                     } while (byteread > -1);
144                     soapdata.close();
145                     soapStream.close();
146                     soapStream = new java.io.ByteArrayInputStream(
147                      soapdata.toByteArray());
148                 }
149                 dimeDelimitedStream = dimeDelimitedStream.getNextStream();
150             }
151             //Now start searching for the data.
152 
153             if (null != dimeDelimitedStream) {
154                 do {
155                     String contentId = dimeDelimitedStream.getContentId();
156                     String type = dimeDelimitedStream.getType();
157 
158                     if (type != null && !dimeDelimitedStream.getDimeTypeNameFormat().equals(DimeTypeNameFormat.MIME)) {
159                         type = "application/uri; uri=\"" + type + "\"";
160                     }
161 
162 
163                     ManagedMemoryDataSource source = new ManagedMemoryDataSource(dimeDelimitedStream,
164                                           ManagedMemoryDataSource.MAX_MEMORY_DISK_CACHED, type, true);
165                     DataHandler dh = new DataHandler(source);
166 
167                     AttachmentPart ap = new AttachmentPart(dh);
168                     if (contentId != null) {
169                         ap.setMimeHeader(HTTPConstants.HEADER_CONTENT_ID, contentId);
170                     }
171 
172                     addPart(contentId, "", ap);
173 
174                     for (int i = id.length - 1; ret == null && i > -1; --i) {
175                         if (contentId != null && id[i].equals(contentId)) { //This is the part being sought
176                             ret = ap;
177                         }
178                     }
179 
180                     dimeDelimitedStream =
181                      dimeDelimitedStream.getNextStream();
182 
183                 }
184                 while (null == ret && null != dimeDelimitedStream);
185             }
186         } catch (Exception e) {
187             throw org.apache.axis.AxisFault.makeFault(e);
188         }
189 
190         return ret;
191     }
192 
193     /**
194      * Return the content location.
195      * @return the Content-Location of the stream.
196      *   Null if no content-location specified.
197      */
198     public String getContentLocation() {
199         return null;
200     }
201 
202     /**
203      * Return the content id of the stream.
204      *
205      * @return the Content-Location of the stream.
206      *   Null if no content-location specified.
207      */
208     public String getContentId() {
209         return contentId;
210     }
211 
212     public int read(byte[] b, int off, int len)
213       throws java.io.IOException {
214         if (closed) {
215             throw new java.io.IOException(Messages.getMessage(
216               "streamClosed"));
217         }
218         if (eos) {
219             return -1;
220         }
221         int read = soapStream.read(b, off, len);
222 
223         if (read < 0) {
224             eos = true;
225         }
226         return read;
227     }
228 
229     public int read(byte[] b) throws java.io.IOException {
230         return read(b, 0, b.length);
231     }
232 
233     public int read() throws java.io.IOException {
234         if (closed) {
235             throw new java.io.IOException(Messages.getMessage(
236             "streamClosed"));
237         }
238         if (eos) {
239             return -1;
240         }
241         int ret = soapStream.read();
242 
243         if (ret < 0) {
244             eos = true;
245         }
246         return ret;
247     }
248 
249     public void close() throws java.io.IOException {
250         closed = true;
251         soapStream.close();
252     }
253 }