1/* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5/* 6 * Licensed to the Apache Software Foundation (ASF) under one or more 7 * contributor license agreements. See the NOTICE file distributed with 8 * this work for additional information regarding copyright ownership. 9 * The ASF licenses this file to You under the Apache License, Version 2.0 10 * (the "License"); you may not use this file except in compliance with 11 * the License. You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 */ 21 22package com.sun.org.apache.xerces.internal.impl.xs; 23 24import com.sun.org.apache.xerces.internal.impl.dv.ValidatedInfo; 25import com.sun.org.apache.xerces.internal.impl.xs.util.XSObjectListImpl; 26import com.sun.org.apache.xerces.internal.xs.XSAnnotation; 27import com.sun.org.apache.xerces.internal.xs.XSAttributeGroupDefinition; 28import com.sun.org.apache.xerces.internal.xs.XSAttributeUse; 29import com.sun.org.apache.xerces.internal.xs.XSConstants; 30import com.sun.org.apache.xerces.internal.xs.XSNamespaceItem; 31import com.sun.org.apache.xerces.internal.xs.XSObjectList; 32import com.sun.org.apache.xerces.internal.xs.XSWildcard; 33 34/** 35 * The XML representation for an attribute group declaration 36 * schema component is a global <attributeGroup> element information item 37 * 38 * @xerces.internal 39 * 40 * @author Sandy Gao, IBM 41 * @author Rahul Srivastava, Sun Microsystems Inc. 42 * 43 */ 44public class XSAttributeGroupDecl implements XSAttributeGroupDefinition { 45 46 // name of the attribute group 47 public String fName = null; 48 // target namespace of the attribute group 49 public String fTargetNamespace = null; 50 // number of attribute uses included by this attribute group 51 int fAttrUseNum = 0; 52 // attribute uses included by this attribute group 53 private static final int INITIAL_SIZE = 5; 54 XSAttributeUseImpl[] fAttributeUses = new XSAttributeUseImpl[INITIAL_SIZE]; 55 // attribute wildcard included by this attribute group 56 public XSWildcardDecl fAttributeWC = null; 57 // whether there is an attribute use whose type is or is derived from ID. 58 public String fIDAttrName = null; 59 60 // optional annotation 61 public XSObjectList fAnnotations; 62 63 protected XSObjectListImpl fAttrUses = null; 64 65 // The namespace schema information item corresponding to the target namespace 66 // of the attribute group definition, if it is globally declared; or null otherwise. 67 private XSNamespaceItem fNamespaceItem = null; 68 69 // add an attribute use 70 // if the type is derived from ID, but there is already another attribute 71 // use of type ID, then return the name of the other attribute use; 72 // otherwise, return null 73 public String addAttributeUse(XSAttributeUseImpl attrUse) { 74 75 // if this attribute use is prohibited, then don't check whether it's 76 // of type ID 77 if (attrUse.fUse != SchemaSymbols.USE_PROHIBITED) { 78 if (attrUse.fAttrDecl.fType.isIDType()) { 79 // if there is already an attribute use of type ID, 80 // return its name (and don't add it to the list, to avoid 81 // interruption to instance validation. 82 if (fIDAttrName == null) 83 fIDAttrName = attrUse.fAttrDecl.fName; 84 else 85 return fIDAttrName; 86 } 87 } 88 89 if (fAttrUseNum == fAttributeUses.length) { 90 fAttributeUses = resize(fAttributeUses, fAttrUseNum*2); 91 } 92 fAttributeUses[fAttrUseNum++] = attrUse; 93 94 return null; 95 } 96 97 public void replaceAttributeUse(XSAttributeUse oldUse, XSAttributeUseImpl newUse) { 98 for (int i=0; i<fAttrUseNum; i++) { 99 if (fAttributeUses[i] == oldUse) { 100 fAttributeUses[i] = newUse; 101 } 102 } 103 } 104 105 public XSAttributeUse getAttributeUse(String namespace, String name) { 106 for (int i=0; i<fAttrUseNum; i++) { 107 if ( (fAttributeUses[i].fAttrDecl.fTargetNamespace == namespace) && 108 (fAttributeUses[i].fAttrDecl.fName == name) ) 109 return fAttributeUses[i]; 110 } 111 112 return null; 113 } 114 115 public XSAttributeUse getAttributeUseNoProhibited(String namespace, String name) { 116 for (int i=0; i<fAttrUseNum; i++) { 117 if ( (fAttributeUses[i].fAttrDecl.fTargetNamespace == namespace) && 118 (fAttributeUses[i].fAttrDecl.fName == name) && 119 (fAttributeUses[i].fUse != SchemaSymbols.USE_PROHIBITED)) 120 return fAttributeUses[i]; 121 } 122 123 return null; 124 } 125 126 public void removeProhibitedAttrs() { 127 if (fAttrUseNum == 0) return; 128 // Remove all prohibited attributes. 129 int count = 0; 130 XSAttributeUseImpl[] uses = new XSAttributeUseImpl[fAttrUseNum]; 131 for (int i = 0; i < fAttrUseNum; i++) { 132 if (fAttributeUses[i].fUse != SchemaSymbols.USE_PROHIBITED) { 133 uses[count++] = fAttributeUses[i]; 134 } 135 } 136 fAttributeUses = uses; 137 fAttrUseNum = count; 138 139 // Do not remove attributes that have the same name as the prohibited 140 // ones, because they are specified at the same level. Prohibited 141 // attributes are only to remove attributes from the base type in a 142 // restriction. 143// int newCount = 0; 144// if (pCount > 0) { 145// OUTER: for (int i = 0; i < fAttrUseNum; i++) { 146// if (fAttributeUses[i].fUse == SchemaSymbols.USE_PROHIBITED) 147// continue; 148// for (int j = 1; j <= pCount; j++) { 149// if (fAttributeUses[i].fAttrDecl.fName == pUses[fAttrUseNum-pCount].fAttrDecl.fName && 150// fAttributeUses[i].fAttrDecl.fTargetNamespace == pUses[fAttrUseNum-pCount].fAttrDecl.fTargetNamespace) { 151// continue OUTER; 152// } 153// } 154// pUses[newCount++] = fAttributeUses[i]; 155// } 156// fAttributeUses = pUses; 157// fAttrUseNum = newCount; 158// } 159 } 160 161 /** 162 * Check that the attributes in this group validly restrict those from a base group. 163 * If an error is found, an Object[] is returned. This contains the arguments for the error message 164 * describing the error. The last element in the array (at index arr.length - 1) is the the error code. 165 * Returns null if there is no error. 166 * 167 * REVISIT: is there a better way of returning the appropriate information for the error? 168 * 169 * @param typeName the name of the type containing this attribute group, used for error reporting purposes 170 * @param baseGroup the XSAttributeGroupDecl that is the base we are checking against 171 */ 172 public Object[] validRestrictionOf(String typeName, XSAttributeGroupDecl baseGroup) { 173 174 Object[] errorArgs = null; 175 XSAttributeUseImpl attrUse = null; 176 XSAttributeDecl attrDecl = null; 177 XSAttributeUseImpl baseAttrUse = null; 178 XSAttributeDecl baseAttrDecl = null; 179 180 for (int i=0; i<fAttrUseNum; i++) { 181 182 attrUse = fAttributeUses[i]; 183 attrDecl = attrUse.fAttrDecl; 184 185 // Look for a match in the base 186 baseAttrUse = (XSAttributeUseImpl)baseGroup.getAttributeUse(attrDecl.fTargetNamespace,attrDecl.fName); 187 if (baseAttrUse != null) { 188 // 189 // derivation-ok-restriction. Constraint 2.1.1 190 // 191 192 if (baseAttrUse.getRequired() && !attrUse.getRequired()) { 193 errorArgs = new Object[]{typeName, attrDecl.fName, 194 attrUse.fUse == SchemaSymbols.USE_OPTIONAL ? SchemaSymbols.ATTVAL_OPTIONAL : SchemaSymbols.ATTVAL_PROHIBITED, 195 "derivation-ok-restriction.2.1.1"}; 196 return errorArgs; 197 } 198 199 // if this attribute is prohibited in the derived type, don't 200 // need to check any of the following constraints. 201 if (attrUse.fUse == SchemaSymbols.USE_PROHIBITED) { 202 continue; 203 } 204 205 baseAttrDecl = baseAttrUse.fAttrDecl; 206 // 207 // derivation-ok-restriction. Constraint 2.1.1 208 // 209 if (! XSConstraints.checkSimpleDerivationOk(attrDecl.fType, 210 baseAttrDecl.fType, 211 baseAttrDecl.fType.getFinal()) ) { 212 errorArgs = new Object[]{typeName, attrDecl.fName, attrDecl.fType.getName(), 213 baseAttrDecl.fType.getName(), "derivation-ok-restriction.2.1.2"}; 214 return errorArgs; 215 } 216 217 218 // 219 // derivation-ok-restriction. Constraint 2.1.3 220 // 221 int baseConsType=baseAttrUse.fConstraintType!=XSConstants.VC_NONE? 222 baseAttrUse.fConstraintType:baseAttrDecl.getConstraintType(); 223 int thisConstType = attrUse.fConstraintType!=XSConstants.VC_NONE? 224 attrUse.fConstraintType:attrDecl.getConstraintType(); 225 226 if (baseConsType == XSConstants.VC_FIXED) { 227 228 if (thisConstType != XSConstants.VC_FIXED) { 229 errorArgs = new Object[]{typeName, attrDecl.fName, 230 "derivation-ok-restriction.2.1.3.a"}; 231 return errorArgs; 232 } else { 233 // check the values are the same. 234 ValidatedInfo baseFixedValue=(baseAttrUse.fDefault!=null ? 235 baseAttrUse.fDefault: baseAttrDecl.fDefault); 236 ValidatedInfo thisFixedValue=(attrUse.fDefault!=null ? 237 attrUse.fDefault: attrDecl.fDefault); 238 if (!baseFixedValue.actualValue.equals(thisFixedValue.actualValue)) { 239 errorArgs = new Object[]{typeName, attrDecl.fName, thisFixedValue.stringValue(), 240 baseFixedValue.stringValue(), "derivation-ok-restriction.2.1.3.b"}; 241 return errorArgs; 242 } 243 244 } 245 246 } 247 } else { 248 // No matching attribute in base - there should be a matching wildcard 249 250 // 251 // derivation-ok-restriction. Constraint 2.2 252 // 253 if (baseGroup.fAttributeWC == null) { 254 errorArgs = new Object[]{typeName, attrDecl.fName, 255 "derivation-ok-restriction.2.2.a"}; 256 return errorArgs; 257 } 258 else if (!baseGroup.fAttributeWC.allowNamespace(attrDecl.fTargetNamespace)) { 259 errorArgs = new Object[]{typeName, attrDecl.fName, 260 attrDecl.fTargetNamespace==null?"":attrDecl.fTargetNamespace, 261 "derivation-ok-restriction.2.2.b"}; 262 return errorArgs; 263 } 264 } 265 } 266 267 // 268 // Check that any REQUIRED attributes in the base have matching attributes 269 // in this group 270 // derivation-ok-restriction. Constraint 3 271 // 272 for (int i=0; i<baseGroup.fAttrUseNum; i++) { 273 274 baseAttrUse = baseGroup.fAttributeUses[i]; 275 276 if (baseAttrUse.fUse == SchemaSymbols.USE_REQUIRED) { 277 278 baseAttrDecl = baseAttrUse.fAttrDecl; 279 // Look for a match in this group 280 if (getAttributeUse(baseAttrDecl.fTargetNamespace,baseAttrDecl.fName) == null) { 281 errorArgs = new Object[]{typeName, baseAttrUse.fAttrDecl.fName, 282 "derivation-ok-restriction.3"}; 283 return errorArgs; 284 } 285 } 286 } 287 288 289 // Now, check wildcards 290 // 291 // derivation-ok-restriction. Constraint 4 292 // 293 if (fAttributeWC != null) { 294 if (baseGroup.fAttributeWC == null) { 295 errorArgs = new Object[]{typeName, "derivation-ok-restriction.4.1"}; 296 return errorArgs; 297 } 298 if (! fAttributeWC.isSubsetOf(baseGroup.fAttributeWC)) { 299 errorArgs = new Object[]{typeName, "derivation-ok-restriction.4.2"}; 300 return errorArgs; 301 } 302 if (fAttributeWC.weakerProcessContents(baseGroup.fAttributeWC)) { 303 errorArgs = new Object[]{typeName, 304 fAttributeWC.getProcessContentsAsString(), 305 baseGroup.fAttributeWC.getProcessContentsAsString(), 306 "derivation-ok-restriction.4.3"}; 307 return errorArgs; 308 } 309 } 310 311 return null; 312 313 } 314 315 static final XSAttributeUseImpl[] resize(XSAttributeUseImpl[] oldArray, int newSize) { 316 XSAttributeUseImpl[] newArray = new XSAttributeUseImpl[newSize]; 317 System.arraycopy(oldArray, 0, newArray, 0, Math.min(oldArray.length, newSize)); 318 return newArray; 319 } 320 321 // reset the attribute group declaration 322 public void reset(){ 323 fName = null; 324 fTargetNamespace = null; 325 // reset attribute uses 326 for (int i=0;i<fAttrUseNum;i++) { 327 fAttributeUses[i] = null; 328 } 329 fAttrUseNum = 0; 330 fAttributeWC = null; 331 fAnnotations = null; 332 fIDAttrName = null; 333 334 } 335 336 /** 337 * Get the type of the object, i.e ELEMENT_DECLARATION. 338 */ 339 public short getType() { 340 return XSConstants.ATTRIBUTE_GROUP; 341 } 342 343 /** 344 * The <code>name</code> of this <code>XSObject</code> depending on the 345 * <code>XSObject</code> type. 346 */ 347 public String getName() { 348 return fName; 349 } 350 351 /** 352 * The namespace URI of this node, or <code>null</code> if it is 353 * unspecified. defines how a namespace URI is attached to schema 354 * components. 355 */ 356 public String getNamespace() { 357 return fTargetNamespace; 358 } 359 360 /** 361 * {attribute uses} A set of attribute uses. 362 */ 363 public XSObjectList getAttributeUses() { 364 if (fAttrUses == null){ 365 fAttrUses = new XSObjectListImpl(fAttributeUses, fAttrUseNum); 366 } 367 return fAttrUses; 368 } 369 370 /** 371 * {attribute wildcard} Optional. A wildcard. 372 */ 373 public XSWildcard getAttributeWildcard() { 374 return fAttributeWC; 375 } 376 377 /** 378 * Optional. Annotation. 379 */ 380 public XSAnnotation getAnnotation() { 381 return (fAnnotations != null) ? (XSAnnotation) fAnnotations.item(0) : null; 382 } 383 384 /** 385 * Optional. Annotations. 386 */ 387 public XSObjectList getAnnotations() { 388 return (fAnnotations != null) ? fAnnotations : XSObjectListImpl.EMPTY_LIST; 389 } 390 391 /** 392 * @see org.apache.xerces.xs.XSObject#getNamespaceItem() 393 */ 394 public XSNamespaceItem getNamespaceItem() { 395 return fNamespaceItem; 396 } 397 398 void setNamespaceItem(XSNamespaceItem namespaceItem) { 399 fNamespaceItem = namespaceItem; 400 } 401 402} // class XSAttributeGroupDecl 403