1 /* 2 * $Id$ 3 * 4 * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie 5 * 6 * The contents of this file are subject to the Mozilla Public License Version 1.1 7 * (the "License"); you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at http://www.mozilla.org/MPL/ 9 * 10 * Software distributed under the License is distributed on an "AS IS" basis, 11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 12 * for the specific language governing rights and limitations under the License. 13 * 14 * The Original Code is 'iText, a free JAVA-PDF library'. 15 * 16 * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by 17 * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. 18 * All Rights Reserved. 19 * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer 20 * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. 21 * 22 * Contributor(s): all the names of the contributors are added in the source code 23 * where applicable. 24 * 25 * Alternatively, the contents of this file may be used under the terms of the 26 * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the 27 * provisions of LGPL are applicable instead of those above. If you wish to 28 * allow use of your version of this file only under the terms of the LGPL 29 * License and not to allow others to use your version of this file under 30 * the MPL, indicate your decision by deleting the provisions above and 31 * replace them with the notice and other provisions required by the LGPL. 32 * If you do not delete the provisions above, a recipient may use your version 33 * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. 34 * 35 * This library is free software; you can redistribute it and/or modify it 36 * under the terms of the MPL as stated above or under the terms of the GNU 37 * Library General Public License as published by the Free Software Foundation; 38 * either version 2 of the License, or any later version. 39 * 40 * This library is distributed in the hope that it will be useful, but WITHOUT 41 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 42 * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more 43 * details. 44 * 45 * If you didn't download this code from the following link, you should check if 46 * you aren't using an obsolete version: 47 * http://www.lowagie.com/iText/ 48 */ 49 50 package com.lowagie.text.pdf; 51 52 import java.io.IOException; 53 import java.io.OutputStream; 54 import java.util.ArrayList; 55 import java.util.Iterator; 56 import java.util.ListIterator; 57 58 /** 59 * <CODE>PdfArray</CODE> is the PDF Array object. 60 * <P> 61 * An array is a sequence of PDF objects. An array may contain a mixture of 62 * object types. 63 * An array is written as a left square bracket ([), followed by a sequence of 64 * objects, followed by a right square bracket (]).<BR> 65 * This object is described in the 'Portable Document Format Reference Manual 66 * version 1.7' section 3.2.5 (page 58). 67 * 68 * @see PdfObject 69 */ 70 public class PdfArray extends PdfObject { 71 72 // CLASS VARIABLES 73 74 /** this is the actual array of PdfObjects */ 75 protected ArrayList arrayList; 76 77 // constructors 78 79 /** 80 * Constructs an empty <CODE>PdfArray</CODE>-object. 81 */ PdfArray()82 public PdfArray() { 83 super(ARRAY); 84 arrayList = new ArrayList(); 85 } 86 87 /** 88 * Constructs an <CODE>PdfArray</CODE>-object, containing 1 89 * <CODE>PdfObject</CODE>. 90 * 91 * @param object a <CODE>PdfObject</CODE> that has to be added to the array 92 */ PdfArray(PdfObject object)93 public PdfArray(PdfObject object) { 94 super(ARRAY); 95 arrayList = new ArrayList(); 96 arrayList.add(object); 97 } 98 99 /** 100 * Constructs a <CODE>PdfArray</CODE>-object, containing all 101 * <CODE>float</CODE> values in a specified array. 102 * 103 * The <CODE>float</CODE> values are internally converted to 104 * <CODE>PdfNumber</CODE> objects. 105 * 106 * @param values an array of <CODE>float</CODE> values to be added 107 */ PdfArray(float values[])108 public PdfArray(float values[]) { 109 super(ARRAY); 110 arrayList = new ArrayList(); 111 add(values); 112 } 113 114 /** 115 * Constructs a <CODE>PdfArray</CODE>-object, containing all 116 * <CODE>int</CODE> values in a specified array. 117 * 118 * The <CODE>int</CODE> values are internally converted to 119 * <CODE>PdfNumber</CODE> objects. 120 * 121 * @param values an array of <CODE>int</CODE> values to be added 122 */ PdfArray(int values[])123 public PdfArray(int values[]) { 124 super(ARRAY); 125 arrayList = new ArrayList(); 126 add(values); 127 } 128 129 /** 130 * Constructs a <CODE>PdfArray</CODE>, containing all elements of a 131 * specified <CODE>ArrayList</CODE>. 132 * 133 * @param l an <CODE>ArrayList</CODE> with <CODE>PdfObject</CODE>s to be 134 * added to the array 135 * @throws ClassCastException if the <CODE>ArrayList</CODE> contains 136 * something that isn't a <CODE>PdfObject</CODE> 137 * @since 2.1.3 138 */ PdfArray(ArrayList l)139 public PdfArray(ArrayList l) { 140 this(); 141 for (Iterator i = l.iterator(); i.hasNext(); ) 142 add((PdfObject)i.next()); 143 } 144 145 /** 146 * Constructs an <CODE>PdfArray</CODE>-object, containing all 147 * <CODE>PdfObject</CODE>s in a specified <CODE>PdfArray</CODE>. 148 * 149 * @param array a <CODE>PdfArray</CODE> to be added to the array 150 */ PdfArray(PdfArray array)151 public PdfArray(PdfArray array) { 152 super(ARRAY); 153 arrayList = new ArrayList(array.arrayList); 154 } 155 156 // METHODS OVERRIDING SOME PDFOBJECT METHODS 157 158 /** 159 * Writes the PDF representation of this <CODE>PdfArray</CODE> as an array 160 * of <CODE>byte</CODE> to the specified <CODE>OutputStream</CODE>. 161 * 162 * @param writer for backwards compatibility 163 * @param os the <CODE>OutputStream</CODE> to write the bytes to. 164 */ toPdf(PdfWriter writer, OutputStream os)165 public void toPdf(PdfWriter writer, OutputStream os) throws IOException { 166 os.write('['); 167 168 Iterator i = arrayList.iterator(); 169 PdfObject object; 170 int type = 0; 171 if (i.hasNext()) { 172 object = (PdfObject) i.next(); 173 if (object == null) 174 object = PdfNull.PDFNULL; 175 object.toPdf(writer, os); 176 } 177 while (i.hasNext()) { 178 object = (PdfObject) i.next(); 179 if (object == null) 180 object = PdfNull.PDFNULL; 181 type = object.type(); 182 if (type != PdfObject.ARRAY && type != PdfObject.DICTIONARY && type != PdfObject.NAME && type != PdfObject.STRING) 183 os.write(' '); 184 object.toPdf(writer, os); 185 } 186 os.write(']'); 187 } 188 189 /** 190 * Returns a string representation of this <CODE>PdfArray</CODE>. 191 * 192 * The string representation consists of a list of all 193 * <CODE>PdfObject</CODE>s contained in this <CODE>PdfArray</CODE>, 194 * enclosed in square brackets ("[]"). Adjacent elements are separated 195 * by the characters ", " (comma and space). 196 * 197 * @return the string representation of this <CODE>PdfArray</CODE> 198 */ toString()199 public String toString() { 200 return arrayList.toString(); 201 } 202 203 // ARRAY CONTENT METHODS 204 205 /** 206 * Overwrites a specified location of the array, returning the previous 207 * value 208 * 209 * @param idx The index of the element to be overwritten 210 * @param obj new value for the specified index 211 * @throws IndexOutOfBoundsException if the specified position doesn't exist 212 * @return the previous value 213 * @since 2.1.5 214 */ set(int idx, PdfObject obj)215 public PdfObject set(int idx, PdfObject obj) { 216 return (PdfObject) arrayList.set(idx, obj); 217 } 218 219 /** 220 * Remove the element at the specified position from the array. 221 * 222 * Shifts any subsequent elements to the left (subtracts one from their 223 * indices). 224 * 225 * @param idx The index of the element to be removed. 226 * @throws IndexOutOfBoundsException the specified position doesn't exist 227 * @since 2.1.5 228 */ remove(int idx)229 public PdfObject remove(int idx) { 230 return (PdfObject) arrayList.remove(idx); 231 } 232 233 /** 234 * Get the internal arrayList for this PdfArray. Not Recommended. 235 * 236 * @deprecated 237 * @return the internal ArrayList. Naughty Naughty. 238 */ getArrayList()239 public ArrayList getArrayList() { 240 return arrayList; 241 } 242 243 /** 244 * Returns the number of entries in the array. 245 * 246 * @return the size of the ArrayList 247 */ size()248 public int size() { 249 return arrayList.size(); 250 } 251 252 /** 253 * Returns <CODE>true</CODE> if the array is empty. 254 * 255 * @return <CODE>true</CODE> if the array is empty 256 * @since 2.1.5 257 */ isEmpty()258 public boolean isEmpty() { 259 return arrayList.isEmpty(); 260 } 261 262 /** 263 * Adds a <CODE>PdfObject</CODE> to the end of the <CODE>PdfArray</CODE>. 264 * 265 * The <CODE>PdfObject</CODE> will be the last element. 266 * 267 * @param object <CODE>PdfObject</CODE> to add 268 * @return always <CODE>true</CODE> 269 */ add(PdfObject object)270 public boolean add(PdfObject object) { 271 return arrayList.add(object); 272 } 273 274 /** 275 * Adds an array of <CODE>float</CODE> values to end of the 276 * <CODE>PdfArray</CODE>. 277 * 278 * The values will be the last elements. 279 * The <CODE>float</CODE> values are internally converted to 280 * <CODE>PdfNumber</CODE> objects. 281 * 282 * @param values An array of <CODE>float</CODE> values to add 283 * @return always <CODE>true</CODE> 284 */ add(float values[])285 public boolean add(float values[]) { 286 for (int k = 0; k < values.length; ++k) 287 arrayList.add(new PdfNumber(values[k])); 288 return true; 289 } 290 291 /** 292 * Adds an array of <CODE>int</CODE> values to end of the <CODE>PdfArray</CODE>. 293 * 294 * The values will be the last elements. 295 * The <CODE>int</CODE> values are internally converted to 296 * <CODE>PdfNumber</CODE> objects. 297 * 298 * @param values An array of <CODE>int</CODE> values to add 299 * @return always <CODE>true</CODE> 300 */ add(int values[])301 public boolean add(int values[]) { 302 for (int k = 0; k < values.length; ++k) 303 arrayList.add(new PdfNumber(values[k])); 304 return true; 305 } 306 307 /** 308 * Inserts the specified element at the specified position. 309 * 310 * Shifts the element currently at that position (if any) and 311 * any subsequent elements to the right (adds one to their indices). 312 * 313 * @param index The index at which the specified element is to be inserted 314 * @param element The element to be inserted 315 * @throws IndexOutOfBoundsException if the specified index is larger than the 316 * last position currently set, plus 1. 317 * @since 2.1.5 318 */ add(int index, PdfObject element)319 public void add(int index, PdfObject element) { 320 arrayList.add(index, element); 321 } 322 323 /** 324 * Inserts a <CODE>PdfObject</CODE> at the beginning of the 325 * <CODE>PdfArray</CODE>. 326 * 327 * The <CODE>PdfObject</CODE> will be the first element, any other elements 328 * will be shifted to the right (adds one to their indices). 329 * 330 * @param object The <CODE>PdfObject</CODE> to add 331 */ addFirst(PdfObject object)332 public void addFirst(PdfObject object) { 333 arrayList.add(0, object); 334 } 335 336 /** 337 * Checks if the <CODE>PdfArray</CODE> already contains a certain 338 * <CODE>PdfObject</CODE>. 339 * 340 * @param object The <CODE>PdfObject</CODE> to check 341 * @return <CODE>true</CODE> 342 */ contains(PdfObject object)343 public boolean contains(PdfObject object) { 344 return arrayList.contains(object); 345 } 346 347 /** 348 * Returns the list iterator for the array. 349 * 350 * @return a ListIterator 351 */ listIterator()352 public ListIterator listIterator() { 353 return arrayList.listIterator(); 354 } 355 356 /** 357 * Returns the <CODE>PdfObject</CODE> with the specified index. 358 * 359 * A possible indirect references is not resolved, so the returned 360 * <CODE>PdfObject</CODE> may be either a direct object or an indirect 361 * reference, depending on how the object is stored in the 362 * <CODE>PdfArray</CODE>. 363 * 364 * @param idx The index of the <CODE>PdfObject</CODE> to be returned 365 * @return A <CODE>PdfObject</CODE> 366 */ getPdfObject(int idx)367 public PdfObject getPdfObject(int idx) { 368 return (PdfObject)arrayList.get(idx); 369 } 370 371 /** 372 * Returns the <CODE>PdfObject</CODE> with the specified index, resolving 373 * a possible indirect reference to a direct object. 374 * 375 * Thus this method will never return a <CODE>PdfIndirectReference</CODE> 376 * object. 377 * 378 * @param idx The index of the <CODE>PdfObject</CODE> to be returned 379 * @return A direct <CODE>PdfObject</CODE> or <CODE>null</CODE> 380 */ getDirectObject(int idx)381 public PdfObject getDirectObject(int idx) { 382 return PdfReader.getPdfObject(getPdfObject(idx)); 383 } 384 385 // DOWNCASTING GETTERS 386 // @author Mark A Storer (2/17/06) 387 388 /** 389 * Returns a <CODE>PdfObject</CODE> as a <CODE>PdfDictionary</CODE>, 390 * resolving indirect references. 391 * 392 * The object corresponding to the specified index is retrieved and 393 * resolvedto a direct object. 394 * If it is a <CODE>PdfDictionary</CODE>, it is cast down and returned as such. 395 * Otherwise <CODE>null</CODE> is returned. 396 * 397 * @param idx The index of the <CODE>PdfObject</CODE> to be returned 398 * @return the corresponding <CODE>PdfDictionary</CODE> object, 399 * or <CODE>null</CODE> 400 */ getAsDict(int idx)401 public PdfDictionary getAsDict(int idx) { 402 PdfDictionary dict = null; 403 PdfObject orig = getDirectObject(idx); 404 if (orig != null && orig.isDictionary()) 405 dict = (PdfDictionary) orig; 406 return dict; 407 } 408 409 /** 410 * Returns a <CODE>PdfObject</CODE> as a <CODE>PdfArray</CODE>, 411 * resolving indirect references. 412 * 413 * The object corresponding to the specified index is retrieved and 414 * resolved to a direct object. 415 * If it is a <CODE>PdfArray</CODE>, it is cast down and returned as such. 416 * Otherwise <CODE>null</CODE> is returned. 417 * 418 * @param idx The index of the <CODE>PdfObject</CODE> to be returned 419 * @return the corresponding <CODE>PdfArray</CODE> object, 420 * or <CODE>null</CODE> 421 */ getAsArray(int idx)422 public PdfArray getAsArray(int idx) { 423 PdfArray array = null; 424 PdfObject orig = getDirectObject(idx); 425 if (orig != null && orig.isArray()) 426 array = (PdfArray) orig; 427 return array; 428 } 429 430 /** 431 * Returns a <CODE>PdfObject</CODE> as a <CODE>PdfStream</CODE>, 432 * resolving indirect references. 433 * 434 * The object corresponding to the specified index is retrieved and 435 * resolved to a direct object. 436 * If it is a <CODE>PdfStream</CODE>, it is cast down and returned as such. 437 * Otherwise <CODE>null</CODE> is returned. 438 * 439 * @param idx The index of the <CODE>PdfObject</CODE> to be returned 440 * @return the corresponding <CODE>PdfStream</CODE> object, 441 * or <CODE>null</CODE> 442 */ getAsStream(int idx)443 public PdfStream getAsStream(int idx) { 444 PdfStream stream = null; 445 PdfObject orig = getDirectObject(idx); 446 if (orig != null && orig.isStream()) 447 stream = (PdfStream) orig; 448 return stream; 449 } 450 451 /** 452 * Returns a <CODE>PdfObject</CODE> as a <CODE>PdfString</CODE>, 453 * resolving indirect references. 454 * 455 * The object corresponding to the specified index is retrieved and 456 * resolved to a direct object. 457 * If it is a <CODE>PdfString</CODE>, it is cast down and returned as such. 458 * Otherwise <CODE>null</CODE> is returned. 459 * 460 * @param idx The index of the <CODE>PdfObject</CODE> to be returned 461 * @return the corresponding <CODE>PdfString</CODE> object, 462 * or <CODE>null</CODE> 463 */ getAsString(int idx)464 public PdfString getAsString(int idx) { 465 PdfString string = null; 466 PdfObject orig = getDirectObject(idx); 467 if (orig != null && orig.isString()) 468 string = (PdfString) orig; 469 return string; 470 } 471 472 /** 473 * Returns a <CODE>PdfObject</CODE> as a <CODE>PdfNumber</CODE>, 474 * resolving indirect references. 475 * 476 * The object corresponding to the specified index is retrieved and 477 * resolved to a direct object. 478 * If it is a <CODE>PdfNumber</CODE>, it is cast down and returned as such. 479 * Otherwise <CODE>null</CODE> is returned. 480 * 481 * @param idx The index of the <CODE>PdfObject</CODE> to be returned 482 * @return the corresponding <CODE>PdfNumber</CODE> object, 483 * or <CODE>null</CODE> 484 */ getAsNumber(int idx)485 public PdfNumber getAsNumber(int idx) { 486 PdfNumber number = null; 487 PdfObject orig = getDirectObject(idx); 488 if (orig != null && orig.isNumber()) 489 number = (PdfNumber) orig; 490 return number; 491 } 492 493 /** 494 * Returns a <CODE>PdfObject</CODE> as a <CODE>PdfName</CODE>, 495 * resolving indirect references. 496 * 497 * The object corresponding to the specified index is retrieved and 498 * resolved to a direct object. 499 * If it is a <CODE>PdfName</CODE>, it is cast down and returned as such. 500 * Otherwise <CODE>null</CODE> is returned. 501 * 502 * @param idx The index of the <CODE>PdfObject</CODE> to be returned 503 * @return the corresponding <CODE>PdfName</CODE> object, 504 * or <CODE>null</CODE> 505 */ getAsName(int idx)506 public PdfName getAsName(int idx) { 507 PdfName name = null; 508 PdfObject orig = getDirectObject(idx); 509 if (orig != null && orig.isName()) 510 name = (PdfName) orig; 511 return name; 512 } 513 514 /** 515 * Returns a <CODE>PdfObject</CODE> as a <CODE>PdfBoolean</CODE>, 516 * resolving indirect references. 517 * 518 * The object corresponding to the specified index is retrieved and 519 * resolved to a direct object. 520 * If it is a <CODE>PdfBoolean</CODE>, it is cast down and returned as 521 * such. Otherwise <CODE>null</CODE> is returned. 522 * 523 * @param idx The index of the <CODE>PdfObject</CODE> to be returned 524 * @return the corresponding <CODE>PdfBoolean</CODE> object, 525 * or <CODE>null</CODE> 526 */ getAsBoolean(int idx)527 public PdfBoolean getAsBoolean(int idx) { 528 PdfBoolean bool = null; 529 PdfObject orig = getDirectObject(idx); 530 if (orig != null && orig.isBoolean()) 531 bool = (PdfBoolean) orig; 532 return bool; 533 } 534 535 /** 536 * Returns a <CODE>PdfObject</CODE> as a <CODE>PdfIndirectReference</CODE>. 537 * 538 * The object corresponding to the specified index is retrieved. 539 * If it is a <CODE>PdfIndirectReference</CODE>, it is cast down and 540 * returned as such. Otherwise <CODE>null</CODE> is returned. 541 * 542 * @param idx The index of the <CODE>PdfObject</CODE> to be returned 543 * @return the corresponding <CODE>PdfIndirectReference</CODE> object, 544 * or <CODE>null</CODE> 545 */ getAsIndirectObject(int idx)546 public PdfIndirectReference getAsIndirectObject(int idx) { 547 PdfIndirectReference ref = null; 548 PdfObject orig = getPdfObject(idx); // not getDirect this time. 549 if (orig != null && orig.isIndirect()) 550 ref = (PdfIndirectReference) orig; 551 return ref; 552 } 553 } 554