KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > pdfbox > pdmodel > common > COSArrayList


1 /**
2  * Copyright (c) 2003-2006, www.pdfbox.org
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  * 3. Neither the name of pdfbox; nor the names of its
14  * contributors may be used to endorse or promote products derived from this
15  * software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  * http://www.pdfbox.org
29  *
30  */

31 package org.pdfbox.pdmodel.common;
32
33 import org.pdfbox.cos.COSArray;
34 import org.pdfbox.cos.COSBase;
35 import org.pdfbox.cos.COSDictionary;
36 import org.pdfbox.cos.COSInteger;
37 import org.pdfbox.cos.COSFloat;
38 import org.pdfbox.cos.COSString;
39 import org.pdfbox.cos.COSName;
40 import org.pdfbox.cos.COSNull;
41 import org.pdfbox.cos.COSNumber;
42
43 import java.util.ArrayList JavaDoc;
44 import java.util.Collection JavaDoc;
45 import java.util.Iterator JavaDoc;
46 import java.util.List JavaDoc;
47 import java.util.ListIterator JavaDoc;
48
49 /**
50  * This is an implementation of a List that will sync its contents to a COSArray.
51  *
52  * @author <a HREF="mailto:ben@benlitchfield.com">Ben Litchfield</a>
53  * @version $Revision: 1.15 $
54  */

