File indexing completed on 2024-12-15 04:19:54

0001 package mso.generator.utils;
0002 
0003 import java.io.IOException;
0004 import java.util.ArrayList;
0005 import java.util.Collection;
0006 import java.util.HashMap;
0007 import java.util.List;
0008 import java.util.Map;
0009 import java.util.Set;
0010 import java.util.TreeSet;
0011 
0012 import javax.xml.xpath.XPath;
0013 import javax.xml.xpath.XPathConstants;
0014 import javax.xml.xpath.XPathExpressionException;
0015 import javax.xml.xpath.XPathFactory;
0016 
0017 import org.w3c.dom.Document;
0018 import org.w3c.dom.Element;
0019 import org.w3c.dom.Node;
0020 import org.w3c.dom.NodeList;
0021 
0022 public class ParserGeneratorUtils {
0023 
0024     // get a list of all structures that this structure relies on
0025     static Collection<String> getDependencies(Element e) {
0026         Set<String> deps = new TreeSet<String>();
0027         NodeList l = e.getElementsByTagName("type");
0028         for (int i = 0; i < l.getLength(); ++i) {
0029             Element se = (Element) l.item(i);
0030             // leave out structures that are not required
0031             if (!se.hasAttribute("count") && !se.hasAttribute("array")) {
0032                 deps.add(se.getAttribute("type"));
0033             }
0034         }
0035         return deps;
0036     }
0037 
0038     static List<Element> getOrderedStructureList(Document dom)
0039             throws IOException {
0040 
0041         List<Element> unorderedList = new ArrayList<Element>();
0042         Node n = dom.getDocumentElement().getFirstChild();
0043         while (n != null) {
0044             if (n instanceof Element && "struct".equals(n.getNodeName())) {
0045                 unorderedList.add((Element)n);
0046             }
0047             n = n.getNextSibling();
0048         }
0049 
0050         List<String> done = new ArrayList<String>();
0051         List<Element> orderedList = new ArrayList<Element>();
0052         while (unorderedList.size() > 0) {
0053             int count = unorderedList.size();
0054             for (int i = 0; i < unorderedList.size();) {
0055                 Element e = unorderedList.get(i);
0056                 Collection<String> deps = getDependencies(e);
0057                 deps.removeAll(done);
0058                 if (deps.size() == 0) {
0059                     orderedList.add(e);
0060                     done.add(e.getAttribute("name"));
0061                     unorderedList.remove(e);
0062                 } else {
0063                     i++;
0064                 }
0065             }
0066             if (count == unorderedList.size()) {
0067                 String msg = "";
0068                 for (Element e : unorderedList) {
0069                     Collection<String> deps = getDependencies(e);
0070                     deps.removeAll(done);
0071                     msg = msg + e.getAttribute("name") + ": " + deps + "\n";
0072                 }
0073                 throw new IOException(msg + count);
0074             }
0075         }
0076         return orderedList;
0077     }
0078 
0079     public static Map<Integer, String> getRecordTypeNames(Document dom)
0080             throws XPathExpressionException {
0081         Map<Integer, String> map = new HashMap<Integer, String>();
0082 
0083         XPath xpath = XPathFactory.newInstance().newXPath();
0084         String expression = "/mso/struct/type[@name='rh']/limitation[@name='recType']";
0085         NodeList list = (NodeList) xpath.evaluate(expression, dom,
0086                 XPathConstants.NODESET);
0087 
0088         for (int i = 0; i < list.getLength(); ++i) {
0089             Element e = (Element) list.item(i);
0090             String name = ((Element) e.getParentNode().getParentNode())
0091                     .getAttribute("name");
0092             String type = e.getAttribute("value").replace("0x", "");
0093             for (String s : type.split("\\|")) {
0094                 int typeNumber = Integer.parseInt(s, 16);
0095                 if (map.containsKey(typeNumber)) {
0096                     name = map.get(typeNumber) + "/" + name;
0097                 }
0098                 map.put(typeNumber, name);
0099             }
0100         }
0101         return map;
0102     }
0103 }