예제 #1
0
  public AssociationInfo isAssocClass() {
    // Only retrieve/compute the association once
    // Cache the result for subsequent use
    if (!isAssocClassAccessed) {

      isAssocClassAccessed = true;

      if (eaClassElement.GetSubtype() == 17 && !eaClassElement.MiscData(3).isEmpty()) {
        assoc = document.fAssociationById.get(eaClassElement.MiscData(3));
      }
    }
    return assoc;
  }
예제 #2
0
  // Validate tagged values cache, filtering on tagged values defined within
  // ShapeChange ...
  public void validateTaggedValuesCache() {
    if (taggedValuesCache == null) {
      // Fetch tagged values collection
      Collection<TaggedValue> tvs = eaClassElement.GetTaggedValues();

      // ensure that there are tagged values
      if (tvs != null) {
        // Allocate cache
        int ntvs = tvs.GetCount();
        taggedValuesCache = options().taggedValueFactory(ntvs);
        // Copy tag-value-pairs, leave out non-ShapeChange stuff and
        // normalize deprecated tags.
        for (TaggedValue tv : tvs) {
          String t = tv.GetName();
          t = document.normalizeTaggedValue(t);
          if (t != null) {
            String v = tv.GetValue();
            if (v.equals("<memo>")) v = tv.GetNotes();
            taggedValuesCache.add(t, v);
          }
        }
      } else {
        taggedValuesCache = options().taggedValueFactory(0);
      }
    }
  } // validateTaggedValuesCache()
예제 #3
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()
예제 #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()
예제 #5
0
 /** Set the tagged value for the tag given. */
 public void taggedValue(String tag, String value) {
   Collection<TaggedValue> cTV = eaClassElement.GetTaggedValues();
   TaggedValue tv = cTV.GetByName(tag);
   if (tv == null && value != null) {
     tv = cTV.AddNew(tag, value);
     tv.Update();
   } else if (tv != null) {
     if (value == null) value = "";
     if (!tv.GetValue().equals(value)) {
       tv.SetValue(value);
       tv.Update();
     }
   }
   // invalidate cache
   taggedValuesCache = null;
 } // taggedValue()
예제 #6
0
 // Validate stereotypes cache of the class. The stereotypes found are 1.
 // restricted to those defined within ShapeChange and 2. deprecated ones
 // are normalized to the lastest definitions.
 public void validateStereotypesCache() {
   if (stereotypesCache == null) {
     // Fetch stereotypes 'collection' ...
     String sts = eaClassElement.GetStereotypeEx();
     String[] stereotypes = sts.split("\\,");
     // Allocate cache
     stereotypesCache = options().stereotypesFactory();
     // Copy stereotypes found in class selecting those defined in
     // ShapeChange and normalizing deprecated ones.
     for (String stereotype : stereotypes) {
       String st = document.options.normalizeStereotype(stereotype.trim());
       if (st != null)
         for (String s : Options.classStereotypes) {
           if (st.toLowerCase().equals(s)) stereotypesCache.add(s);
         }
     }
   }
 } // validateStereotypesCache()
예제 #7
0
  /** Get alias name of the class. */
  @Override
  public String aliasName() {
    // Only retrieve/compute the alias once
    // Cache the result for subsequent use
    if (!aliasAccessed) {

      aliasAccessed = true;

      // Obtain alias name from default implementation
      String a = super.aliasName();
      // If not present, obtain from EA model directly, if ea:alias is identified as the source
      if ((a == null || a.length() == 0)
          && descriptorSource(Options.Descriptor.ALIAS.toString()).equals("ea:alias")) {
        a = eaClassElement.GetAlias();
        super.aliasName = options().internalize(a);
      }
    }
    return super.aliasName;
  } // aliasName()
예제 #8
0
 // Validate operations cache. This makes sure the operations cache contains
 // all Operations ordered by their appearance in the class.
 private void validateOperationsCache() {
   if (operationsCache == null) {
     // Allocate the cache
     operationsCache = new TreeMap<Integer, OperationInfo>();
     // Load methods ...
     Collection<Method> meths = eaClassElement.GetMethods();
     int i = 0;
     // Ensure that there are methods before continuing
     if (meths != null) {
       for (Method meth : meths) {
         // Create the operation object.
         OperationInfoEA oi = new OperationInfoEA(document, this, meth);
         // Drop in cache
         // operationsCache.put(oi.eaMethod.GetPos(), oi); <-- does
         // not work!
         operationsCache.put(++i, oi);
       }
     }
   }
 } // validateOperationsCache()
