00001 package edu.tum.cs.bayesnets.core.io;
00002
00003
00004
00005
00006
00007 import edu.ksu.cis.bnj.ver3.core.BeliefNetwork;
00008 import edu.ksu.cis.bnj.ver3.streams.*;
00009
00010 import java.io.*;
00011 import java.util.*;
00012 import javax.xml.parsers.DocumentBuilder;
00013 import javax.xml.parsers.DocumentBuilderFactory;
00014 import org.w3c.dom.*;
00015
00022 public class Converter_xmlbif
00023 implements OmniFormatV1, Exporter, Importer
00024 {
00025
00026 public Converter_xmlbif()
00027 {
00028 w = null;
00029 curBeliefNode = 0;
00030 }
00031
00032 public OmniFormatV1 getStream1()
00033 {
00034 return this;
00035 }
00036
00037 public void load(InputStream stream, OmniFormatV1 writer)
00038 {
00039 _Writer = writer;
00040 _Writer.Start();
00041 bn_cnt = 0;
00042 bnode_cnt = 0;
00043 _nodenames = new HashMap();
00044 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
00045 factory.setValidating(true);
00046 factory.setNamespaceAware(true);
00047 org.w3c.dom.Document doc;
00048 try
00049 {
00050 DocumentBuilder parser = factory.newDocumentBuilder();
00051 doc = parser.parse(stream);
00052 }
00053 catch(Exception e)
00054 {
00055 throw new RuntimeException(e);
00056 }
00057 visitDocument(doc);
00058 System.gc();
00059 }
00060
00061 public void visitDocument(Node parent)
00062 {
00063 NodeList l = parent.getChildNodes();
00064 if(l == null)
00065 throw new RuntimeException("Unexpected end of document!");
00066 int max = l.getLength();
00067 for(int i = 0; i < max;)
00068 {
00069 Node node = l.item(i);
00070 switch(node.getNodeType())
00071 {
00072 case 1:
00073 String name = node.getNodeName();
00074 if(name.equals("BIF"))
00075 {
00076 NamedNodeMap attrs = node.getAttributes();
00077 if(attrs != null)
00078 {
00079 int amax = attrs.getLength();
00080 for(int j = 0; j < amax; j++)
00081 {
00082 Node attr = attrs.item(j);
00083 String aname = attr.getNodeName().toUpperCase();
00084 if(aname.equals("VERSION"))
00085 try
00086 {
00087 int ver = (int)(Double.parseDouble(attr.getNodeValue()) * 100D);
00088 if(ver != 30)
00089 System.out.println("version " + ver + " is not supported");
00090 }
00091 catch(Exception exx) { }
00092 else
00093 System.out.println("property:" + aname + " not handled");
00094 }
00095
00096 }
00097 visitDocument(node);
00098 } else
00099 if(name.equals("NETWORK"))
00100 {
00101 _Writer.CreateBeliefNetwork(bn_cnt);
00102 visitModel(node);
00103 bn_cnt++;
00104 } else
00105 {
00106 throw new RuntimeException("Unhandled element " + name);
00107 }
00108
00109
00110 case 2:
00111 case 3:
00112 case 4:
00113 case 5:
00114 case 6:
00115 case 7:
00116 case 8:
00117 case 9:
00118 case 10:
00119 default:
00120 i++;
00121 break;
00122 }
00123 }
00124
00125 }
00126
00127 public void visitModel(Node parent)
00128 {
00129 NodeList l = parent.getChildNodes();
00130 if(l == null)
00131 throw new RuntimeException("Unexpected end of document!");
00132 int max = l.getLength();
00133 for(int i = 0; i < max;)
00134 {
00135 Node node = l.item(i);
00136 switch(node.getNodeType())
00137 {
00138 case 1:
00139 String name = node.getNodeName();
00140 if(name.equals("NAME"))
00141 _Writer.SetBeliefNetworkName(bn_cnt, getElementValue(node));
00142 else
00143 if(!name.equals("PRM_CLASS") && name.equals("VARIABLE"))
00144 {
00145 _Writer.BeginBeliefNode(bnode_cnt);
00146 visitVariable(node);
00147 _Writer.EndBeliefNode();
00148 bnode_cnt++;
00149 }
00150
00151
00152 case 2:
00153 case 3:
00154 case 4:
00155 case 5:
00156 case 6:
00157 case 7:
00158 case 8:
00159 case 9:
00160 case 10:
00161 default:
00162 i++;
00163 break;
00164 }
00165 }
00166
00167 for(int i = 0; i < max;)
00168 {
00169 Node node = l.item(i);
00170 switch(node.getNodeType())
00171 {
00172 case 1:
00173 String name = node.getNodeName();
00174 if(name.equals("DEFINITION") || name.equals("PROBABILITY"))
00175 visitDefinition(node);
00176
00177
00178 case 2:
00179 case 3:
00180 case 4:
00181 case 5:
00182 case 6:
00183 case 7:
00184 case 8:
00185 case 9:
00186 case 10:
00187 default:
00188 i++;
00189 break;
00190 }
00191 }
00192
00193 }
00194
00195 protected void visitVariable(Node parent)
00196 {
00197 NodeList l = parent.getChildNodes();
00198 String propType = "nature";
00199 NamedNodeMap attrs = parent.getAttributes();
00200 int max;
00201 if(attrs != null)
00202 {
00203 max = attrs.getLength();
00204 for(int i = 0; i < max; i++)
00205 {
00206 Node attr = attrs.item(i);
00207 String name = attr.getNodeName();
00208 String value = attr.getNodeValue();
00209 if(name.equals("TYPE"))
00210 {
00211 propType = value;
00212 if(value.equals("decision"))
00213 _Writer.SetType("decision");
00214 else
00215 if(value.equals("utility"))
00216 _Writer.SetType("utility");
00217 } else
00218 {
00219 System.out.println("Unhandled variable property attribute " + name);
00220 }
00221 }
00222
00223 }
00224 max = l.getLength();
00225 for(int i = 0; i < max;)
00226 {
00227 Node node = l.item(i);
00228 switch(node.getNodeType())
00229 {
00230 case 1:
00231 String name = node.getNodeName();
00232 if(name.equals("NAME"))
00233 {
00234 String desc = getElementValue(node);
00235 _nodenames.put(desc, new Integer(bnode_cnt));
00236 _Writer.SetBeliefNodeName(desc);
00237 } else
00238 if(name.equals("OUTCOME") || name.equals("VALUE"))
00239 {
00240 String value = getElementValue(node);
00241 _Writer.BeliefNodeOutcome(value);
00242 } else
00243 if(name.equals("PROPERTY"))
00244 {
00245 String assignment = getElementValue(node);
00246 int eq = assignment.indexOf("=");
00247 String var = assignment.substring(0, eq).trim().toUpperCase();
00248 String val = assignment.substring(eq + 1).trim();
00249 if(var.equals("POSITION"))
00250 {
00251 int cma = val.indexOf(",");
00252 int left = val.indexOf("(");
00253 int right = val.indexOf(")");
00254 String X = val.substring(left + 1, cma).trim();
00255 String Y = val.substring(cma + 1, right).trim();
00256 _Writer.SetBeliefNodePosition(Integer.parseInt(X), Integer.parseInt(Y));
00257 } else if (var.equals("DOMAINCLASS")) {
00258 String domainClassName = val.trim();
00259 _Writer.SetBeliefNodeDomainClass(domainClassName);
00260 }
00261 }
00262
00263
00264 case 2:
00265 case 3:
00266 case 4:
00267 case 5:
00268 case 6:
00269 case 7:
00270 case 8:
00271 case 9:
00272 default:
00273 i++;
00274 break;
00275 }
00276 }
00277
00278 }
00279
00280 protected void visitDefinition(Node parent)
00281 {
00282 NodeList l = parent.getChildNodes();
00283 if(l == null)
00284 return;
00285 LinkedList parents = new LinkedList();
00286 int curNode = -1;
00287 String CPTString = "";
00288 int max = l.getLength();
00289 for(int i = 0; i < max;)
00290 {
00291 Node node = l.item(i);
00292 switch(node.getNodeType())
00293 {
00294 case 1:
00295 String name = node.getNodeName();
00296 if(name.equals("FOR"))
00297 {
00298 String cNode = getElementValue(node);
00299 curNode = ((Integer)_nodenames.get(cNode)).intValue();
00300 } else
00301 if(name.equals("GIVEN"))
00302 parents.add(_nodenames.get(getElementValue(node)));
00303 else
00304 if(name.equals("TABLE"))
00305 CPTString = getElementValue(node);
00306
00307
00308 case 2:
00309 case 3:
00310 case 4:
00311 case 5:
00312 case 6:
00313 case 7:
00314 case 8:
00315 case 9:
00316 default:
00317 i++;
00318 break;
00319 }
00320 }
00321
00322 if(curNode >= 0)
00323 {
00324 int p;
00325 for(Iterator i = parents.iterator(); i.hasNext(); _Writer.Connect(p, curNode))
00326 p = ((Integer)i.next()).intValue();
00327
00328 _Writer.BeginCPF(curNode);
00329 StringTokenizer tok = new StringTokenizer(CPTString);
00330 int maxz = tok.countTokens();
00331 for(int c = 0; c < maxz; c++)
00332 {
00333 String SSS = tok.nextToken();
00334 _Writer.ForwardFlat_CPFWriteValue(SSS);
00335 }
00336
00337 _Writer.EndCPF();
00338 }
00339 }
00340
00341 protected String getElementValue(Node parent)
00342 {
00343 NodeList l = parent.getChildNodes();
00344 if(l == null)
00345 return null;
00346 StringBuffer buf = new StringBuffer();
00347 int max = l.getLength();
00348 for(int i = 0; i < max; i++)
00349 {
00350 Node node = l.item(i);
00351 switch(node.getNodeType())
00352 {
00353 case 3:
00354 buf.append(node.getNodeValue());
00355 break;
00356
00357 default:
00358 System.out.println("Unhandled node " + node.getNodeName());
00359 break;
00360
00361 case 1:
00362 case 8:
00363 break;
00364 }
00365 }
00366
00367 return buf.toString().trim();
00368 }
00369
00370 public void save(BeliefNetwork bn, OutputStream os)
00371 {
00372 w = new OutputStreamWriter(os);
00373 OmniFormatV1_Writer.Write(bn, this);
00374 }
00375
00376 public void fwrite(String x)
00377 {
00378 try
00379 {
00380 w.write(x);
00381 w.flush();
00382 }
00383 catch(Exception e)
00384 {
00385 System.out.println("unable to write?");
00386 }
00387 }
00388
00389 public void Start()
00390 {
00391 netDepth = 0;
00392 BeliefNames = new HashMap();
00393 AdjList = new HashMap();
00394 fwrite("<?xml version=\"1.0\" encoding=\"US-ASCII\"?>\n");
00395 fwrite("<!--\n");
00396 fwrite("Bayesian network in XMLBIF v0.3 (BayesNet Interchange Format)\n");
00397 fwrite("Produced by BNJ 3.0 (http://bndev.sourceforge.net/\n");
00398 fwrite("-->\n");
00399 fwrite("\t\t<!-- DTD for the XMLBIF 0.3 format -->\n");
00400 fwrite("<!DOCTYPE BIF [\n");
00401 fwrite("<!ELEMENT BIF ( NETWORK )*>\n");
00402 fwrite("<!ATTLIST BIF VERSION CDATA #REQUIRED>\n");
00403 fwrite("<!ELEMENT NETWORK ( NAME, ( PROPERTY | VARIABLE | DEFINITION )* )>\n");
00404 fwrite("<!ELEMENT NAME (#PCDATA)>\n");
00405 fwrite("<!ELEMENT VARIABLE ( NAME, ( OUTCOME | PROPERTY )* ) >\n");
00406 fwrite("\t<!ATTLIST VARIABLE TYPE (nature|decision|utility) \"nature\">\n");
00407 fwrite("<!ELEMENT OUTCOME (#PCDATA)>\n");
00408 fwrite("<!ELEMENT DEFINITION ( FOR | GIVEN | TABLE | PROPERTY )* >\n");
00409 fwrite("<!ELEMENT FOR (#PCDATA)>\n");
00410 fwrite("<!ELEMENT GIVEN (#PCDATA)>\n");
00411 fwrite("<!ELEMENT TABLE (#PCDATA)>\n");
00412 fwrite("<!ELEMENT PROPERTY (#PCDATA)>\n");
00413 fwrite("]>\n");
00414 fwrite("<BIF VERSION=\"0.3\">\n");
00415 }
00416
00417 public void CreateBeliefNetwork(int idx)
00418 {
00419 if(netDepth > 0)
00420 {
00421 netDepth = 0;
00422 fwrite("</NETWORK>\n");
00423 }
00424 fwrite("<NETWORK>\n");
00425 netDepth = 1;
00426 }
00427
00428 public void SetBeliefNetworkName(int idx, String name)
00429 {
00430 fwrite("<NAME>" + name + "</NAME>\n");
00431 }
00432
00433 public void BeginBeliefNode(int idx)
00434 {
00435 nodeType = "nature";
00436 internalNode = "";
00437 curBeliefNode = idx;
00438 AdjList.put(new Integer(curBeliefNode), new ArrayList());
00439 }
00440
00441 public void SetType(String type)
00442 {
00443 if(!type.equals("chance"))
00444 nodeType = type;
00445 }
00446
00447 public void SetBeliefNodePosition(int x, int y)
00448 {
00449 internalNode += "\t\t<PROPERTY>position = (" + x + "," + y + ")</PROPERTY>\n";
00450 }
00451
00452 public void SetBeliefNodeDomainClass(String domainClassName) {
00453 internalNode += "\t\t<PROPERTY>domainclass = " + domainClassName + "</PROPERTY>\n";
00454 }
00455
00456 public void BeliefNodeOutcome(String outcome)
00457 {
00458 internalNode += "\t\t<OUTCOME>" + outcome.replaceAll("<", "<").replaceAll(">", ">") + "</OUTCOME>\n";
00459 }
00460
00461 public void SetBeliefNodeName(String name)
00462 {
00463 internalNode += "\t\t<NAME>" + name + "</NAME>\n";
00464 BeliefNames.put(new Integer(curBeliefNode), name);
00465 }
00466
00467 public void MakeContinuous(String s)
00468 {
00469 }
00470
00471 public void EndBeliefNode()
00472 {
00473 fwrite("\t<VARIABLE TYPE=\"" + nodeType + "\">\n");
00474 fwrite(internalNode);
00475 fwrite("\t</VARIABLE>\n");
00476 }
00477
00478 public void Connect(int par_idx, int chi_idx)
00479 {
00480 ArrayList adj = (ArrayList)AdjList.get(new Integer(chi_idx));
00481 adj.add(new Integer(par_idx));
00482 }
00483
00484 public void BeginCPF(int idx)
00485 {
00486 ArrayList adj = (ArrayList)AdjList.get(new Integer(idx));
00487 String name = (String)BeliefNames.get(new Integer(idx));
00488 fwrite("\t<DEFINITION>\n");
00489 fwrite("\t\t<FOR>" + name + "</FOR>\n");
00490 String gname;
00491 for(Iterator it = adj.iterator(); it.hasNext(); fwrite("\t\t<GIVEN>" + gname + "</GIVEN>\n"))
00492 {
00493 Integer given = (Integer)it.next();
00494 gname = (String)BeliefNames.get(given);
00495 }
00496
00497 fwrite("\t\t<TABLE>");
00498 }
00499
00500 public void ForwardFlat_CPFWriteValue(String x)
00501 {
00502 fwrite(x + " ");
00503 }
00504
00505 public void EndCPF()
00506 {
00507 fwrite("\t\t</TABLE>");
00508 fwrite("\t</DEFINITION>");
00509 }
00510
00511 public int GetCPFSize()
00512 {
00513 return 0;
00514 }
00515
00516 public void Finish()
00517 {
00518 if(netDepth > 0)
00519 {
00520 netDepth = 0;
00521 fwrite("</NETWORK>\n");
00522 }
00523 fwrite("</BIF>\n");
00524 try
00525 {
00526 w.close();
00527 }
00528 catch(Exception exception) { }
00529 }
00530
00531 public String getExt()
00532 {
00533 return "*.xml";
00534 }
00535
00536 public String getDesc()
00537 {
00538 return "XML Bayesian Network Interchange Format";
00539 }
00540
00541 private OmniFormatV1 _Writer;
00542 private int bn_cnt;
00543 private int bnode_cnt;
00544 private HashMap _nodenames;
00545 Writer w;
00546 public int netDepth;
00547 int curBeliefNode;
00548 HashMap BeliefNames;
00549 HashMap AdjList;
00550 String internalNode;
00551 String nodeType;
00552 }