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