com.thaiopensource.validate.picl.ValidatorImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of wicketstuff-jing Show documentation
Show all versions of wicketstuff-jing Show documentation
Jing is a validator for RELAX NG and other schema languages. This
project was taken from http://code.google.com/p/jing-trang and
mavenized for inclusion in the Wicket Stuff HTML Validator.
The code was taken from the 20091111 release.
package com.thaiopensource.validate.picl;
import com.thaiopensource.validate.Validator;
import com.thaiopensource.validate.ValidateProperty;
import com.thaiopensource.util.Localizer;
import com.thaiopensource.util.PropertyMap;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.LocatorImpl;
import org.xml.sax.ContentHandler;
import org.xml.sax.Attributes;
import org.xml.sax.DTDHandler;
import org.xml.sax.SAXException;
import org.xml.sax.Locator;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXParseException;
import java.util.Stack;
class ValidatorImpl extends DefaultHandler implements Validator, Path, PatternManager, ErrorContext {
private final Constraint constraint;
private final Stack openElements = new Stack();
private final Stack valueHandlers = new Stack();
private final Stack activePatterns = new Stack();
private final AttributePath attributePath = new AttributePath();
private Locator locator;
private final ErrorHandler eh;
private final Localizer localizer = new Localizer(ValidatorImpl.class);
private static class WrappedSAXException extends RuntimeException {
final SAXException exception;
WrappedSAXException(SAXException exception) {
this.exception = exception;
}
}
static class ActivePattern {
final int rootDepth;
final Pattern pattern;
final SelectionHandler handler;
ActivePattern(int rootDepth, Pattern pattern, SelectionHandler handler) {
this.rootDepth = rootDepth;
this.pattern = pattern;
this.handler = handler;
}
}
static class OpenElement {
final String namespaceUri;
final String localName;
int nActivePatterns;
int nValueHandlers;
OpenElement(String namespaceUri, String localName) {
this.namespaceUri = namespaceUri;
this.localName = localName;
}
}
class AttributePath implements Path {
private Attributes atts;
private int attIndex;
void set(Attributes atts, int attIndex) {
this.atts = atts;
this.attIndex = attIndex;
}
public boolean isAttribute() {
return true;
}
public int length() {
return ValidatorImpl.this.length() + 1;
}
public String getLocalName(int i) {
if (i == openElements.size())
return atts.getLocalName(attIndex);
return ValidatorImpl.this.getLocalName(i);
}
public String getNamespaceUri(int i) {
if (i == openElements.size())
return atts.getURI(attIndex);
return ValidatorImpl.this.getNamespaceUri(i);
}
}
ValidatorImpl(Constraint constraint, PropertyMap properties) {
this.constraint = constraint;
this.eh = properties.get(ValidateProperty.ERROR_HANDLER);
}
public ContentHandler getContentHandler() {
return this;
}
public DTDHandler getDTDHandler() {
return null;
}
public void reset() {
openElements.setSize(0);
valueHandlers.setSize(0);
activePatterns.setSize(0);
locator = null;
}
public int length() {
return openElements.size();
}
public String getLocalName(int i) {
return ((OpenElement)openElements.elementAt(i)).localName;
}
public String getNamespaceUri(int i) {
return ((OpenElement)openElements.elementAt(i)).namespaceUri;
}
public boolean isAttribute() {
return false;
}
public void registerPattern(Pattern pattern, SelectionHandler handler) {
// XXX what about case where it matches dot?
activePatterns.push(new ActivePattern(openElements.size(), pattern, handler));
((OpenElement)openElements.peek()).nActivePatterns += 1;
}
public void registerValueHandler(ValueHandler handler) {
valueHandlers.push(handler);
((OpenElement)openElements.peek()).nValueHandlers += 1;
}
public void setDocumentLocator(Locator locator) {
this.locator = locator;
}
public void startDocument() throws SAXException {
if (locator == null) {
LocatorImpl tem = new LocatorImpl();
tem.setLineNumber(-1);
tem.setColumnNumber(-1);
locator = tem;
}
openElements.push(new OpenElement("", "#root"));
try {
constraint.activate(this);
}
catch (WrappedSAXException e) {
throw e.exception;
}
}
public void endDocument() throws SAXException {
try {
popOpenElement();
}
catch (WrappedSAXException e) {
throw e.exception;
}
}
public void startElement(String uri, String localName,
String qName, Attributes attributes)
throws SAXException {
try {
openElements.push(new OpenElement(uri, localName));
for (int i = 0, len = valueHandlers.size(); i < len; i++)
((ValueHandler)valueHandlers.elementAt(i)).tag(this);
for (int i = 0, len = activePatterns.size(); i < len; i++) {
ActivePattern ap = (ActivePattern)activePatterns.elementAt(i);
if (ap.pattern.matches(this, ap.rootDepth))
ap.handler.selectElement(this, this, this);
}
int nActivePatterns = activePatterns.size();
for (int i = 0, len = attributes.getLength(); i < len; i++) {
attributePath.set(attributes, i);
for (int j = 0; j < nActivePatterns; j++) {
ActivePattern ap = (ActivePattern)activePatterns.elementAt(j);
if (ap.pattern.matches(attributePath, ap.rootDepth))
ap.handler.selectAttribute(this, attributePath, attributes.getValue(i));
}
}
}
catch (WrappedSAXException e) {
throw e.exception;
}
}
public void endElement(String uri, String localName, String qName)
throws SAXException {
try {
popOpenElement();
}
catch (WrappedSAXException e) {
throw e.exception;
}
}
public void characters(char ch[], int start, int length)
throws SAXException {
try {
for (int i = 0, len = valueHandlers.size(); i < len; i++)
((ValueHandler)valueHandlers.elementAt(i)).characters(this, ch, start, length);
}
catch (WrappedSAXException e) {
throw e.exception;
}
}
public void ignorableWhitespace(char ch[], int start, int length)
throws SAXException {
characters(ch, start, length);
}
private void popOpenElement() {
OpenElement top = (OpenElement)openElements.pop();
for (int i = 0; i < top.nValueHandlers; i++) {
ValueHandler h = (ValueHandler)valueHandlers.pop();
h.valueComplete(this);
}
for (int i = 0; i < top.nActivePatterns; i++) {
ActivePattern ap = (ActivePattern)activePatterns.pop();
ap.handler.selectComplete(this);
}
}
public void error(Locator locator, String key) {
if (locator == null)
locator = this.locator;
try {
eh.error(new SAXParseException(localizer.message(key), locator));
}
catch (SAXException e) {
throw new WrappedSAXException(e);
}
}
public void error(Locator locator, String key, String arg) {
if (locator == null)
locator = this.locator;
try {
eh.error(new SAXParseException(localizer.message(key, arg), locator));
}
catch (SAXException e) {
throw new WrappedSAXException(e);
}
}
public Locator saveLocator() {
return new LocatorImpl(locator);
}
}