details: https://code.openbravo.com/erp/devel/pi/rev/073bf9bf00fe changeset: 13629:073bf9bf00fe user: Antonio Moreno <antonio.moreno <at> openbravo.com> date: Wed Aug 31 15:28:11 2011 +0200 summary: Fixed issue 15728. The following changes have been made: - The logic which gets the image and sends it to the client has been moved to a series of methods in the new ImageUtils class - ShowImage and ShowImageLogo now use this class - An ETag is now calculated when an image is sent. This ETag is based on the audit information of the image object. - If the ETag is sent in the request, and is equal to the current ETag of the image, then the image is now sent, because it hasn't changed.
diffstat: src/org/openbravo/erpCommon/utility/ImageUtils.java | 176 +++++++++++++++++ src/org/openbravo/erpCommon/utility/ShowImage.java | 42 +--- src/org/openbravo/erpCommon/utility/ShowImageLogo.java | 68 +------ 3 files changed, 179 insertions(+), 107 deletions(-) diffs (truncated from 336 to 300 lines): diff -r 5fdf47cc9185 -r 073bf9bf00fe src/org/openbravo/erpCommon/utility/ImageUtils.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/org/openbravo/erpCommon/utility/ImageUtils.java Wed Aug 31 15:28:11 2011 +0200 @@ -0,0 +1,176 @@ +/* + ************************************************************************* + * The contents of this file are subject to the Openbravo Public License + * Version 1.1 (the "License"), being the Mozilla Public License + * Version 1.1 with a permitted attribution clause; you may not use this + * file except in compliance with the License. You may obtain a copy of + * the License at http://www.openbravo.com/legal/license.html + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + * License for the specific language governing rights and limitations + * under the License. + * The Original Code is Openbravo ERP. + * The Initial Developer of the Original Code is Openbravo SLU + * All portions are Copyright (C) 2011 Openbravo SLU + * All Rights Reserved. + * Contributor(s): ______________________________________. + ************************************************************************ + */ + +package org.openbravo.erpCommon.utility; + +import java.io.IOException; +import java.io.OutputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.log4j.Logger; +import org.openbravo.base.secureApp.VariablesSecureApp; +import org.openbravo.dal.service.OBDal; +import org.openbravo.model.ad.utility.Image; + +/** + * Contains several methods used in the Image related servlets + * + */ +public class ImageUtils { + + private static final String ETAG_ALGORITHM = "MD5"; + protected static final String RESPONSE_HEADER_ETAG = "ETag"; + protected static final String RESPONSE_HEADER_LASTMODIFIED = "Last-Modified"; + protected static final String RESPONSE_HEADER_CACHE_CONTROL = "Cache-Control"; + protected static final String RESPONSE_NO_CACHE = "no-cache"; + protected static final String RESPONSE_HEADER_CONTENTTYPE = "Content-Type"; + private static final String REQUEST_HEADER_IFNONEMATCH = "If-None-Match"; + private static final String REQUEST_HEADER_IFMODIFIEDSINCE = "If-Modified-Since"; + private static Logger log4j = Logger.getLogger(ImageUtils.class); + + /** + * Checks if the content is to be send in response. + * + * This uses HTTP ETag technology and sets required headers. + */ + private static boolean isImageResponseRequired(final HttpServletRequest req, + final HttpServletResponse resp, final String resourceName) { + final String match = req.getHeader(REQUEST_HEADER_IFNONEMATCH); + final String etag = getHashDigestTag(resourceName); + + resp.setHeader(RESPONSE_HEADER_ETAG, etag); + + return !etag.equals(match); + } + + /** + * Calculates the ETag of the resourceName + */ + private static String getHashDigestTag(final String resourceName) { + try { + MessageDigest dig = MessageDigest.getInstance(ETAG_ALGORITHM); + + final byte[] digest = dig.digest(resourceName.getBytes()); + + return DigestUtils.md5Hex(digest); + + } catch (NoSuchAlgorithmException nsae) { + log4j.error("Cannot find ETag algorithm " + ETAG_ALGORITHM, nsae); + } + + return resourceName; + } + + /** + * Outputs the image/content to the response + */ + public static void outputImageResource(final HttpServletRequest req, + final HttpServletResponse resp, final String imageType) throws IOException, ServletException { + + // enforce cache validation/checks every time + resp.addHeader(RESPONSE_HEADER_CACHE_CONTROL, RESPONSE_NO_CACHE); + VariablesSecureApp vars = new VariablesSecureApp(req); + + Image img = null; + if (imageType == "logo") { + String logo = vars.getStringParameter("logo"); + String org = vars.getStringParameter("orgId"); + img = Utility.getImageLogoObject(logo, org); + if (img == null) { + byte[] imageFileContent = Utility.getImageLogo(logo, org); + String mimeType = MimeTypeUtil.getInstance().getMimeTypeName(imageFileContent); + resp.setContentType(mimeType); + OutputStream out = resp.getOutputStream(); + resp.setContentLength(imageFileContent.length); + out.write(imageFileContent); + out.close(); + return; + } + } else { + img = Utility.getImageObject(vars.getStringParameter("id")); + } + String imageID = "IMGTAG" + img.getUpdated().toString(); + + if (ImageUtils.isImageResponseRequired(req, resp, imageID)) { + + // read the image data + byte[] imgByte = img.getBindaryData(); + + // write the mimetype + String mimeType = img.getMimetype();// write the mimetype + if (mimeType == null) { + mimeType = MimeTypeUtil.getInstance().getMimeTypeName(img.getBindaryData()); + if (img != null) { + // If there is an OBContext, we attempt to save the MIME type of the image + updateMimeType(img.getId(), mimeType); + } + } + + if (!mimeType.equals("")) { + resp.setContentType(mimeType); + } + + // write the image + OutputStream out = resp.getOutputStream(); + resp.setContentLength(imgByte.length); + out.write(imgByte); + out.close(); + + } else { + resp.sendError(HttpServletResponse.SC_NOT_MODIFIED); + resp.setDateHeader(RESPONSE_HEADER_LASTMODIFIED, + req.getDateHeader(REQUEST_HEADER_IFMODIFIEDSINCE)); + + } + + } + + /** + * This method updates the MIME type of an image, using SQL. DAL cannot be used because sometimes + * there is no OBContext (specifically, it happens for images in the Login page) + */ + private static void updateMimeType(String id, String mimeType) { + PreparedStatement ps = null; + try { + ps = OBDal.getInstance().getConnection(true) + .prepareStatement("UPDATE ad_image SET mimetype=? WHERE ad_image_id=?"); + ps.setString(1, mimeType); + ps.setString(2, id); + ps.executeUpdate(); + } catch (SQLException e) { + log4j.error("Couldn't update mime information of image", e); + } finally { + try { + if (ps != null) { + ps.close(); + } + } catch (SQLException e) { + // ignore + } + } + } +} diff -r 5fdf47cc9185 -r 073bf9bf00fe src/org/openbravo/erpCommon/utility/ShowImage.java --- a/src/org/openbravo/erpCommon/utility/ShowImage.java Wed Aug 31 12:03:48 2011 +0200 +++ b/src/org/openbravo/erpCommon/utility/ShowImage.java Wed Aug 31 15:28:11 2011 +0200 @@ -20,7 +20,6 @@ package org.openbravo.erpCommon.utility; import java.io.IOException; -import java.io.OutputStream; import javax.servlet.ServletConfig; import javax.servlet.ServletException; @@ -28,10 +27,6 @@ import javax.servlet.http.HttpServletResponse; import org.openbravo.base.secureApp.HttpSecureAppServlet; -import org.openbravo.base.secureApp.VariablesSecureApp; -import org.openbravo.dal.core.OBContext; -import org.openbravo.dal.service.OBDal; -import org.openbravo.model.ad.utility.Image; /** * @@ -54,40 +49,7 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { - VariablesSecureApp vars = new VariablesSecureApp(request); - String id = vars.getStringParameter("id"); + ImageUtils.outputImageResource(request, response, "standard"); + } - try { - OBContext.setAdminMode(true); - // read the image data - byte[] img = Utility.getImage(id); - - // write the mimetype - Image image = OBDal.getInstance().get(Image.class, id); - final String mimeType; - if (image.getMimetype() != null) { - mimeType = image.getMimetype(); - } else { - mimeType = MimeTypeUtil.getInstance().getMimeTypeName(img); - // If there is an OBContext, we attempt to save the MIME type of the image - if (OBContext.getOBContext() != null) { - image.setMimetype(mimeType); - OBDal.getInstance().save(image); - OBDal.getInstance().flush(); - } - } - - if (!mimeType.equals("")) { - response.setContentType(mimeType); - } - - // write the image - OutputStream out = response.getOutputStream(); - response.setContentLength(img.length); - out.write(img); - out.close(); - } finally { - OBContext.restorePreviousMode(); - } - } } diff -r 5fdf47cc9185 -r 073bf9bf00fe src/org/openbravo/erpCommon/utility/ShowImageLogo.java --- a/src/org/openbravo/erpCommon/utility/ShowImageLogo.java Wed Aug 31 12:03:48 2011 +0200 +++ b/src/org/openbravo/erpCommon/utility/ShowImageLogo.java Wed Aug 31 15:28:11 2011 +0200 @@ -20,19 +20,12 @@ package org.openbravo.erpCommon.utility; import java.io.IOException; -import java.io.OutputStream; -import java.sql.PreparedStatement; -import java.sql.SQLException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.openbravo.base.HttpBaseServlet; -import org.openbravo.base.secureApp.VariablesSecureApp; -import org.openbravo.dal.core.OBContext; -import org.openbravo.dal.service.OBDal; -import org.openbravo.model.ad.utility.Image; /** * @@ -50,66 +43,7 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { - VariablesSecureApp vars = new VariablesSecureApp(request); - String logo = vars.getStringParameter("logo"); - String org = vars.getStringParameter("orgId"); + ImageUtils.outputImageResource(request, response, "logo"); - // read the image data - byte[] img; - String mimeType = null; - try { - OBContext.setAdminMode(true); - Image image = Utility.getImageLogoObject(logo, org); - if (image != null) { - img = image.getBindaryData(); - mimeType = image.getMimetype(); - } else { - img = Utility.getImageLogo(logo, org); - } - // write the mimetype - if (mimeType == null) { - mimeType = MimeTypeUtil.getInstance().getMimeTypeName(img); - if (image != null) { - // If there is an OBContext, we attempt to save the MIME type of the image - updateMimeType(image.getId(), mimeType); - } - } - if (!mimeType.equals("")) { - response.setContentType(mimeType); - } ------------------------------------------------------------------------------ Special Offer -- Download ArcSight Logger for FREE! Finally, a world-class log management solution at an even better price-free! And you'll get a free "Love Thy Logs" t-shirt when you download Logger. Secure your free ArcSight Logger TODAY! http://p.sf.net/sfu/arcsisghtdev2dev _______________________________________________ Openbravo-commits mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/openbravo-commits
