Package com.dotmarketing.servlets.image

Source Code of com.dotmarketing.servlets.image.ResizeImageServlet

package com.dotmarketing.servlets.image;

import static com.dotmarketing.business.PermissionAPI.PERMISSION_READ;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.StringTokenizer;
import java.util.TimeZone;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.dotcms.repackage.org.apache.commons.lang.time.FastDateFormat;

import com.dotmarketing.beans.Host;
import com.dotmarketing.beans.Identifier;
import com.dotmarketing.business.APILocator;
import com.dotmarketing.business.PermissionAPI;
import com.dotmarketing.business.web.WebAPILocator;
import com.dotmarketing.cache.LiveCache;
import com.dotmarketing.cache.WorkingCache;
import com.dotmarketing.exception.DotDataException;
import com.dotmarketing.portlets.contentlet.business.DotContentletStateException;
import com.dotmarketing.portlets.contentlet.model.Contentlet;
import com.dotmarketing.portlets.fileassets.business.FileAsset;
import com.dotmarketing.portlets.fileassets.business.FileAssetAPI;
import com.dotmarketing.portlets.files.business.FileAPI;
import com.dotmarketing.portlets.files.model.File;
import com.dotmarketing.util.Config;
import com.dotmarketing.util.Constants;
import com.dotmarketing.util.InodeUtils;
import com.dotmarketing.util.Logger;
import com.dotmarketing.util.UtilMethods;
import com.dotmarketing.util.WebKeys;
import com.liferay.portal.model.User;

/**
* This servlet resize an image proportionally without placing that image into a
* box background. The image generated is with the .png extension
*
* @author Oswaldo
*
*/
public class ResizeImageServlet extends HttpServlet {
    private static final FileAPI fileAPI = APILocator.getFileAPI();
  /**
     * serialVersionUID
     */
    private static final long serialVersionUID = 1L;
    private static PermissionAPI permissionAPI = APILocator.getPermissionAPI();

    /* This is a thread safe date formatter */
    FastDateFormat df = FastDateFormat.getInstance(Constants.RFC2822_FORMAT, TimeZone.getTimeZone("GMT"), Locale.US);
    /**
     * resize an image proportionally without placing that image into a box
     * background. The image generated is with the .png extension
     */
    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        long time = System.currentTimeMillis();

    User user = null;
    try {
      user = WebAPILocator.getUserWebAPI().getLoggedInUser(request);
    } catch (Exception nsue) {
      Logger.warn(this, "Exception trying to getUser: " + nsue.getMessage(), nsue);
    }

    boolean liveMode = ((request.getSession().getAttribute(com.dotmarketing.util.WebKeys.ADMIN_MODE_SESSION) == null));
        String id = request.getParameter("id");
        if(!UtilMethods.isSet(id)){
          id = request.getParameter("inode");
        }
        String url = (request.getParameter("path") != null) ? request.getParameter("path"): request.getParameter("url");

        Identifier identifier = null;
        File file = null;
        //Contentlet contentlet = null;


        String inode = null;
        Boolean fileAsContent = false;


        if(UtilMethods.isSet(url)) {
            //If path is the dotasset portlet
            if(url.startsWith("/dotAsset")) {
            StringTokenizer _st = new StringTokenizer(url, "/");
            String _fileName = null;
            while(_st.hasMoreElements()){
              _fileName = _st.nextToken();
            }
                id = UtilMethods.getFileName(_fileName); // Sets the identifier
            } else {
            //If it's a regular path
              Host currentHost;
        try {
          currentHost = WebAPILocator.getHostWebAPI().getCurrentHost(request);
          String path = LiveCache.getPathFromCache(url, currentHost);
          String cinode=path.split("/")[3];
          id=APILocator.getIdentifierAPI().findFromInode(cinode).getId();
        } catch (Exception e) {
          Logger.error(ResizeImageServlet.class, e.getMessage(), e);
          throw new ServletException(e.getMessage(), e);
        }


            }
        }

