Package org.integratedmodelling.riskwiz.io.xmlbif

Source Code of org.integratedmodelling.riskwiz.io.xmlbif.XmlBifReader

/**
* XmlBifReader.java
* ----------------------------------------------------------------------------------
*
* Copyright (C) 2008 www.integratedmodelling.org
* Created: Mar 6, 2008
*
* ----------------------------------------------------------------------------------
* This file is part of RiskWiz.
*
* RiskWiz is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* RiskWiz is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the software; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*
* ----------------------------------------------------------------------------------
*
* @copyright 2008 www.integratedmodelling.org
* @author    Sergey Krivov
* @date      Mar 6, 2008
* @license   http://www.gnu.org/licenses/gpl.txt GNU General Public License v3
* @link      http://www.integratedmodelling.org
**/

package org.integratedmodelling.riskwiz.io.xmlbif;


import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.StringTokenizer;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.integratedmodelling.riskwiz.Setting;
import org.integratedmodelling.riskwiz.bn.BNNode;
import org.integratedmodelling.riskwiz.bn.BeliefNetwork;
import org.integratedmodelling.riskwiz.domain.LabelDomain;
import org.integratedmodelling.riskwiz.io.IOUtil;
import org.integratedmodelling.riskwiz.pfunction.TabularFunction;
import org.nfunk.jep.ParseException;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


/**
* @author Sergey Krivov
*
*/
public class XmlBifReader {

    /**
     *
     */
    public XmlBifReader() {// TODO Auto-generated constructor stub
    }

    protected BeliefNetwork graph = null;

    protected boolean rowFirst = true;

    public BeliefNetwork loadFromFile(String name) {

        FileInputStream fis = null;

        try {
            fis = new FileInputStream(name);
        } catch (Exception e) {
            System.out.println("File " + name + " not found");
        }   
        return load(fis);

    }

