oaacontenthandler.java

来自「SRI international 发布的OAA框架软件」· Java 代码 · 共 246 行

JAVA
246
字号
/*
#=========================================================================
# Copyright 2003 SRI International.  All rights reserved.
#
# The material contained in this file is confidential and proprietary to SRI
# International and may not be reproduced, published, or disclosed to others
# without authorization from SRI International.
#
# DISCLAIMER OF WARRANTIES
#
# SRI International MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE
# SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT
# LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SRI International SHALL NOT BE
# LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
# OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES
#=========================================================================
  Author : shardt
  Date: Aug 11, 2003
*/
package com.sri.oaa2.tools.oaatest;

import java.util.*;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;


/** Cursor to fill enclosing OaaTestCase with TestItems. */
class OaaContentHandler extends DefaultHandler {
  /** Create new OaaContentHandler to fill given List of TestItems.
   * @param items should start out empty.
   * @param defaultTimeout in milliseconds
   */
  OaaContentHandler(List items,int defaultTimeout) {
    this.items = items;
    this.defaultTimeout = defaultTimeout;
  }

  public void setDocumentLocator(Locator l) {
    locator = l;
  }

  public void startElement(String namespaceURI, String localName,
                           String qName, Attributes attribs) 
                           throws SAXException {
    switch (currElement) {
      // Top-level, inside <testcase>, or inside <testcase><parallel>
      case EL_NONE:
        if (qName.equals("testcase")) {
          // Get new default timeout value.
          defaultTimeout = timeoutFromAttribs(attribs,defaultTimeout);      
        }
        else if (qName.equals("send")) {
          if (parallelItem != null) {
            throw new ParseException("<parallel> can only have <toFac> or <fromFac> children.",locator);
          }
          currElement = EL_SEND;
          currChars.setLength(0);
        }
        else if (qName.equals("toFac")) {
          currElement = EL_TO_FAC;
          currChars.setLength(0);
          facTimeout = timeoutFromAttribs(attribs,defaultTimeout);
          constraints.clear();
        }
        else if (qName.equals("fromFac")) {
          currElement = EL_FROM_FAC;
          currChars.setLength(0);
          facTimeout = timeoutFromAttribs(attribs,defaultTimeout);
          constraints.clear();
        }
        else if (qName.equals("prompt")) {
          if (parallelItem != null) {
            throw new ParseException("Can't have <prompt> inside <parallel>.",locator);
          }
          String message = attribs.getValue("message");
          currChars.setLength(0);          
          if (message == null) {
            currElement = EL_PROMPT_BARE;
          }
          else {
            currElement = EL_PROMPT_ATTRIBS;
            currChars.append(message);         
          }
        }
        else if (qName.equals("parallel")) {
          if (parallelItem != null) {
            throw new ParseException("Can't have nested <parallel> tags.",locator);
          }
          parallelItem = new ParallelItem(timeoutFromAttribs(attribs,defaultTimeout));
        }
        else {
          throw new ParseException("Unexpected element " + qName,locator);
        }
        break;
      
      case EL_SEND:
        throw new ParseException("<send> can have no children",locator);
        
      case EL_PROMPT_BARE:
      case EL_PROMPT_ATTRIBS:
        throw new ParseException("<prompt> can have no children",locator);

      case EL_TO_FAC:
      case EL_FROM_FAC:
        // Will throw if we hit something other than a constraint.
        constraints.add(Constraint.create(qName,attribs,locator));
        break; 
    }
  }

  public void endElement(String namespaceURI, String localName,
                         String qName) throws SAXException {
    switch (currElement) {
      case EL_SEND:
        if (qName.equals("send")) {
          items.add(new SendItem(currChars.toString(),locator));
          currElement = EL_NONE;
        }
        break;
        
      case EL_TO_FAC:
      case EL_FROM_FAC:
        if (qName.equals("toFac") || qName.equals("fromFac")) {
          FacItem item = new FacItem(qName.equals("toFac"),currChars.toString(),
                                     facTimeout,constraints,locator);
          // Add to current ParallelItem.
          if (parallelItem != null) {
            parallelItem.addFacItem(item);
          }
          // Add to top-level list.
          else {
            items.add(item);
          }
          
          currElement = EL_NONE;
        }
        break;

      case EL_PROMPT_BARE:
      case EL_PROMPT_ATTRIBS:
        if (parallelItem != null) {
          throw new RuntimeException("Internal error in parsing logic.");
        }
        if (currChars.length() == 0) {
          throw new ParseException("<prompt> with no message.",locator);
        }
        items.add(new PromptItem(currChars.toString()));
        currElement = EL_NONE;
        break;
        
      case EL_NONE:
        if (qName.equals("parallel")) {
          if (parallelItem == null) {
            throw new ParseException("</parallel> at unexpected place",locator);
          }
          if (parallelItem.size() == 0) {
            throw new ParseException("<parallel> must have at least one <recv> child.",locator);
          }
          items.add(parallelItem);
          parallelItem = null;
        }
        else if (qName.equals("testcase")) {
          if (items.size() == 0) {
            throw new ParseException("<testcase> must have at least one child.",locator);
          }
        }
    }
  }
  
  // Add characters to a buffer.
  public void characters(char[] ch,
                         int start,
                         int length) throws SAXException {    
    if (currElement == EL_PROMPT_ATTRIBS) {
      throw new ParseException(Prompt.ERR_DUPLICATE_MESSAGE,locator);
    }
    else if (currElement != EL_NONE) {
      currChars.append(ch,start,length);
    }
  }

  /** Look for the "timeout" attribute and return value in milliseconds or defaultTimeout if
   * not found.
   */
  private int timeoutFromAttribs(Attributes attribs,int defaultTimeout) throws ParseException {
    if (defaultTimeout <= 0) {
      throw new RuntimeException("internal error w/ timeout");
    }

    // We could parse timeouts like "10s", "500ms", for now we only take
    // a value in seconds.
    String timeoutSec = attribs.getValue("timeout");
    if (timeoutSec == null) {
      return defaultTimeout;
    }

    int timeoutMs;
    try {
      timeoutMs = Integer.parseInt(timeoutSec) * 1000;
    }
    catch (NumberFormatException e) {
      throw new ParseException("timeout must be an integer value",locator);
    }
    if (timeoutMs <= 0) {
      throw new ParseException("timeout must be > 0",locator);
    }
    return timeoutMs;
  }

  /** The final output, fill this list. */
  private List items;
  
  /** Set by SAX, tells us where we are. */
  private Locator locator;

  // Non-null if we're inside a ParallelItem.
  private ParallelItem parallelItem = null;

  /** Not inside an element that contains an ICL string. */
  private final static byte EL_NONE = 0;                  
  /** Inside <send> */
  private final static byte EL_SEND = 1;                  
  /** Inside  <toFac> */
  private final static byte EL_TO_FAC = 2;                  
  /** Inside  <fromFac> */
  private final static byte EL_FROM_FAC = 3;                  
  /** Inside  <prompt> no message attribute. */
  private final static byte EL_PROMPT_BARE = 4;                  
  /** Inside  <prompt message=> */
  private final static byte EL_PROMPT_ATTRIBS = 5;                  

  /** Current parse element */
  private byte currElement = EL_NONE;
  
  // The following two are only valid when iclElement != EL_NONE
  private StringBuffer currChars = new StringBuffer();

  // Only valid when iclElement == EL_TO/FROM_FAC
  private int facTimeout = 0;
  private ArrayList constraints = new ArrayList();

  private int defaultTimeout;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?