FileDocCategorySizeDatePackage
AttachmentsImpl.javaAPI DocApache Axis 1.424823Sat Apr 22 18:57:26 BST 2006org.apache.axis.attachments

AttachmentsImpl

public class AttachmentsImpl extends Object implements Attachments
Implements the Attachment interface, via an actual Hashmap of actual AttachmentParts.

Fields Summary
protected static Log
log
private HashMap
attachments
Field attachments.
private LinkedList
orderedAttachments
Field orderedAttachments.
protected org.apache.axis.SOAPPart
soapPart
Field soapPart.
protected MultiPartInputStream
mpartStream
The actual stream to manage the multi-related input stream.
protected int
sendtype
The form of the attachments, whether MIME or DIME.
protected String
contentLocation
This is the content location as specified in SOAP with Attachments. This maybe null if the message had no Content-Location specifed.
private HashMap
stackDataHandler
The HashMap for DataHandler Managements.
private IncomingAttachmentStreams
_streams
Used to distribute attachment streams without caching them.
private boolean
_askedForAttachments
private boolean
_askedForStreams
MimeMultipart
multipart
multipart , cached entries for the stream of attachment that are going to be sent.
DimeMultiPart
dimemultipart
Constructors Summary
public AttachmentsImpl(Object intialContents, String contentType, String contentLocation)
Construct one of these on a parent Message. Should only ever be called by Message constructor!

param
intialContents should be anything but today only a stream is supported.
param
contentType The mime content type of the stream for transports that provide it.
param
contentLocation
throws
org.apache.axis.AxisFault


                                                                     
     
                 
              

        if (contentLocation != null) {
            contentLocation = contentLocation.trim();

            if (contentLocation.length() == 0) {
                contentLocation = null;
            }
        }

        this.contentLocation = contentLocation;

        if (contentType != null) {
            if (contentType.equals(org.apache.axis.Message.MIME_UNKNOWN)) {

            } else {
                java.util.StringTokenizer st =
                        new java.util.StringTokenizer(contentType, " \t;");

                if (st.hasMoreTokens()) {
                    String token = st.nextToken();

                    if (token.equalsIgnoreCase(
                            org.apache.axis.Message.MIME_MULTIPART_RELATED)) {
                        sendtype=  SEND_TYPE_MIME;
                        mpartStream =
                                new org.apache.axis.attachments.MultiPartRelatedInputStream(
                                        contentType,
                                        (java.io.InputStream) intialContents);

                        if (null == contentLocation) {

                            // If the content location is not specified as
                            // of the main message use the SOAP content location.
                            contentLocation = mpartStream.getContentLocation();

                            if (contentLocation != null) {
                                contentLocation = contentLocation.trim();

                                if (contentLocation.length() == 0) {
                                    contentLocation = null;
                                }
                            }
                        }

                        soapPart = new org.apache.axis.SOAPPart(null,
                                mpartStream,
                                false);
                        MultiPartRelatedInputStream specificType = (MultiPartRelatedInputStream) mpartStream;
                        _streams = new MultipartAttachmentStreams(specificType.boundaryDelimitedStream, specificType.orderedParts);
                     } else if (token.equalsIgnoreCase(org.apache.axis.Message.MIME_APPLICATION_DIME)) {
                         try{
                            mpartStream=
                             new MultiPartDimeInputStream( (java.io.InputStream) intialContents);
                             soapPart = new org.apache.axis.SOAPPart(null, mpartStream, false);
                         }catch(Exception e){ throw org.apache.axis.AxisFault.makeFault(e);}
                         sendtype=  SEND_TYPE_DIME;
                         MultiPartDimeInputStream specificType = (MultiPartDimeInputStream) mpartStream;
                         _streams = new DimeAttachmentStreams(specificType.dimeDelimitedStream);
                    } else if (token.indexOf(org.apache.axis.Message.CONTENT_TYPE_MTOM)!=-1){
                        sendtype = SEND_TYPE_MTOM;
                    }
                }
            }
        }

    
Methods Summary
private java.util.IteratorGetAttachmentsIterator()
get an iterator over all attachments. This

return
iterator of Part Objects; some of which may be AttachmentPart instances
see
org.apache.axis.Part
see
AttachmentPart

        java.util.Iterator iterator = attachments.values().iterator();
        return iterator;
    
public org.apache.axis.PartaddAttachmentPart(org.apache.axis.Part newPart)
Adds an existing attachment to this list. Note: Passed part will be bound to this message.

