Java tutorial
/* * Copyright 2001-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.axis.attachments; import org.apache.axis.Part; import org.apache.axis.components.logger.LogFactory; import org.apache.axis.transport.http.HTTPConstants; import org.apache.axis.utils.Messages; import org.apache.commons.logging.Log; import javax.activation.DataHandler; /** * This simulates the multipart stream. * * @author Rick Rineholt */ public class MultiPartDimeInputStream extends MultiPartInputStream { protected static Log log = LogFactory.getLog(MultiPartDimeInputStream.class.getName()); protected java.util.HashMap parts = new java.util.HashMap(); protected java.util.LinkedList orderedParts = new java.util.LinkedList(); protected int rootPartLength = 0; protected boolean closed = false; //If true the stream has been closed. protected boolean eos = false; //This is set once the SOAP packet has reached the end of stream. //This stream controls and manages the boundary. protected DimeDelimitedInputStream dimeDelimitedStream = null; protected java.io.InputStream soapStream = null; //Set the soap stream once found. protected byte[] boundary = null; protected java.io.ByteArrayInputStream cachedSOAPEnvelope = null; //Caches the soap stream if it is //Still open and a reference to read data in a later attachment occurs. protected String contentId = null; /** * Create a new Multipart stream from an input stream. * * @param is the true input stream that is read from * @throws java.io.IOException if it was not possible to build the Multipart */ public MultiPartDimeInputStream(java.io.InputStream is) throws java.io.IOException { super(null); //don't cache this stream. soapStream = dimeDelimitedStream = new DimeDelimitedInputStream(is); //The Soap stream must always be first contentId = dimeDelimitedStream.getContentId(); } public Part getAttachmentByReference(final String[] id) throws org.apache.axis.AxisFault { //First see if we have read it in yet. Part ret = null; try { for (int i = id.length - 1; ret == null && i > -1; --i) { ret = (AttachmentPart) parts.get(id[i]); } if (null == ret) { ret = readTillFound(id); } log.debug(Messages.getMessage("return02", "getAttachmentByReference(\"" + id + "\"", (ret == null ? "null" : ret.toString()))); } catch (java.io.IOException e) { throw new org.apache.axis.AxisFault(e.getClass().getName() + e.getMessage()); } return ret; } protected void addPart(String contentId, String locationId, AttachmentPart ap) { //For DIME streams Content-Location is ignored. if (contentId != null && contentId.trim().length() != 0) parts.put(contentId, ap); orderedParts.add(ap); } //Shouldn't never match protected static final String[] READ_ALL = { " * \0 ".intern() }; protected void readAll() throws org.apache.axis.AxisFault { try { readTillFound(READ_ALL); } catch (Exception e) { throw org.apache.axis.AxisFault.makeFault(e); } } public java.util.Collection getAttachments() throws org.apache.axis.AxisFault { readAll(); return new java.util.LinkedList(orderedParts); } /** * This will read streams in till the one that is needed is found. * * @param id is the stream being sought * @return a <code>Part</code> matching the ids */ protected Part readTillFound(final String[] id) throws java.io.IOException { if (dimeDelimitedStream == null) { //The whole stream has been consumed already return null; } Part ret = null; try { if (soapStream != null) { //Still on the SOAP stream. if (!eos) { //The SOAP packet has not been fully read yet. Need to store it away. java.io.ByteArrayOutputStream soapdata = new java.io.ByteArrayOutputStream(1024 * 8); byte[] buf = new byte[1024 * 16]; int byteread = 0; do { byteread = soapStream.read(buf); if (byteread > 0) { soapdata.write(buf, 0, byteread); } } while (byteread > -1); soapdata.close(); soapStream.close(); soapStream = new java.io.ByteArrayInputStream(soapdata.toByteArray()); } dimeDelimitedStream = dimeDelimitedStream.getNextStream(); } //Now start searching for the data. if (null != dimeDelimitedStream) { do { String contentId = dimeDelimitedStream.getContentId(); String type = dimeDelimitedStream.getType(); if (type != null && !dimeDelimitedStream.getDimeTypeNameFormat().equals(DimeTypeNameFormat.MIME)) { type = "application/uri; uri=\"" + type + "\""; } ManagedMemoryDataSource source = new ManagedMemoryDataSource(dimeDelimitedStream, ManagedMemoryDataSource.MAX_MEMORY_DISK_CACHED, type, true); DataHandler dh = new DataHandler(source); AttachmentPart ap = new AttachmentPart(dh); if (contentId != null) { ap.setMimeHeader(HTTPConstants.HEADER_CONTENT_ID, contentId); } addPart(contentId, "", ap); for (int i = id.length - 1; ret == null && i > -1; --i) { if (contentId != null && id[i].equals(contentId)) { //This is the part being sought ret = ap; } } dimeDelimitedStream = dimeDelimitedStream.getNextStream(); } while (null == ret && null != dimeDelimitedStream); } } catch (Exception e) { throw org.apache.axis.AxisFault.makeFault(e); } return ret; } /** * Return the content location. * @return the Content-Location of the stream. * Null if no content-location specified. */ public String getContentLocation() { return null; } /** * Return the content id of the stream. * * @return the Content-Location of the stream. * Null if no content-location specified. */ public String getContentId() { return contentId; } public int read(byte[] b, int off, int len) throws java.io.IOException { if (closed) { throw new java.io.IOException(Messages.getMessage("streamClosed")); } if (eos) { return -1; } int read = soapStream.read(b, off, len); if (read < 0) { eos = true; } return read; } public int read(byte[] b) throws java.io.IOException { return read(b, 0, b.length); } public int read() throws java.io.IOException { if (closed) { throw new java.io.IOException(Messages.getMessage("streamClosed")); } if (eos) { return -1; } int ret = soapStream.read(); if (ret < 0) { eos = true; } return ret; } public void close() throws java.io.IOException { closed = true; soapStream.close(); } }