001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.activemq.command;
018
019import java.io.IOException;
020import java.io.InputStream;
021import java.net.MalformedURLException;
022import java.net.URL;
023
024import javax.jms.JMSException;
025
026import org.apache.activemq.BlobMessage;
027import org.apache.activemq.blob.BlobDownloader;
028import org.apache.activemq.blob.BlobUploader;
029import org.apache.activemq.util.JMSExceptionSupport;
030
031/**
032 * An implementation of {@link BlobMessage} for out of band BLOB transfer
033 * 
034 * 
035 * @openwire:marshaller code="29"
036 */
037public class ActiveMQBlobMessage extends ActiveMQMessage implements BlobMessage {
038    public static final byte DATA_STRUCTURE_TYPE = CommandTypes.ACTIVEMQ_BLOB_MESSAGE;
039
040    public static final String BINARY_MIME_TYPE = "application/octet-stream";
041
042    private String remoteBlobUrl;
043    private String mimeType;
044    private String name;
045    private boolean deletedByBroker;
046
047    private transient BlobUploader blobUploader;
048    private transient BlobDownloader blobDownloader;
049    private transient URL url;
050
051    public Message copy() {
052        ActiveMQBlobMessage copy = new ActiveMQBlobMessage();
053        copy(copy);
054        return copy;
055    }
056
057    private void copy(ActiveMQBlobMessage copy) {
058        super.copy(copy);
059        copy.setRemoteBlobUrl(getRemoteBlobUrl());
060        copy.setMimeType(getMimeType());
061        copy.setDeletedByBroker(isDeletedByBroker());
062        copy.setBlobUploader(getBlobUploader());
063        copy.setName(getName());
064    }
065
066    public byte getDataStructureType() {
067        return DATA_STRUCTURE_TYPE;
068    }
069
070    /**
071     * @openwire:property version=3 cache=false
072     */
073    public String getRemoteBlobUrl() {
074        return remoteBlobUrl;
075    }
076
077    public void setRemoteBlobUrl(String remoteBlobUrl) {
078        this.remoteBlobUrl = remoteBlobUrl;
079        url = null;
080    }
081
082    /**
083     * The MIME type of the BLOB which can be used to apply different content
084     * types to messages.
085     * 
086     * @openwire:property version=3 cache=true
087     */
088    public String getMimeType() {
089        if (mimeType == null) {
090            return BINARY_MIME_TYPE;
091        }
092        return mimeType;
093    }
094
095    public void setMimeType(String mimeType) {
096        this.mimeType = mimeType;
097    }
098
099    public String getName() {
100        return name;
101    }
102
103    /**
104     * The name of the attachment which can be useful information if
105     * transmitting files over ActiveMQ
106     * 
107     * @openwire:property version=3 cache=false
108     */
109    public void setName(String name) {
110        this.name = name;
111    }
112
113    /**
114     * @openwire:property version=3 cache=false
115     */
116    public boolean isDeletedByBroker() {
117        return deletedByBroker;
118    }
119
120    public void setDeletedByBroker(boolean deletedByBroker) {
121        this.deletedByBroker = deletedByBroker;
122    }
123
124    public String getJMSXMimeType() {
125        return getMimeType();
126    }
127
128    public InputStream getInputStream() throws IOException, JMSException {
129        if(blobDownloader == null) {
130            return null;
131        }
132        return blobDownloader.getInputStream(this);
133    }
134
135    public URL getURL() throws JMSException {
136        if (url == null && remoteBlobUrl != null) {
137            try {
138                url = new URL(remoteBlobUrl);
139            } catch (MalformedURLException e) {
140                throw JMSExceptionSupport.create(e);
141            }
142        }
143        return url;
144    }
145
146    public void setURL(URL url) {
147        this.url = url;
148        remoteBlobUrl = url != null ? url.toExternalForm() : null;
149    }
150
151    public BlobUploader getBlobUploader() {
152        return blobUploader;
153    }
154
155    public void setBlobUploader(BlobUploader blobUploader) {
156        this.blobUploader = blobUploader;
157    }
158
159    public BlobDownloader getBlobDownloader() {
160        return blobDownloader;
161    }
162
163    public void setBlobDownloader(BlobDownloader blobDownloader) {
164        this.blobDownloader = blobDownloader;
165    }
166
167    public void onSend() throws JMSException {
168        super.onSend();
169
170        // lets ensure we upload the BLOB first out of band before we send the
171        // message
172        if (blobUploader != null) {
173            try {
174                URL value = blobUploader.upload(this);
175                setURL(value);
176            } catch (IOException e) {
177                throw JMSExceptionSupport.create(e);
178            }
179        }
180    }
181    
182    public void deleteFile() throws IOException, JMSException {
183        blobDownloader.deleteFile(this);
184    }
185}