示例#1
0
 /**
  * This is supposed to find out, whether the given category 'cat' applied in 'this' class complies
  * to the categories of all its base classes. If at least one base class does not comply, 'false'
  * is returned. Overloaded from supertype, because we here have more comfortable data structures
  * available.
  */
 @Override
 public boolean checkSupertypes(int cat) {
   // Prepare set of base classes
   TreeSet<ClassInfoEA> bcis = new TreeSet<ClassInfoEA>();
   if (baseclassInfo != null) bcis.add(baseclassInfo);
   else if (baseclassInfoSet != null) bcis = baseclassInfoSet;
   // Consider all baseclasses in turn, break as soon as a first non-
   // compliancy is detected.
   boolean res = true;
   for (ClassInfoEA bci : bcis) {
     // Get category of base class
     int bcicat = bci.category();
     // Find out about category compliance
     if (bcicat == Options.UNKNOWN) {
       // If base class category unknown, obtain from its base classes
       res = bci.checkSupertypes(cat);
     } else if (bcicat == Options.MIXIN) {
       // Ignore mixin base class
       continue;
     } else if (bcicat != cat) {
       // Not compliant: Reject
       res = false;
     }
     // We no longer need to look, if the result is non-compliant ...
     if (!res) break;
   }
   // Trace for debugging
   if (res) document.result.addDebug(null, 10003, name(), "" + cat, "TRUE");
   else document.result.addDebug(null, 10003, name(), "" + cat, "FALSE");
   // Return, what we found out
   return res;
 } // checkSupertypes()
示例#2
0
  /**
   * This determines the particular base class of a class in the sense of ISO19136 annex D+E. Only
   * classes of categories resulting from the acknowledged stereotypes are considered. A base class
   * is selected if it has the same category as this class or category unknown. However mixin
   * classes are always ignored.
   */
  public ClassInfo baseClass() {
    // Initialize
    int stsize = 0; // # of proper base candidates
    ClassInfo cir = null; // the base result
    int cat = category(); // category of this class
    // Check if the class has one of the acknowledged categories. If not
    // no bases classes will be reported.
    if (cat == Options.FEATURE
        || cat == Options.OBJECT
        || cat == Options.DATATYPE
        || cat == Options.MIXIN
        || cat == Options.UNION) {
      // Get hold of the available base classes
      TreeSet<ClassInfoEA> baseCIs = null;
      if (baseclassInfoSet != null) baseCIs = baseclassInfoSet;
      else if (baseclassInfo != null) {
        baseCIs = new TreeSet<ClassInfoEA>();
        baseCIs.add(baseclassInfo);
      }
      // Loop over base classes and select the GML-relevant one
      if (baseCIs != null) {
        for (ClassInfoEA baseCI : baseCIs) {
          // Get base class category
          int bcat = baseCI.category();
          // Needs to compatible and not a mixin. If not so,
          // we have an error
          if ((cat == bcat || bcat == Options.UNKNOWN) && bcat != Options.MIXIN) {
            // Compatible select and count
            stsize++;
            cir = baseCI;
          } else if (bcat != Options.MIXIN) {

            // Ignore, if we accept supertypes that are not mixins and we are a mixin
            if (cat == Options.MIXIN
                && matches("rule-xsd-cls-mixin-classes-non-mixin-supertypes")) {
              // do nothing and ignore
            } else if (this.model().isInSelectedSchemas(this)) {
              // Not compatible and not mixin: An error
              MessageContext mc = document.result.addError(null, 108, name());
              if (mc != null) mc.addDetail(null, 400, "Package", pkg().fullName());
              document.result.addDebug(null, 10003, name(), "" + cat, "!FALSE");
              document.result.addDebug(null, 10003, name(), "" + bcat, "!TRUE");
            } else {
              /*
               * 2015-07-17 JE: So this is a class that violates
               * multiple inheritance rules. However, it is
               * outside the selected schemas. We could log a
               * debug, info, or even warning message. However, we
               * should not raise an error because creation of a
               * complete GenericModel that also copies ISO
               * classes would raise an error which would cause a
               * unit test to fail.
               */
            }
          }
        }
      }
      // Did we find more than one suitable base class? Which is
      // an error.
      if (stsize > 1) {

        if (this.model().isInSelectedSchemas(this)) {
          MessageContext mc = document.result.addError(null, 109, name());
          if (mc != null) mc.addDetail(null, 400, "Package", pkg().fullName());
        } else {
          /*
           * 2015-07-17 JE: So this is a class that violates multiple
           * inheritance rules. However, it is outside the selected
           * schemas. We could log a debug, info, or even warning
           * message. However, we should not raise an error because
           * creation of a complete GenericModel that also copies ISO
           * classes would raise an error which would cause a unit
           * test to fail.
           */
        }
      }
    }
    // Return, what we found
    return cir;
  } // baseClass()
示例#3
0
  // Establish class derivation hierarchy. This auxiliary initializing
  // method sets the base class relation ship obtained from the model and
  // also enters this class as subclass of all its base classes.
  // Note that invocation of this method requires that all classes in
  // the model are already cached.
  // Note: ISO19107 makes use of realization instead of generalization in some
  // cases to inherit from interfaces. Therefore realization of interfaces is
  // also considered a base class relationship as a default unless overruled
  // by
  // a parameter.
  public void establishClassDerivationHierarchy() {
    // Find out about all connectors attached to the class
    // Only do this once; cache the results for subsequent use
    if (!connectorsAccessed) {
      conns = eaClassElement.GetConnectors();
      connectorsAccessed = true;
    }

    // check that this class has connectors
    if (conns != null) {

      // Enumerate connectors selecting those where this class is the
      // client,
      // from these select "Generalization" and "Realisation". Retrieve
      // the
      // supplier class wrappers. For "Realisation" type suppliers also
      // make
      // sure the class is an interface. The classes found are registered
      // as
      // base classes. In the base classes register this class as
      // subclass.
      int nbcl = 0;
      int clientid, bclid, cat;
      String conntype;
      boolean gen, rea;
      for (Connector conn : conns) {

        // Skip all other connector types
        conntype = conn.GetType();
        gen = conntype.equals("Generalization");
        rea = conntype.equals("Realisation");

        // this.realization is determined from configuration parameters
        // if it is not null then it is false
        if (this.realization != null && !this.realization.booleanValue()) rea = false;
        if (!gen && !rea) continue;

        // Make sure we are the client of this connector
        clientid = conn.GetClientID();
        if (clientid != this.eaClassId) continue;

        // Find out about the id of the base class (=supplier)
        bclid = conn.GetSupplierID();
        // From this determine the ClassInfo wrapper object
        ClassInfoEA baseCI = document.fClassById.get(String.valueOf(bclid));
        // If such an object exists establish it as base class.
        if (baseCI != null) {
          // If we know this via a Realization we additionally check
          // we are seeing an interface.
          if (rea) {
            cat = baseCI.category();
            if (cat != Options.MIXIN) continue;
          }
          // Establish as base class. Since most classes indeed
          // possess
          // at most one base class, this case will be treated
          // somewhat
          // storage-optimized.
          if (++nbcl == 1) {
            baseclassInfo = baseCI;
          } else {
            if (baseclassInfoSet == null) {
              baseclassInfoSet = new TreeSet<ClassInfoEA>();
              baseclassInfoSet.add(baseclassInfo);
              baseclassInfo = null;
            }
            baseclassInfoSet.add(baseCI);
          }
          // Register with the subclasses of the base class.
          baseCI.subclassInfoSet.add(this);
        }
      }
    }
  } // establishClassDerivationHierarchy()