001: package com.sun.xml.xsom.impl.scd;
002:
003: import com.sun.xml.xsom.XSAttContainer;
004: import com.sun.xml.xsom.XSAttGroupDecl;
005: import com.sun.xml.xsom.XSAttributeDecl;
006: import com.sun.xml.xsom.XSAttributeUse;
007: import com.sun.xml.xsom.XSComplexType;
008: import com.sun.xml.xsom.XSComponent;
009: import com.sun.xml.xsom.XSElementDecl;
010: import com.sun.xml.xsom.XSFacet;
011: import com.sun.xml.xsom.XSIdentityConstraint;
012: import com.sun.xml.xsom.XSListSimpleType;
013: import com.sun.xml.xsom.XSModelGroup;
014: import com.sun.xml.xsom.XSModelGroup.Compositor;
015: import com.sun.xml.xsom.XSModelGroupDecl;
016: import com.sun.xml.xsom.XSNotation;
017: import com.sun.xml.xsom.XSParticle;
018: import com.sun.xml.xsom.XSRestrictionSimpleType;
019: import com.sun.xml.xsom.XSSchema;
020: import com.sun.xml.xsom.XSSimpleType;
021: import com.sun.xml.xsom.XSType;
022: import com.sun.xml.xsom.XSUnionSimpleType;
023: import com.sun.xml.xsom.XSWildcard;
024:
025: import java.util.ArrayList;
026: import java.util.HashSet;
027: import java.util.Iterator;
028: import java.util.List;
029: import java.util.Set;
030:
031: /**
032: * Axis of traversal.
033: *
034: * @param <T>
035: * The kind of components that this axis may return.
036: *
037: * @author Kohsuke Kawaguchi
038: */
039: public interface Axis<T extends XSComponent> {
040: Iterator<T> iterator(XSComponent contextNode);
041:
042: Iterator<T> iterator(Iterator<? extends XSComponent> contextNodes);
043:
044: /**
045: * Returns true if this is one of the model group axis.
046: */
047: boolean isModelGroup();
048:
049: /**
050: * Pseudo-axis that selects all the {@link XSSchema}s in the current set.
051: * Used to implement the absolute path expression
052: */
053: public static final Axis<XSSchema> ROOT = new Axis<XSSchema>() {
054: public Iterator<XSSchema> iterator(XSComponent contextNode) {
055: return contextNode.getRoot().iterateSchema();
056: }
057:
058: public Iterator<XSSchema> iterator(
059: Iterator<? extends XSComponent> contextNodes) {
060: if (!contextNodes.hasNext())
061: return Iterators.empty();
062: else
063: // this assumes that all current nodes belong to the same owner.
064: return iterator(contextNodes.next());
065: }
066:
067: public boolean isModelGroup() {
068: return false;
069: }
070:
071: public String toString() {
072: return "root::";
073: }
074: };
075:
076: /**
077: * Pseudo-axis that visits all skipped intermediate steps.
078: * Those are:
079: * <ol>
080: * <li>complex type reachable from element
081: * <li>model groups
082: * <li>combination of above.
083: * </ol>
084: */
085: public static final Axis<XSComponent> INTERMEDIATE_SKIP = new AbstractAxisImpl<XSComponent>() {
086: public Iterator<XSComponent> elementDecl(XSElementDecl decl) {
087: XSComplexType ct = decl.getType().asComplexType();
088: if (ct == null)
089: return empty();
090: else {
091: // also pick up model groups inside this complex type
092: return new Iterators.Union<XSComponent>(singleton(ct),
093: complexType(ct));
094: }
095: }
096:
097: public Iterator<XSComponent> modelGroupDecl(
098: XSModelGroupDecl decl) {
099: return descendants(decl.getModelGroup());
100: }
101:
102: public Iterator<XSComponent> particle(XSParticle particle) {
103: return descendants(particle.getTerm().asModelGroup());
104: }
105:
106: /**
107: * Iterate all descendant model groups of the given model group, including itself.
108: */
109: private Iterator<XSComponent> descendants(XSModelGroup mg) {
110: // TODO: write a tree iterator
111: // for now, we do it eagerly because I'm lazy
112: List<XSComponent> r = new ArrayList<XSComponent>();
113: visit(mg, r);
114: return r.iterator();
115: }
116:
117: private void visit(XSModelGroup mg, List<XSComponent> r) {
118: // since model groups never form a cycle, no cycle check is needed
119: r.add(mg);
120: for (XSParticle p : mg) {
121: XSModelGroup child = p.getTerm().asModelGroup();
122: if (child != null)
123: visit(child, r);
124: }
125: }
126:
127: public String toString() {
128: return "(intermediateSkip)";
129: }
130: };
131:
132: /**
133: * All descendants reachable via default axes. Used to implement the "//" semantics.
134: *
135: * So far the default axes together are guaranteed not to cause any cycle, so
136: * no cycle check is needed (if it's needed, the life would be much harder!)
137: */
138: public static final Axis<XSComponent> DESCENDANTS = new Axis<XSComponent>() {
139: public Iterator<XSComponent> iterator(XSComponent contextNode) {
140: return new Visitor().iterator(contextNode);
141: }
142:
143: public Iterator<XSComponent> iterator(
144: Iterator<? extends XSComponent> contextNodes) {
145: return new Visitor().iterator(contextNodes);
146: }
147:
148: public boolean isModelGroup() {
149: return false;
150: }
151:
152: /**
153: * Stateful visitor that remembers what's already traversed, to reduce the search space.
154: */
155: final class Visitor extends AbstractAxisImpl<XSComponent> {
156: private final Set<XSComponent> visited = new HashSet<XSComponent>();
157:
158: /**
159: * Recursively apply the {@link Axis#DESCENDANTS} axis.
160: */
161: final class Recursion extends
162: Iterators.Map<XSComponent, XSComponent> {
163: public Recursion(Iterator<? extends XSComponent> core) {
164: super (core);
165: }
166:
167: protected Iterator<XSComponent> apply(XSComponent u) {
168: return DESCENDANTS.iterator(u);
169: }
170: }
171:
172: public Iterator<XSComponent> schema(XSSchema schema) {
173: if (visited.add(schema))
174: return ret(schema, new Recursion(schema
175: .iterateElementDecls()));
176: else
177: return empty();
178: }
179:
180: public Iterator<XSComponent> elementDecl(XSElementDecl decl) {
181: if (visited.add(decl))
182: return ret(decl, iterator(decl.getType()));
183: else
184: return empty();
185: }
186:
187: public Iterator<XSComponent> simpleType(XSSimpleType type) {
188: if (visited.add(type))
189: return ret(type, FACET.iterator(type));
190: else
191: return empty();
192: }
193:
194: public Iterator<XSComponent> complexType(XSComplexType type) {
195: if (visited.add(type))
196: return ret(type, iterator(type.getContentType()));
197: else
198: return empty();
199: }
200:
201: public Iterator<XSComponent> particle(XSParticle particle) {
202: if (visited.add(particle))
203: return ret(particle, iterator(particle.getTerm()));
204: else
205: return empty();
206: }
207:
208: public Iterator<XSComponent> modelGroupDecl(
209: XSModelGroupDecl decl) {
210: if (visited.add(decl))
211: return ret(decl, iterator(decl.getModelGroup()));
212: else
213: return empty();
214: }
215:
216: public Iterator<XSComponent> modelGroup(XSModelGroup group) {
217: if (visited.add(group))
218: return ret(group, new Recursion(group.iterator()));
219: else
220: return empty();
221: }
222:
223: public Iterator<XSComponent> attGroupDecl(
224: XSAttGroupDecl decl) {
225: if (visited.add(decl))
226: return ret(decl, new Recursion(decl
227: .iterateAttributeUses()));
228: else
229: return empty();
230: }
231:
232: public Iterator<XSComponent> attributeUse(XSAttributeUse use) {
233: if (visited.add(use))
234: return ret(use, iterator(use.getDecl()));
235: else
236: return empty();
237: }
238:
239: public Iterator<XSComponent> attributeDecl(
240: XSAttributeDecl decl) {
241: if (visited.add(decl))
242: return ret(decl, iterator(decl.getType()));
243: else
244: return empty();
245: }
246:
247: private Iterator<XSComponent> ret(XSComponent one,
248: Iterator<? extends XSComponent> rest) {
249: return union(singleton(one), rest);
250: }
251: }
252:
253: public String toString() {
254: return "/";
255: }
256: };
257:
258: public static final Axis<XSSchema> X_SCHEMA = new Axis<XSSchema>() {
259: public Iterator<XSSchema> iterator(XSComponent contextNode) {
260: return Iterators.singleton(contextNode.getOwnerSchema());
261: }
262:
263: public Iterator<XSSchema> iterator(
264: Iterator<? extends XSComponent> contextNodes) {
265: return new Iterators.Adapter<XSSchema, XSComponent>(
266: contextNodes) {
267: protected XSSchema filter(XSComponent u) {
268: return u.getOwnerSchema();
269: }
270: };
271: }
272:
273: public boolean isModelGroup() {
274: return false;
275: }
276:
277: public String toString() {
278: return "x-schema::";
279: }
280: };
281:
282: public static final Axis<XSElementDecl> SUBSTITUTION_GROUP = new AbstractAxisImpl<XSElementDecl>() {
283: public Iterator<XSElementDecl> elementDecl(XSElementDecl decl) {
284: return singleton(decl.getSubstAffiliation());
285: }
286:
287: public String toString() {
288: return "substitutionGroup::";
289: }
290: };
291:
292: public static final Axis<XSAttributeDecl> ATTRIBUTE = new AbstractAxisImpl<XSAttributeDecl>() {
293: public Iterator<XSAttributeDecl> complexType(XSComplexType type) {
294: return attributeHolder(type);
295: }
296:
297: public Iterator<XSAttributeDecl> attGroupDecl(
298: XSAttGroupDecl decl) {
299: return attributeHolder(decl);
300: }
301:
302: private Iterator<XSAttributeDecl> attributeHolder(
303: final XSAttContainer atts) {
304: // TODO: check spec. is this correct?
305: return new Iterators.Adapter<XSAttributeDecl, XSAttributeUse>(
306: atts.iterateAttributeUses()) {
307: protected XSAttributeDecl filter(XSAttributeUse u) {
308: return u.getDecl();
309: }
310: };
311: }
312:
313: public Iterator<XSAttributeDecl> schema(XSSchema schema) {
314: return schema.iterateAttributeDecls();
315: }
316:
317: public String toString() {
318: return "@";
319: }
320: };
321:
322: public static final Axis<XSElementDecl> ELEMENT = new AbstractAxisImpl<XSElementDecl>() {
323: public Iterator<XSElementDecl> particle(XSParticle particle) {
324: return singleton(particle.getTerm().asElementDecl());
325: }
326:
327: public Iterator<XSElementDecl> schema(XSSchema schema) {
328: return schema.iterateElementDecls();
329: }
330:
331: public Iterator<XSElementDecl> modelGroupDecl(
332: XSModelGroupDecl decl) {
333: return modelGroup(decl.getModelGroup());
334: }
335:
336: //public Iterator<XSElementDecl> modelGroup(XSModelGroup group) {
337: // return new Iterators.Map<XSElementDecl,XSParticle>(group.iterator()) {
338: // protected Iterator<XSElementDecl> apply(XSParticle p) {
339: // return particle(p);
340: // }
341: // };
342: //}
343:
344: @Override
345: public String getName() {
346: return "";
347: }
348:
349: public String toString() {
350: return "element::";
351: }
352: };
353:
354: public static final Axis<XSType> TYPE_DEFINITION = new AbstractAxisImpl<XSType>() {
355: public Iterator<XSType> schema(XSSchema schema) {
356: return schema.iterateTypes();
357: }
358:
359: public Iterator<XSType> attributeDecl(XSAttributeDecl decl) {
360: return singleton(decl.getType());
361: }
362:
363: public Iterator<XSType> elementDecl(XSElementDecl decl) {
364: return singleton(decl.getType());
365: }
366:
367: public String toString() {
368: return "~";
369: }
370: };
371:
372: public static final Axis<XSType> BASETYPE = new AbstractAxisImpl<XSType>() {
373: public Iterator<XSType> simpleType(XSSimpleType type) {
374: return singleton(type.getBaseType());
375: }
376:
377: public Iterator<XSType> complexType(XSComplexType type) {
378: return singleton(type.getBaseType());
379: }
380:
381: public String toString() {
382: return "baseType::";
383: }
384: };
385:
386: public static final Axis<XSSimpleType> PRIMITIVE_TYPE = new AbstractAxisImpl<XSSimpleType>() {
387: public Iterator<XSSimpleType> simpleType(XSSimpleType type) {
388: return singleton(type.getPrimitiveType());
389: }
390:
391: public String toString() {
392: return "primitiveType::";
393: }
394: };
395:
396: public static final Axis<XSSimpleType> ITEM_TYPE = new AbstractAxisImpl<XSSimpleType>() {
397: public Iterator<XSSimpleType> simpleType(XSSimpleType type) {
398: XSListSimpleType baseList = type.getBaseListType();
399: if (baseList == null)
400: return empty();
401: return singleton(baseList.getItemType());
402: }
403:
404: public String toString() {
405: return "itemType::";
406: }
407: };
408:
409: public static final Axis<XSSimpleType> MEMBER_TYPE = new AbstractAxisImpl<XSSimpleType>() {
410: public Iterator<XSSimpleType> simpleType(XSSimpleType type) {
411: XSUnionSimpleType baseUnion = type.getBaseUnionType();
412: if (baseUnion == null)
413: return empty();
414: return baseUnion.iterator();
415: }
416:
417: public String toString() {
418: return "memberType::";
419: }
420: };
421:
422: public static final Axis<XSComponent> SCOPE = new AbstractAxisImpl<XSComponent>() {
423: public Iterator<XSComponent> complexType(XSComplexType type) {
424: return singleton(type.getScope());
425: }
426:
427: // TODO: attribute declaration has a scope, too.
428: // TODO: element declaration has a scope
429:
430: public String toString() {
431: return "scope::";
432: }
433: };
434:
435: public static final Axis<XSAttGroupDecl> ATTRIBUTE_GROUP = new AbstractAxisImpl<XSAttGroupDecl>() {
436: public Iterator<XSAttGroupDecl> schema(XSSchema schema) {
437: return schema.iterateAttGroupDecls();
438: }
439:
440: public String toString() {
441: return "attributeGroup::";
442: }
443: };
444:
445: public static final Axis<XSModelGroupDecl> MODEL_GROUP_DECL = new AbstractAxisImpl<XSModelGroupDecl>() {
446: public Iterator<XSModelGroupDecl> schema(XSSchema schema) {
447: return schema.iterateModelGroupDecls();
448: }
449:
450: public Iterator<XSModelGroupDecl> particle(XSParticle particle) {
451: return singleton(particle.getTerm().asModelGroupDecl());
452: }
453:
454: public String toString() {
455: return "group::";
456: }
457: };
458:
459: public static final Axis<XSIdentityConstraint> IDENTITY_CONSTRAINT = new AbstractAxisImpl<XSIdentityConstraint>() {
460: public Iterator<XSIdentityConstraint> elementDecl(
461: XSElementDecl decl) {
462: return decl.getIdentityConstraints().iterator();
463: }
464:
465: public Iterator<XSIdentityConstraint> schema(XSSchema schema) {
466: // TODO: iterate all elements in this schema (local or global!) and its identity constraints
467: return super .schema(schema);
468: }
469:
470: public String toString() {
471: return "identityConstraint::";
472: }
473: };
474:
475: public static final Axis<XSIdentityConstraint> REFERENCED_KEY = new AbstractAxisImpl<XSIdentityConstraint>() {
476: public Iterator<XSIdentityConstraint> identityConstraint(
477: XSIdentityConstraint decl) {
478: return singleton(decl.getReferencedKey());
479: }
480:
481: public String toString() {
482: return "key::";
483: }
484: };
485:
486: public static final Axis<XSNotation> NOTATION = new AbstractAxisImpl<XSNotation>() {
487: public Iterator<XSNotation> schema(XSSchema schema) {
488: return schema.iterateNotations();
489: }
490:
491: public String toString() {
492: return "notation::";
493: }
494: };
495:
496: public static final Axis<XSWildcard> WILDCARD = new AbstractAxisImpl<XSWildcard>() {
497: public Iterator<XSWildcard> particle(XSParticle particle) {
498: return singleton(particle.getTerm().asWildcard());
499: }
500:
501: public String toString() {
502: return "any::";
503: }
504: };
505:
506: public static final Axis<XSWildcard> ATTRIBUTE_WILDCARD = new AbstractAxisImpl<XSWildcard>() {
507: public Iterator<XSWildcard> complexType(XSComplexType type) {
508: return singleton(type.getAttributeWildcard());
509: }
510:
511: public Iterator<XSWildcard> attGroupDecl(XSAttGroupDecl decl) {
512: return singleton(decl.getAttributeWildcard());
513: }
514:
515: public String toString() {
516: return "anyAttribute::";
517: }
518: };
519:
520: public static final Axis<XSFacet> FACET = new AbstractAxisImpl<XSFacet>() {
521: public Iterator<XSFacet> simpleType(XSSimpleType type) {
522: // TODO: it's not clear if "facets" mean all inherited facets or just declared facets
523: XSRestrictionSimpleType r = type.asRestriction();
524: if (r != null)
525: return r.iterateDeclaredFacets();
526: else
527: return empty();
528: }
529:
530: public String toString() {
531: return "facet::";
532: }
533: };
534:
535: public static final Axis<XSModelGroup> MODELGROUP_ALL = new ModelGroupAxis(
536: Compositor.ALL);
537: public static final Axis<XSModelGroup> MODELGROUP_CHOICE = new ModelGroupAxis(
538: Compositor.CHOICE);
539: public static final Axis<XSModelGroup> MODELGROUP_SEQUENCE = new ModelGroupAxis(
540: Compositor.SEQUENCE);
541: public static final Axis<XSModelGroup> MODELGROUP_ANY = new ModelGroupAxis(
542: null);
543:
544: static final class ModelGroupAxis extends
545: AbstractAxisImpl<XSModelGroup> {
546: private final XSModelGroup.Compositor compositor;
547:
548: ModelGroupAxis(Compositor compositor) {
549: this .compositor = compositor;
550: }
551:
552: @Override
553: public boolean isModelGroup() {
554: return true;
555: }
556:
557: public Iterator<XSModelGroup> particle(XSParticle particle) {
558: return filter(particle.getTerm().asModelGroup());
559: }
560:
561: public Iterator<XSModelGroup> modelGroupDecl(
562: XSModelGroupDecl decl) {
563: return filter(decl.getModelGroup());
564: }
565:
566: private Iterator<XSModelGroup> filter(XSModelGroup mg) {
567: if (mg == null)
568: return empty();
569: if (mg.getCompositor() == compositor || compositor == null)
570: return singleton(mg);
571: else
572: return empty();
573: }
574:
575: public String toString() {
576: if (compositor == null)
577: return "model::*";
578: else
579: return "model::" + compositor;
580: }
581: }
582: }
|