All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.xml.xsom.impl.scd.Axis Maven / Gradle / Ivy

There is a newer version: 4.0.5
Show newest version
/*
 * Copyright (c) 1997, 2022 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0, which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

package com.sun.xml.xsom.impl.scd;

import com.sun.xml.xsom.XSAttContainer;
import com.sun.xml.xsom.XSAttGroupDecl;
import com.sun.xml.xsom.XSAttributeDecl;
import com.sun.xml.xsom.XSAttributeUse;
import com.sun.xml.xsom.XSComplexType;
import com.sun.xml.xsom.XSComponent;
import com.sun.xml.xsom.XSElementDecl;
import com.sun.xml.xsom.XSFacet;
import com.sun.xml.xsom.XSIdentityConstraint;
import com.sun.xml.xsom.XSListSimpleType;
import com.sun.xml.xsom.XSModelGroup;
import com.sun.xml.xsom.XSModelGroup.Compositor;
import com.sun.xml.xsom.XSModelGroupDecl;
import com.sun.xml.xsom.XSNotation;
import com.sun.xml.xsom.XSParticle;
import com.sun.xml.xsom.XSRestrictionSimpleType;
import com.sun.xml.xsom.XSSchema;
import com.sun.xml.xsom.XSSimpleType;
import com.sun.xml.xsom.XSType;
import com.sun.xml.xsom.XSUnionSimpleType;
import com.sun.xml.xsom.XSWildcard;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
 * Axis of traversal.
 *
 * @param 
 *      The kind of components that this axis may return.
 *
 * @author Kohsuke Kawaguchi
 */
public interface Axis {
    Iterator iterator(XSComponent contextNode);

    Iterator iterator(Iterator contextNodes);

    /**
     * Returns true if this is one of the model group axis.
     */
    boolean isModelGroup();


    /**
     * Pseudo-axis that selects all the {@link XSSchema}s in the current set.
     * Used to implement the absolute path expression
     */
    Axis ROOT = new Axis<>() {
        public Iterator iterator(XSComponent contextNode) {
            return contextNode.getRoot().iterateSchema();
        }

        public Iterator iterator(Iterator contextNodes) {
            if (!contextNodes.hasNext())
                return Iterators.empty();
            else
                // this assumes that all current nodes belong to the same owner.
                return iterator(contextNodes.next());
        }

        public boolean isModelGroup() {
            return false;
        }

        public String toString() {
            return "root::";
        }
    };

