| AttachmentPartImpl.java |
/*
* 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.jboss.axis.attachments;
import org.jboss.axis.Part;
import org.jboss.axis.components.image.ImageIOFactory;
import org.jboss.axis.transport.http.HTTPConstants;
import org.jboss.axis.utils.IOUtils;
import org.jboss.axis.utils.Messages;
import org.jboss.axis.utils.SessionUtils;
import org.jboss.logging.Logger;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.mail.internet.MimeMultipart;
import javax.xml.soap.AttachmentPart;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPException;
import javax.xml.transform.stream.StreamSource;
import java.awt.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
/**
* An attachment part. * *
*/
public class AttachmentPartImpl extends AttachmentPart implements Part
{
/**
* Field log
*/
private static Logger log = Logger.getLogger(AttachmentPartImpl.class.getName());
/**
* Field datahandler
*/
private DataHandler datahandler = null;
/**
* Field mimeHeaders
*/
private MimeHeaders mimeHeaders = new MimeHeaders();
/**
* Field contentObject
*/
private Object contentObject;
/**
* Constructor AttachmentPart
*/
public AttachmentPartImpl()
{
setMimeHeader(HTTPConstants.HEADER_CONTENT_ID, SessionUtils.generateSessionId());
}
/**
* Constructor AttachmentPart
*
* @param dh
*/
public AttachmentPartImpl(DataHandler dh)
{
setMimeHeader(HTTPConstants.HEADER_CONTENT_ID, SessionUtils.generateSessionId());
datahandler = dh;
if (dh != null)
setMimeHeader(HTTPConstants.HEADER_CONTENT_TYPE, dh.getContentType());
}
/**
* Method getActivationDataHandler
*
* @return
*/
public DataHandler getActivationDataHandler()
{
return datahandler;
}
/**
* getContentType
*
* @return content type
*/
public String getContentType()
{
return getFirstMimeHeader(HTTPConstants.HEADER_CONTENT_TYPE);
}
public void setContentType(String contentType)
{
super.setContentType(contentType);
setMimeHeader(HTTPConstants.HEADER_CONTENT_TYPE, contentType);
}
/**
* Add the specified MIME header, as per JAXM.
*
* @param header
* @param value
*/
public void addMimeHeader(String header, String value)
{
mimeHeaders.addHeader(header, value);
}
/**
* Get the specified MIME header.
*
* @param header
* @return
*/
public String getFirstMimeHeader(String header)
{
String[] values = mimeHeaders.getHeader(header.toLowerCase());
if ((values != null) && (values.length > 0))
{
return values[0];
}
return null;
}
/**
* check if this Part's mimeheaders matches the one passed in.
* TODO: Am not sure about the logic.
*/
public boolean matches(javax.xml.soap.MimeHeaders headers)
{
for (Iterator i = headers.getAllHeaders(); i.hasNext();)
{
javax.xml.soap.MimeHeader hdr = (javax.xml.soap.MimeHeader)i.next();
String values[] = mimeHeaders.getHeader(hdr.getName());
boolean found = false;
if (values != null)
{
for (int j = 0; j < values.length; j++)
{
if (!hdr.getValue().equalsIgnoreCase(values[j]))
{
continue;
}
found = true;
break;
}
}
if (!found)
{
return false;
}
}
return true;
}
/**
* Content location.
*/
public String getContentLocation()
{
return getFirstMimeHeader(HTTPConstants.HEADER_CONTENT_LOCATION);
}
/**
* Set content location.
*
* @param loc
*/
public void setContentLocation(String loc)
{
setMimeHeader(HTTPConstants.HEADER_CONTENT_LOCATION, loc);
}
/**
* Sets Content-Id of this part.
* already defined.
*
* @param newCid new Content-Id
*/
public void setContentId(String newCid)
{
setMimeHeader(HTTPConstants.HEADER_CONTENT_ID, newCid);
}
/**
* Content ID.
*
* @return
*/
public String getContentId()
{
return getFirstMimeHeader(HTTPConstants.HEADER_CONTENT_ID);
}
/**
* Get all headers that match
*
* @param match
* @return
*/
public java.util.Iterator getMatchingMimeHeaders(final String[] match)
{
return mimeHeaders.getMatchingHeaders(match);
}
/**
* Get all headers that do not match
*
* @param match
* @return
*/
public java.util.Iterator getNonMatchingMimeHeaders(final String[] match)
{
return mimeHeaders.getNonMatchingHeaders(match);
}
/**
* Retrieves all the headers for this <CODE>
* AttachmentPart</CODE> object as an iterator over the <CODE>
* MimeHeader</CODE> objects.
*
* @return an <CODE>Iterator</CODE> object with all of the Mime
* headers for this <CODE>AttachmentPart</CODE> object
*/
public Iterator getAllMimeHeaders()
{
return mimeHeaders.getAllHeaders();
}
/**
* Changes the first header entry that matches the given name
* to the given value, adding a new header if no existing
* header matches. This method also removes all matching
* headers but the first.
* <p/>
* <P>Note that RFC822 headers can only contain US-ASCII
* characters.</P>
*
* @param name a <CODE>String</CODE> giving the
* name of the header for which to search
* @param value a <CODE>String</CODE> giving the
* value to be set for the header whose name matches the
* given name
* @throws java.lang.IllegalArgumentException
* if
* there was a problem with the specified mime header name
* or value
*/
public void setMimeHeader(String name, String value)
{
mimeHeaders.setHeader(name, value);
}
/**
* Removes all the MIME header entries.
*/
public void removeAllMimeHeaders()
{
mimeHeaders.removeAllHeaders();
}
/**
* Removes all MIME headers that match the given name.
*
* @param header - the string name of the MIME
* header/s to be removed
*/
public void removeMimeHeader(String header)
{
mimeHeaders.removeHeader(header);
}
/**
* Gets the <CODE>DataHandler</CODE> object for this <CODE>
* AttachmentPart</CODE> object.
*
* @return the <CODE>DataHandler</CODE> object associated with
* this <CODE>AttachmentPart</CODE> object
* @throws SOAPException if there is
* no data in this <CODE>AttachmentPart</CODE> object
*/
public DataHandler getDataHandler() throws SOAPException
{
if (datahandler == null)
{
throw new SOAPException(Messages.getMessage("noContent"));
}
return datahandler;
}
/**
* Sets the given <CODE>DataHandler</CODE> object as the
* data handler for this <CODE>AttachmentPart</CODE> object.
* Typically, on an incoming message, the data handler is
* automatically set. When a message is being created and
* populated with content, the <CODE>setDataHandler</CODE>
* method can be used to get data from various data sources into
* the message.
*
* @param datahandler <CODE>DataHandler</CODE> object to
* be set
* @throws IllegalArgumentException if
* there was a problem with the specified <CODE>
* DataHandler</CODE> object
*/
public void setDataHandler(DataHandler datahandler)
{
if (datahandler == null)
{
throw new IllegalArgumentException(Messages.getMessage("illegalArgumentException00"));
}
this.datahandler = datahandler;
setMimeHeader(HTTPConstants.HEADER_CONTENT_TYPE, datahandler.getContentType());
}
/**
* Gets the content of this <CODE>AttachmentPart</CODE> object
* as a Java object. The type of the returned Java object
* depends on (1) the <CODE>DataContentHandler</CODE> object
* that is used to interpret the bytes and (2) the <CODE>
* Content-Type</CODE> given in the header.
* <p/>
* <P>For the MIME content types "text/plain", "text/html" and
* "text/xml", the <CODE>DataContentHandler</CODE> object does
* the conversions to and from the Java types corresponding to
* the MIME types. For other MIME types,the <CODE>
* DataContentHandler</CODE> object can return an <CODE>
* InputStream</CODE> object that contains the content data as
* raw bytes.</P>
* <p/>
* <P>A JAXM-compliant implementation must, as a minimum,
* return a <CODE>String</CODE> object corresponding
* to any content stream with a <CODE>Content-Type</CODE>
* value of <CODE>text/plain</CODE> and a <CODE>
* javax.xml.transform.StreamSource</CODE> object
* corresponding to a content stream with a <CODE>
* Content-Type</CODE> value of <CODE>text/xml</CODE>. For
* those content types that an installed <CODE>
* DataContentHandler</CODE> object does not understand, the
* <CODE>DataContentHandler</CODE> object is required to
* return a <CODE>java.io.InputStream</CODE> object with the
* raw bytes.</P>
*
* @return a Java object with the content of this <CODE>
* AttachmentPart</CODE> object
* @throws SOAPException if there is no content set
* into this <CODE>AttachmentPart</CODE> object or if there
* was a data transformation error
*/
public Object getContent() throws SOAPException
{
if (contentObject != null)
return contentObject;
try
{
if (datahandler != null)
{
DataSource ds = datahandler.getDataSource();
InputStream is = ds.getInputStream();
String contentType = ds.getContentType();
if (contentType.equals("text/plain"))
{
byte[] bytes = IOUtils.toByteArray(is);
contentObject = new String(bytes);
}
else if (contentType.equals("text/xml") || contentType.equals("application/xml"))
{
contentObject = new StreamSource(is);
}
else if (contentType.startsWith("multipart/"))
{
MimeMultipart mmp = new MimeMultipart(ds);
contentObject = mmp;
}
else if (contentType.equals("image/gif") || contentType.equals("image/jpeg"))
{
contentObject = ImageIOFactory.getImageIO().loadImage(is);
}
else
{
contentObject = is;
}
}
}
catch (SOAPException e)
{
throw e;
}
catch (Exception e)
{
throw new SOAPException("Cannot get content", e);
}
if (contentObject == null)
throw new SOAPException("Content is not available");
return contentObject;
}
/**
* Sets the content of this attachment part to that of the
* given <CODE>Object</CODE> and sets the value of the <CODE>
* Content-Type</CODE> header to the given type. The type of the
* <CODE>Object</CODE> should correspond to the value given for
* the <CODE>Content-Type</CODE>. This depends on the particular
* set of <CODE>DataContentHandler</CODE> objects in use.
*
* @param object the Java object that makes up
* the content for this attachment part
* @param contentType the MIME string that
* specifies the type of the content
* @throws IllegalArgumentException if
* the contentType does not match the type of the content
* object, or if there was no <CODE>
* DataContentHandler</CODE> object for this content
* object
* @see #getContent() getContent()
*/
public void setContent(Object object, String contentType)
{
try
{
contentObject = object;
if (object instanceof String)
{
InputStream inputStream = new ByteArrayInputStream(((String)contentObject).getBytes());
ManagedMemoryDataSource source = new ManagedMemoryDataSource(inputStream, contentType);
datahandler = new DataHandler(source);
}
else if (object instanceof StreamSource)
{
InputStream inputStream = ((StreamSource)object).getInputStream();
ManagedMemoryDataSource source = new ManagedMemoryDataSource(inputStream, contentType);
datahandler = new DataHandler(source);
}
else if (object instanceof Image)
{
datahandler = new DataHandler(object, contentType);
}
else if (object instanceof MimeMultipart)
{
ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
MimeMultipart mmp = (MimeMultipart)object;
mmp.writeTo(baos);
InputStream inputStream = new ByteArrayInputStream(baos.toByteArray());
ManagedMemoryDataSource source = new ManagedMemoryDataSource(inputStream, contentType);
datahandler = new DataHandler(source);
}
else if (object instanceof InputStream)
{
InputStream inputStream = ((InputStream)object);
ManagedMemoryDataSource source = new ManagedMemoryDataSource(inputStream, contentType);
datahandler = new DataHandler(source);
}
else
{
throw new IllegalArgumentException("Cannot set content: " + object);
}
}
catch (IllegalArgumentException e)
{
throw e;
}
catch (Exception e)
{
throw new IllegalArgumentException(e.toString());
}
}
public void dispose()
{
contentObject = null;
datahandler = null;
}
/**
* Clears out the content of this <CODE>
* AttachmentPart</CODE> object. The MIME header portion is left
* untouched.
*/
public void clearContent()
{
datahandler = null;
contentObject = null;
}
/**
* Returns the number of bytes in this <CODE>
* AttachmentPart</CODE> object.
*
* @return the size of this <CODE>AttachmentPart</CODE> object
* in bytes or -1 if the size cannot be determined
* @throws SOAPException if the content of this
* attachment is corrupted of if there was an exception
* while trying to determine the size.
*/
public int getSize() throws SOAPException
{
if (datahandler == null)
{
return 0;
}
ByteArrayOutputStream bout = new ByteArrayOutputStream();
try
{
datahandler.writeTo(bout);
}
catch (IOException ex)
{
log.error(Messages.getMessage("javaIOException00"), ex);
throw new SOAPException(Messages.getMessage("javaIOException01", ex.getMessage()), ex);
}
return bout.size();
}
/**
* Gets all the values of the header identified by the given
* <CODE>String</CODE>.
*
* @param name the name of the header; example:
* "Content-Type"
* @return a <CODE>String</CODE> array giving the value for the
* specified header
* @see #setMimeHeader(String, String) setMimeHeader(String, String)
*/
public String[] getMimeHeader(String name)
{
return mimeHeaders.getHeader(name);
}
/**
* Content ID.
*
* @return the contentId reference value that should be used directly
* as an href in a SOAP element to reference this attachment.
* <B>Not part of JAX-RPC, JAX-M, SAAJ, etc. </B>
*/
public String getContentIdRef()
{
return Attachments.CIDprefix + getContentId();
}
}
| AttachmentPartImpl.java |