blob: d18d86b5d1341596a2305da96954ccf5cacedcb4 [file] [log] [blame]
//------------------------------------------------------------------------------
// Copyright (c) 2005, 2008 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.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.epf.library.IConfigurationManager;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.configuration.closure.ConfigurationClosure;
import org.eclipse.epf.library.configuration.closure.ElementReference;
import org.eclipse.epf.library.edit.util.DebugUtil;
import org.eclipse.epf.library.util.LibraryUtil;
import org.eclipse.epf.uma.Descriptor;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.MethodPackage;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.Role;
import org.eclipse.epf.uma.Task;
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.util.UmaUtil;
/**
* Class managing supporting elements
*
* @author Weiping Lu - Mar 22, 2008
* @since 1.5
*/
public class SupportingElementData extends ConfigDataBase {
private Set<MethodElement> supportingElements;
private boolean duringUpdateSupporitngElements = false;
private Set<MethodPlugin> supportingPlugins;
private Set<MethodPackage> selectedPackages;
private static boolean localDebug = false;
private static boolean localDebug1 = false;
private boolean enabled = true;
private static boolean descriptorExclusiveOption = true;
public SupportingElementData(MethodConfiguration config) {
super(config);
}
public void beginUpdateSupportingElements() {
setUpdatingChanges(true);
if (localDebug) {
System.out.println("LD> beginUpdateSupportingElements -> "); //$NON-NLS-1$
}
supportingElements = new HashSet<MethodElement>();
supportingPlugins = new HashSet<MethodPlugin>();
Set<MethodPlugin> plugins = new HashSet<MethodPlugin>(getConfig()
.getMethodPluginSelection());
for (MethodPlugin plugin : plugins) {
if (plugin.isSupporting()) {
supportingPlugins.add(plugin);
}
}
setEnabled(supportingPlugins.size() < plugins.size());
selectedPackages = new HashSet<MethodPackage>();
if (isEnabled() && ! supportingPlugins.isEmpty()) {
List<MethodPackage> packages = getConfig().getMethodPackageSelection();
for (MethodPackage pkg : packages) {
MethodPlugin plugin = UmaUtil.getMethodPlugin(pkg);
if (supportingPlugins.contains(plugin)) {
selectedPackages.add(pkg);
}
}
}
if (localDebug) {
System.out.println("LD> isEnabled(): " + isEnabled()); //$NON-NLS-1$
System.out.println("LD> supportingPlugins: " + supportingPlugins.size()); //$NON-NLS-1$
System.out.println("LD> selectedPackages: " + selectedPackages.size()); //$NON-NLS-1$
System.out.println("LD> beginUpdateSupportingElements <- "); //$NON-NLS-1$
System.out.println(""); //$NON-NLS-1$
}
}
// Collect map of referred references outside the config
public void endUpdateSupportingElements(
Map<String, ElementReference> outConfigRefMap) {
if (localDebug) {
System.out.println("LD> endUpdateSupportingElements -> "); //$NON-NLS-1$
}
if (isEnabled()) {
Set<MethodElement> supportingElementsToCollect = new HashSet<MethodElement>(supportingElements);
while (!supportingElementsToCollect.isEmpty()) {
Set<MethodElement> newSupportingElements = new HashSet<MethodElement>();
processReferencesOutsideConfig(supportingElementsToCollect, outConfigRefMap, newSupportingElements);
if (localDebug) {
System.out.println("LD> newSupportingElements: " + newSupportingElements.size()); //$NON-NLS-1$
}
supportingElementsToCollect = newSupportingElements;
}
}
setUpdatingChanges(false);
setNeedUpdateChanges(false);
if (localDebug) {
System.out.println("LD> supportingElements: " + supportingElements.size()); //$NON-NLS-1$
System.out.println("LD> outConfigRefMap: " + outConfigRefMap.size()); //$NON-NLS-1$
System.out.println("LD> endUpdateSupportingElements <- "); //$NON-NLS-1$
System.out.println(""); //$NON-NLS-1$
}
}
private void processReferencesOutsideConfig(
Collection<MethodElement> elements,
Map<String, ElementReference> outConfigRefMap, Set<MethodElement> newSupportingElements) {
for (MethodElement element : elements) {
processReferencesOutsideConfig(element, outConfigRefMap, newSupportingElements);
}
}
private void processReferencesOutsideConfig(MethodElement element,
Map<String, ElementReference> outConfigRefMap, Set<MethodElement> newSupportingElements) {
IConfigurationManager configManager = LibraryService.getInstance().getConfigurationManager(
getConfig());
Set<VariabilityElement> replacerSet = null;
if (configManager != null) {
replacerSet = configManager.getDependencyManager().getReplacerSet();
}
List properties = LibraryUtil.getStructuralFeatures(element);
for (EStructuralFeature f: (List<EStructuralFeature>) properties) {
if (!(f instanceof EReference)) {
continue;
}
EReference feature = (EReference) f;
if (feature.isContainer() || feature.isContainment()) {
continue;
}
Object value = element.eGet(feature);
if (value == null) {
continue;
}
List values = null;
if ( feature.isMany() ) {
values = (List) value;
} else if ( value instanceof MethodElement ) {
if (descriptorExclusiveCheck((MethodElement) value, element, feature)) {
continue;
}
values = new ArrayList();
values.add(value);
if (replacerSet != null) {
if (feature == UmaPackage.eINSTANCE.getVariabilityElement_VariabilityBasedOnElement()) {
VariabilityElement ve = element instanceof VariabilityElement ?
(VariabilityElement) element : null;
VariabilityType type = ve == null ? null : ve.getVariabilityType();
if (type == VariabilityType.EXTENDS_REPLACES ||
type == VariabilityType.REPLACES) {
replacerSet.add(ve);
}
}
}
}
String guid = element.getGuid();
for (Object referredValue: values) {
if (! (referredValue instanceof MethodElement)) {
continue;
}
MethodElement referredElement = (MethodElement) referredValue;
boolean isOutConfig = checkOutConfigElement(referredElement, element, newSupportingElements);
if (isOutConfig && outConfigRefMap != null){
String key = guid + referredElement.getGuid();
ElementReference elementReference = outConfigRefMap.get(key);
if (elementReference == null) {
elementReference = new ElementReference(element, referredElement);
outConfigRefMap.put(key, elementReference);
}
elementReference.addFeature(feature);
}
}
}
}
private boolean descriptorExclusiveCheck(MethodElement referredElement, MethodElement referringElement, EStructuralFeature feature) {
if (! descriptorExclusiveOption) {
return false;
}
if (! (referringElement instanceof Descriptor)) {
return false;
}
if (feature == UmaPackage.eINSTANCE.getTaskDescriptor_Task()) {
return referredElement instanceof Task;
}
if (feature == UmaPackage.eINSTANCE.getRoleDescriptor_Role()) {
return referredElement instanceof Role;
}
if (feature == UmaPackage.eINSTANCE.getWorkProductDescriptor_WorkProduct()) {
return referredElement instanceof WorkProduct;
}
return false;
}
private boolean checkOutConfigElement(MethodElement referredElement, MethodElement referingElement, Set<MethodElement> newSupportingElements) {
if (referredElement instanceof MethodPackage
|| referredElement instanceof MethodConfiguration) {
return false;
}
if (referredElement instanceof VariabilityElement) {
VariabilityElement replacer = ConfigurationHelper.getReplacer(
(VariabilityElement) referredElement, getConfig());
if (replacer != null) {
return false;
}
}
// the element might be subtracted, so ignore it
if (!supportingElements.contains(referingElement) && !ConfigurationHelper.inConfig(referingElement, getConfig(), true, false)) {
return false;
}
if (!ConfigurationHelper.inConfig(referredElement, getConfig())
&& !isOwnerSelected(referredElement, newSupportingElements)) {
return true;
}
return false;
}
public boolean isSupportingElement(MethodElement element) {
boolean ret = isSupportingElement_(element);
if (localDebug1) {
System.out.println("LD> isSE: " + ret + //$NON-NLS-1$
", element: " + DebugUtil.toString(element, 2));//$NON-NLS-1$
}
return ret;
}
private boolean isSupportingElement_(MethodElement element) {
if (isUpdatingChanges()) {
throw new UnsupportedOperationException();
} else if (isNeedUpdateChanges()) {
updateChanges();
}
return supportingElements.contains(element);
}
protected void updateChangeImpl() {
ConfigurationClosure closure = new ConfigurationClosure(null, getConfig());
}
//isSupportingElement check during updating mode
public boolean isSupportingElementCallDuringUpdating(ElementReference ref) {
if (! isEnabled()) {
return false;
}
MethodElement referringElement = ref.getElement();
MethodElement referredElement = ref.getRefElement();
EStructuralFeature feature = ref.getSingleFeature();
if (descriptorExclusiveCheck(referredElement, referringElement, feature)) {
return false;
}
return isOwnerSelected(referredElement, null);
}
private boolean isOwnerSelected(MethodElement element,
Set<MethodElement> newSupportingElements) {
if (! isUpdatingChanges()) {
throw new UnsupportedOperationException();
}
if (supportingElements.contains(element)) {
return true;
}
boolean ret = false;
EObject selectable = LibraryUtil.getSelectable(element);
if (selectable instanceof MethodPackage) {
ret = selectedPackages.contains(selectable);
} else if (selectable instanceof MethodPlugin) {
ret = supportingPlugins.contains(selectable);
} else if (selectable instanceof MethodLibrary) {
ret = true;
}
if (ret) {
supportingElements.add(element);
if (localDebug1) {
System.out
.println("LD> supportingElements added: " + DebugUtil.toString(element, 2));//$NON-NLS-1$
}
if (newSupportingElements != null) {
newSupportingElements.add(element);
}
}
return ret;
}
public boolean isSupportingSelectable(MethodElement element) {
if (! isEnabled()) {
return false;
}
return selectedPackages.contains(element) || supportingPlugins.contains(element);
}
public boolean isEnabled() {
return enabled;
}
private void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public static synchronized boolean isDescriptorExclusiveOption() {
return descriptorExclusiveOption;
}
public static synchronized void setDescriptorExclusiveOption(
boolean descriptorExclusiveOption) {
SupportingElementData.descriptorExclusiveOption = descriptorExclusiveOption;
}
}