// 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;
}
}