Example #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()
Example #2
0
 /**
  * Find the operation identified by its name and the types of its parameters in this class or (if
  * not present there) recursively in its base classes.
  */
 public OperationInfo operation(String name, String[] types) {
   // Make sure operations are loaded
   validateOperationsCache();
   // Search in the class itself
   search_operation:
   for (OperationInfo oi : operationsCache.values()) {
     if (oi.name().equals(name)) {
       // Success if types shall not be compared
       if (types == null) return oi;
       // Check number of parameters
       if (types.length != oi.parameterCount()) continue;
       // Check type strings
       SortedMap<Integer, String> ptypes = oi.parameterTypes();
       for (int i = 0; i < types.length; i++) {
         if (types[i].equals("*")) continue;
         if (!ptypes.get(i + 1).equals(types[i])) continue search_operation;
       }
       // All types found matching
       return oi;
     }
   }
   // Go and search in base classes
   TreeSet<ClassInfoEA> bcis = new TreeSet<ClassInfoEA>();
   if (baseclassInfo != null) bcis.add(baseclassInfo);
   else if (baseclassInfoSet != null) bcis = baseclassInfoSet;
   for (ClassInfoEA bci : bcis) {
     OperationInfo oi = bci.operation(name, types);
     if (oi != null) return oi;
   }
   return null;
 }
Example #3
0
 /** @see de.interactive_instruments.ShapeChange.Model.ClassInfo#supertypes() */
 public SortedSet<String> supertypes() {
   // Convert base class object set to base class id set.
   SortedSet<String> baseids = new TreeSet<String>();
   if (baseclassInfo != null) baseids.add(baseclassInfo.id());
   else if (baseclassInfoSet != null)
     for (ClassInfoEA bci : baseclassInfoSet) baseids.add(bci.id());
   return baseids;
 } // supertypes()
Example #4
0
  /** @return set of ids of classes this class depends on */
  protected TreeSet<String> supplierIds() {

    // Only retrieve/compute supplierIds once
    // Cache the results for subsequent use
    if (supplierIds == null) {

      // Prepare set to return
      supplierIds = new TreeSet<String>();
      // Ask EA for the connectors attached to the package object and loop
      // over the connectors returned
      // Only compute them once for the whole class
      if (!connectorsAccessed) {
        conns = eaClassElement.GetConnectors();
        connectorsAccessed = true;
      }
      // Ensure that there are connectors before continuing
      if (conns != null) {
        for (Connector conn : conns) {
          // Single out dependency connectors
          String type = conn.GetType();
          if (type.equals("Dependency")) {
            // From the dependency grab the id of the supplier
            int suppId = conn.GetSupplierID();
            String suppIdS = Integer.toString(suppId);
            // Since all connectors are delivered from both objects
            // at the
            // connector ends, we have to make sure it is not
            // accidently us,
            // which we found.
            if (suppId == eaClassId) continue;
            // Now, this is an element id, not a package id. So we
            // have to
            // identify the package, which owns the element
            // addressed.
            ClassInfoEA suppClass = (ClassInfoEA) document.fClassById.get(suppIdS);

            if (suppClass != null) {
              // From this only the id is required
              String suppPackId = suppClass.id();
              if (suppPackId != null) supplierIds.add(suppPackId);

            } else {
              // package of supplier class has not been loaded,
              // dismiss the supplier
            }
          }
        }
      }
    }
    return supplierIds;
  } // supplierIds()
Example #5
0
 /** @see de.interactive_instruments.ShapeChange.Model.ClassInfo#property(java.lang.String) */
 public PropertyInfo property(String name) {
   // Search in own properties
   validatePropertiesCache();
   for (PropertyInfo pi : propertiesCache.values()) {
     if (pi.name().equals(name)) return pi;
   }
   // Go and search in base classes
   TreeSet<ClassInfoEA> bcis = new TreeSet<ClassInfoEA>();
   if (baseclassInfo != null) bcis.add(baseclassInfo);
   else if (baseclassInfoSet != null) bcis = baseclassInfoSet;
   for (ClassInfoEA bci : bcis) {
     PropertyInfo pi = bci.property(name);
     if (pi != null) return pi;
   }
   return null;
 } // property()
Example #6
0
  /**
   * Return the documentation attached to the property object. This is fetched from tagged values
   * and - if this is absent - from the 'notes' specific to the EA objects model.
   */
  @Override
  public String documentation() {

    // Retrieve/compute the documentation only once
    // Cache the result for subsequent use
    if (!documentationAccessed) {

      documentationAccessed = true;

      // Try default first
      String s = super.documentation();

      // Try EA notes, if both tagged values fail and ea:notes is the source
      if ((s == null || s.length() == 0)
          && descriptorSource(Options.Descriptor.DOCUMENTATION.toString()).equals("ea:notes")) {
        s = eaClassElement.GetNotes();
        // Fix for EA7.5 bug
        if (s != null) {
          s = EADocument.removeSpuriousEA75EntitiesFromStrings(s);
          super.documentation = options().internalize(s);
        }
      }

      // If result is empty, check if we can get the documentation from a
      // dependency
      if (s == null || s.isEmpty()) {
        for (Iterator<String> i = this.supplierIds().iterator(); i.hasNext(); ) {
          String cid = i.next();
          ClassInfoEA cix = document.fClassById.get(cid);
          if (cix != null) {
            if (cix.name().equalsIgnoreCase(this.name()) && cix.stereotype("featureconcept")) {
              s = cix.documentation();
              break;
            }
          }
        }
      }

      // If result is empty, check if we can get the documentation from a
      // supertype with the same name (added for ELF/INSPIRE)
      if (s == null || s.isEmpty()) {
        HashSet<ClassInfoEA> sts = supertypesAsClassInfoEA();
        if (sts != null) {
          for (ClassInfoEA stci : sts) {
            if (stci.name().equals(this.name())) {
              s = stci.documentation();
              break;
            }
          }
        }
      }

      // Assign what we got or "" ...
      super.documentation = options().internalize(s != null ? s : "");
    }
    return super.documentation;
  } // documentation()
