001: /*
002: Copyright (C) Etymon Systems, Inc. <http://www.etymon.com/>
003: */
004:
005: package com.etymon.pjx;
006:
007: import java.io.*;
008: import java.util.*;
009:
010: /**
011: Represents the PDF dictionary object.
012: @author Nassib Nassar
013: */
014: public class PdfDictionary extends PdfObject {
015:
016: /**
017: The contents of the dictionary.
018: */
019: protected Map _m;
020:
021: /**
022: A protected constructor intended to be called only from
023: {@link #wrap(Map) wrap(Map)}.
024: */
025: protected PdfDictionary() {
026: }
027:
028: /**
029: Constructs a dictionary object from a map of
030: <code>PdfName</code> keys and <code>PdfObject</code>
031: values.
032: @param m the map containing the keys and values.
033: */
034: public PdfDictionary(Map m) {
035: _m = Collections.unmodifiableMap(new HashMap(m));
036: }
037:
038: protected PdfObject filterContents(PdfObjectFilter f)
039: throws PdfFormatException {
040: Map newMap = new HashMap(_m.size());
041: for (Iterator t = _m.keySet().iterator(); t.hasNext();) {
042:
043: Object obj = t.next();
044: if (!(obj instanceof PdfObject)) {
045: throw new PdfFormatException(
046: "Dictionary key is not a PDF object.");
047: }
048: PdfObject key = (PdfObject) obj;
049: PdfObject keyF = key.filter(f);
050:
051: if (keyF != null) {
052: obj = _m.get(key);
053: if (!(obj instanceof PdfObject)) {
054: throw new PdfFormatException(
055: "Dictionary value is not a PDF object.");
056: }
057: PdfObject valueF = ((PdfObject) obj).filter(f);
058:
059: if (valueF != null) {
060: newMap.put(key, ((PdfObject) obj).filter(f));
061: }
062: }
063:
064: }
065: return f.postFilter(new PdfDictionary(newMap));
066: }
067:
068: public boolean equals(Object obj) {
069:
070: if ((obj == null) || (!(obj instanceof PdfDictionary))) {
071: return false;
072: }
073:
074: return _m.equals(((PdfDictionary) obj)._m);
075: }
076:
077: /**
078: Returns the map of keys and values contained in this
079: dictionary.
080: @return the map of keys and values. The returned
081: <code>Map</code> object is unmodifiable.
082: */
083: public Map getMap() {
084: return _m;
085: }
086:
087: public int hashCode() {
088: return _m.hashCode();
089: }
090:
091: /**
092: A factory for fast construction of this class. The
093: constructed object will be a wrapper around the specified
094: <code>Map</code>. The calling method must ensure that the
095: <code>Map</code> is never externally modified, in order to
096: meet the immutability requirement of {@link PdfObject
097: PdfObject}.
098: @param m the <code>Map</code> to be used to back this
099: dictionary.
100: @return the constructed object.
101: */
102: protected static PdfDictionary wrap(Map m) {
103: PdfDictionary pd = new PdfDictionary();
104: pd._m = Collections.unmodifiableMap(m);
105: return pd;
106: }
107:
108: protected int writePdf(PdfWriter w, boolean spacing)
109: throws IOException {
110:
111: DataOutputStream dos = w.getDataOutputStream();
112:
113: int count = 4; // for << and >>
114:
115: dos.writeBytes("<<");
116:
117: boolean first = true;
118: for (Iterator p = _m.keySet().iterator(); p.hasNext();) {
119: PdfName key = (PdfName) p.next();
120: PdfObject value = (PdfObject) _m.get(key);
121: if (first) {
122: count += key.writePdf(w, false);
123: first = false;
124: } else {
125: count += key.writePdf(w, true);
126: }
127: count += value.writePdf(w, true);
128: }
129:
130: dos.writeBytes(">>");
131:
132: return count;
133:
134: }
135:
136: }
|