Package railo.runtime.tag

Source Code of railo.runtime.tag.Image

package railo.runtime.tag;

import java.awt.Color;
import java.io.IOException;

import javax.servlet.jsp.JspException;

import railo.commons.color.ColorCaster;
import railo.commons.io.res.Resource;
import railo.commons.io.res.util.ResourceUtil;
import railo.commons.lang.StringUtil;
import railo.runtime.exp.ApplicationException;
import railo.runtime.exp.ExpressionException;
import railo.runtime.exp.PageException;
import railo.runtime.ext.tag.TagImpl;
import railo.runtime.functions.other.CreateUUID;
import railo.runtime.functions.system.ContractPath;
import railo.runtime.img.ImageUtil;
import railo.runtime.img.MarpleCaptcha;
import railo.runtime.op.Caster;
import railo.runtime.type.Struct;
import railo.runtime.type.util.ArrayUtil;
import railo.runtime.type.util.ListUtil;

// GetWriteableImageFormats
// GetReadableImageFormats


/**
* Lets you resize and add labels to GIF and JPEG format images.
*
*
*
**/
public final class Image extends TagImpl {
 
  private static int ACTION_BORDER=0;
  private static int ACTION_CAPTCHA=1;
  private static int ACTION_CONVERT=2;
  private static int ACTION_INFO=3;
  private static int ACTION_READ=4;
  private static int ACTION_RESIZE=5;
  private static int ACTION_ROTATE=6;
  private static int ACTION_WRITE=7;
  private static int ACTION_WRITE_TO_BROWSER=8;


  private int action=ACTION_READ;
  private String strAction="read";
  private int angle=-1;
  private Color color=Color.BLACK;
  private Resource destination;
  private int difficulty=MarpleCaptcha.DIFFICULTY_LOW;
  private String[] fonts=new String[]{"arial"};
  private int fontsize=24;
  private String format="png";
  private String height;
  private String width;
  private boolean isbase64;
  private String name;
  private boolean overwrite;
  private float quality=.75F;
  private Object oSource;
  private railo.runtime.img.Image source;
  private String structName;
  private String text;
  private int thickness=1;
  private String passthrough;
  private boolean base64;
 



  @Override
  public void release() {
    super.release();
    action=ACTION_READ;
    strAction="read";
    angle=-1;
    color=Color.BLACK;
    destination=null;
    difficulty=MarpleCaptcha.DIFFICULTY_LOW;
    fonts=new String[]{"arial"};
    fontsize=24;
    format="png";
    height=null;
    width=null;
    isbase64=false;
    name=null;
    overwrite=false;
    quality=0.75F;
    source=null;
    oSource=null;
    structName=null;
    text=null;
    thickness=1;
    passthrough=null;
    base64=false;
  }


  /**
   * @param action the action to set
   * @throws ApplicationException
   */
  public void setAction(String strAction) throws ApplicationException {
    this.strAction = strAction;
    strAction=strAction.trim().toLowerCase();
    if(StringUtil.isEmpty(strAction))action=ACTION_READ;
    else if("border".equals(strAction))action=ACTION_BORDER;
    else if("captcha".equals(strAction))action=ACTION_CAPTCHA;
    else if("convert".equals(strAction))action=ACTION_CONVERT;
    else if("info".equals(strAction))action=ACTION_INFO;
    else if("read".equals(strAction))action=ACTION_READ;
    else if("resize".equals(strAction))action=ACTION_RESIZE;
    else if("rotate".equals(strAction))action=ACTION_ROTATE;
    else if("write".equals(strAction))action=ACTION_WRITE;
    else if("writetobrowser".equals(strAction))action=ACTION_WRITE_TO_BROWSER;
    else if("write-to-browser".equals(strAction))action=ACTION_WRITE_TO_BROWSER;
    else if("write_to_browser".equals(strAction))action=ACTION_WRITE_TO_BROWSER;
    else throw new ApplicationException("invalid action ["+this.strAction+"], " +
    "valid actions are [border,captcha,convert,info,read,resize,rotate,write,writeToBrowser]");
  }


  /**
   * @param base64 the base64 to set
   */
  public void setBase64(boolean base64) {
    this.base64 = base64;
  }


