Clover coverage report - JBind Project
Coverage timestamp: Fr Mai 28 2004 11:17:36 CEST
file stats: LOC: 203   Methods: 14
NCLOC: 136   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
UnionType.java 84,6% 92,2% 92,9% 90,4%
 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.cmp;
 11   
 
 12   
 import java.util.ArrayList;
 13   
 import java.util.Collection;
 14   
 import java.util.Iterator;
 15   
 import java.util.Set;
 16   
 
 17   
 import org.jbind.xml.base.FinalType;
 18   
 import org.jbind.xml.base.WhiteSpaceProcessing;
 19   
 import org.jbind.xml.core.bridge.IDataImpl;
 20   
 import org.jbind.xml.core.cmp.IComponentVisitor;
 21   
 import org.jbind.xml.core.cmp.ISourceInfo;
 22   
 import org.jbind.xml.core.constraint.ConstraintType;
 23   
 import org.jbind.xml.core.constraint.ICheckContext;
 24   
 import org.jbind.xml.core.data.IAnyTypeData;
 25   
 import org.jbind.xml.core.type.IAnyType;
 26   
 import org.jbind.xml.core.type.ISimpleType;
 27   
 import org.jbind.xml.core.type.IUnionType;
 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.constraint.Constraints;
 32   
 
 33   
 public class UnionType extends SimpleType implements IUnionType {
 34   
 
 35   
   private Collection myMemberTypes = new ArrayList();
 36   
 
 37   
   private IAnyType myCommonBaseType = null;
 38   
 
 39  23
   public UnionType(ISourceInfo aSourceInfo, String aNamespace, String aName, String aRole, Set aFinalTypes) {
 40  23
     super(aSourceInfo, aNamespace, aName, aRole, aFinalTypes);
 41  23
     setBaseType(W3CTypes.anySimpleType);
 42  23
     setConstraints(new Constraints());
 43  23
     getConstraints().setWhiteSpaceProcessing(WhiteSpaceProcessing.PRESERVE);
 44   
   }
 45   
 
 46  10
   public final boolean isApplicable(ConstraintType aConstraintType) {
 47  10
     return ConstraintType.CHECKER_EP.isApplicable(aConstraintType);
 48   
   }
 49   
 
 50  44
   public void addMemberType(ISimpleType aSimpleType, IConstraintViolations aViolations) {
 51  44
     if (aSimpleType.isActive(FinalType.UNION)) {
 52  0
       aViolations.add(XmlMessages.memberTypeIsFinalizedForUnion(aSimpleType.getLocation(), this));
 53   
     }
 54   
     // A union is finalized for list if it has a member type that is finalized 
 55   
     // for list.
 56  44
     if (aSimpleType.isActive(FinalType.LIST)) {
 57  10
       addFinalType(FinalType.LIST);
 58   
     }
 59  44
     myMemberTypes.add(aSimpleType);
 60   
   }
 61   
 
 62  277
   public Iterator iterMemberTypes() {
 63  277
     return myMemberTypes.iterator();
 64   
   }
 65   
 
 66  23
   public void validate(IConstraintViolations aViolations) {
 67  23
     super.validate(aViolations);
 68   
 
 69  23
     if (myMemberTypes.size() == 0) {
 70  0
       aViolations.add(XmlMessages.missingMemberType(this));
 71   
     }
 72   
 
 73   
     // Determine the most specific common base type of the member types.
 74   
     // This allows the code generator to generate more specific code.
 75   
 
 76   
     // Start with the first member type and follow its base types until all member
 77   
     // types are sub types.
 78  23
     Iterator i = iterMemberTypes();
 79   
 
 80  23
     myCommonBaseType = ((IAnyType)i.next()).getInstanceType();
 81  23
     while (i.hasNext()) {
 82  21
       IAnyType t = ((IAnyType)i.next()).getInstanceType();
 83  21
       while (!myCommonBaseType.isBaseType(t)) {
 84  59
         myCommonBaseType = myCommonBaseType.getBaseType();
 85   
       }
 86   
     }
 87   
 
 88   
   }
 89   
 
 90   
   /**
 91   
    * Creates a data object for the specified implementation.
 92   
    * <p>
 93   
    * If an overloading type
 94   
    * is specified then it is validated that the overloading type is contained in the
 95   
    * member types. The overloading type is then used to create an unchecked data object.
 96   
    * <p>
 97   
    * If no overloading type is specified then a member type is looked for that can
 98   
    * create a <b>checked</b> data object without constraint violations. If such a type
 99   
    * is found then the created data object is returned. Otherwise it is tried to find
 100   
    * a type that can create an <b>unchecked</b> data object. If such a type is found
 101   
    * then the created data object is returned.
 102   
    *
 103   
    * @param anImpl <i>(required)</i>.
 104   
    * @return <i>(required)</i>.
 105   
    * @throws XmlException Description of the Exception
 106   
    */
 107  92
   protected IAnyTypeData doCreateEmptyData(IDataImpl anImpl) throws XmlException {
 108  92
     IAnyTypeData res = null;
 109  92
     IAnyTypeData uncheckedObject = null;
 110  92
     IAnyTypeData checkedObject = null;
 111   
 
 112  92
     for (Iterator i = iterMemberTypes(); i.hasNext(); ) {
 113  128
       ISimpleType t = (ISimpleType)i.next();
 114  128
       try {
 115  128
         checkedObject = (IAnyTypeData)t.createData(anImpl);
 116  90
         break;
 117   
       } catch (XmlException e) {
 118  38
         try {
 119  38
           if (null == uncheckedObject) {
 120  36
             uncheckedObject = t.createUncheckedData(anImpl);
 121   
           }
 122   
         } catch (XmlException ex) {}
 123   
       }
 124   
     }
 125   
 
 126  92
     res = (null != checkedObject) ? checkedObject : uncheckedObject;
 127   
 
 128  92
     if (null == res) {
 129  0
       throw new XmlException(XmlMessages.noUnionMemberFound(anImpl.getTextContent(), anImpl));
 130   
     }
 131   
 
 132  92
     return res;
 133   
   }
 134   
 
 135  20
   public boolean canBeOverloadedBy(IAnyType aType) {
 136   
     // A union type may also be overloaded by another union type.
 137  20
     boolean res = isBaseType(aType);
 138  20
     for (Iterator i = iterMemberTypes(); !res && i.hasNext(); ) {
 139  28
       IAnyType memberType = (IAnyType)i.next();
 140  28
       res = memberType.canBeOverloadedBy(aType);
 141   
     }
 142  20
     return res;
 143   
   }
 144   
 
 145  130
   public boolean isInstanceType(IAnyType aType) {
 146  130
     boolean res = aType.isBaseType(this);
 147  130
     for (Iterator i = iterMemberTypes(); !res && i.hasNext(); ) {
 148  260
       IAnyType memberType = (IAnyType)i.next();
 149  260
       res = memberType.isInstanceType(aType);
 150   
     }
 151  130
     return res;
 152   
   }
 153   
 
 154  105
   public IAnyType getInstanceType() {
 155  105
     return myCommonBaseType;
 156   
   }
 157   
 
 158  122
   public void checkEnclosedConstraints(ICheckContext aContext) {
 159  122
     IAnyType dataType = aContext.getData().getType_();
 160  122
     if (dataType.isComplex()) {
 161  12
       complexCheck:
 162   
       {
 163   
         // The data type is a complex type with simple content that was derived
 164   
         // from a union.
 165   
         // -> check the data against the member types. There must be at least one
 166   
         // Member type that accepts the data.
 167  12
         IAnyType t = null;
 168  12
         for (t = dataType; !(t instanceof IUnionType); t = t.getBaseType());
 169  16
         for (Iterator i = ((IUnionType)t).iterMemberTypes(); i.hasNext(); ) {
 170  16
           ISimpleType st = (ISimpleType)i.next();
 171  16
           try {
 172  16
             st.createData(aContext.getData().getImpl_());
 173  12
             break complexCheck;
 174   
           } catch (XmlException e) {
 175   
             // ignore
 176   
           }
 177   
         }
 178  0
         aContext.add(XmlMessages.dataNotAcceptedByAnyMemberType(aContext.getData().getImpl_().getTextContent(), aContext.getData().getImpl_()));
 179   
       }// complexCheck
 180   
     } else {
 181  110
       dataType.checkConstraints(aContext);
 182   
     }
 183   
   }
 184   
 
 185  49
   public void accept(IComponentVisitor aVisitor) throws XmlException {
 186  49
     aVisitor.visitUnionTypeStart(this);
 187  49
     visitSubComponents(aVisitor);
 188  49
     aVisitor.visitUnionTypeEnd(this);
 189   
   }
 190   
 
 191  6
   public ISimpleType createRestriction(ISourceInfo aSourceInfo, String aNamespace, String aName, String aRole, Set aFinalTypes, IConstraintViolations aViolations) {
 192  6
     return new RestrictedUnionType(aSourceInfo, aNamespace, aName, aRole, aFinalTypes, aViolations);
 193   
   }
 194   
 
 195  457
   public Class getSimpleStorageType() {
 196  457
     return myCommonBaseType.getSimpleStorageType();
 197   
   }
 198   
 
 199  0
   protected boolean isUnion() {
 200  0
     return true;
 201   
   }
 202   
 }
 203