Clover coverage report - JBind Project
Coverage timestamp: Fr Mai 28 2004 11:17:36 CEST
file stats: LOC: 564   Methods: 31
NCLOC: 407   Classes: 3
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
DataCartridge.java 65,4% 97,1% 96,8% 87,3%
 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.compiler;
 11   
 
 12   
 import java.io.BufferedReader;
 13   
 import java.io.File;
 14   
 import java.io.IOException;
 15   
 import java.io.Reader;
 16   
 import java.util.ArrayList;
 17   
 import java.util.Collections;
 18   
 import java.util.Comparator;
 19   
 import java.util.HashMap;
 20   
 import java.util.Iterator;
 21   
 import java.util.List;
 22   
 import java.util.Map;
 23   
 import java.util.StringTokenizer;
 24   
 import java.util.TreeMap;
 25   
 
 26   
 import org.jbind.message.IMessage;
 27   
 import org.jbind.util.collection.ConcatIterator;
 28   
 import org.jbind.util.reflect.ReflectUtil;
 29   
 import org.jbind.xml.base.IAttribute;
 30   
 import org.jbind.xml.base.IBindingAttributes;
 31   
 import org.jbind.xml.base.IRange;
 32   
 import org.jbind.xml.base.IRef;
 33   
 import org.jbind.xml.base.RefComparator;
 34   
 import org.jbind.xml.base.StringUtil;
 35   
 import org.jbind.xml.core.bridge.IXPathMethod;
 36   
 import org.jbind.xml.core.cmp.IAttributesModel;
 37   
 import org.jbind.xml.core.cmp.IBinding;
 38   
 import org.jbind.xml.core.cmp.IComponent;
 39   
 import org.jbind.xml.core.cmp.IContentModel;
 40   
 import org.jbind.xml.core.cmp.ISourceInfo;
 41   
 import org.jbind.xml.core.constraint.ConstraintType;
 42   
 import org.jbind.xml.core.constraint.IIdRefOrIdRefsConstraint;
 43   
 import org.jbind.xml.core.constraint.IReferenceConstraint;
 44   
 import org.jbind.xml.core.constraint.ITypeKeyRefConstraint;
 45   
 import org.jbind.xml.core.content.IAttrRefOrDecl;
 46   
 import org.jbind.xml.core.content.IDataRefOrDecl;
 47   
 import org.jbind.xml.core.content.IElemRefOrDecl;
 48   
 import org.jbind.xml.core.type.IAnyType;
 49   
 import org.jbind.xml.msg.XmlException;
 50   
 import org.jbind.xml.msg.XmlMessages;
 51   
 
 52   
 public abstract class DataCartridge extends BaseCartridge {
 53   
 
 54  6
   public DataCartridge(String aCartridgeAttributePrefix, String aNamePrefix, String aNameSuffix) {
 55  6
     super(aCartridgeAttributePrefix, aNamePrefix, aNameSuffix);
 56   
   }
 57   
 
 58  1132
   public boolean overwrite() {
 59  1132
     return true;
 60   
   }
 61   
 
 62  397
   public boolean isUpToDate(Reader aReader, IFileInfo aFileInfo) throws IOException {
 63  397
     BufferedReader reader = new BufferedReader(aReader);
 64  397
     StringTokenizer stringTokenizer = new StringTokenizer(aFileInfo.getGeneratedCode(), "\n");
 65  397
     while (true) {
 66  25926
       String previousLine = reader.readLine();
 67  25926
       if (null == previousLine) {
 68  397
         if (stringTokenizer.hasMoreElements()) {
 69  0
           return false;
 70   
         } else {
 71  397
           return true;
 72   
         }
 73   
       }
 74  25529
       if (!stringTokenizer.hasMoreElements()) {
 75  0
         return false;
 76   
       }
 77  25529
       String generatedLine = (String)stringTokenizer.nextElement();
 78  25529
       if (!previousLine.equals(generatedLine)) {
 79  0
         return false;
 80   
       }
 81   
     }
 82   
   }
 83   
 
 84  0
   public IMessage getEditHint(File aFile, IComponent aComponent) {
 85   
     assert false;
 86  0
     return null;
 87   
   }
 88   
 
 89  118
   public IBinding createGlobalAttrDeclBinding(IComponent aComponent, String aRootPackage, boolean aUseBuiltInClassesOnly) {
 90  118
     return new PackageBinding(aRootPackage, this, aComponent);
 91   
   }
 92  70
   public IBinding createGlobalGroupDeclBinding(IComponent aComponent, String aRootPackage, boolean aUseBuiltInClassesOnly) {
 93  70
     return new GlobalBinding(aRootPackage, this, aComponent);
 94   
   }
 95  580
   public IBinding createGlobalElemDeclBinding(IComponent aComponent, String aRootPackage, boolean aUseBuiltInClassesOnly) {
 96  580
     return new PackageBinding(aRootPackage, this, aComponent);
 97   
   }
 98  88
   public IBinding createGlobalAttrGroupBinding(IComponent aComponent, String aRootPackage, boolean aUseBuiltInClassesOnly) {
 99  88
     return new GlobalBinding(aRootPackage, this, aComponent);
 100   
   }
 101  564
   public IBinding createBuiltInBinding(IComponent aComponent) {
 102  564
     return new BuiltInBinding(aComponent, doGetBuiltInPackage(), getNamePrefix(aComponent), getNameSuffix(aComponent));
 103   
   }
 104  60
   public IBinding createInnerAttrRefBinding(IComponent aComponent, IBinding aParentBinding, boolean aUseBuiltInClassesOnly) {
 105  60
     return aParentBinding;
 106   
   }
 107  1120
   public IBinding createInnerAttrDeclBinding(IComponent aComponent, IBinding aParentBinding, boolean aUseBuiltInClassesOnly) {
 108  1120
     return aParentBinding;
 109   
   }
 110  132
   public IBinding createInnerAttrWildcardBinding(IComponent aComponent, IBinding aParentBinding, boolean aUseBuiltInClassesOnly) {
 111  132
     return aParentBinding;
 112   
   }
 113  772
   public IBinding createInnerGroupRefOrDeclBinding(IComponent aComponent, IBinding aParentBinding, boolean aUseBuiltInClassesOnly) {
 114  772
     return aParentBinding;
 115   
   }
 116  420
   public IBinding createInnerElemRefBinding(IComponent aComponent, IBinding aParentBinding, boolean aUseBuiltInClassesOnly) {
 117  420
     return aParentBinding;
 118   
   }
 119  740
   public IBinding createInnerElemDeclBinding(IComponent aComponent, IBinding aParentBinding, boolean aUseBuiltInClassesOnly) {
 120  740
     return aParentBinding;
 121   
   }
 122  54
   public IBinding createInnerElemWildcardBinding(IComponent aComponent, IBinding aParentBinding, boolean aUseBuiltInClassesOnly) {
 123  54
     return aParentBinding;
 124   
   }
 125  988
   public IBinding createInnerAttrGroupBinding(IComponent aComponent, IBinding aParentBinding, boolean aUseBuiltInClassesOnly) {
 126  988
     return aParentBinding;
 127   
   }
 128   
 
 129   
   protected abstract String doGetBuiltInPackage();
 130   
 
 131  874
   protected boolean doVisitAnyTypeStart(IAnyType aType) throws XmlException {
 132  874
     writeMultiLn(typeComment(aType));
 133  874
     writeLn(declaration(aType) + " {");
 134  874
     addIndent();
 135  874
     writeMultiLn(begin(aType));
 136  874
     setOuterComponent(aType);
 137  874
     if (!treatMethods(aType)) {
 138  6
       return true;
 139   
     }
 140  868
     setNotEmpty();
 141   
 
 142   
     /**
 143   
      * Maps property names to their components. Used to indicate naming problems
 144   
      * during generation.
 145   
      */
 146  868
     Map propertyNames = new HashMap();
 147   
 
 148  868
     MethodVariant pv = null;
 149   
 
 150   
     //
 151   
     // elements
 152   
     //
 153   
 
 154   
     // The elements are sorted to guarantee the same sequence of generation.
 155  868
     Map elementInfos = new TreeMap(RefComparator.INSTANCE);
 156  868
     collectElementInfos(aType, elementInfos, false);
 157   
 
 158  868
     for (Iterator i = elementInfos.values().iterator(); i.hasNext(); ) {
 159  1106
       ElementInfo elementInfo = (ElementInfo)i.next();
 160  1106
       IElemRefOrDecl elemRefOrDecl = elementInfo.elemRefOrDecl;
 161   
 
 162   
       // check if the property name is unique
 163  1106
       String propertyName = propertyName(elemRefOrDecl);
 164  1106
       ISourceInfo previous = (ISourceInfo)propertyNames.put(propertyName, elemRefOrDecl);
 165  1106
       if (null != previous) {
 166  0
         throw new XmlException(XmlMessages.ambiguousProperty(propertyName, previous.getLocation(), elemRefOrDecl));
 167   
       }
 168   
 
 169  1106
       boolean useDataClass = useDataClass(elemRefOrDecl);
 170   
 
 171  1106
       if (elementInfo.isSingle && (!elementInfo.isInheritedSingle || treatInherited())) {
 172  ?
         if (MethodVariant.NONE != (pv = MethodVariant.getMethodVariant(elemRefOrDecl, IBindingAttributes.GETTER, "normal"))) {
 173  374
           writeMultiLn(elementGetter(aType, elemRefOrDecl, pv, useDataClass));
 174   
         }
 175  ?
         if (MethodVariant.NONE != (pv = MethodVariant.getMethodVariant(elemRefOrDecl, IBindingAttributes.CHECKER, "none"))) {
 176  46
           writeMultiLn(elementChecker(aType, elemRefOrDecl, pv));
 177   
         }
 178  ?
         if (MethodVariant.NONE != (pv = MethodVariant.getMethodVariant(elemRefOrDecl, IBindingAttributes.REMOVER, "none"))) {
 179  24
           writeMultiLn(elementRemover(aType, elemRefOrDecl, pv));
 180   
         }
 181   
       }
 182   
 
 183  1106
       if (!elementInfo.isInherited || treatInherited()) {
 184  ?
         if (MethodVariant.NONE != (pv = MethodVariant.getMethodVariant(elemRefOrDecl, IBindingAttributes.CREATOR, "none"))) {
 185  10
           writeMultiLn(elementCreator(aType, elemRefOrDecl, pv));
 186   
         }
 187   
       }
 188   
 
 189  1106
       if (!elementInfo.isInherited || treatInherited()) {
 190  ?
         if (MethodVariant.NONE != (pv = MethodVariant.getMethodVariant(elemRefOrDecl, IBindingAttributes.CREATOR_WITH_TYPE, "none"))) {
 191  30
           writeMultiLn(elementCreatorWithType(aType, elemRefOrDecl, pv));
 192   
         }
 193   
       }
 194   
 
 195  1106
       if (elementInfo.isMultiple && (!elementInfo.isInheritedMultiple || treatInherited())) {
 196  ?
         if (MethodVariant.NONE != (pv = MethodVariant.getMethodVariant(elemRefOrDecl, IBindingAttributes.ITERATOR, "normal"))) {
 197  500
           writeMultiLn(elementIterator(aType, elemRefOrDecl, pv, useDataClass));
 198   
         }
 199   
       }
 200   
 
 201   
     }
 202   
 
 203  868
     IAnyType baseType = aType.getBaseType();
 204   
 
 205   
     //
 206   
     // attributes
 207   
     //
 208   
 
 209  868
     for (Iterator i = aType.getAttributesModel().iterAttributes();
 210  1619
             i.hasNext(); ) {
 211  751
       IAttrRefOrDecl attr = (IAttrRefOrDecl)i.next();
 212  751
       IRef ref = attr.getGlobalRef();
 213  751
       IAttrRefOrDecl baseAttr = getBaseAttributeDecl(ref, aType);
 214   
 
 215   
       // check if the property name is unique
 216  751
       String propertyName = propertyName(attr);
 217  751
       ISourceInfo previous = (ISourceInfo)propertyNames.put(propertyName, attr);
 218  751
       if (null != previous) {
 219  0
         throw new XmlException(XmlMessages.ambiguousProperty(propertyName, previous.getLocation(), attr));
 220   
       }
 221   
 
 222  751
       boolean useDataClass = useDataClass(baseAttr);
 223   
 
 224   
       // indicates if the attribute is inherited
 225  751
       boolean inherited = baseType.getAttributesModel().hasAttribute(ref);
 226   
 
 227  751
       if (!inherited || treatInherited()) {
 228  ?
         if (MethodVariant.NONE != (pv = MethodVariant.getMethodVariant(baseAttr, IBindingAttributes.GETTER, "normal"))) {
 229  580
           writeMultiLn(attributeGetter(aType, baseAttr, pv, useDataClass));
 230   
         }
 231  ?
         if (MethodVariant.NONE != (pv = MethodVariant.getMethodVariant(baseAttr, IBindingAttributes.SETTER, "none"))) {
 232  114
           writeMultiLn(attributeSetter(aType, baseAttr, pv, useDataClass));
 233   
         }
 234  ?
         if (MethodVariant.NONE != (pv = MethodVariant.getMethodVariant(baseAttr, IBindingAttributes.ITERATOR, "normal"))) {
 235  580
           writeMultiLn(attributeIterator(aType, baseAttr, pv, useDataClass));
 236   
         }
 237  ?
         if (MethodVariant.NONE != (pv = MethodVariant.getMethodVariant(baseAttr, IBindingAttributes.CHECKER, "none"))) {
 238  206
           writeMultiLn(attributeChecker(aType, baseAttr, pv));
 239   
         }
 240  ?
         if (MethodVariant.NONE != (pv = MethodVariant.getMethodVariant(baseAttr, IBindingAttributes.REMOVER, "none"))) {
 241  114
           writeMultiLn(attributeRemover(aType, baseAttr, pv));
 242   
         }
 243   
       }
 244   
     }
 245   
 
 246   
     //
 247   
     // reference constraints
 248   
     //
 249   
 
 250  868
     List l = new ArrayList();
 251  868
     for (Iterator i = aType.getConstraints().getConstraintList(ConstraintType.TYPE_KEY_REF).iterator();
 252  876
             i.hasNext(); ) {
 253  8
       ITypeKeyRefConstraint c = (ITypeKeyRefConstraint)i.next();
 254  8
       String propertyName = c.getLocalStringBindingAttribute(IBindingAttributes.NAME);
 255  8
       if (null == propertyName) {
 256  8
         propertyName = c.getName();
 257   
       }
 258  8
       String comment = "keyRef (" + c.getName() + ")";
 259  8
       l.add(new RefConstraintInfo(c, c.getConstraintKey(), StringUtil.firstUpper(StringUtil.toJavaIdentifier(propertyName)), comment, c.getDataType()));
 260   
     }
 261  868
     Iterator i1 = aType.getConstraints().getConstraintList(ConstraintType.ID_REF).iterator();
 262  868
     Iterator i2 = aType.getConstraints().getConstraintList(ConstraintType.ID_REFS).iterator();
 263  868
     for (Iterator i = new ConcatIterator(i1, i2); i.hasNext(); ) {
 264  8
       IIdRefOrIdRefsConstraint c = (IIdRefOrIdRefsConstraint)i.next();
 265  8
       String propertyName = c.getAttrRefOrDecl().getLocalStringBindingAttribute(IBindingAttributes.NAME);
 266  8
       if (null == propertyName) {
 267  8
         propertyName = c.getAttrRefOrDecl().getGlobalRef().getLocalPart();
 268   
       }
 269  8
       String comment = null;
 270  8
       if (c.isSingleNotMultipleReference()) {
 271  4
         comment = "IDREF(" + c.getAttrRefOrDecl().getGlobalRef().getLocalPart() + ")";
 272   
       } else {
 273  4
         comment = "IDREFS(" + c.getAttrRefOrDecl().getGlobalRef().getLocalPart() + ")";
 274   
       }
 275   
 
 276  8
       l.add(new RefConstraintInfo(c, c.getConstraintKey(), StringUtil.firstUpper(StringUtil.toJavaIdentifier(propertyName)), comment, c.getDataType()));
 277   
     }
 278  868
     for (Iterator i = l.iterator(); i.hasNext(); ) {
 279  16
       RefConstraintInfo constraintInfo = (RefConstraintInfo)i.next();
 280  16
       IReferenceConstraint constraint = constraintInfo.referenceConstraint;
 281   
       // indicates if the constraint is inherited
 282  16
       boolean inherited = baseType.getConstraints().hasConstraint(constraint);
 283  16
       if (!inherited || treatInherited()) {
 284  16
         if (constraint.isSingleNotMultipleReference()) {
 285  ?
           if (MethodVariant.NONE != (pv = MethodVariant.getMethodVariant(constraint, IBindingAttributes.REFERENCE_GETTER, "normal"))) {
 286  10
             writeMultiLn(referenceGetter(aType, constraintInfo, pv));
 287   
           }
 288   
         }
 289  16
         if (!constraint.isSingleNotMultipleReference()) {
 290  ?
           if (MethodVariant.NONE != (pv = MethodVariant.getMethodVariant(constraint, IBindingAttributes.REFERENCE_ITERATOR, "normal"))) {
 291  6
             writeMultiLn(referenceIterator(aType, constraintInfo, pv));
 292   
           }
 293   
         }
 294   
       }
 295   
     }
 296   
 
 297  868
     ArrayList xPathMethods = new ArrayList(aType.getXPathMethods().values());
 298  868
     Collections.sort(xPathMethods, new Comparator() {
 299  14
       public int compare(Object anObject1, Object anObject2) {
 300  14
         IXPathMethod m1 = (IXPathMethod)anObject1;
 301  14
         IXPathMethod m2 = (IXPathMethod)anObject2;
 302  14
         return m1.getName().compareTo(m2.getName());
 303   
       }
 304   
     });
 305   
 
 306  868
     for (Iterator i = xPathMethods.iterator(); i.hasNext(); ) {
 307  12
       IXPathMethod m = (IXPathMethod)i.next();
 308  12
       boolean inherited = null != baseType.getXPathMethods().get(m.getName());
 309  12
       if (!inherited || treatInherited()) {
 310  12
         writeMultiLn(xPathMethod(aType, m, pv));
 311   
       }
 312   
     }
 313   
 
 314  868
     return true;
 315   
   }
 316   
 
 317  874
   protected void doVisitAnyTypeEnd(IAnyType aType) {
 318  874
     removeIndent();
 319  874
     writeLn("}");
 320   
   }
 321   
 
 322   
   /**
 323   
    * Collects the property infos of all element declarations of this type and
 324   
    * all of its super types. Element declararations may have be removed from a
 325   
    * type be restriction. Yet, the corresponding methods must be generated in
 326   
    * the data class.
 327   
    */
 328  4059
   private void collectElementInfos(IAnyType aType, Map aMap, boolean aSuperType) {
 329  4059
     if (null != aType) {
 330  3191
       collectElementInfos(aType.getBaseType(), aMap, true);
 331  3191
       IContentModel contentModel = aType.getContentModel();
 332  3191
       for (Iterator i = contentModel.iterElements(); i.hasNext(); ) {
 333  1653
         IElemRefOrDecl e = (IElemRefOrDecl)i.next();
 334  1653
         IRef ref = e.getGlobalRef();
 335  1653
         ElementInfo ei = (ElementInfo)aMap.get(ref);
 336  1653
         if (null == ei) {
 337  1106
           ei = new ElementInfo(e);
 338  1106
           aMap.put(ref, ei);
 339   
         }
 340  1653
         IRange range = contentModel.getRange(ref);
 341  1653
         boolean isSingle = range.compareMaxOccurs(1);
 342  1653
         boolean isMultiple = range.isUnbounded() || (range.getMaxOccurs() > 1);
 343  1653
         ei.isSingle |= isSingle;
 344  1653
         ei.isMultiple |= isMultiple;
 345  1653
         ei.isInheritedSingle |= isSingle && aSuperType;
 346  1653
         ei.isInheritedMultiple |= isMultiple && aSuperType;
 347  1653
         ei.isInherited |= aSuperType;
 348   
       }
 349   
     }
 350   
   }
 351   
 
 352  7317
   protected boolean useDataClass(IDataRefOrDecl aRefOrDecl) {
 353  7317
     boolean res = false;
 354  7317
     IAttribute a = null;
 355  7317
     a = aRefOrDecl.getBindingAttribute(IBindingAttributes.USE_DATA_CLASS);
 356  7317
     if (a != null) {
 357  48
       res = a.getBoolean();
 358   
     } else {
 359  7269
       a = aRefOrDecl.getType().getDefaultedLocalBindingAttribute(IBindingAttributes.HAS_BEHAVIOUR);
 360  7269
       if (a != null) {
 361  605
         res = a.getBoolean();
 362   
       }
 363   
     }
 364  7317
     return res;
 365   
   }
 366   
 
 367   
   /**
 368   
    * Gets the property name of the decl. The first letter of the property name
 369   
    * is guaranteed to be an upper case letter.
 370   
    *
 371   
    * @param anAttrOrElem <i>(required)</i>.
 372   
    * @return <i>(required)</i>.
 373   
    */
 374  5685
   protected String propertyName(IDataRefOrDecl anAttrOrElem) {
 375  5685
     String res = anAttrOrElem.getLocalStringBindingAttribute(IBindingAttributes.NAME);
 376  5685
     if (null == res) {
 377  5685
       res = StringUtil.firstUpper(anAttrOrElem.getName());
 378   
     }
 379  5685
     return StringUtil.firstUpper(StringUtil.toJavaIdentifier(res));
 380   
   }
 381   
 
 382   
   /**
 383   
    * Gets the base attribute declaration for a reference. The base attribute
 384   
    * declaration is the attribute declaration from that base type that has no base
 385   
    * type that also has the attribute.
 386   
    */
 387  751
   private IAttrRefOrDecl getBaseAttributeDecl(IRef aRef, IAnyType aType) {
 388  751
     IAttrRefOrDecl res = null;
 389  751
     for (IAnyType t = aType; ; t = t.getBaseType()) {
 390  1991
       IAttributesModel m = t.getAttributesModel();
 391  1991
       IAttrRefOrDecl a = m.getAttrRefOrDecl(aRef);
 392  1991
       if (null == a) {
 393  751
         break;
 394   
       }
 395  1240
       res = a;
 396   
     }
 397  751
     return res;
 398   
   }
 399   
 
 400   
   //
 401   
   // Hook methods
 402   
   //
 403   
 
 404   
   protected abstract String typeComment(IAnyType aType);
 405   
   protected abstract String declaration(IAnyType aType);
 406   
   protected abstract String begin(IAnyType aType);
 407   
 
 408   
   protected abstract String elementGetter(IAnyType aType, IElemRefOrDecl aRefOrDecl, MethodVariant aPropertyVariant, boolean aUseDataClass);
 409   
   protected abstract String elementChecker(IAnyType aType, IElemRefOrDecl aRefOrDecl, MethodVariant aPropertyVariant);
 410   
   protected abstract String elementRemover(IAnyType aType, IElemRefOrDecl aRefOrDecl, MethodVariant aPropertyVariant);
 411   
   protected abstract String elementCreator(IAnyType aType, IElemRefOrDecl aRefOrDecl, MethodVariant aPropertyVariant);
 412   
   protected abstract String elementCreatorWithType(IAnyType aType, IElemRefOrDecl aRefOrDecl, MethodVariant aPropertyVariant);
 413   
   protected abstract String elementIterator(IAnyType aType, IElemRefOrDecl aRefOrDecl, MethodVariant aPropertyVariant, boolean aUseDataClass);
 414   
 
 415   
   protected abstract String attributeGetter(IAnyType aType, IAttrRefOrDecl aRefOrDecl, MethodVariant aPropertyVariant, boolean aUseDataClass);
 416   
   protected abstract String attributeChecker(IAnyType aType, IAttrRefOrDecl aRefOrDecl, MethodVariant aPropertyVariant);
 417   
   protected abstract String attributeRemover(IAnyType aType, IAttrRefOrDecl aRefOrDecl, MethodVariant aPropertyVariant);
 418   
   protected abstract String attributeSetter(IAnyType aType, IAttrRefOrDecl aRefOrDecl, MethodVariant aPropertyVariant, boolean aUseDataClass);
 419   
   protected abstract String attributeIterator(IAnyType aType, IAttrRefOrDecl aRefOrDecl, MethodVariant aPropertyVariant, boolean aUseDataClass);
 420   
 
 421   
   protected abstract String referenceGetter(IAnyType aType, RefConstraintInfo aConstraintInfo, MethodVariant aPropertyVariant);
 422   
   protected abstract String referenceIterator(IAnyType aType, RefConstraintInfo aConstraintInfo, MethodVariant aPropertyVariant);
 423   
 
 424   
   protected abstract String xPathMethod(IAnyType aType, IXPathMethod aMethod, MethodVariant aPropertyVariant);
 425   
 
 426   
   /**
 427   
    * Checks if code for methods is to be created. No method code is generated for
 428   
    * abstract data classes. Yet the abstract data class itself is to be created
 429   
    * because it may contain inner classes that are not abstract.
 430   
    *
 431   
    * @param aType <i>(required)</i>.
 432   
    * @return Returns <code>true</code> iff code for methods is to be created.
 433   
    */
 434   
   protected abstract boolean treatMethods(IAnyType aType);
 435   
 
 436   
   protected abstract boolean treatInherited();
 437   
 
 438   
   protected static class RefConstraintInfo {
 439   
 
 440   
     IReferenceConstraint referenceConstraint;
 441   
     /**
 442   
      * Key of the reference constraint. The key must be unique within the
 443   
      * type the reference constraint belongs to. The key is used by the methods
 444   
      * that are generated to access their referenced data.
 445   
      */
 446   
     String constraintKey;
 447   
     String propertyName;
 448   
     String comment;
 449   
     IAnyType dataType;
 450  16
     RefConstraintInfo(IReferenceConstraint aConstraint, String aConstraintKey, String aPropertyName, String aComment, IAnyType aDataType) {
 451  16
       referenceConstraint = aConstraint;
 452  16
       constraintKey = aConstraintKey;
 453  16
       propertyName = aPropertyName;
 454  16
       comment = aComment;
 455  16
       dataType = aDataType;
 456   
     }
 457   
   }
 458   
 
 459   
   /**
 460   
    *
 461   
    */
 462   
   private static class ElementInfo {
 463   
 
 464   
     public IElemRefOrDecl elemRefOrDecl;
 465   
     /**
 466   
      * Indicates that the element is already present in a super type.
 467   
      */
 468   
     public boolean isInherited = false;
 469   
 
 470   
     /**
 471   
      * Inidicates that the element is already present in a super type where it
 472   
      * had a maximum occurence of 1.
 473   
      */
 474   
     public boolean isInheritedSingle = false;
 475   
 
 476   
     /**
 477   
      * Indicates that the element had somewhere in the derivation hierarchy
 478   
      * a maximum occurence of 1.
 479   
      */
 480   
     public boolean isSingle = false;
 481   
 
 482   
     /**
 483   
      * Indicates that the element had somewhere in the derivation hierarchy
 484   
      * a maximum number of occurences greater than 1.
 485   
      */
 486   
     public boolean isMultiple = false;
 487   
 
 488   
     /**
 489   
      * Indicates that the element is already present in a super type with a
 490   
      * maximum number of occurences greater than 1.
 491   
      */
 492   
     public boolean isInheritedMultiple = false;
 493   
 
 494  1106
     public ElementInfo(IElemRefOrDecl anElemRefOrDecl) {
 495  1106
       elemRefOrDecl = anElemRefOrDecl;
 496   
     }
 497   
   }
 498   
 
 499  2888
   protected String simpleTypeName(IAnyType aType, boolean aUseDataClass) {
 500  2888
     String res = null;
 501  2888
     if (!aUseDataClass) {
 502  2866
       Class c = aType.getSimpleStorageType();
 503  2866
       if (null != c) {
 504  1603
         res = ReflectUtil.getTypeName(c);
 505   
       }
 506   
     }
 507  2888
     if (null == res) {
 508  1285
       res = interfaceName(aType);
 509   
     }
 510  2888
     return res;
 511   
   }
 512   
 
 513  2840
   protected String interfaceName(IAnyType aType) {
 514  2840
     return getBehaviourInterfaceCartridge().getUsableFqName(aType.getInstanceType());
 515   
   }
 516   
 
 517  452
   protected String ssoAccessor(Class aClass) {
 518   
     assert !aClass.isArray();
 519  452
     String s = aClass.getName();
 520   
     assert !(s.lastIndexOf('$') >= 0);
 521  452
     String n = s.substring(s.lastIndexOf('.') + 1);
 522  452
     StringBuffer sb = null;
 523  452
     if (aClass.isInterface() && n.startsWith("I") && Character.isUpperCase(n.charAt(1))) {
 524  32
       sb = new StringBuffer(n.substring(1));
 525   
     } else {
 526  420
       sb = new StringBuffer(n);
 527   
     }
 528  452
     sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
 529  452
     return sb.toString();
 530   
   }
 531   
 
 532  24
   protected String simpleStorageObjectTypeName(IAnyType aType) {
 533  24
     return ReflectUtil.getWrapperClass(aType.getSimpleStorageType()).getName();
 534   
   }
 535   
 
 536   
   /**
 537   
    * Get the plural form of a property name. The plural form is constructed
 538   
    * by the following rules: if the property name ends with a &quot;y&quot; and the second
 539   
    * last character is not a vowel then the
 540   
    * &quot;y&quot; is replaced by &quot;ies&quot, if the property name ends with a
 541   
    * &quot;s&quot; then &quot;es&quot; is appended, otherwise a &quot;s&quot; is appended.
 542   
    *
 543   
    * @param aPropertyName <i>(required)</i>.
 544   
    * @return <i>(required)</i>.
 545   
    */
 546  500
   protected String pluralForm(String aPropertyName) {
 547  500
     String res = null;
 548  500
     if (aPropertyName.endsWith("y") && (aPropertyName.length() > 1)) {
 549  30
       char c = aPropertyName.charAt(aPropertyName.length() - 2);
 550  30
       if ((c == 'a') || (c == 'e') || (c == 'i') || (c == 'o') || (c == 'u')) {
 551  8
         res = aPropertyName + "s";
 552   
       } else {
 553  22
         res = aPropertyName.substring(0, aPropertyName.length() - 1) + "ies";
 554   
       }
 555  470
     } else if (aPropertyName.endsWith("s")) {
 556  30
       res = aPropertyName + "es";
 557   
     } else {
 558  440
       res = aPropertyName + "s";
 559   
     }
 560  500
     return res;
 561   
   }
 562   
 
 563   
 }
 564