blob: 00f317090b0b040f95792f37090353adb6f1fe6c [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.configuration.closure.ConfigurationClosure;
import org.eclipse.epf.library.configuration.closure.ElementReference;
import org.eclipse.epf.library.util.LibraryUtil;
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.VariabilityElement;
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;
public SupportingElementData(MethodConfiguration config) {
super(config);
}
public void beginUpdateSupportingElements() {
setUpdatingChanges(true);
supportingElements = new HashSet<MethodElement>();
supportingPlugins = new HashSet<MethodPlugin>();
List<MethodPlugin> plugins = getConfig().getMethodPluginSelection();
for (MethodPlugin plugin : plugins) {
if (plugin.isSupporting()) {
supportingElements.add(plugin);
}
}
selectedPackages = new HashSet<MethodPackage>();
if (! supportingPlugins.isEmpty()) {
List<MethodPackage> packages = getConfig().getMethodPackageSelection();
for (MethodPackage pkg : packages) {
MethodPlugin plugin = UmaUtil.getMethodPlugin(pkg);
if (supportingPlugins.contains(plugin)) {
selectedPackages.add(pkg);
}
}
}
}
// Collect map of referred references outside the config
public void endUpdateSupportingElements(
Map<String, ElementReference> outConfigRefMap) {
Set<MethodElement> supportingElementsToCollect = supportingElements;
while (!supportingElementsToCollect.isEmpty()) {
Set<MethodElement> newSupportingElements = new HashSet<MethodElement>();
processReferencesOutsideConfig(supportingElementsToCollect, outConfigRefMap, newSupportingElements);
supportingElementsToCollect = newSupportingElements;
}
supportingPlugins = null;
selectedPackages = null;
setUpdatingChanges(false);
}
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) {
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 ) {
values = new ArrayList();
values.add(value);
}
String guid = element.getGuid();
for (Object referredValue: values) {
if (! (referredValue instanceof MethodElement)) {
continue;
}
MethodElement refElement = (MethodElement) referredValue;
boolean isOutConfig = checkOutConfigElement(refElement, newSupportingElements);
if (isOutConfig && outConfigRefMap != null){
String key = guid + refElement.getGuid();
ElementReference elementReference = outConfigRefMap.get(key);
if (elementReference == null) {
elementReference = new ElementReference(element, refElement);
outConfigRefMap.put(key, elementReference);
}
elementReference.addFeature(feature);
}
}
}
}
private boolean checkOutConfigElement(MethodElement refElement, Set<MethodElement> newSupportingElements) {
if (refElement instanceof MethodPackage
|| refElement instanceof MethodConfiguration) {
return false;
}
if (refElement instanceof VariabilityElement) {
VariabilityElement replacer = ConfigurationHelper.getReplacer(
(VariabilityElement) refElement, getConfig());
if (replacer != null) {
return false;
}
}
// the element might be subtracted, so ignore it
if (!ConfigurationHelper.inConfig(refElement, getConfig(), true, false)) {
return false;
}
if (!ConfigurationHelper.inConfig(refElement, getConfig())
&& !isSupportingElement(refElement, newSupportingElements, true)) {
return true;
}
return false;
}
public boolean isSupportingElement(MethodElement element) {
if (isUpdatingChanges()) {
return isSupportingElement(element, null, true);
} else if (isNeedUpdateChanges()) {
updateChanges();
}
if (supportingElements.isEmpty()) {
return false;
}
boolean ret = supportingElements.contains(element);
if (! ret) {
EObject container = LibraryUtil.getSelectable(element);
if (container instanceof MethodPackage) {
return isSupportingElement((MethodPackage) container, null, false);
}
}
return ret;
}
protected void updateChangeImpl() {
ConfigurationClosure closure = new ConfigurationClosure(null, getConfig());
setUpdatingChanges(false);
setNeedUpdateChanges(false);
}
private boolean isSupportingElement(MethodElement element, Set<MethodElement> newSupportingElements, boolean checkContainer) {
if (supportingElements.contains(element)) {
return true;
}
EObject container = LibraryUtil.getSelectable(element);
if (isUpdatingChanges()) {
boolean ret = false;
if (container instanceof MethodPackage) {
ret = selectedPackages.contains(container);
if (checkContainer && !ret) {
ret = isSupportingElement((MethodPackage)container, newSupportingElements, false);
}
} else if (container instanceof MethodPlugin) {
ret = supportingPlugins.contains(container);
} else if (container instanceof MethodLibrary) {
ret = supportingPlugins.contains(element);
}
if (ret) {
supportingElements.add(element);
newSupportingElements.add(element);
}
return ret;
}
if (checkContainer && container instanceof MethodPackage) {
return isSupportingElement((MethodPackage)container, newSupportingElements, false);
}
return false;
}
public boolean isSupportingSelectable(MethodElement element) {
return selectedPackages.contains(element) || supportingPlugins.contains(element);
}
}