package com.ctc.wstx.dtd;

import java.util.StringTokenizer;

import javax.xml.stream.XMLStreamException;

import com.ctc.wstx.ent.EntityDecl;
import com.ctc.wstx.io.WstxInputData;
import com.ctc.wstx.sr.InputProblemReporter;
import com.ctc.wstx.util.PrefixedName;

Specific attribute class for attributes that contain (unique) identifiers.
/** * Specific attribute class for attributes that contain (unique) * identifiers. */
public final class DTDEntitiesAttr extends DTDAttribute { /* /////////////////////////////////////////////////// // Life-cycle /////////////////////////////////////////////////// */
Main constructor. Note that id attributes can never have default values.
/** * Main constructor. Note that id attributes can never have * default values. */
public DTDEntitiesAttr(PrefixedName name, DefaultAttrValue defValue, int specIndex, boolean nsAware, boolean xml11) { super(name, defValue, specIndex, nsAware, xml11); } @Override public DTDAttribute cloneWith(int specIndex) { return new DTDEntitiesAttr(mName, mDefValue, specIndex, mCfgNsAware, mCfgXml11); } /* /////////////////////////////////////////////////// // Public API /////////////////////////////////////////////////// */ @Override public int getValueType() { return TYPE_ENTITIES; } /* /////////////////////////////////////////////////// // Public API, validation /////////////////////////////////////////////////// */
Method called by the DTDValidatorBase to let the attribute do necessary normalization and/or validation for the value.
/** * Method called by the {@link DTDValidatorBase} * to let the attribute do necessary normalization and/or validation * for the value. * */
@Override public String validate(DTDValidatorBase v, char[] cbuf, int start, int end, boolean normalize) throws XMLStreamException { /* Let's skip leading/trailing white space, even if we are not * to normalize visible attribute value. This allows for better * round-trip handling (no changes for physical value caller * gets), but still allows succesful validation. */ while (start < end && WstxInputData.isSpaceChar(cbuf[start])) { ++start; } // Empty value? if (start >= end) { return reportValidationProblem(v, "Empty ENTITIES value"); } --end; // so that it now points to the last char while (end > start && WstxInputData.isSpaceChar(cbuf[end])) { --end; } // Ok; now start points to first, last to last char (both inclusive) String idStr = null; StringBuilder sb = null; while (start <= end) { // Ok, need to check char validity, and also calc hash code: char c = cbuf[start]; if (!WstxInputData.isNameStartChar(c, mCfgNsAware, mCfgXml11)) { return reportInvalidChar(v, c, "not valid as the first ENTITIES character"); } int i = start+1; for (; i <= end; ++i) { c = cbuf[i]; if (WstxInputData.isSpaceChar(c)) { break; } if (!WstxInputData.isNameChar(c, mCfgNsAware, mCfgXml11)) { return reportInvalidChar(v, c, "not valid as an ENTITIES character"); } } EntityDecl ent = findEntityDecl(v, cbuf, start, (i - start)); // only returns if entity was found... // Can skip the trailing space char (if there was one) start = i+1; /* When normalizing, we can possibly share id String, or * alternatively, compose normalized String if multiple */ if (normalize) { if (idStr == null) { // first idref idStr = ent.getName(); } else { if (sb == null) { sb = new StringBuilder(idStr); } idStr = ent.getName(); sb.append(' '); sb.append(idStr); } } // Ok, any white space to skip? while (start <= end && WstxInputData.isSpaceChar(cbuf[start])) { ++start; } } if (normalize) { if (sb != null) { idStr = sb.toString(); } return idStr; } return null; }
Method called by the validator object to ask attribute to verify that the default it has (if any) is valid for such type.
/** * Method called by the validator object * to ask attribute to verify that the default it has (if any) is * valid for such type. */
@Override public void validateDefault(InputProblemReporter rep, boolean normalize) throws XMLStreamException { String normStr = validateDefaultNames(rep, true); if (normalize) { mDefValue.setValue(normStr); } // Ok, but were they declared? /* Performance really shouldn't be critical here (only called when * parsing DTDs, which get cached) -- let's just * tokenize using standard StringTokenizer */ StringTokenizer st = new StringTokenizer(normStr); /* !!! 03-Dec-2004, TSa: This is rather ugly -- need to know we * actually really get a DTD reader, and DTD reader needs * to expose a special method... but it gets things done. */ MinimalDTDReader dtdr = (MinimalDTDReader) rep; while (st.hasMoreTokens()) { String str = st.nextToken(); EntityDecl ent = dtdr.findEntity(str); // Needs to exists, and be an unparsed entity... checkEntity(rep, normStr, ent); } } }