  /**
   * @param angle the angle to set
   */
  public void setAngle(double angle) {
    this.angle = (int) angle;
  }


  /**
   * @param color the color to set
   * @throws ExpressionException
   */
  public void setColor(String strColor) throws ExpressionException {
    this.color = ColorCaster.toColor(strColor);
  }


  /**
   * @param destination the destination to set
   */
  public void setDestination(String destination) {
    this.destination = ResourceUtil.toResourceNotExisting(pageContext, destination);
  }


  /**
   * @param difficulty the difficulty to set
   * @throws ApplicationException
   */
  public void setDifficulty(String strDifficulty) throws ApplicationException {
    strDifficulty=strDifficulty.trim().toLowerCase();
    if(StringUtil.isEmpty(strDifficulty))  difficulty=MarpleCaptcha.DIFFICULTY_LOW;
    else if("low".equals(strDifficulty))  difficulty=MarpleCaptcha.DIFFICULTY_LOW;
    else if("medium".equals(strDifficulty))  difficulty=MarpleCaptcha.DIFFICULTY_MEDIUM;
    else if("high".equals(strDifficulty))  difficulty=MarpleCaptcha.DIFFICULTY_HIGH;
    else throw new ApplicationException("invalid difficulty level ["+strDifficulty+"], " +
    "valid difficulty level are [low,medium,high]");
   
  }


  /**
   * @param fonts the fonts to set
   * @throws PageException
   */
  public void setFonts(String fontList) throws PageException {
    fonts=ArrayUtil.trim(ListUtil.toStringArray(ListUtil.listToArray(fontList, ',')));
  }

 

  /**
   * @param passthrough the passthrough to set
   */
  public void setPassthrough(String passthrough) {
    this.passthrough = passthrough;
  }

  /**
   * @param fontsize the fontsize to set
   */
  public void setFontsize(double fontsize) {
    this.fontsize = (int) fontsize;
  }


  /**
   * @param format the format to set
   * @throws ApplicationException
   */
  public void setFormat(String format) throws ApplicationException {
    format=format.trim().toLowerCase();
    if("gif".equalsIgnoreCase(format))    this.format =  "gif";
    else if("jpg".equalsIgnoreCase(format))  this.format =  "jpg";
    else if("jpe".equalsIgnoreCase(format))  this.format =  "jpg";
    else if("jpeg".equalsIgnoreCase(format))this.format =  "jpg";
    else if("png".equalsIgnoreCase(format))  this.format =  "png";
    else if("tiff".equalsIgnoreCase(format))this.format =  "tiff";
    else if("bmp".equalsIgnoreCase(format))  this.format =  "bmp";
    else throw new ApplicationException("invalid format ["+format+"], " +
    "valid formats are [gif,jpg,png,tiff,bmp]");
  }


  /**
   * @param height the height to set
   */
  public void setHeight(String height) {
    this.height = height;
  }


  /**
   * @param width the width to set
   */
  public void setWidth(String width) {
    this.width = width;
  }


  /**
   * @param isbase64 the isbase64 to set
   */
  public void setIsbase64(boolean isbase64) {
    this.isbase64 = isbase64;
  }


  /**
   * @param name the name to set
   */
  public void setName(String name) {
    this.name = name;
  }


  /**
   * @param overwrite the overwrite to set
   */
  public void setOverwrite(boolean overwrite) {
    this.overwrite = overwrite;
  }


  /**
   * @param quality the quality to set
   * @throws ApplicationException
   */
  public void setQuality(double quality) throws ApplicationException {
    this.quality = (float) quality;
    if(quality<0 || quality>1)
      throw new ApplicationException("quality ("+Caster.toString(quality)+") has to be a value between 0 and 1");
  }


  /**
   * @param source the source to set
   * @throws PageException
   */
  public void setSource(Object source) {
    this.oSource=source;
    // this.source=railo.runtime.img.Image.createImage(pageContext, source, false, false);
  }


  /**
   * @param structName the structName to set
   */
  public void setStructname(String structName) {
    this.structName = structName;
  }


  /**
   * @param structName the structName to set
   */
  public void setResult(String structName) {
    this.structName = structName;
  }


