/******************************************************************************* * Copyright (c) 2009 MATERNA Information & Communications. All rights reserved. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html. For further * project-related information visit http://www.ws4d.org. The most recent * version of the JMEDS framework can be obtained from * http://sourceforge.net/projects/ws4d-javame. ******************************************************************************/ package org.ws4d.java.attachment; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.ws4d.java.service.parameter.ParameterValue; import org.ws4d.java.types.InternetMediaType; import org.ws4d.java.util.IDGenerator; /** * This class is used to represent an attachment as a byte array. Access to this * attachemnt's raw data is possible by means of method {@link #getBytes()} * (which returns a reference to the actual bytes of the attachment rather than * a copy), but also using method {@link #getInputStream()}. The latter will * return a new input stream instance for every call. * <p> * In order to support easy and fast type checking, method {@link #getType()} * will return always {@link #MEMORY_ATTACHMENT} for instances of this class. * </p> */ class MemoryAttachment extends AbstractAttachment implements IncomingAttachment, OutgoingAttachment { private byte[] bytes; /** * Creates an attachment by obtaining its raw data from the specified byte * array <code>bytes</code>. A unique {@link #getContentId() content ID} for * this attachment is automatically generated. Its {@link #getContentType() * content type} will be unspecified. * * @param bytes the array constituting this attachemnt's raw data */ MemoryAttachment(byte[] bytes) { this(bytes, (InternetMediaType) null); } /** * Creates an attachment by obtaining its raw data from the specified byte * array <code>bytes</code>. A unique {@link #getContentId() content ID} for * this attachment is automatically generated. * * @param bytes the array constituting this attachemnt's raw data * @param contentType the MIME content type of the attachment */ MemoryAttachment(byte[] bytes, InternetMediaType contentType) { this(bytes, IDGenerator.getUUID(), contentType); } /** * Creates an attachment by obtaining its raw data from the specified byte * array <code>bytes</code>. A unique {@link #getContentId() content ID} for * this attachment is automatically generated. * * @param bytes the array constituting this attachemnt's raw data * @param contentType the MIME content type of the attachment */ MemoryAttachment(byte[] bytes, String contentType) { this(bytes, IDGenerator.getUUID(), contentType); } /** * Creates an attachment by obtaining its raw data from the specified byte * array <code>bytes</code> and assigns the specified <code>contentId</code> * to it. * * @param bytes the array constituting this attachemnt's raw data * @param contentId the MIME content ID of the attachment, which should be * unique within the scope of the MIME package that the * attachment is contained in; in the case of DPWS this scope * corresponds to a single invocation message, i.e. the content * ID must be unique within the {@link ParameterValue} hierarchy * of an operations input or output parameters * @param contentType the MIME content type of the attachment */ MemoryAttachment(byte[] bytes, String contentId, InternetMediaType contentType) { super(contentId, contentType); this.bytes = bytes; } /** * Creates an attachment by obtaining its raw data from the specified byte * array <code>bytes</code> and assigns the specified <code>contentId</code> * to it. * * @param bytes the array constituting this attachemnt's raw data * @param contentId the MIME content ID of the attachment which should be * unique within the scope of the MIME package the attachment is * contained in; in the case of DPWS this scope corresponds to a * single invocation message, i.e. the content ID must be unique * within the {@link ParameterValue} hierarchy of an operation's * input or output parameters * @param contentType the MIME content type of the attachment */ MemoryAttachment(byte[] bytes, String contentId, String contentType) { this(bytes, contentId, maskContentType(contentType)); } /* * This special constructor is only used by the DefaultAttachmentStore to * handle faulty attachments. */ MemoryAttachment(AttachmentException readInException) { this(EMPTY_BYTE_ARRAY); setReadInException(readInException); } /** * Always returns {@link #MEMORY_ATTACHMENT}. */ public final int getType() throws AttachmentException { return MEMORY_ATTACHMENT; } /* * (non-Javadoc) * @see org.ws4d.java.attachment.Attachment#dispose() */ public void dispose() { bytes = null; } /** * Returns a <em>reference to</em> (rather than a <em>copy of</em>) the byte * array that contains the raw data of this attachment. * * @return byte array containing this attachment's raw data * @throws AttachmentException if attachment processing is not supported * within the current runtime or obtaining the attachment failed * for any reason */ public byte[] getBytes() throws AttachmentException { if (readInException != null) { throw readInException; } return bytes == null ? EMPTY_BYTE_ARRAY : bytes; } /** * Returns the length of the byte array constituting this attachemnt's raw * data. */ public long size() throws AttachmentException { if (readInException != null) { throw readInException; } if (bytes == null) { return 0; } return bytes.length; } /** * Creates and returns a new stream wrapped around this attachment's raw * data for each call. */ public InputStream getInputStream() throws AttachmentException, IOException { if (readInException != null) { throw readInException; } if (bytes == null) { return EMPTY_STREAM; } return new ByteArrayInputStream(bytes); } /* * (non-Javadoc) * @see * org.ws4d.java.communication.protocol.mime.MIMEEntityOutput#serialize( * java.io.OutputStream) */ public void serialize(OutputStream out) throws IOException { if (bytes != null) { out.write(bytes); dispose(); } } /* * (non-Javadoc) * @see org.ws4d.java.attachment.Attachment#isLocal() */ public boolean isLocal() { return true; } /* * (non-Javadoc) * @see org.ws4d.java.attachment.Attachment#getFilePath() */ public String getFilePath() throws AttachmentException { throw new AttachmentException("file system operations not supported for memory attachments"); } /* * (non-Javadoc) * @see org.ws4d.java.attachment.Attachment#save(java.lang.String) */ public void save(String targetFilePath) throws AttachmentException, IOException { throw new AttachmentException("file system operations not supported for memory attachments"); } /* * (non-Javadoc) * @see org.ws4d.java.attachment.Attachment#move(java.lang.String) */ public boolean move(String newFilePath) throws AttachmentException { throw new AttachmentException("file system operations not supported for memory attachments"); } }