param
newPart new part to add
return
Part old attachment with the same Content-ID, or null.
throws
org.apache.axis.AxisFault

        if (_askedForStreams) {
            throw new IllegalStateException(Messages.getMessage("concurrentModificationOfStream"));
        }

        multipart = null;
        dimemultipart = null;

        mergeinAttachments();

        Part oldPart = (Part) attachments.put(newPart.getContentId(), newPart);

        if (oldPart != null) {
            orderedAttachments.remove(oldPart);
            attachments.remove(oldPart.getContentLocation());
        }

        orderedAttachments.add(newPart);

        if (newPart.getContentLocation() != null) {
            attachments.put(newPart.getContentLocation(), newPart);
        }

        return oldPart;
    
public org.apache.axis.PartcreateAttachmentPart()
Create a new attachment Part in this Message. Will actually, and always, return an AttachmentPart.

return
a new attachment Part
throws
org.apache.axis.AxisFault

        return new AttachmentPart();
    
public org.apache.axis.PartcreateAttachmentPart(java.lang.Object datahandler)


        // Searching for the same attachements
    	Integer key = new Integer(datahandler.hashCode());
    	if (stackDataHandler.containsKey(key)) {
        	return (Part)stackDataHandler.get(key);
        }

        multipart = null;

        dimemultipart = null;

        mergeinAttachments();

        if (!(datahandler instanceof javax.activation.DataHandler)) {
            throw new org.apache.axis.AxisFault(
                    Messages.getMessage(
                            "unsupportedAttach", datahandler.getClass().getName(),
                            javax.activation.DataHandler.class.getName()));
        }

        Part ret =
                new AttachmentPart((javax.activation.DataHandler) datahandler);

        addAttachmentPart(ret);

        // Store the current DataHandler with its key
    	stackDataHandler.put(key, ret);

        return ret;
    
protected DimeMultiPartcreateDimeMessage()
Creates the DIME message

return
a DIME part
throws
org.apache.axis.AxisFault if the part could not be built

        int sendtype= this.sendtype == SEND_TYPE_NOTSET ? SEND_TYPE_DEFAULT :   this.sendtype;
        if (sendtype == SEND_TYPE_DIME){
           if(dimemultipart== null){

              dimemultipart= new DimeMultiPart();
              dimemultipart.addBodyPart(new DimeBodyPart(
                soapPart.getAsBytes(), DimeTypeNameFormat.URI,
                "http://schemas.xmlsoap.org/soap/envelope/",
                  "uuid:714C6C40-4531-442E-A498-3AC614200295"));

              for( java.util.Iterator i= orderedAttachments.iterator();
                i.hasNext(); ){
                AttachmentPart part= (AttachmentPart)i.next();
                    DataHandler dh= AttachmentUtils.
                      getActivationDataHandler(part);
                    dimemultipart.addBodyPart(new
                      DimeBodyPart(dh,part.getContentId()));
              }
            }
        }
        return dimemultipart;
      
public voiddispose()
dispose of the attachments and their files; do not use the object after making this call.

        java.util.Iterator iterator = GetAttachmentsIterator();
        while (iterator.hasNext()) {
            Part part = (Part) iterator.next();
            if (part instanceof AttachmentPart) {
                AttachmentPart apart=(AttachmentPart)part;
                apart.dispose();
            }
        }

    
public org.apache.axis.PartgetAttachmentByReference(java.lang.String reference)
This method should look at a refernce and determine if it is a CID: or url to look for attachment.
Note: if Content-Id or Content-Location headers have changed by outside code, lookup will not return proper values. In order to change these values attachment should be removed, then added again.

param
reference The reference in the xml that referers to an attachment.
return
The part associated with the attachment.
throws
org.apache.axis.AxisFault

        if (_askedForStreams) {
            throw new IllegalStateException(Messages.getMessage("concurrentModificationOfStream"));
        }

        if (null == reference) {
            return null;
        }

        reference = reference.trim();

        if (0 == reference.length()) {
            return null;
        }

        mergeinAttachments();

        //This search will pickit up if its fully qualified location or if it's a content-id
        // that is not prefixed by the cid.

        Part ret = (Part) attachments.get(reference);
        if( null != ret) return ret;


        if (!reference.startsWith(Attachments.CIDprefix) && (null != contentLocation)) {
            //Not a content-id check to see if its a relative location id.

                String fqreference = contentLocation;

                if (!fqreference.endsWith("/")) {
                    fqreference += "/";
                }

                if (reference.startsWith("/")) {
                    fqreference += reference.substring(1);
                } else {
                    fqreference += reference;
                }

                // lets see if we can get it as Content-Location
                ret = (AttachmentPart) attachments.get(fqreference);
        }

        if( null == ret && reference.startsWith(Attachments.CIDprefix)){
             //This is a content-id lets see if we have it.
                ret = (Part) attachments.get( reference.substring(4));
        }

        return ret;
    
public intgetAttachmentCount()
This is the number of attachments.

