//
// FlowStepVarSelect.java - Select
//

package nyangau.jmsadapter;

//...simports:0:
import java.util.Set;
import java.util.HashSet;
import java.util.Map;
import java.util.HashMap;
import java.util.Vector;
import java.util.regex.*;
import java.io.IOException;
import javax.jms.JMSException;
import javax.xml.namespace.NamespaceContext;
import javax.xml.transform.dom.DOMSource;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
//...e

public class FlowStepVarSelect extends FlowStep
  {
  protected String var;
  protected String destvar;
  protected XPathExpression xpe;
  protected Pattern pattern;
  protected int cg;
//...sFlowStepVarSelect:2:
public FlowStepVarSelect(Node eStep)
  throws FlowProcessorException
  {
  super(eStep);
  NamedNodeMap nnmStep = eStep.getAttributes();
  Node aVar = nnmStep.getNamedItem("var");
  var = ( aVar != null ) ? aVar.getNodeValue() : "v0";
  Node aDestVar = nnmStep.getNamedItem("destvar");
  destvar = ( aDestVar != null ) ? aDestVar.getNodeValue() : var;
  Node aXpath = nnmStep.getNamedItem("xpath");
  if ( aXpath != null )
    {
    String xpath = aXpath.getNodeValue();
    try
      {
      XPath xp = XPathFactory.newInstance().newXPath();
      Node aNsctx = nnmStep.getNamedItem("nsctx");
      if ( aNsctx != null )
        xp.setNamespaceContext( FlowHelper.getNamespaceContext(aNsctx.getNodeValue()) );
      xpe = xp.compile(xpath);
      }
    catch ( XPathExpressionException e )
      {
      throw new FlowProcessorException("bad XPath "+xpath+" in step "+name, e);
      }
    }
  else
    xpe = null;
  Node aRegexp = nnmStep.getNamedItem("regexp");
  if ( aRegexp != null )
    {
    String regexp = aRegexp.getNodeValue();
    try
      {
      pattern = Pattern.compile(regexp);
      }
    catch ( PatternSyntaxException e )
      {
      throw new FlowProcessorException("bad Java Regular Expression "+regexp+" in step "+name, e);
      }
    }
  else
    pattern = null;
  Node aCg = nnmStep.getNamedItem("group");
  cg = ( aCg != null ) ? Integer.parseInt(aCg.getNodeValue()) : 0;
  }
//...e
//...sprocess:2:
public void process(FlowContext c)
  throws FlowProcessorException, JMSException
  {
  Object o = c.getVar(var);
  if ( o == null )
    throw new FlowProcessorException(var+" undefined in step "+name);
  if ( o instanceof FlowNullValue )
    throw new FlowProcessorException(var+" is null in step "+name);

  // XPath from a Document
  if ( o instanceof Document && xpe != null )
    {
    Document d = (Document) o;
    String s;
    try
      {
      s = xpe.evaluate(d);
      }
    catch ( XPathExpressionException e )
      {
      throw new FlowProcessorException("bad XPath in step "+name, e);
      }
    catch ( NullPointerException e )
      {
      throw new FlowProcessorException("unexpected NullPointerException", e);
      }
    c.setVar(destvar, s);
    }
  else if ( o instanceof String && pattern != null )
    {
    String s = (String) o;
    Matcher matcher = pattern.matcher(new StringBuffer(s));
    StringBuffer sb = new StringBuffer();
    while ( matcher.find() )
      {
      int start = matcher.start(cg);
      int end   = matcher.end  (cg);
      sb.append(s.substring(start, end));
      }
    c.setVar(destvar, sb.toString());
    }
  else
    throw new FlowProcessorException(var+" is not selectable in step "+name);
  }
//...e
  }
