1 57 58 package com.sun.org.apache.xerces.internal.impl.xs; 59 60 import com.sun.org.apache.xerces.internal.xs.XSConstants; 61 import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition; 62 import com.sun.org.apache.xerces.internal.xni.QName; 63 import java.util.Hashtable ; 64 import java.util.Vector ; 65 66 73 public class SubstitutionGroupHandler { 74 75 XSGrammarBucket fGrammarBucket; 77 78 81 public SubstitutionGroupHandler(XSGrammarBucket grammarBucket) { 82 fGrammarBucket = grammarBucket; 83 } 84 85 public XSElementDecl getMatchingElemDecl(QName element, XSElementDecl exemplar) { 88 if (element.localpart == exemplar.fName && 89 element.uri == exemplar.fTargetNamespace) { 90 return exemplar; 91 } 92 93 if (exemplar.fScope != XSConstants.SCOPE_GLOBAL) 96 return null; 97 98 if ((exemplar.fBlock & XSConstants.DERIVATION_SUBSTITUTION) != 0) 100 return null; 101 102 SchemaGrammar sGrammar = fGrammarBucket.getGrammar(element.uri); 104 if (sGrammar == null) 105 return null; 106 107 XSElementDecl eDecl = sGrammar.getGlobalElementDecl(element.localpart); 109 if (eDecl == null) 110 return null; 111 112 if (substitutionGroupOK(eDecl, exemplar, exemplar.fBlock)) 114 return eDecl; 115 116 return null; 117 } 118 119 protected boolean substitutionGroupOK(XSElementDecl element, XSElementDecl exemplar, short blockingConstraint) { 122 if (element == exemplar) 125 return true; 126 127 if ((blockingConstraint & XSConstants.DERIVATION_SUBSTITUTION) != 0) 130 return false; 131 132 XSElementDecl subGroup = element.fSubGroup; 134 while (subGroup != null && subGroup != exemplar) { 135 subGroup = subGroup.fSubGroup; 136 } 137 138 if (subGroup == null) 139 return false; 140 141 short devMethod = 0, blockConstraint = blockingConstraint; 145 146 XSTypeDefinition type = element.fType; 150 while (type != exemplar.fType && type != SchemaGrammar.fAnyType) { 151 if (type.getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE) 152 devMethod |= ((XSComplexTypeDecl)type).fDerivedBy; 153 else 154 devMethod |= XSConstants.DERIVATION_RESTRICTION; 155 type = type.getBaseType(); 156 if (type == null) 159 type = SchemaGrammar.fAnyType; 160 if (type.getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE) 161 blockConstraint |= ((XSComplexTypeDecl)type).fBlock; 162 } 163 if (type != exemplar.fType) 164 return false; 165 166 if ((devMethod & blockConstraint) != 0) 167 return false; 168 169 return true; 170 } 171 172 public boolean inSubstitutionGroup(XSElementDecl element, XSElementDecl exemplar) { 174 return substitutionGroupOK(element, exemplar, exemplar.fBlock); 182 } 183 184 Hashtable fSubGroupsB = new Hashtable (); 190 private static final OneSubGroup[] EMPTY_VECTOR = new OneSubGroup[0]; 191 Hashtable fSubGroups = new Hashtable (); 193 194 197 public void reset() { 198 fSubGroupsB.clear(); 199 fSubGroups.clear(); 200 } 201 202 205 public void addSubstitutionGroup(XSElementDecl[] elements) { 206 XSElementDecl subHead, element; 207 Vector subGroup; 208 for (int i = elements.length-1; i >= 0; i--) { 210 element = elements[i]; 211 subHead = element.fSubGroup; 212 subGroup = (Vector )fSubGroupsB.get(subHead); 214 if (subGroup == null) { 215 subGroup = new Vector (); 217 fSubGroupsB.put(subHead, subGroup); 218 } 219 subGroup.addElement(element); 221 } 222 } 223 224 232 public XSElementDecl[] getSubstitutionGroup(XSElementDecl element) { 233 Object subGroup = fSubGroups.get(element); 235 if (subGroup != null) 236 return (XSElementDecl[])subGroup; 237 238 OneSubGroup[] groupB = getSubGroupB(element, new OneSubGroup()); 241 int len = groupB.length, rlen = 0; 242 XSElementDecl[] ret = new XSElementDecl[len]; 243 for (int i = 0 ; i < len; i++) { 246 if ((element.fBlock & groupB[i].dMethod) == 0) 247 ret[rlen++] = groupB[i].sub; 248 } 249 if (rlen < len) { 251 XSElementDecl[] ret1 = new XSElementDecl[rlen]; 252 System.arraycopy(ret, 0, ret1, 0, rlen); 253 ret = ret1; 254 } 255 fSubGroups.put(element, ret); 257 258 return ret; 259 } 260 261 private OneSubGroup[] getSubGroupB(XSElementDecl element, OneSubGroup methods) { 263 Object subGroup = fSubGroupsB.get(element); 264 265 if (subGroup == null) { 267 fSubGroupsB.put(element, EMPTY_VECTOR); 268 return EMPTY_VECTOR; 269 } 270 271 if (subGroup instanceof OneSubGroup[]) 273 return (OneSubGroup[])subGroup; 274 275 Vector group = (Vector )subGroup, newGroup = new Vector (); 277 OneSubGroup[] group1; 278 short dMethod, bMethod, dSubMethod, bSubMethod; 281 for (int i = group.size()-1, j; i >= 0; i--) { 282 XSElementDecl sub = (XSElementDecl)group.elementAt(i); 284 if (!getDBMethods(sub.fType, element.fType, methods)) 285 continue; 286 dMethod = methods.dMethod; 288 bMethod = methods.bMethod; 289 newGroup.addElement(new OneSubGroup(sub, methods.dMethod, methods.bMethod)); 291 group1 = getSubGroupB(sub, methods); 293 for (j = group1.length-1; j >= 0; j--) { 294 dSubMethod = (short)(dMethod | group1[j].dMethod); 296 bSubMethod = (short)(bMethod | group1[j].bMethod); 297 if ((dSubMethod & bSubMethod) != 0) 299 continue; 300 newGroup.addElement(new OneSubGroup(group1[j].sub, dSubMethod, bSubMethod)); 301 } 302 } 303 OneSubGroup[] ret = new OneSubGroup[newGroup.size()]; 305 for (int i = newGroup.size()-1; i >= 0; i--) { 306 ret[i] = (OneSubGroup)newGroup.elementAt(i); 307 } 308 fSubGroupsB.put(element, ret); 310 311 return ret; 312 } 313 314 private boolean getDBMethods(XSTypeDefinition typed, XSTypeDefinition typeb, 315 OneSubGroup methods) { 316 short dMethod = 0, bMethod = 0; 317 while (typed != typeb && typed != SchemaGrammar.fAnyType) { 318 if (typed.getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE) 319 dMethod |= ((XSComplexTypeDecl)typed).fDerivedBy; 320 else 321 dMethod |= XSConstants.DERIVATION_RESTRICTION; 322 typed = typed.getBaseType(); 323 if (typed == null) 326 typed = SchemaGrammar.fAnyType; 327 if (typed.getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE) 328 bMethod |= ((XSComplexTypeDecl)typed).fBlock; 329 } 330 if (typed != typeb || (dMethod & bMethod) != 0) 332 return false; 333 334 methods.dMethod = dMethod; 336 methods.bMethod = bMethod; 337 return true; 338 } 339 340 private static final class OneSubGroup { 342 OneSubGroup() {} 343 OneSubGroup(XSElementDecl sub, short dMethod, short bMethod) { 344 this.sub = sub; 345 this.dMethod = dMethod; 346 this.bMethod = bMethod; 347 } 348 XSElementDecl sub; 350 short dMethod; 353 short bMethod; 356 } 357 } | Popular Tags |