55 public class COSArrayList implements List JavaDoc
56 {
57     private COSArray array;
58     private List JavaDoc actual;
59     
60     private COSDictionary parentDict;
61     private String JavaDoc dictKey;
62     
63     /**
64      * Default constructor.
65      */

66     public COSArrayList()
67     {
68         array = new COSArray();
69         actual = new ArrayList JavaDoc();
70     }
71
72     /**
73      * Constructor.
74      *
75      * @param actualList The list of standard java objects
76      * @param cosArray The COS array object to sync to.
77      */

78     public COSArrayList( List JavaDoc actualList, COSArray cosArray )
79     {
80         actual = actualList;
81         array = cosArray;
82     }
83     
84     /**
85      * This is a really special constructor. Sometimes the PDF spec says
86      * that a dictionary entry can either be a single item or an array of those
87      * items. But in the PDModel interface we really just want to always return
88      * a java.util.List. In the case were we get the list and never modify it
89      * we don't want to convert to COSArray and put one element, unless we append
90      * to the list. So here we are going to create this object with a single
91      * item instead of a list, but allow more items to be added and then converted
92      * to an array.
93      *
94      * @param actualObject The PDModel object.
95      * @param item The COS Model object.
96      * @param dictionary The dictionary that holds the item, and will hold the array if an item is added.
97      * @param dictionaryKey The key into the dictionary to set the item.
98      */

99     public COSArrayList( Object JavaDoc actualObject, COSBase item, COSDictionary dictionary, String JavaDoc dictionaryKey )
100     {
101         array = new COSArray();
102         array.add( item );
103         actual = new ArrayList JavaDoc();
104         actual.add( actualObject );
105         
106         parentDict = dictionary;
107         dictKey = dictionaryKey;
108     }
109
110     /**
111      * {@inheritDoc}
112      */

113     public int size()
114     {
115         return actual.size();
116     }
117
118     /**
119      * {@inheritDoc}
120      */

121     public boolean isEmpty()
122     {
123         return actual.isEmpty();
124     }
125
126     /**
127      * {@inheritDoc}
128      */

129     public boolean contains(Object JavaDoc o)
130     {
131         return actual.contains(o);
132     }
133
134     /**
135      * {@inheritDoc}
136      */

137     public Iterator JavaDoc iterator()
138     {
139         return actual.iterator();
140     }
141
142     /**
143      * {@inheritDoc}
144      */

145     public Object JavaDoc[] toArray()
146     {
147         return actual.toArray();
148     }
149
150     /**
151      * {@inheritDoc}
152      */

153     public Object JavaDoc[] toArray(Object JavaDoc[] a)
154     {
155         return actual.toArray(a);
156
157     }
158
159     /**
160      * {@inheritDoc}
161      */

162     public boolean add(Object JavaDoc o)
163     {
164         //when adding if there is a parentDict then change the item
165
//in the dictionary from a single item to an array.
166
if( parentDict != null )
167         {
168             parentDict.setItem( dictKey, array );
169             //clear the parent dict so it doesn't happen again, there might be
170
//a usecase for keeping the parentDict around but not now.
171
parentDict = null;
172         }
173         //string is a special case because we can't subclass to be COSObjectable
174
if( o instanceof String JavaDoc )
175         {
176             array.add( new COSString( (String JavaDoc)o ) );
177         }
178         else if( o instanceof DualCOSObjectable )
179         {
180             DualCOSObjectable dual = (DualCOSObjectable)o;
181             array.add( dual.getFirstCOSObject() );
182             array.add( dual.getSecondCOSObject() );
183         }
184         else
185         {
186             array.add( ((COSObjectable)o).getCOSObject() );
187         }
188         return actual.add(o);
189     }
190
191     /**
192      * {@inheritDoc}
193      */

194     public boolean remove(Object JavaDoc o)
195     {
196         boolean retval = true;
197         int index = actual.indexOf( o );
198         if( index >= 0 )
199         {
200             actual.remove( index );
201             array.remove( index );
202         }
203         else
204         {
205             retval = false;
206         }
207         return retval;
208     }
209
210     /**
211      * {@inheritDoc}
212      */

213     public boolean containsAll(Collection JavaDoc c)
214     {
215         return actual.containsAll( c );
216     }
217
218     /**
219      * {@inheritDoc}
220      */

221     public boolean addAll(Collection JavaDoc c)
222     {
223         //when adding if there is a parentDict then change the item
224
//in the dictionary from a single item to an array.
225
if( parentDict != null && c.size() > 0)
226         {
227             parentDict.setItem( dictKey, array );
228             //clear the parent dict so it doesn't happen again, there might be
229
//a usecase for keeping the parentDict around but not now.
230
parentDict = null;
231         }
232         array.addAll( toCOSObjectList( c ) );
233         return actual.addAll( c );
234     }
235
236     /**
237      * {@inheritDoc}
238      */

239     public boolean addAll(int index, Collection JavaDoc c)
240     {
241         //when adding if there is a parentDict then change the item
242
//in the dictionary from a single item to an array.
243
if( parentDict != null && c.size() > 0)
244         {
245             parentDict.setItem( dictKey, array );
246             //clear the parent dict so it doesn't happen again, there might be
247
//a usecase for keeping the parentDict around but not now.
248
parentDict = null;
249         }
250         
251         if( c.size() >0 && c.toArray()[0] instanceof DualCOSObjectable )
252         {
253             array.addAll( index*2, toCOSObjectList( c ) );
254         }
255         else
256         {
257             array.addAll( index, toCOSObjectList( c ) );
258         }
259         return actual.addAll( index, c );
260     }
261
262     /**
263      * This will take an array of COSNumbers and return a COSArrayList of
264      * java.lang.Integer values.
265      *
266      * @param intArray The existing integer Array.
267      *
268      * @return A list that is part of the core Java collections.
269      */

270     public static List JavaDoc convertIntegerCOSArrayToList( COSArray intArray )
271     {
272         List JavaDoc numbers = new ArrayList JavaDoc();
273         for( int i=0; i<intArray.size(); i++ )
274         {
275             numbers.add( new Integer JavaDoc( ((COSNumber)intArray.get( i )).intValue() ) );
276         }
277         return new COSArrayList( numbers, intArray );
278     }
279
280     /**
281      * This will take an array of COSNumbers and return a COSArrayList of
282      * java.lang.Float values.
283      *
284      * @param floatArray The existing float Array.
285      *
286      * @return The list of Float objects.
287      */

288     public static List JavaDoc convertFloatCOSArrayToList( COSArray floatArray )
289     {
290         List JavaDoc retval = null;
291         if( floatArray != null )
292         {
293             List JavaDoc numbers = new ArrayList JavaDoc();
294             for( int i=0; i<floatArray.size(); i++ )
295             {
296                 numbers.add( new Float JavaDoc( ((COSNumber)floatArray.get( i )).floatValue() ) );
297             }
298             retval = new COSArrayList( numbers, floatArray );
299         }
300         return retval;
301     }
302
303     /**
304      * This will take an array of COSName and return a COSArrayList of
305      * java.lang.String values.
306      *
307      * @param nameArray The existing name Array.
308      *
309      * @return The list of String objects.
310      */

311     public static List JavaDoc convertCOSNameCOSArrayToList( COSArray nameArray )
312     {
313         List JavaDoc retval = null;
314         if( nameArray != null )
315         {
316             List JavaDoc names = new ArrayList JavaDoc();
317             for( int i=0; i<nameArray.size(); i++ )
318             {
319                 names.add( ((COSName)nameArray.getObject( i )).getName() );
320             }
321             retval = new COSArrayList( names, nameArray );
322         }
323         return retval;
324     }
325
326     /**
327      * This will take an array of COSString and return a COSArrayList of
328      * java.lang.String values.
329      *
330      * @param stringArray The existing name Array.
331      *
332      * @return The list of String objects.
333      */

334     public static List JavaDoc convertCOSStringCOSArrayToList( COSArray stringArray )
335     {
336         List JavaDoc retval = null;
337         if( stringArray != null )
338         {
339             List JavaDoc string = new ArrayList JavaDoc();
340             for( int i=0; i<stringArray.size(); i++ )
341             {
342                 string.add( ((COSString)stringArray.getObject( i )).getString() );
343             }
344             retval = new COSArrayList( string, stringArray );
345         }
346         return retval;
347     }
348
349     /**
350      * This will take an list of string objects and return a COSArray of COSName
351      * objects.
352      *
353      * @param strings A list of strings
354      *
355      * @return An array of COSName objects
356      */

357     public static COSArray convertStringListToCOSNameCOSArray( List JavaDoc strings )
358     {
359         COSArray retval = new COSArray();
360         for( int i=0; i<strings.size(); i++ )
361         {
362             Object JavaDoc next = strings.get( i );
363             if( next instanceof COSName )
364             {
365                 retval.add( (COSName)next );
366             }
367             else
368             {
369                 retval.add( COSName.getPDFName( (String JavaDoc)next ) );
370             }
371         }
372         return retval;
373     }
374
375     /**
376      * This will take an list of string objects and return a COSArray of COSName
377      * objects.
378      *
379      * @param strings A list of strings
380      *
381      * @return An array of COSName objects
382      */

383     public static COSArray convertStringListToCOSStringCOSArray( List JavaDoc strings )
384     {
385         COSArray retval = new COSArray();
386         for( int i=0; i<strings.size(); i++ )
387         {
388             retval.add( new COSString( (String JavaDoc)strings.get( i ) ) );
389         }
390         return retval;
391     }
392
393     /**
394      * This will convert a list of COSObjectables to an
395      * array list of COSBase objects.
396      *
397      * @param cosObjectableList A list of COSObjectable.
398      *
399      * @return A list of COSBase.
400      */

401     public static COSArray converterToCOSArray( List JavaDoc cosObjectableList )
402     {
403         COSArray array = null;
404         if( cosObjectableList != null )
405         {
406             if( cosObjectableList instanceof COSArrayList )
407             {
408                 //if it is already a COSArrayList then we don't want to recreate the array, we want to reuse it.
409
array = ((COSArrayList)cosObjectableList).array;
410             }
411             else
412             {
413                 array = new COSArray();
414                 Iterator JavaDoc iter = cosObjectableList.iterator();
415                 while( iter.hasNext() )
416                 {
417                     Object JavaDoc next = iter.next();
418                     if( next instanceof String JavaDoc )
419                     {
420                         array.add( new COSString( (String JavaDoc)next ) );
421                     }
422                     else if( next instanceof Integer JavaDoc || next instanceof Long JavaDoc )
423                     {
424                         array.add( new COSInteger( ((Number JavaDoc)next).longValue() ) );
425                     }
426                     else if( next instanceof Float JavaDoc || next instanceof Double JavaDoc )
427                     {
428                         array.add( new COSFloat( ((Number JavaDoc)next).floatValue() ) );
429                     }
430                     else if( next instanceof COSObjectable )
431                     {
432                         COSObjectable object = (COSObjectable)next;
433                         array.add( object.getCOSObject() );
434                     }
435                     else if( next instanceof DualCOSObjectable )
436                     {
437                         DualCOSObjectable object = (DualCOSObjectable)next;
438                         array.add( object.getFirstCOSObject() );
439                         array.add( object.getSecondCOSObject() );
440                     }
441                     else if( next == null )
442                     {
443                         array.add( COSNull.NULL );
444                     }
445                     else
446                     {
447                         throw new RuntimeException JavaDoc( "Error: Don't know how to convert type to COSBase '" +
448                         next.getClass().getName() + "'" );
449                     }
450                 }
451             }
452         }
453         return array;
454     }
455
456     private List JavaDoc toCOSObjectList( Collection JavaDoc list )
457     {
458         List JavaDoc cosObjects = new ArrayList JavaDoc();
459         Iterator JavaDoc iter = list.iterator();
460         while( iter.hasNext() )
461         {
462             Object JavaDoc next = iter.next();
463             if( next instanceof String JavaDoc )
464             {
465                 cosObjects.add( new COSString( (String JavaDoc)next ) );
466             }
467             else if( next instanceof DualCOSObjectable )
468             {
469                 DualCOSObjectable object = (DualCOSObjectable)next;
470                 array.add( object.getFirstCOSObject() );
471                 array.add( object.getSecondCOSObject() );
472             }
473             else
474             {
475                 COSObjectable cos = (COSObjectable)next;
476                 cosObjects.add( cos.getCOSObject() );
477             }
478         }
479         return cosObjects;
480     }
481
482     /**
483      * {@inheritDoc}
484      */

485     public boolean removeAll(Collection JavaDoc c)
486     {
487         array.removeAll( toCOSObjectList( c ) );
488         return actual.removeAll( c );
489     }
490
491     /**
492      * {@inheritDoc}
493      */

494     public boolean retainAll(Collection JavaDoc c)
495     {
496         array.retainAll( toCOSObjectList( c ) );
497         return actual.retainAll( c );
498     }
499
500     /**
501      * {@inheritDoc}
502      */

503     public void clear()
504     {
505         //when adding if there is a parentDict then change the item
506
//in the dictionary from a single item to an array.
507
if( parentDict != null )
508         {
509             parentDict.setItem( dictKey, (COSBase)null );
510         }
511         actual.clear();
512         array.clear();
513     }
514
515     /**
516      * {@inheritDoc}
517      */

518     public boolean equals(Object JavaDoc o)
519     {
520         return actual.equals( o );
521     }
522
523     /**
524      * {@inheritDoc}
525      */

526     public int hashCode()
527     {
528         return actual.hashCode();
529     }
530
531     /**
532      * {@inheritDoc}
533      */

534     public Object JavaDoc get(int index)
535     {
536         return actual.get( index );
537
538     }
539
540     /**
541      * {@inheritDoc}
542      */

543     public Object JavaDoc set(int index, Object JavaDoc element)
544     {
545         if( element instanceof String JavaDoc )
546         {
547             COSString item = new COSString( (String JavaDoc)element );
548             if( parentDict != null && index == 0 )
549             {
550                 parentDict.setItem( dictKey, item );
551             }
552             array.set( index, item );
553         }
554         else if( element instanceof DualCOSObjectable )
555         {
556             DualCOSObjectable dual = (DualCOSObjectable)element;
557             array.set( index*2, dual.getFirstCOSObject() );
558             array.set( index*2+1, dual.getSecondCOSObject() );
559         }
560         else
561         {
562             if( parentDict != null && index == 0 )
563             {
564                 parentDict.setItem( dictKey, ((COSObjectable)element).getCOSObject() );
565             }
566             array.set( index, ((COSObjectable)element).getCOSObject() );
567         }
568         return actual.set( index, element );
569     }
570
571     /**
572      * {@inheritDoc}
573      */

574     public void add(int index, Object JavaDoc element)
575     {
576         //when adding if there is a parentDict then change the item
577
//in the dictionary from a single item to an array.
578
if( parentDict != null )
579         {
580             parentDict.setItem( dictKey, array );
581             //clear the parent dict so it doesn't happen again, there might be
582
//a usecase for keeping the parentDict around but not now.
583
parentDict = null;
584         }
585         actual.add( index, element );
586         if( element instanceof String JavaDoc )
587         {
588             array.add( index, new COSString( (String JavaDoc)element ) );
589         }
590         else if( element instanceof DualCOSObjectable )
591         {
592             DualCOSObjectable dual = (DualCOSObjectable)element;
593             array.add( index*2, dual.getFirstCOSObject() );
594             array.add( index*2+1, dual.getSecondCOSObject() );
595         }
596         else
597         {
598             array.add( index, ((COSObjectable)element).getCOSObject() );
599         }
600     }
601
602     /**
603      * {@inheritDoc}
604      */

605     public Object JavaDoc remove(int index)
606     {
607         if( array.size() > index && array.get( index ) instanceof DualCOSObjectable )
608         {
609             //remove both objects
610
array.remove( index );
611             array.remove( index );
612         }
613         else
614         {
615             array.remove( index );
616         }
617         return actual.remove( index );
618     }
619
620     /**
621      * {@inheritDoc}
622      */

623     public int indexOf(Object JavaDoc o)
624     {
625         return actual.indexOf( o );
626     }
627
628     /**
629      * {@inheritDoc}
630      */

631     public int lastIndexOf(Object JavaDoc o)
632     {
633         return actual.indexOf( o );
634
635     }
636
637     /**
638      * {@inheritDoc}
639      */

640     public ListIterator JavaDoc listIterator()
641     {
642         return actual.listIterator();
643     }
644
645     /**
646      * {@inheritDoc}
647      */

648     public ListIterator JavaDoc listIterator(int index)
649     {
650         return actual.listIterator( index );
651     }
652
653     /**
654      * {@inheritDoc}
655      */

656     public List JavaDoc subList(int fromIndex, int toIndex)
657     {
658         return actual.subList( fromIndex, toIndex );
659     }
660 }
Popular Tags