package no.priv.garshol.duke;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import no.priv.garshol.duke.utils.XMLPrettyPrinter;
import org.xml.sax.helpers.AttributeListImpl;
/**
* Can write XML configuration files. <b>WARNING</b>: It does not
* completely preserve all aspects of configurations, so be careful.
* @since 1.1
*/
public class ConfigWriter {
private final XMLPrettyPrinter pp;
public ConfigWriter(OutputStream fos) throws FileNotFoundException, UnsupportedEncodingException {
pp = new XMLPrettyPrinter(fos);
}
/**
* Writes the given configuration to the given file.
*/
public void write(Configuration config)
throws IOException {
pp.startDocument();
pp.startElement("duke", null);
// FIXME: here we should write the objects, but that's not
// possible with the current API. we don't need that for the
// genetic algorithm at the moment, but it would be useful.
pp.startElement("schema", null);
writeElement("threshold", "" + config.getThreshold());
if (config.getMaybeThreshold() != 0.0)
writeElement("maybe-threshold", "" + config.getMaybeThreshold());
for (Property p : config.getProperties())
writeProperty(p);
pp.endElement("schema");
String dbclass = config.getDatabase(false).getClass().getName();
AttributeListImpl atts = new AttributeListImpl();
atts.addAttribute("class", "CDATA", dbclass);
pp.startElement("database", atts);
pp.endElement("database");
if (config.isDeduplicationMode())
for (DataSource src : config.getDataSources())
writeDataSource(src);
else {
pp.startElement("group", null);
for (DataSource src : config.getDataSources(1))
writeDataSource(src);
pp.endElement("group");
pp.startElement("group", null);
for (DataSource src : config.getDataSources(2))
writeDataSource(src);
pp.endElement("group");
}
pp.endElement("duke");
pp.endDocument();
}
public void writeParam(String name, String value) {
if (value == null)
return;
AttributeListImpl atts = new AttributeListImpl();
atts.addAttribute("name", "CDATA", name);
atts.addAttribute("value", "CDATA", value);
pp.startElement("param", atts);
pp.endElement("param");
}
public void writeParam(String name, int value) {
writeParam(name, "" + value);
}
public void writeParam(String name, char value) {
writeParam(name, "" + value);
}
public void writeParam(String name, boolean value) {
writeParam(name, "" + value);
}
private void writeElement(String name, String value) {
if (value == null)
return; // saves us having to repeat these tests everywhere
pp.startElement(name, null);
pp.text(value);
pp.endElement(name);
}
private void writeProperty(Property prop) {
AttributeListImpl atts = new AttributeListImpl();
if (prop.isIdProperty())
atts.addAttribute("type", "CDATA", "id");
else if (prop.isIgnoreProperty())
atts.addAttribute("type", "CDATA", "ignore");
if (!prop.isIdProperty() &&
prop.getLookupBehaviour() != Property.Lookup.DEFAULT) {
String value = prop.getLookupBehaviour().toString().toLowerCase();
atts.addAttribute("lookup", "CDATA", value);
}
pp.startElement("property", atts);
writeElement("name", prop.getName());
if (prop.getComparator() != null)
writeElement("comparator", prop.getComparator().getClass().getName());
if (prop.getLowProbability() != 0.0)
writeElement("low", "" + prop.getLowProbability());
if (prop.getHighProbability() != 0.0)
writeElement("high", "" + prop.getHighProbability());
pp.endElement("property");
}
private void writeDataSource(DataSource src) {
src.writeConfig(this);
}
public void writeStartElement(String name, AttributeListImpl atts) {
pp.startElement(name, atts);
}
public void writeEndElement(String name) {
pp.endElement(name);
}
}