return
the number of attachments

        if (_askedForStreams) {
            throw new IllegalStateException(Messages.getMessage("concurrentModificationOfStream"));
        }

        try {
            mergeinAttachments();

            // force a serialization of the message so that
            // any attachments will be added
            soapPart.saveChanges();
            
            return orderedAttachments.size();
        } catch (AxisFault e) {
            log.warn(Messages.getMessage("exception00"),e);
        }

        return 0;
    
public java.util.IteratorgetAttachments(javax.xml.soap.MimeHeaders headers)
Retrieves all the AttachmentPart objects that have header entries that match the specified headers. Note that a returned attachment could have headers in addition to those specified.

param
headers a MimeHeaders object containing the MIME headers for which to search
return
an iterator over all attachments that have a header that matches one of the given headers

        if (_askedForStreams) {
            throw new IllegalStateException(Messages.getMessage("concurrentModificationOfStream"));
        }
        java.util.Vector vecParts = new java.util.Vector();
        java.util.Iterator iterator = GetAttachmentsIterator();
        while(iterator.hasNext()){
            Part part = (Part) iterator.next();
            if(part instanceof AttachmentPart){
                if(((AttachmentPart)part).matches(headers)){
                    vecParts.add(part);
                }
            }
        }
        return vecParts.iterator();
    
public java.util.CollectiongetAttachments()
This method will return all attachments as a collection.

return
A collection of attachments.
throws
org.apache.axis.AxisFault

        if (_askedForStreams) {
            throw new IllegalStateException(Messages.getMessage("concurrentModificationOfStream"));
        }

        mergeinAttachments();

        return new LinkedList(orderedAttachments);
    
public longgetContentLength()
Get the content length of the stream.

return
the content length of the stream
throws
org.apache.axis.AxisFault


                         
         
        if (_askedForStreams) {
            throw new IllegalStateException(Messages.getMessage("concurrentModificationOfStream"));
        }

        mergeinAttachments();

        int sendtype= this.sendtype == SEND_TYPE_NOTSET ? SEND_TYPE_DEFAULT :   this.sendtype;

        try {
              if(sendtype == SEND_TYPE_MIME || sendtype == SEND_TYPE_MTOM)
                 return org.apache.axis.attachments.MimeUtils.getContentLength(
                                multipart != null ? multipart : (multipart = org.apache.axis.attachments.MimeUtils.createMP(soapPart.getAsString(), orderedAttachments, getSendType())));
              else if (sendtype == SEND_TYPE_DIME)return createDimeMessage().getTransmissionSize();
        } catch (Exception e) {
            throw AxisFault.makeFault(e);
        }
        return 0;
    
public java.lang.StringgetContentType()
Gets the content type for the whole stream.

return
the content type for the whole stream
throws
org.apache.axis.AxisFault


        mergeinAttachments();

        int sendtype= this.sendtype == SEND_TYPE_NOTSET ? SEND_TYPE_DEFAULT :
               this.sendtype;
        if(sendtype == SEND_TYPE_MIME || sendtype == SEND_TYPE_MTOM)
          return org.apache.axis.attachments.MimeUtils.getContentType((multipart
                  != null)
                  ? multipart
                  : (multipart =
                  org.apache.axis.attachments.MimeUtils.createMP(
                          soapPart.getAsString(),
                          orderedAttachments, getSendType())));
        else return org.apache.axis.Message.MIME_APPLICATION_DIME;
    
public IncomingAttachmentStreamsgetIncomingAttachmentStreams()
Once this method is called, attachments can only be accessed via the InputStreams. Any other access to the attachments collection (e.g. via getAttachments()) is prohibited and will cause a IllegalStateException to be thrown.

return
All of the attachment streams.

        if (_askedForAttachments) {
            throw new IllegalStateException(Messages.getMessage("concurrentModificationOfStream"));
        }
        _askedForStreams = true;
        mpartStream = null; // todo: comment
        return _streams;
    
public org.apache.axis.PartgetRootPart()
From the complex stream return the root part. Today this is SOAP.

return
the root Part

        return soapPart;
    
public intgetSendType()

      return sendtype;
    
public static intgetSendType(java.lang.String value)
Determine how an object typically sent as attachments are to be represented. Currently, MIME DIME and NONE are reccognised.

param
value a String representing a sending type, treated in a case-insensetive manner
return
an int send type code

        if (value.equalsIgnoreCase("MTOM")) return SEND_TYPE_MTOM;
        if (value.equalsIgnoreCase("MIME")) return SEND_TYPE_MIME;
        if (value.equalsIgnoreCase("DIME")) return SEND_TYPE_DIME;
        if (value.equalsIgnoreCase("NONE")) return SEND_TYPE_NONE;
        return SEND_TYPE_NOTSET;
    
public static java.lang.StringgetSendTypeString(int value)
For a given sendType value, return a string representation.

