Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* $Id: PDFObject.java,v 1.8 2009/03/15 20:47:38 tomoke Exp $
*
* Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
* Santa Clara, California 95054, U.S.A. All rights reserved.
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package com.sun.pdfview;
import java.io.IOException;
import java.lang.ref.SoftReference;
import java.nio.ByteBuffer;
import java.util.*;
import com.sun.pdfview.decode.PDFDecoder;
import com.sun.pdfview.decrypt.PDFDecrypter;
import com.sun.pdfview.decrypt.IdentityDecrypter;
/**
* a class encapsulating all the possibilities of content for
* an object in a PDF file.
*
* A PDF object can be a simple type, like a Boolean, a Number,
* a String, or the Null value. It can also be a NAME, which
* looks like a string, but is a special type in PDF files, like
* "/Name".
*
* A PDF object can also be complex types, including Array;
* Dictionary; Stream, which is a Dictionary plus an array of
* bytes; or Indirect, which is a reference to some other
* PDF object. Indirect references will always be dereferenced
* by the time any data is returned from one of the methods
* in this class.
*
* @author Mike Wessler
*/
public class PDFObject {
/** an indirect reference*/
public static final int INDIRECT = 0; // PDFXref
/** a Boolean */
public static final int BOOLEAN = 1; // Boolean
/** a Number, represented as a double */
public static final int NUMBER = 2; // Double
/** a String */
public static final int STRING = 3; // String
/** a special string, seen in PDF files as /Name */
public static final int NAME = 4; // String
/** an array of PDFObjects */
public static final int ARRAY = 5; // Array of PDFObject
/** a Hashmap that maps String names to PDFObjects */
public static final int DICTIONARY = 6; // HashMap(String->PDFObject)
/** a Stream: a Hashmap with a byte array */
public static final int STREAM = 7; // HashMap + byte[]
/** the NULL object (there is only one) */
public static final int NULL = 8; // null
/** a special PDF bare word, like R, obj, true, false, etc */
public static final int KEYWORD = 9; // String
/**
* When a value of {@link #getObjGen objNum} or {@link #getObjGen objGen},
* indicates that the object is not top-level, and is embedded in another
* object
*/
public static final int OBJ_NUM_EMBEDDED = -2;
/**
* When a value of {@link #getObjGen objNum} or {@link #getObjGen objGen},
* indicates that the object is not top-level, and is embedded directly
* in the trailer.
*/
public static final int OBJ_NUM_TRAILER = -1;
/** the NULL PDFObject */
public static final PDFObject nullObj = new PDFObject(null, NULL, null);
/** the type of this object */
private int type;
/** the value of this object. It can be a wide number of things, defined by type */
private Object value;
/** the encoded stream, if this is a STREAM object */
private ByteBuffer stream;
/** a cached version of the decoded stream */
private SoftReference decodedStream;
/**
* the PDFFile from which this object came, used for
* dereferences
*/
private PDFFile owner;
/**
* a cache of translated data. This data can be
* garbage collected at any time, after which it will
* have to be rebuilt.
*/
private SoftReference cache;
/** @see #getObjNum() */
private int objNum = OBJ_NUM_EMBEDDED;
/** @see #getObjGen() */
private int objGen = OBJ_NUM_EMBEDDED;
/**
* create a new simple PDFObject with a type and a value
* @param owner the PDFFile in which this object resides, used
* for dereferencing. This may be null.
* @param type the type of object
* @param value the value. For DICTIONARY, this is a HashMap.
* for ARRAY it's an ArrayList. For NUMBER, it's a Double.
* for BOOLEAN, it's Boolean.TRUE or Boolean.FALSE. For
* everything else, it's a String.
*/
public PDFObject(PDFFile owner, int type, Object value) {
this.type = type;
if (type == NAME) {
value = ((String) value).intern();
} else if (type == KEYWORD && value.equals("true")) {
this.type = BOOLEAN;
value = Boolean.TRUE;
} else if (type == KEYWORD && value.equals("false")) {
this.type = BOOLEAN;
value = Boolean.FALSE;
}
this.value = value;
this.owner = owner;
}
/**
* create a new PDFObject that is the closest match to a
* given Java object. Possibilities include Double, String,
* PDFObject[], HashMap, Boolean, or PDFParser.Tok,
* which should be "true" or "false" to turn into a BOOLEAN.
*
* @param obj the sample Java object to convert to a PDFObject.
* @throws PDFParseException if the object isn't one of the
* above examples, and can't be turned into a PDFObject.
*/
public PDFObject(Object obj) throws PDFParseException {
this.owner = null;
this.value = obj;
if ((obj instanceof Double) || (obj instanceof Integer)) {
this.type = NUMBER;
} else if (obj instanceof String) {
this.type = NAME;
} else if (obj instanceof PDFObject[]) {
this.type = ARRAY;
} else if (obj instanceof Object[]) {
Object[] srcary = (Object[]) obj;
PDFObject[] dstary = new PDFObject[srcary.length];
for (int i = 0; i < srcary.length; i++) {
dstary[i] = new PDFObject(srcary[i]);
}
value = dstary;
this.type = ARRAY;
} else if (obj instanceof HashMap) {
this.type = DICTIONARY;
} else if (obj instanceof Boolean) {
this.type = BOOLEAN;
} else if (obj instanceof PDFParser.Tok) {
PDFParser.Tok tok = (PDFParser.Tok) obj;
if (tok.name.equals("true")) {
this.value = Boolean.TRUE;
this.type = BOOLEAN;
} else if (tok.name.equals("false")) {
this.value = Boolean.FALSE;
this.type = BOOLEAN;
} else {
this.value = tok.name;
this.type = NAME;
}
} else {
throw new PDFParseException("Bad type for raw PDFObject: " + obj);
}
}
/**
* create a new PDFObject based on a PDFXref
* @param owner the PDFFile from which the PDFXref was drawn
* @param xref the PDFXref to turn into a PDFObject
*/
public PDFObject(PDFFile owner, PDFXref xref) {
this.type = INDIRECT;
this.value = xref;
this.owner = owner;
}
/**
* get the type of this object. The object will be
* dereferenced, so INDIRECT will never be returned.
* @return the type of the object
*/
public int getType() throws IOException {
if (type == INDIRECT) {
return dereference().getType();
}
return type;
}
/**
* set the stream of this object. It should have been
* a DICTIONARY before the call.
* @param data the data, as a ByteBuffer.
*/
public void setStream(ByteBuffer data) {
this.type = STREAM;
this.stream = data;
}
/**
* get the value in the cache. May become null at any time.
* @return the cached value, or null if the value has been
* garbage collected.
*/
public Object getCache() throws IOException {
if (type == INDIRECT) {
return dereference().getCache();
} else if (cache != null) {
return cache.get();
} else {
return null;
}
}
/**
* set the cached value. The object may be garbage collected
* if no other reference exists to it.
* @param obj the object to be cached
*/
public void setCache(Object obj) throws IOException {
if (type == INDIRECT) {
dereference().setCache(obj);
return;
} else {
cache = new SoftReference