diff --git a/ccm-cms/src/WEB-INF/resources/cms-service-map.xml b/ccm-cms/src/WEB-INF/resources/cms-service-map.xml index daa156357..63149439a 100755 --- a/ccm-cms/src/WEB-INF/resources/cms-service-map.xml +++ b/ccm-cms/src/WEB-INF/resources/cms-service-map.xml @@ -7,6 +7,10 @@ stream/image/ com.arsdigita.cms.dispatcher.StreamImage + + download/image/ + com.arsdigita.cms.dispatcher.DownloadImage + stream/asset/ com.arsdigita.cms.dispatcher.StreamAsset diff --git a/ccm-cms/src/com/arsdigita/cms/dispatcher/BaseAsset.java b/ccm-cms/src/com/arsdigita/cms/dispatcher/BaseAsset.java index 537249ce9..41b8a7e8c 100755 --- a/ccm-cms/src/com/arsdigita/cms/dispatcher/BaseAsset.java +++ b/ccm-cms/src/com/arsdigita/cms/dispatcher/BaseAsset.java @@ -44,12 +44,9 @@ import javax.servlet.ServletException; class BaseAsset extends ResourceHandlerImpl { private static final Logger s_log = Logger.getLogger(BaseAsset.class); - public final static String ASSET_ID = "asset_id"; public static final String OID_PARAM = "oid"; - private final static String s_defaultName = "File"; - private static final BigDecimalParameter s_assetId = new BigDecimalParameter(ASSET_ID); private static final OIDParameter s_oid = new OIDParameter(OID_PARAM); @@ -58,11 +55,10 @@ class BaseAsset extends ResourceHandlerImpl { * to variable declaration (see above). */ /*static { - s_assetId = new BigDecimalParameter(ASSET_ID); - s_oid = new OIDParameter(OID_PARAM); - //s_assetId.addParameterListener(new NotNullValidationListener()); + s_assetId = new BigDecimalParameter(ASSET_ID); + s_oid = new OIDParameter(OID_PARAM); + //s_assetId.addParameterListener(new NotNullValidationListener()); }*/ - private final boolean m_download; private String m_disposition; @@ -81,21 +77,23 @@ class BaseAsset extends ResourceHandlerImpl { * Content-Disposition in HTTP. */ protected void setFilenameHeader(HttpServletResponse response, - BinaryAsset asset) { + BinaryAsset asset) { String filename = asset.getName(); - if (filename == null) { filename = s_defaultName; } + if (filename == null) { + filename = s_defaultName; + } // quote the file name to deal with any special // characters in the name of the file - StringBuffer disposition = new StringBuffer(m_disposition); + StringBuilder disposition = new StringBuilder(m_disposition); disposition.append('"').append(filename).append('"'); response.setHeader("Content-Disposition", disposition.toString()); } private void setHeaders(HttpServletResponse response, - BinaryAsset asset) { + BinaryAsset asset) { setFilenameHeader(response, asset); Long contentLength = new Long(asset.getSize()); @@ -113,7 +111,7 @@ class BaseAsset extends ResourceHandlerImpl { // PDFs need to be cached for a different amount of time to avoid issues with IE6 - see ticket #20266 if (mimeType != null && mimeType.getMimeType().equals("application/pdf")) { - DispatcherHelper.cacheForWorld(response,30); + DispatcherHelper.cacheForWorld(response, 30); } else { // Default caching for all other types DispatcherHelper.cacheForWorld(response); @@ -121,7 +119,7 @@ class BaseAsset extends ResourceHandlerImpl { } private void send(HttpServletResponse response, - BinaryAsset asset) throws IOException { + BinaryAsset asset) throws IOException { // Stream the blob. OutputStream out = response.getOutputStream(); try { @@ -131,27 +129,28 @@ class BaseAsset extends ResourceHandlerImpl { } } + @Override public final void dispatch(HttpServletRequest request, - HttpServletResponse response, - RequestContext actx) - throws IOException, ServletException { + HttpServletResponse response, + RequestContext actx) + throws IOException, ServletException { // Fetch and validate the asset ID OID oid = null; BigDecimal assetId = null; try { - oid = (OID)s_oid.transformValue(request); + oid = (OID) s_oid.transformValue(request); assetId = (BigDecimal) s_assetId.transformValue(request); } catch (Exception e) { response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.toString()); return; } - if ( assetId == null && oid == null ) { + if (assetId == null && oid == null) { response.sendError(HttpServletResponse.SC_BAD_REQUEST, "either " + ASSET_ID + " or " + OID_PARAM + " is required."); return; - } else if ( assetId != null && oid != null ) { + } else if (assetId != null && oid != null) { response.sendError(HttpServletResponse.SC_BAD_REQUEST, "either " + ASSET_ID + " or " + OID_PARAM + " is required."); return; @@ -162,8 +161,7 @@ class BaseAsset extends ResourceHandlerImpl { BinaryAsset asset = null; try { - Asset a = (Asset) - DomainObjectFactory.newInstance(oid); + Asset a = (Asset) DomainObjectFactory.newInstance(oid); if (a instanceof BinaryAsset) { asset = (BinaryAsset) a; @@ -182,7 +180,7 @@ class BaseAsset extends ResourceHandlerImpl { if (asset == null) { response.sendError(HttpServletResponse.SC_NOT_FOUND, - "No asset with ID " + assetId); + "No asset with ID " + assetId); return; } diff --git a/ccm-cms/src/com/arsdigita/cms/dispatcher/BaseImage.java b/ccm-cms/src/com/arsdigita/cms/dispatcher/BaseImage.java new file mode 100755 index 000000000..9b13bf534 --- /dev/null +++ b/ccm-cms/src/com/arsdigita/cms/dispatcher/BaseImage.java @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.cms.dispatcher; + +import com.arsdigita.bebop.parameters.BigDecimalParameter; +import com.arsdigita.cms.Asset; +import com.arsdigita.cms.ImageAsset; +import com.arsdigita.dispatcher.DispatcherHelper; +import com.arsdigita.dispatcher.RequestContext; +import com.arsdigita.domain.DataObjectNotFoundException; +import com.arsdigita.domain.DomainObjectFactory; +import com.arsdigita.mimetypes.MimeType; +import com.arsdigita.persistence.OID; +import com.arsdigita.toolbox.ui.OIDParameter; + +import java.io.IOException; +import java.io.OutputStream; +import java.math.BigDecimal; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; + +/** + * A resource handler which streams out a blob from the database. + * + * @author Stanislav Freidin (sfreidin@arsdigita.com) + * @author Michael Pih (pihman@arsdigita.com) + * @version $Revision: #20 $ $DateTime: 2004/08/17 23:15:09 $ + * @version $Id: BaseImage.java 1571 2007-04-20 15:57:54Z apevec $ + */ +public class BaseImage extends ResourceHandlerImpl { + + public static final String IMAGE_ID = "image_id"; + public static final String OID_PARAM = "oid"; + private final static String s_defaultName = "Image"; + // the transactionID and objectID allow us to rollback to a specific + // version of an image. If we only have a transactionID and + // the item is its own master then we can also roll it back +// public static final String TRANSACTION_ID = "transID"; +// public static final String OBJECT_ID = "objectID"; + private BigDecimalParameter m_imageId; + private OIDParameter m_oid; +// private BigDecimalParameter m_transactionID; +// private BigDecimalParameter m_objectID; + private final boolean m_download; + private String m_disposition; + private static final Logger s_log = + Logger.getLogger(BaseImage.class); + + /** + * Construct the resource handler + */ + public BaseImage(boolean download) { + m_imageId = new BigDecimalParameter(IMAGE_ID); + m_oid = new OIDParameter(OID_PARAM); +// m_transactionID = new BigDecimalParameter(TRANSACTION_ID); +// m_objectID = new BigDecimalParameter(OBJECT_ID); + + m_download = download; + if (m_download) { + m_disposition = "attachment; filename="; + } else { + m_disposition = "inline; filename="; + } + } + + /** + * Sets RFC2183 governed Contnet-Disposition header to supply filename to + * client. See section 19.5.1 of RFC2616 for interpretation of + * Content-Disposition in HTTP. + */ + protected void setFilenameHeader(HttpServletResponse response, + ImageAsset image) { + String filename = image.getName(); + if (filename == null) { + filename = s_defaultName; + } + + // quote the file name to deal with any special + // characters in the name of the file + StringBuilder disposition = new StringBuilder(m_disposition); + disposition.append('"').append(filename).append('"'); + + response.setHeader("Content-Disposition", disposition.toString()); + } + + private void setHeaders(HttpServletResponse response, + ImageAsset image) { + setFilenameHeader(response, image); + + Long contentLength = new Long(image.getSize()); + response.setContentLength(contentLength.intValue()); + + MimeType mimeType = image.getMimeType(); + + if (m_download || mimeType == null) { + // Section 19.5.1 of RFC2616 says this implies download + // instead of view + response.setContentType("application/octet-stream"); + } else { + response.setContentType(mimeType.getMimeType()); + } + + // Default caching for all other types + if ("live".equals(image.getVersion())) { + DispatcherHelper.cacheForWorld(response); + } else { + DispatcherHelper.cacheDisable(response); + } + } + + private void send(HttpServletResponse response, + ImageAsset image) throws IOException { + // Stream the blob. + OutputStream out = response.getOutputStream(); + try { + image.writeBytes(out); + } finally { + out.close(); + } + } + + /** + * Streams an image from the database. + * + * @param request The servlet request object + * @param response the servlet response object + * @param actx The request context + */ + @Override + public void dispatch(HttpServletRequest request, + HttpServletResponse response, + RequestContext actx) + throws IOException, ServletException { + + // Fetch and validate the image ID + OID oid = null; + BigDecimal imageId = null; +// BigDecimal transactionID = null; +// BigDecimal objectID = null; + try { + oid = (OID) m_oid.transformValue(request); + imageId = (BigDecimal) m_imageId.transformValue(request); +// transactionID = +// (BigDecimal) m_transactionID.transformValue(request); +// objectID = +// (BigDecimal) m_objectID.transformValue(request); + } catch (Exception e) { + response.sendError(HttpServletResponse.SC_BAD_REQUEST, + e.toString()); + return; + } + if (imageId == null && oid == null) { + response.sendError(HttpServletResponse.SC_BAD_REQUEST, + "either " + IMAGE_ID + " or " + OID_PARAM + " is required."); + return; + } else if (imageId != null && oid != null) { + response.sendError(HttpServletResponse.SC_BAD_REQUEST, + "either " + IMAGE_ID + " or " + OID_PARAM + " is required."); + return; + } + if (oid == null) { + oid = new OID(ImageAsset.BASE_DATA_OBJECT_TYPE, imageId); + } + +// Transaction transaction = null; +// GenericArticle article = null; + // XXX: add back rollback + /*if (transactionID != null) { + try { + transaction = + new Transaction(transactionID); + // we have a transaction so let's see if we have an article + if (objectID != null) { + article = new GenericArticle(objectID); + article.rollBackTo(transaction); + } + } catch (DataObjectNotFoundException e) { + s_log.warn("Unable to locate transaction " + transactionID); + // this is non-critical so we just continue + } + }*/ + + ImageAsset image = null; +// if (article == null) { + try { + Asset a = (Asset) DomainObjectFactory.newInstance(oid); + + if (a instanceof ImageAsset) { + image = (ImageAsset) a; + } else { + if (s_log.isInfoEnabled()) { + s_log.info("Asset " + oid + " is not an ImageAsset"); + } + } + } catch (DataObjectNotFoundException nfe) { + response.sendError(HttpServletResponse.SC_NOT_FOUND, + "no ImageAsset with oid " + oid); + return; + } +// } + +// if (image.getMimeType() == null) { +// response.sendError(HttpServletResponse.SC_NOT_FOUND, +// "MIME type not found for ImageAsset " + imageId); +// } + + // Not until permissions are properly assigned to assets + //checkUserAccess(request, response, actx, image); + +// response.setContentType(image.getMimeType().getMimeType()); + + setHeaders(response, image); + send(response, image); + } +} diff --git a/ccm-cms/src/com/arsdigita/cms/dispatcher/DownloadAsset.java b/ccm-cms/src/com/arsdigita/cms/dispatcher/DownloadAsset.java index 04365ff70..4568ca7be 100755 --- a/ccm-cms/src/com/arsdigita/cms/dispatcher/DownloadAsset.java +++ b/ccm-cms/src/com/arsdigita/cms/dispatcher/DownloadAsset.java @@ -20,7 +20,6 @@ package com.arsdigita.cms.dispatcher; import org.apache.log4j.Logger; - /** * A servlet used for downloading DPAssets. * @@ -30,7 +29,6 @@ import org.apache.log4j.Logger; public class DownloadAsset extends BaseAsset { private static Logger s_log = Logger.getLogger(DownloadAsset.class); - public final static String ASSET_ID = BaseAsset.ASSET_ID; public DownloadAsset() { diff --git a/ccm-cms/src/com/arsdigita/cms/dispatcher/DownloadImage.java b/ccm-cms/src/com/arsdigita/cms/dispatcher/DownloadImage.java new file mode 100644 index 000000000..4510c1bd6 --- /dev/null +++ b/ccm-cms/src/com/arsdigita/cms/dispatcher/DownloadImage.java @@ -0,0 +1,18 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.arsdigita.cms.dispatcher; + +/** + * + * @author Sören Bernstein (quasimodo) + */ +public class DownloadImage extends BaseImage { + + public DownloadImage() { + super(true); + } + +} diff --git a/ccm-cms/src/com/arsdigita/cms/dispatcher/StreamAsset.java b/ccm-cms/src/com/arsdigita/cms/dispatcher/StreamAsset.java index 7d60d786d..53a63cad8 100755 --- a/ccm-cms/src/com/arsdigita/cms/dispatcher/StreamAsset.java +++ b/ccm-cms/src/com/arsdigita/cms/dispatcher/StreamAsset.java @@ -24,7 +24,6 @@ import org.apache.log4j.Logger; import com.arsdigita.cms.BinaryAsset; - /** * A resource handler which streams out a blob from the database. * @@ -35,7 +34,6 @@ import com.arsdigita.cms.BinaryAsset; public class StreamAsset extends BaseAsset { private static final Logger s_log = Logger.getLogger(StreamAsset.class); - public final static String ASSET_ID = BaseAsset.ASSET_ID; public StreamAsset() { diff --git a/ccm-cms/src/com/arsdigita/cms/dispatcher/StreamImage.java b/ccm-cms/src/com/arsdigita/cms/dispatcher/StreamImage.java index 9c94f0a83..3c37ac595 100755 --- a/ccm-cms/src/com/arsdigita/cms/dispatcher/StreamImage.java +++ b/ccm-cms/src/com/arsdigita/cms/dispatcher/StreamImage.java @@ -1,173 +1,16 @@ /* - * Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * To change this template, choose Tools | Templates + * and open the template in the editor. */ package com.arsdigita.cms.dispatcher; -import com.arsdigita.bebop.parameters.BigDecimalParameter; -import com.arsdigita.cms.contenttypes.GenericArticle; -import com.arsdigita.cms.ImageAsset; -import com.arsdigita.dispatcher.DispatcherHelper; -import com.arsdigita.dispatcher.RequestContext; -import com.arsdigita.domain.DataObjectNotFoundException; -import com.arsdigita.domain.DomainObjectFactory; -import com.arsdigita.persistence.OID; -import com.arsdigita.toolbox.ui.OIDParameter; -import com.arsdigita.versioning.Transaction; - -import java.io.IOException; -import java.io.OutputStream; -import java.math.BigDecimal; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.log4j.Logger; - - /** - * A resource handler which streams out a blob from the database. * - * @author Stanislav Freidin (sfreidin@arsdigita.com) - * @author Michael Pih (pihman@arsdigita.com) - * @version $Revision: #20 $ $DateTime: 2004/08/17 23:15:09 $ - * @version $Id: StreamImage.java 1571 2007-04-20 15:57:54Z apevec $ + * @author Sören Bernstein (quasimodo) */ -public class StreamImage extends ResourceHandlerImpl { +public class StreamImage extends BaseImage { - public static final String IMAGE_ID = "image_id"; - public static final String OID_PARAM = "oid"; - - // the transactionID and objectID allow us to rollback to a specific - // version of an image. If we only have a transactionID and - // the item is its own master then we can also roll it back - public static final String TRANSACTION_ID = "transID"; - public static final String OBJECT_ID = "objectID"; - - private BigDecimalParameter m_imageId; - private OIDParameter m_oid; - private BigDecimalParameter m_transactionID; - private BigDecimalParameter m_objectID; - - private static final Logger s_log = - Logger.getLogger(StreamImage.class); - - /** - * Construct the resource handler - */ public StreamImage() { - m_imageId = new BigDecimalParameter(IMAGE_ID); - m_oid = new OIDParameter(OID_PARAM); - m_transactionID = new BigDecimalParameter(TRANSACTION_ID); - m_objectID = new BigDecimalParameter(OBJECT_ID); - } - - /** - * Streams an image from the database. - * - * @param request The servlet request object - * @param response the servlet response object - * @param actx The request context - */ - public void dispatch(HttpServletRequest request, - HttpServletResponse response, - RequestContext actx) - throws IOException, ServletException { - - // Fetch and validate the image ID - OID oid = null; - BigDecimal imageId = null; - BigDecimal transactionID = null; - BigDecimal objectID = null; - try { - oid = (OID)m_oid.transformValue(request); - imageId = (BigDecimal) m_imageId.transformValue(request); - transactionID = - (BigDecimal) m_transactionID.transformValue(request); - objectID = - (BigDecimal) m_objectID.transformValue(request); - } catch (Exception e) { - response.sendError(HttpServletResponse.SC_BAD_REQUEST, - e.toString()); - return; - } - if ( imageId == null && oid == null ) { - response.sendError(HttpServletResponse.SC_BAD_REQUEST, - "either " + IMAGE_ID + " or " + OID_PARAM + " is required."); - return; - } else if ( imageId != null && oid != null ) { - response.sendError(HttpServletResponse.SC_BAD_REQUEST, - "either " + IMAGE_ID + " or " + OID_PARAM + " is required."); - return; - } - if (oid == null) { - oid = new OID(ImageAsset.BASE_DATA_OBJECT_TYPE, imageId); - } - Transaction transaction = null; - GenericArticle article = null; - // XXX: add back rollback - /*if (transactionID != null) { - try { - transaction = - new Transaction(transactionID); - // we have a transaction so let's see if we have an article - if (objectID != null) { - article = new GenericArticle(objectID); - article.rollBackTo(transaction); - } - } catch (DataObjectNotFoundException e) { - s_log.warn("Unable to locate transaction " + transactionID); - // this is non-critical so we just continue - } - }*/ - - ImageAsset image = null; - String mimeType = null; - - if (article == null) { - try { - image = (ImageAsset) DomainObjectFactory.newInstance(oid); - - } catch (DataObjectNotFoundException nfe) { - response.sendError(HttpServletResponse.SC_NOT_FOUND, - "no ImageAsset with oid " + oid); - return; - } - } - - - if ( image.getMimeType() == null ) { - response.sendError(HttpServletResponse.SC_NOT_FOUND, - "MIME type not found for ImageAsset " + imageId); - } - - if ("live".equals(image.getVersion())) { - DispatcherHelper.cacheForWorld(response); - } else { - DispatcherHelper.cacheDisable( response ); - } - - // Not until permissions are properly assigned to assets - //checkUserAccess(request, response, actx, image); - - response.setContentType(image.getMimeType().getMimeType()); - // Stream the blob. - OutputStream out = response.getOutputStream(); - image.writeBytes(out); - out.close(); + super(false); } }