    /**
     * Pseudo-axis that visits all skipped intermediate steps.
     * Those are:
     * 
    *
  1. complex type reachable from element *
  2. model groups *
  3. combination of above. *
*/ Axis INTERMEDIATE_SKIP = new AbstractAxisImpl<>() { public Iterator elementDecl(XSElementDecl decl) { XSComplexType ct = decl.getType().asComplexType(); if (ct == null) return empty(); else { // also pick up model groups inside this complex type return new Iterators.Union<>(singleton(ct), complexType(ct)); } } public Iterator modelGroupDecl(XSModelGroupDecl decl) { return descendants(decl.getModelGroup()); } public Iterator particle(XSParticle particle) { return descendants(particle.getTerm().asModelGroup()); } /** * Iterate all descendant model groups of the given model group, including itself. */ private Iterator descendants(XSModelGroup mg) { // TODO: write a tree iterator // for now, we do it eagerly because I'm lazy List r = new ArrayList<>(); visit(mg, r); return r.iterator(); } private void visit(XSModelGroup mg, List r) { // since model groups never form a cycle, no cycle check is needed r.add(mg); for (XSParticle p : mg) { XSModelGroup child = p.getTerm().asModelGroup(); if (child != null) visit(child, r); } } public String toString() { return "(intermediateSkip)"; } }; /** * All descendants reachable via default axes. Used to implement the "//" semantics. * * So far the default axes together are guaranteed not to cause any cycle, so * no cycle check is needed (if it's needed, the life would be much harder!) */ Axis DESCENDANTS = new Axis<>() { public Iterator iterator(XSComponent contextNode) { return new Visitor().iterator(contextNode); } public Iterator iterator(Iterator contextNodes) { return new Visitor().iterator(contextNodes); } public boolean isModelGroup() { return false; } /** * Stateful visitor that remembers what's already traversed, to reduce the search space. */ final class Visitor extends AbstractAxisImpl { private final Set visited = new HashSet<>(); /** * Recursively apply the {@link Axis#DESCENDANTS} axis. */ final class Recursion extends Iterators.Map { public Recursion(Iterator core) { super(core); } protected Iterator apply(XSComponent u) { return DESCENDANTS.iterator(u); } } public Iterator schema(XSSchema schema) { if (visited.add(schema)) return ret(schema, new Recursion(schema.iterateElementDecls())); else return empty(); } public Iterator elementDecl(XSElementDecl decl) { if (visited.add(decl)) return ret(decl, iterator(decl.getType())); else return empty(); } public Iterator simpleType(XSSimpleType type) { if (visited.add(type)) return ret(type, FACET.iterator(type)); else return empty(); } public Iterator complexType(XSComplexType type) { if (visited.add(type)) return ret(type, iterator(type.getContentType())); else return empty(); } public Iterator particle(XSParticle particle) { if (visited.add(particle)) return ret(particle, iterator(particle.getTerm())); else return empty(); } public Iterator modelGroupDecl(XSModelGroupDecl decl) { if (visited.add(decl)) return ret(decl, iterator(decl.getModelGroup())); else return empty(); } public Iterator modelGroup(XSModelGroup group) { if (visited.add(group)) return ret(group, new Recursion(group.iterator())); else return empty(); } public Iterator attGroupDecl(XSAttGroupDecl decl) { if (visited.add(decl)) return ret(decl, new Recursion(decl.iterateAttributeUses())); else return empty(); } public Iterator attributeUse(XSAttributeUse use) { if (visited.add(use)) return ret(use, iterator(use.getDecl())); else return empty(); } public Iterator attributeDecl(XSAttributeDecl decl) { if (visited.add(decl)) return ret(decl, iterator(decl.getType())); else return empty(); } private Iterator ret(XSComponent one, Iterator rest) { return union(singleton(one), rest); } } public String toString() { return "/"; } }; Axis X_SCHEMA = new Axis<>() { public Iterator iterator(XSComponent contextNode) { return Iterators.singleton(contextNode.getOwnerSchema()); } public Iterator iterator(Iterator contextNodes) { return new Iterators.Adapter(contextNodes) { protected XSSchema filter(XSComponent u) { return u.getOwnerSchema(); } }; } public boolean isModelGroup() { return false; } public String toString() { return "x-schema::"; } }; Axis SUBSTITUTION_GROUP = new AbstractAxisImpl<>() { public Iterator elementDecl(XSElementDecl decl) { return singleton(decl.getSubstAffiliation()); } public String toString() { return "substitutionGroup::"; } }; Axis ATTRIBUTE = new AbstractAxisImpl<>() { public Iterator complexType(XSComplexType type) { return attributeHolder(type); } public Iterator attGroupDecl(XSAttGroupDecl decl) { return attributeHolder(decl); } private Iterator attributeHolder(final XSAttContainer atts) { // TODO: check spec. is this correct? return new Iterators.Adapter(atts.iterateAttributeUses()) { protected XSAttributeDecl filter(XSAttributeUse u) { return u.getDecl(); } }; } public Iterator schema(XSSchema schema) { return schema.iterateAttributeDecls(); } public String toString() { return "@"; } }; Axis ELEMENT = new AbstractAxisImpl<>() { public Iterator particle(XSParticle particle) { return singleton(particle.getTerm().asElementDecl()); } public Iterator schema(XSSchema schema) { return schema.iterateElementDecls(); } public Iterator modelGroupDecl(XSModelGroupDecl decl) { return modelGroup(decl.getModelGroup()); } //public Iterator modelGroup(XSModelGroup group) { // return new Iterators.Map(group.iterator()) { // protected Iterator apply(XSParticle p) { // return particle(p); // } // }; //} @Override public String getName() { return ""; } public String toString() { return "element::"; } }; Axis TYPE_DEFINITION = new AbstractAxisImpl<>() { public Iterator schema(XSSchema schema) { return schema.iterateTypes(); } public Iterator attributeDecl(XSAttributeDecl decl) { return singleton(decl.getType()); } public Iterator elementDecl(XSElementDecl decl) { return singleton(decl.getType()); } public String toString() { return "~"; } }; Axis BASETYPE = new AbstractAxisImpl<>() { public Iterator simpleType(XSSimpleType type) { return singleton(type.getBaseType()); } public Iterator complexType(XSComplexType type) { return singleton(type.getBaseType()); } public String toString() { return "baseType::"; } }; Axis PRIMITIVE_TYPE = new AbstractAxisImpl<>() { public Iterator simpleType(XSSimpleType type) { return singleton(type.getPrimitiveType()); } public String toString() { return "primitiveType::"; } }; Axis ITEM_TYPE = new AbstractAxisImpl<>() { public Iterator simpleType(XSSimpleType type) { XSListSimpleType baseList = type.getBaseListType(); if (baseList == null) return empty(); return singleton(baseList.getItemType()); } public String toString() { return "itemType::"; } }; Axis MEMBER_TYPE = new AbstractAxisImpl<>() { public Iterator simpleType(XSSimpleType type) { XSUnionSimpleType baseUnion = type.getBaseUnionType(); if (baseUnion == null) return empty(); return baseUnion.iterator(); } public String toString() { return "memberType::"; } }; Axis SCOPE = new AbstractAxisImpl<>() { public Iterator complexType(XSComplexType type) { return singleton(type.getScope()); } // TODO: attribute declaration has a scope, too. // TODO: element declaration has a scope public String toString() { return "scope::"; } }; Axis ATTRIBUTE_GROUP = new AbstractAxisImpl<>() { public Iterator schema(XSSchema schema) { return schema.iterateAttGroupDecls(); } public String toString() { return "attributeGroup::"; } }; Axis MODEL_GROUP_DECL = new AbstractAxisImpl<>() { public Iterator schema(XSSchema schema) { return schema.iterateModelGroupDecls(); } public Iterator particle(XSParticle particle) { return singleton(particle.getTerm().asModelGroupDecl()); } public String toString() { return "group::"; } }; Axis IDENTITY_CONSTRAINT = new AbstractAxisImpl<>() { public Iterator elementDecl(XSElementDecl decl) { return decl.getIdentityConstraints().iterator(); } public Iterator schema(XSSchema schema) { // TODO: iterate all elements in this schema (local or global!) and its identity constraints return super.schema(schema); } public String toString() { return "identityConstraint::"; } }; Axis REFERENCED_KEY = new AbstractAxisImpl<>() { public Iterator identityConstraint(XSIdentityConstraint decl) { return singleton(decl.getReferencedKey()); } public String toString() { return "key::"; } }; Axis NOTATION = new AbstractAxisImpl<>() { public Iterator schema(XSSchema schema) { return schema.iterateNotations(); } public String toString() { return "notation::"; } }; Axis WILDCARD = new AbstractAxisImpl<>() { public Iterator particle(XSParticle particle) { return singleton(particle.getTerm().asWildcard()); } public String toString() { return "any::"; } }; Axis ATTRIBUTE_WILDCARD = new AbstractAxisImpl<>() { public Iterator complexType(XSComplexType type) { return singleton(type.getAttributeWildcard()); } public Iterator attGroupDecl(XSAttGroupDecl decl) { return singleton(decl.getAttributeWildcard()); } public String toString() { return "anyAttribute::"; } }; Axis FACET = new AbstractAxisImpl<>() { public Iterator simpleType(XSSimpleType type) { // TODO: it's not clear if "facets" mean all inherited facets or just declared facets XSRestrictionSimpleType r = type.asRestriction(); if (r != null) return r.iterateDeclaredFacets(); else return empty(); } public String toString() { return "facet::"; } }; Axis MODELGROUP_ALL = new ModelGroupAxis(Compositor.ALL); Axis MODELGROUP_CHOICE = new ModelGroupAxis(Compositor.CHOICE); Axis MODELGROUP_SEQUENCE = new ModelGroupAxis(Compositor.SEQUENCE); Axis MODELGROUP_ANY = new ModelGroupAxis(null); final class ModelGroupAxis extends AbstractAxisImpl { private final XSModelGroup.Compositor compositor; ModelGroupAxis(Compositor compositor) { this.compositor = compositor; } @Override public boolean isModelGroup() { return true; } public Iterator particle(XSParticle particle) { return filter(particle.getTerm().asModelGroup()); } public Iterator modelGroupDecl(XSModelGroupDecl decl) { return filter(decl.getModelGroup()); } private Iterator filter(XSModelGroup mg) { if(mg==null) return empty(); if(mg.getCompositor() == compositor || compositor == null) return singleton(mg); else return empty(); } public String toString() { if(compositor==null) return "model::*"; else return "model::"+compositor; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy