blob: 1d4959a5dd631f664ca953fa51b0c0f8159f17a7 [file] [log] [blame]
package org.eclipse.epf.library.realization.impl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.epf.library.LibraryPlugin;
import org.eclipse.epf.library.configuration.ConfigurationHelper;
import org.eclipse.epf.library.configuration.DefaultElementRealizer;
import org.eclipse.epf.library.configuration.ElementRealizer;
import org.eclipse.epf.library.edit.realization.IRealizedDescriptor;
import org.eclipse.epf.library.edit.realization.IRealizedElement;
import org.eclipse.epf.library.edit.util.DescriptorPropUtil;
import org.eclipse.epf.library.edit.util.LibraryEditUtil;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.ContentElement;
import org.eclipse.epf.uma.Descriptor;
import org.eclipse.epf.uma.Guidance;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.RoleDescriptor;
import org.eclipse.epf.uma.TaskDescriptor;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.WorkProductDescriptor;
import org.eclipse.epf.uma.ecore.util.OppositeFeature;
public class RealizedDescriptor extends RealizedElement implements
IRealizedDescriptor, IRealizedElement {
private static Set<EStructuralFeature> featureSet = new HashSet<EStructuralFeature>();
private static Map<EStructuralFeature, EStructuralFeature> contentFeatureMap = new HashMap<EStructuralFeature, EStructuralFeature>();
static {
UmaPackage up = UmaPackage.eINSTANCE;
featureSet.add(up.getNamedElement_Name());
featureSet.add(up.getMethodElement_PresentationName());
featureSet.add(up.getMethodElement_BriefDescription());
contentFeatureMap.put(up.getDescriptorDescription_RefinedDescription(),
up.getContentDescription_MainDescription());
contentFeatureMap.put(up.getContentDescription_KeyConsiderations(), up
.getContentDescription_KeyConsiderations());
}
public RealizedDescriptor(Descriptor descriptor) {
super(descriptor);
}
public boolean handleFeature(EStructuralFeature feature) {
return featureSet.contains(feature);
}
private Object getContentFeatureValue(EStructuralFeature feature) {
EStructuralFeature elementFeature = contentFeatureMap.get(feature);
if (elementFeature != null) {
Object value = null;
if (getDescriptor().getPresentation() != null) {
value = getDescriptor().getPresentation().eGet(feature);
}
if (getLinkedElement() == null || getLinkedElement().getPresentation() == null) {
return value;
}
DescriptorPropUtil propUtil = DescriptorPropUtil.getDesciptorPropUtil();
if (propUtil.isValueReplaced(feature, getDescriptor())) {
return value;
}
Descriptor greenParent = propUtil.getGreenParentDescriptor(getDescriptor());
Object linkedValue;
if (greenParent == null) {
linkedValue = ConfigurationHelper.calcAttributeFeatureValue(
getLinkedElement().getPresentation(), elementFeature, getConfig());
} else {
linkedValue = greenParent.getPresentation().eGet(feature);
}
if (linkedValue == null && value != null || linkedValue != null && !linkedValue.equals(value)) {
getDescriptor().getPresentation().eSet(feature, linkedValue);
}
return linkedValue;
}
throw new UnsupportedOperationException();
}
public Object getFeatureValue(EStructuralFeature feature) {
if (contentFeatureMap.containsKey(feature)) {
return getContentFeatureValue(feature);
}
if (! featureSet.contains(feature)) {
return super.getFeatureValue(feature);
}
if (feature instanceof EAttribute) {
Object value = getDescriptor().eGet(feature);
if (getLinkedElement() == null) {
return value;
}
DescriptorPropUtil propUtil = DescriptorPropUtil.getDesciptorPropUtil();
if (propUtil.isValueReplaced(feature, getDescriptor())) {
return value;
}
Descriptor greenParent = propUtil.getGreenParentDescriptor(getDescriptor());
Object linkedValue;
if (greenParent == null) {
linkedValue = calcAttributeFeatureValue(getLinkedElement(), feature, getConfig());
} else {
linkedValue = greenParent.eGet(feature);
}
if (linkedValue == null && value != null || linkedValue != null && !linkedValue.equals(value)) {
getDescriptor().eSet(feature, linkedValue);
}
return linkedValue;
}
return super.getFeatureValue(feature);
}
private Object calcAttributeFeatureValue(MethodElement linkedElement,
EStructuralFeature feature, MethodConfiguration config) {
if (feature == UmaPackage.eINSTANCE.getMethodElement_PresentationName()) {
return ConfigurationHelper.getPresentationName(linkedElement, config);
}
return ConfigurationHelper.calcAttributeFeatureValue(
getLinkedElement(), feature, getConfig());
}
public Object getOFeatureValue(OppositeFeature ofeature) {
return super.getOFeatureValue(ofeature);
}
protected ContentElement getLinkedElement() {
MethodElement element = getRawLinkedElement();
if (element == null) {
return null;
}
return (ContentElement) ConfigurationHelper.getCalculatedElement(element, getConfig());
}
protected MethodElement getRawLinkedElement() {
throw new UnsupportedOperationException();
}
protected Descriptor getDescriptor() {
return (Descriptor) getElement();
}
protected List<? extends Descriptor> getDescriptorList(EReference elementFeature,
EReference[] descriptorFeatures) {
ElementRealizer realizer = DefaultElementRealizer
.newElementRealizer(getConfig());
EReference dFeature = descriptorFeatures[0];
EReference dFeatureExclude = descriptorFeatures[1];
MethodElement element = getLinkedElement();
if (element == null) {
return ConfigurationHelper.calc0nFeatureValue(getDescriptor(),
dFeature, realizer);
}
List<MethodElement> elementList = ConfigurationHelper.calc0nFeatureValue(element,
elementFeature, realizer);
List<Descriptor> resultDescriptorList = new ArrayList<Descriptor>();
EReference eRef = LibraryEditUtil.getInstance().getExcludeFeature(
dFeature);
Set<MethodElement> excludeElements = this.getExcludeOrAddtionalRefSet(
getDescriptor(), eRef, realizer);
Set<MethodElement> elementSet = new LinkedHashSet<MethodElement>();
if (elementList != null) {
for (MethodElement elem : elementList) {
if (!excludeElements.contains(elem)) {
elementSet.add(elem);
}
}
}
DescriptorPropUtil propUtil = DescriptorPropUtil.getDesciptorPropUtil();
Set<Descriptor> localUsedDescriptors = propUtil.getLocalUsedDescriptors(getDescriptor(), dFeature);
if (! localUsedDescriptors.isEmpty()) {
for (Descriptor des : localUsedDescriptors) {
MethodElement localUseElement = getLinkedElement(des);
if (localUseElement != null) {
localUseElement = ConfigurationHelper.getCalculatedElement(localUseElement, getConfig());
if (localUseElement != null && !excludeElements.contains(localUseElement)) {
elementSet.add(localUseElement);
}
}
}
}
List<Descriptor> descriptorList = ConfigurationHelper.calc0nFeatureValue(
getDescriptor(), dFeature, realizer);
for (Descriptor des : descriptorList) {
MethodElement me = getLinkedElement(des);
if (me == null || propUtil.localUse(des, getDescriptor(), dFeature)) {
resultDescriptorList.add(des);
if (me != null) {
elementSet.remove(me);
}
} else if (elementSet.contains(me)) {
resultDescriptorList.add(des);
elementSet.remove(me);
}
}
if (elementSet.isEmpty()) {
return processResultDescriptorList(resultDescriptorList, dFeature);
}
Activity parentAct = getDescriptor().getSuperActivities();
if (parentAct == null) {
return processResultDescriptorList(resultDescriptorList, dFeature);
}
for (MethodElement me : elementSet) {
Descriptor des = (Descriptor) getMgr().getDescriptor(
getDescriptor(), parentAct, me, dFeature);
resultDescriptorList.add(des);
}
return processResultDescriptorList(resultDescriptorList, dFeature);
}
private List<Descriptor> processResultDescriptorList(
List<Descriptor> resultDescriptorList, EReference dFeature) {
if (dFeature.isMany()) {
List<Descriptor> listValue = (List<Descriptor>) getDescriptor().eGet(
dFeature);
if (listValue != null && !listValue.isEmpty()) {
Set<Descriptor> resultSet = new HashSet<Descriptor>(
resultDescriptorList);
LibraryEditUtil libEditUtil = LibraryEditUtil.getInstance();
boolean oldDeliver = getDescriptor().eDeliver();
getDescriptor().eSetDeliver(false);
try {
for (int i = listValue.size() - 1; i >= 0; i--) {
Descriptor des = listValue.get(i);
if (!resultSet.contains(des)) {
listValue.remove(i);
libEditUtil.removeOppositeFeature(getDescriptor(), des, dFeature);
}
}
} finally {
getDescriptor().eSetDeliver(oldDeliver);
}
}
}
return resultDescriptorList;
}
private MethodElement getLinkedElement(Descriptor des) {
MethodElement element = DescriptorPropUtil.getDesciptorPropUtil().getLinkedElement(des);
if (element == null) {
return null;
}
return ConfigurationHelper.getCalculatedElement(element, getConfig());
}
public Set<Descriptor> updateAndGetAllReferenced() {
List<Guidance> gList = getGuidances();
return Collections.EMPTY_SET;
}
protected void addToSet(Set<Descriptor> set, List<? extends Descriptor> list) {
if (list == null || list.isEmpty()) {
return;
}
set.addAll(list);
}
public void updateStringValues() {
if (! ProcessUtil.isSynFree()) {
return;
}
for (EStructuralFeature feature : featureSet) {
getFeatureValue(feature);
}
for (EStructuralFeature feature : contentFeatureMap.keySet()) {
getFeatureValue(feature);
}
}
protected Set<MethodElement> getExcludeOrAddtionalRefSet(Descriptor des,
EReference eRef, ElementRealizer realizer) {
Set<MethodElement> set = new LinkedHashSet<MethodElement>();
if (! ProcessUtil.isSynFree()) {
return set;
}
if (des == null) {
return set;
}
try {
Set<MethodElement> rawSet = getRawExcludeOrAddtionalRefSet(des, eRef,
realizer.getConfiguration(), true);
for (MethodElement elem : rawSet) {
MethodElement realized = ConfigurationHelper.getCalculatedElement(elem, realizer);
if (realized != null) {
set.add(realized);
}
}
} catch (Exception e) {
LibraryPlugin.getDefault().getLogger().logError(e);
}
return set;
}
private Set<MethodElement> getRawExcludeOrAddtionalRefSet(Descriptor des, EReference eRef, MethodConfiguration config, boolean topLevelCall) {
List<MethodElement> list;
Set<MethodElement> refSet = new LinkedHashSet<MethodElement>();
DescriptorPropUtil propUtil = DescriptorPropUtil.getDesciptorPropUtil();
Descriptor greenParent = propUtil.getGreenParentDescriptor(des);
//An "exclude" or "additional guidance" list of customized descriptor is always
//calculated in the following block - its eGet value is never used as the realized
//value.
if (greenParent != null && ConfigurationHelper.inConfig(greenParent, config)) {
Set<MethodElement> parentSet = getRawExcludeOrAddtionalRefSet(greenParent, eRef, config, false);
refSet.addAll(parentSet);
list = propUtil.getGreenRefDeltaList(des, eRef, false);
if (list != null && !list.isEmpty()) {
refSet.removeAll(list);
}
list = propUtil.getGreenRefDeltaList(des, eRef, true);
if (list != null && !list.isEmpty()) {
refSet.addAll(list);
}
}
list = (List<MethodElement>) des.eGet(eRef);
if (greenParent == null && list != null && ! list.isEmpty()) {
refSet.addAll(list);
}
if (topLevelCall && greenParent != null) {
if (list.size() != refSet.size()) {
list.clear();
list.addAll(refSet);
}
}
return refSet;
}
public List<Guidance> getGuidances() {
UmaPackage up = UmaPackage.eINSTANCE;
List<Guidance> resultList = new ArrayList<Guidance>();
Map<EReference, EReference> refMap = LibraryEditUtil.getInstance()
.getGuidanceRefMap(getLinkedElementType());
ElementRealizer realizer = DefaultElementRealizer
.newElementRealizer(getConfig());
// List<Guidance> excludeList = ConfigurationHelper.calc0nFeatureValue(
// getDescriptor(), up.getDescriptor_GuidanceExclude(), realizer);
Set<MethodElement> excludeList = getExcludeOrAddtionalRefSet(
getDescriptor(), up.getDescriptor_GuidanceExclude(), realizer);
Set<MethodElement> addtionList = getExcludeOrAddtionalRefSet(
getDescriptor(), up.getDescriptor_GuidanceAdditional(),
realizer);
for (Map.Entry<EReference, EReference> entry : refMap.entrySet()) {
List<Guidance> subList = calculateGuidances(entry.getKey(), entry
.getValue(), excludeList, addtionList);
resultList.addAll(subList);
}
return resultList;
}
private List<Guidance> calculateGuidances(EReference eRef, EReference dRef,
Collection<MethodElement> excludeList, Collection<MethodElement> addtionList) {
// System.out.println("LD> eRef: " + eRef);
// System.out.println("LD> dRef: " + dRef);
// System.out.println("");
UmaPackage up = UmaPackage.eINSTANCE;
ElementRealizer realizer = DefaultElementRealizer
.newElementRealizer(getConfig());
MethodElement element = getLinkedElement();
if (element == null) {
return ConfigurationHelper.calc0nFeatureValue(getDescriptor(),
dRef, realizer);
}
List<Guidance> elementGuidanceList = ConfigurationHelper.calc0nFeatureValue(element,
eRef, realizer);
Set<Guidance> resultGuidanceSet = new LinkedHashSet<Guidance>();
if (addtionList != null) {
for (MethodElement me : addtionList) {
Guidance g = (Guidance) me;
if (eRef.getEType().isInstance(g)) {
resultGuidanceSet.add(g);
}
}
}
if (!elementGuidanceList.isEmpty()) {
resultGuidanceSet.addAll(elementGuidanceList);
if (excludeList != null && ! excludeList.isEmpty()) {
resultGuidanceSet.removeAll(excludeList);
}
}
List<Guidance> resultGuidanceList = new ArrayList<Guidance>();
boolean oldDeliver = getDescriptor().eDeliver();
try {
LibraryEditUtil libEditUtil = LibraryEditUtil.getInstance();
getDescriptor().eSetDeliver(false);
List<Guidance> desCuidanceList = (List<Guidance>) getDescriptor().eGet(dRef);
for (int i = desCuidanceList.size() -1; i >= 0 ; i--) {
boolean keepInList = resultGuidanceSet.remove(desCuidanceList.get(i));
if (! keepInList) {
Guidance g = desCuidanceList.remove(i);
libEditUtil.removeOppositeFeature(getDescriptor(), g, dRef);
}
}
if (! resultGuidanceSet.isEmpty()) {
Set<Guidance> desGuidanceSet = new HashSet<Guidance>();
desGuidanceSet.addAll(desCuidanceList);
for (Guidance g : resultGuidanceSet) {
if (! desGuidanceSet.contains(g)) {
desCuidanceList.add(g);
libEditUtil.addOppositeFeature(getDescriptor(), g, dRef);
}
}
}
resultGuidanceList.addAll(desCuidanceList);
} finally {
getDescriptor().eSetDeliver(oldDeliver);
}
return resultGuidanceList;
}
private EClass getLinkedElementType() {
if (getDescriptor() instanceof TaskDescriptor) {
return UmaPackage.eINSTANCE.getTask();
}
if (getDescriptor() instanceof RoleDescriptor) {
return UmaPackage.eINSTANCE.getRole();
}
if (getDescriptor() instanceof WorkProductDescriptor) {
return UmaPackage.eINSTANCE.getWorkProduct();
}
throw new UnsupportedOperationException();
}
}