        // if we have an id
        if( UtilMethods.isSet(id) ) {

          try {
            identifier = APILocator.getIdentifierAPI().loadFromCache(id);
            if(identifier != null && (InodeUtils.isSet(identifier.getInode()))) {
              //it's an identifier
              String path = null;
              try {
                path = (liveMode) ? LiveCache.getPathFromCache(identifier.getURI(), identifier.getHostId())
              : WorkingCache.getPathFromCache(identifier.getURI(), identifier.getHostId());
              } catch(DotContentletStateException e) {
                path = WorkingCache.getPathFromCache(identifier.getURI(), identifier.getHostId());
              }

              if(path==null) {
                  Logger.debug(this.getClass(), "Can't find path with URI " + identifier.getURI());
                  return;
                }

                inode = UtilMethods.getFileName(path);
            } else {
              //it might be an inode
              try {
                file = APILocator.getFileAPI().find(id, user, true);
              } catch(Exception e) {
                Contentlet c = APILocator.getContentletAPI().find(id, user, true);
                fileAsContent = UtilMethods.isSet(c);
              }
                  if(file != null && (InodeUtils.isSet(file.getInode()))) {
                    inode = file.getInode();
                    identifier = APILocator.getIdentifierAPI().find(file.getIdentifier());
                  } else{
                    //Finally it's not a file and we did the first round trip to database
                    //then we do the second round trip to database to find the identifier,
                    //but after this the next hit will find it cached.
                    identifier = APILocator.getIdentifierAPI().find(id);
                    if(identifier != null && (InodeUtils.isSet(identifier.getInode())) ) {
                  String path = LiveCache.getPathFromCache(identifier.getURI(), identifier.getHostId());
                      inode = UtilMethods.getFileName(path);
                    }
                  }
            }
      } catch (Exception e) {
        System.out.println(e);
      }

        }


        if (!InodeUtils.isSet(inode) && !fileAsContent) {
            response.sendError(404);
            return;
        }

        try {
      //Checking permissions
          /**
           * Build a fake proxy file object so we
           * can get inheritable permissions on it
           * without having to hit cache or db
           */

            file = null;
            if(identifier!=null && UtilMethods.isSet(identifier.getInode())){
              file = new File();
              file.setIdentifier(identifier.getInode());
            }
            else{
              try {
                file = APILocator.getFileAPI().find(inode, user, true);
                identifier.setId(file.getIdentifier());
        } catch (Exception e) {
          Logger.error(ResizeImageServlet.class,e.getMessage(),e);
        }

            }

            if (file!=null && !permissionAPI.doesUserHavePermission(file, PERMISSION_READ, user, true)) {
              if(user == null)
                //Sending user to unauthorized the might send him to login
                response.sendError(401, "The requested file is unauthorized");
              else
                //sending the user to forbidden
                response.sendError(403, "The requested file is forbidden");
               return;
            }
    } catch (DotDataException e1) {
      Logger.error(this,e1.getMessage());
      response.sendError(500,e1.getMessage());
      return;
    }



        String h = request.getParameter("h");
        String w = request.getParameter("w");

        String maxh = request.getParameter("maxh");
        String maxw = request.getParameter("maxw");

        int height = Config.getIntProperty("DEFAULT_HEIGHT");
        int width = Config.getIntProperty("DEFAULT_WIDTH");
        int imageWidth = 0;
        int imageHeight = 0;
        double imageRatio = 0;

