| //------------------------------------------------------------------------------ |
| // Copyright (c) 2005, 2006 IBM Corporation and others. |
| // All rights reserved. This program and the accompanying materials |
| // are made available under the terms of the Eclipse Public License v1.0 |
| // which accompanies this distribution, and is available at |
| // http://www.eclipse.org/legal/epl-v10.html |
| // |
| // Contributors: |
| // IBM Corporation - initial implementation |
| //------------------------------------------------------------------------------ |
| package org.eclipse.epf.library.configuration; |
| |
| import java.net.URI; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Set; |
| import java.util.TreeSet; |
| |
| import org.eclipse.emf.ecore.EAttribute; |
| import org.eclipse.emf.ecore.EClass; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.EStructuralFeature; |
| import org.eclipse.epf.common.utils.ExtensionHelper; |
| import org.eclipse.epf.common.utils.StrUtil; |
| import org.eclipse.epf.library.ConfigHelperDelegate; |
| import org.eclipse.epf.library.LibraryPlugin; |
| import org.eclipse.epf.library.edit.PresentationContext; |
| import org.eclipse.epf.library.edit.util.CategorySortHelper; |
| import org.eclipse.epf.library.edit.util.SectionList; |
| import org.eclipse.epf.library.edit.util.TngUtil; |
| import org.eclipse.epf.library.util.LibraryUtil; |
| import org.eclipse.epf.library.util.ResourceHelper; |
| import org.eclipse.epf.uma.Activity; |
| import org.eclipse.epf.uma.Artifact; |
| import org.eclipse.epf.uma.CapabilityPattern; |
| import org.eclipse.epf.uma.ContentDescription; |
| import org.eclipse.epf.uma.ContentElement; |
| import org.eclipse.epf.uma.DeliveryProcess; |
| import org.eclipse.epf.uma.DescribableElement; |
| import org.eclipse.epf.uma.FulfillableElement; |
| import org.eclipse.epf.uma.MethodConfiguration; |
| import org.eclipse.epf.uma.MethodElement; |
| import org.eclipse.epf.uma.MethodPackage; |
| import org.eclipse.epf.uma.MethodPlugin; |
| import org.eclipse.epf.uma.Practice; |
| import org.eclipse.epf.uma.Role; |
| import org.eclipse.epf.uma.RoleDescriptor; |
| import org.eclipse.epf.uma.SupportingMaterial; |
| import org.eclipse.epf.uma.Task; |
| import org.eclipse.epf.uma.TaskDescriptor; |
| import org.eclipse.epf.uma.UmaPackage; |
| import org.eclipse.epf.uma.VariabilityElement; |
| import org.eclipse.epf.uma.VariabilityType; |
| import org.eclipse.epf.uma.WorkProduct; |
| import org.eclipse.epf.uma.WorkProductDescriptor; |
| import org.eclipse.epf.uma.ecore.impl.MultiResourceEObject; |
| import org.eclipse.epf.uma.ecore.util.OppositeFeature; |
| import org.eclipse.epf.uma.util.AssociationHelper; |
| |
| |
| /** |
| * @author Jinhua Xi |
| * @author Phong Nguyen Le |
| * @author Weiping Lu |
| * @since 1.0 |
| */ |
| public class ConfigurationHelper { |
| |
| private static ConfigHelperDelegate delegate; |
| |
| static { |
| ConfigHelperDelegate extendedDelegate = (ConfigHelperDelegate) ExtensionHelper |
| .getExtension(LibraryPlugin.getDefault().getId(), |
| "configHelperDelegateExt");//$NON-NLS-1$ |
| if (extendedDelegate == null) { |
| delegate = new ConfigHelperDelegate(); |
| } else { |
| delegate = extendedDelegate; |
| } |
| } |
| |
| public static ConfigHelperDelegate getDelegate() { |
| return delegate; |
| } |
| |
| private static boolean inheritingSlotFeatures = false; |
| |
| public static final String ATTRIBUTE_VALUE_SEPERATOR = "<p/>"; //$NON-NLS-1$ |
| |
| private static boolean debug = LibraryPlugin.getDefault().isDebugging(); |
| |
| /** |
| * check if the element is a ContentDescription |
| * |
| * @param element {@link MethodElement} |
| * @return boolean |
| */ |
| public static boolean isDescriptionElement(MethodElement element) { |
| if ( element == null ) { |
| return false; |
| } |
| |
| return (element instanceof ContentDescription || element.eContainer() instanceof ContentDescription); |
| |
| } |
| |
| /** |
| * check if the method pacj=kage is a global package |
| * |
| * @param pkg {@link MethodPackage} |
| * @return boolean |
| */ |
| public static boolean isGlobalPackage(MethodPackage pkg) { |
| if (pkg == null) { |
| if (debug) { |
| System.out |
| .println("ConfigurationHelper.isGlobalPackage: method package is null"); //$NON-NLS-1$ |
| } |
| return false; |
| } |
| |
| MethodPlugin p = LibraryUtil.getMethodPlugin(pkg); |
| if (p == null) { |
| if (debug) { |
| System.out |
| .println("ConfigurationHelper.isGlobalPackage: Unable to find method plug-in for " + pkg.getName() + ": " + pkg.getGuid()); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| return false; |
| } |
| |
| return getDelegate().isSystemPackage(p, pkg); |
| } |
| |
| /** |
| * check if the element is in the configuration |
| * |
| * @param element |
| * @param config |
| * @return |
| */ |
| public static boolean inConfig(MethodElement element, |
| MethodConfiguration config) { |
| return inConfig(element, config, true); |
| } |
| |
| |
| /** |
| * check if the element is in the configuration |
| * |
| * @param element |
| * @param config |
| * @return |
| */ |
| public static boolean inConfig(MethodElement element, |
| MethodConfiguration config, boolean checkSubtracted) { |
| return inConfig(element, config, checkSubtracted, true); |
| } |
| |
| /** |
| * check if the element is in the configuration |
| * |
| * @param element |
| * @param config |
| * @return |
| */ |
| public static boolean inConfig(MethodElement element, |
| MethodConfiguration config, boolean checkSubtracted, boolean checkBase) { |
| if (!isOwnerSelected(element, config, checkSubtracted)) { |
| return false; |
| } |
| |
| //Bug 207429 - Configration: Warring info should shown when deselect the replaced element |
| // for configuration closure checking, the missing base should be reported |
| // so the element been checked still treated as in config |
| // added the checkBase flag to ignore the base checking |
| // for configuration realization, this flag should be set to true |
| // so the replacer missing base is not included in the config. |
| |
| // if the element is a repalcer, and it's base element has more than one |
| // replacer |
| // none of the replacers should be included into the configuration |
| if (checkBase && (element instanceof VariabilityElement) ) { |
| VariabilityElement ve = (VariabilityElement) element; |
| if (isReplacer(ve)) { |
| VariabilityElement base = ve.getVariabilityBasedOnElement(); |
| if (inConfig(base, config)) { |
| |
| // // Invalid hotspot created for locally replaced activity in activity diagram |
| // // this is because the activity has more than one local replacers |
| // // in version 7.0, local replacement is modeled the same way as nomal replacement |
| // // we need to ignore this checking for activity |
| // if ( element instanceof Activity ) { |
| // return true; |
| // } |
| |
| for (Iterator it = AssociationHelper.getImmediateVarieties( |
| base).iterator(); it.hasNext();) { |
| VariabilityElement e = (VariabilityElement) it.next(); |
| if ((e != element) |
| && (e.getVariabilityType() == VariabilityType.REPLACES) |
| && isOwnerSelected(e, config, checkSubtracted)) { |
| if (debug) { |
| System.out |
| .println("ConfigurationHelper.inConfig: Ignoring replacing element '" + LibraryUtil.getTypeName(element) + "' since its base element has more than one replacer in the configuration"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| return false; |
| } |
| } |
| } else { |
| return false; // base must be in the configuration |
| } |
| } |
| } |
| |
| return true; |
| } |
| |
| private static boolean isOwnerSelected(MethodElement element, |
| MethodConfiguration config, boolean checkSubtracted) { |
| return getDelegate().isOwnerSelected(element, config, checkSubtracted); |
| } |
| |
| /** |
| * is the element a contributor? |
| * @param element |
| * @return boolean |
| */ |
| public static boolean isContributor(VariabilityElement element) { |
| if (element == null || element.getVariabilityBasedOnElement() == null) |
| return false; |
| |
| return element.getVariabilityType() == VariabilityType.CONTRIBUTES; |
| } |
| |
| /** |
| * is the element a replacer? |
| * @param element |
| * @return boolean |
| */ |
| public static boolean isReplacer(VariabilityElement element) { |
| if (element == null || element.getVariabilityBasedOnElement() == null) |
| return false; |
| |
| return element.getVariabilityType() == VariabilityType.REPLACES; |
| } |
| |
| /** |
| * is "b" an ancestor of "a" through a "contribute chain" relationship |
| * @param a |
| * @param b |
| * @return |
| */ |
| public static boolean contrubuteChain(VariabilityElement a, VariabilityElement b) { |
| VariabilityElement element = a; |
| while (element != null) { |
| if (element.getVariabilityType() != VariabilityType.CONTRIBUTES) { |
| return false; |
| } |
| element = element.getVariabilityBasedOnElement(); |
| if (element == null) { |
| return false; |
| } |
| if (element == b) { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| /** |
| * is the element a extend-replacer? |
| * @param element |
| * @return boolean |
| */ |
| public static boolean isExtendReplacer(VariabilityElement element) { |
| if (element == null || element.getVariabilityBasedOnElement() == null) |
| return false; |
| |
| return element.getVariabilityType() == VariabilityType.EXTENDS_REPLACES; |
| } |
| |
| /** |
| * is the element an extender? |
| * @param element |
| * @return boolean |
| */ |
| public static boolean isExtender(VariabilityElement element) { |
| if (element == null || element.getVariabilityBasedOnElement() == null) |
| return false; |
| |
| return element.getVariabilityType() == VariabilityType.EXTENDS; |
| } |
| |
| /** |
| * get the replacer of the element in the configuration. Only one replacer |
| * is allowed. If more than one replacer is found, then none of them will be |
| * returned. |
| * |
| * @param element |
| * VariabilityElement the element |
| * @param config |
| * MethodConfiguration |
| * @return VariabilityElement the replacer if there is one and ONLY one, |
| * null otherwise |
| */ |
| public static VariabilityElement getReplacer(VariabilityElement element, |
| MethodConfiguration config) { |
| VariabilityElement ve = null; |
| |
| // this will get all replacers recursively. we only need the immediate |
| // ones |
| // for(Iterator iterator = TngUtil.getGeneralizers(element, |
| // VariabilityType.REPLACES_LITERAL); iterator.hasNext();) |
| for (Iterator it = AssociationHelper.getImmediateVarieties(element) |
| .iterator(); it.hasNext();) { |
| VariabilityElement e = (VariabilityElement) it.next(); |
| if ( e == null || !inConfig(e, config) ) { |
| continue; |
| } |
| |
| VariabilityType type = e.getVariabilityType(); |
| if ( type == VariabilityType.REPLACES |
| || type == VariabilityType.EXTENDS_REPLACES) { |
| if (ve != null) { |
| if (debug) { |
| System.out |
| .println("ConfigurationHelper.getReplacer: Replacer ignored for element '" + LibraryUtil.getTypeName(element) + "' since it has more than one replacerin the configuration"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| return null; // if more than one replacer, return null |
| } |
| |
| ve = e; |
| } |
| } |
| |
| return ve; |
| } |
| |
| /** |
| * get the immediate contributors of the element within the configuration. |
| * If a contributor has immediate replacer, it is repalced with the replacer |
| * |
| * @param element |
| * @param config |
| * @return |
| */ |
| public static List getContributors(VariabilityElement element, |
| MethodConfiguration config) { |
| List items = new ArrayList(); |
| |
| if ( element == null ) { |
| return items; |
| } |
| |
| // This method get all contributors recursively, |
| // we only need the first level |
| // for (Iterator it = TngUtil.getContributors(element); it.hasNext(); ) |
| for (Iterator it = AssociationHelper.getImmediateVarieties(element) |
| .iterator(); it.hasNext();) { |
| VariabilityElement e = (VariabilityElement) it.next(); |
| if ((e != null) |
| && (e.getVariabilityType() == VariabilityType.CONTRIBUTES) |
| && inConfig(e, config)) { |
| VariabilityElement replacer = getReplacer(e, config); |
| if (replacer != null) { |
| items.add(replacer); |
| } else { |
| items.add(e); |
| } |
| } |
| } |
| |
| return items; |
| } |
| |
| public static List getExtenders(VariabilityElement element, |
| MethodConfiguration config) { |
| List items = new ArrayList(); |
| |
| if ( element == null ) { |
| return items; |
| } |
| |
| for (Iterator it = AssociationHelper.getImmediateVarieties(element) |
| .iterator(); it.hasNext();) { |
| VariabilityElement e = (VariabilityElement) it.next(); |
| if ((e != null) |
| && (e.getVariabilityType() == VariabilityType.EXTENDS) |
| && inConfig(e, config)) { |
| items.add(e); |
| } |
| } |
| |
| return items; |
| } |
| |
| public static Set<VariabilityElement> getLocalContributersAndReplacers(VariabilityElement element, |
| MethodConfiguration config) { |
| Set<VariabilityElement> items = new HashSet<VariabilityElement>(); |
| |
| if ( element == null ) { |
| return items; |
| } |
| |
| for (Iterator it = AssociationHelper.getImmediateVarieties(element) |
| .iterator(); it.hasNext();) { |
| VariabilityElement e = (VariabilityElement) it.next(); |
| if ((e != null) |
| && (isLocalContributerOrReplacer(e)) |
| && inConfig(e, config)) { |
| items.add(e); |
| } |
| } |
| |
| return items; |
| } |
| |
| private static boolean isLocalContributerOrReplacer( |
| VariabilityElement ve) { |
| VariabilityType type = ve.getVariabilityType(); |
| return type == VariabilityType.LOCAL_CONTRIBUTION |
| || type == VariabilityType.LOCAL_REPLACEMENT; |
| } |
| |
| public static boolean canShow(MethodElement element, |
| MethodConfiguration config) { |
| return canShow(element,config, true); |
| } |
| |
| |
| /** |
| * element can't show in the configuration tree if 1. the element is not in |
| * the configuration 2. the element is a contribution to another element 3. |
| * if the element is a replacer to a 3. the element has a replacement |
| * element in the configuration |
| * |
| * @param element |
| * @param config |
| * @return boolean |
| */ |
| public static boolean canShow(MethodElement element, |
| MethodConfiguration config, boolean checkSubtracted) { |
| if (element == null) { |
| return false; |
| } |
| |
| if (!inConfig(element, config, checkSubtracted)) { |
| return false; |
| } |
| |
| // // if it;s an activity, return since contributors are local contribution and needs to be shown |
| // if (element instanceof Activity) { |
| // return true; |
| // } |
| |
| // ///////////////////////////////////////////////////////////////////////////////////////////////// |
| // // this is not needed any more since the suppression state is determined by the activity adaptor factory |
| // // just leave it here for now since it does not hurt. take it away in next release |
| // |
| // NO, we still need to keep this to check the suppression of descriptors referenced by another descriptor. |
| // for example, when displaying a TD page, we need to handle the suppression of the referenced WPDs and RDs. |
| // 00395278 - Browsing TD with suppressed RD/WPD under it -- suppressed ones still showing |
| // Note: this does not handle the case when the descriptor is with an inherited activity. |
| // in that case, the suppression need to be determined by the activity path. TODO |
| Boolean supressed = element.getSuppressed(); |
| if (supressed != null && supressed.booleanValue() == true) { |
| return false; |
| } |
| // ///////////////////////////////////////////////////////////////////////////////////////////////// |
| |
| if ( element instanceof VariabilityElement) { |
| if ( !canShowByCheckingVE((VariabilityElement) element,config) ) { |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| /** |
| * |
| * @param e |
| * @param config |
| * @return |
| */ |
| public static boolean canShowByCheckingVE(VariabilityElement e, MethodConfiguration config){ |
| |
| // if this is an extender, always show, even though it extends a |
| // contributor |
| if (isExtender(e)) { |
| return true; |
| } |
| |
| if (isContributor(e) || getReplacer(e, config) != null) { |
| return false; |
| } |
| |
| // for activity, don't show the ones that contains contributors |
| // the resaon for this is to simplify the logic. |
| // assuming that user uses this activity to contribute to other activities |
| // so that part should not be involved in the navigation |
| // |
| // Jinhua Xi, 07/14/06, |
| if ( (e instanceof Activity) && hasContributor((Activity)e) ) { |
| return false; |
| } |
| |
| while ((e != null) && (isReplacer(e) || isExtendReplacer(e))) { |
| e = (VariabilityElement) e.getVariabilityBasedOnElement(); |
| if (isContributor(e)) { |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| /** |
| * get the name of the element in the configuration. 1. if it's a |
| * contributor, show the name of the base element 2. if it has a |
| * replacemenet, show the name of the replacement element |
| * |
| * @param element |
| * @param config |
| * @return String |
| */ |
| public static String getName(MethodElement element, |
| MethodConfiguration config) { |
| if (element instanceof VariabilityElement) { |
| VariabilityElement e = (VariabilityElement) element; |
| if (isContributor(e)) { |
| return getName(e.getVariabilityBasedOnElement(), config); |
| } else { |
| VariabilityElement rep = getReplacer(e, config); |
| if (rep != null) { |
| return getName(rep, config); |
| } |
| } |
| } |
| |
| return element.getName(); |
| } |
| |
| /** |
| * get the presentation name for an element in the configuration |
| * @param element |
| * @param config |
| * @return String |
| */ |
| public static String getPresentationName(MethodElement element, |
| MethodConfiguration config) { |
| |
| // [Bug 196399] P-name is not inherited from its base element in an extending element |
| String name = null; |
| |
| name = element.getPresentationName(); |
| if ( StrUtil.isBlank(name) && (element instanceof VariabilityElement) ) { |
| EStructuralFeature f = UmaPackage.eINSTANCE.getVariabilityElement_VariabilityBasedOnElement(); |
| ElementRealizer r = DefaultElementRealizer.newElementRealizer(config); |
| MethodElement me = element; |
| |
| Set<MethodElement> seens = new HashSet<MethodElement>(); |
| do { |
| VariabilityElement oldMe = (VariabilityElement) me; |
| me = (DescribableElement)ConfigurationHelper.calc01FeatureValue(me, f, r); |
| if ( me == null ) { |
| break; |
| } else if (oldMe == me) { |
| me = oldMe.getVariabilityBasedOnElement(); |
| if (me == null) { |
| break; |
| } |
| } |
| name = ((DescribableElement)me).getPresentationName(); |
| if (seens.contains(me)) { //to prevent loop in case such as |
| break; //both extend-replacer and base have empty pres name |
| } |
| seens.add(me); |
| } while ( StrUtil.isBlank(name) ); |
| } |
| |
| if ( StrUtil.isBlank(name) ) { |
| name = TngUtil.getPresentationName(element); |
| } |
| |
| return name; |
| } |
| |
| /** |
| * get the variability element owner. If the element is a |
| * VariabilityElement, return itself otherwise, find it's owner. For |
| * example, a ContentDescriotion object is ownered by a VariabilityElement |
| * |
| * @param e |
| * MethodElement |
| * @return VariabilityElement |
| */ |
| public static VariabilityElement getVariableOwner(MethodElement e) { |
| if (e instanceof VariabilityElement) { |
| return (VariabilityElement) e; |
| } else if (e instanceof ContentDescription) { |
| // return AssociationHelper.getOwner( (ContentDescription)e ); |
| EObject eObj = e.eContainer(); |
| if (eObj instanceof VariabilityElement) { |
| return (VariabilityElement) eObj; |
| } |
| } |
| |
| return null; |
| } |
| |
| /** |
| * check if the feature value is mergable or not |
| * @param feature |
| * @return boolean |
| */ |
| public static boolean isMergableAttribute(EStructuralFeature feature) { |
| if (!feature.getEType().getInstanceClassName().equals( |
| "java.lang.String")) //$NON-NLS-1$ |
| { |
| return false; |
| } |
| |
| // feature id is not globally unique, can't do a switch here |
| // compare the acture featrue instead |
| /* |
| * switch ( feature.getFeatureID() ) { case |
| * UmaPackage.METHOD_ELEMENT__GUID: case |
| * UmaPackage.METHOD_ELEMENT__NAME: |
| * Contributing a Unique ID for work product renders |
| * bad html // don't merge Unique ID: case |
| * UmaPackage.WORK_PRODUCT_DESCRIPTION__EXTERNAL_ID: return false; } |
| */ |
| |
| if (feature == UmaPackage.eINSTANCE.getMethodElement_Guid() |
| || feature == UmaPackage.eINSTANCE.getNamedElement_Name() |
| || feature == UmaPackage.eINSTANCE |
| .getContentDescription_ExternalId() |
| || feature == UmaPackage.eINSTANCE.getMethodElement_PresentationName()) { |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /** |
| * is attribute feature value? |
| * @param feature |
| * @return boolean |
| */ |
| public static boolean isAttributeFeature(EStructuralFeature feature) { |
| return (feature.getEType() instanceof EAttribute); |
| } |
| |
| /** |
| * is this a to-one feature? |
| * @param feature |
| * @return boolean |
| */ |
| public static boolean is01Feature(EStructuralFeature feature) { |
| return (feature.getEType() instanceof EClass) && !feature.isMany(); |
| } |
| |
| /** |
| * is this a to-many feature? |
| * @param feature |
| * @return boolean |
| */ |
| public static boolean is0nFeature(EStructuralFeature feature) { |
| return (feature.getEType() instanceof EClass) && feature.isMany(); |
| } |
| |
| |
| /** |
| * calculate the value of the specified element and feature |
| * |
| * @param element |
| * @param feature |
| * @param config |
| * @param values |
| * The List of values of the feature. if the feature is a 0..1 |
| * association, the List holds a single value if any for |
| * reference list feature, it's a list of references for |
| * attribute feature, it's a list of attribute values to be |
| * mergered for 0..1 association, the list may contain 1 value. |
| */ |
| // private static void calculateFeature(MethodElement element, |
| // EStructuralFeature feature, MethodConfiguration config, |
| // List values, ElementRealizer realizer) { |
| // calculateFeature(element, null, feature, config, values, realizer); |
| // } |
| |
| private static void calculateFeature(MethodElement element, |
| MethodElement OwnerElement, EStructuralFeature feature, |
| MethodConfiguration config, FeatureValue values, ElementRealizer realizer) { |
| |
| // make sure this is a valid feature |
| // for example, if an activity contributes to a Capability Pattern, |
| // some CapabilityPattern specific feature may not be a valid feature for the Activity |
| // List features = element.getInstanceProperties(); |
| List features = LibraryUtil.getStructuralFeatures(element); |
| if ( !features.contains(feature) ) { |
| return; |
| } |
| |
| // EClassifier type = feature.getEType(); |
| VariabilityElement ve = getVariableOwner((OwnerElement == null) ? element |
| : OwnerElement); |
| |
| Object value = element.eGet(feature); |
| |
| values.add(ve, value); |
| |
| if (config == null) { |
| return; |
| } |
| |
| // realize the variability relationship |
| if (ve == null) { |
| return; |
| } |
| |
| // according to Peter, the realization should be always top down. |
| // i.e realize the base first, then include the contributions |
| __mergeBase(element, ve, feature, config, values, realizer); |
| |
| if (element instanceof FulfillableElement) { |
| if (feature != UmaPackage.eINSTANCE |
| .getFulfillableElement_Fulfills()) { |
| mergeSlotFeatureValues((FulfillableElement) element, feature, |
| config, values, realizer); |
| } |
| } else if (OwnerElement instanceof FulfillableElement) { |
| mergeSlotFeatureValues(element, (FulfillableElement) OwnerElement, |
| feature, config, values, realizer); |
| } |
| |
| if (realizer != null) { |
| realizer.addExtraFeatureValues(element, feature, values); |
| } |
| |
| if (!is01Feature(feature) || (values.size() == 0) ) { |
| __mergeContributors(element, ve, feature, config, values, realizer); |
| } |
| } |
| |
| public static List<FulfillableElement> calcFulfillableElement_Fulfills(FulfillableElement element, |
| MethodConfiguration config) { |
| List<FulfillableElement> resultList = new ArrayList<FulfillableElement>(); |
| |
| ElementRealizer realizer = DefaultElementRealizer.newElementRealizer(config); |
| Object fullfillsObj = calc0nFeatureValue(element, |
| UmaPackage.eINSTANCE.getFulfillableElement_Fulfills(), |
| realizer); |
| |
| if (! (fullfillsObj instanceof List)) { |
| return resultList; |
| } |
| |
| EStructuralFeature feature = UmaPackage.eINSTANCE.getFulfillableElement_Fulfills(); |
| for (FulfillableElement slot : (List<FulfillableElement>) fullfillsObj) { |
| slot = (FulfillableElement) getCalculatedElement(slot, config); |
| if (slotMatching(slot, element, realizer)) { |
| resultList.add(slot); |
| } |
| } |
| |
| if (resultList.size() > 1) { |
| Comparator comparator = PresentationContext.INSTANCE.getPresNameComparator(); |
| Collections.<FulfillableElement>sort(resultList, comparator); |
| } |
| |
| return resultList; |
| } |
| |
| private static void mergeSlotFeatureValues(FulfillableElement element, |
| EStructuralFeature feature, MethodConfiguration config, |
| FeatureValue values, ElementRealizer realizer) { |
| if (!inheritingSlotFeatures) { |
| return; |
| } |
| |
| if (feature == UmaPackage.eINSTANCE.getFulfillableElement_Fulfills()) { |
| return; |
| } |
| if (!(element instanceof WorkProduct)) { |
| return; |
| } |
| if (values.size() > 0) { |
| return; |
| } |
| |
| List<FulfillableElement> slots = calcFulfillableElement_Fulfills(element, config); |
| |
| for (FulfillableElement slot : slots) { |
| if (slot instanceof WorkProduct) { |
| slot = (FulfillableElement) getCalculatedElement(slot, config); |
| calculateFeature(slot, null, feature, config, values, |
| realizer); |
| } |
| } |
| } |
| |
| private static void mergeSlotFeatureValues(MethodElement element, FulfillableElement OwnerElement, |
| EStructuralFeature feature, MethodConfiguration config, |
| FeatureValue values, ElementRealizer realizer) { |
| if (!inheritingSlotFeatures) { |
| return; |
| } |
| |
| if (! (element instanceof ContentDescription)) { |
| return; |
| } |
| |
| if (!(OwnerElement instanceof WorkProduct)) { |
| return; |
| } |
| if (values.size() > 0) { |
| return; |
| } |
| |
| List<FulfillableElement> slots = calcFulfillableElement_Fulfills(OwnerElement, config); |
| |
| for (FulfillableElement slot : slots) { |
| if (slot instanceof WorkProduct) { |
| slot = (FulfillableElement) getCalculatedElement(slot, config); |
| ContentDescription slotOwnedElement = slot.getPresentation(); |
| calculateFeature(slotOwnedElement, slot, feature, config, values, |
| realizer); |
| } |
| } |
| } |
| |
| private static void mergeSlotOppositeFeatureValues(FulfillableElement element, |
| OppositeFeature feature, MethodConfiguration config, |
| FeatureValue values, ElementRealizer realizer) { |
| if (!inheritingSlotFeatures) { |
| return; |
| } |
| |
| if (feature == AssociationHelper.FulFills_FullFillableElements) { |
| return; |
| } |
| |
| if (!(element instanceof WorkProduct)) { |
| return; |
| } |
| if (values.size() > 0) { |
| return; |
| } |
| |
| List<FulfillableElement> slots = calcFulfillableElement_Fulfills(element, config); |
| |
| for (FulfillableElement slot : slots) { |
| slot = (FulfillableElement) getCalculatedElement(slot, config); |
| calculateOppositeFeature(slot, feature, realizer, values); |
| } |
| } |
| |
| public static List<FulfillableElement> calcFulfills_FulfillableElement( |
| FulfillableElement slot, MethodConfiguration config) { |
| List<FulfillableElement> resultList = new ArrayList<FulfillableElement>(); |
| |
| ElementRealizer realizer = DefaultElementRealizer |
| .newElementRealizer(config); |
| |
| List fulfillingList = calc0nFeatureValue(slot, AssociationHelper.FulFills_FullFillableElements, realizer); |
| |
| for (FulfillableElement element : (List<FulfillableElement>) fulfillingList) { |
| element = (FulfillableElement) getCalculatedElement(element, config); |
| if (slotMatching(slot, element, realizer)) { |
| resultList.add(element); |
| } |
| } |
| |
| if (resultList.size() > 1) { |
| Comparator comparator = PresentationContext.INSTANCE.getPresNameComparator(); |
| Collections.<FulfillableElement>sort(resultList, comparator); |
| } |
| |
| return resultList; |
| } |
| |
| private static boolean slotMatching(FulfillableElement slot, |
| FulfillableElement element, ElementRealizer realizer) { |
| if (slot == null || !slot.getIsAbstract()) { |
| return false; |
| } |
| |
| if (realizer != null) { |
| return realizer.slotMatching(slot, element); |
| } |
| |
| return true; |
| } |
| |
| private static void __mergeBase(MethodElement element, |
| VariabilityElement ve, EStructuralFeature feature, |
| MethodConfiguration config, FeatureValue values, ElementRealizer realizer) { |
| |
| // if the element is an extended element, get the base element's |
| // properties if needed |
| boolean extendReplace = isExtendReplacer(ve) || |
| ElementRealizer.isExtendReplaceEnabled() && isReplacer(ve); |
| boolean isExtender = isExtender(ve); |
| |
| if (isExtender || extendReplace) { |
| boolean mergebase = false; |
| if (is0nFeature(feature)) { |
| mergebase = true; |
| if ( extendReplace |
| || isExtender && ElementRealizer.ignoreBaseToManyAssociations()) { |
| mergebase = (values.size() == 0); |
| } |
| } else if (is01Feature(feature)) { |
| mergebase = (values.size() == 0); |
| } else { |
| mergebase = (isMergableAttribute(feature) && (values.size() == 0)); |
| } |
| |
| if (mergebase) { |
| // Authoring: Extending a base that has been |
| // replaced, does not extend the replacement |
| // need to get the realized element, |
| // the base element might be replaced by another one, |
| // or might be a contributor to another base |
| MethodElement e = ve.getVariabilityBasedOnElement(); |
| if ( !extendReplace ) { |
| e= getCalculatedElement(e, config); |
| } |
| MethodElement o = e; |
| |
| // if it's a containment feature, such as sub-artifacts |
| // the base should not be the container |
| // 162154 - Check circular references with parent-/sub-artifacts and practices/sub-practices |
| if ( isContainmentFeature(feature) ) { |
| List containers = getContainers(ve, config); |
| if (containers.contains(e) ) { |
| mergebase = false; |
| } |
| } |
| |
| if (mergebase && (ve != e) && inConfig(e, config)) { |
| // if the current element is a description, |
| // get the the description object of the base |
| if (element instanceof ContentDescription) { |
| try { |
| e = ((DescribableElement) e).getPresentation(); |
| } catch (Exception e1) { |
| e1.printStackTrace(); |
| } |
| } |
| |
| calculateFeature(e, o, feature, config, values, realizer); |
| |
| // for extender, we need to re-sort the steps based on the |
| // extender defined order |
| if ((ve instanceof ContentElement) |
| && (feature == UmaPackage.eINSTANCE |
| .getContentDescription_Sections())) { |
| orderSections((ContentElement) ve, (List)values.getValue()); |
| } |
| } |
| } |
| } |
| |
| } |
| |
| private static void __mergeContributors(MethodElement element, |
| VariabilityElement ve, EStructuralFeature feature, |
| MethodConfiguration config, FeatureValue values, ElementRealizer realizer) { |
| boolean mergeable = true; |
| if ( isAttributeFeature(feature) && !isMergableAttribute(feature) ) { |
| mergeable = false; |
| } |
| |
| if ( mergeable ) { |
| // if the element has contributors in the configuration, get the |
| // reference properties |
| // if a contributor has replacer, it's replacer is used |
| List items = getContributors(ve, config); |
| if (items != null && items.size() > 0) { |
| for (Iterator it = items.iterator(); it.hasNext();) { |
| MethodElement e = (MethodElement) it.next(); |
| MethodElement o = e; // the owner |
| |
| // if the current element is a description, |
| // get the the description object of the contributor |
| if (element instanceof ContentDescription) { |
| e = ((DescribableElement) e).getPresentation(); |
| } |
| calculateFeature(e, o, feature, config, values, realizer); |
| } |
| } |
| } |
| |
| } |
| |
| /** |
| * calculate the reflist for the specified element and OppositeFeature |
| * |
| * @param element |
| * @param feature |
| * OppositeFeature |
| * @param realizer ElementRealizer |
| * @param values |
| * The List of values of the feature. for reference list feature, |
| * it's a list of references for attribute feature, it's a list |
| * of attribute values to be mergered |
| */ |
| private static void calculateOppositeFeature(MethodElement element, |
| OppositeFeature feature, ElementRealizer realizer, FeatureValue values) { |
| calculateOppositeFeature(element, feature, true, false, realizer, values); |
| } |
| |
| |
| /** |
| * calculate the reflist for the specified element and OppositeFeature |
| * |
| * @param element |
| * @param feature |
| * OppositeFeature |
| * @param realizer ElementRealizer |
| * @param values |
| * The List of values of the feature. for reference list feature, |
| * it's a list of references for attribute feature, it's a list |
| * of attribute values to be mergered |
| */ |
| private static void calculateOppositeFeature(MethodElement element, |
| OppositeFeature feature, boolean mergeReplacerBase, boolean mergeExtenderBase, |
| ElementRealizer realizer, FeatureValue values) { |
| // must be a MultiResourceEObject |
| if (!(element instanceof MultiResourceEObject)) { |
| return; |
| } |
| |
| MethodConfiguration config = realizer.getConfiguration(); |
| |
| VariabilityElement ve = getVariableOwner(element); |
| |
| Object value = ((MultiResourceEObject) element) |
| .getOppositeFeatureValue(feature); |
| values.add(ve, value); |
| |
| if (element instanceof VariabilityElement && config != null) { |
| VariabilityElement ce = (VariabilityElement) element; |
| |
| // if the element has contributors in the configuration, get the |
| // reference properties |
| List items = getContributors(ce, config); |
| if (items != null && items.size() > 0) { |
| for (Iterator it = items.iterator(); it.hasNext();) { |
| MethodElement e = (MethodElement) it.next(); |
| calculateOppositeFeature(e, feature, mergeReplacerBase, mergeExtenderBase, realizer, values); |
| } |
| } |
| |
| // if the element is a replacer of a base element, |
| // get the base element's properties |
| // only cover 01 or 0m references |
| // attributes can't be opposite feature |
| |
| // replaced element does not show incoming |
| // relationships |
| // imcoming relationships are represented by opposite feature |
| // so keep the references to the base element |
| |
| // Inconsistency between Published Work Product: Workload Analysis Page and Referenced Pages |
| // this is from the base of the extender. |
| // incoming associations from the base should be discarded for extenders |
| boolean mergebase = false; |
| boolean isExtender = isExtender(ce); |
| boolean isReplacer = isReplacer(ce); |
| boolean isExtendReplacer = isExtendReplacer(ce) || |
| ElementRealizer.isExtendReplaceEnabled() && isReplacer; |
| |
| // //This is a conservative fix for "Extends-replace displine rendered wrong in conf tree view" |
| // if (isExtendReplacer(ce) && realizer.getClass() == DefaultElementRealizer.class) { |
| // if (feature == AssociationHelper.Discipline_DisciplineGroupings) { |
| // isReplacer = true; |
| // } |
| // if (feature == AssociationHelper.RoleSet_RoleSetGrouppings) { |
| // isReplacer = true; |
| // } |
| // } |
| |
| // extenderReplacer behaves like replacer when realizing incoming associations |
| // Bug 199694 - Extends-Replace ignores incoming relationships of contributer |
| if ( isExtendReplacer ) { |
| isReplacer = true; |
| } |
| |
| if (isReplacer) { |
| mergebase = mergeReplacerBase && ((value instanceof List) || (values.size() == 0)); |
| } else if (isExtender) { |
| mergebase = mergeExtenderBase; |
| } |
| |
| if (mergebase) { |
| // resolve the base contributor to the base if i am not a |
| // replacer |
| // don't resolve the contributors to the base if i am a |
| // replacer, |
| // the call is coming from the base. So if resolve to base again |
| // will cause deadlock. |
| // don't resolve to the replacer since we need to carry down all |
| // the incoming 0n associations from base |
| // actually should resolve to replacer if i am not a replacer |
| // (i.e. i am an entender) |
| // this handles the senario: G2 replaces G1 and G3 extends G1 |
| ElementRealizer realizer2 = |
| DefaultElementRealizer.newElementRealizer(config, (!isReplacer), (!isReplacer)); |
| |
| MethodElement e = getCalculatedElement(ce |
| .getVariabilityBasedOnElement(), realizer2); |
| |
| // if the base element resolved to null, |
| // this is because canShow() don't allow replaced element to show. |
| // we don't want to take the risk to fix ElementRealizer |
| // so fix here since 7.0.1_ifix1, |
| // Jinhua Xi, 4/17/06 |
| if ( e == null ) { |
| e = ce.getVariabilityBasedOnElement(); |
| } |
| |
| if ((e != ce) && inConfig(e, config)) { |
| calculateOppositeFeature(e, feature, mergeReplacerBase, mergeExtenderBase, realizer, values); |
| } |
| } |
| |
| if (element instanceof FulfillableElement) { |
| mergeSlotOppositeFeatureValues((FulfillableElement) element, feature, config, values, realizer); |
| } |
| |
| } |
| } |
| |
| /** |
| * calculate the elements in the list, and returns a new list of unique |
| * elements |
| * |
| * @param elements |
| * @param config |
| * @return List |
| */ |
| public static List getCalculatedElements(List elements, |
| MethodConfiguration config) { |
| return getCalculatedElements(elements, DefaultElementRealizer.newElementRealizer(config) ); |
| } |
| |
| /** |
| * calculate the elements in the list, and returns a new list of unique |
| * elements |
| * |
| * @param elements |
| * @param realizer ElementRealizer |
| * @return List |
| */ |
| public static List getCalculatedElements(List elements, ElementRealizer realizer ) { |
| // calculate each element in the list and return a new list of elements |
| List values = new ArrayList(); |
| for (Iterator it = elements.iterator(); it.hasNext();) { |
| MethodElement e = (MethodElement) it.next(); |
| e = ConfigurationHelper.getCalculatedElement(e, realizer); |
| if ((e != null) && (!values.contains(e))) { |
| values.add(e); |
| } |
| } |
| |
| return values; |
| } |
| |
| /** |
| * calculate the element based on tle configuration. If nothing can be |
| * shown, return null. |
| * |
| * @param element |
| * @param config |
| * @return |
| */ |
| public static MethodElement getCalculatedElement(MethodElement element, |
| MethodConfiguration config) { |
| ElementRealizer realizer = DefaultElementRealizer.newElementRealizer(config, true, true); |
| |
| return getCalculatedElement(element, realizer); |
| } |
| |
| public static MethodElement getCalculatedElement(MethodElement element, |
| ElementRealizer realizer) { |
| |
| MethodElement e = element; |
| MethodElement e2; |
| while ((e2 = realizer.realize(e)) != e) { |
| e = e2; |
| } |
| return e; |
| } |
| |
| /** |
| * get the calculated 0..1 feature value of the specipied element and |
| * feature |
| * |
| * @return MethodElement |
| */ |
| public static MethodElement calc01FeatureValue(MethodElement element, |
| EStructuralFeature feature, ElementRealizer realizer) { |
| return calc01FeatureValue(element, null, feature, realizer); |
| } |
| |
| /** |
| * get the calculated 0..1 feature value of the specipied element and |
| * feature |
| * |
| * @return MethodElement |
| */ |
| public static MethodElement calc01FeatureValue(MethodElement element, MethodElement ownerElement, |
| EStructuralFeature feature, ElementRealizer realizer) { |
| // presentation object feature should never be realized. always keep |
| // it's own value |
| Object v = element.eGet(feature); |
| if (v instanceof ContentDescription) { |
| return (MethodElement) v; |
| } |
| |
| ToOneFeatureValue values = new ToOneFeatureValue(element, ownerElement, feature, realizer); |
| calculateFeature(element, ownerElement, feature, realizer.getConfiguration(), values, realizer); |
| // if (values.size() > 0) { |
| // v = (MethodElement) values.get(0); |
| // if (v instanceof MethodElement) { |
| // return getCalculatedElement((MethodElement) v, realizer.getConfiguration()); |
| // } |
| // } |
| |
| return (MethodElement)values.getValue(); |
| } |
| |
| |
| /** |
| * is this feature for containd children? such as artifact's contained artifact. |
| * @param feature |
| * @return boolean |
| */ |
| public static boolean isContainmentFeature(EStructuralFeature feature) { |
| return feature == UmaPackage.eINSTANCE.getArtifact_ContainedArtifacts() |
| || feature == UmaPackage.eINSTANCE.getPractice_SubPractices(); |
| } |
| |
| /** |
| * check if the element allow contained element |
| * @param element |
| * @return boolean |
| */ |
| public static boolean isContainmentElement(Object element) { |
| return element instanceof Artifact || element instanceof Practice; |
| } |
| |
| private static List getContainers(MethodElement element, |
| MethodConfiguration config) { |
| List items = new ArrayList(); |
| |
| EObject o = element; |
| while ((o != null) && ((o = o.eContainer()) != null) |
| && o.getClass().isInstance(element)) { |
| if (o instanceof VariabilityElement) { |
| o = getCalculatedElement((VariabilityElement) o, config); |
| } |
| |
| if ((o != null) && !items.contains(o)) { |
| items.add(o); |
| } |
| } |
| |
| return items; |
| } |
| |
| /** |
| * get the 01 opposite feature (if any) for the given feature. returns null |
| * if no such feature |
| * |
| * @param feature |
| * EStructuralFeature |
| * @return OppositeFeature the 01 opposite feature of the given feature, |
| * null if no such thing |
| */ |
| public static OppositeFeature get01OppositeFeature( |
| EStructuralFeature feature) { |
| |
| // since 1.0m4, these are not 01 feature any more |
| // if (feature == UmaPackage.eINSTANCE.getDiscipline_Tasks()) { |
| // return AssociationHelper.Task_Discipline; |
| // } else if (feature == UmaPackage.eINSTANCE.getRole_ResponsibleFor()) { |
| // return AssociationHelper.WorkProduct_ResponsibleRole; |
| // } |
| |
| // if ( feature == UmaPackage.eINSTANCE.getDomain_WorkProducts() ) { |
| // return AssociationHelper.WorkProduct_Domains; |
| // } |
| |
| return null; |
| } |
| |
| |
| /** |
| * get the target feature for the opposite feature if the target feature is a to-One feature, |
| * otherwise, return null. |
| * @param oFeature |
| * @return EStructuralFeature |
| */ |
| public static EStructuralFeature get01Feature(OppositeFeature oFeature) { |
| /* if ( oFeature == AssociationHelper.Role_Primary_Tasks |
| || oFeature == AssociationHelper.RoleDescriptor_PrimaryTaskDescriptors ) { |
| return oFeature.getTargetFeature(); |
| }*/ |
| |
| return null; |
| } |
| |
| /** |
| * get the calculated 0..n feature value of the specipied element, it's |
| * owner element and feature |
| * |
| * @param element {@link MethodElement} |
| * @param feature {@link EStructuralFeature} |
| * @param realizer {@link ElementRealizer} |
| * @return List a list of {@link MethodElement} |
| */ |
| public static List calc0nFeatureValue(MethodElement element, |
| EStructuralFeature feature, ElementRealizer realizer) |
| { |
| return calc0nFeatureValue(element, null, feature, realizer); |
| } |
| |
| /** |
| * get the calculated 0..n feature value of the specipied element and |
| * feature. if the opposite feature on the other end is a to-one feature, |
| * the feature value item can't be in the value list unless it's opposite |
| * feature value is the current element. For example, for discipline_tasks, |
| * the tasks can be selected if and ONLY if the task's task_discipline |
| * opposite feature value is the current discipline |
| * |
| * @param element MethodElement |
| * @param ownerElement {@link MethodElement} |
| * @param feature {@link EStructuralFeature} |
| * @param realizer {@link ElementRealizer} |
| * @return List a list of {@link MethodElement} |
| */ |
| public static List calc0nFeatureValue(MethodElement element, MethodElement ownerElement, |
| EStructuralFeature feature, ElementRealizer realizer) { |
| |
| List v = null; |
| MethodConfiguration config = realizer.getConfiguration(); |
| |
| // Wrong "modifies" information published in team allocation view for small configuration |
| // need to manually calculate the modify features |
| // can't rely on the uma model since that is not configuration specific. |
| // role modifies product means: |
| // role performs on tasks, and tasks produce workproducts as output |
| // so handle these scenarios as special cases |
| if ( element instanceof Role && feature == UmaPackage.eINSTANCE.getRole_Modifies() ) { |
| // List v2 = new ArrayList(); |
| // calculateOppositeFeature(element, AssociationHelper.Role_Primary_Tasks, realizer, v2); |
| // if ( v2.size() > 0 ) { |
| // for (Iterator it = v2.iterator(); it.hasNext(); ) { |
| // MethodElement e = (MethodElement)it.next(); |
| // calculateFeature(e, ownerElement, UmaPackage.eINSTANCE.getTask_Output(), config, v, realizer); |
| // } |
| // } |
| v = calcModifiedWorkProducts((Role)element, ownerElement, realizer); |
| }else if ( element instanceof RoleDescriptor && feature == UmaPackage.eINSTANCE.getRoleDescriptor_Modifies() ) { |
| // List v2 = new ArrayList(); |
| // calculateOppositeFeature(element, AssociationHelper.RoleDescriptor_PrimaryTaskDescriptors, realizer, v2); |
| // if ( v2.size() > 0 ) { |
| // for (Iterator it = v2.iterator(); it.hasNext(); ) { |
| // MethodElement e = (MethodElement)it.next(); |
| // calculateFeature(e, ownerElement, UmaPackage.eINSTANCE.getTaskDescriptor_Output(), config, v, realizer); |
| // } |
| // } |
| v = calcModifiedWorkProductDescriptors((RoleDescriptor)element, ownerElement, realizer); |
| } else { |
| ToManyFeatureValue fv = new ToManyFeatureValue(element, ownerElement, feature, realizer); |
| calculateFeature(element, ownerElement, feature, config, fv, realizer); |
| v = (List)fv.getValue(); |
| } |
| |
| List values = getCalculatedElements(v, realizer); |
| if (values.contains(element)) { |
| values.remove(element); |
| } |
| |
| // * if the opposite feature on the other end is a to-one feature, |
| // * the feature value item can't be in the value list unless it's |
| // opposite feature value is the current element. |
| // * For example, for discipline_tasks, the tasks can be selected |
| // * if and ONLY if the task's task_discipline opposite feature value is |
| // the current discipline |
| OppositeFeature of = get01OppositeFeature(feature); |
| if (of != null) { |
| int i = 0; |
| while (i < values.size()) { |
| MethodElement o = (MethodElement) values.get(i); |
| |
| // calculate it's opposite feature value, the value must be the |
| // given element |
| // otherwise, remove it |
| // note: don't use the current realizer |
| // use the default realizer since we need to realize the element in the default way |
| // 158924 - wrong categories in configuration view |
| |
| |
| // workaround to allow show/hide subtracted elements |
| ElementRealizer r = DefaultElementRealizer.newElementRealizer(config); |
| r.setShowSubtracted(realizer.showSubtracted()); |
| |
| MethodElement oo = calc01FeatureValue(o, of, r); |
| if (oo != element) { |
| values.remove(i); |
| } else { |
| i++; |
| } |
| } |
| } |
| |
| // containment feature value should not contain the owner element or its |
| // parents |
| // for example, artifact_containedArtifacts should not be the artifact |
| // itself or its parents |
| if (isContainmentFeature(feature)) { |
| List containers = getContainers(element, config); |
| int i = 0; |
| while (i < values.size()) { |
| Object o = (Object) values.get(i); |
| if (o == element || containers.contains(o)) { |
| values.remove(i); |
| } else { |
| i++; |
| } |
| } |
| } |
| |
| List returnList = realizer.realize(element, feature, values); |
| if (CategorySortHelper.needToSort(element, feature)) { |
| returnList = CategorySortHelper.sortCategoryElements(element, returnList.toArray(), true, feature); |
| } |
| |
| // the following part might not be general to all cases |
| // so put it into the realizer |
| return returnList; |
| |
| // // if the feature value is containment element such as artifact |
| // // the child element can't show if any of the parent(s) are in the list |
| // // Published site: Display of WPs under responsible role |
| // if (feature.isMany() && values.size() > 0 |
| // && isContainmentElement(values.get(0))) { |
| // int i = 0; |
| // while (i < values.size()) { |
| // MethodElement o = (MethodElement) values.get(i); |
| // |
| // // if the container of the element is in the list, remove this |
| // // element from the list |
| // if (isContainerInList(o, values, config)) { |
| // values.remove(i); |
| // } else { |
| // i++; |
| // } |
| // } |
| // } |
| // |
| // // need to sort the concept and papers by type |
| // if ((feature == UmaPackage.eINSTANCE |
| // .getContentElement_ConceptsAndPapers()) |
| // && (values.size() > 0)) { |
| // List papers = new ArrayList(); |
| // int i = 0; |
| // while (i < values.size()) { |
| // Object o = values.get(i); |
| // if (o instanceof Whitepaper) { |
| // papers.add(o); |
| // values.remove(i); |
| // } else { |
| // i++; |
| // } |
| // } |
| // |
| // if (papers.size() > 0) { |
| // values.addAll(papers); |
| // } |
| // } |
| // |
| // return values; |
| } |
| |
| /** |
| * check if the container of the element is in the list or not |
| * |
| * @param element |
| * @param items |
| * @param config |
| * @return |
| */ |
| public static boolean isContainerInList(MethodElement element, List items, |
| MethodConfiguration config) { |
| EObject o = element; |
| while ((o != null) && ((o = o.eContainer()) != null) |
| && o.getClass().isInstance(element)) { |
| if (items.contains(o)) { |
| return true; |
| } |
| |
| if (o instanceof VariabilityElement) { |
| o = getCalculatedElement((VariabilityElement) o, config); |
| } |
| |
| if ((o != null) && items.contains(o)) { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| /** |
| * get the calculated attribute feature value of the specipied element and |
| * feature |
| * |
| * @param element {@link MethodElement} |
| * @param feature {@link EStructuralFeature} |
| * @param config {@link MethodConfiguration} |
| * @return Object |
| */ |
| public static Object calcAttributeFeatureValue(MethodElement element, |
| EStructuralFeature feature, MethodConfiguration config) { |
| return calcAttributeFeatureValue(element, null, feature, config); |
| } |
| |
| /** |
| * get the calculated attribute feature value of the specipied element and |
| * feature |
| * |
| * @param element MethodElement |
| * @param ownerElement {@link MethodElement} |
| * @param feature {@link EStructuralFeature} |
| * @param config {@link MethodConfiguration} |
| * @return Object |
| */ |
| public static Object calcAttributeFeatureValue(MethodElement element, |
| MethodElement ownerElement, EStructuralFeature feature, |
| MethodConfiguration config) { |
| if (isMergableAttribute(feature)) { |
| // merge the attribute values |
| ElementRealizer realizer = DefaultElementRealizer.newElementRealizer(config); |
| AttributeFeatureValue values = new AttributeFeatureValue(element, ownerElement, feature, realizer); |
| calculateFeature(element, ownerElement, feature, config, values, |
| realizer); |
| |
| // StringBuffer buffer = new StringBuffer(); |
| // for (Iterator it = values.iterator(); it.hasNext();) { |
| // FeatureValue av = (FeatureValue) it.next(); |
| // if (av.text == null || av.text.toString().length() == 0) { |
| // continue; |
| // } |
| // |
| // if (feature == UmaPackage.eINSTANCE |
| // .getMethodElement_PresentationName()) { |
| // if (values.size() > 1) { |
| // // something wrong here, will not happen but put test |
| // // message here just in case |
| // if (debug) { |
| // System.out |
| // .println("ConfigurationHelper.calcAttributeFeatureValue: Presentation Name get more then one entry: " + LibraryUtil.getTypeName(element)); //$NON-NLS-1$ |
| // } |
| // } |
| // return av.text; |
| // } |
| // |
| // if (buffer.length() > 0) { |
| // buffer.append(ATTRIBUTE_VALUE_SEPERATOR); |
| // } |
| // |
| // if (av.element == element) { |
| // buffer.append(av.text); |
| // } else { |
| // String contentPath = ResourceHelper |
| // .getElementPath((av.element instanceof ContentDescription) ? (MethodElement) av.element |
| // .eContainer() |
| // : av.element); |
| // |
| // String backPath = ResourceHelper |
| // .getBackPath((element instanceof ContentDescription) ? ((ownerElement != null) ? ownerElement |
| // : (MethodElement) element.eContainer()) |
| // : element); |
| // |
| // buffer.append(ResourceHelper.fixContentUrlPath(av.text, |
| // contentPath, backPath)); |
| // } |
| // } |
| // |
| // return buffer.toString(); |
| |
| return values.getValue(); |
| } |
| |
| return element.eGet(feature); |
| } |
| |
| /** |
| * get the calculated 0..n opposite feature value of the specipied element |
| * and opposite feature |
| * |
| * @param element MethodElement |
| * @param feature {@link EStructuralFeature} |
| * @param realizer {@link ElementRealizer} |
| * @return List a list of {@link MethodElement} |
| */ |
| public static List calc0nFeatureValue(MethodElement element, |
| OppositeFeature feature, ElementRealizer realizer) { |
| return calc0nFeatureValue(element, feature, true, false, realizer); |
| } |
| |
| /** |
| * get the calculated 0..n opposite feature value of the specipied element |
| * and opposite feature |
| * |
| * @param element MethodElement |
| * @param ownerElement {@link MethodElement} |
| * @param feature {@link OppositeFeature} |
| * @param mergeReplacerBase boolean |
| * @param mergeExtenderBase boolean |
| * @param realizer {@link ElementRealizer} |
| * @return List a list of {@link MethodElement} |
| */ |
| public static List calc0nFeatureValue(MethodElement element, |
| OppositeFeature feature, boolean mergeReplacerBase, boolean mergeExtenderBase, ElementRealizer realizer) { |
| ToManyOppositeFeatureValue values = new ToManyOppositeFeatureValue(element, feature, realizer); |
| calculateOppositeFeature(element, feature, mergeReplacerBase, mergeExtenderBase, realizer, values); |
| return (List)values.getValue(); |
| } |
| |
| |
| |
| /** |
| * get the calculated 0..1 feature value of the specipied element and |
| * opposite feature |
| * @param element {@link MethodElement} |
| * @param feature {@link OppositeFeature} |
| * @param realizer {@link ElementRealizer} |
| * |
| * @return MethodElement |
| */ |
| public static MethodElement calc01FeatureValue(MethodElement element, |
| OppositeFeature feature, ElementRealizer realizer) { |
| ToOneOppositeFeatureValue values = new ToOneOppositeFeatureValue(element, feature, realizer); |
| calculateOppositeFeature(element, feature, realizer, values); |
| // if (values.size() > 0) { |
| // return getCalculatedElement((MethodElement) values.get(0), realizer); |
| // } |
| // |
| // return null; |
| |
| return (MethodElement)values.getValue(); |
| |
| } |
| |
| /** |
| * order the sections |
| * |
| * @param element {@link ContentElement} |
| * @param values {@link List} |
| */ |
| public static void orderSections(ContentElement element, List values) { |
| String orderingGuide = element.getOrderingGuide(); |
| if (orderingGuide == null || orderingGuide.trim().length() == 0) { |
| return; |
| } |
| SectionList slist = new SectionList(element, |
| SectionList.STEPS_FOR_ELEMENT_AND_PARENTS); |
| |
| if (isSameList(values, slist)) { |
| values.clear(); |
| values.addAll(slist); |
| return; |
| } |
| |
| // otherwise, need to reorder the list |
| OrderedListComparator comp = new OrderedListComparator(new ArrayList( |
| values), slist); |
| TreeSet s = new TreeSet(comp); |
| s.addAll(values); |
| |
| values.clear(); |
| values.addAll(s); |
| } |
| |
| private static boolean isSameList(List l1, List l2) { |
| if (l1.size() != l2.size()) { |
| return false; |
| } |
| |
| for (Iterator it = l1.iterator(); it.hasNext();) { |
| Object o = it.next(); |
| if (!l2.contains(o)) { |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| /** |
| * calculate the copyright of the element int he configuration. Rule: 1. |
| * contributors' copyright statment should be merged to the base 2. extended |
| * element inherites the copyrights from the base 3. replacer don't inherite |
| * the copyrights from the base 4. copyright elements should be unique, no |
| * duplicate entry |
| * |
| * @param element |
| * @param config |
| * @param values |
| */ |
| private static void calculateCopyright(MethodElement element, |
| MethodConfiguration config, List values) { |
| SupportingMaterial copyright = (SupportingMaterial) getCalculatedElement( |
| LibraryUtil.getCopyright(element), config); |
| if (copyright != null && !values.contains(copyright)) { |
| values.add(copyright); |
| } |
| |
| VariabilityElement ve = getVariableOwner(element); |
| if (ve == null) { |
| return; |
| } |
| |
| if (config == null) { |
| return; |
| } |
| |
| // merge copyrights of contributors |
| List items = getContributors(ve, config); |
| if (items != null && items.size() > 0) { |
| for (Iterator it = items.iterator(); it.hasNext();) { |
| MethodElement e = (MethodElement) it.next(); |
| calculateCopyright(e, config, values); |
| } |
| } |
| |
| // if the element is an extended element, get the base element's |
| // copyright |
| // the base element's copyright should appear first |
| if (isExtender(ve)) { |
| // realize the base element first. |
| MethodElement e = getCalculatedElement(ve |
| .getVariabilityBasedOnElement(), config); |
| if ((ve != e) && inConfig(e, config)) { |
| List baseItems = new ArrayList(); |
| calculateCopyright(e, config, baseItems); |
| |
| // add the base items to the begining |
| if (baseItems.size() > 0) { |
| // Authoring: Duplicate copyrights when 2 |
| // elements with the same coyright are extending each other |
| // remove the duplicate ones |
| int i = 0; |
| while (i < values.size()) { |
| if (baseItems.contains(values.get(i))) { |
| values.remove(i); |
| } else { |
| i++; |
| } |
| } |
| |
| values.addAll(0, baseItems); |
| } |
| } |
| } |
| |
| } |
| |
| /** |
| * get the copyright text |
| * |
| * @param element {@link MethodElement} |
| * @param config {@link MethodConfiguration} |
| * @return String |
| */ |
| public static String getCopyrightText(MethodElement element, |
| MethodConfiguration config) { |
| StringBuffer copyrights = new StringBuffer(); |
| List items = new ArrayList(); |
| ConfigurationHelper.calculateCopyright(element, config, items); |
| if (items.size() > 0) { |
| SupportingMaterial copyright; |
| for (Iterator it = items.iterator(); it.hasNext();) { |
| copyright = (SupportingMaterial) it.next(); |
| |
| // Contributing support material does not show |
| // up in copy right |
| // need to resolve the feature value. can't just get the value, |
| // it may have contributors |
| // String statement = |
| // copyright.getPresentation().getMainDescription(); |
| // |
| String statement = (String) calcAttributeFeatureValue(copyright |
| .getPresentation(), copyright, UmaPackage.eINSTANCE |
| .getContentDescription_MainDescription(), config); |
| if (statement != null && statement.length() > 0) { |
| // need to fix the content for relative links. |
| // since the link is a relative path to the |
| // SupportingMaterial location, |
| // need to convert to relative to the current element |
| // so re-calcuate the back path |
| // jxi, 06/28/05 |
| String contentPath = ResourceHelper |
| .getElementPath(copyright); |
| String backPath = ResourceHelper.getBackPath(element); |
| statement = ResourceHelper.fixContentUrlPath(statement, |
| contentPath, backPath); |
| |
| if (copyrights.length() > 0) { |
| copyrights.append("<p/>"); //$NON-NLS-1$ |
| } |
| copyrights.append(statement); |
| } |
| } |
| } |
| |
| return copyrights.toString(); |
| } |
| |
| /** |
| * Gets String attribute values of an activity |
| * |
| * @param e Activity or it's ContentDescription |
| * @param attrib |
| * @param config |
| * @return String |
| */ |
| public static String getActivityStringAttribute(MethodElement e, MethodElement ownerElement, |
| EAttribute attrib, MethodConfiguration config) { |
| if(!String.class.isAssignableFrom(attrib.getEAttributeType().getInstanceClass())) { |
| throw new IllegalArgumentException("The specified attribute is not of type String: " + attrib); //$NON-NLS-1$ |
| } |
| |
| Object str = null; |
| boolean isDesc; |
| VariabilityElement ve; |
| if ( e instanceof ContentDescription ) |
| { |
| ve = (VariabilityElement) e.eContainer(); |
| if ( ve == null ) { |
| ve = (VariabilityElement)ownerElement; |
| } |
| isDesc = true; |
| } |
| else if ( e instanceof VariabilityElement) |
| { |
| ve = (VariabilityElement)e; |
| isDesc = false; |
| } else { |
| str = e.eGet(attrib); |
| return (str==null) ? "" : str.toString(); //$NON-NLS-1$ |
| } |
| |
| |
| if(attrib == UmaPackage.eINSTANCE.getMethodElement_Guid() || attrib == UmaPackage.eINSTANCE.getNamedElement_Name()) { |
| return (String)e.eGet(attrib); |
| } |
| |
| VariabilityElement base = ve.getVariabilityBasedOnElement(); |
| VariabilityType variabilityType = ve.getVariabilityType(); |
| if( base != null && variabilityType == VariabilityType.LOCAL_CONTRIBUTION) { |
| // for local contribution, append the text to the base |
| Object strBase; |
| if ( isDesc ) { |
| str = ((DescribableElement)ve).getPresentation().eGet(attrib); |
| strBase = calcAttributeFeatureValue( ((DescribableElement)base).getPresentation(), base, attrib, config); |
| } else { |
| str = ve.eGet(attrib); |
| strBase = calcAttributeFeatureValue(base, null, attrib, config); |
| } |
| |
| if ( strBase != null && strBase.toString().length() > 0 ) { |
| if ( str != null && str.toString().length() > 0 ) { |
| str = strBase + ATTRIBUTE_VALUE_SEPERATOR + str; |
| } else { |
| str = strBase; |
| } |
| } |
| } else { |
| str = calcAttributeFeatureValue(e, ve, attrib, config); |
| } |
| |
| return (str==null) ? "" : str.toString(); //$NON-NLS-1$ |
| |
| // List values = new ArrayList(); |
| // VariabilityElement base; |
| // VariabilityType variabilityType; |
| // boolean concat = attrib != UmaPackage.eINSTANCE.getMethodElement_PresentationName(); |
| // while(true) { |
| // base = ve.getVariabilityBasedOnElement(); |
| // if(base == null) { |
| // Object str; |
| // if ( isDesc ) { |
| // str = ((DescribableElement)ve).getPresentation().eGet(attrib); |
| // } else { |
| // str = ve.eGet(attrib); |
| // } |
| // if(str == null || str.toString().length() == 0) { |
| // if(values.isEmpty()) { |
| // values.add(str); |
| // } |
| // } |
| // else { |
| // values.add(0, str); |
| // } |
| // break; |
| // } |
| // else if(base instanceof Activity) { |
| // Object str; |
| // if ( isDesc ) { |
| // str = ((DescribableElement)ve).getPresentation().eGet(attrib); |
| // } else { |
| // str = ve.eGet(attrib); |
| // } |
| // |
| // variabilityType = ve.getVariabilityType(); |
| // if(variabilityType == VariabilityType.EXTENDS_LITERAL) { |
| // if(str == null || str.toString().length() == 0) { |
| // // use the value of the base |
| // // |
| // ve = base; |
| // } |
| // else { |
| // values.add(0, str); |
| // break; |
| // } |
| // } |
| // else if(variabilityType == VariabilityType.LOCAL_CONTRIBUTION_LITERAL) { |
| // if(str != null && str.toString().length() > 0) { |
| // // add to the list |
| // // |
| // values.add(0, str); |
| // if(!concat) { |
| // break; |
| // } |
| // } |
| // // go to the base |
| // ve = base; |
| // } |
| // else if(variabilityType == VariabilityType.LOCAL_REPLACEMENT_LITERAL) { |
| // values.add(0, str); |
| // break; |
| // } |
| // //TODO: handle CONTRIBUTES AND REPLACES |
| // } |
| // } |
| // |
| // if ( values.size() == 0 ) { |
| // return ""; //$NON-NLS-1$ |
| // } |
| // else if ( values.size() ==1 ) { |
| // return (String)values.get(0); |
| // } |
| // else { |
| // StringBuffer buffer = new StringBuffer(); |
| // for (Iterator it = values.iterator(); it.hasNext(); ) { |
| // if ( buffer.length() > 0 ) { |
| // buffer.append(ATTRIBUTE_VALUE_SEPERATOR); |
| // } |
| // buffer.append(it.next()); |
| // } |
| // return buffer.toString(); |
| // } |
| } |
| |
| /** |
| * get all processes in the configuration |
| * |
| * @param config |
| * @return List |
| */ |
| public static List getAllProcesses(MethodConfiguration config) { |
| List processes = new ArrayList(); |
| List plugins = config.getMethodPluginSelection(); |
| for (Iterator it = plugins.iterator(); it.hasNext(); ) { |
| List items = TngUtil.getAllProcesses((MethodPlugin)it.next()); |
| for ( Iterator itp = items.iterator(); itp.hasNext(); ) { |
| org.eclipse.epf.uma.Process p = (org.eclipse.epf.uma.Process)itp.next(); |
| if ( canShow(p, config) && !processes.contains(p) ) { |
| processes.add(p); |
| } |
| } |
| } |
| |
| return processes; |
| } |
| |
| /** |
| * get all processes in the plugin and the configuration |
| * |
| * @param plugin |
| * @param config |
| * @return List |
| */ |
| public static List getAllProcesses(MethodPlugin plugin, MethodConfiguration config) { |
| List processes = new ArrayList(); |
| List items = TngUtil.getAllProcesses(plugin); |
| for ( Iterator itp = items.iterator(); itp.hasNext(); ) { |
| org.eclipse.epf.uma.Process p = (org.eclipse.epf.uma.Process)itp.next(); |
| if ( canShow(p, config) && !processes.contains(p) ) { |
| processes.add(p); |
| } |
| } |
| |
| return processes; |
| } |
| |
| /** |
| * get all delivery processes in the plugin and configuration |
| * @param plugin |
| * @param config |
| * @return List |
| */ |
| public static List getAllDeliveryProcesses(MethodPlugin plugin, MethodConfiguration config) { |
| List processes = new ArrayList(); |
| List items = TngUtil.getAllProcesses(plugin); |
| for ( Iterator itp = items.iterator(); itp.hasNext(); ) { |
| org.eclipse.epf.uma.Process p = (org.eclipse.epf.uma.Process)itp.next(); |
| if ( p instanceof DeliveryProcess ) { |
| if ( canShow(p, config) && !processes.contains(p) ) { |
| processes.add(p); |
| } |
| } |
| } |
| |
| return processes; |
| } |
| |
| /** |
| * get all CapabilityPatterns in the plugin and configuration |
| * |
| * @param plugin |
| * @param config |
| * @return List |
| */ |
| public static List getAllCapabilityPatterns(MethodPlugin plugin, MethodConfiguration config) { |
| List processes = new ArrayList(); |
| List items = TngUtil.getAllProcesses(plugin); |
| for ( Iterator itp = items.iterator(); itp.hasNext(); ) { |
| org.eclipse.epf.uma.Process p = (org.eclipse.epf.uma.Process)itp.next(); |
| if ( p instanceof CapabilityPattern ) { |
| if ( canShow(p, config) && !processes.contains(p) ) { |
| processes.add(p); |
| } |
| } |
| } |
| |
| return processes; |
| } |
| |
| /** |
| * calculate the work products modified by the specified role, in the configuration |
| * |
| * @param element Role |
| * @param ownerElement MethodElement the owner to accept the calculated value |
| * @param realizer |
| * @return List list of work products being modified by the role |
| */ |
| public static List calcModifiedWorkProducts(Role element, MethodElement ownerElement, ElementRealizer realizer) { |
| List v = new ArrayList(); |
| OppositeFeature ofeature = AssociationHelper.Role_Primary_Tasks; |
| ToManyOppositeFeatureValue fv2 = new ToManyOppositeFeatureValue(element, ofeature, realizer); |
| calculateOppositeFeature(element, ofeature, realizer, fv2); |
| if ( fv2.size() > 0 ) { |
| List v2 = (List)fv2.getValue(); |
| EStructuralFeature feature = UmaPackage.eINSTANCE.getTask_Output(); |
| for (Iterator it = v2.iterator(); it.hasNext(); ) { |
| MethodElement e = (MethodElement)it.next(); |
| ToManyFeatureValue fv = new ToManyFeatureValue(element, ownerElement, feature, realizer); |
| ((List)fv.getValue()).addAll(v); |
| |
| calculateFeature(e, ownerElement, |
| feature, |
| realizer.getConfiguration(), fv, realizer); |
| v = (List)fv.getValue(); |
| } |
| } |
| |
| return v; |
| } |
| |
| /** |
| * calculate the work product descriptors modified by the specified role descriptor, in the configuration |
| * |
| * @param element RoleDescriptor |
| * @param ownerElement MethodElement the owner to accept the calculated value |
| * @param realizer |
| * @return List list of work product descriptors being modified by the role descriptor |
| * @deprecated use the RoleDescriptorLayout to calculate the feature value |
| */ |
| public static List calcModifiedWorkProductDescriptors(RoleDescriptor element, MethodElement ownerElement, ElementRealizer realizer) { |
| List v = new ArrayList(); |
| OppositeFeature ofeature = AssociationHelper.RoleDescriptor_PrimaryTaskDescriptors; |
| ToManyOppositeFeatureValue fv2 = new ToManyOppositeFeatureValue(element, ofeature, realizer); |
| calculateOppositeFeature(element, ofeature, realizer, fv2); |
| if ( fv2.size() > 0 ) { |
| List v2 = (List)fv2.getValue(); |
| EStructuralFeature feature = UmaPackage.eINSTANCE.getTaskDescriptor_Output(); |
| for (Iterator it = v2.iterator(); it.hasNext(); ) { |
| MethodElement e = (MethodElement)it.next(); |
| |
| ToManyFeatureValue fv = new ToManyFeatureValue(element, ownerElement, feature, realizer); |
| ((List)fv.getValue()).addAll(v); |
| |
| calculateFeature(e, ownerElement, |
| feature, |
| realizer.getConfiguration(), fv, realizer); |
| v = (List)fv.getValue(); |
| } |
| } |
| |
| return v; |
| } |
| |
| /** |
| * calculate the roles that modifies the specified work product in the configuration |
| * @param element WorkProduct |
| * @param realizer |
| * @return List the roles |
| */ |
| public static List calcModifyRoles(WorkProduct element, ElementRealizer realizer) { |
| List tasks = ConfigurationHelper.calc0nFeatureValue( |
| element, |
| AssociationHelper.WorkProduct_OutputFrom_Tasks, |
| realizer); |
| List modifyRoles = new ArrayList(); |
| for (Iterator it = tasks.iterator(); it.hasNext(); ) { |
| Task t = (Task)it.next(); |
| List<Role> rList = (List<Role>)ConfigurationHelper.calc0nFeatureValue( |
| t, |
| UmaPackage.eINSTANCE.getTask_PerformedBy(), |
| realizer); |
| for (Role r: rList) { |
| if ( (r != null) && !modifyRoles.contains(r) ) { |
| modifyRoles.add(r); |
| } |
| } |
| } |
| |
| return modifyRoles; |
| } |
| |
| /** |
| * calculate the role descriptors that modifies the specified work product descriptor in the configuration |
| * @param element WorkProductDescriptor |
| * @param realizer |
| * @return List the role descriptors |
| * @deprecated use the WorkProductDescriptorlayout to calculate the feature value |
| */ |
| public static List calcModifyRoleDescriptors(WorkProductDescriptor element, ElementRealizer realizer) { |
| List taskDescriptors = ConfigurationHelper.calc0nFeatureValue( |
| element, |
| AssociationHelper.WorkProductDescriptor_OutputFrom_TaskDescriptors, |
| realizer); |
| List modifyRoles = new ArrayList(); |
| for (Iterator it = taskDescriptors.iterator(); it.hasNext(); ) { |
| TaskDescriptor t = (TaskDescriptor)it.next(); |
| RoleDescriptor r = (RoleDescriptor)ConfigurationHelper.calc01FeatureValue( |
| t, |
| UmaPackage.eINSTANCE.getTaskDescriptor_PerformedPrimarilyBy(), |
| realizer); |
| if ( (r != null) && !modifyRoles.contains(r) ) { |
| modifyRoles.add(r); |
| } |
| } |
| |
| return modifyRoles; |
| } |
| |
| /** |
| * check if the activity is a contributor |
| * or contains any sub-activities that are contributors |
| * @param element Activity |
| * @return boolean |
| */ |
| public static boolean hasContributor(Activity element) { |
| if ( isContributor(element)) { |
| return true; |
| } |
| |
| for ( Iterator it = element.getBreakdownElements().iterator(); it.hasNext(); ) { |
| Object o = it.next(); |
| if ( !(o instanceof Activity) ) { |
| continue; |
| } |
| |
| if ( hasContributor( (Activity)o ) ) { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| /** |
| * get the base processes for an {@link Activity} in the Configuration |
| * @param element |
| * @param config |
| * @return List |
| */ |
| public static List getBaseProcesses(Activity element, MethodConfiguration config) { |
| List value = new ArrayList(); |
| getBaseProcesses(element, config, value); |
| return value; |
| } |
| |
| /** |
| * get all base processes for an activity in the configuration |
| * @param element |
| * @param config |
| * @param value List the bases processes |
| */ |
| public static void getBaseProcesses(Activity element, MethodConfiguration config, List value) { |
| |
| // get it's own base |
| if ( ConfigurationHelper.isExtender(element) ) { |
| Activity base = (Activity)element.getVariabilityBasedOnElement(); |
| if ( base != null |
| && !value.contains(base) |
| && (base instanceof org.eclipse.epf.uma.Process) ) { |
| if ( canShow(base, config) ) { |
| value.add(base); |
| } |
| getBaseProcesses(base, config, value); |
| } |
| } |
| |
| // if the sub-activities have base, process it |
| for ( Iterator it = element.getBreakdownElements().iterator(); it.hasNext(); ) { |
| Object o = it.next(); |
| if ( o instanceof Activity ) { |
| getBaseProcesses((Activity)o, config, value); |
| } |
| } |
| } |
| |
| public static URI getInheritingUri(DescribableElement obj, URI uri, |
| VariabilityElement[] uriInheritingBases, MethodConfiguration config, int uriType) { |
| VariabilityElement ve = (VariabilityElement) obj; |
| VariabilityElement base = ve.getVariabilityBasedOnElement(); |
| if (base != null |
| && (ve.getVariabilityType() == VariabilityType.EXTENDS || ve |
| .getVariabilityType() == VariabilityType.EXTENDS_REPLACES)) { |
| base = (VariabilityElement) ConfigurationHelper.getCalculatedElement(base, config); |
| if (base != null) { |
| if (uriType == 0) { |
| uri = ((DescribableElement) base).getNodeicon(); |
| } else if (uriType == 1) { |
| uri = ((DescribableElement) base).getShapeicon(); |
| } |
| if (uri != null) { |
| uriInheritingBases[0] = base; |
| } |
| } |
| } |
| return uri; |
| } |
| } |