Clover coverage report - JBind Project
Coverage timestamp: Fr Mai 28 2004 11:17:36 CEST
file stats: LOC: 323   Methods: 23
NCLOC: 262   Classes: 1
This license of Clover is provided to support the development of JBind only. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover.
 
 Source file Conditionals Statements Methods TOTAL
ElementDeclaration.java 86,6% 86,1% 60,9% 83,9%
 1   
 /*
 2   
  * JBind
 3   
  *
 4   
  * Copyright (c) by Stefan Wachter. All rights reserved.
 5   
  *
 6   
  * Usage, modification, and redistribution is subject to license terms that are
 7   
  * available at 'http://www.jbind.org'. The JBind license is like the
 8   
  * 'Apache Software License V 1.1'.
 9   
  */
 10   
 package org.jbind.xml.schema.element;
 11   
 
 12   
 import java.util.Iterator;
 13   
 import java.util.Set;
 14   
 
 15   
 import org.jbind.xml.base.FinalType;
 16   
 import org.jbind.xml.base.IAttribute;
 17   
 import org.jbind.xml.base.INamespaces;
 18   
 import org.jbind.xml.base.IRange;
 19   
 import org.jbind.xml.base.IRef;
 20   
 import org.jbind.xml.base.ISymbolspace;
 21   
 import org.jbind.xml.base.ISymbolspaces;
 22   
 import org.jbind.xml.base.Range;
 23   
 import org.jbind.xml.core.cmp.IComponent;
 24   
 import org.jbind.xml.core.cmp.ISchema;
 25   
 import org.jbind.xml.core.content.IElemDecl;
 26   
 import org.jbind.xml.core.content.IElemRefOrDecl;
 27   
 import org.jbind.xml.core.type.IAnyType;
 28   
 import org.jbind.xml.msg.IConstraintViolations;
 29   
 import org.jbind.xml.msg.XmlException;
 30   
 import org.jbind.xml.msg.XmlMessages;
 31   
 import org.jbind.xml.schema.cmp.ElemDecl;
 32   
 import org.jbind.xml.schema.cmp.ElemRef;
 33   
 import org.jbind.xml.schema.cmp.W3CTypes;
 34   
 import org.jbind.xml.schema.constraint.ElementIdentityConstraint;
 35   
 import org.jbind.xml.schema.instantiation.IComponentSetter;
 36   
 import org.jbind.xml.schema.instantiation.IElemValHelper;
 37   
 import org.jbind.xml.schema.instantiation.IElementHelper;
 38   
 import org.jbind.xml.schema.instantiation.IJobRefs;
 39   
 
 40   
 public class ElementDeclaration extends PartDeclaration implements IElementDeclaration {
 41   
 
 42   
   private boolean myIsUnbounded = false;
 43   
   private int myMin = 1;
 44   
   private int myMax = 1;
 45   
 
 46   
   private boolean myIsNillable = false;
 47   
   private boolean myIsAbstract = false;
 48   
   private Set myBlockTypes = null;
 49   
   private Set myFinalTypes = null;
 50   
 
 51   
   private IRef mySubstitutionGroup = null;
 52   
   private ITypeDef myTypeDef = null;
 53   
 
 54  951
   public ElementDeclaration(CreationParams aCreationParams, boolean anIsLocal) {
 55  951
     super(aCreationParams, anIsLocal);
 56  951
     myBlockTypes = getSchemaElement().getDefaultBlockTypes();
 57  951
     myFinalTypes = getSchemaElement().getDefaultFinalTypes();
 58   
   }
 59   
 
 60  316
   public IElement doCreateChild(CreationParams aCreationParams) throws XmlException {
 61  316
     IElement res = null;
 62  316
     String componentName = NameUtil.getSchemaComponentName(aCreationParams);
 63  316
     if ("unique".equals(componentName)) {
 64  5
       res = new ElementUniqueConstraintElement(aCreationParams);
 65  311
     } else if ("key".equals(componentName)) {
 66  27
       res = new ElementKeyConstraintElement(aCreationParams);
 67  284
     } else if ("keyref".equals(componentName)) {
 68  15
       res = new ElementKeyRefConstraintElement(aCreationParams);
 69  269
     } else if ("simpleType".equals(componentName)) {
 70  3
       res = new SimpleTypeDef(aCreationParams, getBoundName());
 71  266
     } else if ("complexType".equals(componentName)) {
 72  190
       res = new ComplexTypeDef(aCreationParams, getBoundName());
 73   
     } else {
 74  76
       res = super.doCreateChild(aCreationParams);
 75   
     }
 76  316
     return res;
 77   
   }
 78   
 
 79  1799
   protected IAttribute doCreateAttribute(ACParams anACParams) throws XmlException {
 80  1799
     IAttribute res = null;
 81  1799
     String an = NameUtil.getSchemaAttributeName(anACParams);
 82  1799
     if ("abstract".equals(an)) {
 83  8
       res = new BooleanAttribute(anACParams);
 84  7
       myIsAbstract = res.getBoolean();
 85  1791
     } else if ("nillable".equals(an)) {
 86  2
       res = new BooleanAttribute(anACParams);
 87  2
       myIsNillable = res.getBoolean();
 88  1789
     } else if ("block".equals(an)) {
 89  2
       res = new Attribute(anACParams);
 90  2
       myBlockTypes = ConstantResolver.getBlockTypes(res.getStringValue(), this);
 91  1787
     } else if ("final".equals(an)) {
 92  4
       res = new Attribute(anACParams);
 93  4
       myFinalTypes = ConstantResolver.getFinalTypes(res.getStringValue(), this);
 94  1783
     } else if ("substitutionGroup".equals(an)) {
 95  42
       res = new RefAttribute(anACParams, ISymbolspaces.ELEMENT);
 96  42
       mySubstitutionGroup = res.getRef();
 97  1741
     } else if ("minOccurs".equals(an)) {
 98  140
       if (isTopLevelComponent()) {
 99  0
         throw new XmlException(XmlMessages.minOccursAttributeNotAllowedAtTopLevel(this));
 100   
       }
 101  140
       res = new IntAttribute(anACParams);
 102  140
       myMin = res.getInt();
 103  1601
     } else if ("maxOccurs".equals(an)) {
 104  84
       if (isTopLevelComponent()) {
 105  0
         throw new XmlException(XmlMessages.maxOccursAttributeNotAllowedAtTopLevel(this));
 106   
       }
 107  84
       if ("unbounded".equals(anACParams.value)) {
 108  52
         res = new Attribute(anACParams);
 109  52
         myIsUnbounded = true;
 110   
       } else {
 111  32
         res = new IntAttribute(anACParams);
 112  32
         myMax = res.getInt();
 113   
       }
 114   
     } else {
 115  1517
       res = super.doCreateAttribute(anACParams);
 116   
     }
 117  1797
     return res;
 118   
   }
 119   
 
 120  0
   public int getMinOccurs() {
 121  0
     return myMin;
 122   
   }
 123  0
   public int getMaxOccurs() {
 124  0
     return myMax;
 125   
   }
 126  0
   public boolean isUnbounded() {
 127  0
     return myIsUnbounded;
 128   
   }
 129   
 
 130  0
   public boolean getIsAbstract() {
 131  0
     return myIsAbstract;
 132   
   }
 133   
 
 134  0
   public Set getFinalTypes() {
 135  0
     return myFinalTypes;
 136   
   }
 137   
 
 138  0
   public Set getBlockTypes() {
 139  0
     return myBlockTypes;
 140   
   }
 141   
 
 142  2432
   public IRef getSubstitutionGroup() {
 143  2432
     return mySubstitutionGroup;
 144   
   }
 145   
 
 146  0
   public boolean getIsNillable() {
 147  0
     return myIsNillable;
 148   
   }
 149   
 
 150  0
   public Iterator iterIdentityConstraintElements() {
 151  0
     return iterChildrenByClass(IIdentityConstraintElement.class);
 152   
   }
 153   
 
 154  541
   public ISymbolspace getSymbolSpace() {
 155  541
     return ISymbolspaces.ELEMENT;
 156   
   }
 157   
 
 158  456
   public ITypeDef getTypeDef() {
 159  456
     return myTypeDef;
 160   
   }
 161   
 
 162  951
   public void validateElement(IElemValHelper aHelper, IConstraintViolations aViolations) {
 163  951
     super.validateElement(aHelper, aViolations);
 164  951
     myTypeDef = (ITypeDef)getSubElement(ITypeDef.class, "duplicate type definition", aViolations);
 165  951
     if ((null != getType()) && (null != myTypeDef)) {
 166  0
       aViolations.add(XmlMessages.declMustNotHaveTypeAttAndInlinedType(this));
 167   
     }
 168  951
     if (((null != getType()) || (null != myTypeDef)) && (null != getRef())) {
 169  0
       aViolations.add(XmlMessages.declWithRefMustNotHaveType(this));
 170   
     }
 171  951
     if (myMin < 0) {
 172  0
       aViolations.add(XmlMessages.minOccursLessThan0(this));
 173   
     }
 174  951
     if (!myIsUnbounded && (myMin > myMax)) {
 175  0
       aViolations.add(XmlMessages.minOccursGreaterThanMax(this));
 176   
     }
 177   
   }
 178   
 
 179  919
   private IRange getRange() {
 180  919
     return Range.createRange(myMin, myMax, myIsUnbounded);
 181   
   }
 182   
 
 183   
   //
 184   
   // Implementation of IComponentJobHelper
 185   
   //
 186   
 
 187  1648
   public void collectRefsForCreation(IJobRefs aJobRefs) {
 188  1648
     if (null != getRef()) {
 189  446
       aJobRefs.add(getRef(), false, this);
 190   
     }
 191   
     // The type of an element must only be created and not yet be completed when the element declaration
 192   
     // is created. This allows recursive data structures.
 193  1648
     if (null != getType()) {
 194  749
       aJobRefs.add(getType(), false, this);
 195   
     }
 196  1648
     if (null != myTypeDef) {
 197  235
       myTypeDef.collectRefsForCreation(aJobRefs);
 198   
     }
 199  1648
     if (null != getSubstitutionGroup()) {
 200  42
       aJobRefs.add(getSubstitutionGroup(), true, this);
 201   
     }
 202   
   }
 203   
 
 204  3248
   public void collectRefsForCompletion(IElementHelper anElementHelper, IJobRefs aJobRefs) {
 205   
 //              if (null != getRef()) {
 206   
 //                      aJobRefs.add(getRef(), false, this);
 207   
 //              }
 208   
     // The type of an element must have been validated before the element declaration can
 209   
     // be validated if the type is a simple type. In this case the element declaration
 210   
     // may contain value constrains that need a validated type to be applied.
 211  3248
     if (null != getType()) {
 212  1490
       IAnyType type = (IAnyType)anElementHelper.getComponent(getType(), false);
 213  1490
       if (type.isSimple()) {
 214  512
         aJobRefs.add(getType(), true, this);
 215   
       }
 216   
     }
 217  3248
     if (null != myTypeDef) {
 218  434
       myTypeDef.collectRefsForCompletion(anElementHelper, aJobRefs);
 219   
     }
 220   
   }
 221   
 
 222  0
   public void collectRefsForValidation(IElementHelper anElementHelper, IJobRefs aJobRefs) {
 223  0
     if (null != myTypeDef) {
 224  0
       myTypeDef.collectRefsForValidation(anElementHelper, aJobRefs);
 225   
     }
 226   
   }
 227   
 
 228  919
   public IComponent createComponent(IElementHelper anElementHelper, IConstraintViolations aViolations) {
 229  919
     IElemRefOrDecl res = null;
 230   
 
 231  919
     if (null != getRef()) {
 232  214
       IElemDecl c = (IElemDecl)anElementHelper.getComponent(getRef(), false);
 233  214
       res = new ElemRef(this, getRange(), c);
 234   
 
 235   
     } else {
 236  705
       FormType ft = null;
 237  705
       if (isTopLevelComponent()) {
 238  310
         ft = FormType.QUALIFIED;
 239   
       } else {
 240  395
         ft = getFormType();
 241  395
         if (null == ft) {
 242  389
           ft = getSchemaElement().getElementFormDefault();
 243   
         }
 244   
       }
 245  705
       String namespace = ft.equals(FormType.QUALIFIED) ? getSchemaElement().getTargetNamespace() : INamespaces.NO;
 246   
 
 247  705
       final ElemDecl finalRes = new ElemDecl(this, namespace, getName(), getRange(), myFinalTypes, myBlockTypes, myIsAbstract, myIsNillable);
 248  705
       res = finalRes;
 249   
 
 250  705
       IElemDecl substitutionGroup = null;
 251  705
       if (null != getSubstitutionGroup()) {
 252  37
         substitutionGroup = (IElemDecl)anElementHelper.getComponent(getSubstitutionGroup(), true);
 253  37
         finalRes.setSubstitutionGroup(substitutionGroup);
 254  37
         for (IElemDecl d = substitutionGroup; null != d;
 255   
                 d = d.getSubstitutionGroup()) {
 256  46
           d.addSubstitute(finalRes);
 257   
         }
 258   
       }
 259   
 
 260  705
       if (null != getType()) {
 261   
         // The type is possibley not yet validated.
 262  428
         finalRes.setType((IAnyType)anElementHelper.getComponent(getType(), false));
 263   
       } else {
 264  277
         if (null != getTypeDef()) {
 265  179
           anElementHelper.addSubJob(getTypeDef(), new IComponentSetter() {
 266  170
             public void set(IComponent aComponent, IConstraintViolations aVls) {
 267  170
               IAnyType t = (IAnyType)aComponent;
 268  170
               finalRes.setType(t);
 269   
             }
 270   
           });
 271  98
         } else if (null != substitutionGroup) {
 272  2
           finalRes.setType(substitutionGroup.getType());
 273   
         } else {
 274  96
           finalRes.setType(W3CTypes.anyType);
 275   
         }
 276   
       }
 277   
 
 278  705
       final ISchema schema = getSchema();
 279   
 
 280  705
       for (Iterator i = iterChildrenByClass(IIdentityConstraintElement.class);
 281  752
               i.hasNext(); ) {
 282  47
         IIdentityConstraintElement ice = (IIdentityConstraintElement)i.next();
 283  47
         anElementHelper.addSubJob(ice, new IComponentSetter() {
 284  43
           public void set(IComponent aComponent, IConstraintViolations aVls) {
 285  43
             ElementIdentityConstraint c = (ElementIdentityConstraint)aComponent;
 286  43
             finalRes.add(c);
 287  43
             c.setElementDecl(finalRes);
 288  43
             schema.setComponent(c, aVls);
 289   
           }
 290   
         });
 291   
       }
 292   
 
 293   
     }
 294   
 
 295  919
     return res;
 296   
   }
 297   
 
 298  906
   public void completeComponent(IElementHelper anElementHelper, IComponent aComponent, IConstraintViolations aViolations) {
 299  906
     super.completeComponent(anElementHelper, aComponent, aViolations);
 300   
     // Substitution group constraints must only be checked if the element is not a reference.
 301   
     // In case that the element is a reference then the referenced element will check the
 302   
     // constraints.
 303  906
     if (getRef() == null) {
 304  692
       IElemRefOrDecl decl = (IElemRefOrDecl)aComponent;
 305  692
       if (null != decl.getSubstitutionGroup()) {
 306  37
         IAnyType type = decl.getType();
 307  37
         IElemDecl headDecl = decl.getSubstitutionGroup();
 308  37
         IAnyType headType = headDecl.getType();
 309  37
         if (!headType.isBaseType(type)) {
 310  0
           aViolations.add(XmlMessages.substitutionGroupTypeMustBeBaseType(this));
 311   
         }
 312  37
         if (headDecl.isActive(FinalType.EXTENSION) && type.isExtension(headType)) {
 313  0
           aViolations.add(XmlMessages.substitutionFinalizedForExtension(headDecl.getGlobalRef(), this));
 314   
         }
 315  37
         if (headDecl.isActive(FinalType.RESTRICTION) && type.isRestriction(headType)) {
 316  0
           aViolations.add(XmlMessages.substitutionFinalizedForRestriction(headDecl.getGlobalRef(), this));
 317   
         }
 318   
       }
 319   
     }
 320   
   }
 321   
 
 322   
 }
 323