// Copyright 2001 freehep package org.freehep.graphicsio.pdf; import java.io.IOException; import java.util.Collection; import java.util.Hashtable; import java.util.Iterator; import java.util.LinkedList; import java.util.Map; import java.util.Vector; /** * This class keeps track of all kinds of objects written to a pdf file and * avoids to write them several times instead of referencing the same object * several times. Right now only encoding tables are supported. * * An implementation for images and paint would be possible. * * @author Simon Fischer * @version $Id: PDFRedundanceTracker.java 8584 2006-08-10 23:06:37Z duns $ */ public class PDFRedundanceTracker { /** * To be implemented by Writers which write objects that may already have * been written. */ public interface Writer { public void writeObject(Object o, PDFRef reference, PDFWriter pdf) throws IOException; } private class Entry { private static final String REF_PREFIX = "PDF_RTObj"; private Object object; private Writer writer; private boolean written; private PDFRef reference; private Object groupID; private Entry(Object o, Object groupID, Writer w) { this.object = o; this.groupID = groupID; this.writer = w; this.written = false; this.reference = pdf.ref(REF_PREFIX + (refCount++)); } } private static int refCount = 1; private PDFWriter pdf; private Map objects; private Vector orderedObjects; // to keep order public PDFRedundanceTracker(PDFWriter pdf) { this.pdf = pdf; objects = new Hashtable(); orderedObjects = new Vector(); } /** * Returns a reference that points to object. When this method * is called several times for the same object (according to its hash code) * the same reference is returned. When writeAll() is called the * writer's writeObject() method will be called once with * object as argument.
* The groupID is only used for getGroup() */ public PDFRef getReference(Object object, Object groupID, Writer writer) { Object o = objects.get(object); if (o != null) { return ((Entry) o).reference; } else { Entry entry = new Entry(object, groupID, writer); objects.put(object, entry); orderedObjects.add(entry); return entry.reference; } } public PDFRef getReference(Object object, Writer writer) { return getReference(object, null, writer); } /** * Writes all objects that are not yet written. If the method is called * several times then each times only the new objects are written. */ public void writeAll() { Iterator i = orderedObjects.iterator(); while (i.hasNext()) { Entry entry = (Entry) i.next(); if (!entry.written) { try { // System.out.println("PDFRT: Writing: " + entry.object); entry.writer .writeObject(entry.object, entry.reference, pdf); entry.written = true; } catch (IOException e) { e.printStackTrace(); } } } } /** Returns all objects belonging to a particular group. */ public Collection getGroup(Object groupID) { Collection result = new LinkedList(); Iterator i = orderedObjects.iterator(); while (i.hasNext()) { Entry entry = (Entry) i.next(); if (groupID.equals(entry.groupID)) { result.add(entry.object); } } return result; } }