001: /*
002: Copyright © 2006 Stefano Chizzolini. http://clown.stefanochizzolini.it
003:
004: Contributors:
005: * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it):
006: contributed code is Copyright © 2006 by Stefano Chizzolini.
007:
008: This file should be part of the source code distribution of "PDF Clown library"
009: (the Program): see the accompanying README files for more info.
010:
011: This Program is free software; you can redistribute it and/or modify it under
012: the terms of the GNU General Public License as published by the Free Software
013: Foundation; either version 2 of the License, or (at your option) any later version.
014:
015: This Program is distributed in the hope that it will be useful, but WITHOUT ANY
016: WARRANTY, either expressed or implied; without even the implied warranty of
017: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
018:
019: You should have received a copy of the GNU General Public License along with this
020: Program (see README files); if not, go to the GNU website (http://www.gnu.org/).
021:
022: Redistribution and use, with or without modification, are permitted provided that such
023: redistributions retain the above copyright notice, license and disclaimer, along with
024: this list of conditions.
025: */
026:
027: package it.stefanochizzolini.clown.documents.interaction.navigation.document;
028:
029: import it.stefanochizzolini.clown.documents.Document;
030: import it.stefanochizzolini.clown.files.File;
031: import it.stefanochizzolini.clown.objects.IPdfNumber;
032: import it.stefanochizzolini.clown.objects.PdfDictionary;
033: import it.stefanochizzolini.clown.objects.PdfDirectObject;
034: import it.stefanochizzolini.clown.objects.PdfInteger;
035: import it.stefanochizzolini.clown.objects.PdfName;
036: import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
037: import it.stefanochizzolini.clown.objects.PdfReference;
038: import it.stefanochizzolini.clown.util.NotImplementedException;
039:
040: import java.util.Collection;
041: import java.util.Iterator;
042: import java.util.List;
043: import java.util.ListIterator;
044: import java.util.NoSuchElementException;
045:
046: /**
047: Collection of bookmarks [PDF:1.6:8.2.2].
048: */
049: public class Bookmarks extends PdfObjectWrapper<PdfDictionary>
050: implements List<Bookmark> {
051: // <class>
052: // <dynamic>
053: // <constructors>
054: public Bookmarks(Document context) {
055: super (context.getFile(), new PdfDictionary(new PdfName[] {
056: PdfName.Type, PdfName.Count }, new PdfDirectObject[] {
057: PdfName.Outlines, new PdfInteger(0) }));
058: }
059:
060: /**
061: <h3>Remarks</h3>
062: <p>For internal use only.</p>
063: */
064: public Bookmarks(PdfDirectObject baseObject) {
065: super (baseObject, null // NO container (bookmark MUST be an indirect object [PDF:1.6:8.2.2]).
066: );
067: }
068:
069: // </constructors>
070:
071: // <interface>
072: // <public>
073: @Override
074: public Bookmarks clone(Document context) {
075: throw new NotImplementedException();
076: }
077:
078: // <List>
079: public void add(int index, Bookmark bookmark) {
080: throw new NotImplementedException();
081: }
082:
083: public boolean addAll(int index,
084: Collection<? extends Bookmark> bookmarks) {
085: throw new NotImplementedException();
086: }
087:
088: public Bookmark get(int index) {
089: PdfReference bookmarkObject = (PdfReference) getBaseDataObject()
090: .get(PdfName.First);
091: while (index > 0) {
092: bookmarkObject = (PdfReference) ((PdfDictionary) File
093: .resolve(bookmarkObject)).get(PdfName.Next);
094: // Did we go past the collection range?
095: if (bookmarkObject == null)
096: throw new IndexOutOfBoundsException();
097:
098: index--;
099: }
100:
101: return new Bookmark(bookmarkObject);
102: }
103:
104: public int indexOf(Object bookmark) {
105: throw new NotImplementedException();
106: }
107:
108: public int lastIndexOf(Object bookmark) {
109: return indexOf(bookmark);
110: }
111:
112: public ListIterator<Bookmark> listIterator() {
113: throw new NotImplementedException();
114: }
115:
116: public ListIterator<Bookmark> listIterator(int index) {
117: throw new NotImplementedException();
118: }
119:
120: public Bookmark remove(int index) {
121: throw new NotImplementedException();
122: }
123:
124: public Bookmark set(int index, Bookmark bookmark) {
125: throw new NotImplementedException();
126: }
127:
128: public List<Bookmark> subList(int fromIndex, int toIndex) {
129: throw new NotImplementedException();
130: }
131:
132: // <Collection>
133: public boolean add(Bookmark bookmark) {
134: /*
135: NOTE: Bookmarks imported from alien PDF files MUST be cloned
136: before being added.
137: */
138: bookmark.getBaseDataObject().put(PdfName.Parent,
139: getBaseObject());
140:
141: PdfInteger countObject = ensureCountObject();
142: // Is it the first bookmark?
143: if (countObject.getValue() == 0) // First bookmark.
144: {
145: getBaseDataObject().put(PdfName.First,
146: bookmark.getBaseObject());
147: getBaseDataObject().put(PdfName.Last,
148: bookmark.getBaseObject());
149:
150: ((IPdfNumber) countObject).translateNumberValue(+1);
151: } else // Non-first bookmark.
152: {
153: PdfReference oldLastBookmarkReference = (PdfReference) getBaseDataObject()
154: .get(PdfName.Last);
155: getBaseDataObject().put(PdfName.Last,
156: bookmark.getBaseObject()); // Added bookmark is the last in the collection...
157: ((PdfDictionary) File.resolve(oldLastBookmarkReference))
158: .put(PdfName.Next, bookmark.getBaseObject()); // ...and the next of the previously-last bookmark.
159: bookmark.getBaseDataObject().put(PdfName.Prev,
160: oldLastBookmarkReference);
161:
162: /*
163: NOTE: The Count entry is a relative number (whose sign represents
164: the node open state).
165: */
166: ((IPdfNumber) countObject).translateNumberValue(Math
167: .signum(countObject.getValue()));
168: }
169:
170: return true;
171: }
172:
173: public boolean addAll(Collection<? extends Bookmark> bookmarks) {
174: throw new NotImplementedException();
175: }
176:
177: public void clear() {
178: throw new NotImplementedException();
179: }
180:
181: public boolean contains(Object bookmark) {
182: throw new NotImplementedException();
183: }
184:
185: public boolean containsAll(Collection<?> bookmarks) {
186: throw new NotImplementedException();
187: }
188:
189: public boolean equals(Object object) {
190: throw new NotImplementedException();
191: }
192:
193: public int hashCode() {
194: throw new NotImplementedException();
195: }
196:
197: public boolean isEmpty() {
198: throw new NotImplementedException();
199: }
200:
201: public boolean remove(Object bookmark) {
202: throw new NotImplementedException();
203: }
204:
205: public boolean removeAll(Collection<?> bookmarks) {
206: throw new NotImplementedException();
207: }
208:
209: public boolean retainAll(Collection<?> bookmarks) {
210: throw new NotImplementedException();
211: }
212:
213: public int size() {
214: /*
215: NOTE: The Count entry may be absent [PDF:1.6:8.2.2].
216: */
217: PdfInteger countObject = (PdfInteger) getBaseDataObject().get(
218: PdfName.Count);
219: if (countObject == null)
220: return 0;
221: else
222: return countObject.getValue();
223: }
224:
225: public Bookmark[] toArray() {
226: throw new NotImplementedException();
227: }
228:
229: public <Bookmark> Bookmark[] toArray(Bookmark[] bookmarks) {
230: throw new NotImplementedException();
231: }
232:
233: // <Iterable>
234: public Iterator<Bookmark> iterator() {
235: return new Iterator<Bookmark>() {
236: // <class>
237: // <dynamic>
238: // <fields>
239: /**
240: Current bookmark.
241: */
242: private PdfDirectObject currentBookmarkObject = null;
243: /**
244: Next bookmark.
245: */
246: private PdfDirectObject nextBookmarkObject = getBaseDataObject()
247: .get(PdfName.First);
248:
249: // </fields>
250:
251: // <interface>
252: // <public>
253: // <Iterator>
254: public boolean hasNext() {
255: return (nextBookmarkObject != null);
256: }
257:
258: public Bookmark next() {
259: if (!hasNext())
260: throw new NoSuchElementException();
261:
262: currentBookmarkObject = nextBookmarkObject;
263: nextBookmarkObject = ((PdfDictionary) File
264: .resolve(currentBookmarkObject))
265: .get(PdfName.Next);
266:
267: return new Bookmark(currentBookmarkObject);
268: }
269:
270: public void remove() {
271: throw new UnsupportedOperationException();
272: }
273: // </Iterator>
274: // </public>
275: // </interface>
276: // </dynamic>
277: // </class>
278: };
279: }
280:
281: // </Iterable>
282: // </Collection>
283: // </List>
284: // </public>
285:
286: // <protected>
287: /**
288: Gets the count object, forcing its creation if it doesn't exist.
289: */
290: protected PdfInteger ensureCountObject() {
291: /*
292: NOTE: The Count entry may be absent [PDF:1.6:8.2.2].
293: */
294: PdfInteger countObject = (PdfInteger) getBaseDataObject().get(
295: PdfName.Count);
296: if (countObject == null)
297: getBaseDataObject().put(PdfName.Count,
298: countObject = new PdfInteger(0));
299:
300: return countObject;
301: }
302: // </protected>
303: // </interface>
304: // </dynamic>
305: // </class>
306: }
|