        try {

            if (fileAsContent || inode != null && inode.length() > 0 && InodeUtils.isSet(inode)) {

              boolean isSet = false;
              boolean isCont = false;
              String fileName = "";
              String inodeOrId = "";

              String contAssetPath = "";
              int imgWidth = 0;
              int imgLength = 0;
              String ext = "";
              if(fileAsContent || id!=null && InodeUtils.isSet(identifier.getId()) && identifier.getAssetType().equals("contentlet")){
                Contentlet cont = null;

                if(fileAsContent) {
                  cont = APILocator.getContentletAPI().find(id, user, true);
                  inode = id;
                } else {
                  try {
                      boolean live=true;
                          if(request.getSession().getAttribute("tm_date")!=null) {
                              live=true;
                              Identifier ident=APILocator.getIdentifierAPI().find(id);
                              if(UtilMethods.isSet(ident.getSysPublishDate()) || UtilMethods.isSet(ident.getSysExpireDate())) {
                                  Date fdate=new Date(Long.parseLong((String)request.getSession().getAttribute("tm_date")));
                                  if(UtilMethods.isSet(ident.getSysPublishDate()) && ident.getSysPublishDate().before(fdate))
                                      live=false;
                                  if(UtilMethods.isSet(ident.getSysExpireDate()) && ident.getSysExpireDate().before(fdate))
                                      return; // expired!
                              }
                          }
                    cont = APILocator.getContentletAPI().findContentletByIdentifier(id, live, APILocator.getLanguageAPI().getDefaultLanguage().getId(), user, true);
                  }
                  catch(DotContentletStateException e) {
                    cont = APILocator.getContentletAPI().findContentletByIdentifier(id, false, APILocator.getLanguageAPI().getDefaultLanguage().getId(), user, true);
                  }

                  if(cont==null) {
                    Logger.debug(this.getClass(), "Can't find content with id " + id);
                    return;
                  }
                }

                FileAsset fa = APILocator.getFileAssetAPI().fromContentlet(cont);
                isSet = InodeUtils.isSet(cont.getInode());
                fileName = fa.getFileName();
                isCont = true;
                inodeOrId = cont.getInode();
              contAssetPath = APILocator.getFileAssetAPI().getRealAssetPath(cont.getInode());
              java.util.Map<String, Object> keyValueMap = null;
              String JSONValue = cont.getStringProperty(FileAssetAPI.META_DATA_FIELD);
              //Convert JSON to Table Display {key, value, order}
              if(UtilMethods.isSet(JSONValue)){
                keyValueMap =  com.dotmarketing.portlets.structure.model.KeyValueFieldUtil.JSONValueToHashMap(JSONValue);
                if(UtilMethods.isSet((String)keyValueMap.get("width"))){
                  imgWidth = Integer.parseInt((String)keyValueMap.get("width"));
                }
                if(UtilMethods.isSet((String)keyValueMap.get("height"))){
                  imgLength = Integer.parseInt((String)keyValueMap.get("height"));
                }
              }
              if(!contAssetPath.endsWith(java.io.File.separator)){
                contAssetPath += java.io.File.separator;
              }
              ext = fa.getExtension();
              }else if(InodeUtils.isSet(identifier.getId())){
                    file = fileAPI.find(inode,user,true);
                    isSet =InodeUtils.isSet(file.getInode());
                    fileName = file.getFileName();
                    inodeOrId = inode;
                    imgWidth = file.getWidth();
                    imgLength = file.getHeight();
                    ext = file.getExtension();
              }


                if (isSet) {
                    // Set the size
                    if (UtilMethods.isSet(h) || UtilMethods.isSet(w)) {

                        if (UtilMethods.isInt(h) && UtilMethods.isInt(w)) {

                            height = (Integer.parseInt(h) > 0 ? Integer.parseInt(h) : Config.getIntProperty("DEFAULT_HEIGHT"));
                            width = (Integer.parseInt(w) > 0 ? Integer.parseInt(w) : Config.getIntProperty("DEFAULT_WIDTH"));

                        } else if (UtilMethods.isInt(h)) {

                            height = (Integer.parseInt(h) > 0 ? Integer.parseInt(h) : Config.getIntProperty("DEFAULT_HEIGHT"));

                            // determine thumbnail size from WIDTH and HEIGHT
                            imageWidth = imgWidth == 0?width:imgWidth;
                            imageHeight = imgLength == 0?height:imgLength;

                            // JIRA: http://jira.dotmarketing.net/browse/DOTCMS-1340
                            width = (int) Math.ceil((imageWidth * height)/imageHeight);

                        } else if (UtilMethods.isInt(w)) {

                            width = (Integer.parseInt(w) > 0 ? Integer.parseInt(w) : Config.getIntProperty("DEFAULT_WIDTH"));

                            // determine thumbnail size from WIDTH and HEIGHT
                            imageWidth = imgWidth == 0?width:imgWidth;
                            imageHeight = imgLength == 0?height:imgLength;

                            // JIRA: http://jira.dotmarketing.net/browse/DOTCMS-1340
                            height = (int) Math.ceil((imageHeight * width)/imageWidth);

                        }

                    } else if (UtilMethods.isSet(maxh) && UtilMethods.isSet(maxw)) {

                        int maxhint = Integer.parseInt(maxh);
                        int maxwint = Integer.parseInt(maxw);
                        int decrease = 0;

                        imageWidth = imgWidth == 0?width:imgWidth;
                        imageHeight = imgLength == 0?height:imgLength;

                        imageRatio = (double) imageWidth / (double) imageHeight;
                        boolean imageFinishied = true;

                        width = maxwint;
                        height = maxhint;

                        do {

                            if (width <= height) {

                                width = width - decrease;
                                height = (int) Math.ceil((width / imageRatio));

                            } else {

                                height = height - decrease;
                                width = (int) (height * imageRatio);
                            }

                            decrease = 1;

                            if (height <= maxhint && width <= maxwint) {
                                imageFinishied = false;
                            }

                        } while (imageFinishied);

                    }

                    // gets file extension
                    String suffix = ext;

                    // gets the real path to the assets directory
                    String filePath = fileAPI.getRealAssetsRootPath();

                    // creates the path where to save the working file based on
                    // the inode
                    String workingFileInodePath = String.valueOf(inode);
                    if(fileAsContent || id != null && identifier.getAssetType().equals("contentlet"))//DOTCMS-6531
                      workingFileInodePath = String.valueOf(inodeOrId);
                    if (workingFileInodePath.length() == 1) {
                        workingFileInodePath = workingFileInodePath + "0";
                    }

                    // creates the path with inode{1} + inode{2}
                    workingFileInodePath = workingFileInodePath.substring(0, 1) + java.io.File.separator + workingFileInodePath.substring(1, 2);

                    String thumbExtension = WebKeys.GENERATED_FILE  +inodeOrId +  height  + "_w_" + width ;
                    String thumbnailFilePath = "";
                    if(!isCont){
                    // creates the path with id{1} + id{2}

                        thumbnailFilePath = filePath + java.io.File.separator + workingFileInodePath + java.io.File.separator
                            +thumbExtension + "." + suffix;
                    }else if(fileAsContent){

                        thumbnailFilePath = filePath + java.io.File.separator + workingFileInodePath + java.io.File.separator + inodeOrId  + java.io.File.separator + "fileAsset"  + java.io.File.separator
                                +fileName;
                    } else {
                       thumbnailFilePath = filePath + java.io.File.separator + workingFileInodePath + java.io.File.separator + inodeOrId  + java.io.File.separator + "fileAsset"  + java.io.File.separator
                                 +thumbExtension + "." + suffix;
                    }



                    java.io.File thumbFile = null;
                    synchronized (inode.intern()) {

                        thumbFile = new java.io.File(thumbnailFilePath);
                        Logger.debug(this, "Checking resized image for " + thumbnailFilePath);
                        if (!thumbFile.exists() || (request.getParameter("nocache") != null)) {
                            Logger.debug(this, "File doesn't exists creating it");
                            String realPathAux= "";
                        if(isCont){
                          realPathAux = contAssetPath;
                        }else{
                          realPathAux = filePath + java.io.File.separator + workingFileInodePath+ java.io.File.separator;
                        }
                            com.dotmarketing.util.ImageResizeUtils.resizeImage(realPathAux, inode, suffix, thumbExtension, width, height);
                            thumbFile = new java.io.File(thumbnailFilePath);
                            Logger.debug(this, "File created thumbFile.exists() = " + thumbFile.exists());
                        }

                    }
                    if(thumbFile ==null){
                      response.sendError(404);
                      return;
                    }
                    Logger.debug(this, "Streaming the image");



                    //  -------- HTTP HEADER/ MODIFIED SINCE CODE -----------//

                    long _lastModified = thumbFile.lastModified();
                    long _fileLength = thumbFile.length();
          String _eTag = "dot:" + inode + "-" + _lastModified/1000 + "-" + _fileLength;
                    String ifModifiedSince = request.getHeader("If-Modified-Since");
                    String ifNoneMatch = request.getHeader("If-None-Match");

                    /*
                     * If the etag matches then the file is the same
                     *
                    */

                    if(ifNoneMatch != null){
                        if(_eTag.equals(ifNoneMatch) || ifNoneMatch.equals("*")){
                            response.setStatus(HttpServletResponse.SC_NOT_MODIFIED );
                            thumbFile = null;
                            return;
                        }
                    }
                    /* Using the If-Modified-Since Header */
                    if(ifModifiedSince != null){
              try{
                java.text.SimpleDateFormat httpDate = new java.text.SimpleDateFormat(Constants.RFC2822_FORMAT, Locale.US);
                httpDate.setTimeZone(TimeZone.getDefault());
                  Date ifModifiedSinceDate = httpDate.parse(ifModifiedSince);

                  if(_lastModified <= ifModifiedSinceDate.getTime()){

                      response.setStatus(HttpServletResponse.SC_NOT_MODIFIED );
                      thumbFile = null;
                      return;
                  }
              }
              catch(Exception e){}
          }

                    response.setHeader("Content-Length", String.valueOf(_fileLength));
                    response.setHeader("Last-Modified", df.format(_lastModified));
                    response.setHeader("ETag", "\"" + _eTag +"\"");
                    // Set the expiration time
                    GregorianCalendar expiration = new GregorianCalendar();
                    expiration.add(java.util.Calendar.YEAR, 1);
                    response.setHeader("Expires", df.format(expiration.getTime()));
                    response.setHeader("Cache-Control", "max-age=31104000");
                    // END Set the expiration time

                    //  -------- /HTTP HEADER/ MODIFIED SINCE CODE -----------//



                    // set the content type and get the output stream
                    response.setContentType(this.getServletContext().getMimeType(thumbnailFilePath));
                    Logger.debug(this, "Image mime type " + this.getServletContext().getMimeType(thumbnailFilePath));

                    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(thumbFile));
                    OutputStream os = response.getOutputStream();
                    byte[] buf = new byte[4096];
                    int i = 0;

                    while ((i = bis.read(buf)) != -1) {
                        os.write(buf, 0, i);
                    }

                    os.flush();
                    os.close();
                    bis.close();
                    Logger.debug(this.getClass(), "time to serve ResizeImage thumbnail: " + (System.currentTimeMillis() - time) + "ms");
                } else {
                    // set the content type and get the output stream
                    response.setContentType("image/jpeg");
                    // Construct the image
                    String path = fileAPI.getRealAssetsRootPath() + java.io.File.separator + ".." + java.io.File.separator + "html" + java.io.File.separator + "js" + java.io.File.separator +
                        "editor" + java.io.File.separator + "images" + java.io.File.separator + "spacer.gif";
                    java.io.File f = new java.io.File(path);

                    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f));
                    OutputStream os = response.getOutputStream();
                    byte[] buf = new byte[4096];
                    int i = 0;

                    while ((i = bis.read(buf)) != -1) {
                        os.write(buf, 0, i);
                    }

                    os.flush();
                    os.close();
                    bis.close();
                }

            }
        }
        catch(java.net.SocketException ex) {
            Logger.debug(this, "got socketException",ex);
        }
        catch (Exception e) {
            Logger.error(ResizeImageServlet.class, "Error creating thumbnail from ResizeImage servlet: " + e.getMessage(),e);
        }
        return;
    }
}
TOP

Related Classes of com.dotmarketing.servlets.image.ResizeImageServlet

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.