1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.pdfbox.cos; 18 19 import java.util.ArrayList; 20 import java.util.Collection; 21 import java.util.Iterator; 22 import java.util.List; 23 24 25 26 import org.apache.pdfbox.exceptions.COSVisitorException; 27 import org.apache.pdfbox.pdmodel.common.COSObjectable; 28 29 /** 30 * An array of PDFBase objects as part of the PDF document. 31 * 32 * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a> 33 * @version $Revision: 1.24 $ 34 */ 35 public class COSArray extends COSBase 36 { 37 private List<COSBase> objects = new ArrayList<COSBase>(); 38 39 /** 40 * Constructor. 41 */ 42 public COSArray() 43 { 44 //default constructor 45 } 46 47 /** 48 * This will add an object to the array. 49 * 50 * @param object The object to add to the array. 51 */ 52 public void add( COSBase object ) 53 { 54 objects.add( object ); 55 } 56 57 /** 58 * This will add an object to the array. 59 * 60 * @param object The object to add to the array. 61 */ 62 public void add( COSObjectable object ) 63 { 64 objects.add( object.getCOSObject() ); 65 } 66 67 /** 68 * Add the specified object at the ith location and push the rest to the 69 * right. 70 * 71 * @param i The index to add at. 72 * @param object The object to add at that index. 73 */ 74 public void add( int i, COSBase object) 75 { 76 objects.add( i, object ); 77 } 78 79 /** 80 * This will remove all of the objects in the collection. 81 */ 82 public void clear() 83 { 84 objects.clear(); 85 } 86 87 /** 88 * This will remove all of the objects in the collection. 89 * 90 * @param objectsList The list of objects to remove from the collection. 91 */ 92 public void removeAll( Collection<COSBase> objectsList ) 93 { 94 objects.removeAll( objectsList ); 95 } 96 97 /** 98 * This will retain all of the objects in the collection. 99 * 100 * @param objectsList The list of objects to retain from the collection. 101 */ 102 public void retainAll( Collection<COSBase> objectsList ) 103 { 104 objects.retainAll( objectsList ); 105 } 106 107 /** 108 * This will add an object to the array. 109 * 110 * @param objectsList The object to add to the array. 111 */ 112 public void addAll( Collection<COSBase> objectsList ) 113 { 114 objects.addAll( objectsList ); 115 } 116 117 /** 118 * This will add all objects to this array. 119 * 120 * @param objectList The objects to add. 121 */ 122 public void addAll( COSArray objectList ) 123 { 124 if( objectList != null ) 125 { 126 objects.addAll( objectList.objects ); 127 } 128 } 129 130 /** 131 * Add the specified object at the ith location and push the rest to the 132 * right. 133 * 134 * @param i The index to add at. 135 * @param objectList The object to add at that index. 136 */ 137 public void addAll( int i, Collection<COSBase> objectList ) 138 { 139 objects.addAll( i, objectList ); 140 } 141 142 /** 143 * This will set an object at a specific index. 144 * 145 * @param index zero based index into array. 146 * @param object The object to set. 147 */ 148 public void set( int index, COSBase object ) 149 { 150 objects.set( index, object ); 151 } 152 153 /** 154 * This will set an object at a specific index. 155 * 156 * @param index zero based index into array. 157 * @param intVal The object to set. 158 */ 159 public void set( int index, int intVal ) 160 { 161 objects.set( index, COSInteger.get(intVal) ); 162 } 163 164 /** 165 * This will set an object at a specific index. 166 * 167 * @param index zero based index into array. 168 * @param object The object to set. 169 */ 170 public void set( int index, COSObjectable object ) 171 { 172 COSBase base = null; 173 if( object != null ) 174 { 175 base = object.getCOSObject(); 176 } 177 objects.set( index, base ); 178 } 179 180 /** 181 * This will get an object from the array. This will dereference the object. 182 * If the object is COSNull then null will be returned. 183 * 184 * @param index The index into the array to get the object. 185 * 186 * @return The object at the requested index. 187 */ 188 public COSBase getObject( int index ) 189 { 190 Object obj = objects.get( index ); 191 if( obj instanceof COSObject ) 192 { 193 obj = ((COSObject)obj).getObject(); 194 } 195 else if( obj instanceof COSNull ) 196 { 197 obj = null; 198 } 199 return (COSBase)obj; 200 } 201 202 /** 203 * This will get an object from the array. This will NOT derefernce 204 * the COS object. 205 * 206 * @param index The index into the array to get the object. 207 * 208 * @return The object at the requested index. 209 */ 210 public COSBase get( int index ) 211 { 212 return (COSBase)objects.get( index ); 213 } 214 215 /** 216 * Get the value of the array as an integer. 217 * 218 * @param index The index into the list. 219 * 220 * @return The value at that index or -1 if it is null. 221 */ 222 public int getInt( int index ) 223 { 224 return getInt( index, -1 ); 225 } 226 227 /** 228 * Get the value of the array as an integer, return the default if it does 229 * not exist. 230 * 231 * @param index The value of the array. 232 * @param defaultValue The value to return if the value is null. 233 * @return The value at the index or the defaultValue. 234 */ 235 public int getInt( int index, int defaultValue ) 236 { 237 int retval = defaultValue; 238 if ( index < size() ) 239 { 240 Object obj = objects.get( index ); 241 if( obj instanceof COSNumber ) 242 { 243 retval = ((COSNumber)obj).intValue(); 244 } 245 } 246 return retval; 247 } 248 249 /** 250 * Set the value in the array as an integer. 251 * 252 * @param index The index into the array. 253 * @param value The value to set. 254 */ 255 public void setInt( int index, int value ) 256 { 257 set( index, COSInteger.get( value ) ); 258 } 259 260 /** 261 * Set the value in the array as a name. 262 * @param index The index into the array. 263 * @param name The name to set in the array. 264 */ 265 public void setName( int index, String name ) 266 { 267 set( index, COSName.getPDFName( name ) ); 268 } 269 270 /** 271 * Get the value of the array as a string. 272 * 273 * @param index The index into the array. 274 * @return The name converted to a string or null if it does not exist. 275 */ 276 public String getName( int index ) 277 { 278 return getName( index, null ); 279 } 280 281 /** 282 * Get an entry in the array that is expected to be a COSName. 283 * @param index The index into the array. 284 * @param defaultValue The value to return if it is null. 285 * @return The value at the index or defaultValue if none is found. 286 */ 287 public String getName( int index, String defaultValue ) 288 { 289 String retval = defaultValue; 290 if( index < size() ) 291 { 292 Object obj = objects.get( index ); 293 if( obj instanceof COSName ) 294 { 295 retval = ((COSName)obj).getName(); 296 } 297 } 298 return retval; 299 } 300 301 /** 302 * Set the value in the array as a string. 303 * @param index The index into the array. 304 * @param string The string to set in the array. 305 */ 306 public void setString( int index, String string ) 307 { 308 set( index, new COSString( string ) ); 309 } 310 311 /** 312 * Get the value of the array as a string. 313 * 314 * @param index The index into the array. 315 * @return The string or null if it does not exist. 316 */ 317 public String getString( int index ) 318 { 319 return getString( index, null ); 320 } 321 322 /** 323 * Get an entry in the array that is expected to be a COSName. 324 * @param index The index into the array. 325 * @param defaultValue The value to return if it is null. 326 * @return The value at the index or defaultValue if none is found. 327 */ 328 public String getString( int index, String defaultValue ) 329 { 330 String retval = defaultValue; 331 if( index < size() ) 332 { 333 Object obj = objects.get( index ); 334 if( obj instanceof COSString ) 335 { 336 retval = ((COSString)obj).getString(); 337 } 338 } 339 return retval; 340 } 341 342 /** 343 * This will get the size of this array. 344 * 345 * @return The number of elements in the array. 346 */ 347 public int size() 348 { 349 return objects.size(); 350 } 351 352 /** 353 * This will remove an element from the array. 354 * 355 * @param i The index of the object to remove. 356 * 357 * @return The object that was removed. 358 */ 359 public COSBase remove( int i ) 360 { 361 return (COSBase)objects.remove( i ); 362 } 363 364 /** 365 * This will remove an element from the array. 366 * 367 * @param o The object to remove. 368 * 369 * @return <code>true</code> if the object was removed, <code>false</code> 370 * otherwise 371 */ 372 public boolean remove( COSBase o ) 373 { 374 return objects.remove( o ); 375 } 376 377 /** 378 * This will remove an element from the array. 379 * This method will also remove a reference to the object. 380 * 381 * @param o The object to remove. 382 * @return <code>true</code> if the object was removed, <code>false</code> 383 * otherwise 384 */ 385 public boolean removeObject(COSBase o) 386 { 387 boolean removed = this.remove(o); 388 if (!removed) 389 { 390 for (int i = 0; i < this.size(); i++) 391 { 392 COSBase entry = this.get(i); 393 if (entry instanceof COSObject) 394 { 395 COSObject objEntry = (COSObject) entry; 396 if (objEntry.getObject().equals(o)) 397 { 398 return this.remove(entry); 399 } 400 } 401 } 402 } 403 return removed; 404 } 405 406 /** 407 * {@inheritDoc} 408 */ 409 public String toString() 410 { 411 return "COSArray{" + objects + "}"; 412 } 413 414 /** 415 * Get access to the list. 416 * 417 * @return an iterator over the array elements 418 */ 419 public Iterator<COSBase> iterator() 420 { 421 return objects.iterator(); 422 } 423 424 /** 425 * This will return the index of the entry or -1 if it is not found. 426 * 427 * @param object The object to search for. 428 * @return The index of the object or -1. 429 */ 430 public int indexOf( COSBase object ) 431 { 432 int retval = -1; 433 for( int i=0; retval < 0 && i<size(); i++ ) 434 { 435 if( get( i ).equals( object ) ) 436 { 437 retval = i; 438 } 439 } 440 return retval; 441 } 442 443 /** 444 * This will return the index of the entry or -1 if it is not found. 445 * This method will also find references to indirect objects. 446 * 447 * @param object The object to search for. 448 * @return The index of the object or -1. 449 */ 450 public int indexOfObject(COSBase object) 451 { 452 int retval = -1; 453 for (int i = 0; retval < 0 && i < this.size(); i++) 454 { 455 COSBase item = this.get(i); 456 if (item.equals(object)) 457 { 458 retval = i; 459 break; 460 } 461 else if (item instanceof COSObject) 462 { 463 if (((COSObject) item).getObject().equals(object)) 464 { 465 retval = i; 466 break; 467 } 468 } 469 } 470 return retval; 471 } 472 473 /** 474 * This will add null values until the size of the array is at least 475 * as large as the parameter. If the array is already larger than the 476 * parameter then nothing is done. 477 * 478 * @param size The desired size of the array. 479 */ 480 public void growToSize( int size ) 481 { 482 growToSize( size, null ); 483 } 484 485 /** 486 * This will add the object until the size of the array is at least 487 * as large as the parameter. If the array is already larger than the 488 * parameter then nothing is done. 489 * 490 * @param size The desired size of the array. 491 * @param object The object to fill the array with. 492 */ 493 public void growToSize( int size, COSBase object ) 494 { 495 while( size() < size ) 496 { 497 add( object ); 498 } 499 } 500 501 /** 502 * visitor pattern double dispatch method. 503 * 504 * @param visitor The object to notify when visiting this object. 505 * @return any object, depending on the visitor implementation, or null 506 * @throws COSVisitorException If an error occurs while visiting this object. 507 */ 508 public Object accept(ICOSVisitor visitor) throws COSVisitorException 509 { 510 return visitor.visitFromArray(this); 511 } 512 513 /** 514 * This will take an COSArray of numbers and convert it to a float[]. 515 * 516 * @return This COSArray as an array of float numbers. 517 */ 518 public float[] toFloatArray() 519 { 520 float[] retval = new float[size()]; 521 for( int i=0; i<size(); i++ ) 522 { 523 retval[i] = ((COSNumber)getObject( i )).floatValue(); 524 } 525 return retval; 526 } 527 528 /** 529 * Clear the current contents of the COSArray and set it with the float[]. 530 * 531 * @param value The new value of the float array. 532 */ 533 public void setFloatArray( float[] value ) 534 { 535 this.clear(); 536 for( int i=0; i<value.length; i++ ) 537 { 538 add( new COSFloat( value[i] ) ); 539 } 540 } 541 542 /** 543 * Return contents of COSArray as a Java List. 544 * 545 * @return the COSArray as List 546 */ 547 public List<COSBase> toList() 548 { 549 ArrayList<COSBase> retList = new ArrayList<COSBase>(size()); 550 for (int i = 0; i < size(); i++) 551 { 552 retList.add(get(i)); 553 } 554 return retList; 555 } 556 }