All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jpedal.io.PdfReader Maven / Gradle / Ivy

The newest version!
/*
 * ===========================================
 * Java Pdf Extraction Decoding Access Library
 * ===========================================
 *
 * Project Info:  http://www.idrsolutions.com
 * Help section for developers at http://www.idrsolutions.com/java-pdf-library-support/
 *
 * (C) Copyright 1997-2013, IDRsolutions and Contributors.
 *
 * 	This file is part of JPedal
 *
     This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


 *
 * ---------------
 * PdfReader.java
 * ---------------
 */
package org.jpedal.io;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.stream.ImageInputStream;

import org.jpedal.exception.PdfException;
import org.jpedal.objects.Javascript;
import org.jpedal.objects.PageLookup;
import org.jpedal.objects.raw.FDFObject;
import org.jpedal.objects.raw.PageObject;
import org.jpedal.objects.raw.PdfDictionary;
import org.jpedal.objects.raw.PdfObject;
import org.jpedal.utils.LogWriter;

public class PdfReader implements PdfObjectReader, Serializable {

	private static final long serialVersionUID = 9005615362777773174L;

	private PdfFileReader objectReader = new PdfFileReader();

	/**
	 * holds pdf id (ie 4 0 R) which stores each object
	 */
	Map pagesReferences = new HashMap();

	/**
	 * page lookup table using objects as key
	 */
	private PageLookup pageLookup = new PageLookup();

	/** file length */
	private long eof = 0;

	private String tempFileName = null;

	/** names lookup table */
	private NameLookup nameLookup = null;

	RandomAccessBuffer pdf_datafile = null;

	public PdfReader() {}

	/**
	 * set password as well
	 * 
	 * @param password
	 */
	public PdfReader(String password) {
		super();

		if (password == null) password = "";

		this.objectReader.setPassword(password);
	}

	public PdfReader(Certificate certificate, PrivateKey key) {

		this.objectReader.setCertificate(certificate, key);
	}

	/**
	 * reference for Page object
	 * 
	 * @param page
	 * @return String ref (ie 1 0 R) pdfObject=new PageObject(currentPageOffset); currentPdfFile.readObject(pdfObject);
	 */
	@Override
	public String getReferenceforPage(int page) {
		return (String) this.pagesReferences.get(page);
	}

	/**
	 * close the file
	 */
	@Override
	final public void closePdfFile() {
		try {
			this.objectReader.closeFile();

			if (this.pdf_datafile != null) this.pdf_datafile.close();

			// ensure temp file deleted
			if (this.tempFileName != null) {
				File fileToDelete = new File(this.tempFileName);
				fileToDelete.delete();
				this.tempFileName = null;
			}
		}
		catch (Exception e) {
			if (LogWriter.isOutput()) LogWriter.writeLog("Exception " + e + " closing file");
		}
	}

	/**
	 * allow user to access SOME PDF objects currently PdfDictionary.Encryption
	 */
	@Override
	public PdfObject getPDFObject(int key) {

		if (key == PdfDictionary.Encrypt) {
			return this.objectReader.encyptionObj;
		}
		else throw new RuntimeException("Access to " + key + " not supported");
	}

	@Override
	public PdfFileReader getObjectReader() {
		return this.objectReader;
	}

	/**
	 * convert name into object ref
	 */
	@Override
	public String convertNameToRef(String value) {

		// see if decoded
		if (this.nameLookup == null) return null;
		else return (String) this.nameLookup.get(value);
	}

	// /////////////////////////////////////////////////////////////////////////

	/**
	 * read FDF
	 */
	@Override
	final public PdfObject readFDF() throws PdfException {

		PdfObject fdfObj;

		try {

			byte[] fileData = this.objectReader.readFDFData();

			fdfObj = new FDFObject("1 0 R");

			// find /FDF key
			int ii = 0;
			while (ii < this.eof) {
				if (fileData[ii] == '/' && fileData[ii + 1] == 'F' && fileData[ii + 2] == 'D' && fileData[ii + 3] == 'F') break;

				ii++;
			}

			ii = ii + 4;

			// move beyond <<
			while (ii < this.eof) {
				if (fileData[ii] == '<' && fileData[ii + 1] == '<') break;

				ii++;
			}
			ii = ii + 2;
			ObjectDecoder objectDecoder = new ObjectDecoder(this.objectReader);
			objectDecoder.readDictionaryAsObject(fdfObj, ii, fileData);

		}
		catch (Exception e) {
			try {
				this.objectReader.closeFile();
			}
			catch (IOException e1) {
				if (LogWriter.isOutput()) LogWriter.writeLog("Exception " + e + " closing file");
			}

			throw new PdfException("Exception " + e + " reading trailer");
		}

		return fdfObj;
	}

	/**
	 * read any names into names lookup
	 */
	@Override
	public void readNames(PdfObject nameObject, Javascript javascript, boolean isKid) {

		this.nameLookup = new NameLookup(this.objectReader);
		this.nameLookup.readNames(nameObject, javascript, isKid);
	}

	/**
	 * given a ref, what is the page
	 * 
	 * @param ref
	 *            - PDF object reference
	 * @return - page number with being first page
	 */
	@Override
	public int convertObjectToPageNumber(String ref) {
		return this.pageLookup.convertObjectToPageNumber(ref);
	}

	@Override
	public void setLookup(String currentPageOffset, int tempPageCount) {
		this.pageLookup.put(currentPageOffset, tempPageCount);
		this.pagesReferences.put(tempPageCount, currentPageOffset);
	}