  /**
   * @param text the text to set
   */
  public void setText(String text) {
    this.text = text;
  }


  /**
   * @param thickness the thickness to set
   */
  public void setThickness(double thickness) {
    this.thickness = (int) thickness;
  }


  @Override
  public int doStartTag() throws JspException {
    try {
      if(this.oSource!=null){
        if(isbase64) this.source=new railo.runtime.img.Image(Caster.toString(oSource));
        else this.source=railo.runtime.img.Image.createImage(pageContext, oSource, false, false,true,null);
      }
     
      if(action==ACTION_BORDER)    doActionBorder();
      else if(action==ACTION_CAPTCHA) doActionCaptcha();
      else if(action==ACTION_CONVERT) doActionConvert();
      else if(action==ACTION_INFO)   doActionInfo();
      else if(action==ACTION_READ)   doActionRead();
      else if(action==ACTION_RESIZE)   doActionResize();
      else if(action==ACTION_ROTATE)   doActionRotate();
      else if(action==ACTION_WRITE)   doActionWrite();
      else if(action==ACTION_WRITE_TO_BROWSER)
                      doActionWriteToBrowser();
    }
    catch(Throwable t) {
      throw Caster.toPageException(t);
    }
    return SKIP_BODY;
  }

  // Add a border to an image
  private void doActionBorder() throws PageException, IOException {
    required("source", source);
   
    source.addBorder(thickness,color,railo.runtime.img.Image.BORDER_TYPE_CONSTANT);
    write();
       
  }


  // Create a CAPTCHA image
  private void doActionCaptcha() throws PageException, IOException {
    required("height", height);
    required("width", width);
    required("text", text);

        boolean doRenderHtmlTag = ( destination == null );

    String path=null;
   
    // create destination
    if(StringUtil.isEmpty(name))path=touchDestination();
   
    MarpleCaptcha c=new MarpleCaptcha();
    source=new railo.runtime.img.Image(c.generate(text, Caster.toIntValue(width),Caster.toIntValue(height), fonts, true,
        Color.BLACK,fontsize,
        difficulty));
   
    // link destination
    if ( doRenderHtmlTag )
      writeLink( path );
   
    // write out
    write();
  }
 
  private void writeLink(String path) throws IOException, PageException {
    String add="";
    if(passthrough!=null) {
            add=" "+passthrough;
        }
   
    if(base64) {
      String b64 = source.getBase64String(format);
      pageContext.write("<img src=\"data:image/"+ImageUtil.getMimeTypeFromFormat(format)+";base64,"+b64+"\" width=\""+source.getWidth()+"\" height=\""+source.getHeight()+"\""+add+" />");
      return;
    }
    pageContext.write("<img src=\""+path+"\" width=\""+source.getWidth()+"\" height=\""+source.getHeight()+"\""+add+" />");
 
 
  }


  private String touchDestination() throws IOException {
    if(destination==null) {
      String name=CreateUUID.call(pageContext)+"."+format;
      Resource folder = pageContext.getConfig().getTempDirectory().getRealResource("graph");
      if(!folder.exists())folder.createDirectory(true);
      destination = folder.getRealResource(name);
      cleanOld(folder);
     
      // create path
      String cp = pageContext.getHttpServletRequest().getContextPath();
      if(StringUtil.isEmpty(cp)) cp="";
      return cp+"/railo-context/graph.cfm?img="+name+"&type="+(ListUtil.last(ImageUtil.getMimeTypeFromFormat(format),'/').trim());
    }
    return ContractPath.call(pageContext, destination.getAbsolutePath());
  }


  private static void cleanOld(Resource folder) throws IOException {
    if(!folder.exists())folder.createDirectory(true);
    else if(folder.isDirectory() && ResourceUtil.getRealSize(folder)>(1024*1024)) {
     
      Resource[] children = folder.listResources();
      long maxAge=System.currentTimeMillis()-(1000*60);
      for(int i=0;i<children.length;i++) {
        if(children[i].lastModified()<maxAge)
          children[i].delete();
      }
    }
  }

