com.sun.msv.grammar.xmlschema.ElementDeclExp Maven / Gradle / Ivy
/*
* Copyright (c) 2001-2013 Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.msv.grammar.xmlschema;
import java.util.Vector;
import com.sun.msv.grammar.ChoiceExp;
import com.sun.msv.grammar.ElementExp;
import com.sun.msv.grammar.Expression;
import com.sun.msv.grammar.NameClass;
import com.sun.msv.grammar.ReferenceExp;
import com.sun.msv.grammar.SimpleNameClass;
import com.sun.msv.grammar.util.ExpressionWalker;
/**
* Element declaration.
*
*
* the inherited exp field holds an expression that
* also matches to substituted element declarations.
*
*
* The body
field contains an expression that matches
* only to this element declaration without no substituted element decls.
*
*
*
Element Declaration Schema Component Properties
*
* This table shows the mapping between
*
* "element declaration schema component properties"
* (which is defined in the spec) and corresponding method/field of this class.
*
*
*
* Property of the spec
* method/field of this class
*
*
*
* name
*
* The {@link #name} field.
*
*
*
* target namespace
*
* the {@link #getTargetNamespace()} method.
*
*
*
* type definition
*
* {@link #getTypeDefinition()} method.
*
*
*
* scope
*
* To be implemented
*
*
*
* value constraint
*
* To be implemented. Accessible through the {@link #body} field.
*
*
*
* nillable
*
* the {@link #isNillable} field.
*
*
*
* identity constraints
*
* The identityConstraints
field of the {@link XSElementExp},
* which in turn can be obtained throught the {@link #body} field.
*
*
*
* substitution group affiliation
*
* The {@link #substitutionAffiliation} field.
*
*
*
* substitution group exclusion
*
* The {@link #finalValue} field.
*
*
*
* disallowed substitution
*
* The {@link #block} field.
*
*
*
* abstract
*
* the {@link #isAbstract()} method.
*
*
*
* annotation
*
* Unaccessible. This information is removed during the parsing phase.
*
*
*
*
*
*
* Abstractness
*
*
* The exp
field and the self
field are very similar.
* In fact, the only difference is that the former is affected by the abstract
* property, while the latter isn't.
*
*
* So if it has to be affected by the
* abstract property (like referencing a complex type as the element body),
* you should use the exp
field.
* If you don't want to be affected by the abstract property
* (like referencing a complex type as the base type of another complex type),
* then you should refer to the body
field.
*
*
* @author Kohsuke KAWAGUCHI
*/
public class ElementDeclExp extends ReferenceExp
{
public ElementDeclExp( XMLSchemaSchema schema, String typeLocalName ) {
super(typeLocalName);
this.parent = schema;
this.substitutions = new ReferenceExp( typeLocalName+":substitutions" );
this.substitutions.exp = Expression.nullSet;
}
/**
*
* The substitution group affiliation property
* of this component, if any.
* Otherwise null.
*/
public ElementDeclExp substitutionAffiliation;
/**
* The expression that represents the "body" of this expression.
* Usually, this refers to XSElementExp, but not necessarily.
*/
public final ReferenceExp body = new ReferenceExp(null);
private XSElementExp element;
public void setElementExp( XSElementExp exp ) {
this.element = exp;
body.exp = exp;
}
public XSElementExp getElementExp() { return element; }
/**
* choices of all elements that can validly substitute this element.
*/
public final ReferenceExp substitutions;
/**
* gets the pattern that represents the content model of
* this element declaration.
*
* This method is just a short cut for self.contentModel
.
*/
public Expression getContentModel() {
return element.contentModel;
}
/** parent XMLSchemaSchema object to which this object belongs. */
public final XMLSchemaSchema parent;
/**
* XML Schema version of {@link ElementExp}.
*
* @author Kohsuke KAWAGUCHI
*/
public class XSElementExp extends ElementExp {
public final SimpleNameClass elementName;
public final NameClass getNameClass() { return elementName; }
public XSElementExp( SimpleNameClass elementName, Expression contentModel ) {
super(contentModel,false);
this.elementName = elementName;
parent = ElementDeclExp.this;
}
/**
* identity constraints associated to this declaration.
* When no constraint exists, this field may be null (or empty vector).
* Items are of derived types of {@link IdentityConstraint} class.
*
*
* These identity constraints are not enforced by the default Verifier
* implementation.
*/
public final Vector identityConstraints = new Vector();
public final ElementDeclExp parent;
}
//
// Schema component properties
//======================================
//
/**
* gets the nillable property of this component as
*
* specified in the spec.
*/
public boolean isNillable;
/**
* gets the scope property of this component as
*
* specified in the spec.
*
* @return
* true if this component is global.
* false if this component is local.
*/
public boolean isGlobal() {
return parent.elementDecls.get(name)==this;
}
/**
* gets the target namespace property of this component as
*
* specified in the spec.
*
*
* If the property is
* absent, then this method returns the empty string.
*
*
* This method is just a shortcut for parent.targetNamespace
.
*/
public final String getTargetNamespace() {
return parent.targetNamespace;
}
/**
* checks if this element declaration is abstract.
*
* @return
* true if this method is abstract.
*/
public boolean isAbstract() {
if( exp instanceof ChoiceExp ) {
ChoiceExp cexp = (ChoiceExp)exp;
if(cexp.exp1!=body && cexp.exp2!=body)
throw new Error(); // assertion failed
return true;
}
if(exp!=substitutions)
throw new Error(); // assertion failed
return false;
}
public void setAbstract( boolean isAbstract ) {
if(isAbstract) exp = substitutions;
else exp = parent.pool.createChoice( substitutions, body );
}
public static final int RESTRICTION = 0x1;
public static final int EXTENSION = 0x2;
public static final int SUBSTITUTION = 0x4;
public static final int ALL = 0x7;
/**
* The
* substitution group exclusions property of this schema component,
* implemented as a bit field.
*
*
* a bit-wise OR of RESTRICTION and EXTENSION.
*/
public int finalValue =0;
/**
* The
* disallowed substitution property of this schema component,
* implemented as a bit field.
*
*
* a bit-wise OR of RESTRICTION, EXTENSION, and SUBSTITUTION.
*/
public int block =0;
public boolean isSubstitutionBlocked() { return (block&SUBSTITUTION)!=0; }
public boolean isRestrictionBlocked() { return (block&RESTRICTION)!=0; }
/**
* gets the
* type definition property of this schema component.
*/
public XMLSchemaTypeExp getTypeDefinition() {
final RuntimeException eureka = new RuntimeException();
final XMLSchemaTypeExp[] result = new XMLSchemaTypeExp[1];
try {
getContentModel().visit( new ExpressionWalker(){
public void onElement( ElementExp exp ) {}
public void onRef( ReferenceExp exp ) {
if(exp instanceof XMLSchemaTypeExp) {
result[0] = (XMLSchemaTypeExp)exp;
throw eureka;
}
super.onRef(exp);
}
});
// assertion failed. It couldn't be found.
throw new Error();
} catch( RuntimeException e ) {
if(e==eureka) return result[0];
throw e;
}
}
//
// Implementation details
//=========================================
public boolean isDefined() {
return super.isDefined() && element!=null;
}
// serialization support
private static final long serialVersionUID = 1;
}