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 */ 25 26 package com.sun.xml.internal.xsom.impl; 27 28 import com.sun.xml.internal.xsom.XSAttGroupDecl; 29 import com.sun.xml.internal.xsom.XSAttributeDecl; 30 import com.sun.xml.internal.xsom.XSAttributeUse; 31 import com.sun.xml.internal.xsom.XSComplexType; 32 import com.sun.xml.internal.xsom.XSContentType; 33 import com.sun.xml.internal.xsom.XSElementDecl; 34 import com.sun.xml.internal.xsom.XSSchema; 35 import com.sun.xml.internal.xsom.XSSchemaSet; 36 import com.sun.xml.internal.xsom.XSSimpleType; 37 import com.sun.xml.internal.xsom.XSType; 38 import com.sun.xml.internal.xsom.XSWildcard; 39 import com.sun.xml.internal.xsom.impl.parser.DelayedRef; 40 import com.sun.xml.internal.xsom.impl.parser.SchemaDocumentImpl; 41 import com.sun.xml.internal.xsom.impl.scd.Iterators; 42 import com.sun.xml.internal.xsom.visitor.XSFunction; 43 import com.sun.xml.internal.xsom.visitor.XSVisitor; 44 import java.util.ArrayList; 45 import java.util.List; 46 import org.xml.sax.Locator; 47 48 import java.util.Collection; 49 import java.util.HashMap; 50 import java.util.Iterator; 51 import java.util.Map; 52 53 public class ComplexTypeImpl extends AttributesHolder implements XSComplexType, Ref.ComplexType 54 { ComplexTypeImpl( SchemaDocumentImpl _parent, AnnotationImpl _annon, Locator _loc, ForeignAttributesImpl _fa, String _name, boolean _anonymous, boolean _abstract, int _derivationMethod, Ref.Type _base, int _final, int _block, boolean _mixed )55 public ComplexTypeImpl( SchemaDocumentImpl _parent, 56 AnnotationImpl _annon, Locator _loc, ForeignAttributesImpl _fa, 57 String _name, boolean _anonymous, 58 59 boolean _abstract, int _derivationMethod, 60 Ref.Type _base, int _final, int _block, boolean _mixed ) { 61 62 super(_parent,_annon,_loc,_fa,_name,_anonymous); 63 64 if(_base==null) 65 throw new IllegalArgumentException(); 66 67 this._abstract = _abstract; 68 this.derivationMethod = _derivationMethod; 69 this.baseType = _base; 70 this.finalValue = _final; 71 this.blockValue = _block; 72 this.mixed = _mixed; 73 } 74 asComplexType()75 public XSComplexType asComplexType(){ return this; } 76 isDerivedFrom(XSType t)77 public boolean isDerivedFrom(XSType t) { 78 XSType x = this; 79 while(true) { 80 if(t==x) 81 return true; 82 XSType s = x.getBaseType(); 83 if(s==x) 84 return false; 85 x = s; 86 } 87 } 88 asSimpleType()89 public XSSimpleType asSimpleType() { return null; } isSimpleType()90 public final boolean isSimpleType() { return false; } isComplexType()91 public final boolean isComplexType(){ return true; } 92 93 private int derivationMethod; getDerivationMethod()94 public int getDerivationMethod() { return derivationMethod; } 95 96 private Ref.Type baseType; getBaseType()97 public XSType getBaseType() { return baseType.getType(); } 98 99 /** 100 * Called when this complex type redefines the specified complex type. 101 */ redefine( ComplexTypeImpl ct )102 public void redefine( ComplexTypeImpl ct ) { 103 if( baseType instanceof DelayedRef ) 104 ((DelayedRef)baseType).redefine(ct); 105 else 106 this.baseType = ct; 107 ct.redefinedBy = this; 108 redefiningCount = (short)(ct.redefiningCount+1); 109 } 110 111 /** 112 * Number of times this component redefines other components. 113 */ 114 private short redefiningCount = 0; 115 116 private ComplexTypeImpl redefinedBy = null; 117 getRedefinedBy()118 public XSComplexType getRedefinedBy() { 119 return redefinedBy; 120 } 121 getRedefinedCount()122 public int getRedefinedCount() { 123 int i=0; 124 for( ComplexTypeImpl ct=this.redefinedBy; ct!=null; ct=ct.redefinedBy) 125 i++; 126 return i; 127 } 128 129 130 private XSElementDecl scope; getScope()131 public XSElementDecl getScope() { return scope; } setScope( XSElementDecl _scope )132 public void setScope( XSElementDecl _scope ) { this.scope=_scope; } 133 134 private final boolean _abstract; isAbstract()135 public boolean isAbstract() { return _abstract; } 136 137 private WildcardImpl localAttWildcard; 138 /** 139 * Set the local attribute wildcard. 140 */ setWildcard( WildcardImpl wc )141 public void setWildcard( WildcardImpl wc ) { 142 this.localAttWildcard = wc; 143 } getAttributeWildcard()144 public XSWildcard getAttributeWildcard() { 145 WildcardImpl complete = localAttWildcard; 146 147 Iterator itr = iterateAttGroups(); 148 while( itr.hasNext() ) { 149 WildcardImpl w = (WildcardImpl)((XSAttGroupDecl)itr.next()).getAttributeWildcard(); 150 151 if(w==null) continue; 152 153 if(complete==null) 154 complete = w; 155 else 156 // TODO: the spec says it's intersection, 157 // but I think it has to be union. 158 complete = complete.union(ownerDocument,w); 159 } 160 161 if( getDerivationMethod()==RESTRICTION ) return complete; 162 163 WildcardImpl base=null; 164 XSType baseType = getBaseType(); 165 if(baseType.asComplexType()!=null) 166 base = (WildcardImpl)baseType.asComplexType().getAttributeWildcard(); 167 168 if(complete==null) return base; 169 if(base==null) return complete; 170 171 return complete.union(ownerDocument,base); 172 } 173 174 private final int finalValue; isFinal( int derivationMethod )175 public boolean isFinal( int derivationMethod ) { 176 return (finalValue&derivationMethod)!=0; 177 } 178 179 private final int blockValue; isSubstitutionProhibited( int method )180 public boolean isSubstitutionProhibited( int method ) { 181 return (blockValue&method)!=0; 182 } 183 184 185 private Ref.ContentType contentType; setContentType( Ref.ContentType v )186 public void setContentType( Ref.ContentType v ) { contentType = v; } getContentType()187 public XSContentType getContentType() { return contentType.getContentType(); } 188 189 private XSContentType explicitContent; setExplicitContent( XSContentType v )190 public void setExplicitContent( XSContentType v ) { 191 this.explicitContent = v; 192 } getExplicitContent()193 public XSContentType getExplicitContent() { return explicitContent; } 194 195 private final boolean mixed; isMixed()196 public boolean isMixed() { return mixed; } 197 198 199 200 getAttributeUse( String nsURI, String localName )201 public XSAttributeUse getAttributeUse( String nsURI, String localName ) { 202 UName name = new UName(nsURI,localName); 203 204 if(prohibitedAtts.contains(name)) return null; 205 206 XSAttributeUse o = attributes.get(name); 207 208 209 if(o==null) { 210 Iterator itr = iterateAttGroups(); 211 while(itr.hasNext() && o==null) 212 o = ((XSAttGroupDecl)itr.next()).getAttributeUse(nsURI,localName); 213 } 214 215 if(o==null) { 216 XSType base = getBaseType(); 217 if(base.asComplexType()!=null) 218 o = base.asComplexType().getAttributeUse(nsURI,localName); 219 } 220 221 return o; 222 } 223 iterateAttributeUses()224 public Iterator<XSAttributeUse> iterateAttributeUses() { 225 226 XSComplexType baseType = getBaseType().asComplexType(); 227 228 if( baseType==null ) return super.iterateAttributeUses(); 229 230 return new Iterators.Union<XSAttributeUse>( 231 new Iterators.Filter<XSAttributeUse>(baseType.iterateAttributeUses()) { 232 protected boolean matches(XSAttributeUse value) { 233 XSAttributeDecl u = value.getDecl(); 234 UName n = new UName(u.getTargetNamespace(),u.getName()); 235 return !prohibitedAtts.contains(n); 236 } 237 }, 238 super.iterateAttributeUses() ); 239 } 240 241 public Collection<XSAttributeUse> getAttributeUses() { 242 XSComplexType baseType = getBaseType().asComplexType(); 243 244 if( baseType==null ) return super.getAttributeUses(); 245 246 // TODO: this is fairly inefficient 247 Map<UName,XSAttributeUse> uses = new HashMap<UName, XSAttributeUse>(); 248 for( XSAttributeUse a : baseType.getAttributeUses()) 249 uses.put(new UName(a.getDecl()),a); 250 251 uses.keySet().removeAll(prohibitedAtts); 252 253 for( XSAttributeUse a : super.getAttributeUses()) 254 uses.put(new UName(a.getDecl()),a); 255 256 return uses.values(); 257 } 258 259 260 public XSType[] listSubstitutables() { 261 return Util.listSubstitutables(this); 262 } 263 264 public void visit( XSVisitor visitor ) { 265 visitor.complexType(this); 266 } 267 public <T> T apply( XSFunction<T> function ) { 268 return function.complexType(this); 269 } 270 271 // Ref.ComplexType implementation 272 public XSComplexType getType() { return this; } 273 274 public List<XSComplexType> getSubtypes() { 275 ArrayList subtypeList = new ArrayList(); 276 Iterator<XSComplexType> cTypes = getRoot().iterateComplexTypes(); 277 while (cTypes.hasNext()) { 278 XSComplexType cType= cTypes.next(); 279 XSType base = cType.getBaseType(); 280 if ((base != null) && (base.equals(this))) { 281 subtypeList.add(cType); 282 } 283 } 284 return subtypeList; 285 } 286 287 public List<XSElementDecl> getElementDecls() { 288 ArrayList declList = new ArrayList(); 289 XSSchemaSet schemaSet = getRoot(); 290 for (XSSchema sch : schemaSet.getSchemas()) { 291 for (XSElementDecl decl : sch.getElementDecls().values()) { 292 if (decl.getType().equals(this)) { 293 declList.add(decl); 294 } 295 } 296 } 297 return declList; 298 } 299 } 300