1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 /*
   6  * Copyright 2001-2004 The Apache Software Foundation.
   7  *
   8  * Licensed under the Apache License, Version 2.0 (the "License");
   9  * you may not use this file except in compliance with the License.
  10  * You may obtain a copy of the License at
  11  *
  12  *      http://www.apache.org/licenses/LICENSE-2.0
  13  *
  14  * Unless required by applicable law or agreed to in writing, software
  15  * distributed under the License is distributed on an "AS IS" BASIS,
  16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17  * See the License for the specific language governing permissions and
  18  * limitations under the License.
  19  */
  20 package com.sun.org.apache.xerces.internal.impl.xs.traversers;
  21 
  22 import com.sun.org.apache.xerces.internal.impl.xs.SchemaGrammar;
  23 import com.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols;
  24 import com.sun.org.apache.xerces.internal.impl.xs.XSAnnotationImpl;
  25 import com.sun.org.apache.xerces.internal.impl.xs.XSAttributeGroupDecl;
  26 import com.sun.org.apache.xerces.internal.impl.xs.util.XSObjectListImpl;
  27 import com.sun.org.apache.xerces.internal.util.DOMUtil;
  28 import com.sun.org.apache.xerces.internal.util.XMLSymbols;
  29 import com.sun.org.apache.xerces.internal.xni.QName;
  30 import com.sun.org.apache.xerces.internal.xs.XSObjectList;
  31 import org.w3c.dom.Element;
  32 
  33 /**
  34  * The attribute group definition schema component traverser.
  35  *
  36  * <attributeGroup
  37  *   id = ID
  38  *   name = NCName
  39  *   ref = QName
  40  *   {any attributes with non-schema namespace . . .}>
  41  *   Content: (annotation?, ((attribute | attributeGroup)*, anyAttribute?))
  42  * </attributeGroup>
  43  *
  44  * @xerces.internal
  45  *
  46  * @author Rahul Srivastava, Sun Microsystems Inc.
  47  * @author Sandy Gao, IBM
  48  *
  49  * @version $Id: XSDAttributeGroupTraverser.java,v 1.7 2010-11-01 04:40:02 joehw Exp $
  50  */
  51 class XSDAttributeGroupTraverser extends XSDAbstractTraverser {
  52 
  53     XSDAttributeGroupTraverser (XSDHandler handler,
  54             XSAttributeChecker gAttrCheck) {
  55 
  56         super(handler, gAttrCheck);
  57     }
  58 
  59 
  60     XSAttributeGroupDecl traverseLocal(Element elmNode,
  61             XSDocumentInfo schemaDoc,
  62             SchemaGrammar grammar) {
  63 
  64         // General Attribute Checking for elmNode declared locally
  65         Object[] attrValues = fAttrChecker.checkAttributes(elmNode, false, schemaDoc);
  66 
  67         // get attribute
  68         QName   refAttr = (QName)   attrValues[XSAttributeChecker.ATTIDX_REF];
  69 
  70         XSAttributeGroupDecl attrGrp = null;
  71 
  72         // ref should be here.
  73         if (refAttr == null) {
  74             reportSchemaError("s4s-att-must-appear", new Object[]{"attributeGroup (local)", "ref"}, elmNode);
  75             fAttrChecker.returnAttrArray(attrValues, schemaDoc);
  76             return null;
  77         }
  78 
  79         // get global decl
  80         attrGrp = (XSAttributeGroupDecl)fSchemaHandler.getGlobalDecl(schemaDoc, XSDHandler.ATTRIBUTEGROUP_TYPE, refAttr, elmNode);
  81 
  82         // no children are allowed here except annotation, which is optional.
  83         Element child = DOMUtil.getFirstChildElement(elmNode);
  84         if (child != null) {
  85             String childName = DOMUtil.getLocalName(child);
  86             if (childName.equals(SchemaSymbols.ELT_ANNOTATION)) {
  87                 traverseAnnotationDecl(child, attrValues, false, schemaDoc);
  88                 child = DOMUtil.getNextSiblingElement(child);
  89             } else {
  90                 String text = DOMUtil.getSyntheticAnnotation(child);
  91                 if (text != null) {
  92                     traverseSyntheticAnnotation(child, text, attrValues, false, schemaDoc);
  93                 }
  94             }
  95 
  96             if (child != null) {
  97                 Object[] args = new Object [] {refAttr.rawname, "(annotation?)", DOMUtil.getLocalName(child)};
  98                 reportSchemaError("s4s-elt-must-match.1", args, child);
  99             }
 100         } // if
 101 
 102         fAttrChecker.returnAttrArray(attrValues, schemaDoc);
 103         return attrGrp;
 104 
 105     } // traverseLocal
 106 
 107     XSAttributeGroupDecl traverseGlobal(Element elmNode,
 108             XSDocumentInfo schemaDoc,
 109             SchemaGrammar grammar) {
 110 
 111         XSAttributeGroupDecl attrGrp = new XSAttributeGroupDecl();
 112 
 113         // General Attribute Checking for elmNode declared globally
 114         Object[] attrValues = fAttrChecker.checkAttributes(elmNode, true, schemaDoc);
 115 
 116         String  nameAttr   = (String) attrValues[XSAttributeChecker.ATTIDX_NAME];
 117 
 118         // global declaration must have a name
 119         if (nameAttr == null) {
 120             reportSchemaError("s4s-att-must-appear", new Object[]{"attributeGroup (global)", "name"}, elmNode);
 121             nameAttr = NO_NAME;
 122         }
 123 
 124         attrGrp.fName = nameAttr;
 125         attrGrp.fTargetNamespace = schemaDoc.fTargetNamespace;
 126 
 127         // check the content
 128         Element child = DOMUtil.getFirstChildElement(elmNode);
 129         XSAnnotationImpl annotation = null;
 130 
 131         if (child!=null && DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) {
 132             annotation = traverseAnnotationDecl(child, attrValues, false, schemaDoc);
 133             child = DOMUtil.getNextSiblingElement(child);
 134         }
 135         else {
 136             String text = DOMUtil.getSyntheticAnnotation(elmNode);
 137             if (text != null) {
 138                 annotation = traverseSyntheticAnnotation(elmNode, text, attrValues, false, schemaDoc);
 139             }
 140         }
 141 
 142         // Traverse the attribute and attribute group elements and fill in the
 143         // attributeGroup structure
 144 
 145         Element nextNode = traverseAttrsAndAttrGrps(child, attrGrp, schemaDoc, grammar, null);
 146         if (nextNode!=null) {
 147             // An invalid element was found...
 148             Object[] args = new Object [] {nameAttr, "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))", DOMUtil.getLocalName(nextNode)};
 149             reportSchemaError("s4s-elt-must-match.1", args, nextNode);
 150         }
 151 
 152         if (nameAttr.equals(NO_NAME)) {
 153             // if a global group doesn't have a name, then don't add it.
 154             fAttrChecker.returnAttrArray(attrValues, schemaDoc);
 155             return null;
 156         }
 157 
 158         // Remove prohibited attributes from the set
 159         attrGrp.removeProhibitedAttrs();
 160 
 161         // check for restricted redefine:
 162         XSAttributeGroupDecl redefinedAttrGrp = (XSAttributeGroupDecl)fSchemaHandler.getGrpOrAttrGrpRedefinedByRestriction(
 163                 XSDHandler.ATTRIBUTEGROUP_TYPE,
 164                 new QName(XMLSymbols.EMPTY_STRING, nameAttr, nameAttr, schemaDoc.fTargetNamespace),
 165                 schemaDoc, elmNode);
 166         if(redefinedAttrGrp != null) {
 167             Object[] errArgs = attrGrp.validRestrictionOf(nameAttr, redefinedAttrGrp);
 168             if (errArgs != null) {
 169                 reportSchemaError((String)errArgs[errArgs.length-1], errArgs, child);
 170                 reportSchemaError("src-redefine.7.2.2", new Object [] {nameAttr, errArgs[errArgs.length-1]}, child);
 171             }
 172         }
 173 
 174         XSObjectList annotations;
 175         if (annotation != null) {
 176             annotations = new XSObjectListImpl();
 177             ((XSObjectListImpl)annotations).addXSObject (annotation);
 178         } else {
 179             annotations = XSObjectListImpl.EMPTY_LIST;
 180         }
 181 
 182         attrGrp.fAnnotations = annotations;
 183 
 184         // make an entry in global declarations.
 185         if (grammar.getGlobalAttributeGroupDecl(attrGrp.fName) == null) {
 186             grammar.addGlobalAttributeGroupDecl(attrGrp);
 187         }
 188 
 189         // also add it to extended map
 190         final String loc = fSchemaHandler.schemaDocument2SystemId(schemaDoc);
 191         final XSAttributeGroupDecl attrGrp2 = grammar.getGlobalAttributeGroupDecl(attrGrp.fName, loc);
 192         if (attrGrp2 == null) {
 193             grammar.addGlobalAttributeGroupDecl(attrGrp, loc);
 194         }
 195 
 196         // handle duplicates
 197         if (fSchemaHandler.fTolerateDuplicates) {
 198             if (attrGrp2 != null) {
 199                 attrGrp = attrGrp2;
 200             }
 201             fSchemaHandler.addGlobalAttributeGroupDecl(attrGrp);
 202         }
 203 
 204         fAttrChecker.returnAttrArray(attrValues, schemaDoc);
 205         return attrGrp;
 206 
 207     } // traverseGlobal
 208 
 209 } // XSDAttributeGroupTraverser