	@Override
	public void dispose() {

		// this.objData=null;
		// this.lastRef=null;

		this.nameLookup = null;

		// this.fields=null;

		if (this.objectReader != null) this.objectReader.dispose();
		this.objectReader = null;

		if (this.pageLookup != null) this.pageLookup.dispose();
		this.pageLookup = null;
	}

	/**
	 * open pdf file
* Only files allowed (not http) so we can handle Random Access of pdf */ @Override final public void openPdfFile(InputStream in) throws PdfException { try { // use byte[] directly if small otherwise use Memory Map this.pdf_datafile = new RandomAccessMemoryMapBuffer(in); this.objectReader.init(this.pdf_datafile); this.eof = this.pdf_datafile.length(); // pdf_datafile = new RandomAccessFile( filename, "r" ); } catch (Exception e) { if (LogWriter.isOutput()) LogWriter.writeLog("Exception " + e + " accessing file"); throw new PdfException("Exception " + e + " accessing file"); } } /** * open pdf file
* Only files allowed (not http) so we can handle Random Access of pdf */ @Override final public void openPdfFile(ImageInputStream iis) throws PdfException { RandomAccessBuffer pdf_datafile; try { // use byte[] directly if small otherwise use Memory Map pdf_datafile = new ImageInputStreamFileBuffer(iis); // pdf_datafile = new RandomAccessFileBuffer( filename, "r" ); // pdf_datafile = new RandomAccessFCTest( new FileInputStream(filename)); this.objectReader.init(pdf_datafile); this.eof = pdf_datafile.length(); } catch (Exception e) { if (LogWriter.isOutput()) LogWriter.writeLog("Exception " + e + " accessing file"); throw new PdfException("Exception " + e + " accessing file"); } } @Override public void checkParentForResources(PdfObject pdfObject) { /** * if no resource, check parent for one (in theory should recurse up whole tree) */ if (pdfObject.getDictionary(PdfDictionary.Resources) == null) { String parent = pdfObject.getStringKey(PdfDictionary.Parent); if (parent != null) { PdfObject parentObj = new PageObject(parent); readObject(parentObj); PdfObject resObj = parentObj.getDictionary(PdfDictionary.Resources); if (resObj != null) { pdfObject.setDictionary(PdfDictionary.Resources, resObj); } } } } /** * open pdf file
* Only files allowed (not http) so we can handle Random Access of pdf */ @Override final public void openPdfFile(String filename) throws PdfException { RandomAccessBuffer pdf_datafile; try { pdf_datafile = new RandomAccessFileBuffer(filename, "r"); // pdf_datafile = new RandomAccessFCTest( new FileInputStream(filename)); this.objectReader.init(pdf_datafile); this.eof = pdf_datafile.length(); } catch (Exception e) { if (LogWriter.isOutput()) LogWriter.writeLog("Exception " + e + " accessing file"); throw new PdfException("Exception " + e + " accessing file"); } } /** * open pdf file using a byte stream - By default files under 16384 bytes are cached to disk but this can be altered by setting * PdfFileReader.alwaysCacheInMemory to a maximimum size or -1 (always keep in memory) */ @Override final public void openPdfFile(byte[] data) throws PdfException { RandomAccessBuffer pdf_datafile; try { // use byte[] directly if small otherwise use Memory Map if (PdfFileReader.alwaysCacheInMemory == -1 || data.length < PdfFileReader.alwaysCacheInMemory) pdf_datafile = new RandomAccessDataBuffer( data); else { // cache as file and access via RandomAccess // pdf_datafile = new RandomAccessMemoryMapBuffer( data ); old version very slow try { File file = File.createTempFile("page", ".bin", new File(ObjectStore.temp_dir)); this.tempFileName = file.getAbsolutePath(); // file.deleteOnExit(); java.io.FileOutputStream a = new java.io.FileOutputStream(file); a.write(data); a.flush(); a.close(); pdf_datafile = new RandomAccessFileBuffer(this.tempFileName, "r"); } catch (Exception e) { throw new RuntimeException("Unable to create temporary file in " + ObjectStore.temp_dir); } } this.objectReader.init(pdf_datafile); this.eof = pdf_datafile.length(); // pdf_datafile = new RandomAccessFile( filename, "r" ); } catch (Exception e) { if (LogWriter.isOutput()) LogWriter.writeLog("Exception " + e + " accessing file"); throw new PdfException("Exception " + e + " accessing file"); } } /** handle onto JS object */ private Javascript javascript; /** pass in Javascript object from JPedal */ public void setJavaScriptObject(Javascript javascript) { this.javascript = javascript; } @Override public void checkResolved(PdfObject pdfObject) { ObjectDecoder objectDecoder = new ObjectDecoder(this.objectReader); objectDecoder.checkResolved(pdfObject); } @Override public byte[] readStream(PdfObject obj, boolean cacheValue, boolean decompress, boolean keepRaw, boolean isMetaData, boolean isCompressedStream, String cacheFile) { return this.objectReader.readStream(obj, cacheValue, decompress, keepRaw, isMetaData, isCompressedStream, cacheFile); } @Override public void readObject(PdfObject pdfObject) { this.objectReader.readObject(pdfObject); } /** * return type of encryption as Enum in EncryptionUsed */ @Override public EncryptionUsed getEncryptionType() { PdfFileReader objectReader = this.objectReader; DecryptionFactory decryption = objectReader.getDecryptionObject(); if (decryption == null) { return EncryptionUsed.NO_ENCRYPTION; } else if (decryption.hasPassword()) { return EncryptionUsed.PASSWORD; } else // cert by process of elimination return EncryptionUsed.CERTIFICATE; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy