001/* 002 * $Id: PdfObject.java 4784 2011-03-15 08:33:00Z blowagie $ 003 * 004 * This file is part of the iText (R) project. 005 * Copyright (c) 1998-2011 1T3XT BVBA 006 * Authors: Bruno Lowagie, Paulo Soares, et al. 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU Affero General Public License version 3 010 * as published by the Free Software Foundation with the addition of the 011 * following permission added to Section 15 as permitted in Section 7(a): 012 * FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY 1T3XT, 013 * 1T3XT DISCLAIMS THE WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. 014 * 015 * This program is distributed in the hope that it will be useful, but 016 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 017 * or FITNESS FOR A PARTICULAR PURPOSE. 018 * See the GNU Affero General Public License for more details. 019 * You should have received a copy of the GNU Affero General Public License 020 * along with this program; if not, see http://www.gnu.org/licenses or write to 021 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 022 * Boston, MA, 02110-1301 USA, or download the license from the following URL: 023 * http://itextpdf.com/terms-of-use/ 024 * 025 * The interactive user interfaces in modified source and object code versions 026 * of this program must display Appropriate Legal Notices, as required under 027 * Section 5 of the GNU Affero General Public License. 028 * 029 * In accordance with Section 7(b) of the GNU Affero General Public License, 030 * a covered work must retain the producer line in every PDF that is created 031 * or manipulated using iText. 032 * 033 * You can be released from the requirements of the license by purchasing 034 * a commercial license. Buying such a license is mandatory as soon as you 035 * develop commercial activities involving the iText software without 036 * disclosing the source code of your own applications. 037 * These activities include: offering paid services to customers as an ASP, 038 * serving PDFs on the fly in a web application, shipping iText with a closed 039 * source product. 040 * 041 * For more information, please contact iText Software Corp. at this 042 * address: sales@itextpdf.com 043 */ 044package com.itextpdf.text.pdf; 045import java.io.IOException; 046import java.io.OutputStream; 047 048/** 049 * <CODE>PdfObject</CODE> is the abstract superclass of all PDF objects. 050 * <P> 051 * PDF supports seven basic types of objects: Booleans, numbers, strings, names, 052 * arrays, dictionaries and streams. In addition, PDF provides a null object. 053 * Objects may be labeled so that they can be referred to by other objects.<BR> 054 * All these basic PDF objects are described in the 'Portable Document Format 055 * Reference Manual version 1.3' Chapter 4 (pages 37-54). 056 * 057 * @see PdfNull 058 * @see PdfBoolean 059 * @see PdfNumber 060 * @see PdfString 061 * @see PdfName 062 * @see PdfArray 063 * @see PdfDictionary 064 * @see PdfStream 065 * @see PdfIndirectReference 066 */ 067public abstract class PdfObject { 068 069 // CONSTANTS 070 071 /** A possible type of <CODE>PdfObject</CODE> */ 072 public static final int BOOLEAN = 1; 073 074 /** A possible type of <CODE>PdfObject</CODE> */ 075 public static final int NUMBER = 2; 076 077 /** A possible type of <CODE>PdfObject</CODE> */ 078 public static final int STRING = 3; 079 080 /** A possible type of <CODE>PdfObject</CODE> */ 081 public static final int NAME = 4; 082 083 /** A possible type of <CODE>PdfObject</CODE> */ 084 public static final int ARRAY = 5; 085 086 /** A possible type of <CODE>PdfObject</CODE> */ 087 public static final int DICTIONARY = 6; 088 089 /** A possible type of <CODE>PdfObject</CODE> */ 090 public static final int STREAM = 7; 091 092 /** A possible type of <CODE>PdfObject</CODE> */ 093 public static final int NULL = 8; 094 095 /** A possible type of <CODE>PdfObject</CODE> */ 096 public static final int INDIRECT = 10; 097 098 /** An empty string used for the <CODE>PdfNull</CODE>-object and for an empty <CODE>PdfString</CODE>-object. */ 099 public static final String NOTHING = ""; 100 101 /** 102 * This is the default encoding to be used for converting Strings into 103 * bytes and vice versa. The default encoding is PdfDocEncoding. 104 */ 105 public static final String TEXT_PDFDOCENCODING = "PDF"; 106 107 /** This is the encoding to be used to output text in Unicode. */ 108 public static final String TEXT_UNICODE = "UnicodeBig"; 109 110 // CLASS VARIABLES 111 112 /** The content of this <CODE>PdfObject</CODE> */ 113 protected byte[] bytes; 114 115 /** The type of this <CODE>PdfObject</CODE> */ 116 protected int type; 117 118 /** Holds the indirect reference. */ 119 protected PRIndirectReference indRef; 120 121 // CONSTRUCTORS 122 123 /** 124 * Constructs a <CODE>PdfObject</CODE> of a certain <VAR>type</VAR> 125 * without any <VAR>content</VAR>. 126 * 127 * @param type type of the new <CODE>PdfObject</CODE> 128 */ 129 protected PdfObject(int type) { 130 this.type = type; 131 } 132 133 /** 134 * Constructs a <CODE>PdfObject</CODE> of a certain <VAR>type</VAR> 135 * with a certain <VAR>content</VAR>. 136 * 137 * @param type type of the new <CODE>PdfObject</CODE> 138 * @param content content of the new <CODE>PdfObject</CODE> as a 139 * <CODE>String</CODE>. 140 */ 141 protected PdfObject(int type, String content) { 142 this.type = type; 143 bytes = PdfEncodings.convertToBytes(content, null); 144 } 145 146 /** 147 * Constructs a <CODE>PdfObject</CODE> of a certain <VAR>type</VAR> 148 * with a certain <VAR>content</VAR>. 149 * 150 * @param type type of the new <CODE>PdfObject</CODE> 151 * @param bytes content of the new <CODE>PdfObject</CODE> as an array of 152 * <CODE>byte</CODE>. 153 */ 154 protected PdfObject(int type, byte[] bytes) { 155 this.bytes = bytes; 156 this.type = type; 157 } 158 159 // methods dealing with the content of this object 160 161 /** 162 * Writes the PDF representation of this <CODE>PdfObject</CODE> as an 163 * array of <CODE>byte</CODE>s to the writer. 164 * 165 * @param writer for backwards compatibility 166 * @param os The <CODE>OutputStream</CODE> to write the bytes to. 167 * @throws IOException 168 */ 169 public void toPdf(PdfWriter writer, OutputStream os) throws IOException { 170 if (bytes != null) 171 os.write(bytes); 172 } 173 174 /** 175 * Returns the <CODE>String</CODE>-representation of this 176 * <CODE>PdfObject</CODE>. 177 * 178 * @return a <CODE>String</CODE> 179 */ 180 public String toString() { 181 if (bytes == null) 182 return super.toString(); 183 return PdfEncodings.convertToString(bytes, null); 184 } 185 186 /** 187 * Gets the presentation of this object in a byte array 188 * 189 * @return a byte array 190 */ 191 public byte[] getBytes() { 192 return bytes; 193 } 194 195 /** 196 * Whether this object can be contained in an object stream. 197 * 198 * PdfObjects of type STREAM OR INDIRECT can not be contained in an 199 * object stream. 200 * 201 * @return <CODE>true</CODE> if this object can be in an object stream. 202 * Otherwise <CODE>false</CODE> 203 */ 204 public boolean canBeInObjStm() { 205 switch (type) { 206 case NULL: 207 case BOOLEAN: 208 case NUMBER: 209 case STRING: 210 case NAME: 211 case ARRAY: 212 case DICTIONARY: 213 return true; 214 case STREAM: 215 case INDIRECT: 216 default: 217 return false; 218 } 219 } 220 221 /** 222 * Returns the length of the PDF representation of the <CODE>PdfObject</CODE>. 223 * <P> 224 * In some cases, namely for <CODE>PdfString</CODE> and <CODE>PdfStream</CODE>, 225 * this method differs from the method <CODE>length</CODE> because <CODE>length</CODE> 226 * returns the length of the actual content of the <CODE>PdfObject</CODE>.</P> 227 * <P> 228 * Remark: the actual content of an object is in most cases identical to its representation. 229 * The following statement is always true: length() >= pdfLength().</P> 230 * 231 * @return a length 232 */ 233// public int pdfLength() { 234// return toPdf(null).length; 235// } 236 237 /** 238 * Returns the length of the actual content of the <CODE>PdfObject</CODE>. 239 * <P> 240 * In some cases, namely for <CODE>PdfString</CODE> and <CODE>PdfStream</CODE>, 241 * this method differs from the method <CODE>pdfLength</CODE> because <CODE>pdfLength</CODE> 242 * returns the length of the PDF representation of the object, not of the actual content 243 * as does the method <CODE>length</CODE>.</P> 244 * <P> 245 * Remark: the actual content of an object is in some cases identical to its representation. 246 * The following statement is always true: length() >= pdfLength().</P> 247 * 248 * @return The length as <CODE>int</CODE> 249 */ 250 public int length() { 251 return toString().length(); 252 } 253 254 /** 255 * Changes the content of this <CODE>PdfObject</CODE>. 256 * 257 * @param content the new content of this <CODE>PdfObject</CODE> 258 */ 259 protected void setContent(String content) { 260 bytes = PdfEncodings.convertToBytes(content, null); 261 } 262 263 // methods dealing with the type of this object 264 265 /** 266 * Returns the type of this <CODE>PdfObject</CODE>. 267 * 268 * May be either of: 269 * - <VAR>NULL</VAR>: A <CODE>PdfNull</CODE> 270 * - <VAR>BOOLEAN</VAR>: A <CODE>PdfBoolean</CODE> 271 * - <VAR>NUMBER</VAR>: A <CODE>PdfNumber</CODE> 272 * - <VAR>STRING</VAR>: A <CODE>PdfString</CODE> 273 * - <VAR>NAME</VAR>: A <CODE>PdfName</CODE> 274 * - <VAR>ARRAY</VAR>: A <CODE>PdfArray</CODE> 275 * - <VAR>DICTIONARY</VAR>: A <CODE>PdfDictionary</CODE> 276 * - <VAR>STREAM</VAR>: A <CODE>PdfStream</CODE> 277 * - <VAR>INDIRECT</VAR>: ><CODE>PdfIndirectObject</CODE> 278 * 279 * @return The type 280 */ 281 public int type() { 282 return type; 283 } 284 285 /** 286 * Checks if this <CODE>PdfObject</CODE> is of the type 287 * <CODE>PdfNull</CODE>. 288 * 289 * @return <CODE>true</CODE> or <CODE>false</CODE> 290 */ 291 public boolean isNull() { 292 return (type == NULL); 293 } 294 295 /** 296 * Checks if this <CODE>PdfObject</CODE> is of the type 297 * <CODE>PdfBoolean</CODE>. 298 * 299 * @return <CODE>true</CODE> or <CODE>false</CODE> 300 */ 301 public boolean isBoolean() { 302 return (type == BOOLEAN); 303 } 304 305 /** 306 * Checks if this <CODE>PdfObject</CODE> is of the type 307 * <CODE>PdfNumber</CODE>. 308 * 309 * @return <CODE>true</CODE> or <CODE>false</CODE> 310 */ 311 public boolean isNumber() { 312 return (type == NUMBER); 313 } 314 315 /** 316 * Checks if this <CODE>PdfObject</CODE> is of the type 317 * <CODE>PdfString</CODE>. 318 * 319 * @return <CODE>true</CODE> or <CODE>false</CODE> 320 */ 321 public boolean isString() { 322 return (type == STRING); 323 } 324 325 /** 326 * Checks if this <CODE>PdfObject</CODE> is of the type 327 * <CODE>PdfName</CODE>. 328 * 329 * @return <CODE>true</CODE> or <CODE>false</CODE> 330 */ 331 public boolean isName() { 332 return (type == NAME); 333 } 334 335 /** 336 * Checks if this <CODE>PdfObject</CODE> is of the type 337 * <CODE>PdfArray</CODE>. 338 * 339 * @return <CODE>true</CODE> or <CODE>false</CODE> 340 */ 341 public boolean isArray() { 342 return (type == ARRAY); 343 } 344 345 /** 346 * Checks if this <CODE>PdfObject</CODE> is of the type 347 * <CODE>PdfDictionary</CODE>. 348 * 349 * @return <CODE>true</CODE> or <CODE>false</CODE> 350 */ 351 public boolean isDictionary() { 352 return (type == DICTIONARY); 353 } 354 355 /** 356 * Checks if this <CODE>PdfObject</CODE> is of the type 357 * <CODE>PdfStream</CODE>. 358 * 359 * @return <CODE>true</CODE> or <CODE>false</CODE> 360 */ 361 public boolean isStream() { 362 return (type == STREAM); 363 } 364 365 /** 366 * Checks if this <CODE>PdfObject</CODE> is of the type 367 * <CODE>PdfIndirectObject</CODE>. 368 * 369 * @return <CODE>true</CODE> if this is an indirect object, 370 * otherwise <CODE>false</CODE> 371 */ 372 public boolean isIndirect() { 373 return (type == INDIRECT); 374 } 375 376 /** 377 * Get the indirect reference 378 * 379 * @return A <CODE>PdfIndirectReference</CODE> 380 */ 381 public PRIndirectReference getIndRef() { 382 return indRef; 383 } 384 385 /** 386 * Set the indirect reference 387 * 388 * @param indRef New value as a <CODE>PdfIndirectReference</CODE> 389 */ 390 public void setIndRef(PRIndirectReference indRef) { 391 this.indRef = indRef; 392 } 393}