/*
* $Id: Parser.java,v 1.4 2002/09/16 08:05:06 jkl Exp $
*
* Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
*
* Use is subject to license terms, as defined in
* Anvil Sofware License, Version 1.1. See LICENSE
* file, or http://njet.org/license-1.1.txt
*/
package anvil.script.statements.taglib;
import anvil.ErrorListener;
import anvil.Location;
import anvil.parser.DocumentHandler;
import anvil.parser.InputSource;
import anvil.parser.Locator;
import anvil.parser.URLInputSource;
import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;
public class Parser implements DocumentHandler
{
private static final int STATE_NULL = 0;
private static final int STATE_LIB = 1;
private static final int STATE_LIB_ATTR = 2;
private static final int STATE_TAG = 3;
private static final int STATE_TAG_ATTR = 4;
private static final int STATE_ATTR = 5;
private static final int STATE_ATTR_ATTR = 6;
private Locator _locator;
private ErrorListener _listener;
private TagLibrary _lib = null;
private Tag _tag = null;
private Attribute _attr = null;
private String _property = null;
private int _state = STATE_NULL;
public Parser(ErrorListener listener)
{
_listener = listener;
}
public void error(String message)
{
_listener.error(_locator.getLocation(), message);
}
private String getName(anvil.parser.Tag tag)
{
String name = tag.getValue("name");
if (name == null) {
error("Attribute 'name' missing from tag");
name = "";
} else {
if (!anvil.script.Grammar.isValidIdentifier(name)) {
error("Value of attribute 'name' is not a valid identifier");
}
}
return name;
}
public void setDocumentLocator(Locator locator)
{
_locator = locator;
}
public void startDocument()
{
}
public void endDocument()
{
}
public void handleCharacters(String cdata)
{
boolean ok = true;
switch(_state) {
case STATE_LIB_ATTR:
ok = _lib.setAttribute(this, _property, cdata);
break;
case STATE_TAG_ATTR:
ok = _tag.setAttribute(this, _property, cdata);
break;
case STATE_ATTR_ATTR:
ok = _attr.setAttribute(this, _property, cdata);
break;
}
if (!ok) {
error("Invalid property '"+_property+"'");
}
}
public void handleComment(String cdata)
{
}
public void handleTag(anvil.parser.Tag tag)
{
String tagname = tag.getName();
switch(_state) {
case STATE_NULL:
if (tagname.equalsIgnoreCase("taglib")) {
_state = STATE_LIB;
_lib = new TagLibrary(getName(tag));
return;
}
break;
case STATE_LIB:
if (tagname.equalsIgnoreCase("tag")) {
_state = STATE_TAG;
_tag = new Tag(_lib, getName(tag));
_lib.addTag(_tag);
return;
} else if (tagname.equalsIgnoreCase("/taglib")) {
_state = STATE_NULL;
return;
}
_state = STATE_LIB_ATTR;
_property = tagname;
return;
case STATE_LIB_ATTR:
if (tagname.equalsIgnoreCase("/"+_property)) {
_state = STATE_LIB;
return;
}
break;
case STATE_TAG:
if (tagname.equalsIgnoreCase("attribute")) {
_state = STATE_ATTR;
_attr = new Attribute(getName(tag));
_tag.addAttribute(_attr);
return;
} else if (tagname.equalsIgnoreCase("/tag")) {
_state = STATE_LIB;
return;
}
_state = STATE_TAG_ATTR;
_property = tagname;
return;
case STATE_TAG_ATTR:
if (tagname.equalsIgnoreCase("/"+_property)) {
_state = STATE_TAG;
return;
}
break;
case STATE_ATTR:
if (tagname.equalsIgnoreCase("/attribute")) {
_state = STATE_TAG;
return;
}
_state = STATE_ATTR_ATTR;
_property = tagname;
return;
case STATE_ATTR_ATTR:
if (tagname.equalsIgnoreCase("/"+_property)) {
_state = STATE_ATTR;
return;
}
}
error("Invalid tag " + tag);
}
public void handleProcessingInstruction(String data)
{
}
public TagLibrary getLibrary()
{
return _lib;
}
public static TagLibrary parse(ErrorListener listener, URL url, Location location,
String namespace, String tagns)
{
try {
anvil.parser.Parser parser = new anvil.parser.Parser();
Parser libparser = new Parser(listener);
parser.parse(libparser, new URLInputSource(url));
TagLibrary library = libparser.getLibrary();
library.setNamespaces(namespace, tagns);
return library;
} catch (IOException e) {
listener.error(location, "IO-Error while loading taglib description: "+e);
}
return null;
}
}
|