001: /*
002: * $Id: PdfDictionary.java 2879 2007-08-06 09:10:46Z blowagie $
003: * $Name$
004: *
005: * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
006: *
007: * The contents of this file are subject to the Mozilla Public License Version 1.1
008: * (the "License"); you may not use this file except in compliance with the License.
009: * You may obtain a copy of the License at http://www.mozilla.org/MPL/
010: *
011: * Software distributed under the License is distributed on an "AS IS" basis,
012: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
013: * for the specific language governing rights and limitations under the License.
014: *
015: * The Original Code is 'iText, a free JAVA-PDF library'.
016: *
017: * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
018: * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
019: * All Rights Reserved.
020: * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
021: * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
022: *
023: * Contributor(s): all the names of the contributors are added in the source code
024: * where applicable.
025: *
026: * Alternatively, the contents of this file may be used under the terms of the
027: * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
028: * provisions of LGPL are applicable instead of those above. If you wish to
029: * allow use of your version of this file only under the terms of the LGPL
030: * License and not to allow others to use your version of this file under
031: * the MPL, indicate your decision by deleting the provisions above and
032: * replace them with the notice and other provisions required by the LGPL.
033: * If you do not delete the provisions above, a recipient may use your version
034: * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
035: *
036: * This library is free software; you can redistribute it and/or modify it
037: * under the terms of the MPL as stated above or under the terms of the GNU
038: * Library General Public License as published by the Free Software Foundation;
039: * either version 2 of the License, or any later version.
040: *
041: * This library is distributed in the hope that it will be useful, but WITHOUT
042: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
043: * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
044: * details.
045: *
046: * If you didn't download this code from the following link, you should check if
047: * you aren't using an obsolete version:
048: * http://www.lowagie.com/iText/
049: */
050:
051: package com.lowagie.text.pdf;
052:
053: import java.io.IOException;
054: import java.io.OutputStream;
055: import java.util.HashMap;
056: import java.util.Iterator;
057: import java.util.Set;
058:
059: /**
060: * <CODE>PdfDictionary</CODE> is the Pdf dictionary object.
061: * <P>
062: * A dictionary is an associative table containing pairs of objects. The first element
063: * of each pair is called the <I>key</I> and the second element is called the <I>value</I>.
064: * Unlike dictionaries in the PostScript language, a key must be a <CODE>PdfName</CODE>.
065: * A value can be any kind of <CODE>PdfObject</CODE>, including a dictionary. A dictionary is
066: * generally used to collect and tie together the attributes of a complex object, with each
067: * key-value pair specifying the name and value of an attribute.<BR>
068: * A dictionary is represented by two left angle brackets (<<), followed by a sequence of
069: * key-value pairs, followed by two right angle brackets (>>).<BR>
070: * This object is described in the 'Portable Document Format Reference Manual version 1.7'
071: * section 3.2.6 (page 59-60).
072: * <P>
073: *
074: * @see PdfObject
075: * @see PdfName
076: * @see BadPdfFormatException
077: */
078:
079: public class PdfDictionary extends PdfObject {
080:
081: // static membervariables (types of dictionary's)
082:
083: /** This is a possible type of dictionary */
084: public static final PdfName FONT = PdfName.FONT;
085:
086: /** This is a possible type of dictionary */
087: public static final PdfName OUTLINES = PdfName.OUTLINES;
088:
089: /** This is a possible type of dictionary */
090: public static final PdfName PAGE = PdfName.PAGE;
091:
092: /** This is a possible type of dictionary */
093: public static final PdfName PAGES = PdfName.PAGES;
094:
095: /** This is a possible type of dictionary */
096: public static final PdfName CATALOG = PdfName.CATALOG;
097:
098: // membervariables
099:
100: /** This is the type of this dictionary */
101: private PdfName dictionaryType = null;
102:
103: /** This is the hashmap that contains all the values and keys of the dictionary */
104: protected HashMap hashMap;
105:
106: // constructors
107:
108: /**
109: * Constructs an empty <CODE>PdfDictionary</CODE>-object.
110: */
111:
112: public PdfDictionary() {
113: super (DICTIONARY);
114: hashMap = new HashMap();
115: }
116:
117: /**
118: * Constructs a <CODE>PdfDictionary</CODE>-object of a certain type.
119: *
120: * @param type a <CODE>PdfName</CODE>
121: */
122:
123: public PdfDictionary(PdfName type) {
124: this ();
125: dictionaryType = type;
126: put(PdfName.TYPE, dictionaryType);
127: }
128:
129: // methods overriding some methods in PdfObject
130:
131: /**
132: * Returns the PDF representation of this <CODE>PdfDictionary</CODE>.
133: */
134:
135: public void toPdf(PdfWriter writer, OutputStream os)
136: throws IOException {
137: os.write('<');
138: os.write('<');
139:
140: // loop over all the object-pairs in the HashMap
141: PdfName key;
142: PdfObject value;
143: int type = 0;
144: for (Iterator i = hashMap.keySet().iterator(); i.hasNext();) {
145: key = (PdfName) i.next();
146: value = (PdfObject) hashMap.get(key);
147: key.toPdf(writer, os);
148: type = value.type();
149: if (type != PdfObject.ARRAY && type != PdfObject.DICTIONARY
150: && type != PdfObject.NAME
151: && type != PdfObject.STRING)
152: os.write(' ');
153: value.toPdf(writer, os);
154: }
155: os.write('>');
156: os.write('>');
157: }
158:
159: // methods concerning the HashMap member value
160:
161: /**
162: * Adds a <CODE>PdfObject</CODE> and its key to the <CODE>PdfDictionary</CODE>.
163: * If the value is <CODE>null</CODE> or <CODE>PdfNull</CODE> the key is deleted.
164: *
165: * @param key key of the entry (a <CODE>PdfName</CODE>)
166: * @param value value of the entry (a <CODE>PdfObject</CODE>)
167: */
168:
169: public void put(PdfName key, PdfObject value) {
170: if (value == null || value.isNull())
171: hashMap.remove(key);
172: else
173: hashMap.put(key, value);
174: }
175:
176: /**
177: * Adds a <CODE>PdfObject</CODE> and its key to the <CODE>PdfDictionary</CODE>.
178: * If the value is null it does nothing.
179: *
180: * @param key key of the entry (a <CODE>PdfName</CODE>)
181: * @param value value of the entry (a <CODE>PdfObject</CODE>)
182: */
183: public void putEx(PdfName key, PdfObject value) {
184: if (value == null)
185: return;
186: put(key, value);
187: }
188:
189: /**
190: * Removes a <CODE>PdfObject</CODE> and its key from the <CODE>PdfDictionary</CODE>.
191: *
192: * @param key key of the entry (a <CODE>PdfName</CODE>)
193: */
194:
195: public void remove(PdfName key) {
196: hashMap.remove(key);
197: }
198:
199: /**
200: * Gets a <CODE>PdfObject</CODE> with a certain key from the <CODE>PdfDictionary</CODE>.
201: *
202: * @param key key of the entry (a <CODE>PdfName</CODE>)
203: * @return the previous </CODE>PdfObject</CODE> corresponding with the <VAR>key</VAR>
204: */
205:
206: public PdfObject get(PdfName key) {
207: return (PdfObject) hashMap.get(key);
208: }
209:
210: // methods concerning the type of Dictionary
211:
212: /**
213: * Checks if a <CODE>PdfDictionary</CODE> is of a certain type.
214: *
215: * @param type a type of dictionary
216: * @return <CODE>true</CODE> of <CODE>false</CODE>
217: *
218: * @deprecated
219: */
220:
221: public boolean isDictionaryType(PdfName type) {
222: return type.equals(dictionaryType);
223: }
224:
225: /**
226: * Checks if a <CODE>Dictionary</CODE> is of the type FONT.
227: *
228: * @return <CODE>true</CODE> if it is, <CODE>false</CODE> if it isn't.
229: */
230:
231: public boolean isFont() {
232: return FONT.equals(dictionaryType);
233: }
234:
235: /**
236: * Checks if a <CODE>Dictionary</CODE> is of the type PAGE.
237: *
238: * @return <CODE>true</CODE> if it is, <CODE>false</CODE> if it isn't.
239: */
240:
241: public boolean isPage() {
242: return PAGE.equals(dictionaryType);
243: }
244:
245: /**
246: * Checks if a <CODE>Dictionary</CODE> is of the type PAGES.
247: *
248: * @return <CODE>true</CODE> if it is, <CODE>false</CODE> if it isn't.
249: */
250:
251: public boolean isPages() {
252: return PAGES.equals(dictionaryType);
253: }
254:
255: /**
256: * Checks if a <CODE>Dictionary</CODE> is of the type CATALOG.
257: *
258: * @return <CODE>true</CODE> if it is, <CODE>false</CODE> if it isn't.
259: */
260:
261: public boolean isCatalog() {
262: return CATALOG.equals(dictionaryType);
263: }
264:
265: /**
266: * Checks if a <CODE>Dictionary</CODE> is of the type OUTLINES.
267: *
268: * @return <CODE>true</CODE> if it is, <CODE>false</CODE> if it isn't.
269: */
270:
271: public boolean isOutlineTree() {
272: return OUTLINES.equals(dictionaryType);
273: }
274:
275: public void merge(PdfDictionary other) {
276: hashMap.putAll(other.hashMap);
277: }
278:
279: public void mergeDifferent(PdfDictionary other) {
280: for (Iterator i = other.hashMap.keySet().iterator(); i
281: .hasNext();) {
282: Object key = i.next();
283: if (!hashMap.containsKey(key)) {
284: hashMap.put(key, other.hashMap.get(key));
285: }
286: }
287: }
288:
289: public Set getKeys() {
290: return hashMap.keySet();
291: }
292:
293: public void putAll(PdfDictionary dic) {
294: hashMap.putAll(dic.hashMap);
295: }
296:
297: public int size() {
298: return hashMap.size();
299: }
300:
301: public boolean contains(PdfName key) {
302: return hashMap.containsKey(key);
303: }
304:
305: /**
306: * @see com.lowagie.text.pdf.PdfObject#toString()
307: */
308: public String toString() {
309: if (get(PdfName.TYPE) == null)
310: return "Dictionary";
311: return "Dictionary of type: " + get(PdfName.TYPE);
312: }
313:
314: /**
315: * This function behaves the same as 'get', but will never return an indirect reference,
316: * it will always look such references up and return the actual object.
317: * @param key
318: * @return null, or a non-indirect object
319: */
320: public PdfObject getDirectObject(PdfName key) {
321: return PdfReader.getPdfObject(get(key));
322: }
323:
324: /**
325: * All the getAs functions will return either null, or the specified object type
326: * This function will automatically look up indirect references. There's one obvious
327: * exception, the one that will only return an indirect reference. All direct objects
328: * come back as a null.
329: * Mark A Storer (2/17/06)
330: * @param key
331: * @return the appropriate object in its final type, or null
332: */
333: public PdfDictionary getAsDict(PdfName key) {
334: PdfDictionary dict = null;
335: PdfObject orig = getDirectObject(key);
336: if (orig != null && orig.isDictionary())
337: dict = (PdfDictionary) orig;
338: return dict;
339: }
340:
341: public PdfArray getAsArray(PdfName key) {
342: PdfArray array = null;
343: PdfObject orig = getDirectObject(key);
344: if (orig != null && orig.isArray())
345: array = (PdfArray) orig;
346: return array;
347: }
348:
349: public PdfStream getAsStream(PdfName key) {
350: PdfStream stream = null;
351: PdfObject orig = getDirectObject(key);
352: if (orig != null && orig.isStream())
353: stream = (PdfStream) orig;
354: return stream;
355: }
356:
357: public PdfString getAsString(PdfName key) {
358: PdfString string = null;
359: PdfObject orig = getDirectObject(key);
360: if (orig != null && orig.isString())
361: string = (PdfString) orig;
362: return string;
363: }
364:
365: public PdfNumber getAsNumber(PdfName key) {
366: PdfNumber number = null;
367: PdfObject orig = getDirectObject(key);
368: if (orig != null && orig.isNumber())
369: number = (PdfNumber) orig;
370: return number;
371: }
372:
373: public PdfName getAsName(PdfName key) {
374: PdfName name = null;
375: PdfObject orig = getDirectObject(key);
376: if (orig != null && orig.isName())
377: name = (PdfName) orig;
378: return name;
379: }
380:
381: public PdfBoolean getAsBoolean(PdfName key) {
382: PdfBoolean bool = null;
383: PdfObject orig = getDirectObject(key);
384: if (orig != null && orig.isBoolean())
385: bool = (PdfBoolean) orig;
386: return bool;
387: }
388:
389: public PdfIndirectReference getAsIndirectObject(PdfName key) {
390: PdfIndirectReference ref = null;
391: PdfObject orig = get(key); // not getDirect this time.
392: if (orig != null && orig.isIndirect())
393: ref = (PdfIndirectReference) orig;
394: return ref;
395: }
396: }
|