예제 #9
0
  // Establish all class associations. This is an auxiliary initializing
  // method, which retrieves all associations (EA: Connectors) known to
  // the class and creates wrapper objects for them in case they have not
  // already been encountered from the other class end. All created
  // association objects are registered. Object creation established the
  // necessary links to source and target objects and properties.
  // Note that invocation of this method requires that all classes of the
  // model are already cached.
  public void establishAssociations() {
    // Find out about associations connected 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
      boolean known;
      int id;
      String connid;

      for (Connector conn : conns) {

        // only process "Association" connectors
        String type = conn.GetType();
        if (!type.equalsIgnoreCase("Association") && !type.equalsIgnoreCase("Aggregation")) {
          continue;
        }
        // First find out whether the association has already been
        // processed from its other end. If so, discard.
        id = conn.GetConnectorID();
        connid = new Integer(id).toString();
        known = document.fAssociationById.containsKey(connid);
        if (known) continue;
        // First encounter: Create AssociationInfo wrapper and
        // properties linkage.
        AssociationInfoEA ai = new AssociationInfoEA(document, conn, id);
        // Register with global associations map, if relevant class
        // association
        if (ai.relevant) document.fAssociationById.put(connid, ai);
      }
    }
  }
예제 #10
0
  /**
   * Create new ClassInfo object
   *
   * @throws ShapeChangeAbortException
   */
  public ClassInfoEA(EADocument doc, PackageInfoEA pi, org.sparx.Element elmt)
      throws ShapeChangeAbortException {
    // Memorize document and parent package.
    document = doc;
    packageInfo = pi;
    // EA object reference. Fetch id and name.
    eaClassElement = elmt;
    eaClassId = eaClassElement.GetElementID();
    eaName = eaClassElement.GetName().trim();

    // Register as child of parent package.
    pi.childCI.add(this);

    if (options().isLoadGlobalIdentifiers()) {
      globalIdentifier =
          document.repository.GetProjectInterface().GUIDtoXML(eaClassElement.GetElementGUID());
    }

    // Determine some class flags
    isAbstract = eaClassElement.GetAbstract().equals("1");
    isLeaf = eaClassElement.GetIsLeaf();
    // Determine class category
    if (elmt.GetType().equalsIgnoreCase("enumeration")) category = Options.ENUMERATION;
    else establishCategory();

    // Cache if realisations should not be treated as generalisations
    /*
     * 2015-04-16 JE TBD: 'realisationLikeGeneralisation' should become a
     * general input parameter. Loading of the input model should not depend
     * on a specific target.
     */
    String realization =
        document.options.parameter(Options.TargetXmlSchemaClass, "realisationLikeGeneralisation");
    if (realization != null && realization.equalsIgnoreCase("false")) {
      this.realization = Boolean.FALSE;
    }
  } // ClassInfoEA Ctor
예제 #11
0
  // Validate properties cache. This makes sure the property cache contains
  // all properties ordered by their appearance in the class.
  private void validatePropertiesCache() {

    if (propertiesCache == null) {

      // Allocate the cache
      propertiesCache = new TreeMap<StructuredNumber, PropertyInfo>();

      // Load attributes ...
      Collection<Attribute> attrs = eaClassElement.GetAttributes();

      // Ensure that there are attributes before continuing
      if (attrs != null) {
        for (Attribute attr : attrs) {
          // Pick public attributes if this has been requested
          if (document.options.parameter("publicOnly").equals("true")) {
            String vis = attr.GetVisibility();
            if (!vis.equalsIgnoreCase("Public")) {
              continue;
            }
          }
          // Create the property object.
          PropertyInfoEA pi = new PropertyInfoEA(document, this, attr);
          // Check sequence number on duplicates
          PropertyInfo piTemp = propertiesCache.get(pi.sequenceNumber());
          if (piTemp != null) {
            int cat = category();
            if (cat != Options.ENUMERATION
                && cat != Options.CODELIST
                && !pi.sequenceNumber.equals(new StructuredNumber(Integer.MIN_VALUE))) {
              MessageContext mc =
                  document.result.addError(null, 107, pi.name(), name(), piTemp.name());
              if (mc != null) mc.addDetail(null, 400, "Package", pkg().fullName());
            }
          }
          // Add to properties cache
          propertiesCache.put(pi.sequenceNumber(), pi);
        }
      }

      // Load roles ...
      for (PropertyInfoEA pi : registeredRoles) {
        // Check sequence number on duplicates
        PropertyInfo piTemp = propertiesCache.get(pi.sequenceNumber());
        if (piTemp != null) {
          MessageContext mc = document.result.addError(null, 107, pi.name(), name(), piTemp.name());
          if (mc != null) mc.addDetail(null, 400, "Package", pkg().fullName());
        }
        // Add to properties cache
        propertiesCache.put(pi.sequenceNumber(), pi);
      }

      // Are there any nilReason implementation uses in the class ?
      // This is called at the end of loading all properties,
      // as there could be cases in which the order of the property
      // loading
      // matters, for example the detection of the union direct case
      // in the implementedByNilReason() method.
      for (PropertyInfo pi : propertiesCache.values()) {
        if (pi.implementedByNilReason()) hasNilReason = true;
      }
    }
  } // validatePropertiesCache()
예제 #12
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);
            }
          }
        }
      }
    }
  }
예제 #13
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()