Thu, 12 Oct 2017 19:44:07 +0800
merge
1 /*
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package com.sun.xml.internal.xsom.impl.scd;
28 import com.sun.xml.internal.xsom.XSAttContainer;
29 import com.sun.xml.internal.xsom.XSAttGroupDecl;
30 import com.sun.xml.internal.xsom.XSAttributeDecl;
31 import com.sun.xml.internal.xsom.XSAttributeUse;
32 import com.sun.xml.internal.xsom.XSComplexType;
33 import com.sun.xml.internal.xsom.XSComponent;
34 import com.sun.xml.internal.xsom.XSElementDecl;
35 import com.sun.xml.internal.xsom.XSFacet;
36 import com.sun.xml.internal.xsom.XSIdentityConstraint;
37 import com.sun.xml.internal.xsom.XSListSimpleType;
38 import com.sun.xml.internal.xsom.XSModelGroup;
39 import com.sun.xml.internal.xsom.XSModelGroup.Compositor;
40 import com.sun.xml.internal.xsom.XSModelGroupDecl;
41 import com.sun.xml.internal.xsom.XSNotation;
42 import com.sun.xml.internal.xsom.XSParticle;
43 import com.sun.xml.internal.xsom.XSRestrictionSimpleType;
44 import com.sun.xml.internal.xsom.XSSchema;
45 import com.sun.xml.internal.xsom.XSSimpleType;
46 import com.sun.xml.internal.xsom.XSType;
47 import com.sun.xml.internal.xsom.XSUnionSimpleType;
48 import com.sun.xml.internal.xsom.XSWildcard;
50 import java.util.ArrayList;
51 import java.util.HashSet;
52 import java.util.Iterator;
53 import java.util.List;
54 import java.util.Set;
56 /**
57 * Axis of traversal.
58 *
59 * @param <T>
60 * The kind of components that this axis may return.
61 *
62 * @author Kohsuke Kawaguchi
63 */
64 public interface Axis<T extends XSComponent> {
65 Iterator<T> iterator(XSComponent contextNode);
67 Iterator<T> iterator(Iterator<? extends XSComponent> contextNodes);
69 /**
70 * Returns true if this is one of the model group axis.
71 */
72 boolean isModelGroup();
75 /**
76 * Pseudo-axis that selects all the {@link XSSchema}s in the current set.
77 * Used to implement the absolute path expression
78 */
79 public static final Axis<XSSchema> ROOT = new Axis<XSSchema>() {
80 public Iterator<XSSchema> iterator(XSComponent contextNode) {
81 return contextNode.getRoot().iterateSchema();
82 }
84 public Iterator<XSSchema> iterator(Iterator<? extends XSComponent> contextNodes) {
85 if(!contextNodes.hasNext())
86 return Iterators.empty();
87 else
88 // this assumes that all current nodes belong to the same owner.
89 return iterator(contextNodes.next());
90 }
92 public boolean isModelGroup() {
93 return false;
94 }
96 public String toString() {
97 return "root::";
98 }
99 };
101 /**
102 * Pseudo-axis that visits all skipped intermediate steps.
103 * Those are:
104 * <ol>
105 * <li>complex type reachable from element
106 * <li>model groups
107 * <li>combination of above.
108 * </ol>
109 */
110 public static final Axis<XSComponent> INTERMEDIATE_SKIP = new AbstractAxisImpl<XSComponent>() {
111 public Iterator<XSComponent> elementDecl(XSElementDecl decl) {
112 XSComplexType ct = decl.getType().asComplexType();
113 if(ct==null)
114 return empty();
115 else {
116 // also pick up model groups inside this complex type
117 return new Iterators.Union<XSComponent>(singleton(ct),complexType(ct));
118 }
119 }
121 public Iterator<XSComponent> modelGroupDecl(XSModelGroupDecl decl) {
122 return descendants(decl.getModelGroup());
123 }
125 public Iterator<XSComponent> particle(XSParticle particle) {
126 return descendants(particle.getTerm().asModelGroup());
127 }
129 /**
130 * Iterate all descendant model groups of the given model group, including itself.
131 */
132 private Iterator<XSComponent> descendants(XSModelGroup mg) {
133 // TODO: write a tree iterator
134 // for now, we do it eagerly because I'm lazy
135 List<XSComponent> r = new ArrayList<XSComponent>();
136 visit(mg,r);
137 return r.iterator();
138 }
140 private void visit(XSModelGroup mg, List<XSComponent> r) {
141 // since model groups never form a cycle, no cycle check is needed
142 r.add(mg);
143 for (XSParticle p : mg) {
144 XSModelGroup child = p.getTerm().asModelGroup();
145 if(child!=null)
146 visit(child,r);
147 }
148 }
150 public String toString() {
151 return "(intermediateSkip)";
152 }
153 };
155 /**
156 * All descendants reachable via default axes. Used to implement the "//" semantics.
157 *
158 * So far the default axes together are guaranteed not to cause any cycle, so
159 * no cycle check is needed (if it's needed, the life would be much harder!)
160 */
161 public static final Axis<XSComponent> DESCENDANTS = new Axis<XSComponent>() {
162 public Iterator<XSComponent> iterator(XSComponent contextNode) {
163 return new Visitor().iterator(contextNode);
164 }
165 public Iterator<XSComponent> iterator(Iterator<? extends XSComponent> contextNodes) {
166 return new Visitor().iterator(contextNodes);
167 }
169 public boolean isModelGroup() {
170 return false;
171 }
173 /**
174 * Stateful visitor that remembers what's already traversed, to reduce the search space.
175 */
176 final class Visitor extends AbstractAxisImpl<XSComponent> {
177 private final Set<XSComponent> visited = new HashSet<XSComponent>();
179 /**
180 * Recursively apply the {@link Axis#DESCENDANTS} axis.
181 */
182 final class Recursion extends Iterators.Map<XSComponent,XSComponent> {
183 public Recursion(Iterator<? extends XSComponent> core) {
184 super(core);
185 }
187 protected Iterator<XSComponent> apply(XSComponent u) {
188 return DESCENDANTS.iterator(u);
189 }
190 }
191 public Iterator<XSComponent> schema(XSSchema schema) {
192 if(visited.add(schema))
193 return ret( schema, new Recursion(schema.iterateElementDecls()));
194 else
195 return empty();
196 }
198 public Iterator<XSComponent> elementDecl(XSElementDecl decl) {
199 if(visited.add(decl))
200 return ret(decl, iterator(decl.getType()) );
201 else
202 return empty();
203 }
205 public Iterator<XSComponent> simpleType(XSSimpleType type) {
206 if(visited.add(type))
207 return ret(type, FACET.iterator(type));
208 else
209 return empty();
210 }
212 public Iterator<XSComponent> complexType(XSComplexType type) {
213 if(visited.add(type))
214 return ret(type, iterator(type.getContentType()));
215 else
216 return empty();
217 }
219 public Iterator<XSComponent> particle(XSParticle particle) {
220 if(visited.add(particle))
221 return ret(particle, iterator(particle.getTerm()));
222 else
223 return empty();
224 }
226 public Iterator<XSComponent> modelGroupDecl(XSModelGroupDecl decl) {
227 if(visited.add(decl))
228 return ret(decl, iterator(decl.getModelGroup()));
229 else
230 return empty();
231 }
233 public Iterator<XSComponent> modelGroup(XSModelGroup group) {
234 if(visited.add(group))
235 return ret(group, new Recursion(group.iterator()));
236 else
237 return empty();
238 }
240 public Iterator<XSComponent> attGroupDecl(XSAttGroupDecl decl) {
241 if(visited.add(decl))
242 return ret(decl, new Recursion(decl.iterateAttributeUses()));
243 else
244 return empty();
245 }
247 public Iterator<XSComponent> attributeUse(XSAttributeUse use) {
248 if(visited.add(use))
249 return ret(use, iterator(use.getDecl()));
250 else
251 return empty();
252 }
254 public Iterator<XSComponent> attributeDecl(XSAttributeDecl decl) {
255 if(visited.add(decl))
256 return ret(decl, iterator(decl.getType()));
257 else
258 return empty();
259 }
261 private Iterator<XSComponent> ret( XSComponent one, Iterator<? extends XSComponent> rest ) {
262 return union(singleton(one),rest);
263 }
264 }
266 public String toString() {
267 return "/";
268 }
269 };
271 public static final Axis<XSSchema> X_SCHEMA = new Axis<XSSchema>() {
272 public Iterator<XSSchema> iterator(XSComponent contextNode) {
273 return Iterators.singleton(contextNode.getOwnerSchema());
274 }
276 public Iterator<XSSchema> iterator(Iterator<? extends XSComponent> contextNodes) {
277 return new Iterators.Adapter<XSSchema,XSComponent>(contextNodes) {
278 protected XSSchema filter(XSComponent u) {
279 return u.getOwnerSchema();
280 }
281 };
282 }
284 public boolean isModelGroup() {
285 return false;
286 }
288 public String toString() {
289 return "x-schema::";
290 }
291 };
293 public static final Axis<XSElementDecl> SUBSTITUTION_GROUP = new AbstractAxisImpl<XSElementDecl>() {
294 public Iterator<XSElementDecl> elementDecl(XSElementDecl decl) {
295 return singleton(decl.getSubstAffiliation());
296 }
298 public String toString() {
299 return "substitutionGroup::";
300 }
301 };
303 public static final Axis<XSAttributeDecl> ATTRIBUTE = new AbstractAxisImpl<XSAttributeDecl>() {
304 public Iterator<XSAttributeDecl> complexType(XSComplexType type) {
305 return attributeHolder(type);
306 }
308 public Iterator<XSAttributeDecl> attGroupDecl(XSAttGroupDecl decl) {
309 return attributeHolder(decl);
310 }
312 private Iterator<XSAttributeDecl> attributeHolder(final XSAttContainer atts) {
313 // TODO: check spec. is this correct?
314 return new Iterators.Adapter<XSAttributeDecl,XSAttributeUse>(atts.iterateAttributeUses()) {
315 protected XSAttributeDecl filter(XSAttributeUse u) {
316 return u.getDecl();
317 }
318 };
319 }
321 public Iterator<XSAttributeDecl> schema(XSSchema schema) {
322 return schema.iterateAttributeDecls();
323 }
325 public String toString() {
326 return "@";
327 }
328 };
330 public static final Axis<XSElementDecl> ELEMENT = new AbstractAxisImpl<XSElementDecl>() {
331 public Iterator<XSElementDecl> particle(XSParticle particle) {
332 return singleton(particle.getTerm().asElementDecl());
333 }
335 public Iterator<XSElementDecl> schema(XSSchema schema) {
336 return schema.iterateElementDecls();
337 }
339 public Iterator<XSElementDecl> modelGroupDecl(XSModelGroupDecl decl) {
340 return modelGroup(decl.getModelGroup());
341 }
343 //public Iterator<XSElementDecl> modelGroup(XSModelGroup group) {
344 // return new Iterators.Map<XSElementDecl,XSParticle>(group.iterator()) {
345 // protected Iterator<XSElementDecl> apply(XSParticle p) {
346 // return particle(p);
347 // }
348 // };
349 //}
351 @Override
352 public String getName() {
353 return "";
354 }
356 public String toString() {
357 return "element::";
358 }
359 };
362 public static final Axis<XSType> TYPE_DEFINITION = new AbstractAxisImpl<XSType>() {
363 public Iterator<XSType> schema(XSSchema schema) {
364 return schema.iterateTypes();
365 }
367 public Iterator<XSType> attributeDecl(XSAttributeDecl decl) {
368 return singleton(decl.getType());
369 }
371 public Iterator<XSType> elementDecl(XSElementDecl decl) {
372 return singleton(decl.getType());
373 }
375 public String toString() {
376 return "~";
377 }
378 };
380 public static final Axis<XSType> BASETYPE = new AbstractAxisImpl<XSType>() {
381 public Iterator<XSType> simpleType(XSSimpleType type) {
382 return singleton(type.getBaseType());
383 }
385 public Iterator<XSType> complexType(XSComplexType type) {
386 return singleton(type.getBaseType());
387 }
389 public String toString() {
390 return "baseType::";
391 }
392 };
394 public static final Axis<XSSimpleType> PRIMITIVE_TYPE = new AbstractAxisImpl<XSSimpleType>() {
395 public Iterator<XSSimpleType> simpleType(XSSimpleType type) {
396 return singleton(type.getPrimitiveType());
397 }
399 public String toString() {
400 return "primitiveType::";
401 }
402 };
404 public static final Axis<XSSimpleType> ITEM_TYPE = new AbstractAxisImpl<XSSimpleType>() {
405 public Iterator<XSSimpleType> simpleType(XSSimpleType type) {
406 XSListSimpleType baseList = type.getBaseListType();
407 if(baseList==null) return empty();
408 return singleton(baseList.getItemType());
409 }
411 public String toString() {
412 return "itemType::";
413 }
414 };
416 public static final Axis<XSSimpleType> MEMBER_TYPE = new AbstractAxisImpl<XSSimpleType>() {
417 public Iterator<XSSimpleType> simpleType(XSSimpleType type) {
418 XSUnionSimpleType baseUnion = type.getBaseUnionType();
419 if(baseUnion ==null) return empty();
420 return baseUnion.iterator();
421 }
423 public String toString() {
424 return "memberType::";
425 }
426 };
428 public static final Axis<XSComponent> SCOPE = new AbstractAxisImpl<XSComponent>() {
429 public Iterator<XSComponent> complexType(XSComplexType type) {
430 return singleton(type.getScope());
431 }
432 // TODO: attribute declaration has a scope, too.
433 // TODO: element declaration has a scope
435 public String toString() {
436 return "scope::";
437 }
438 };
440 public static final Axis<XSAttGroupDecl> ATTRIBUTE_GROUP = new AbstractAxisImpl<XSAttGroupDecl>() {
441 public Iterator<XSAttGroupDecl> schema(XSSchema schema) {
442 return schema.iterateAttGroupDecls();
443 }
445 public String toString() {
446 return "attributeGroup::";
447 }
448 };
450 public static final Axis<XSModelGroupDecl> MODEL_GROUP_DECL = new AbstractAxisImpl<XSModelGroupDecl>() {
451 public Iterator<XSModelGroupDecl> schema(XSSchema schema) {
452 return schema.iterateModelGroupDecls();
453 }
455 public Iterator<XSModelGroupDecl> particle(XSParticle particle) {
456 return singleton(particle.getTerm().asModelGroupDecl());
457 }
459 public String toString() {
460 return "group::";
461 }
462 };
464 public static final Axis<XSIdentityConstraint> IDENTITY_CONSTRAINT = new AbstractAxisImpl<XSIdentityConstraint>() {
465 public Iterator<XSIdentityConstraint> elementDecl(XSElementDecl decl) {
466 return decl.getIdentityConstraints().iterator();
467 }
469 public Iterator<XSIdentityConstraint> schema(XSSchema schema) {
470 // TODO: iterate all elements in this schema (local or global!) and its identity constraints
471 return super.schema(schema);
472 }
474 public String toString() {
475 return "identityConstraint::";
476 }
477 };
479 public static final Axis<XSIdentityConstraint> REFERENCED_KEY = new AbstractAxisImpl<XSIdentityConstraint>() {
480 public Iterator<XSIdentityConstraint> identityConstraint(XSIdentityConstraint decl) {
481 return singleton(decl.getReferencedKey());
482 }
484 public String toString() {
485 return "key::";
486 }
487 };
489 public static final Axis<XSNotation> NOTATION = new AbstractAxisImpl<XSNotation>() {
490 public Iterator<XSNotation> schema(XSSchema schema) {
491 return schema.iterateNotations();
492 }
494 public String toString() {
495 return "notation::";
496 }
497 };
499 public static final Axis<XSWildcard> WILDCARD = new AbstractAxisImpl<XSWildcard>() {
500 public Iterator<XSWildcard> particle(XSParticle particle) {
501 return singleton(particle.getTerm().asWildcard());
502 }
504 public String toString() {
505 return "any::";
506 }
507 };
509 public static final Axis<XSWildcard> ATTRIBUTE_WILDCARD = new AbstractAxisImpl<XSWildcard>() {
510 public Iterator<XSWildcard> complexType(XSComplexType type) {
511 return singleton(type.getAttributeWildcard());
512 }
514 public Iterator<XSWildcard> attGroupDecl(XSAttGroupDecl decl) {
515 return singleton(decl.getAttributeWildcard());
516 }
518 public String toString() {
519 return "anyAttribute::";
520 }
521 };
523 public static final Axis<XSFacet> FACET = new AbstractAxisImpl<XSFacet>() {
524 public Iterator<XSFacet> simpleType(XSSimpleType type) {
525 // TODO: it's not clear if "facets" mean all inherited facets or just declared facets
526 XSRestrictionSimpleType r = type.asRestriction();
527 if(r!=null)
528 return r.iterateDeclaredFacets();
529 else
530 return empty();
531 }
533 public String toString() {
534 return "facet::";
535 }
536 };
538 public static final Axis<XSModelGroup> MODELGROUP_ALL = new ModelGroupAxis(Compositor.ALL);
539 public static final Axis<XSModelGroup> MODELGROUP_CHOICE = new ModelGroupAxis(Compositor.CHOICE);
540 public static final Axis<XSModelGroup> MODELGROUP_SEQUENCE = new ModelGroupAxis(Compositor.SEQUENCE);
541 public static final Axis<XSModelGroup> MODELGROUP_ANY = new ModelGroupAxis(null);
543 static final class ModelGroupAxis extends AbstractAxisImpl<XSModelGroup> {
544 private final XSModelGroup.Compositor compositor;
546 ModelGroupAxis(Compositor compositor) {
547 this.compositor = compositor;
548 }
550 @Override
551 public boolean isModelGroup() {
552 return true;
553 }
555 public Iterator<XSModelGroup> particle(XSParticle particle) {
556 return filter(particle.getTerm().asModelGroup());
557 }
559 public Iterator<XSModelGroup> modelGroupDecl(XSModelGroupDecl decl) {
560 return filter(decl.getModelGroup());
561 }
563 private Iterator<XSModelGroup> filter(XSModelGroup mg) {
564 if(mg==null)
565 return empty();
566 if(mg.getCompositor() == compositor || compositor == null)
567 return singleton(mg);
568 else
569 return empty();
570 }
572 public String toString() {
573 if(compositor==null)
574 return "model::*";
575 else
576 return "model::"+compositor;
577 }
578 }
579 }