Thu, 12 Oct 2017 19:44:07 +0800
merge
aoqi@0 | 1 | /* |
aoqi@0 | 2 | * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. |
aoqi@0 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
aoqi@0 | 4 | * |
aoqi@0 | 5 | * This code is free software; you can redistribute it and/or modify it |
aoqi@0 | 6 | * under the terms of the GNU General Public License version 2 only, as |
aoqi@0 | 7 | * published by the Free Software Foundation. Oracle designates this |
aoqi@0 | 8 | * particular file as subject to the "Classpath" exception as provided |
aoqi@0 | 9 | * by Oracle in the LICENSE file that accompanied this code. |
aoqi@0 | 10 | * |
aoqi@0 | 11 | * This code is distributed in the hope that it will be useful, but WITHOUT |
aoqi@0 | 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
aoqi@0 | 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
aoqi@0 | 14 | * version 2 for more details (a copy is included in the LICENSE file that |
aoqi@0 | 15 | * accompanied this code). |
aoqi@0 | 16 | * |
aoqi@0 | 17 | * You should have received a copy of the GNU General Public License version |
aoqi@0 | 18 | * 2 along with this work; if not, write to the Free Software Foundation, |
aoqi@0 | 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
aoqi@0 | 20 | * |
aoqi@0 | 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
aoqi@0 | 22 | * or visit www.oracle.com if you need additional information or have any |
aoqi@0 | 23 | * questions. |
aoqi@0 | 24 | */ |
aoqi@0 | 25 | |
aoqi@0 | 26 | package com.sun.xml.internal.xsom.impl; |
aoqi@0 | 27 | |
aoqi@0 | 28 | import com.sun.xml.internal.xsom.XSElementDecl; |
aoqi@0 | 29 | import com.sun.xml.internal.xsom.XSIdentityConstraint; |
aoqi@0 | 30 | import com.sun.xml.internal.xsom.XSModelGroup; |
aoqi@0 | 31 | import com.sun.xml.internal.xsom.XSModelGroupDecl; |
aoqi@0 | 32 | import com.sun.xml.internal.xsom.XSTerm; |
aoqi@0 | 33 | import com.sun.xml.internal.xsom.XSType; |
aoqi@0 | 34 | import com.sun.xml.internal.xsom.XSWildcard; |
aoqi@0 | 35 | import com.sun.xml.internal.xsom.XmlString; |
aoqi@0 | 36 | import com.sun.xml.internal.xsom.impl.parser.PatcherManager; |
aoqi@0 | 37 | import com.sun.xml.internal.xsom.impl.parser.SchemaDocumentImpl; |
aoqi@0 | 38 | import com.sun.xml.internal.xsom.visitor.XSFunction; |
aoqi@0 | 39 | import com.sun.xml.internal.xsom.visitor.XSTermFunction; |
aoqi@0 | 40 | import com.sun.xml.internal.xsom.visitor.XSTermFunctionWithParam; |
aoqi@0 | 41 | import com.sun.xml.internal.xsom.visitor.XSTermVisitor; |
aoqi@0 | 42 | import com.sun.xml.internal.xsom.visitor.XSVisitor; |
aoqi@0 | 43 | import org.xml.sax.Locator; |
aoqi@0 | 44 | |
aoqi@0 | 45 | import java.util.Collections; |
aoqi@0 | 46 | import java.util.HashSet; |
aoqi@0 | 47 | import java.util.List; |
aoqi@0 | 48 | import java.util.Set; |
aoqi@0 | 49 | |
aoqi@0 | 50 | public class ElementDecl extends DeclarationImpl implements XSElementDecl, Ref.Term |
aoqi@0 | 51 | { |
aoqi@0 | 52 | public ElementDecl( PatcherManager reader, SchemaDocumentImpl owner, |
aoqi@0 | 53 | AnnotationImpl _annon, Locator _loc, ForeignAttributesImpl fa, |
aoqi@0 | 54 | String _tns, String _name, boolean _anonymous, |
aoqi@0 | 55 | |
aoqi@0 | 56 | XmlString _defv, XmlString _fixedv, |
aoqi@0 | 57 | boolean _nillable, boolean _abstract, Boolean _form, |
aoqi@0 | 58 | Ref.Type _type, Ref.Element _substHead, |
aoqi@0 | 59 | int _substDisallowed, int _substExcluded, |
aoqi@0 | 60 | List<IdentityConstraintImpl> idConstraints) { |
aoqi@0 | 61 | |
aoqi@0 | 62 | super(owner,_annon,_loc,fa,_tns,_name,_anonymous); |
aoqi@0 | 63 | |
aoqi@0 | 64 | this.defaultValue = _defv; |
aoqi@0 | 65 | this.fixedValue = _fixedv; |
aoqi@0 | 66 | this.nillable = _nillable; |
aoqi@0 | 67 | this._abstract = _abstract; |
aoqi@0 | 68 | this.form = _form; |
aoqi@0 | 69 | this.type = _type; |
aoqi@0 | 70 | this.substHead = _substHead; |
aoqi@0 | 71 | this.substDisallowed = _substDisallowed; |
aoqi@0 | 72 | this.substExcluded = _substExcluded; |
aoqi@0 | 73 | this.idConstraints = Collections.unmodifiableList((List<? extends XSIdentityConstraint>)idConstraints); |
aoqi@0 | 74 | |
aoqi@0 | 75 | for (IdentityConstraintImpl idc : idConstraints) |
aoqi@0 | 76 | idc.setParent(this); |
aoqi@0 | 77 | |
aoqi@0 | 78 | if(type==null) |
aoqi@0 | 79 | throw new IllegalArgumentException(); |
aoqi@0 | 80 | } |
aoqi@0 | 81 | |
aoqi@0 | 82 | private XmlString defaultValue; |
aoqi@0 | 83 | public XmlString getDefaultValue() { return defaultValue; } |
aoqi@0 | 84 | |
aoqi@0 | 85 | private XmlString fixedValue; |
aoqi@0 | 86 | public XmlString getFixedValue() { return fixedValue; } |
aoqi@0 | 87 | |
aoqi@0 | 88 | private boolean nillable; |
aoqi@0 | 89 | public boolean isNillable() { return nillable; } |
aoqi@0 | 90 | |
aoqi@0 | 91 | private boolean _abstract; |
aoqi@0 | 92 | public boolean isAbstract() { return _abstract; } |
aoqi@0 | 93 | |
aoqi@0 | 94 | private Ref.Type type; |
aoqi@0 | 95 | public XSType getType() { return type.getType(); } |
aoqi@0 | 96 | |
aoqi@0 | 97 | private Ref.Element substHead; |
aoqi@0 | 98 | public XSElementDecl getSubstAffiliation() { |
aoqi@0 | 99 | if(substHead==null) return null; |
aoqi@0 | 100 | return substHead.get(); |
aoqi@0 | 101 | } |
aoqi@0 | 102 | |
aoqi@0 | 103 | private int substDisallowed; |
aoqi@0 | 104 | public boolean isSubstitutionDisallowed( int method ) { |
aoqi@0 | 105 | return (substDisallowed&method)!=0; |
aoqi@0 | 106 | } |
aoqi@0 | 107 | |
aoqi@0 | 108 | private int substExcluded; |
aoqi@0 | 109 | public boolean isSubstitutionExcluded( int method ) { |
aoqi@0 | 110 | return (substExcluded&method)!=0; |
aoqi@0 | 111 | } |
aoqi@0 | 112 | |
aoqi@0 | 113 | private final List<XSIdentityConstraint> idConstraints; |
aoqi@0 | 114 | public List<XSIdentityConstraint> getIdentityConstraints() { |
aoqi@0 | 115 | return idConstraints; |
aoqi@0 | 116 | } |
aoqi@0 | 117 | |
aoqi@0 | 118 | private Boolean form; |
aoqi@0 | 119 | public Boolean getForm() { |
aoqi@0 | 120 | return form; |
aoqi@0 | 121 | } |
aoqi@0 | 122 | |
aoqi@0 | 123 | |
aoqi@0 | 124 | /** |
aoqi@0 | 125 | * @deprecated |
aoqi@0 | 126 | */ |
aoqi@0 | 127 | public XSElementDecl[] listSubstitutables() { |
aoqi@0 | 128 | Set<? extends XSElementDecl> s = getSubstitutables(); |
aoqi@0 | 129 | return s.toArray(new XSElementDecl[s.size()]); |
aoqi@0 | 130 | } |
aoqi@0 | 131 | |
aoqi@0 | 132 | /** Set that represents element decls that can substitute this element. */ |
aoqi@0 | 133 | private Set<XSElementDecl> substitutables = null; |
aoqi@0 | 134 | |
aoqi@0 | 135 | /** Unmodifieable view of {@link #substitutables}. */ |
aoqi@0 | 136 | private Set<XSElementDecl> substitutablesView = null; |
aoqi@0 | 137 | |
aoqi@0 | 138 | public Set<? extends XSElementDecl> getSubstitutables() { |
aoqi@0 | 139 | if( substitutables==null ) { |
aoqi@0 | 140 | // if the field is null by the time this method |
aoqi@0 | 141 | // is called, it means this element is substitutable by itself only. |
aoqi@0 | 142 | substitutables = substitutablesView = Collections.singleton((XSElementDecl)this); |
aoqi@0 | 143 | } |
aoqi@0 | 144 | return substitutablesView; |
aoqi@0 | 145 | } |
aoqi@0 | 146 | |
aoqi@0 | 147 | protected void addSubstitutable( ElementDecl decl ) { |
aoqi@0 | 148 | if( substitutables==null ) { |
aoqi@0 | 149 | substitutables = new HashSet<XSElementDecl>(); |
aoqi@0 | 150 | substitutables.add(this); |
aoqi@0 | 151 | substitutablesView = Collections.unmodifiableSet(substitutables); |
aoqi@0 | 152 | } |
aoqi@0 | 153 | substitutables.add(decl); |
aoqi@0 | 154 | } |
aoqi@0 | 155 | |
aoqi@0 | 156 | |
aoqi@0 | 157 | public void updateSubstitutabilityMap() { |
aoqi@0 | 158 | ElementDecl parent = this; |
aoqi@0 | 159 | XSType type = this.getType(); |
aoqi@0 | 160 | |
aoqi@0 | 161 | boolean rused = false; |
aoqi@0 | 162 | boolean eused = false; |
aoqi@0 | 163 | |
aoqi@0 | 164 | while( (parent=(ElementDecl)parent.getSubstAffiliation())!=null ) { |
aoqi@0 | 165 | |
aoqi@0 | 166 | if(parent.isSubstitutionDisallowed(XSType.SUBSTITUTION)) |
aoqi@0 | 167 | continue; |
aoqi@0 | 168 | |
aoqi@0 | 169 | boolean rd = parent.isSubstitutionDisallowed(XSType.RESTRICTION); |
aoqi@0 | 170 | boolean ed = parent.isSubstitutionDisallowed(XSType.EXTENSION); |
aoqi@0 | 171 | |
aoqi@0 | 172 | if( (rd && rused) || ( ed && eused ) ) continue; |
aoqi@0 | 173 | |
aoqi@0 | 174 | XSType parentType = parent.getType(); |
aoqi@0 | 175 | while (type!=parentType) { |
aoqi@0 | 176 | if(type.getDerivationMethod()==XSType.RESTRICTION) rused = true; |
aoqi@0 | 177 | else eused = true; |
aoqi@0 | 178 | |
aoqi@0 | 179 | type = type.getBaseType(); |
aoqi@0 | 180 | if(type==null) // parentType and type doesn't share the common base type. a bug in the schema. |
aoqi@0 | 181 | break; |
aoqi@0 | 182 | |
aoqi@0 | 183 | if( type.isComplexType() ) { |
aoqi@0 | 184 | rd |= type.asComplexType().isSubstitutionProhibited(XSType.RESTRICTION); |
aoqi@0 | 185 | ed |= type.asComplexType().isSubstitutionProhibited(XSType.EXTENSION); |
aoqi@0 | 186 | } |
aoqi@0 | 187 | if (getRoot().getAnyType().equals(type)) break; |
aoqi@0 | 188 | } |
aoqi@0 | 189 | |
aoqi@0 | 190 | if( (rd && rused) || ( ed && eused ) ) continue; |
aoqi@0 | 191 | |
aoqi@0 | 192 | // this element can substitute "parent" |
aoqi@0 | 193 | parent.addSubstitutable(this); |
aoqi@0 | 194 | } |
aoqi@0 | 195 | } |
aoqi@0 | 196 | |
aoqi@0 | 197 | public boolean canBeSubstitutedBy(XSElementDecl e) { |
aoqi@0 | 198 | return getSubstitutables().contains(e); |
aoqi@0 | 199 | } |
aoqi@0 | 200 | |
aoqi@0 | 201 | public boolean isWildcard() { return false; } |
aoqi@0 | 202 | public boolean isModelGroupDecl() { return false; } |
aoqi@0 | 203 | public boolean isModelGroup() { return false; } |
aoqi@0 | 204 | public boolean isElementDecl() { return true; } |
aoqi@0 | 205 | |
aoqi@0 | 206 | public XSWildcard asWildcard() { return null; } |
aoqi@0 | 207 | public XSModelGroupDecl asModelGroupDecl() { return null; } |
aoqi@0 | 208 | public XSModelGroup asModelGroup() { return null; } |
aoqi@0 | 209 | public XSElementDecl asElementDecl() { return this; } |
aoqi@0 | 210 | |
aoqi@0 | 211 | |
aoqi@0 | 212 | |
aoqi@0 | 213 | |
aoqi@0 | 214 | public void visit( XSVisitor visitor ) { |
aoqi@0 | 215 | visitor.elementDecl(this); |
aoqi@0 | 216 | } |
aoqi@0 | 217 | public void visit( XSTermVisitor visitor ) { |
aoqi@0 | 218 | visitor.elementDecl(this); |
aoqi@0 | 219 | } |
aoqi@0 | 220 | public Object apply( XSTermFunction function ) { |
aoqi@0 | 221 | return function.elementDecl(this); |
aoqi@0 | 222 | } |
aoqi@0 | 223 | |
aoqi@0 | 224 | public <T,P> T apply(XSTermFunctionWithParam<T, P> function, P param) { |
aoqi@0 | 225 | return function.elementDecl(this,param); |
aoqi@0 | 226 | } |
aoqi@0 | 227 | |
aoqi@0 | 228 | public Object apply( XSFunction function ) { |
aoqi@0 | 229 | return function.elementDecl(this); |
aoqi@0 | 230 | } |
aoqi@0 | 231 | |
aoqi@0 | 232 | |
aoqi@0 | 233 | // Ref.Term implementation |
aoqi@0 | 234 | public XSTerm getTerm() { return this; } |
aoqi@0 | 235 | } |