001: /*
002: Copyright © 2007 Stefano Chizzolini. http://clown.stefanochizzolini.it
003:
004: Contributors:
005: * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it):
006: contributed code is Copyright © 2007 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.objects;
028:
029: import it.stefanochizzolini.clown.documents.Document;
030: import it.stefanochizzolini.clown.files.File;
031: import it.stefanochizzolini.clown.util.NotImplementedException;
032:
033: import java.util.Collection;
034: import java.util.Map;
035: import java.util.Set;
036:
037: /**
038: Name tree [PDF:1.6:3.8.5].
039:
040: @author Stefano Chizzolini
041: @version 0.0.4
042: @since 0.0.4
043: */
044: public abstract class PdfNameTree<T extends PdfObjectWrapper<?>>
045: extends PdfObjectWrapper<PdfDictionary> implements
046: Map<PdfLiteral, T> {
047: /*
048: TODO:IMPL A B-tree algorithm should be implemented to optimize the inner layout
049: of the name tree (better insertion/deletion performance). In this case, it would
050: be necessary to keep track of the modified tree nodes for incremental update.
051: */
052: // <class>
053: // <dynamic>
054: // <constructors>
055: public PdfNameTree(Document context) {
056: super (context.getFile(), new PdfDictionary(
057: new PdfName[] { PdfName.Names },
058: new PdfDirectObject[] { new PdfArray() }));
059: }
060:
061: public PdfNameTree(PdfDirectObject baseObject,
062: PdfIndirectObject container) {
063: super (baseObject, container);
064: }
065:
066: // </constructors>
067:
068: // <interface>
069: // <public>
070: public Object clone(Document context) {
071: throw new NotImplementedException();
072: }
073:
074: // <Map>
075: public void clear() {
076: throw new NotImplementedException();
077: }
078:
079: public boolean containsKey(Object key) {
080: throw new NotImplementedException();
081: }
082:
083: public boolean containsValue(Object value) {
084: throw new NotImplementedException();
085: }
086:
087: public Set<Map.Entry<PdfLiteral, T>> entrySet() {
088: throw new NotImplementedException();
089: }
090:
091: public boolean equals(Object object) {
092: throw new NotImplementedException();
093: }
094:
095: public T get(Object key) {
096: String keyString = ((PdfLiteral) key).getValue();
097: PdfDirectObject containerObject = getBaseObject();
098: PdfDictionary parent = getBaseDataObject();
099: while (true) {
100: PdfDirectObject namesObject = parent.get(PdfName.Names);
101: // Intermediate node?
102: if (namesObject == null) {
103: PdfArray kids = (PdfArray) File.resolve(parent
104: .get(PdfName.Kids));
105: int low = 0, high = kids.size() - 1;
106: while (true) {
107: if (low > high)
108: return null;
109:
110: int mid = (low + high) / 2;
111: PdfDirectObject kidObject = kids.get(mid);
112: PdfDictionary kid = (PdfDictionary) File
113: .resolve(kidObject);
114: PdfArray limits = (PdfArray) File.resolve(kid
115: .get(PdfName.Limits));
116: // Compare to the lower limit!
117: int comparison = keyString
118: .compareTo(((PdfLiteral) limits.get(0))
119: .getValue());
120: if (comparison < 0) {
121: high = mid - 1;
122: } else {
123: // Compare to the upper limit!
124: comparison = keyString
125: .compareTo(((PdfLiteral) limits.get(1))
126: .getValue());
127: if (comparison > 0) {
128: low = mid + 1;
129: } else {
130: // Go down one level!
131: containerObject = kidObject; // NOTE: Node children MUST be indirectly referenced.
132: parent = kid;
133: break;
134: }
135: }
136: }
137: } else // Leaf node.
138: {
139: if (namesObject instanceof PdfReference) {
140: containerObject = namesObject;
141: }
142:
143: PdfArray names = (PdfArray) File.resolve(namesObject);
144: int low = 0, high = names.size();
145: while (true) {
146: if (low > high)
147: return null;
148:
149: int mid = (mid = ((low + high) / 2)) - (mid % 2);
150: int comparison = keyString
151: .compareTo(((PdfLiteral) names.get(mid))
152: .getValue());
153: if (comparison < 0) {
154: high = mid - 2;
155: } else if (comparison > 0) {
156: low = mid + 2;
157: } else {
158: // We got it!
159: return wrap(names.get(mid + 1),
160: ((PdfReference) containerObject)
161: .getIndirectObject());
162: }
163: }
164: }
165: }
166: }
167:
168: public int hashCode() {
169: throw new NotImplementedException();
170: }
171:
172: public boolean isEmpty() {
173: throw new NotImplementedException();
174: }
175:
176: public Set<PdfLiteral> keySet() {
177: throw new NotImplementedException();
178: }
179:
180: public T put(PdfLiteral key, T value) {
181: throw new NotImplementedException();
182: }
183:
184: public void putAll(Map<? extends PdfLiteral, ? extends T> entries) {
185: throw new NotImplementedException();
186: }
187:
188: public T remove(Object key) {
189: throw new NotImplementedException();
190: }
191:
192: public int size() {
193: throw new NotImplementedException();
194: }
195:
196: public Collection<T> values() {
197: throw new NotImplementedException();
198: }
199:
200: // </Map>
201: // </public>
202:
203: // <protected>
204: /**
205: Wraps a base object within its corresponding high-level representation.
206: */
207: protected abstract T wrap(PdfDirectObject baseObject,
208: PdfIndirectObject container);
209: // </protected>
210: // </interface>
211: // </dynamic>
212: // </class>
213: }
|