package com.ctc.wstx.dtd;

import com.ctc.wstx.cfg.ErrorConsts;
import com.ctc.wstx.util.PrefixedName;

Content specification that defines content model consisting of just one allowed element. In addition to the allowed element, spec can have optional arity ("*", "+", "?") marker.
/** * Content specification that defines content model consisting of just * one allowed element. In addition to the allowed element, spec can have * optional arity ("*", "+", "?") marker. */
public class TokenContentSpec extends ContentSpec { final static TokenContentSpec sDummy = new TokenContentSpec (' ', new PrefixedName("*", "*")); final PrefixedName mElemName; /* /////////////////////////////////////////////////// // Life-cycle /////////////////////////////////////////////////// */ public TokenContentSpec(char arity, PrefixedName elemName) { super(arity); mElemName = elemName; } public static TokenContentSpec construct(char arity, PrefixedName elemName) { return new TokenContentSpec(arity, elemName); } public static TokenContentSpec getDummySpec() { return sDummy; } /* /////////////////////////////////////////////////// // Public API /////////////////////////////////////////////////// */ @Override public boolean isLeaf() { return mArity == ' '; } public PrefixedName getName() { return mElemName; } @Override public StructValidator getSimpleValidator() { return new Validator(mArity, mElemName); } @Override public ModelNode rewrite() { TokenModel model = new TokenModel(mElemName); if (mArity == '*') { return new StarModel(model); } if (mArity == '?') { return new OptionalModel(model); } if (mArity == '+') { return new ConcatModel(model, new StarModel(new TokenModel(mElemName))); } return model; } @Override public String toString() { return (mArity == ' ') ? mElemName.toString() : (mElemName.toString() + mArity); } /* /////////////////////////////////////////////////// // Validator class: /////////////////////////////////////////////////// */ final static class Validator extends StructValidator { final char mArity; final PrefixedName mElemName; int mCount = 0; public Validator(char arity, PrefixedName elemName) { mArity = arity; mElemName = elemName; }
Rules for reuse are simple: if we can have any number of repetitions, we can just use a shared root instance. Although its count variable will get updated this doesn't really matter as it won't be used. Otherwise a new instance has to be created always, to keep track of instance counts.
/** * Rules for reuse are simple: if we can have any number of * repetitions, we can just use a shared root instance. Although * its count variable will get updated this doesn't really * matter as it won't be used. Otherwise a new instance has to * be created always, to keep track of instance counts. */
@Override public StructValidator newInstance() { return (mArity == '*') ? this : new Validator(mArity, mElemName); } @Override public String tryToValidate(PrefixedName elemName) { if (!elemName.equals(mElemName)) { return "Expected element <"+mElemName+">"; } if (++mCount > 1 && (mArity == '?' || mArity == ' ')) { return "More than one instance of element <"+mElemName+">"; } return null; } @Override public String fullyValid() { switch (mArity) { case '*': case '?': return null; case '+': // need at least one (and multiples checked earlier) case ' ': if (mCount > 0) { return null; } return "Expected "+(mArity == '+' ? "at least one" : "") +" element <"+mElemName+">"; } // should never happen: throw new IllegalStateException(ErrorConsts.ERR_INTERNAL); } } }