001: /*
002: Copyright © 2006,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 © 2006,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.bytes.IOutputStream;
030: import it.stefanochizzolini.clown.files.File;
031: import it.stefanochizzolini.clown.util.NotImplementedException;
032:
033: import java.util.Collection;
034: import java.util.HashMap;
035: import java.util.Map;
036: import java.util.Set;
037:
038: /**
039: PDF dictionary object.
040: @version 0.0.5
041: @since 0.0.0
042: */
043: public class PdfDictionary extends PdfDirectObject implements
044: Map<PdfName, PdfDirectObject> {
045: // <class>
046: // <dynamic>
047: // <fields>
048: private HashMap<PdfName, PdfDirectObject> entries;
049:
050: // </fields>
051:
052: // <constructors>
053: public PdfDictionary() {
054: entries = new HashMap<PdfName, PdfDirectObject>();
055: }
056:
057: public PdfDictionary(int capacity) {
058: entries = new HashMap<PdfName, PdfDirectObject>(capacity);
059: }
060:
061: public PdfDictionary(PdfName[] keys, PdfDirectObject[] values) {
062: this (values.length);
063:
064: for (int index = 0; index < values.length; index++) {
065: put(keys[index], values[index]);
066: }
067: }
068:
069: // </constructors>
070:
071: // <interface>
072: // <public>
073: @Override
074: public Object clone(File context) {
075: //TODO:IMPL redefine to support real cloning (current implementation is prone to object slicing hazard)!!!
076: PdfDictionary clone = new PdfDictionary(entries.size());
077:
078: for (Map.Entry<PdfName, PdfDirectObject> entry : entries
079: .entrySet()) {
080: clone.put(entry.getKey(), (PdfDirectObject) entry
081: .getValue().clone(context));
082: }
083:
084: return clone;
085: }
086:
087: /**
088: Gets the key associated to a given value.
089: */
090: public PdfName getKey(PdfDirectObject value) {
091: /*
092: NOTE: Current PdfDictionary implementation doesn't support bidirectional
093: maps, to say that the only currently-available way to retrieve a key from a
094: value is to iterate the whole map (really poor performance!).
095: NOTE: Complex high-level matches are not verified (too expensive!), to say that
096: if the searched high-level object (font, xobject, colorspace etc.) has a
097: PdfReference base-object while some high-level objects in the
098: collection have other direct type (PdfName, for example) base-objects, they
099: won't match in any case (even if they represent the SAME high-level object --
100: but that should be a rare case...).
101: */
102: for (Map.Entry<PdfName, PdfDirectObject> entry : entries
103: .entrySet()) {
104: if (entry.getValue().equals(value))
105: return entry.getKey(); // Found.
106: }
107:
108: return null; // Not found.
109: }
110:
111: /**
112: @version 0.0.5
113: */
114: @Override
115: public String toPdf() {
116: StringBuilder buffer = new StringBuilder();
117:
118: // Begin.
119: buffer.append("<< ");
120:
121: // Entries.
122: for (Map.Entry<PdfName, PdfDirectObject> entry : entries
123: .entrySet()) {
124: // Entry...
125: // ...key.
126: buffer.append(entry.getKey().toPdf() + " ");
127:
128: // ...value.
129: buffer.append(entry.getValue().toPdf() + " ");
130: }
131:
132: // End.
133: buffer.append(">>");
134:
135: return buffer.toString();
136: }
137:
138: @Override
139: public String toString() {
140: StringBuilder buffer = new StringBuilder();
141:
142: // Begin.
143: buffer.append("<< ");
144:
145: // Entries.
146: for (Map.Entry<PdfName, PdfDirectObject> entry : entries
147: .entrySet()) {
148: // Entry...
149: // ...key.
150: buffer.append(entry.getKey().toString() + " ");
151:
152: // ...value.
153: buffer.append(entry.getValue().toString() + " ");
154: }
155:
156: // End.
157: buffer.append(">>");
158:
159: return buffer.toString();
160: }
161:
162: // <Map>
163: public void clear() {
164: entries.clear();
165: }
166:
167: public boolean containsKey(Object key) {
168: return entries.containsKey(key);
169: }
170:
171: public boolean containsValue(Object value) {
172: return entries.containsValue(value);
173: }
174:
175: public Set<Map.Entry<PdfName, PdfDirectObject>> entrySet() {
176: return entries.entrySet();
177: }
178:
179: public boolean equals(Object object) {
180: throw new NotImplementedException();
181: }
182:
183: public PdfDirectObject get(Object key) {
184: return entries.get(key);
185: }
186:
187: public int hashCode() {
188: return entries.hashCode();
189: }
190:
191: public boolean isEmpty() {
192: return entries.isEmpty();
193: }
194:
195: public Set<PdfName> keySet() {
196: return entries.keySet();
197: }
198:
199: public PdfDirectObject put(PdfName key, PdfDirectObject value) {
200: return entries.put(key, value);
201: }
202:
203: public void putAll(
204: Map<? extends PdfName, ? extends PdfDirectObject> entries) {
205: this .entries.putAll(entries);
206: }
207:
208: public PdfDirectObject remove(Object key) {
209: return entries.remove(key);
210: }
211:
212: public int size() {
213: return entries.size();
214: }
215:
216: public Collection<PdfDirectObject> values() {
217: return entries.values();
218: }
219:
220: // </Map>
221: // </public>
222:
223: // <internal>
224: /**
225: <h3>Remarks</h3>
226: <p>For internal use only.</p>
227: */
228: @Override
229: public int writeTo(IOutputStream stream) {
230: // Begin.
231: int size = stream.write("<< ");
232:
233: // Entries.
234: for (Map.Entry<PdfName, PdfDirectObject> entry : entries
235: .entrySet()) {
236: // Entry...
237: // ...key.
238: size += entry.getKey().writeTo(stream);
239: size += stream.write(" ");
240:
241: // ...value.
242: size += entry.getValue().writeTo(stream);
243: size += stream.write(" ");
244: }
245:
246: // End.
247: size += stream.write(">>");
248:
249: return size;
250: }
251: // </internal>
252: // </interface>
253: // </dynamic>
254: // </class>
255: }
|