Working XML

Compiling the paths and automating tests

A closer look at algorithms and JUnit

Return to article.

Listing 2. HCNode.java
package org.ananas.hc.compiler;
import java.util.Set;
import java.util.HashSet;
import java.util.Iterator;
import org.ananas.hc.QName;
import java.text.MessageFormat;
public class HCNode
{
   public final static int ENDMARKER = 1,
                           OR_XPATH = 2,
                           PARENT_OF = 3,
                           XML_NODE = 4;
   private QName qname;
   private int type;
   private HCNode left,
                  right;
   private boolean nullable;
   private Set firstpos,
               lastpos;
   private void merge(Set into,Set set)
   {
      Iterator iterator = set.iterator();
      while(iterator.hasNext())
         into.add(iterator.next());
   }
   public HCNode(QName qname,int type,HCNode left,HCNode right)
   {
      this.qname = qname;
      this.type = type;
      this.left = left;
      this.right = right;
      switch(type)
      {
         case ENDMARKER:
         case XML_NODE:
            nullable = false;
            firstpos = new HashSet();
            firstpos.add(this);
            lastpos = new HashSet();
            lastpos.add(this);
            break;
         case PARENT_OF:
            nullable = left.nullable() && right.nullable();
            firstpos = new HashSet(left.firstpos());
            if(left.nullable())
               merge(firstpos,right.firstpos());
            lastpos = new HashSet(right.lastpos());
            if(right.nullable())
               merge(lastpos,left.lastpos());
            break;
         case OR_XPATH:
            nullable = left.nullable() || right.nullable();
            firstpos = new HashSet(left.firstpos());
            merge(firstpos,right.firstpos());
            lastpos = new HashSet(left.lastpos());
            merge(lastpos,right.lastpos());
            break;
         default:
            throw new IllegalArgumentException("unknown type");
      }
   }
   public QName getQName()
   {
      return qname;
   }
   public int getType()
   {
      return type;
   }
   public HCNode getLeft()
   {
      return left;
   }
   public HCNode getRight()
   {
      return right;
   }
   public boolean nullable()
   {
      return nullable;
   }
   public Set firstpos()
   {
      return firstpos;
   }
   public Set lastpos()
   {
      return lastpos;
   }
   public String toString()
   {
      String pattern = "UNKNOWN";
      switch(type)
      {
         case ENDMARKER:
            pattern = "ENDMARKER: {0}";
            break;
         case OR_XPATH:
            pattern = "OR_XPATH: {0}";
            break;
         case PARENT_OF:
            pattern = "PARENT_OF: {0}";
            break;
         case XML_NODE:
            pattern = "XML_NODE: {0}";
            break;
      }
      return MessageFormat.format(pattern,new Object[] { qname });
   }
}

Return to article.