1. /*
  2. * The Apache Software License, Version 1.1
  3. *
  4. *
  5. * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
  6. * reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. The end-user documentation included with the redistribution,
  21. * if any, must include the following acknowledgment:
  22. * "This product includes software developed by the
  23. * Apache Software Foundation (http://www.apache.org/)."
  24. * Alternately, this acknowledgment may appear in the software itself,
  25. * if and wherever such third-party acknowledgments normally appear.
  26. *
  27. * 4. The names "Xerces" and "Apache Software Foundation" must
  28. * not be used to endorse or promote products derived from this
  29. * software without prior written permission. For written
  30. * permission, please contact apache@apache.org.
  31. *
  32. * 5. Products derived from this software may not be called "Apache",
  33. * nor may "Apache" appear in their name, without prior written
  34. * permission of the Apache Software Foundation.
  35. *
  36. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  37. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  38. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  40. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  41. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  42. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  43. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  44. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  45. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  46. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  47. * SUCH DAMAGE.
  48. * ====================================================================
  49. *
  50. * This software consists of voluntary contributions made by many
  51. * individuals on behalf of the Apache Software Foundation and was
  52. * originally based on software copyright (c) 2001, International
  53. * Business Machines, Inc., http://www.apache.org. For more
  54. * information on the Apache Software Foundation, please see
  55. * <http://www.apache.org/>.
  56. */
  57. package com.sun.org.apache.xerces.internal.impl.xs;
  58. import com.sun.org.apache.xerces.internal.impl.dv.ValidatedInfo;
  59. import com.sun.org.apache.xerces.internal.xs.XSAnnotation;
  60. import com.sun.org.apache.xerces.internal.xs.XSAttributeGroupDefinition;
  61. import com.sun.org.apache.xerces.internal.xs.XSAttributeUse;
  62. import com.sun.org.apache.xerces.internal.xs.XSConstants;
  63. import com.sun.org.apache.xerces.internal.xs.XSNamespaceItem;
  64. import com.sun.org.apache.xerces.internal.xs.XSObjectList;
  65. import com.sun.org.apache.xerces.internal.xs.XSWildcard;
  66. import com.sun.org.apache.xerces.internal.impl.xs.util.XSObjectListImpl;
  67. /**
  68. * The XML representation for an attribute group declaration
  69. * schema component is a global <attributeGroup> element information item
  70. *
  71. * @author Sandy Gao, IBM
  72. * @author Rahul Srivastava, Sun Microsystems Inc.
  73. *
  74. * @version $Id: XSAttributeGroupDecl.java,v 1.16 2003/11/11 20:14:58 sandygao Exp $
  75. */
  76. public class XSAttributeGroupDecl implements XSAttributeGroupDefinition {
  77. // name of the attribute group
  78. public String fName = null;
  79. // target namespace of the attribute group
  80. public String fTargetNamespace = null;
  81. // number of attribute uses included by this attribute group
  82. int fAttrUseNum = 0;
  83. // attribute uses included by this attribute group
  84. private static final int INITIAL_SIZE = 5;
  85. XSAttributeUseImpl[] fAttributeUses = new XSAttributeUseImpl[INITIAL_SIZE];
  86. // attribute wildcard included by this attribute group
  87. public XSWildcardDecl fAttributeWC = null;
  88. // whether there is an attribute use whose type is or is derived from ID.
  89. public String fIDAttrName = null;
  90. // optional annotation
  91. public XSAnnotationImpl fAnnotation;
  92. protected XSObjectListImpl fAttrUses = null;
  93. // add an attribute use
  94. // if the type is derived from ID, but there is already another attribute
  95. // use of type ID, then return the name of the other attribute use;
  96. // otherwise, return null
  97. public String addAttributeUse(XSAttributeUseImpl attrUse) {
  98. if (fAttrUseNum == fAttributeUses.length) {
  99. fAttributeUses = resize(fAttributeUses, fAttrUseNum*2);
  100. }
  101. fAttributeUses[fAttrUseNum++] = attrUse;
  102. // if this attribute use is prohibited, then don't check whether it's
  103. // of type ID
  104. if (attrUse.fUse == SchemaSymbols.USE_PROHIBITED)
  105. return null;
  106. if (attrUse.fAttrDecl.fType.isIDType()) {
  107. // if there is already an attribute use of type ID, return it' sname
  108. if (fIDAttrName == null)
  109. fIDAttrName = attrUse.fAttrDecl.fName;
  110. else
  111. return fIDAttrName;
  112. }
  113. return null;
  114. }
  115. public XSAttributeUse getAttributeUse(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. return fAttributeUses[i];
  120. }
  121. return null;
  122. }
  123. public void removeProhibitedAttrs() {
  124. if (fAttrUseNum == 0) return;
  125. int pCount = 0;
  126. XSAttributeUseImpl[] pUses = new XSAttributeUseImpl[fAttrUseNum];
  127. for (int i = 0; i < fAttrUseNum; i++) {
  128. if (fAttributeUses[i].fUse == SchemaSymbols.USE_PROHIBITED) {
  129. pCount++;
  130. // we use the entries at the end, so that we can use the
  131. // first entries to store non-prohibited attribute uses,
  132. // hence avoid creating a new array.
  133. pUses[fAttrUseNum-pCount] = fAttributeUses[i];
  134. }
  135. }
  136. int newCount = 0;
  137. if (pCount > 0) {
  138. OUTER: for (int i = 0; i < fAttrUseNum; i++) {
  139. if (fAttributeUses[i].fUse == SchemaSymbols.USE_PROHIBITED)
  140. continue;
  141. for (int j = 1; j <= pCount; j++) {
  142. if (fAttributeUses[i].fAttrDecl.fName == pUses[fAttrUseNum-pCount].fAttrDecl.fName &&
  143. fAttributeUses[i].fAttrDecl.fTargetNamespace == pUses[fAttrUseNum-pCount].fAttrDecl.fTargetNamespace) {
  144. continue OUTER;
  145. }
  146. }
  147. pUses[newCount++] = fAttributeUses[i];
  148. }
  149. fAttributeUses = pUses;
  150. fAttrUseNum = newCount;
  151. }
  152. }
  153. /**
  154. * Check that the attributes in this group validly restrict those from a base group.
  155. * If an error is found, an Object[] is returned. This contains the arguments for the error message
  156. * describing the error. The last element in the array (at index arr.length - 1) is the the error code.
  157. * Returns null if there is no error.
  158. *
  159. * REVISIT: is there a better way of returning the appropriate information for the error?
  160. *
  161. * @param typeName the name of the type containing this attribute group, used for error reporting purposes
  162. * @param baseGroup the XSAttributeGroupDecl that is the base we are checking against
  163. */
  164. public Object[] validRestrictionOf(String typeName, XSAttributeGroupDecl baseGroup) {
  165. Object[] errorArgs = null;
  166. XSAttributeUseImpl attrUse = null;
  167. XSAttributeDecl attrDecl = null;
  168. XSAttributeUseImpl baseAttrUse = null;
  169. XSAttributeDecl baseAttrDecl = null;
  170. for (int i=0; i<fAttrUseNum; i++) {
  171. attrUse = fAttributeUses[i];
  172. attrDecl = attrUse.fAttrDecl;
  173. // Look for a match in the base
  174. baseAttrUse = (XSAttributeUseImpl)baseGroup.getAttributeUse(attrDecl.fTargetNamespace,attrDecl.fName);
  175. if (baseAttrUse != null) {
  176. //
  177. // derivation-ok-restriction. Constraint 2.1.1
  178. //
  179. if (baseAttrUse.getRequired() && !attrUse.getRequired()) {
  180. errorArgs = new Object[]{typeName, attrDecl.fName,
  181. attrUse.fUse == SchemaSymbols.USE_OPTIONAL ? SchemaSymbols.ATTVAL_OPTIONAL : SchemaSymbols.ATTVAL_PROHIBITED,
  182. "derivation-ok-restriction.2.1.1"};
  183. return errorArgs;
  184. }
  185. // if this attribute is prohibited in the derived type, don't
  186. // need to check any of the following constraints.
  187. if (attrUse.fUse == SchemaSymbols.USE_PROHIBITED) {
  188. continue;
  189. }
  190. baseAttrDecl = baseAttrUse.fAttrDecl;
  191. //
  192. // derivation-ok-restriction. Constraint 2.1.1
  193. //
  194. if (! XSConstraints.checkSimpleDerivationOk(attrDecl.fType,
  195. baseAttrDecl.fType,
  196. baseAttrDecl.fType.getFinal()) ) {
  197. errorArgs = new Object[]{typeName, attrDecl.fName, attrDecl.fType.getName(),
  198. baseAttrDecl.fType.getName(), "derivation-ok-restriction.2.1.2"};
  199. return errorArgs;
  200. }
  201. //
  202. // derivation-ok-restriction. Constraint 2.1.3
  203. //
  204. int baseConsType=baseAttrUse.fConstraintType!=XSConstants.VC_NONE?
  205. baseAttrUse.fConstraintType:baseAttrDecl.getConstraintType();
  206. int thisConstType = attrUse.fConstraintType!=XSConstants.VC_NONE?
  207. attrUse.fConstraintType:attrDecl.getConstraintType();
  208. if (baseConsType == XSConstants.VC_FIXED) {
  209. if (thisConstType != XSConstants.VC_FIXED) {
  210. errorArgs = new Object[]{typeName, attrDecl.fName,
  211. "derivation-ok-restriction.2.1.3.a"};
  212. return errorArgs;
  213. } else {
  214. // check the values are the same.
  215. ValidatedInfo baseFixedValue=(baseAttrUse.fDefault!=null ?
  216. baseAttrUse.fDefault: baseAttrDecl.fDefault);
  217. ValidatedInfo thisFixedValue=(attrUse.fDefault!=null ?
  218. attrUse.fDefault: attrDecl.fDefault);
  219. if (!baseFixedValue.actualValue.equals(thisFixedValue.actualValue)) {
  220. errorArgs = new Object[]{typeName, attrDecl.fName, thisFixedValue.stringValue(),
  221. baseFixedValue.stringValue(), "derivation-ok-restriction.2.1.3.b"};
  222. return errorArgs;
  223. }
  224. }
  225. }
  226. } else {
  227. // No matching attribute in base - there should be a matching wildcard
  228. //
  229. // derivation-ok-restriction. Constraint 2.2
  230. //
  231. if (baseGroup.fAttributeWC == null) {
  232. errorArgs = new Object[]{typeName, attrDecl.fName,
  233. "derivation-ok-restriction.2.2.a"};
  234. return errorArgs;
  235. }
  236. else if (!baseGroup.fAttributeWC.allowNamespace(attrDecl.fTargetNamespace)) {
  237. errorArgs = new Object[]{typeName, attrDecl.fName,
  238. attrDecl.fTargetNamespace==null?"":attrDecl.fTargetNamespace,
  239. "derivation-ok-restriction.2.2.b"};
  240. return errorArgs;
  241. }
  242. }
  243. }
  244. //
  245. // Check that any REQUIRED attributes in the base have matching attributes
  246. // in this group
  247. // derivation-ok-restriction. Constraint 3
  248. //
  249. for (int i=0; i<baseGroup.fAttrUseNum; i++) {
  250. baseAttrUse = baseGroup.fAttributeUses[i];
  251. if (baseAttrUse.fUse == SchemaSymbols.USE_REQUIRED) {
  252. baseAttrDecl = baseAttrUse.fAttrDecl;
  253. // Look for a match in this group
  254. if (getAttributeUse(baseAttrDecl.fTargetNamespace,baseAttrDecl.fName) == null) {
  255. errorArgs = new Object[]{typeName, baseAttrUse.fAttrDecl.fName,
  256. "derivation-ok-restriction.3"};
  257. return errorArgs;
  258. }
  259. }
  260. }
  261. // Now, check wildcards
  262. //
  263. // derivation-ok-restriction. Constraint 4
  264. //
  265. if (fAttributeWC != null) {
  266. if (baseGroup.fAttributeWC == null) {
  267. errorArgs = new Object[]{typeName, "derivation-ok-restriction.4.1"};
  268. return errorArgs;
  269. }
  270. if (! fAttributeWC.isSubsetOf(baseGroup.fAttributeWC)) {
  271. errorArgs = new Object[]{typeName, "derivation-ok-restriction.4.2"};
  272. return errorArgs;
  273. }
  274. if (fAttributeWC.weakerProcessContents(baseGroup.fAttributeWC)) {
  275. errorArgs = new Object[]{typeName,
  276. fAttributeWC.getProcessContentsAsString(),
  277. baseGroup.fAttributeWC.getProcessContentsAsString(),
  278. "derivation-ok-restriction.4.3"};
  279. return errorArgs;
  280. }
  281. }
  282. return null;
  283. }
  284. static final XSAttributeUseImpl[] resize(XSAttributeUseImpl[] oldArray, int newSize) {
  285. XSAttributeUseImpl[] newArray = new XSAttributeUseImpl[newSize];
  286. System.arraycopy(oldArray, 0, newArray, 0, Math.min(oldArray.length, newSize));
  287. return newArray;
  288. }
  289. // reset the attribute group declaration
  290. public void reset(){
  291. fName = null;
  292. fTargetNamespace = null;
  293. // reset attribute uses
  294. for (int i=0;i<fAttrUseNum;i++) {
  295. fAttributeUses[i] = null;
  296. }
  297. fAttrUseNum = 0;
  298. fAttributeWC = null;
  299. fAnnotation = null;
  300. fIDAttrName = null;
  301. }
  302. /**
  303. * Get the type of the object, i.e ELEMENT_DECLARATION.
  304. */
  305. public short getType() {
  306. return XSConstants.ATTRIBUTE_GROUP;
  307. }
  308. /**
  309. * The <code>name</code> of this <code>XSObject</code> depending on the
  310. * <code>XSObject</code> type.
  311. */
  312. public String getName() {
  313. return fName;
  314. }
  315. /**
  316. * The namespace URI of this node, or <code>null</code> if it is
  317. * unspecified. defines how a namespace URI is attached to schema
  318. * components.
  319. */
  320. public String getNamespace() {
  321. return fTargetNamespace;
  322. }
  323. /**
  324. * {attribute uses} A set of attribute uses.
  325. */
  326. public XSObjectList getAttributeUses() {
  327. if (fAttrUses == null){
  328. fAttrUses = new XSObjectListImpl(fAttributeUses, fAttrUseNum);
  329. }
  330. return fAttrUses;
  331. }
  332. /**
  333. * {attribute wildcard} Optional. A wildcard.
  334. */
  335. public XSWildcard getAttributeWildcard() {
  336. return fAttributeWC;
  337. }
  338. /**
  339. * Optional. Annotation.
  340. */
  341. public XSAnnotation getAnnotation() {
  342. return fAnnotation;
  343. }
  344. /**
  345. * @see com.sun.org.apache.xerces.internal.xs.XSObject#getNamespaceItem()
  346. */
  347. public XSNamespaceItem getNamespaceItem() {
  348. //REVISIT: implement
  349. return null;
  350. }
  351. } // class XSAttributeGroupDecl