  // Convert an image file format
  private void doActionConvert() throws PageException, IOException {
    required("source", source);
    required("destination", destination);
   
    source.convert(ImageUtil.getFormat(destination));
    write();
  }

  // Retrieve information about an image
  private void doActionInfo() throws PageException {
    required("source",source);
    required("structname",structName);
   
    pageContext.setVariable(structName, source.info());
  }
 
  private Struct doActionInfo(railo.runtime.img.Image source) throws PageException {
    return source.info();
  }


  // Read an image into memory
  private void doActionRead() throws PageException {
    required("source",source);
    required("name",name);
   
    pageContext.setVariable(name, source);
  }


  // Resize an image
  private void doActionResize() throws PageException, IOException {
    required("source", source);
   
    //Info i = new Info(source);
    /*int w = toDimension("width",width,i);
    int h = toDimension("height",height,i);
    if(w==-1 && h==-1)
      throw new ApplicationException("Missing attribute [width or height]. The action ["+strAction+"] requires the attribute [width or height].");
    */
   
    source.resize(width,height,"highestquality",1D);
   
    write();
  }
 
  // Rotate an image
  private void doActionRotate() throws PageException, IOException {
    required("source",source);
    required("angle",angle,-1);
   
    source.rotate(-1, -1, angle, railo.runtime.img.Image.INTERPOLATION_NONE);
    write();
   
  }

  // Write an image to a file
  private void doActionWrite() throws ApplicationException, IOException, ExpressionException {
    required("source", source);
    required("destination", destination);
   
    source.writeOut(destination,overwrite,quality);
  }

  // Write an image to the browser
  private void doActionWriteToBrowser() throws IOException, PageException {
    required("source", source);
   
    String path=null;
   
    // create destination
    if(!base64 || !StringUtil.isEmpty(name)) {
      path=touchDestination();
      write();
    }
    // link destination
    if(StringUtil.isEmpty(name))writeLink(path);
   
   
   
   
  }



  private void required(String label, Object value) throws ApplicationException {
    if(value==null)
      throw new ApplicationException("Missing attribute ["+label+"]. The action ["+strAction+"] requires the attribute [" + label + "].");
      //throw new ApplicationException("missing attribute ["+label+"], for the action ["+strAction+"] this attribute is required but was not passed in");
  }
  private void required(String label, int value,int nullValue) throws ApplicationException {
    if(value==nullValue)
      throw new ApplicationException("Missing attribute ["+label+"]. The action ["+strAction+"] requires the attribute [" + label + "].");
      //throw new ApplicationException("missing attribute ["+label+"], for the action ["+strAction+"] this attribute is required but was not passed in");
  }


  private void write() throws IOException, PageException {
    if(destination!=null) {
      doActionWrite();
    }
    if(!StringUtil.isEmpty(name)) {
      required("source", source);
      pageContext.setVariable(name, source);// TODO ist das so gut
    }
    //if(writeToResponseWhenNoOtherTarget) doActionWriteToBrowser();
  }
 

  class Info {
    Struct struct;
    private railo.runtime.img.Image img;

    public Info(railo.runtime.img.Image img) {
      this.img=img;
    }

    /**
     * @return the sct
     * @throws PageException
     */
    public Struct getStruct() throws PageException {
      if(struct==null)
        struct=doActionInfo(img);
      return struct;
    }
  }


  private int toDimension(String label, String dimension, Info info) throws PageException {
    if(StringUtil.isEmpty(dimension)) return -1;
    dimension=dimension.trim();
    // int value
    int i=Caster.toIntValue(dimension,-1);
    if(i>-1) return i;
   
    // percent value
    if(StringUtil.endsWith(dimension, '%')) {
      float pro=Caster.toIntValue(
            dimension.substring(0,dimension.length()-1).trim(),
            -1);
      if(pro<0 || pro>100)
        throw new ExpressionException("attribute ["+label+"] value has an invalid percent definition ["+dimension+"]");
      pro/=100F;
      return (int)(Caster.toFloatValue(info.getStruct().get(label))*pro);
    }
    throw new ExpressionException("attribute ["+label+"] value has an invalid definition ["+dimension+"]");
   
  }

}
TOP

Related Classes of railo.runtime.tag.Image

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.