All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.codehaus.stax2.validation.ValidatorPair Maven / Gradle / Ivy

package org.codehaus.stax2.validation;

import javax.xml.stream.XMLStreamException;

/**
 * Simple utility class that allows chaining of {@link XMLValidator}
 * instances. Since the class itself implements {@link XMLValidator},
 * multiple validators can be added by chaining these pairs; ordering
 * of validator calls depends on ordering of the pairs.
 *

* Default semantics are quite simple: first validator of the pair is * always called first, and results as/if modified by that validator * are passed on to the second validator. *

* It is expected that this class is mostly used by actual stream reader * and writer implementations; not so much by validator implementations. */ public class ValidatorPair extends XMLValidator { public final static String ATTR_TYPE_DEFAULT = "CDATA"; protected XMLValidator mFirst, mSecond; /* //////////////////////////////////////////////////// // Life-cycle //////////////////////////////////////////////////// */ public ValidatorPair(XMLValidator first, XMLValidator second) { mFirst = first; mSecond = second; } /* //////////////////////////////////////////////////// // XMLValidator implementation //////////////////////////////////////////////////// */ /** * Two choices here; could either return schema of the first child, * or return null. Let's do latter, do avoid accidental matches. */ @Override public XMLValidationSchema getSchema() { return null; } @Override public void validateElementStart(String localName, String uri, String prefix) throws XMLStreamException { mFirst.validateElementStart(localName, uri, prefix); mSecond.validateElementStart(localName, uri, prefix); } @Override public String validateAttribute(String localName, String uri, String prefix, String value) throws XMLStreamException { String retVal = mFirst.validateAttribute(localName, uri, prefix, value); if (retVal != null) { value = retVal; } return mSecond.validateAttribute(localName, uri, prefix, value); } @Override public String validateAttribute(String localName, String uri, String prefix, char[] valueChars, int valueStart, int valueEnd) throws XMLStreamException { String retVal = mFirst.validateAttribute(localName, uri, prefix, valueChars, valueStart, valueEnd); /* If it got normalized, let's pass normalized value to the second * validator */ if (retVal != null) { return mSecond.validateAttribute(localName, uri, prefix, retVal); } // Otherwise the original return mSecond.validateAttribute(localName, uri, prefix, valueChars, valueStart, valueEnd); } @Override public int validateElementAndAttributes() throws XMLStreamException { int textType1 = mFirst.validateElementAndAttributes(); int textType2 = mSecond.validateElementAndAttributes(); /* Here, let's choose the stricter (more restrictive) of the two. * Since constants are order from strictest to most lenient, * we'll just take smaller of values */ return (textType1 < textType2) ? textType1 : textType2; } @Override public int validateElementEnd(String localName, String uri, String prefix) throws XMLStreamException { int textType1 = mFirst.validateElementEnd(localName, uri, prefix); int textType2 = mSecond.validateElementEnd(localName, uri, prefix); // As with earlier, let's return stricter of the two return (textType1 < textType2) ? textType1 : textType2; } @Override public void validateText(String text, boolean lastTextSegment) throws XMLStreamException { mFirst.validateText(text, lastTextSegment); mSecond.validateText(text, lastTextSegment); } @Override public void validateText(char[] cbuf, int textStart, int textEnd, boolean lastTextSegment) throws XMLStreamException { mFirst.validateText(cbuf, textStart, textEnd, lastTextSegment); mSecond.validateText(cbuf, textStart, textEnd, lastTextSegment); } @Override public void validationCompleted(boolean eod) throws XMLStreamException { mFirst.validationCompleted(eod); mSecond.validationCompleted(eod); } /* /////////////////////////////////////////////////// // Access to post-validation data (type info) /////////////////////////////////////////////////// */ @Override public String getAttributeType(int index) { String type = mFirst.getAttributeType(index); /* Hmmh. Which heuristic to use here: obviously no answer (null or * empty) is not useful. But what about the default type (CDATA)? * We can probably find a more explicit type? */ if (type == null || type.length() == 0 || type.equals(ATTR_TYPE_DEFAULT)) { String type2 = mSecond.getAttributeType(index); if (type2 != null && type2.length() > 0) { return type2; } } return type; } @Override public int getIdAttrIndex() { int index = mFirst.getIdAttrIndex(); if (index < 0) { return mSecond.getIdAttrIndex(); } return index; } @Override public int getNotationAttrIndex() { int index = mFirst.getNotationAttrIndex(); if (index < 0) { return mSecond.getNotationAttrIndex(); } return index; } /* //////////////////////////////////////////////////// // Additional API used by Woodstox core //////////////////////////////////////////////////// */ public static boolean removeValidator(XMLValidator root, XMLValidationSchema schema, XMLValidator[] results) { if (root instanceof ValidatorPair) { return ((ValidatorPair) root).doRemoveValidator(schema, results); } else { if (root.getSchema() == schema) { results[0] = root; results[1] = null; return true; } } return false; } public static boolean removeValidator(XMLValidator root, XMLValidator vld, XMLValidator[] results) { if (root == vld) { // single validator? results[0] = root; results[1] = null; return true; } else if (root instanceof ValidatorPair) { return ((ValidatorPair) root).doRemoveValidator(vld, results); } return false; } private boolean doRemoveValidator(XMLValidationSchema schema, XMLValidator[] results) { if (removeValidator(mFirst, schema, results)) { XMLValidator newFirst = results[1]; if (newFirst == null) { // removed first (was leaf) -> remove this pair results[1] = mSecond; } else { mFirst = newFirst; // two may be the same, need not be results[1] = this; } return true; } if (removeValidator(mSecond, schema, results)) { XMLValidator newSecond = results[1]; if (newSecond == null) { // removed second (was leaf) -> remove this pair results[1] = mFirst; } else { mSecond = newSecond; // two may be the same, need not be results[1] = this; // will still have this pair } return true; } return false; } private boolean doRemoveValidator(XMLValidator vld, XMLValidator[] results) { if (removeValidator(mFirst, vld, results)) { XMLValidator newFirst = results[1]; if (newFirst == null) { // removed first (was leaf) -> remove this pair results[1] = mSecond; } else { mFirst = newFirst; // two may be the same, need not be results[1] = this; } return true; } if (removeValidator(mSecond, vld, results)) { XMLValidator newSecond = results[1]; if (newSecond == null) { // removed second (was leaf) -> remove this pair results[1] = mFirst; } else { mSecond = newSecond; // two may be the same, need not be results[1] = this; // will still have this pair } return true; } return false; } /* //////////////////////////////////////////////////// // Internal methods //////////////////////////////////////////////////// */ }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy