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