/**
 * Copyright (c) 2011 Michael Kutschke.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Michael Kutschke - initial API and implementation.
 */
package bayesnet.jayes.io.xmlbif;

import static bayesnet.jayes.io.xmlbif.Constants.DEFINITION;
import static bayesnet.jayes.io.xmlbif.Constants.FOR;
import static bayesnet.jayes.io.xmlbif.Constants.GIVEN;
import static bayesnet.jayes.io.xmlbif.Constants.NAME;
import static bayesnet.jayes.io.xmlbif.Constants.OUTCOME;
import static bayesnet.jayes.io.xmlbif.Constants.TABLE;
import static bayesnet.jayes.io.xmlbif.Constants.VARIABLE;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;

import org.apache.commons.lang3.StringEscapeUtils;

import bayesnet.jayes.BayesNet;
import bayesnet.jayes.BayesNode;
import bayesnet.jayes.io.IBayesNetWriter;
import bayesnet.jayes.io.util.XMLUtil;

/**
 * a Writer thats writes the XMLBIF v0.3 format (specification)
 */
public class XMLBIFWriter implements IBayesNetWriter {

    private static final String XML_HEADER = "\n";
    private static final String COMMENT = "\n";
    private static final String DTD = "\n" + "\n" + "\t\t\n"
            + "\t\n"
            + "\t\n" + "\t\n"
            + "\t\t\n"
            + "\t\n" + "\t\n"
            + "\t\n" + "\t\n" + "\t\n"
            + "\t\n" + "]>\n";

    private final Writer wrtr;

    public XMLBIFWriter(OutputStream out) {
        this.wrtr = new OutputStreamWriter(out);
    }

    public void write(BayesNet net) throws IOException {
        StringBuilder bldr = new StringBuilder();
        bldr.append(XML_HEADER);
        bldr.append(COMMENT);
        bldr.append(DTD);

        int offset = bldr.length();
        bldr.append(net.getName());
        XMLUtil.surround(offset, bldr, NAME);

        bldr.append("\n\n");

        writeVariables(bldr, net);

        bldr.append("\n\n");

        writeVariableDefs(bldr, net);

        XMLUtil.surround(offset, bldr, "NETWORK");
        XMLUtil.surround(offset, bldr, "BIF", "VERSION", "0.3");

        wrtr.write(bldr.toString());
        wrtr.flush();
    }

    private void writeVariableDefs(StringBuilder bldr, BayesNet net) {
        for (BayesNode node : net.getNodes()) {
            int offset = bldr.length();
            bldr.append(node.getName());
            XMLUtil.surround(offset, bldr, FOR);
            writeParents(bldr, node);
            writeProbabilities(bldr, node);
            XMLUtil.surround(offset, bldr, DEFINITION);
        }
    }

    private void writeParents(StringBuilder bldr, BayesNode node) {
        for (BayesNode parent : node.getParents()) {
            bldr.append("\n\t");
            int offset = bldr.length();
            bldr.append(parent.getName());
            XMLUtil.surround(offset, bldr, GIVEN);
        }
    }

    private void writeProbabilities(StringBuilder bldr, BayesNode node) {
        if (node.getProbabilities().length == 0) {
            throw new IllegalArgumentException("Bayesian Network is broken: " + node.getName()
                    + " has an empty conditional probability table");
        }
        int offset = bldr.length();
        for (double d : node.getProbabilities()) {
            bldr.append(d);
            bldr.append(' ');
        }
        bldr.deleteCharAt(bldr.length() - 1); // delete last whitespace
        XMLUtil.surround(offset, bldr, TABLE);
    }

    private void writeVariables(StringBuilder bldr, BayesNet net) {
        for (BayesNode node : net.getNodes()) {
            int offset = bldr.length();
            bldr.append(node.getName());
            XMLUtil.surround(offset, bldr, NAME);
            bldr.append("\n");
            for (String outcome : node.getOutcomes()) {
                int offset2 = bldr.length();
                bldr.append(StringEscapeUtils.escapeXml(outcome));
                XMLUtil.surround(offset2, bldr, OUTCOME);
                bldr.append("\n");
            }
            XMLUtil.surround(offset, bldr, VARIABLE);
        }
    }

    @Override
    public void close() throws IOException {
        wrtr.close();
    }
}

 

Ads help maintain this website.