Package dk.brics.xmlgraph

Examples of dk.brics.xmlgraph.XMLGraph


   * @param gaps if set, gaps are included, otherwise they are implicitly closed
   * @param wrapchoices if set, extra choice nodes are added around attribute nodes and
   *       element nodes and above text nodes
   */
  public static XMLGraph convert(XML x, GapConversion gaps, boolean wrapchoices) {
    XMLGraph xg = new XMLGraph();
    xg.useFragment(extend(xg, x, gaps, wrapchoices));
    return xg;
  }
View Full Code Here


        } finally {
          releaseSoot();
        }
            }
      transformFlowGraph(g);
            final XMLGraph sharedXg = g.getXMLGraph();
      List<FlowGraph> graphs = splitFlowGraph(g);
      g = null;
      int index=0;
      final ThreadLocal<XMLGraph> localXg = new ThreadLocal<XMLGraph>();
      for (final FlowGraph g2 : graphs) {
        Debug.println(2, true, "Subgraph index..." + index);
        Debug.println(2, true, "Node count......." + g2.getNodes().size());
        Debug.println(2, true, "Edge count......." + g2.getNumberOfEdges());
          tasks.addTask(new Runnable() {
              public void run() {
                  try {
                      XMLGraph xg = localXg.get();
                      if (xg == null) {
                          xg = safeCloneGraph(sharedXg);
                          localXg.set(xg);
                      }
                      g2.setXMLGraph(xg);
View Full Code Here

   * so there is no interference with other threads.
   * @param xg an XML graph
   * @return a new XML graph
   */
  private XMLGraph safeCloneGraph(XMLGraph xg) {
      final XMLGraph output = xg.clone();
      for (int i=0; i<xg.getNodes().size(); i++) {
          Node node = output.getNode(i);
          node.process(new NodeProcessor<Object>() {
              @Override
              public Object process(AttributeNode n) {
                  n.setName(n.getName().clone(), output);
                  return this;
View Full Code Here

  /**
   * Checks that the given template is valid according to the given schema type.
   * @throws XMLValidationException if the template is invalid
   */
  public static void validate(XML x, String type, Origin origin) throws XMLValidationException {
    XMLGraph xg = XMLGraphConverter.convert(x, XMLGraphConverter.GapConversion.IGNORE, false); // TODO: make variant of validate that treats gaps optimistically instead of just ignoring them
    //new dk.brics.xmlgraph.converter.XMLGraph2Dot(System.out).print(xg);
    XMLGraph t = null;
    int i = 0;
    String expanded = expandQName(type, origin);
    for (ConvertedSchema s : schemas) {
      SequenceNode n = s.types.get(expanded);
      if (n != null) {
View Full Code Here

        ZeroOrOne,
        ZeroOrMore,
    }
   
    public void run(final FlowGraph g, Configuration config) {
        final XMLGraph xg = new XMLGraph();
        g.setXMLGraph(xg);
       
        // load XML Schemas
        for (Map.Entry<String,Origin> entry : g.getSchemas().entrySet()) {
            try {
                Map<String,SequenceNode> map = XMLValidator.loadXMLSchema(new URL(entry.getKey()), xg);
                g.getTypemap().putAll(map);
            } catch (MalformedURLException ex) {
                throw new XMLException("Schema URL is malformed", ex, entry.getValue());
            } catch (ParseException ex) {
                throw new XMLException("Could not parse schema: " + ex.getMessage(), ex, entry.getValue());
            }
        }
        for (URL url : config.getAdditionalSchemas()) {
            try {
                Map<String, SequenceNode> map = XMLValidator.loadXMLSchema(url, xg);
                g.getTypemap().putAll(map);
            } catch (ParseException ex) {
                throw new XMLException("Could not parse schema: " + ex.getMessage(), ex);
            }
        }
       
        // link SchemaTypes to their nodes
        final class Visitor extends BasicStatementVisitor {
            Origin origin;
            @Override
            public void visitAnalyzeStm(AnalyzeStm s) {
              if (s.getKind() != AnalyzeStm.Kind.HOTSPOT) {
                linkSchemaType(s, s.getSchema());
              }
            }
            @Override
            public void visitValidateStm(ValidateStm s) {
                linkSchemaType(s, s.getSchema());
            }
            @Override
            public void visitGapifyStm(GapifyStm s) {
                if (s.getSchema() != null)
                    linkSchemaType(s, s.getSchema());
            }
            @Override
            public void visitConstStm(ConstStm s) {
                TemplateConstant t = s.getConst();
                if (t.getFragment() != null)
                    return;
                // handle empty XML specially to avoid "" text nodes
                if (t.getXML().isText() && t.getXML().asText().getString().isEmpty()) {
                    SequenceNode n = new SequenceNode(Collections.<Integer>emptyList(), s.getOrigin());
                    xg.addNode(n);
                    XMLGraphFragment f = new XMLGraphFragment(n, null, null, null);
                    t.setFragment(f);
                } else {
                    XMLGraphFragment f = XMLGraphConverter.extend(xg, t.getXML(), XMLGraphConverter.GapConversion.CLOSED, true);
                    for (Map.Entry<String,String> en : f.getGapTypeMap().entrySet()) {
                        String gaptype = en.getValue();
                        // add gap types to the xml graph, and ensure that they are valid
                        resolveTypename(gaptype);
                    }
                    t.setFragment(f);
                }
            }
            void linkSchemaType(Statement s, SchemaType type) {
                type.setTypeNode(resolveTypename(type.getType()));
                for (Map.Entry<String,String> gap : type.getGapTypes().entrySet()) {
                    String gapname = gap.getKey();
                    String gaptype = gap.getValue();
                    type.getGapTypeNodes().put(gapname, resolveTypename(gaptype));
                }
            }
            Node resolveTypename(String name) {
                if (g.getTypemap().containsKey(name)) {
                    return g.getTypemap().get(name);
                }
               
                String schemaName;
                Quantifier quantifier;
                if (name.endsWith("?")) {
                    schemaName = name.substring(0, name.length() - 1);
                    quantifier = Quantifier.ZeroOrOne;
                } else if (name.endsWith("+")) {
                    schemaName = name.substring(0, name.length() - 1);
                    quantifier = Quantifier.OneOrMore;
                } else if (name.endsWith("*")) {
                    schemaName = name.substring(0, name.length() - 1);
                    quantifier = Quantifier.ZeroOrMore;
                } else {
                    schemaName = name;
                    quantifier = Quantifier.One;
                }
               
                Node base = g.getTypemap().get(schemaName);
               
                // add datatypes on-the-fly when needed
                if (base == null) {
                    if (XMLSchemaDatatypes.isDatatype(schemaName)) {
                        base = new TextNode(XMLSchemaDatatypes.getDatatype(schemaName, origin), new Origin("", -1, -1));
                        xg.addNode(base);
                        g.getTypemap().put(schemaName, base);
                    }
                }
               
                // if still not found, it does not exist
                if (base == null) {
                    throw new XMLException("Could not find schema for type " + schemaName + " referred to at " + origin, origin);
                }
               
                Node result;
                OneOrMoreNode on;
                SequenceNode empty;
                switch (quantifier) {
                case One:
                    result = base;
                    break;
                case OneOrMore:
                    result = new OneOrMoreNode(base.getIndex(), origin);
                    xg.addNode(result);
                    break;
                case ZeroOrMore:
                    empty = new SequenceNode(Collections.<Integer>emptyList(), origin);
                    on = new OneOrMoreNode(base.getIndex(), origin);
                    xg.addNode(empty);
                    xg.addNode(on);
                    result = new ChoiceNode(set(empty.getIndex(), on.getIndex()), origin);
                    xg.addNode(result);
                    break;
                case ZeroOrOne:
                default:
                    empty = new SequenceNode(Collections.<Integer>emptyList(), origin);
                    xg.addNode(empty);
                    result = new ChoiceNode(set(base.getIndex(), empty.getIndex()), origin);
                    xg.addNode(result);
                    break;
                }
               
                g.getTypemap().put(name, result);
               
View Full Code Here

        int counter = 0;
        for (Map.Entry<ValueBox, AnalyzeStm> en : result.getHotspots()
                .entrySet()) {
            ValueBox value = en.getKey();
            AnalyzeStm stm = en.getValue();
            XMLGraph g = xmlGraphs.getIn(stm, stm.getBase());
            List<Automaton> findInputNameValues = findInputNameValues(g);
            for (Automaton automaton : findInputNameValues) {
                System.out.println(automaton.getFiniteStrings());
            }
            SootMethod method = hotspot2method.get(value);

            System.out
                    .printf("Return stmt from method %s has an XML graph with %d root nodes\n",
                            method.getName(), g.getRoots().size());

            PrintWriter output = new PrintWriter(new File("test/out/"
                    + method.getName() + counter + ".dot"));
            try {
                new XMLGraph2Dot(output).print(g);
View Full Code Here

    }
    return rootelements;
  }

  public XMLGraph transferGet(final GetStm s, final XMLGraph base) {
    final XMLGraph g = base.clone();
    if (g.isUnknown()) {
      return g;
    }
    ChoiceNode cn = stm_nodes.getGetChoiceNode(s, g);
    final LinkedHashSet<Integer> c = new LinkedHashSet<Integer>();
    cn.setContent(c, g);
    switch (s.getKind()) {
    case GET:
    case GETELEMENT: // TODO: to improve analysis precision, only select the *first* element for getElement
    case GETELEMENTS: {
      StatusMap sm;
//      try {
//        sm = evaluator.evaluate(base, s.getXPath(), dummy_root, dummy_root_content);
//      } catch (XPathException e) {
//        throw new XMLXPathException(e);
//      }
      sm = evaluateXPathOrRoot(s.getXPath(), base);
      checkXPathEmpty(s, base, sm);
      for (int i : sm.getNodes()) {
        if (g.getNode(i) instanceof ConcreteNode) {
          StatusMap.Status status = sm.get(i);
          if (status!=StatusMap.Status.NONE && status!=StatusMap.Status.NEVER)
            c.add(i);
        }
      }
      c.addAll(cn.getContents());
      g.getRoots().clear();
      g.addRoot(cn);
      // TODO: could improve precision by considering simple XPath *predicates*
      break;
    }
    case GETFIRSTATTR:
    case GETFIRSTATTRIBUTE:
    case GETFIRSTCHILD:
      g.getRoots().clear();
      g.addRoot(cn);
      Set<ElementNode> rootElements = getFirstRootElements(base);
      for (ElementNode node : rootElements) {
        g.getNode(node.getContent()).process(new CachedNodeProcessor<EPresence>() {
          @Override
          public EPresence cycle() {
            return EPresence.UNKNOWN;
          }
          @Override
          public EPresence process(AttributeNode n) {
            c.add(n.getIndex());
            return EPresence.NONEMPTY;
          }
          @Override
          public EPresence process(ElementNode n) {
            if (s.getKind() == Kind.GETFIRSTATTR || s.getKind() == Kind.GETFIRSTATTRIBUTE) {
              return EPresence.EMPTY;
            } else {
              c.add(n.getIndex());
              return EPresence.NONEMPTY;
            }
          }
          @Override
          public EPresence process(ChoiceNode n) {
            if (n.isGap() && n.isOpen() && s.getKind() == Kind.GETFIRSTATTR && g.getOpenAttributeGaps().contains(n.getName())) {
              c.add(n.getIndex());
              return EPresence.UNKNOWN;
            } else {
              EPresence result = EPresence.BOTTOM;
              for (int child : n.getContents()) {
                result = result.leastUpperBound(g.getNode(child).process(this));
              }
              return result;
            }
          }
          @Override
          public EPresence process(SequenceNode n) {
            EPresence result = EPresence.EMPTY;
            for (int child : n.getContents()) {
              result = result.concat(g.getNode(child).process(this));
              if (result.definitelyNonEmpty())
                break;
            }
            return result;
          }
          @Override
          public EPresence process(OneOrMoreNode n) {
            return g.getNode(n.getContent()).process(this);
          }
          @Override
          public EPresence process(TextNode n) {
            return EPresence.EMPTY;
          }
          @Override
          public EPresence process(InterleaveNode n) {
            EPresence result = EPresence.BOTTOM;
            for (int child : n.getContents()) {
              result = result.leastUpperBound(g.getNode(child).process(this));
            }
            return result;
          }
        });
      }
      break;
     
    case GETFIRSTELEMENT: {
      final Emptiness emptiness = new Emptiness(g, EPresence.EMPTY, EPresence.NONEMPTY, EPresence.EMPTY, EPresence.EMPTY);
      final FirstRootAnalysis first = new FirstRootAnalysis(g, emptiness, false);
      final RootAnalysis roots = new RootAnalysis(g);
          final int emptyIndex = stm_nodes.getGetEmptySequence(s, g).getIndex();
      // we model this as "replace every root node that is not the first root element with the empty sequence"
      g.processReachableNodes(new NodeProcessor<Object>() {
          @Override
          public Object process(ChoiceNode n) {
              EBooleanLattice r = roots.get(n.getIndex());
              if (r.definitelyNot()) {
                  return this;
              }
              LinkedList<Integer> removed = new LinkedList<Integer>();
              boolean addempty = false;
              for (int child : n.getContents()) {
                  if (roots.get(child).maybe()) {
                            if (r.definitely()) {
                                if (first.get(child).definitelyNot() || emptiness.get(child).definitelyEmpty()) {
                                    removed.add(child);
                                }
                            }
                            if (first.get(child).maybeNot() && emptiness.get(child).maybeNonEmpty()) {
                                addempty = true;
                            }
                  }
              }
              boolean removegap = false;
                    if (n.isGap() && n.isOpen() && emptiness.get(n.getIndex()).definitelyEmpty() && r.definitely()) {
                        removegap = true;
                    }
              if (!removed.isEmpty() || addempty || removegap) {
                        LinkedHashSet<Integer> cs = new LinkedHashSet<Integer>(n.getContents());
                        cs.removeAll(removed);
                        cs.add(emptyIndex);
                        if (removegap) {
                            n.setContentAndStatus(false, true, cs, g);
                        } else {
                            n.setContent(cs, g);
                        }
              }
              return this;
          }
      });
      LinkedList<Integer> removed = new LinkedList<Integer>();
      for (int child : g.getRoots()) {
          switch (emptiness.get(child)) {
          case EMPTY:
                case BOTTOM:
              // if no ELEMENT can occur as root here, then remove the root edge
              removed.add(child);
              break;
            default: ;
          }
      }
      g.getRoots().removeAll(removed);
      // note: no need to add an empty root, because getFirstElement() throws
      // an exception if none of the roots are elements
     
      break;
    }
     
    case GETNEXTATTR:
    case GETNEXTATTRIBUTE:
    case GETNEXTSIBLING: {
      Emptiness emptiness = new Emptiness(g,
              null,                                    // allow attributes
              s.getKind() == Kind.GETNEXTSIBLING ? null : EPresence.BOTTOM,      // allow elements
              s.getKind() == Kind.GETNEXTSIBLING ? null : EPresence.BOTTOM,      // allow text
              s.getKind() != Kind.GETNEXTATTRIBUTE ? null : EPresence.BOTTOM);   // allow gaps
      final FirstRootAnalysis first = new FirstRootAnalysis(g, emptiness, s.getKind() == Kind.GETNEXTSIBLING);
          final int emptyIndex = stm_nodes.getGetEmptySequence(s, g).getIndex();
         
      // We model the "get next sibling" operations as "replace first root with empty sequece".
            // If a ChoiceNode has an edge to a ConcreteNode that might be the first root,
            // then the ChoiceNode gets an additional edge to the empty sequence.
      // If that ConcreteNode can only occur as the first root, then the edge to it is removed.
     
      g.processReachableNodes(new NodeProcessor<Object>() {
          @Override
          public Object process(ChoiceNode n) {
              if (first.get(n.getIndex()).definitelyNot())
                  return this;
              LinkedList<Integer> removed = new LinkedList<Integer>();
              boolean addempty = false;
              for (int child : n.getContents()) {
                  if (!(g.getNode(child) instanceof ConcreteNode))
                      continue;
                  switch (first.get(child)) {
                  case YES:
//                      removed.add(child); // cannot remove due to invisible comments and PIs :(
                      addempty = true;
                      break;
                  case MAYBE:
                      addempty = true;
                      break;
                    default: ;
                  }
              }
              if (removed.isEmpty() || addempty) {
                  LinkedHashSet<Integer> cs = new LinkedHashSet<Integer>(n.getContents());
                  cs.removeAll(removed);
                  cs.add(emptyIndex);
                  n.setContent(cs, g);
              }
              return removed;
          }
      });
            LinkedList<Integer> removed = new LinkedList<Integer>();
      boolean addempty = false;
      for (int root : g.getRoots()) {
          if (!(g.getNode(root) instanceof ConcreteNode))
                    continue;
          switch (first.get(root)) {
                case YES:
//                  removed.add(root); // cannot remove due to invisible comments and PIs :(
                    addempty = true;
                    break;
                case MAYBE:
                    addempty = true;
                    break;
                default: ;
                }
      }
      g.getRoots().removeAll(removed);
      if (addempty) {
          g.getRoots().add(emptyIndex);
      }
     
      break;
    }
   
    default:
      throw new RuntimeException("Unexpected GET kind: " + s.getKind());
    }//switch
    g.sharpen();
    return g;
  }
View Full Code Here

    ch.setContent(new LinkedHashSet<Integer>(ch.getContents()), g);
    return (ChoiceNode)g.getNode(ch.getIndex());
  }
 
  public XMLGraph transferInsert(final InsertStm s, XMLGraph base, final XMLGraph xmlsrc) {
    final XMLGraph g = base.clone();
    if (g.isUnknown() || xmlsrc.isUnknown()) {
      g.setUnknown();
      return g;
    }
    final SequenceNode seq = stm_nodes.getInsertSequenceNode(s, g);
    final ChoiceNode left;
    final ChoiceNode right;
    final TextNode text = stm_nodes.getInsertTextNode(s, g);
   
    switch (s.getKind()) {
    case APPEND:
    case APPENDCONTENT:
    case INSERTAFTER:
    case SETATTRIBUTE:
      left = makePrivate(stm_nodes.getInsertLeftSide(s, g), g);
      right = makePrivate(stm_nodes.getInsertRightSide(s, g), g);
      break;
    case PREPEND:
    case PREPENDCONTENT:
    case INSERTBEFORE:
      // SWAP left and right if prepending
      left =  makePrivate(stm_nodes.getInsertRightSide(s, g), g);
      right = makePrivate(stm_nodes.getInsertLeftSide(s, g), g);
      break;
    default:
      throw new RuntimeException("unknown insert kind");
    }
    text.replaceText(s.getStringSource(), g);
    right.getContents().addAll(xmlsrc.getRoots());
    right.getContents().add(text.getIndex());

    switch (s.getKind()) {
    case APPEND:
    case PREPEND:
      g.merge(xmlsrc);
      left.getContents().addAll(base.getRoots());
      g.getRoots().clear();
      g.getRoots().add(seq.getIndex());
      return g;

    case SETATTRIBUTE:
    case APPENDCONTENT: // this is both appendContent(XML) and appendContent(XPath,XML)
    case PREPENDCONTENT:{
      final StatusMap stm = evaluateXPathOrRoot(s.getXPath(), g);
      boolean empty = checkXPathEmpty(s, g, stm);
      if (empty)
        return g;
      g.merge(xmlsrc);
      g.getRoots().retainAll(base.getRoots());
      // TODO can we append as root here???
      g.processReachableNodes(new NodeProcessor<Object>() {
        @Override
        public Object process(ElementNode n) {
          ChoiceNode ch = (ChoiceNode)g.getNode(n.getContent());
          switch (stm.get(n.getIndex())) {
          case DEFINITE:
          case ALL:
            left.getContents().addAll(ch.getContents());
            ch = makePrivate(ch, g);
            if (g.getGapTypeMap().isEmpty()) {
                ch.getContents().clear();
            }
            ch.getContents().add(seq.getIndex());
            break;
          case SOME:
          case DONTKNOW:
            ch = makePrivate(ch, g);
            left.getContents().addAll(ch.getContents());
            ch.getContents().add(seq.getIndex());
            break;
          case NONE:
          case NEVER:
            break;
          }
          return null;
        }
      });
      g.sharpen();
      return g;
    }
    case INSERTAFTER:
    case INSERTBEFORE: {
      final StatusMap stm = evaluateXPathOrRoot(s.getXPath(), g);
      boolean empty = checkXPathEmpty(s, g, stm);
      if (empty)
        return g;
      g.merge(xmlsrc);
      g.getRoots().retainAll(base.getRoots());
      g.processReachableNodes(new NodeProcessor<Object>() {
        @Override
        public Object process(ChoiceNode ch) {
          LinkedHashSet<Integer> cs = new LinkedHashSet<Integer>(ch.getContents());
          for (int child : ch.getContents()) {
            Node node = g.getNode(child);
            if (node instanceof ConcreteNode) {
              switch (stm.get(child)) {
              case ALL:
              case DEFINITE:
                  if (g.getGapTypeMap().isEmpty()) {
                      cs.remove(child);
                  }
                left.getContents().add(child);
                cs.add(seq.getIndex());
                break;
              case SOME:
              case DONTKNOW:
                left.getContents().add(child);
                cs.add(seq.getIndex());
                break;
              case NONE:
              case NEVER:
                break;
              }
            }
          }
          ch.setContent(cs, g);
          return null;
        }
      });
      g.sharpen();
      return g;
    }
    default:
      throw new RuntimeException("unknown insert kind");
    }
View Full Code Here

    private void mergeOpen(ChoiceNode node, XMLGraph g) {
        node.setContentAndStatus(true, node.isRemoved(), node.getContents(), g);
    }
   
  public XMLGraph transferNode(NodeStm s, XMLGraph firstattr, XMLGraph firstchild, XMLGraph nextnode) {
    XMLGraph g = global_xg.clone();
    if (unknown(firstattr) || unknown(firstchild) || unknown(nextnode)) {
      g.setUnknown();
      return g;
    }
    g.getRoots().clear();
    g.getRoots().add(stm_nodes.getStmNode(s, g).getIndex());
    if (nextnode != null) {
      g.merge(nextnode);
      mergeContents(stm_nodes.getStmNextNode(s, g), nextnode.getRoots(), g);
    }
    if (firstattr != null) {
      g.merge(firstattr);
            mergeContents(stm_nodes.getStmFirstAttribute(s, g), firstattr.getRoots(), g);
    }
    if (firstchild != null) {
      g.merge(firstchild);
            mergeContents(stm_nodes.getStmFirstChild(s, g), firstchild.getRoots(), g);
    }
    g.getRoots().clear();
    g.getRoots().add(stm_nodes.getStmNode(s, g).getIndex());
    switch (s.getKind()) {
    case ATTRIBUTEGAP:
        mergeOpen(stm_nodes.getStmGap(s, g), g);
      g.addOpenAttributeGap(s.getGap());
      break;
    case TEMPLATEGAP:
            mergeOpen(stm_nodes.getStmGap(s, g), g);
      g.addOpenTemplateGap(s.getGap());
      break;
    default: ;
    }
    g.sharpen();
    return g;
  }
View Full Code Here

  public XMLGraph transferPlug(final PlugStm s, XMLGraph base, final XMLGraph xmlsrc) {
    /*final XMLGraph g = global_xg.clone();
    g.getRoots().addAll(base.getRoots());
    g.merge(base);*/
    final XMLGraph g = base.clone();
    if (base.isUnknown() || unknown(xmlsrc)) {
      g.setUnknown();
      return g;
    }
    switch (s.getKind()) {
    case PLUG:
    case PLUGMULTI:
    case PLUGWRAP:
      final String gapname = s.getGapName();
      // plug roots into the relevant gaps and merge the XML graphs
      final boolean skip_str = s.getStringSource().isEmpty();
      if (g.getOpenAttributeGaps().contains(gapname) || g.getOpenTemplateGaps().contains(gapname)) {
        g.processRoots(new ReachableNodesProcessor(g) { 
          @Override
          public Object process(ChoiceNode n) {
            if (n.isGap() && n.isOpen() && n.getName().equals(gapname)) {
              Collection<Integer> c = new LinkedHashSet<Integer>();
              c.addAll(n.getContents());
              c.addAll(xmlsrc.getRoots());
              if (!skip_str)
                c.add(stm_nodes.getPlugTextNode(s,g).getIndex());
              n.setContentAndStatus(false, n.isRemoved(), c, g);
            }
            return null;
          }
        });
      }
      if (!skip_str) {
        TextNode tn = stm_nodes.getPlugTextNode(s,g);
        ArrayList<Automaton> ss = new ArrayList<Automaton>();
        ss.add(s.getStringSource());
        ss.add(tn.getText());
        tn.replaceText(Automaton.union(ss), g);
      }
      g.merge(xmlsrc);
      if (s.getKind() == PlugStm.Kind.PLUGWRAP) {
        g.getRoots().clear();
        g.getRoots().add(stm_nodes.getPlugWrapTopNode(s, g).getIndex());
        restoreEdges(stm_nodes.getPlugWrapTopNode(s, g), g);
        stm_nodes.getPlugWrapContentNode(s, g).setContent(base.getRoots(), g);
      } else {
        g.getRoots().retainAll(base.getRoots());
      }
      // mark the gap as closed
      if (g.getOpenTemplateGaps().contains(gapname))
        g.addClosedTemplateGap(gapname);
      g.removeOpenTemplateGap(gapname);
      if (g.getOpenAttributeGaps().contains(gapname))
        g.addClosedAttributeGap(gapname);
      g.removeOpenAttributeGap(gapname);
      g.getGapTypeMap().remove(gapname);
      // open again if the inserted value contains the gap
      if (xmlsrc.getOpenTemplateGaps().contains(gapname)) {
        g.addOpenTemplateGap(gapname);
        if (!xmlsrc.getClosedTemplateGaps().contains(gapname))
          g.removeClosedTemplateGap(gapname);
        String gaptype = xmlsrc.getGapTypeMap().get(gapname);
        if (gaptype != null)
          g.getGapTypeMap().put(gapname, gaptype);
     
      if (xmlsrc.getOpenAttributeGaps().contains(gapname)) {
        g.addOpenAttributeGap(gapname);
        if (!xmlsrc.getClosedAttributeGaps().contains(gapname))
          g.removeClosedAttributeGap(gapname);
        String gaptype = xmlsrc.getGapTypeMap().get(gapname);
        if (gaptype != null)
          g.getGapTypeMap().put(gapname, gaptype);
     
//      XMLGraphDebug.dumpXMLGraph(g, s);
      break;
    case CLOSE:
      g.processRoots(new ReachableNodesProcessor(g) { 
        @Override
        public Object process(ChoiceNode n) {
          if (n.isGap() && n.isOpen()) {
            Collection<Integer> c = new LinkedHashSet<Integer>();
            c.addAll(n.getContents());
            c.add(stm_nodes.getPlugSequenceNode(s,g).getIndex());
            n.setContentAndStatus(false, n.isRemoved(), c, g);
          }
          return null;
        }
      });
      g.getClosedTemplateGaps().addAll(g.getOpenTemplateGaps());
      g.getClosedAttributeGaps().addAll(g.getOpenAttributeGaps());
      g.getOpenTemplateGaps().clear();
      g.getOpenAttributeGaps().clear();
      g.getGapTypeMap().clear();
      break;
    }
    g.sharpen();
    return g;
  }
View Full Code Here

TOP

Related Classes of dk.brics.xmlgraph.XMLGraph

Copyright © 2018 www.massapicom. 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.