    public BeliefNetwork load(InputStream stream) {
        Document doc;
        DocumentBuilder parser;
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

        factory.setValidating(true);
        factory.setNamespaceAware(true);

        // Parse the document
        try {
            parser = factory.newDocumentBuilder();
            doc = parser.parse(stream);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        visitDocument(doc);
        System.gc();
        return graph;
    }

    public void visitDocument(Node parent) {
        NodeList l = parent.getChildNodes();

        if (l == null) {
            throw new RuntimeException("Unexpected end of document!");
        }
        int max = l.getLength();

        for (int i = 0; i < max; i++) {
            Node node = l.item(i);

            switch (node.getNodeType()) {
            case Node.ELEMENT_NODE:
                String name = node.getNodeName();

                if (name.equals("BIF")) { 
                    NamedNodeMap attrs = node.getAttributes();

                    if (attrs != null) {
                        int amax = attrs.getLength();

                        for (int j = 0; j < amax; j++) {
                            Node attr = attrs.item(j);
                            String aname = attr.getNodeName().toUpperCase();

                            if (aname.equals("VERSION")) { 
                                rowFirst = true;
                                try {
                                    double ver = Double.parseDouble(
                                            attr.getNodeValue());

                                    if (ver >= 0.3) {
                                        rowFirst = false;
                                    }
                                } catch (Exception exx) {}
                            }
                        }
                    }
                    visitDocument(node);
                } else if (name.equals("NETWORK")) { 
                    visitModel(node);
                    // if multi-model, add beliefNetwork to a list
                } else {
                    throw new RuntimeException("Unhandled element " + name);
                }
                break;

            case Node.DOCUMENT_TYPE_NODE:
            case Node.DOCUMENT_NODE:
            case Node.COMMENT_NODE:
            case Node.TEXT_NODE:
                // Ignore this
                break;

            default:
                if (Setting.DEBUG) {
                    System.out.println("Unhandled node " + node.getNodeName());
                }
            }
        }
    }

    public void visitModel(Node parent) {
        graph = new BeliefNetwork();
        NodeList l = parent.getChildNodes();

        if (l == null) {
            throw new RuntimeException("Unexpected end of document!");
        }
        int max = l.getLength();

        // Split into two loops so that it can handle forward reference
        for (int i = 0; i < max; i++) {
            Node node = l.item(i);

            switch (node.getNodeType()) {
            case Node.ELEMENT_NODE:
                String name = node.getNodeName();

                if (name.equals("NAME")) { 
                    graph.setName(getElementValue(node));
                } else if (name.equals("VARIABLE")) { 
                    BNNode bbnnode = visitVariable(node);

                    graph.addVertex(bbnnode);
                }
                break;

            case Node.DOCUMENT_TYPE_NODE:
            case Node.DOCUMENT_NODE:
            case Node.COMMENT_NODE:
            case Node.TEXT_NODE:
                // Ignore this
                break;

            default:
                if (Setting.DEBUG) {
                    System.out.println("Unhandled node " + node.getNodeName());
                }
            }
        }

        for (int i = 0; i < max; i++) {
            Node node = l.item(i);

            switch (node.getNodeType()) {
            case Node.ELEMENT_NODE:
                String name = node.getNodeName();

                if (name.equals("DEFINITION") || name.equals("PROBABILITY")) { 
                    visitDefinition(node);
                }
                break;

            case Node.DOCUMENT_TYPE_NODE:
            case Node.DOCUMENT_NODE:
            case Node.COMMENT_NODE:
            case Node.TEXT_NODE:
                // Ignore this
                break;

            default:
                if (Setting.DEBUG) {
                    System.out.println("Unhandled node " + node.getNodeName());
                }
            }
        }
    }

    protected BNNode visitVariable(Node parent) {
        NodeList l = parent.getChildNodes();

        BNNode bbnnode = null; // = new BeliefNode("XXX");
        int max;
        String propType = "nature"
        NamedNodeMap attrs = parent.getAttributes();

        if (attrs != null) {
            max = attrs.getLength();
            for (int i = 0; i < max; i++) {
                Node attr = attrs.item(i);
                String name = attr.getNodeName();
                String value = attr.getNodeValue();

                if (name.equals("TYPE")) { 
                    propType = value;
                    if (value.equals("decision")) { 
                        bbnnode = new BNNode("XXX", BNNode.NodeType.decision);
                    } else if (value.equals("utility")) { 
                        bbnnode = new BNNode("XXX", BNNode.NodeType.utility);
                    } else { // otherwise it's just "nature"
                        bbnnode = new BNNode("XXX",
                                BNNode.NodeType.probabilistic);
                    }
                } else if (Setting.DEBUG) {
                    System.out.println(
                            "Unhandled variable property attribute " + name);
                }
            }
        }

        if (!propType.equals("nature") && !propType.equals("decision")
                && !propType.equals("utility")) { // $NON-NLS-1$
            throw new RuntimeException("Unknown node type " + propType);
        }

        if (l == null) {
            return null;
        }
        LinkedList<String> values = new LinkedList<String>();

        max = l.getLength();
        for (int i = 0; i < max; i++) {
            Node node = l.item(i);

            switch (node.getNodeType()) {
            case Node.ELEMENT_NODE:
                String name = node.getNodeName();

                if (name.equals("NAME")) { // $NON-NLS-1$
                    String desc = getElementValue(node);

                    bbnnode.setName(desc);
                } else if (name.equals("OUTCOME") || name.equals("VALUE")) { 
                    String value = getElementValue(node);

                    if (value != null) {
                        values.add(value);
                    }
                } else if (name.equals("PROPERTY")) { 
                    String value = getElementValue(node);

                    parseProperty(value, bbnnode);
                } else if (Setting.DEBUG) {
                    System.out.println("Unhandled variable element " + name);
                }
                break;

            case Node.DOCUMENT_NODE:
            case Node.COMMENT_NODE:
            case Node.TEXT_NODE:
                // Ignore this
                break;

            default:
                if (Setting.DEBUG) {
                    System.out.println("Unhandled node " + node.getNodeName());
                }
            }
        }

        if (propType.equals("nature") || propType.equals("utility")) { 
            String[] valArr = new String[values.size()];

            values.toArray(valArr);
            LabelDomain dom = new LabelDomain(bbnnode.getName(), valArr);

            // (String[]) values.toArray());

            bbnnode.setDomain(dom);
        }
        return bbnnode;
    }

    /**
     * Parse string property. The input string is expected to have at least one
     * equal sign. If the right hand side is enclosed with parentheses, it will
     * treat it as lists. If the value is numeric, it tries to convert that to a
     * Double. Otherwise, it stores the value as a string.
     *
     * @param s
     *            The property string
     * @param prop
     *            The property table
     */
    protected void parseProperty(String s, BNNode bbnode) {
        int idx = s.indexOf('=');

        if (idx == -1) {
            return;
        }
        String name = s.substring(0, idx).trim();
        String value = s.substring(idx + 1).trim();

        if (value.startsWith("(") && value.endsWith(")")) {
            value = value.substring(1, value.length() - 1).trim();
            StringTokenizer tokenizer = new StringTokenizer(value, ", ");
            LinkedList<Object> values = new LinkedList<Object>();

            while (tokenizer.hasMoreTokens()) {
                String token = tokenizer.nextToken().trim();

                try {
                    Double dbl = new Double(token);

                    values.add(dbl);
                } catch (Exception e) {
                    values.add(token);
                }
            }
            bbnode.setProperty(name, values);
        } else {
            try {
                Double dbl = new Double(value);

                bbnode.setProperty(name, dbl);
            } catch (Exception e) {
                bbnode.setProperty(name, value);
            }
        }
    }

    protected void visitDefinition(Node parent) {
        NodeList l = parent.getChildNodes();

        if (l == null) {
            return;
        }
        LinkedList<String> parents = new LinkedList<String>();
        String curNodeName = null, CPTString = null;

        int max = l.getLength();

        for (int i = 0; i < max; i++) {
            Node node = l.item(i);

            switch (node.getNodeType()) {
            case Node.ELEMENT_NODE:
                String name = node.getNodeName();

                if (name.equals("FOR")) { 
                    curNodeName = getElementValue(node);
                } else if (name.equals("GIVEN")) { 
                    String parentName = getElementValue(node);
                    BNNode parentNode = graph.getBeliefNode(parentName);

                    if (parentNode == null) {
                        throw new RuntimeException(
                                "Cannot resolve node " + parentName);
                    }
                    if (parentNode.isUtility()) {
                        throw new RuntimeException(
                                "Utility nodes can never be parent nodes!");
                    }
                    if (parentNode != null) {
                        parents.add(parentName);
                    }
                } else if (name.equals("TABLE")) { 
                    CPTString = getElementValue(node);
                } else if (Setting.DEBUG) {
                    System.out.println("Unhandled variable element " + name);
                }
                break;

            case Node.DOCUMENT_NODE:
            case Node.COMMENT_NODE:
            case Node.TEXT_NODE:
                // Ignore this
                break;

            default:
                if (Setting.DEBUG) {
                    System.out.println("Unhandled node " + node.getNodeName());
                }
            }
        }

        // Sanity check
        if (curNodeName == null) {
            throw new RuntimeException(
                    "Ill-formed <DEFINITION> tag, no names specified!");
        }

        BNNode curNode = graph.getBeliefNode(curNodeName);

        if (curNode == null) {
            throw new RuntimeException(
                    "Ill-formed <DEFINITION> tag, non-existant names specified!");
        }
        if (curNode.isDecision()) {
            return;
        }
        if (CPTString == null) {
            throw new RuntimeException(
                    "Ill-formed <DEFINITION> tag, no tables specified!");
        }

        // Post processing
        for (Iterator i = parents.iterator(); i.hasNext();) {
            String parentNodeName = (String) i.next();

            graph.addEdge(parentNodeName, curNodeName);
        }

        // if (!curNode.isUtility()) {
        // if (rowFirst) {
        // parents.addFirst(curNodeName);
        // } else {
        // parents.add(curNodeName);
        // }
        // }
        // int domainOrder= curNode.getDomain().getOrder();
        try {
            IOUtil.parseTableString(CPTString,
                    (TabularFunction) curNode.getFunction());
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    protected String getElementValue(Node parent) {
        NodeList l = parent.getChildNodes();

        if (l == null) {
            return null;
        }

        StringBuffer buf = new StringBuffer();
        int max = l.getLength();

        for (int i = 0; i < max; i++) {
            Node node = l.item(i);

            switch (node.getNodeType()) {
            case Node.TEXT_NODE:
                buf.append(node.getNodeValue());
                break;

            case Node.ELEMENT_NODE:
            case Node.COMMENT_NODE:
                // Ignore this
                break;

            default:
                if (Setting.DEBUG) {
                    System.out.println("Unhandled node " + node.getNodeName());
                }
            }
        }
        return buf.toString().trim();
    }

}
TOP

Related Classes of org.integratedmodelling.riskwiz.io.xmlbif.XmlBifReader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.