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.io.IOException; 20 import java.util.ArrayList; 21 import java.util.Calendar; 22 import java.util.Collection; 23 import java.util.LinkedHashMap; 24 import java.util.List; 25 import java.util.Map; 26 import java.util.Set; 27 28 import org.apache.pdfbox.exceptions.COSVisitorException; 29 30 import org.apache.pdfbox.pdmodel.common.COSObjectable; 31 import org.apache.pdfbox.util.DateConverter; 32 33 /** 34 * This class represents a dictionary where name/value pairs reside. 35 * 36 * @author <a href="ben@benlitchfield.com">Ben Litchfield</a> 37 * @version $Revision: 1.32 $ 38 */ 39 public class COSDictionary extends COSBase 40 { 41 private static final String PATH_SEPARATOR = "/"; 42 43 /** 44 * The name-value pairs of this dictionary. The pairs are kept in the 45 * order they were added to the dictionary. 46 */ 47 private final Map<COSName, COSBase> items = 48 new LinkedHashMap<COSName, COSBase>(); 49 50 /** 51 * Constructor. 52 */ 53 public COSDictionary() 54 { 55 //default constructor 56 } 57 58 /** 59 * Copy Constructor. This will make a shallow copy of this dictionary. 60 * 61 * @param dict The dictionary to copy. 62 */ 63 public COSDictionary( COSDictionary dict ) 64 { 65 items.putAll( dict.items ); 66 } 67 68 /** 69 * @see java.util.Map#containsValue(java.lang.Object) 70 * 71 * @param value The value to find in the map. 72 * 73 * @return true if the map contains this value. 74 */ 75 public boolean containsValue( Object value ) 76 { 77 boolean contains = items.containsValue( value ); 78 if( !contains && value instanceof COSObject ) 79 { 80 contains = items.containsValue( ((COSObject)value).getObject()); 81 } 82 return contains; 83 } 84 85 /** 86 * Search in the map for the value that matches the parameter 87 * and return the first key that maps to that value. 88 * 89 * @param value The value to search for in the map. 90 * @return The key for the value in the map or null if it does not exist. 91 */ 92 public COSName getKeyForValue( Object value ) 93 { 94 for( Map.Entry<COSName, COSBase> entry : items.entrySet() ) 95 { 96 Object nextValue = entry.getValue(); 97 if( nextValue.equals( value ) || 98 (nextValue instanceof COSObject && 99 ((COSObject)nextValue).getObject().equals( value)) 100 ) 101 { 102 return entry.getKey(); 103 } 104 } 105 106 return null; 107 } 108 109 /** 110 * This will return the number of elements in this dictionary. 111 * 112 * @return The number of elements in the dictionary. 113 */ 114 public int size() 115 { 116 return items.size(); 117 } 118 119 /** 120 * This will clear all items in the map. 121 */ 122 public void clear() 123 { 124 items.clear(); 125 } 126 127 /** 128 * This will get an object from this dictionary. If the object is a reference then it will 129 * dereference it and get it from the document. If the object is COSNull then 130 * null will be returned. 131 * 132 * @param key The key to the object that we are getting. 133 * 134 * @return The object that matches the key. 135 */ 136 public COSBase getDictionaryObject( String key ) 137 { 138 return getDictionaryObject( COSName.getPDFName( key ) ); 139 } 140 141 /** 142 * This is a special case of getDictionaryObject that takes multiple keys, it will handle 143 * the situation where multiple keys could get the same value, ie if either CS or ColorSpace 144 * is used to get the colorspace. 145 * This will get an object from this dictionary. If the object is a reference then it will 146 * dereference it and get it from the document. If the object is COSNull then 147 * null will be returned. 148 * 149 * @param firstKey The first key to try. 150 * @param secondKey The second key to try. 151 * 152 * @return The object that matches the key. 153 */ 154 public COSBase getDictionaryObject( String firstKey, String secondKey ) 155 { 156 COSBase retval = getDictionaryObject( COSName.getPDFName( firstKey ) ); 157 if( retval == null ) 158 { 159 retval = getDictionaryObject( COSName.getPDFName( secondKey ) ); 160 } 161 return retval; 162 } 163 164 /** 165 * This is a special case of getDictionaryObject that takes multiple keys, it will handle 166 * the situation where multiple keys could get the same value, ie if either CS or ColorSpace 167 * is used to get the colorspace. 168 * This will get an object from this dictionary. If the object is a reference then it will 169 * dereference it and get it from the document. If the object is COSNull then 170 * null will be returned. 171 * 172 * @param keyList The list of keys to find a value. 173 * 174 * @return The object that matches the key. 175 */ 176 public COSBase getDictionaryObject( String[] keyList ) 177 { 178 COSBase retval = null; 179 for( int i=0; i<keyList.length && retval == null; i++ ) 180 { 181 retval = getDictionaryObject( COSName.getPDFName( keyList[i] ) ); 182 } 183 return retval; 184 } 185 186 /** 187 * This will get an object from this dictionary. If the object is a reference then it will 188 * dereference it and get it from the document. If the object is COSNull then 189 * null will be returned. 190 * 191 * @param key The key to the object that we are getting. 192 * 193 * @return The object that matches the key. 194 */ 195 public COSBase getDictionaryObject( COSName key ) 196 { 197 COSBase retval = items.get( key ); 198 if( retval instanceof COSObject ) 199 { 200 retval = ((COSObject)retval).getObject(); 201 } 202 if( retval instanceof COSNull ) 203 { 204 retval = null; 205 } 206 return retval; 207 } 208 209 /** 210 * This will set an item in the dictionary. If value is null then the result 211 * will be the same as removeItem( key ). 212 * 213 * @param key The key to the dictionary object. 214 * @param value The value to the dictionary object. 215 */ 216 public void setItem( COSName key, COSBase value ) 217 { 218 if( value == null ) 219 { 220 removeItem( key ); 221 } 222 else 223 { 224 items.put( key, value ); 225 } 226 } 227 228 /** 229 * This will set an item in the dictionary. If value is null then the result 230 * will be the same as removeItem( key ). 231 * 232 * @param key The key to the dictionary object. 233 * @param value The value to the dictionary object. 234 */ 235 public void setItem( COSName key, COSObjectable value ) 236 { 237 COSBase base = null; 238 if( value != null ) 239 { 240 base = value.getCOSObject(); 241 } 242 setItem( key, base ); 243 } 244 245 /** 246 * This will set an item in the dictionary. If value is null then the result 247 * will be the same as removeItem( key ). 248 * 249 * @param key The key to the dictionary object. 250 * @param value The value to the dictionary object. 251 */ 252 public void setItem( String key, COSObjectable value ) 253 { 254 setItem( COSName.getPDFName( key ), value ); 255 } 256 257 /** 258 * This will set an item in the dictionary. 259 * 260 * @param key The key to the dictionary object. 261 * @param value The value to the dictionary object. 262 */ 263 public void setBoolean( String key, boolean value ) 264 { 265 setItem( COSName.getPDFName( key ), COSBoolean.getBoolean( value ) ); 266 } 267 268 /** 269 * This will set an item in the dictionary. 270 * 271 * @param key The key to the dictionary object. 272 * @param value The value to the dictionary object. 273 */ 274 public void setBoolean( COSName key, boolean value ) 275 { 276 setItem( key , COSBoolean.getBoolean( value ) ); 277 } 278 279 /** 280 * This will set an item in the dictionary. If value is null then the result 281 * will be the same as removeItem( key ). 282 * 283 * @param key The key to the dictionary object. 284 * @param value The value to the dictionary object. 285 */ 286 public void setItem( String key, COSBase value ) 287 { 288 setItem( COSName.getPDFName( key ), value ); 289 } 290 291 /** 292 * This is a convenience method that will convert the value to a COSName 293 * object. If it is null then the object will be removed. 294 * 295 * @param key The key to the object, 296 * @param value The string value for the name. 297 */ 298 public void setName( String key, String value ) 299 { 300 setName( COSName.getPDFName( key ), value ); 301 } 302 303 /** 304 * This is a convenience method that will convert the value to a COSName 305 * object. If it is null then the object will be removed. 306 * 307 * @param key The key to the object, 308 * @param value The string value for the name. 309 */ 310 public void setName( COSName key, String value ) 311 { 312 COSName name = null; 313 if( value != null ) 314 { 315 name = COSName.getPDFName( value ); 316 } 317 setItem( key, name ); 318 } 319 320 /** 321 * Set the value of a date entry in the dictionary. 322 * 323 * @param key The key to the date value. 324 * @param date The date value. 325 */ 326 public void setDate( String key, Calendar date ) 327 { 328 setDate( COSName.getPDFName( key ), date ); 329 } 330 331 /** 332 * Set the date object. 333 * 334 * @param key The key to the date. 335 * @param date The date to set. 336 */ 337 public void setDate( COSName key, Calendar date ) 338 { 339 setString( key, DateConverter.toString( date ) ); 340 } 341 342 /** 343 * Set the value of a date entry in the dictionary. 344 * 345 * @param embedded The embedded dictionary. 346 * @param key The key to the date value. 347 * @param date The date value. 348 */ 349 public void setEmbeddedDate( String embedded, String key, Calendar date ) 350 { 351 setEmbeddedDate( embedded, COSName.getPDFName( key ), date ); 352 } 353 354 /** 355 * Set the date object. 356 * 357 * @param embedded The embedded dictionary. 358 * @param key The key to the date. 359 * @param date The date to set. 360 */ 361 public void setEmbeddedDate( String embedded, COSName key, Calendar date ) 362 { 363 COSDictionary dic = (COSDictionary)getDictionaryObject( embedded ); 364 if( dic == null && date != null ) 365 { 366 dic = new COSDictionary(); 367 setItem( embedded, dic ); 368 } 369 if( dic != null ) 370 { 371 dic.setDate( key, date ); 372 } 373 } 374 375 /** 376 * This is a convenience method that will convert the value to a COSString 377 * object. If it is null then the object will be removed. 378 * 379 * @param key The key to the object, 380 * @param value The string value for the name. 381 */ 382 public void setString( String key, String value ) 383 { 384 setString( COSName.getPDFName( key ), value ); 385 } 386 387 /** 388 * This is a convenience method that will convert the value to a COSString 389 * object. If it is null then the object will be removed. 390 * 391 * @param key The key to the object, 392 * @param value The string value for the name. 393 */ 394 public void setString( COSName key, String value ) 395 { 396 COSString name = null; 397 if( value != null ) 398 { 399 name = new COSString( value ); 400 } 401 setItem( key, name ); 402 } 403 404 /** 405 * This is a convenience method that will convert the value to a COSString 406 * object. If it is null then the object will be removed. 407 * 408 * @param embedded The embedded dictionary to set the item in. 409 * @param key The key to the object, 410 * @param value The string value for the name. 411 */ 412 public void setEmbeddedString( String embedded, String key, String value ) 413 { 414 setEmbeddedString( embedded, COSName.getPDFName( key ), value ); 415 } 416 417 /** 418 * This is a convenience method that will convert the value to a COSString 419 * object. If it is null then the object will be removed. 420 * 421 * @param embedded The embedded dictionary to set the item in. 422 * @param key The key to the object, 423 * @param value The string value for the name. 424 */ 425 public void setEmbeddedString( String embedded, COSName key, String value ) 426 { 427 COSDictionary dic = (COSDictionary)getDictionaryObject( embedded ); 428 if( dic == null && value != null ) 429 { 430 dic = new COSDictionary(); 431 setItem( embedded, dic ); 432 } 433 if( dic != null ) 434 { 435 dic.setString( key, value ); 436 } 437 } 438 439 /** 440 * This is a convenience method that will convert the value to a COSInteger 441 * object. 442 * 443 * @param key The key to the object, 444 * @param value The int value for the name. 445 */ 446 public void setInt( String key, int value ) 447 { 448 setInt( COSName.getPDFName( key ), value ); 449 } 450 451 /** 452 * This is a convenience method that will convert the value to a COSInteger 453 * object. 454 * 455 * @param key The key to the object, 456 * @param value The int value for the name. 457 */ 458 public void setInt( COSName key, int value ) 459 { 460 setItem( key, COSInteger.get(value) ); 461 } 462 463 /** 464 * This is a convenience method that will convert the value to a COSInteger 465 * object. 466 * 467 * @param key The key to the object, 468 * @param value The int value for the name. 469 */ 470 public void setLong( String key, long value ) 471 { 472 setLong( COSName.getPDFName( key ), value ); 473 } 474 475 /** 476 * This is a convenience method that will convert the value to a COSInteger 477 * object. 478 * 479 * @param key The key to the object, 480 * @param value The int value for the name. 481 */ 482 public void setLong( COSName key, long value ) 483 { 484 COSInteger intVal = null; 485 intVal = COSInteger.get(value); 486 setItem( key, intVal ); 487 } 488 489 /** 490 * This is a convenience method that will convert the value to a COSInteger 491 * object. 492 * 493 * @param embeddedDictionary The embedded dictionary. 494 * @param key The key to the object, 495 * @param value The int value for the name. 496 */ 497 public void setEmbeddedInt( String embeddedDictionary, String key, int value ) 498 { 499 setEmbeddedInt( embeddedDictionary, COSName.getPDFName( key ), value ); 500 } 501 502 /** 503 * This is a convenience method that will convert the value to a COSInteger 504 * object. 505 * 506 * @param embeddedDictionary The embedded dictionary. 507 * @param key The key to the object, 508 * @param value The int value for the name. 509 */ 510 public void setEmbeddedInt( String embeddedDictionary, COSName key, int value ) 511 { 512 COSDictionary embedded = (COSDictionary)getDictionaryObject( embeddedDictionary ); 513 if( embedded == null ) 514 { 515 embedded = new COSDictionary(); 516 setItem( embeddedDictionary, embedded ); 517 } 518 embedded.setInt( key, value ); 519 } 520 521 /** 522 * This is a convenience method that will convert the value to a COSFloat 523 * object. 524 * 525 * @param key The key to the object, 526 * @param value The int value for the name. 527 */ 528 public void setFloat( String key, float value ) 529 { 530 setFloat( COSName.getPDFName( key ), value ); 531 } 532 533 /** 534 * This is a convenience method that will convert the value to a COSFloat 535 * object. 536 * 537 * @param key The key to the object, 538 * @param value The int value for the name. 539 */ 540 public void setFloat( COSName key, float value ) 541 { 542 COSFloat fltVal = new COSFloat( value ); 543 setItem( key, fltVal ); 544 } 545 546 /** 547 * This is a convenience method that will get the dictionary object that 548 * is expected to be a name and convert it to a string. Null is returned 549 * if the entry does not exist in the dictionary. 550 * 551 * @param key The key to the item in the dictionary. 552 * @return The name converted to a string. 553 */ 554 public String getNameAsString( String key ) 555 { 556 return getNameAsString( COSName.getPDFName( key ) ); 557 } 558 559 /** 560 * This is a convenience method that will get the dictionary object that 561 * is expected to be a name and convert it to a string. Null is returned 562 * if the entry does not exist in the dictionary. 563 * 564 * @param key The key to the item in the dictionary. 565 * @return The name converted to a string. 566 */ 567 public String getNameAsString( COSName key ) 568 { 569 String retval = null; 570 COSBase name = getDictionaryObject( key ); 571 if( name != null ) 572 { 573 if ( name instanceof COSName) 574 { 575 retval = ((COSName)name).getName(); 576 } 577 else if ( name instanceof COSString) 578 { 579 retval = ((COSString)name).getString(); 580 } 581 } 582 return retval; 583 } 584 585 /** 586 * This is a convenience method that will get the dictionary object that 587 * is expected to be a name and convert it to a string. Null is returned 588 * if the entry does not exist in the dictionary. 589 * 590 * @param key The key to the item in the dictionary. 591 * @param defaultValue The value to return if the dictionary item is null. 592 * @return The name converted to a string. 593 */ 594 public String getNameAsString( String key, String defaultValue ) 595 { 596 return getNameAsString( COSName.getPDFName( key ), defaultValue ); 597 } 598 599 /** 600 * This is a convenience method that will get the dictionary object that 601 * is expected to be a name and convert it to a string. Null is returned 602 * if the entry does not exist in the dictionary. 603 * 604 * @param key The key to the item in the dictionary. 605 * @param defaultValue The value to return if the dictionary item is null. 606 * @return The name converted to a string. 607 */ 608 public String getNameAsString( COSName key, String defaultValue ) 609 { 610 String retval = getNameAsString( key ); 611 if( retval == null ) 612 { 613 retval = defaultValue; 614 } 615 return retval; 616 } 617 618 /** 619 * This is a convenience method that will get the dictionary object that 620 * is expected to be a name and convert it to a string. Null is returned 621 * if the entry does not exist in the dictionary. 622 * 623 * @param key The key to the item in the dictionary. 624 * @return The name converted to a string. 625 */ 626 public String getString( String key ) 627 { 628 return getString( COSName.getPDFName( key ) ); 629 } 630 631 /** 632 * This is a convenience method that will get the dictionary object that 633 * is expected to be a name and convert it to a string. Null is returned 634 * if the entry does not exist in the dictionary. 635 * 636 * @param key The key to the item in the dictionary. 637 * @return The name converted to a string. 638 */ 639 public String getString( COSName key ) 640 { 641 String retval = null; 642 COSBase value = getDictionaryObject( key ); 643 if( value != null && value instanceof COSString) 644 { 645 retval = ((COSString)value).getString(); 646 } 647 return retval; 648 } 649 650 /** 651 * This is a convenience method that will get the dictionary object that 652 * is expected to be a name and convert it to a string. Null is returned 653 * if the entry does not exist in the dictionary. 654 * 655 * @param key The key to the item in the dictionary. 656 * @param defaultValue The default value to return. 657 * @return The name converted to a string. 658 */ 659 public String getString( String key, String defaultValue ) 660 { 661 return getString( COSName.getPDFName( key ), defaultValue ); 662 } 663 664 /** 665 * This is a convenience method that will get the dictionary object that 666 * is expected to be a name and convert it to a string. Null is returned 667 * if the entry does not exist in the dictionary. 668 * 669 * @param key The key to the item in the dictionary. 670 * @param defaultValue The default value to return. 671 * @return The name converted to a string. 672 */ 673 public String getString( COSName key, String defaultValue ) 674 { 675 String retval = getString( key ); 676 if( retval == null ) 677 { 678 retval = defaultValue; 679 } 680 return retval; 681 } 682 683 /** 684 * This is a convenience method that will get the dictionary object that 685 * is expected to be a name and convert it to a string. Null is returned 686 * if the entry does not exist in the dictionary. 687 * 688 * @param embedded The embedded dictionary. 689 * @param key The key to the item in the dictionary. 690 * @return The name converted to a string. 691 */ 692 public String getEmbeddedString( String embedded, String key ) 693 { 694 return getEmbeddedString( embedded, COSName.getPDFName( key ), null ); 695 } 696 697 /** 698 * This is a convenience method that will get the dictionary object that 699 * is expected to be a name and convert it to a string. Null is returned 700 * if the entry does not exist in the dictionary. 701 * 702 * @param embedded The embedded dictionary. 703 * @param key The key to the item in the dictionary. 704 * @return The name converted to a string. 705 */ 706 public String getEmbeddedString( String embedded, COSName key ) 707 { 708 return getEmbeddedString( embedded, key, null ); 709 } 710 711 /** 712 * This is a convenience method that will get the dictionary object that 713 * is expected to be a name and convert it to a string. Null is returned 714 * if the entry does not exist in the dictionary. 715 * 716 * @param embedded The embedded dictionary. 717 * @param key The key to the item in the dictionary. 718 * @param defaultValue The default value to return. 719 * @return The name converted to a string. 720 */ 721 public String getEmbeddedString( String embedded, String key, String defaultValue ) 722 { 723 return getEmbeddedString( embedded, COSName.getPDFName( key ), defaultValue ); 724 } 725 726 /** 727 * This is a convenience method that will get the dictionary object that 728 * is expected to be a name and convert it to a string. Null is returned 729 * if the entry does not exist in the dictionary. 730 * 731 * @param embedded The embedded dictionary. 732 * @param key The key to the item in the dictionary. 733 * @param defaultValue The default value to return. 734 * @return The name converted to a string. 735 */ 736 public String getEmbeddedString( String embedded, COSName key, String defaultValue ) 737 { 738 String retval = defaultValue; 739 COSDictionary dic = (COSDictionary)getDictionaryObject( embedded ); 740 if( dic != null ) 741 { 742 retval = dic.getString( key, defaultValue ); 743 } 744 return retval; 745 } 746 747 /** 748 * This is a convenience method that will get the dictionary object that 749 * is expected to be a name and convert it to a string. Null is returned 750 * if the entry does not exist in the dictionary. 751 * 752 * @param key The key to the item in the dictionary. 753 * @return The name converted to a string. 754 * @throws IOException If there is an error converting to a date. 755 */ 756 public Calendar getDate( String key ) throws IOException 757 { 758 return getDate( COSName.getPDFName( key ) ); 759 } 760 761 /** 762 * This is a convenience method that will get the dictionary object that 763 * is expected to be a name and convert it to a string. Null is returned 764 * if the entry does not exist in the dictionary. 765 * 766 * @param key The key to the item in the dictionary. 767 * @return The name converted to a string. 768 * 769 * @throws IOException If there is an error converting to a date. 770 */ 771 public Calendar getDate( COSName key ) throws IOException 772 { 773 COSString date = (COSString)getDictionaryObject( key ); 774 return DateConverter.toCalendar( date ); 775 } 776 777 /** 778 * This is a convenience method that will get the dictionary object that 779 * is expected to be a date. Null is returned 780 * if the entry does not exist in the dictionary. 781 * 782 * @param key The key to the item in the dictionary. 783 * @param defaultValue The default value to return. 784 * @return The name converted to a string. 785 * @throws IOException If there is an error converting to a date. 786 */ 787 public Calendar getDate( String key, Calendar defaultValue ) throws IOException 788 { 789 return getDate( COSName.getPDFName( key ), defaultValue ); 790 } 791 792 /** 793 * This is a convenience method that will get the dictionary object that 794 * is expected to be a date. Null is returned 795 * if the entry does not exist in the dictionary. 796 * 797 * @param key The key to the item in the dictionary. 798 * @param defaultValue The default value to return. 799 * @return The name converted to a string. 800 * @throws IOException If there is an error converting to a date. 801 */ 802 public Calendar getDate( COSName key, Calendar defaultValue ) throws IOException 803 { 804 Calendar retval = getDate( key ); 805 if( retval == null ) 806 { 807 retval = defaultValue; 808 } 809 return retval; 810 } 811 812 /** 813 * This is a convenience method that will get the dictionary object that 814 * is expected to be a name and convert it to a string. Null is returned 815 * if the entry does not exist in the dictionary. 816 * 817 * @param embedded The embedded dictionary to get. 818 * @param key The key to the item in the dictionary. 819 * @return The name converted to a string. 820 * @throws IOException If there is an error converting to a date. 821 */ 822 public Calendar getEmbeddedDate( String embedded, String key ) throws IOException 823 { 824 return getEmbeddedDate( embedded, COSName.getPDFName( key ), null ); 825 } 826 827 /** 828 * This is a convenience method that will get the dictionary object that 829 * is expected to be a name and convert it to a string. Null is returned 830 * if the entry does not exist in the dictionary. 831 * 832 * @param embedded The embedded dictionary to get. 833 * @param key The key to the item in the dictionary. 834 * @return The name converted to a string. 835 * 836 * @throws IOException If there is an error converting to a date. 837 */ 838 public Calendar getEmbeddedDate( String embedded, COSName key ) throws IOException 839 { 840 return getEmbeddedDate( embedded, key, null ); 841 } 842 843 /** 844 * This is a convenience method that will get the dictionary object that 845 * is expected to be a date. Null is returned 846 * if the entry does not exist in the dictionary. 847 * 848 * @param embedded The embedded dictionary to get. 849 * @param key The key to the item in the dictionary. 850 * @param defaultValue The default value to return. 851 * @return The name converted to a string. 852 * @throws IOException If there is an error converting to a date. 853 */ 854 public Calendar getEmbeddedDate( String embedded, String key, Calendar defaultValue ) throws IOException 855 { 856 return getEmbeddedDate( embedded, COSName.getPDFName( key ), defaultValue ); 857 } 858 859 /** 860 * This is a convenience method that will get the dictionary object that 861 * is expected to be a date. Null is returned 862 * if the entry does not exist in the dictionary. 863 * 864 * @param embedded The embedded dictionary to get. 865 * @param key The key to the item in the dictionary. 866 * @param defaultValue The default value to return. 867 * @return The name converted to a string. 868 * @throws IOException If there is an error converting to a date. 869 */ 870 public Calendar getEmbeddedDate( String embedded, COSName key, Calendar defaultValue ) throws IOException 871 { 872 Calendar retval = defaultValue; 873 COSDictionary eDic = (COSDictionary)getDictionaryObject( embedded ); 874 if( eDic != null ) 875 { 876 retval = eDic.getDate( key, defaultValue ); 877 } 878 return retval; 879 } 880 881 /** 882 * This is a convenience method that will get the dictionary object that 883 * is expected to be a cos boolean and convert it to a primitive boolean. 884 * 885 * @param key The key to the item in the dictionary. 886 * @param defaultValue The value returned if the entry is null. 887 * 888 * @return The value converted to a boolean. 889 */ 890 public boolean getBoolean( String key, boolean defaultValue ) 891 { 892 return getBoolean( COSName.getPDFName( key ), defaultValue ); 893 } 894 895 /** 896 * This is a convenience method that will get the dictionary object that 897 * is expected to be a COSBoolean and convert it to a primitive boolean. 898 * 899 * @param key The key to the item in the dictionary. 900 * @param defaultValue The value returned if the entry is null. 901 * 902 * @return The entry converted to a boolean. 903 */ 904 public boolean getBoolean( COSName key, boolean defaultValue ) 905 { 906 boolean retval = defaultValue; 907 COSBase bool = getDictionaryObject( key ); 908 if( bool != null && bool instanceof COSBoolean) 909 { 910 retval = ((COSBoolean)bool).getValue(); 911 } 912 return retval; 913 } 914 915 /** 916 * Get an integer from an embedded dictionary. Useful for 1-1 mappings. default:-1 917 * 918 * @param embeddedDictionary The name of the embedded dictionary. 919 * @param key The key in the embedded dictionary. 920 * 921 * @return The value of the embedded integer. 922 */ 923 public int getEmbeddedInt( String embeddedDictionary, String key ) 924 { 925 return getEmbeddedInt( embeddedDictionary, COSName.getPDFName( key ) ); 926 } 927 928 /** 929 * Get an integer from an embedded dictionary. Useful for 1-1 mappings. default:-1 930 * 931 * @param embeddedDictionary The name of the embedded dictionary. 932 * @param key The key in the embedded dictionary. 933 * 934 * @return The value of the embedded integer. 935 */ 936 public int getEmbeddedInt( String embeddedDictionary, COSName key ) 937 { 938 return getEmbeddedInt( embeddedDictionary, key, -1 ); 939 } 940 941 /** 942 * Get an integer from an embedded dictionary. Useful for 1-1 mappings. 943 * 944 * @param embeddedDictionary The name of the embedded dictionary. 945 * @param key The key in the embedded dictionary. 946 * @param defaultValue The value if there is no embedded dictionary or it does not contain the key. 947 * 948 * @return The value of the embedded integer. 949 */ 950 public int getEmbeddedInt( String embeddedDictionary, String key, int defaultValue ) 951 { 952 return getEmbeddedInt( embeddedDictionary, COSName.getPDFName( key ), defaultValue ); 953 } 954 955 956 /** 957 * Get an integer from an embedded dictionary. Useful for 1-1 mappings. 958 * 959 * @param embeddedDictionary The name of the embedded dictionary. 960 * @param key The key in the embedded dictionary. 961 * @param defaultValue The value if there is no embedded dictionary or it does not contain the key. 962 * 963 * @return The value of the embedded integer. 964 */ 965 public int getEmbeddedInt( String embeddedDictionary, COSName key, int defaultValue ) 966 { 967 int retval = defaultValue; 968 COSDictionary embedded = (COSDictionary)getDictionaryObject( embeddedDictionary ); 969 if( embedded != null ) 970 { 971 retval = embedded.getInt( key, defaultValue ); 972 } 973 return retval; 974 } 975 976 /** 977 * This is a convenience method that will get the dictionary object that 978 * is expected to be an int. -1 is returned if there is no value. 979 * 980 * @param key The key to the item in the dictionary. 981 * @return The integer value. 982 */ 983 public int getInt( String key ) 984 { 985 return getInt( COSName.getPDFName( key ), -1 ); 986 } 987 988 /** 989 * This is a convenience method that will get the dictionary object that 990 * is expected to be an int. -1 is returned if there is no value. 991 * 992 * @param key The key to the item in the dictionary. 993 * @return The integer value.. 994 */ 995 public int getInt( COSName key ) 996 { 997 return getInt( key, -1 ); 998 } 999 1000 /** 1001 * This is a convenience method that will get the dictionary object that 1002 * is expected to be an integer. If the dictionary value is null then the 1003 * default Value will be returned. 1004 * 1005 * @param keyList The key to the item in the dictionary. 1006 * @param defaultValue The value to return if the dictionary item is null. 1007 * @return The integer value. 1008 */ 1009 public int getInt( String[] keyList, int defaultValue ) 1010 { 1011 int retval = defaultValue; 1012 COSBase obj = getDictionaryObject( keyList ); 1013 if( obj != null && obj instanceof COSNumber) 1014 { 1015 retval = ((COSNumber)obj).intValue(); 1016 } 1017 return retval; 1018 } 1019 1020 /** 1021 * This is a convenience method that will get the dictionary object that 1022 * is expected to be an integer. If the dictionary value is null then the 1023 * default Value will be returned. 1024 * 1025 * @param key The key to the item in the dictionary. 1026 * @param defaultValue The value to return if the dictionary item is null. 1027 * @return The integer value. 1028 */ 1029 public int getInt( String key, int defaultValue ) 1030 { 1031 return getInt( COSName.getPDFName( key ), defaultValue ); 1032 } 1033 1034 /** 1035 * This is a convenience method that will get the dictionary object that 1036 * is expected to be an integer. If the dictionary value is null then the 1037 * default Value will be returned. 1038 * 1039 * @param key The key to the item in the dictionary. 1040 * @param defaultValue The value to return if the dictionary item is null. 1041 * @return The integer value. 1042 */ 1043 public int getInt( COSName key, int defaultValue ) 1044 { 1045 int retval = defaultValue; 1046 COSBase obj = getDictionaryObject( key ); 1047 if( obj != null && obj instanceof COSNumber) 1048 { 1049 retval = ((COSNumber)obj).intValue(); 1050 } 1051 return retval; 1052 } 1053 1054 /** 1055 * This is a convenience method that will get the dictionary object that 1056 * is expected to be an long. -1 is returned if there is no value. 1057 * 1058 * @param key The key to the item in the dictionary. 1059 * 1060 * @return The long value. 1061 */ 1062 public long getLong( String key ) 1063 { 1064 return getLong( COSName.getPDFName( key ), -1L ); 1065 } 1066 1067 /** 1068 * This is a convenience method that will get the dictionary object that 1069 * is expected to be an long. -1 is returned if there is no value. 1070 * 1071 * @param key The key to the item in the dictionary. 1072 * @return The long value. 1073 */ 1074 public long getLong( COSName key ) 1075 { 1076 return getLong( key, -1L ); 1077 } 1078 1079 /** 1080 * This is a convenience method that will get the dictionary object that 1081 * is expected to be an long. If the dictionary value is null then the 1082 * default Value will be returned. 1083 * 1084 * @param keyList The key to the item in the dictionary. 1085 * @param defaultValue The value to return if the dictionary item is null. 1086 * @return The long value. 1087 */ 1088 public long getLong( String[] keyList, long defaultValue ) 1089 { 1090 long retval = defaultValue; 1091 COSBase obj = getDictionaryObject( keyList ); 1092 if( obj != null && obj instanceof COSNumber) 1093 { 1094 retval = ((COSNumber)obj).longValue(); 1095 } 1096 return retval; 1097 } 1098 1099 /** 1100 * This is a convenience method that will get the dictionary object that 1101 * is expected to be an integer. If the dictionary value is null then the 1102 * default Value will be returned. 1103 * 1104 * @param key The key to the item in the dictionary. 1105 * @param defaultValue The value to return if the dictionary item is null. 1106 * @return The integer value. 1107 */ 1108 public long getLong( String key, long defaultValue ) 1109 { 1110 return getLong( COSName.getPDFName( key ), defaultValue ); 1111 } 1112 1113 /** 1114 * This is a convenience method that will get the dictionary object that 1115 * is expected to be an integer. If the dictionary value is null then the 1116 * default Value will be returned. 1117 * 1118 * @param key The key to the item in the dictionary. 1119 * @param defaultValue The value to return if the dictionary item is null. 1120 * @return The integer value. 1121 */ 1122 public long getLong( COSName key, long defaultValue ) 1123 { 1124 long retval = defaultValue; 1125 COSBase obj = getDictionaryObject( key ); 1126 if( obj != null && obj instanceof COSNumber) 1127 { 1128 retval = ((COSNumber)obj).longValue(); 1129 } 1130 return retval; 1131 } 1132 1133 /** 1134 * This is a convenience method that will get the dictionary object that 1135 * is expected to be an float. -1 is returned if there is no value. 1136 * 1137 * @param key The key to the item in the dictionary. 1138 * @return The float value. 1139 */ 1140 public float getFloat( String key ) 1141 { 1142 return getFloat( COSName.getPDFName( key ), -1 ); 1143 } 1144 1145 /** 1146 * This is a convenience method that will get the dictionary object that 1147 * is expected to be an float. -1 is returned if there is no value. 1148 * 1149 * @param key The key to the item in the dictionary. 1150 * @return The float value. 1151 */ 1152 public float getFloat( COSName key ) 1153 { 1154 return getFloat( key, -1 ); 1155 } 1156 1157 /** 1158 * This is a convenience method that will get the dictionary object that 1159 * is expected to be a float. If the dictionary value is null then the 1160 * default Value will be returned. 1161 * 1162 * @param key The key to the item in the dictionary. 1163 * @param defaultValue The value to return if the dictionary item is null. 1164 * @return The float value. 1165 */ 1166 public float getFloat( String key, float defaultValue ) 1167 { 1168 return getFloat( COSName.getPDFName( key ), defaultValue ); 1169 } 1170 1171 /** 1172 * This is a convenience method that will get the dictionary object that 1173 * is expected to be an float. If the dictionary value is null then the 1174 * default Value will be returned. 1175 * 1176 * @param key The key to the item in the dictionary. 1177 * @param defaultValue The value to return if the dictionary item is null. 1178 * @return The float value. 1179 */ 1180 public float getFloat( COSName key, float defaultValue ) 1181 { 1182 float retval = defaultValue; 1183 COSBase obj = getDictionaryObject( key ); 1184 if( obj != null && obj instanceof COSNumber) 1185 { 1186 retval = ((COSNumber)obj).floatValue(); 1187 } 1188 return retval; 1189 } 1190 1191 /** 1192 * This will remove an item for the dictionary. This 1193 * will do nothing of the object does not exist. 1194 * 1195 * @param key The key to the item to remove from the dictionary. 1196 */ 1197 public void removeItem( COSName key ) 1198 { 1199 items.remove( key ); 1200 } 1201 1202 /** 1203 * This will do a lookup into the dictionary. 1204 * 1205 * @param key The key to the object. 1206 * 1207 * @return The item that matches the key. 1208 */ 1209 public COSBase getItem( COSName key ) 1210 { 1211 return items.get( key ); 1212 } 1213 1214 /** 1215 * This will get the keys for all objects in the dictionary in the sequence that 1216 * they were added. 1217 * 1218 * @deprecated Use the {@link #entrySet()} method instead. 1219 * @return a list of the keys in the sequence of insertion 1220 */ 1221 public List<COSName> keyList() 1222 { 1223 return new ArrayList<COSName>(items.keySet()); 1224 } 1225 1226 /** 1227 * Returns the names of the entries in this dictionary. The returned 1228 * set is in the order the entries were added to the dictionary. 1229 * 1230 * @since Apache PDFBox 1.1.0 1231 * @return names of the entries in this dictionary 1232 */ 1233 public Set<COSName> keySet() 1234 { 1235 return items.keySet(); 1236 } 1237 1238 /** 1239 * Returns the name-value entries in this dictionary. The returned 1240 * set is in the order the entries were added to the dictionary. 1241 * 1242 * @since Apache PDFBox 1.1.0 1243 * @return name-value entries in this dictionary 1244 */ 1245 public Set<Map.Entry<COSName, COSBase>> entrySet() { 1246 return items.entrySet(); 1247 } 1248 1249 /** 1250 * This will get all of the values for the dictionary. 1251 * 1252 * @return All the values for the dictionary. 1253 */ 1254 public Collection<COSBase> getValues() 1255 { 1256 return items.values(); 1257 } 1258 1259 /** 1260 * visitor pattern double dispatch method. 1261 * 1262 * @param visitor The object to notify when visiting this object. 1263 * @return The object that the visitor returns. 1264 * 1265 * @throws COSVisitorException If there is an error visiting this object. 1266 */ 1267 public Object accept(ICOSVisitor visitor) throws COSVisitorException 1268 { 1269 return visitor.visitFromDictionary(this); 1270 } 1271 1272 /** 1273 * This will add all of the dictionarys keys/values to this dictionary. 1274 * Only called when adding keys to a trailer that already exists. 1275 * 1276 * @param dic The dic to get the keys from. 1277 */ 1278 public void addAll( COSDictionary dic ) 1279 { 1280 for( Map.Entry<COSName, COSBase> entry : dic.entrySet() ) 1281 { 1282 /* 1283 * If we're at a second trailer, we have a linearized 1284 * pdf file, meaning that the first Size entry represents 1285 * all of the objects so we don't need to grab the second. 1286 */ 1287 if(!entry.getKey().getName().equals("Size") 1288 || !items.containsKey(COSName.getPDFName("Size"))) 1289 { 1290 setItem( entry.getKey(), entry.getValue() ); 1291 } 1292 } 1293 } 1294 1295 /** 1296 * This will add all of the dictionarys keys/values to this dictionary, but only 1297 * if they don't already exist. If a key already exists in this dictionary then 1298 * nothing is changed. 1299 * 1300 * @param dic The dic to get the keys from. 1301 */ 1302 public void mergeInto( COSDictionary dic ) 1303 { 1304 for( Map.Entry<COSName, COSBase> entry : dic.entrySet() ) 1305 { 1306 if( getItem( entry.getKey() ) == null ) 1307 { 1308 setItem( entry.getKey(), entry.getValue() ); 1309 } 1310 } 1311 } 1312 1313 /** 1314 * Nice method, gives you every object you want 1315 * Arrays works properly too. Try "P/Annots/[k]/Rect" 1316 * where k means the index of the Annotsarray. 1317 * 1318 * @param objPath the relative path to the object. 1319 * @return the object 1320 */ 1321 public COSBase getObjectFromPath(String objPath) 1322 { 1323 COSBase retval = null; 1324 String[] path = objPath.split(PATH_SEPARATOR); 1325 retval = this; 1326 1327 for (int i = 0; i < path.length; i++) 1328 { 1329 if(retval instanceof COSArray) 1330 { 1331 int idx = new Integer(path[i].replaceAll("\\[","").replaceAll("\\]","")).intValue(); 1332 retval = ((COSArray)retval).getObject(idx); 1333 } 1334 else if (retval instanceof COSDictionary) 1335 { 1336 retval = ((COSDictionary)retval).getDictionaryObject( path[i] ); 1337 } 1338 } 1339 return retval; 1340 } 1341 1342 /** 1343 * {@inheritDoc} 1344 */ 1345 public String toString() 1346 { 1347 StringBuilder retVal = new StringBuilder("COSDictionary{"); 1348 for( COSName key : items.keySet() ) 1349 { 1350 retVal.append("(" + key + ":" + getDictionaryObject(key).toString() + ") "); 1351 } 1352 retVal.append("}"); 1353 return retVal.toString(); 1354 } 1355 1356 1357 }