com.sun.xml.xsom.impl.scd.Axis Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of schema2proto-xsom Show documentation
Show all versions of schema2proto-xsom Show documentation
XML Schema Object Model (XSOM) is a Java library that allows applications to easily parse XML Schema
documents and inspect information in them. It is expected to be useful for applications that need to take XML
Schema as an input.
The newest version!
/*
* Copyright (c) 1997, 2018 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;
/*-
* #%L
* XSOM
* %%
* Copyright (C) 2019 - 2020 Entur
* %%
* Licensed under the EUPL, Version 1.1 or – as soon they will be
* approved by the European Commission - subsequent versions of the
* EUPL (the "Licence");
*
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://ec.europa.eu/idabc/eupl5
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
* #L%
*/
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.LinkedHashSet;
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 extends XSComponent> 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
*/
public static final Axis ROOT = new Axis() {
public Iterator iterator(XSComponent contextNode) {
return contextNode.getRoot().iterateSchema();
}
public Iterator iterator(Iterator extends XSComponent> 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:
*
* - complex type reachable from element
*
- model groups
*
- combination of above.
*
*/
public static final 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!)
*/
public static final Axis DESCENDANTS = new Axis() {
public Iterator iterator(XSComponent contextNode) {
return new Visitor().iterator(contextNode);
}
public Iterator iterator(Iterator extends XSComponent> 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 LinkedHashSet();
/**
* Recursively apply the {@link Axis#DESCENDANTS} axis.
*/
final class Recursion extends Iterators.Map {
public Recursion(Iterator extends XSComponent> 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 extends XSComponent> rest ) {
return union(singleton(one),rest);
}
}
public String toString() {
return "/";
}
};
public static final Axis X_SCHEMA = new Axis() {
public Iterator iterator(XSComponent contextNode) {
return Iterators.singleton(contextNode.getOwnerSchema());
}
public Iterator iterator(Iterator extends XSComponent> 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::";
}
};
public static final Axis SUBSTITUTION_GROUP = new AbstractAxisImpl() {
public Iterator elementDecl(XSElementDecl decl) {
return singleton(decl.getSubstAffiliation());
}
public String toString() {
return "substitutionGroup::";
}
};
public static final 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 "@";
}
};
public static final 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::";
}
};
public static final 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 "~";
}
};
public static final 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::";
}
};
public static final Axis PRIMITIVE_TYPE = new AbstractAxisImpl() {
public Iterator simpleType(XSSimpleType type) {
return singleton(type.getPrimitiveType());
}
public String toString() {
return "primitiveType::";
}
};
public static final 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::";
}
};
public static final 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::";
}
};
public static final 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::";
}
};
public static final Axis ATTRIBUTE_GROUP = new AbstractAxisImpl() {
public Iterator schema(XSSchema schema) {
return schema.iterateAttGroupDecls();
}
public String toString() {
return "attributeGroup::";
}
};
public static final 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::";
}
};
public static final 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::";
}
};
public static final Axis REFERENCED_KEY = new AbstractAxisImpl() {
public Iterator identityConstraint(XSIdentityConstraint decl) {
return singleton(decl.getReferencedKey());
}
public String toString() {
return "key::";
}
};
public static final Axis NOTATION = new AbstractAxisImpl() {
public Iterator schema(XSSchema schema) {
return schema.iterateNotations();
}
public String toString() {
return "notation::";
}
};
public static final Axis WILDCARD = new AbstractAxisImpl() {
public Iterator particle(XSParticle particle) {
return singleton(particle.getTerm().asWildcard());
}
public String toString() {
return "any::";
}
};
public static final 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::";
}
};
public static final 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::";
}
};
public static final Axis MODELGROUP_ALL = new ModelGroupAxis(Compositor.ALL);
public static final Axis MODELGROUP_CHOICE = new ModelGroupAxis(Compositor.CHOICE);
public static final Axis MODELGROUP_SEQUENCE = new ModelGroupAxis(Compositor.SEQUENCE);
public static final Axis MODELGROUP_ANY = new ModelGroupAxis(null);
static 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;
}
}
}