Package railo.runtime.tag

Source Code of railo.runtime.tag.PDF

package railo.runtime.tag;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.oro.text.regex.MalformedPatternException;
import org.pdfbox.exceptions.CryptographyException;
import org.pdfbox.exceptions.InvalidPasswordException;

import railo.commons.io.IOUtil;
import railo.commons.io.res.Resource;
import railo.commons.io.res.filter.ExtensionResourceFilter;
import railo.commons.io.res.filter.ResourceFilter;
import railo.commons.io.res.util.ResourceUtil;
import railo.commons.io.res.util.WildCardFilter;
import railo.commons.lang.StringUtil;
import railo.runtime.exp.ApplicationException;
import railo.runtime.exp.CasterException;
import railo.runtime.exp.ExpressionException;
import railo.runtime.exp.PageException;
import railo.runtime.ext.tag.BodyTagImpl;
import railo.runtime.op.Caster;
import railo.runtime.op.Decision;
import railo.runtime.text.pdf.PDFDocument;
import railo.runtime.text.pdf.PDFUtil;
import railo.runtime.type.Array;
import railo.runtime.type.Collection.Key;
import railo.runtime.type.Struct;
import railo.runtime.type.util.KeyConstants;
import railo.runtime.type.util.ListUtil;

import com.lowagie.text.DocumentException;
import com.lowagie.text.Image;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfGState;
import com.lowagie.text.pdf.PdfImportedPage;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfStamper;
import com.lowagie.text.pdf.PdfWriter;
import com.lowagie.text.pdf.SimpleBookmark;

public class PDF extends BodyTagImpl  {

  private static final int ACTION_ADD_WATERMARK = 0;
  private static final int ACTION_DELETE_PAGES = 1;
  private static final int ACTION_GET_INFO = 2;
  private static final int ACTION_MERGE = 3;
  private static final int ACTION_PROCESSDDX = 5;
  private static final int ACTION_PROTECT = 5;
  private static final int ACTION_READ = 6;
  private static final int ACTION_REMOVE_WATERMARK = 7;
  private static final int ACTION_SET_INFO = 8;
  private static final int ACTION_THUMBNAIL = 9;
  private static final int ACTION_WRITE = 10;
  private static final int ACTION_EXTRACT_TEXT = 11;

 
  private static final String FORMAT_JPG ="jpg";
  private static final String FORMAT_TIFF = "tiff";
  private static final String FORMAT_PNG = "png";
 
  private static final int ORDER_TIME = 0;
  private static final int ORDER_NAME = 1;
 
  private static final int RESOLUTION_HIGH = 0;
  private static final int RESOLUTION_LOW = 1;

  private static final int SAVE_OPTION_FULL = 0;
  private static final int SAVE_OPTION_INCREMENTAL = 1;
  private static final int SAVE_OPTION_LINEAR = 2;
 
  private static final int TYPE_STRING = 1;
  private static final int TYPE_XML = 2;
   
 
  private static final ExtensionResourceFilter PDF_FILTER = new ExtensionResourceFilter("pdf");
  private static final int UNDEFINED = Integer.MIN_VALUE;
 
 
 
  private int action=ACTION_PROCESSDDX;
  private boolean ascending =false;
  private Object copyFrom=null;
  private String ddxFile=null;
  private Resource destination=null;
  private Resource directory=null;
  private int encrypt=PDFUtil.ENCRYPT_RC4_128;
  private boolean flatten=false;
  private boolean foreground=false;
  private String format=FORMAT_JPG;
  private Object image=null;
  private Struct info=null;
  private Struct inputFiles=null;
  private Struct outputFiles=null;
  private boolean isBase64=false;
  private boolean keepBookmark=false;
  private String name=null;
  private String newOwnerPassword=null;
  private String newUserPassword=null;
  private float opacity=0.3F;
  private int order=ORDER_TIME;
  private boolean overwrite=false;
  private String pages=null;
  private String password=null;
  private int permissions=0;
  private String position=null;
  private int resolution=RESOLUTION_HIGH;
  private float rotation=0;
  private int saveOption=SAVE_OPTION_FULL;
  private int scale=25;
  private boolean showOnPrint=false;
  private Object source =null;
  private boolean stopOnError=false;
  private boolean transparent=false;
  private char version=0;
  private java.util.List<PDFParamBean> params;
  private ResourceFilter filter=null;
  private String imagePrefix=null;
  private int type=TYPE_XML;
 
  @Override
  public void release() {
    super.release();
    action=ACTION_PROCESSDDX;
    ascending =false;
    copyFrom=null;
    ddxFile=null;
    destination=null;
    directory=null;
    encrypt=PDFUtil.ENCRYPT_RC4_128;
    flatten=false;
    foreground=false;
    format=FORMAT_JPG;
    image=null;
    info=null;
    inputFiles=null;
    outputFiles=null;
    isBase64=false;
    keepBookmark=false;
    name=null;
    newOwnerPassword=null;
    newUserPassword=null;
    opacity=0.3F;
    order=ORDER_TIME;
    overwrite=false;
    pages=null;
    password=null;
    permissions=0;
    position=null;
    resolution=RESOLUTION_HIGH;
    rotation=0;
    saveOption=SAVE_OPTION_FULL;
    scale=25;
    showOnPrint=false;
    source =null;
    stopOnError=false;
    transparent=false;
    version=0;
    params=null;
    filter=null;
    imagePrefix=null;
    type=TYPE_XML;
  }
 
 
 
  /**
   * @param imagePrefix the imagePrefix to set
   */
  public void setImageprefix(String imagePrefix) {
    this.imagePrefix = imagePrefix;
  }



  /**
   * @param action the action to set
   * @throws ApplicationException
   */
  public void setAction(String strAction) throws ApplicationException {
   
    strAction=StringUtil.toLowerCase(strAction.trim());
    if("addwatermark".equals(strAction))        action=ACTION_ADD_WATERMARK;
    else if("add-watermark".equals(strAction))      action=ACTION_ADD_WATERMARK;
    else if("add_watermark".equals(strAction))      action=ACTION_ADD_WATERMARK;
    else if("deletepages".equals(strAction))      action=ACTION_DELETE_PAGES;
    else if("delete-pages".equals(strAction))      action=ACTION_DELETE_PAGES;
    else if("delete_pages".equals(strAction))      action=ACTION_DELETE_PAGES;
    else if("deletepage".equals(strAction))        action=ACTION_DELETE_PAGES;
    else if("delete-page".equals(strAction))      action=ACTION_DELETE_PAGES;
    else if("delete_page".equals(strAction))      action=ACTION_DELETE_PAGES;
    else if("getinfo".equals(strAction))        action=ACTION_GET_INFO;
    else if("get-info".equals(strAction))        action=ACTION_GET_INFO;
    else if("get_info".equals(strAction))        action=ACTION_GET_INFO;
    else if("merge".equals(strAction))          action=ACTION_MERGE;
    //else if("processddx".equals(strAction))        action=ACTION_PROCESSDDX;
    //else if("process-ddx".equals(strAction))      action=ACTION_PROCESSDDX;
    //else if("process_ddx".equals(strAction))      action=ACTION_PROCESSDDX;
    else if("protect".equals(strAction))        action=ACTION_PROTECT;
    else if("read".equals(strAction))          action=ACTION_READ;
    else if("removewatermark".equals(strAction))    action=ACTION_REMOVE_WATERMARK;
    else if("removewater-mark".equals(strAction))    action=ACTION_REMOVE_WATERMARK;
    else if("removewater_mark".equals(strAction))    action=ACTION_REMOVE_WATERMARK;
    else if("setinfo".equals(strAction))        action=ACTION_SET_INFO;
    else if("set-info".equals(strAction))        action=ACTION_SET_INFO;
    else if("set_info".equals(strAction))        action=ACTION_SET_INFO;
    else if("thumbnail".equals(strAction))        action=ACTION_THUMBNAIL;
    else if("write".equals(strAction))          action=ACTION_WRITE;
    else if("extracttext".equals(strAction))          action=ACTION_EXTRACT_TEXT;
    else if("extract-text".equals(strAction))          action=ACTION_EXTRACT_TEXT;
    else if("extract_text".equals(strAction))          action=ACTION_EXTRACT_TEXT;
   
    else throw new ApplicationException("invalid action definition ["+strAction+"], valid actions definitions are " +
        "[addWatermark,deletePages,getInfo,merge,protect,read,removeWatermark,setInfo,thumbnail,write]");
   
  }
 

  public void setType(String strType) throws ApplicationException {
   
    strType=StringUtil.toLowerCase(strType.trim());
    if("string".equals(strType))        type=TYPE_STRING;
    else if("text".equals(strType))        type=TYPE_STRING;
    else if("plain".equals(strType))        type=TYPE_STRING;
    else if("xml".equals(strType))        type=TYPE_XML;
   
    else throw new ApplicationException("invalid type definition ["+strType+"], valid type definitions are " +
        "[string,xml]");
   
  }
 
  /**
  *  sets a filter pattern
  * @param pattern
   * @throws PageException
  **/
  public void setFilter(String pattern) throws PageException  {
      if(pattern.trim().length()>0) {
            try {
              this.filter=new WildCardFilter(pattern);
            }
            catch (MalformedPatternException e) {
                throw Caster.toPageException(e);
            }
        }
  }
 
  /**
   * @param ascending the ascending to set
   */
  public void setAscending(boolean ascending) {
    this.ascending = ascending;
  }
  /**
   * @param copyFrom the copyFrom to set
   * @throws ExpressionException
   */
  public void setCopyfrom(Object copyFrom) throws ExpressionException {
    this.copyFrom = copyFrom;//ResourceUtil.toResourceExisting(pageContext, copyFrom);
  }
  /**
   * @param ddxFile the ddxFile to set
   */
  public void setDdxfile(String ddxFile) {
    this.ddxFile = ddxFile;// MUST
  }
  /**
   * @param destination the destination to set
   */
  public void setDestination(String destination) {
    this.destination = ResourceUtil.toResourceNotExisting(pageContext, destination);
  }
  /**
   * @param directory the directory to set
   * @throws ExpressionException
   */
  public void setDirectory(String directory) throws ExpressionException {
    this.directory = ResourceUtil.toResourceExisting(pageContext, directory);
  }
  /**
   * @param encrypt the encrypt to set
   * @throws ApplicationException
   */
  public void setEncrypt(String strEncrypt) throws ApplicationException {

    strEncrypt=StringUtil.toLowerCase(strEncrypt.trim());
    if("aes128".equals(strEncrypt))        encrypt=PDFUtil.ENCRYPT_AES_128; 
    else if("aes-128".equals(strEncrypt))    encrypt=PDFUtil.ENCRYPT_AES_128; 
    else if("aes_128".equals(strEncrypt))    encrypt=PDFUtil.ENCRYPT_AES_128; 
    else if("none".equals(strEncrypt))      encrypt=PDFUtil.ENCRYPT_NONE;   
    else if("".equals(strEncrypt))        encrypt=PDFUtil.ENCRYPT_NONE;   
    else if("rc4128".equals(strEncrypt))    encrypt=PDFUtil.ENCRYPT_RC4_128;   
    else if("rc4-128".equals(strEncrypt))    encrypt=PDFUtil.ENCRYPT_RC4_128;   
    else if("rc4_128".equals(strEncrypt))    encrypt=PDFUtil.ENCRYPT_RC4_128;   
    else if("rc4128m".equals(strEncrypt))    encrypt=PDFUtil.ENCRYPT_RC4_128M;   
    else if("rc4-128m".equals(strEncrypt))    encrypt=PDFUtil.ENCRYPT_RC4_128M;   
    else if("rc4_128m".equals(strEncrypt))    encrypt=PDFUtil.ENCRYPT_RC4_128M;   
    else if("rc440".equals(strEncrypt))      encrypt=PDFUtil.ENCRYPT_RC4_40;   
    else if("rc4-40".equals(strEncrypt))    encrypt=PDFUtil.ENCRYPT_RC4_40;   
    else if("rc4_40".equals(strEncrypt))    encrypt=PDFUtil.ENCRYPT_RC4_40;   
   
   
    else throw new ApplicationException("invalid encrypt definition ["+strEncrypt+"], valid encrypt definitions are " +
        "[aes_128,none,rc4_128,rc4_128m,rc4_40]");
  }
  /**
   * @param flatten the flatten to set
   */
  public void setFlatten(boolean flatten) {
    this.flatten = flatten;
  }
  /**
   * @param foreground the foreground to set
   */
  public void setForeground(boolean foreground) {
    this.foreground = foreground;
  }
  /**
   * @param format the format to set
   * @throws ApplicationException
   */
  public void setFormat(String strFormat) throws ApplicationException {
    strFormat=StringUtil.toLowerCase(strFormat.trim());
    if("jpg".equals(strFormat))          format=FORMAT_JPG; 
    else if("jpeg".equals(strFormat))      format=FORMAT_JPG; 
    else if("jpe".equals(strFormat))      format=FORMAT_JPG; 
    else if("tiff".equals(strFormat))      format=FORMAT_TIFF;
    else if("tif".equals(strFormat))      format=FORMAT_TIFF; 
    else if("png".equals(strFormat))      format=FORMAT_PNG; 
   
    else throw new ApplicationException("invalid format definition ["+strFormat+"], valid format definitions are " +
        "[jpg,tiff,png]");
  }
  /**
   * @param image the image to set
   */
  public void setImage(Object image) {
    this.image = image;// MUST
  }
  /**
   * @param prefix the prefix to set
   */
  public void setPrefix(String prefix) {
    this.imagePrefix = prefix;
  }
  /**
   * @param info the info to set
   */
  public void setInfo(Struct info) {
    this.info = info;
  }
  /**
   * @param inputFiles the inputFiles to set
   */
  public void setInputfiles(Struct inputFiles) {
    this.inputFiles = inputFiles;
  }
  /**
   * @param outputFiles the outputFiles to set
   */
  public void setOutputfiles(Struct outputFiles) {
    this.outputFiles = outputFiles;
  }
  /**
   * @param isBase64 the isBase64 to set
   */
  public void setIsbase64(boolean isBase64) {
    this.isBase64 = isBase64;
  }
  /**
   * @param keepBookmark the keepBookmark to set
   */
  public void setKeepbookmark(boolean keepBookmark) {
    this.keepBookmark = keepBookmark;
  }
  /**
   * @param name the name to set
   */
  public void setName(String name) {
    this.name = name;
  }
  /**
   * @param newOwnerPassword the newOwnerPassword to set
   */
  public void setNewownerpassword(String newOwnerPassword) {
    this.newOwnerPassword = newOwnerPassword;
  }
  /**
   * @param newUserPassword the newUserPassword to set
   */
  public void setNewuserpassword(String newUserPassword) {
    this.newUserPassword = newUserPassword;
  }
  /**
   * @param opacity the opacity to set
   * @throws ApplicationException
   */
  public void setOpacity(double opacity) throws ApplicationException {
    if(opacity<0 || opacity>10)
      throw new ApplicationException("invalid opacity definition ["+Caster.toString(opacity)+"], value should be in range from 0 to 10");
    this.opacity = (float) (opacity/10);
  }
  /**
   * @param order the order to set
   * @throws ApplicationException
   */
  public void setOrder(String strOrder) throws ApplicationException {
    strOrder=StringUtil.toLowerCase(strOrder.trim());
    if("name".equals(strOrder))          order=ORDER_NAME; 
    else if("time".equals(strOrder))      order=ORDER_TIME; 
   
    else throw new ApplicationException("invalid order definition ["+strOrder+"], valid order definitions are " +
        "[name,time]");
  }
  /**
   * @param overwrite the overwrite to set
   */
  public void setOverwrite(boolean overwrite) {
    this.overwrite = overwrite;
  }
  /**
   * @param pages the pages to set
   */
  public void setPages(String pages) {
    this.pages = pages;
  }
  /**
   * @param password the password to set
   */
  public void setPassword(String password) {
    this.password = password;
  }
  /**
   * @param permissions the permissions to set
   * @throws PageException
   */
  public void setPermissions(String strPermissions) throws PageException {
    permissions=PDFUtil.toPermissions(strPermissions);
 
  /**
   * @param position the position to set
   */
  public void setPosition(String position) {
    this.position = position;//MUST
  }
  /**
   * @param resolution the resolution to set
   * @throws ApplicationException
   */
  public void setResolution(String strResolution) throws ApplicationException {
    strResolution=StringUtil.toLowerCase(strResolution.trim());
    if("low".equals(strResolution))      resolution=RESOLUTION_LOW; 
    else if("high".equals(strResolution))  resolution=RESOLUTION_HIGH; 
   
    else throw new ApplicationException("invalid resolution definition ["+strResolution+"], valid resolution definitions are " +
        "[low,high]");
  }
 
  /**
   * @param rotation the rotation to set
   */
  public void setRotation(double rotation) {
    rotation=rotation%360D;
    //rotation=rotation/360*6.28318525;
   
    this.rotation = (float) rotation;
  }
 
  /**
   * @param saveOption the saveOption to set
   * @throws ApplicationException
   */
  public void setSaveoption(String strSaveOption) throws ApplicationException {
    strSaveOption=StringUtil.toLowerCase(strSaveOption.trim());
    if("full".equals(strSaveOption))      saveOption=SAVE_OPTION_FULL; 
    else if("incremental".equals(strSaveOption))saveOption=SAVE_OPTION_INCREMENTAL; 
    else if("linear".equals(strSaveOption))    saveOption=SAVE_OPTION_LINEAR; 
   
    else throw new ApplicationException("invalid saveOption definition ["+strSaveOption+"], valid saveOption definitions are " +
        "[full,linear,incremental]");
  }
 
  /**
   * @param scale the scale to set
   * @throws ApplicationException
   */
  public void setScale(double scale) throws ApplicationException {
    //if(scale<1 || scale>1000)  this check is now done inside PDF2IMage implementation
    //  throw new ApplicationException("invalid scale definition ["+Caster.toString(scale)+"], value should be in range from 1 to 100");
    this.scale = (int) scale;
  }
 
  /**
   * @param showOnPrint the showOnPrint to set
   */
  public void setShowonprint(boolean showOnPrint) {
    this.showOnPrint = showOnPrint;
  }
 
  /**
   * @param source the source to set
   */
  public void setSource(Object source) {
    this.source = source;
  }
  /**
   * @param stopOnError the stopOnError to set
   */
  public void setStoponerror(boolean stopOnError) {
    this.stopOnError = stopOnError;
  }
  /**
   * @param transparent the transparent to set
   */
  public void setTransparent(boolean transparent) {
    this.transparent = transparent;
  }
  /**
   * @param version the version to set
   * @throws ApplicationException
   */
  public void setVersion(double version) throws ApplicationException {
    if(1.1 == version)      this.version='1'
    else if(1.2 == version)    this.version=PdfWriter.VERSION_1_2; 
    else if(1.3 == version)    this.version=PdfWriter.VERSION_1_3; 
    else if(1.4 == version)    this.version=PdfWriter.VERSION_1_4; 
    else if(1.5 == version)    this.version=PdfWriter.VERSION_1_5; 
    else if(1.6 == version)    this.version=PdfWriter.VERSION_1_6; 
   
    else throw new ApplicationException("invalid version definition ["+Caster.toString(version)+"], valid version definitions are " +
        "[1.1, 1.2, 1.3, 1.4, 1.5, 1.6]");
  }
 
  @Override
  public int doStartTag() throws PageException  {
    // RR SerialNumber sn = pageContext.getConfig().getSerialNumber();
      //if(sn.getVersion()==SerialNumber.VERSION_COMMUNITY)
      //    throw new SecurityException("no access to this functionality with the "+sn.getStringVersion()+" version of railo");
     
      return EVAL_BODY_BUFFERED;
  }

  @Override
  public void doInitBody()  {
   
  }
 
  @Override
  public int doAfterBody()  {
    return SKIP_BODY;
  }
 
  @Override
  public int doEndTag() throws PageException {
    try {

      if(ACTION_ADD_WATERMARK==action)      doActionAddWatermark();
      else if(ACTION_REMOVE_WATERMARK==actiondoActionRemoveWatermark();
      else if(ACTION_READ==action)        doActionRead();
      else if(ACTION_WRITE==action)        doActionWrite();
      else if(ACTION_GET_INFO==action)      doActionGetInfo();
      else if(ACTION_SET_INFO==action)      doActionSetInfo();
      else if(ACTION_MERGE==action)        doActionMerge();
      else if(ACTION_DELETE_PAGES==action)    doActionDeletePages();
      else if(ACTION_PROTECT==action)        doActionProtect();
      else if(ACTION_THUMBNAIL==action)      doActionThumbnail();
      else if(ACTION_EXTRACT_TEXT==action)    {
        if(true)throw new ApplicationException("not supported yet, see https://issues.jboss.org/browse/RAILO-1559");
        doActionExtractText();
      }
     
      //else if(ACTION_PROCESSDDX==action)  throw new ApplicationException("action [processddx] not supported");
     
     
     
    }
    catch (Exception e) {
      throw Caster.toPageException(e);
   
    return EVAL_PAGE;
  }
 
 
 
 
  private void doActionWrite() throws PageException, IOException, DocumentException {
    required("pdf", "write", "source", source);
    required("pdf", "write", "destination", destination);
   
    if(destination.exists() && !overwrite)
      throw new ApplicationException("destination file ["+destination+"] already exists");
   
    PDFDocument doc = toPDFDocument(source, password, null);
    //PdfReader pr = doc.getPdfReader();
    // output
    boolean destIsSource = doc.getResource()!=null && destination.equals(doc.getResource());
   
    OutputStream os=null;
    if(destIsSource){
      os=new ByteArrayOutputStream();
    }
    else if(destination!=null) {
      os=destination.getOutputStream();
    }
   
    try
      PDFUtil.concat(new PDFDocument[]{doc}, os, true, true, true,version);
    }
    finally {
      IOUtil.closeEL(os);
      if(os instanceof ByteArrayOutputStream) {
        if(destination!=null)IOUtil.copy(new ByteArrayInputStream(((ByteArrayOutputStream)os).toByteArray()), destination,true);// MUST overwrite
      }
    }
   
/* 
    // flatten = "yes|no"
      // must saveOption = "linear|incremental|full"
*/
  }



  private void doActionThumbnail() throws PageException, IOException, DocumentException {
    required("pdf", "thumbnail", "source", source);

    PDFDocument doc = toPDFDocument(source, password, null);
    PdfReader pr = doc.getPdfReader();
    boolean isEnc=pr.isEncrypted();
    pr.close();
    if(isEnc) {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      //PDFUtil.concat(new PDFDocument[]{doc}, baos, true, true, true, (char)0);
      PDFUtil.encrypt(doc,baos,null,null,0,PDFUtil.ENCRYPT_NONE);
      baos.close();
      doc = new PDFDocument(baos.toByteArray(),doc.getResource(),null);
    }
   
    doc.setPages(pages);
   
    // scale
    if(scale<1)
      throw new ApplicationException("value of attribute scale ["+scale+"] should be at least 1");
   
    // destination
    if(destination==null)
      destination=ResourceUtil.toResourceNotExisting(pageContext, "thumbnails");
   
    // imagePrefix
    if(imagePrefix==null){
      Resource res = doc.getResource();
      if(res!=null){
        String n = res.getName();
        int index=n.lastIndexOf('.');
        if(index!=-1)imagePrefix=n.substring(0,index);
        else imagePrefix=n;
      }
      else imagePrefix="memory";
    }
   
    // MUST password
    PDFUtil.writeImages(doc.getRaw(), doc.getPages(), destination, imagePrefix, format, scale,overwrite,
        resolution==RESOLUTION_HIGH,transparent);
   
   
   
  }
 
 
 
 
  private void doActionAddWatermark() throws PageException, IOException, DocumentException {
    required("pdf", "addWatermark", "source", source);
    if(copyFrom==null && image==null)
      throw new ApplicationException("at least one of the following attributes must be defined " +
          "[copyFrom,image]");
   
    if(destination!=null && destination.exists() && !overwrite)
      throw new ApplicationException("destination file ["+destination+"] already exists");
   
   
    // image
    Image img=null;
    if(image!=null) {
      railo.runtime.img.Image ri = railo.runtime.img.Image.createImage(pageContext,image,false,false,true,null);
      img=Image.getInstance(ri.getBufferedImage(),null,false);
    }
    // copy From
    else {
      byte[] barr;
      try{
        Resource res = Caster.toResource(pageContext, copyFrom, true);
        barr=IOUtil.toBytes(res);
      }
      catch(ExpressionException ee) {
        barr=Caster.toBinary(copyFrom);
      }
      img=Image.getInstance(PDFUtil.toImage(barr, 1).getBufferedImage(),null,false);
     
    }
   
    // position
    float x=UNDEFINED,y=UNDEFINED;
    if(!StringUtil.isEmpty(position)) {
      int index=position.indexOf(',');
      if(index==-1)
        throw new ApplicationException("attribute [position] has an invalid value ["+position+"]," +
            "value should follow one of the following pattern [40,50], [40,] or [,50]");
      String strX = position.substring(0,index).trim();
      String strY = position.substring(index+1).trim();
      if(!StringUtil.isEmpty(strX))x = Caster.toIntValue(strX);
      if(!StringUtil.isEmpty(strY))y = Caster.toIntValue(strY);
     
    }
   
   
    PDFDocument doc = toPDFDocument(source, password, null);
    doc.setPages(pages);
    PdfReader reader = doc.getPdfReader();
    reader.consolidateNamedDestinations();
    boolean destIsSource = destination!=null && doc.getResource()!=null && destination.equals(doc.getResource());
    java.util.List bookmarks = SimpleBookmark.getBookmark(reader);
      ArrayList master = new ArrayList()
    if(bookmarks!=null)master.addAll(bookmarks);
     
    // output
    OutputStream os=null;
    if(!StringUtil.isEmpty(name) || destIsSource){
      os=new ByteArrayOutputStream();
    }
    else if(destination!=null) {
      os=destination.getOutputStream();
    }
   
    try {
     
      int len = reader.getNumberOfPages();
        PdfStamper stamp = new PdfStamper(reader, os);
       
        if(len >0){
          if(x==UNDEFINED || y==UNDEFINED) {
            PdfImportedPage first = stamp.getImportedPage(reader, 1);
            if(y==UNDEFINED)y=(first.getHeight()-img.getHeight())/2;
            if(x==UNDEFINED)x=(first.getWidth()-img.getWidth())/2;       
          }
          img.setAbsolutePosition(x, y);
          //img.setAlignment(Image.ALIGN_JUSTIFIED); ration geht nicht anhand mitte
         
        }
       
      // rotation
      if(rotation!=0) {
        img.setRotationDegrees(rotation);
      }
     
      Set _pages = doc.getPages();
        for (int i=1;i<=len;i++) {
          if(_pages!=null && !_pages.contains(Integer.valueOf(i))) continue;
          PdfContentByte cb =foreground? stamp.getOverContent(i):stamp.getUnderContent(i);
          PdfGState gs1 = new PdfGState();
          //print.out("op:"+opacity);
          gs1.setFillOpacity(opacity);
          //gs1.setStrokeOpacity(opacity);
            cb.setGState(gs1);
          cb.addImage(img);
        }
        if(bookmarks!=null)stamp.setOutlines(master);
        stamp.close();
    }
    finally {
      IOUtil.closeEL(os);
      if(os instanceof ByteArrayOutputStream) {
        if(destination!=null)IOUtil.copy(new ByteArrayInputStream(((ByteArrayOutputStream)os).toByteArray()), destination,true);// MUST overwrite
        if(!StringUtil.isEmpty(name)){
          pageContext.setVariable(name,new PDFDocument(((ByteArrayOutputStream)os).toByteArray(),password));
        }
      }
    }
  }
 
  private void doActionRemoveWatermark() throws PageException, IOException, DocumentException {
    required("pdf", "removeWatermark", "source", source);
   
    if(destination!=null && destination.exists() && !overwrite)
      throw new ApplicationException("destination file ["+destination+"] already exists");
   
    railo.runtime.img.Image ri = new railo.runtime.img.Image(1,1,BufferedImage.TYPE_INT_RGB,Color.BLACK);
    Image img = Image.getInstance(ri.getBufferedImage(),null,false);
    img.setAbsolutePosition(1,1);
   
   
    PDFDocument doc = toPDFDocument(source, password, null);
    doc.setPages(pages);
    PdfReader reader = doc.getPdfReader();

    boolean destIsSource = destination!=null && doc.getResource()!=null && destination.equals(doc.getResource());
    java.util.List bookmarks = SimpleBookmark.getBookmark(reader);
      ArrayList master = new ArrayList()
    if(bookmarks!=null)master.addAll(bookmarks);
     
    // output
    OutputStream os=null;
    if(!StringUtil.isEmpty(name) || destIsSource){
      os=new ByteArrayOutputStream();
    }
    else if(destination!=null) {
      os=destination.getOutputStream();
    }
   
    try {
      int len = reader.getNumberOfPages();
        PdfStamper stamp = new PdfStamper(reader, os);
     
      Set _pages = doc.getPages();
        for (int i=1;i<=len;i++) {
          if(_pages!=null && !_pages.contains(Integer.valueOf(i))) continue;
          PdfContentByte cb =foreground? stamp.getOverContent(i):stamp.getUnderContent(i);
          PdfGState gs1 = new PdfGState();
            gs1.setFillOpacity(0);
            cb.setGState(gs1);
          cb.addImage(img);
        }
        if(bookmarks!=null)stamp.setOutlines(master);
        stamp.close();
    }
    finally {
      IOUtil.closeEL(os);
      if(os instanceof ByteArrayOutputStream) {
        if(destination!=null)IOUtil.copy(new ByteArrayInputStream(((ByteArrayOutputStream)os).toByteArray()), destination,true);// MUST overwrite
        if(!StringUtil.isEmpty(name)){
          pageContext.setVariable(name,new PDFDocument(((ByteArrayOutputStream)os).toByteArray(),password));
        }
      }
    }
  }
 
  private void doActionDeletePages() throws PageException, IOException, DocumentException {
    required("pdf", "deletePage", "pages", pages,true);
    required("pdf", "deletePage", "source", source);
   
    PDFDocument doc = toPDFDocument(source, password, null);
    doc.setPages(pages);
   
   
    if(destination==null && StringUtil.isEmpty(name)){
      if(doc.getResource()==null)
        throw new ApplicationException("source is not based on a resource, destination attribute is required");
      destination=doc.getResource();
    }
    else if(destination!=null && destination.exists() && !overwrite)
      throw new ApplicationException("destination file ["+destination+"] already exists");
   
    boolean destIsSource = destination!=null && doc.getResource()!=null && destination.equals(doc.getResource());
   
    // output
    OutputStream os=null;
    if(!StringUtil.isEmpty(name) || destIsSource){
      os=new ByteArrayOutputStream();
    }
    else if(destination!=null) {
      os=destination.getOutputStream();
    }
   
    try {
      PDFUtil.concat(new PDFDocument[]{doc}, os, true, true,true,version);
    }
    finally {
      //if(document!=null)document.close();
      IOUtil.closeEL(os);
      if(os instanceof ByteArrayOutputStream) {
        if(destination!=null)IOUtil.copy(new ByteArrayInputStream(((ByteArrayOutputStream)os).toByteArray()), destination,true);// MUST overwrite
        if(!StringUtil.isEmpty(name)){
          pageContext.setVariable(name,new PDFDocument(((ByteArrayOutputStream)os).toByteArray(),password));
        }
      }
    }
  }
 
 
  private void doActionMerge() throws ApplicationException, PageException, IOException, DocumentException {
   
    if(source==null && params==null && directory==null)
      throw new ApplicationException("at least one of the following constellation must be defined" +
          " attribute source, attribute directory or cfpdfparam child tags");
    if(destination==null && StringUtil.isEmpty(name,true))
      throw new ApplicationException("at least one of the following attributes must be defined " +
          "[destination,name]");
    if(destination!=null && !overwrite)
      throw new ApplicationException("destination file ["+destination+"] already exists");
   
    ArrayList docs = new ArrayList();
    PDFDocument doc;
    boolean isListing=false;
   
    // source
    if(source!=null) {
      if(Decision.isArray(source)) {
        Array arr = Caster.toArray(source);
        int len = arr.size();
        for(int i=1;i<=len;i++) {
          docs.add(doc=toPDFDocument(arr.getE(i),password,null));
          doc.setPages(pages);
        }
      }
      else if(source instanceof String) {
        String[] sources = ListUtil.toStringArrayTrim(ListUtil.listToArrayRemoveEmpty((String)source, ','));
        for(int i=0;i<sources.length;i++) {
          docs.add(doc=toPDFDocument(sources[i],password,null));
          doc.setPages(pages);
        }
      }
      else docs.add(toPDFDocument(source,password,null));
     
    }
    boolean destIsSource = false;
   
    // params
    if(directory!=null && !directory.isDirectory()) {
      if(!directory.exists())
        throw new ApplicationException("defined attribute directory does not exist");
      throw new ApplicationException("defined attribute directory is not a directory");
    }
    if(params!=null) {
      Iterator it = params.iterator();
      PDFParamBean param;
      while(it.hasNext()) {
        param=(PDFParamBean) it.next();
        docs.add(doc=toPDFDocument(param.getSource(), param.getPassword(),directory));
        doc.setPages(param.getPages());
      }
    }
    else if(directory!=null) {
      isListing=true;
      Resource[] children = ResourceUtil.listResources(directory, filter);
     
      if(ascending) {
        for(int i=children.length-1;i>=0;i--) {
          if(destination!=null && children[i].equals(destination))  destIsSource=true;
          docs.add(doc=toPDFDocument(children[i],password,null));
          doc.setPages(pages);
        }
      }
      else {
        for(int i=0;i<children.length;i++) {
          if(destination!=null && children[i].equals(destination))  destIsSource=true;
          docs.add(doc=toPDFDocument(children[i],password,null));
          doc.setPages(pages);
        }
      }
     
    }
   
    int doclen=docs.size();
    if(doclen==0)
      throw new ApplicationException("you have to define at leat 1 pdf file");
   
    // output
    OutputStream os=null;
    if(!StringUtil.isEmpty(name) || destIsSource){
      os=new ByteArrayOutputStream();
    }
    else if(destination!=null) {
      os=destination.getOutputStream();
    }
   
   
    /*com.lowagie.text.Document document=null;
    PdfCopy copy=null;
    PdfReader pr;
    Set pages;
    int size;*/
   
   
    try {
      if(!isListing)stopOnError=true;
      PDFUtil.concat((PDFDocument[]) docs.toArray(new PDFDocument[docs.size()]), os, keepBookmark, false,stopOnError,version);
      /*
      boolean init=false;
      for(int d=0;d<doclen;d++) {
        doc=(PDFDocument) docs.get(d);
        pages=doc.getPages();
        try {
          pr=doc.getPdfReader();
          print.out(pr.getCatalog().getKeys());
         
        }
        catch(Throwable t) {
          if(isListing && !stopOnError)continue;
          throw Caster.toPageException(t);
        }
        print.out("d+"+d);
        if(!init) {
          init=true;
          print.out("set");
          document = new com.lowagie.text.Document(pr.getPageSizeWithRotation(1));
          copy = new PdfCopy(document,os);
          document.open();
        }
        size=pr.getNumberOfPages();
        print.out("pages:"+size);
        for(int page=1;page<=size;page++) {
          if(pages==null || pages.contains(Constants.Integer(page))) {
            copy.addPage(copy.getImportedPage(pr, page));
          }
        }
      }*/
    }
    finally {
      //if(document!=null)document.close();
      IOUtil.closeEL(os);
      if(os instanceof ByteArrayOutputStream) {
        if(destination!=null)IOUtil.copy(new ByteArrayInputStream(((ByteArrayOutputStream)os).toByteArray()), destination,true);// MUST overwrite
        if(!StringUtil.isEmpty(name))pageContext.setVariable(name, ((ByteArrayOutputStream)os).toByteArray());
      }
     
    }
   
   
  }
  private void doActionRead() throws PageException {
    required("pdf", "read", "name", name,true);
    required("pdf", "read", "source", source);
   
    pageContext.setVariable(name, toPDFDocument(source,password,null));
  }
 
  private void doActionProtect() throws PageException, IOException, DocumentException {
    required("pdf", "protect", "source", source);
   
    if(StringUtil.isEmpty(newUserPassword) && StringUtil.isEmpty(newOwnerPassword))
      throw new ApplicationException("at least one of the following attributes must be defined [newUserPassword,newOwnerPassword]");
       
   
    PDFDocument doc = toPDFDocument(source,password,null);
   
    if(destination==null){
      destination=doc.getResource();
      if(destination==null)
        throw new ApplicationException("source is not based on a resource, destination file is required");
    }
    else if(destination.exists() && !overwrite)
      throw new ApplicationException("destination file ["+destination+"] already exists");
   
    boolean destIsSource = doc.getResource()!=null && destination.equals(doc.getResource());
   
    // output
    OutputStream os=null;
    if(destIsSource){
      os=new ByteArrayOutputStream();
    }
    else {
      os=destination.getOutputStream();
    }
   
   
    try{
      PDFUtil.encrypt(doc,os,newUserPassword,newOwnerPassword,permissions,encrypt);
    }
    finally {
      IOUtil.closeEL(os);
      if(os instanceof ByteArrayOutputStream) {
        IOUtil.copy(new ByteArrayInputStream(((ByteArrayOutputStream)os).toByteArray()), destination,true);// MUST overwrite
      }
     
    }
   
  }
 

 

  private void doActionSetInfo() throws PageException, IOException, DocumentException {
    required("pdf", "setInfo", "info", info);
    required("pdf", "getInfo", "source", source);
   
    PDFDocument doc = toPDFDocument(source,password,null);
    PdfReader pr = doc.getPdfReader();
    OutputStream os=null;
    try {
      if(destination==null){
        if(doc.getResource()==null)
          throw new ApplicationException("source is not based on a resource, destination file is required");
        destination=doc.getResource();
      }
      else if(destination.exists() && !overwrite)
        throw new ApplicationException("destination file ["+destination+"] already exists");
     
      PdfStamper stamp = new PdfStamper(pr, os=destination.getOutputStream());
      HashMap moreInfo = new HashMap();
           
      //Key[] keys = info.keys();
      Iterator<Entry<Key, Object>> it = info.entryIterator();
      Entry<Key, Object> e;
      while(it.hasNext()) {
        e = it.next();
        moreInfo.put(StringUtil.ucFirst(e.getKey().getLowerString()), Caster.toString(e.getValue()));
      }
      // author
      Object value = info.get(KeyConstants._author, null)
      if(value!=null)moreInfo.put("Author", Caster.toString(value));
      // keywords
      value = info.get("keywords", null)
      if(value!=null)moreInfo.put("Keywords", Caster.toString(value));
      // title
      value = info.get(KeyConstants._title, null)
      if(value!=null)moreInfo.put("Title", Caster.toString(value));
      // subject
      value = info.get(KeyConstants._subject, null)
      if(value!=null)moreInfo.put("Subject", Caster.toString(value));
      // creator
      value = info.get("creator", null)
      if(value!=null)moreInfo.put("Creator", Caster.toString(value));
      // trapped
      value = info.get("Trapped", null)
      if(value!=null)moreInfo.put("Trapped", Caster.toString(value));
      // Created
      value = info.get("Created", null)
      if(value!=null)moreInfo.put("Created", Caster.toString(value));
      // Language
      value = info.get("Language", null)
      if(value!=null)moreInfo.put("Language", Caster.toString(value));
     
     
      stamp.setMoreInfo(moreInfo);
      stamp.close();
     
    }
    finally {
      IOUtil.closeEL(os);
      pr.close();
    }
  }
 
  private void doActionGetInfo() throws PageException {
    required("pdf", "getInfo", "name", name,true);
    required("pdf", "getInfo", "source", source);
   
    PDFDocument doc = toPDFDocument(source,password,null);
    pageContext.setVariable(name, doc.getInfo());
   
  }
  private void doActionExtractText() throws PageException, IOException, CryptographyException, InvalidPasswordException {
    required("pdf", "extractText", "name", name,true);
   
    PDFDocument doc = toPDFDocument(source,password,null);
    doc.setPages(pages);
   
    pageContext.setVariable(name, PDFUtil.extractText(doc,doc.getPages()));
    /*
     <cfpdf
required
    action="extracttext" <!---extract all the words in the PDF.--->
    ***source= "absolute or relative path of the PDF file|PDF document variable|
            cfdocument variable"
    pages = "*" <!----page numbers from where the text needs to be extracted from the
                PDF document--->

optional
    addquads = "add the position or quadrants for the text in the PDF"
    honourspaces = "true|false"
    overwrite = "true" <!---Overwrite the specified object in the PDF document--->
    ***password = "" <!--- PDF document password--->
    type = "string|xml" <!---format in which the text needs to be extracted--->
    one of the following:
    destination = "PDF output file pathname"
    name = "PDF document variable"
    usestructure = "true|false"
     * */
  }
 
  private Object allowed(boolean encrypted, int permissions, int permission) {
    return (!encrypted || (permissions&permission)>0)?"Allowed":"Not Allowed";
  }
 

  private PDFDocument toPDFDocument(Object source,String password, Resource directory) throws PageException {
   
    if(source instanceof PDFDocument)
      return (PDFDocument)source;
    if(Decision.isBinary(source)){
      return new PDFDocument(Caster.toBinary(source),password);
    }
    if(source instanceof Resource){
      return new PDFDocument((Resource) source,password);
    }
    if(source instanceof String){
      if(directory!=null) {
        Resource res = directory.getRealResource((String)source);
        if(!res.isFile()){
          Resource res2 = ResourceUtil.toResourceNotExisting(pageContext, (String)source);
          if(res2.isFile())
            res=res2;
          else
            throw new ExpressionException("file or directory "+res+" not exist");
        }
        return new PDFDocument(res,password)
      }
      return new PDFDocument(ResourceUtil.toResourceExisting(pageContext, (String)source),password)
    }
   
    throw new CasterException(source,PdfReader.class);
  }
 
  /*private byte[] toBinary(Object source) throws ExpressionException, IOException {
   
    if(source instanceof PDFDocument)
      return toBinary(((PDFDocument)source).getResource());
    if(Decision.isBinary(source)){
      return Caster.toBinary(source);
    }
    if(source instanceof Resource){
      return IOUtil.toBytes((Resource)source);
    }
    if(source instanceof String){
      if(directory!=null) {
        Resource res = directory.getRealResource((String)source);
        if(!res.isFile()){
          Resource res2 = ResourceUtil.toResourceNotExisting(pageContext, (String)source);
          if(res2.isFile())
            res=res2;
          else
            throw new ExpressionException("file or directory "+res+" not exist");
        }
        return IOUtil.toBytes(res); 
      }
      return IOUtil.toBytes(ResourceUtil.toResourceExisting(pageContext, (String)source)); 
    }
   
    throw new CasterException(source,PdfReader.class);
  }*/
 
  protected void setParam(PDFParamBean param) {
    if(params==null)
      params=new ArrayList<PDFParamBean>();
    params.add(param);
  }
 
 
 

}
TOP

Related Classes of railo.runtime.tag.PDF

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.