Example #7
0
  // Validate constraints cache. This makes sure the constraints cache
  // contains all constraints ordered by their appearance in the class.
  // If constraints are disabled the cache is empty.
  private void validateConstraintsCache() {
    if (constraintsCache == null) {
      // Allocate cache
      constraintsCache = new Vector<Constraint>();
      // Constraints disabled?
      String check = document.options.parameter("checkingConstraints");
      if (check != null && check.equalsIgnoreCase("disabled")) return;

      // Constraints for this class category irrelevant?
      if (!document.options.isClassTypeToCreateConstraintsFor(category())) return;

      // Constraints from selected schemas only?
      if (document.options.isLoadConstraintsForSelectedSchemasOnly()
          && !document.isInSelectedSchemas(this)) {
        return;
      }

      // Filter map for inheritance and overriding by name
      HashMap<String, Constraint> namefilter = new HashMap<String, Constraint>();
      // Access EA constraints data
      Collection<org.sparx.Constraint> constrs = eaClassElement.GetConstraints();
      // Determine constraint types to be parsed as OCL
      String oclTypes = document.options.parameter("oclConstraintTypeRegex");
      // Determine constraint types to be parsed as FOL
      String folTypes = document.options.parameter("folConstraintTypeRegex");
      // Enumerate all constraints found
      // Ensure that there are constraints before continuing
      if (constrs != null) {
        for (org.sparx.Constraint constr : constrs) {
          // Wrap into constraint object
          String type = constr.GetType();
          Constraint oc;
          if (oclTypes.length() > 0 && type.matches(oclTypes)) {
            // 100422/re removed: &&
            // !encodingRule("xsd").equals(Options.ISO19136_2007_INSPIRE)
            OclConstraintEA ocl = new OclConstraintEA(document, this, constr);
            if (ocl.syntaxTree() == null)
              // Text constraint is a fallback in case of parsing
              // issues
              oc = new TextConstraintEA(document, this, constr);
            else oc = ocl;

          } else if (folTypes != null && folTypes.length() > 0 && type.matches(folTypes)) {

            /*
             * only sets up the textual information; parsing is done
             * during model postprocessing - see
             * ModelImpl.postprocessFolConstraints()
             */
            oc = new FolConstraintEA(document, this, constr);

          } else {
            oc = new TextConstraintEA(document, this, constr);
          }
          // Collect in cache
          constraintsCache.add(oc);
          // If the constraint has a name, add it to the filter which
          // blocks inheritance of constraints
          String conam = oc.name();
          if (conam != null && conam.length() > 0) namefilter.put(conam, oc);
        }
      }

      /*
       * Fetch constraints from super-classes. Override by name.
       */

      /*
       * JE: replaced this code with code (see below) that directly
       * accesses the supertype objects, instead of first getting all
       * their IDs and then looking the objects up in the model.
       */

      // HashSet<String> stids = supertypes();
      // if (stids != null) {
      // for (String stid : stids) {
      // ClassInfo stci = model().classById(stid);
      // Vector<Constraint> stcos = null;
      // if (stci != null)
      // stcos = stci.constraints();
      // if (stcos != null) {
      // for (Constraint stco : stcos) {
      // String nam = stco == null ? null : stco.name();
      // if(nam!=null && nam.length()>0 && namefilter.containsKey(nam))
      // continue;
      // constraintsCache.add(stco);
      // }
      // }
      // }
      // }
      HashSet<ClassInfoEA> sts = supertypesAsClassInfoEA();
      if (sts != null) {
        for (ClassInfoEA stci : sts) {
          Vector<Constraint> stcos = null;
          if (stci != null) stcos = stci.constraints();
          if (stcos != null) {
            for (Constraint stco : stcos) {
              String nam = stco == null ? null : stco.name();
              if (nam != null && nam.length() > 0 && namefilter.containsKey(nam)) continue;

              // Is the context of stco still the supertype, or
              // should it not be this (ClassInfoEA)?
              constraintsCache.add(stco);
            }
          }
        }
      }
    }
  }
Example #8
0
 /** Provide the ids of all subclasses of this class. */
 public SortedSet<String> subtypes() {
   // Convert subclass object set to subclass id set.
   SortedSet<String> subids = new TreeSet<String>();
   for (ClassInfoEA sci : subclassInfoSet) subids.add(sci.id());
   return subids;
 } // subtypes()
Example #9
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()
Example #10
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()