param
value a type code integer
return
a String representation of value

        if (value == SEND_TYPE_MTOM) {
            return "MTOM";
        }
        if (value == SEND_TYPE_MIME) {
            return "MIME";
        }
        if (value == SEND_TYPE_DIME) {
            return "DIME";
        }
        if (value == SEND_TYPE_NONE) {
            return "NONE";
        }
        return null;
    
public booleanisAttachment(java.lang.Object value)
Determine if an object is to be treated as an attchment.

param
value the value that is to be determined if its an attachment.
return
True if value should be treated as an attchment.

        return AttachmentUtils.isAttachment(value);
    
private voidmergeinAttachments()
Copies attachment references from the multipartStream to local list. Done only once per object creation.

throws
AxisFault


        if (mpartStream != null) {
            Collection atts = mpartStream.getAttachments();

            if(contentLocation == null)
                contentLocation= mpartStream.getContentLocation();

            mpartStream = null;

            setAttachmentParts(atts);
        }
    
public voidremoveAllAttachments()
Removes all AttachmentPart objects that have been added to this SOAPMessage object.

This method does not touch the SOAP part.

        if (_askedForStreams) {
            throw new IllegalStateException(Messages.getMessage("concurrentModificationOfStream"));
        }
        try {
            multipart = null;
            dimemultipart = null;
            mergeinAttachments();
            attachments.clear();
            orderedAttachments.clear();
            stackDataHandler.clear();
        } catch (AxisFault af){
            log.warn(Messages.getMessage("exception00"),af);
        }
    
public org.apache.axis.PartremoveAttachmentPart(java.lang.String reference)
This method uses getAttacmentByReference() to look for attachment. If attachment has been found, it will be removed from the list, and returned to the user.

param
reference The reference that referers to an attachment.
return
The part associated with the removed attachment, or null.
throws
org.apache.axis.AxisFault

        if (_askedForStreams) {
            throw new IllegalStateException(Messages.getMessage("concurrentModificationOfStream"));
        }

        multipart = null;

        dimemultipart = null;

        mergeinAttachments();

        Part removedPart = getAttachmentByReference(reference);

        if (removedPart != null) {
            attachments.remove(removedPart.getContentId());
            attachments.remove(removedPart.getContentLocation());
            orderedAttachments.remove(removedPart);
        }

        return removedPart;
    
public voidsetAttachmentParts(java.util.Collection parts)
Add the collection of parts.

param
parts
throws
org.apache.axis.AxisFault

        if (_askedForStreams) {
            throw new IllegalStateException(Messages.getMessage("concurrentModificationOfStream"));
        }

        removeAllAttachments();

        if ((parts != null) && !parts.isEmpty()) {
            for (java.util.Iterator i = parts.iterator(); i.hasNext();) {
                Object part = i.next();

                if (null != part) {
                    if(part instanceof Part)
                        addAttachmentPart((Part)part);
                    else
                        createAttachmentPart(part);
                }
            }
        }
    
public voidsetRootPart(org.apache.axis.Part newRoot)


        try {
            this.soapPart = (SOAPPart) newRoot;
            multipart = null;
            dimemultipart = null;
        } catch (ClassCastException e) {
            throw new ClassCastException(Messages.getMessage("onlySOAPParts"));
        }
    
public voidsetSendType(int sendtype)

      if( sendtype < 1)
        throw new IllegalArgumentException("");
      if( sendtype > SEND_TYPE_MAX )
        throw new IllegalArgumentException("");
      this.sendtype= sendtype;
    
public voidwriteContentToStream(java.io.OutputStream os)
Write the content to the stream.

param
os
throws
org.apache.axis.AxisFault

        int sendtype= this.sendtype == SEND_TYPE_NOTSET ?
                          SEND_TYPE_DEFAULT : this.sendtype;
        try{

        mergeinAttachments();
        if(sendtype == SEND_TYPE_MIME || sendtype == SEND_TYPE_MTOM){
        org.apache.axis.attachments.MimeUtils.writeToMultiPartStream(os,
                (multipart != null)
                ? multipart
                : (multipart =
                   org.apache.axis.attachments.MimeUtils.createMP(
                        soapPart.getAsString(), orderedAttachments, getSendType())));

        for (java.util.Iterator i = orderedAttachments.iterator();
             i.hasNext();) {
            AttachmentPart part = (AttachmentPart) i.next();
            DataHandler dh =
                    AttachmentUtils.getActivationDataHandler(part);
            DataSource ds = dh.getDataSource();

            if ((ds != null) && (ds instanceof ManagedMemoryDataSource)) {
                ((ManagedMemoryDataSource) ds).delete();
            }
        }
        }else if (sendtype == SEND_TYPE_DIME)createDimeMessage().write(os);
       }catch(Exception e){ throw org.apache.axis.AxisFault.makeFault(e);}