001: package com.sun.xml.xsom.impl.scd;
002:
003: import com.sun.xml.xsom.XSComponent;
004: import com.sun.xml.xsom.XSDeclaration;
005: import com.sun.xml.xsom.XSFacet;
006: import com.sun.xml.xsom.XSType;
007: import com.sun.xml.xsom.SCD;
008: import com.sun.xml.xsom.XSSchema;
009: import com.sun.xml.xsom.impl.UName;
010:
011: import java.util.Iterator;
012:
013: /**
014: * Building block of {@link SCD}.
015: *
016: * @author Kohsuke Kawaguchi
017: */
018: public abstract class Step<T extends XSComponent> {
019: public final Axis<? extends T> axis;
020:
021: /**
022: * 'Predicate' in SCD designates the index of the item. -1 if there's no predicate.
023: * Predicate starts from 1.
024: *
025: * <p>
026: * Because of the parsing order this parameter cannot be marked
027: * final, even though it's immutable once it's parsed.
028: */
029: int predicate = -1;
030:
031: protected Step(Axis<? extends T> axis) {
032: this .axis = axis;
033: }
034:
035: /**
036: * Perform filtering (which is different depending on the kind of step.)
037: */
038: protected abstract Iterator<? extends T> filter(
039: Iterator<? extends T> base);
040:
041: /**
042: * Evaluate this step against the current node set
043: * and returns matched nodes.
044: */
045: public final Iterator<T> evaluate(Iterator<XSComponent> nodeSet) {
046: // list up the whole thing
047: Iterator<T> r = new Iterators.Map<T, XSComponent>(nodeSet) {
048: protected Iterator<? extends T> apply(
049: XSComponent contextNode) {
050: return filter(axis.iterator(contextNode));
051: }
052: };
053:
054: // avoid duplicates
055: r = new Iterators.Unique<T>(r);
056:
057: if (predicate >= 0) {
058: T item = null;
059: for (int i = predicate; i > 0; i--) {
060: if (!r.hasNext())
061: return Iterators.empty();
062: item = r.next();
063: }
064: return new Iterators.Singleton<T>(item);
065: }
066:
067: return r;
068: }
069:
070: /**
071: * Matches any name.
072: */
073: static final class Any extends Step<XSComponent> {
074: public Any(Axis<? extends XSComponent> axis) {
075: super (axis);
076: }
077:
078: // no filtering.
079: protected Iterator<? extends XSComponent> filter(
080: Iterator<? extends XSComponent> base) {
081: return base;
082: }
083: }
084:
085: private static abstract class Filtered<T extends XSComponent>
086: extends Step<T> {
087: protected Filtered(Axis<? extends T> axis) {
088: super (axis);
089: }
090:
091: protected Iterator<T> filter(Iterator<? extends T> base) {
092: return new Iterators.Filter<T>(base) {
093: protected boolean matches(T d) {
094: return match(d);
095: }
096: };
097: }
098:
099: protected abstract boolean match(T d);
100: }
101:
102: /**
103: * Matches a particular name.
104: */
105: static final class Named extends Filtered<XSDeclaration> {
106: private final String nsUri;
107: private final String localName;
108:
109: public Named(Axis<? extends XSDeclaration> axis, UName n) {
110: this (axis, n.getNamespaceURI(), n.getName());
111: }
112:
113: public Named(Axis<? extends XSDeclaration> axis, String nsUri,
114: String localName) {
115: super (axis);
116: this .nsUri = nsUri;
117: this .localName = localName;
118: }
119:
120: protected boolean match(XSDeclaration d) {
121: return d.getName().equals(localName)
122: && d.getTargetNamespace().equals(nsUri);
123: }
124: }
125:
126: /**
127: * Matches anonymous types.
128: */
129: static final class AnonymousType extends Filtered<XSType> {
130: public AnonymousType(Axis<? extends XSType> axis) {
131: super (axis);
132: }
133:
134: protected boolean match(XSType node) {
135: return node.isLocal();
136: }
137: }
138:
139: /**
140: * Matches a particular kind of facets.
141: */
142: static final class Facet extends Filtered<XSFacet> {
143: private final String name;
144:
145: public Facet(Axis<XSFacet> axis, String facetName) {
146: super (axis);
147: this .name = facetName;
148: }
149:
150: protected boolean match(XSFacet f) {
151: return f.getName().equals(name);
152: }
153: }
154:
155: /**
156: * Matches a schema in a particular namespace.
157: */
158: static final class Schema extends Filtered<XSSchema> {
159: private final String uri;
160:
161: public Schema(Axis<XSSchema> axis, String uri) {
162: super (axis);
163: this .uri = uri;
164: }
165:
166: protected boolean match(XSSchema d) {
167: return d.getTargetNamespace().equals(uri);
168: }
169: }
170: }
|