blob: 4b72290759e2b9cc409fb049ab024a8af0727cb0 [file] [log] [blame]
//------------------------------------------------------------------------------
// 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.edit.itemsfilter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.uma.Artifact;
import org.eclipse.epf.uma.CustomCategory;
import org.eclipse.epf.uma.Deliverable;
import org.eclipse.epf.uma.Domain;
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.Practice;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.util.AssociationHelper;
/**
* This is a filter for variability base element selection. The filter will
* check if object can be accepted as the base element of the filter owner.
*
* Filter rules:
*
* 1. The element itself and it's generalizers (contributor, replacer, or
* extender) should be filtered out
* 2. Any elements in the containment chain of the above, should be filtered
* out
* 3. if any of the base elements can't be selected, then this element can't
* be selected.
*
* @author Jinhua Xi
* @since 1.0
*/
public class VariabilityBaseElementFilter implements
org.eclipse.epf.library.edit.IFilter {
private VariabilityElement element;
private List badguys = new ArrayList();
public VariabilityBaseElementFilter(VariabilityElement element) {
this.element = element;
// first of all, you can't vary yourself
badguys.add(element);
// get all my generalizers
Iterator it = TngUtil.getGeneralizers(element);
while (it.hasNext()) {
VariabilityElement ve = (VariabilityElement) it.next();
badguys.add(ve);
// the containment chain on my generalizers can't be my base
handleContainmentChain(ve);
}
// element's in my chain can't be my base
handleContainmentChain(element);
}
private void handleContainmentChain(VariabilityElement e) {
if (!hasContainmentFeature()) {
return;
}
if (e instanceof CustomCategory) {
List roots = new ArrayList();
loadRootCustomCategories((CustomCategory) e, roots);
badguys.addAll(roots);
} else if (e instanceof Deliverable) {
List roots = new ArrayList();
deliverableParts((Deliverable) e, roots);
badguys.addAll(roots);
} else {
// if the element has containment feature,
// you can't select the element in the containment chain
EObject root = getChainRoot(e);
if (!badguys.contains(root)) {
badguys.add(root);
}
/*
* hold off for now // also only one element in a chain can be
* selected as base // so get all the base elements in the element
* chain, and block the element chain of the base elements
* filterUsedBaseChain((VariabilityElement)root); for (Iterator it =
* root.eAllContents(); it.hasNext(); ) { Object o = it.next(); if (
* o.getClass().isInstance(element) ) {
* filterUsedBaseChain((VariabilityElement)o); } }
*/
}
}
private void deliverableParts(Deliverable e, List roots) {
List list = ((Deliverable) e).getDeliveredWorkProducts();
if (list != null && list.size() > 0) {
for (Iterator iterator = list.iterator(); iterator.hasNext();) {
Object obj = iterator.next();
if (obj instanceof Deliverable) {
roots.add(obj);
deliverableParts((Deliverable) obj, roots);
}
}
}
}
private void loadRootCustomCategories(CustomCategory e, List roots) {
List cs = AssociationHelper.getCustomCategories(e);
if (cs != null && cs.size() > 0) {
for (Iterator it = cs.iterator(); it.hasNext();) {
CustomCategory cc = (CustomCategory) it.next();
if (!TngUtil.isRootCustomCategory(cc)) {
loadRootCustomCategories(cc, roots);
} else {
if (!roots.contains(e)) {
roots.add(e);
}
break;
}
}
} else if (!roots.contains(e)) {
roots.add(e);
}
}
// private void filterUsedBaseChain(VariabilityElement e) {
// VariabilityElement base = e.getVariabilityBasedOnElement();
// if (base != null) {
// // if the element chain is selected as base in the current chain,
// // no element in that chain can be futher selected
// Object root = getChainRoot(base);
// if (!badguys.contains(root)) {
// badguys.add(root);
// }
// }
// }
private boolean hasContainmentFeature() {
return element instanceof Domain || element instanceof CustomCategory
|| element instanceof Artifact || element instanceof Practice
|| element instanceof Deliverable;
}
private EObject getChainRoot(MethodElement e) {
EObject root = e;
Object type = element.getType();
EObject parent = e;
while ((parent = parent.eContainer()) != null
&& ((MethodElement) parent).getType() == type) {
root = parent;
}
return root;
}
public boolean accept(Object obj) {
// always accept packages
if (obj instanceof MethodLibrary || obj instanceof MethodPlugin
|| obj instanceof MethodPackage
|| obj instanceof MethodConfiguration) {
return true;
}
// must be variability element and can't be itself
if (obj == element || !(obj instanceof VariabilityElement)) {
return false;
}
// must be the same type
VariabilityElement ve = (VariabilityElement) obj;
if (ve.getType() != element.getType()) {
return false;
}
// can't be my any of my generalizers
if (badguys.contains(obj)) {
return false;
}
// if this element's base chain is a badguy, can't accept, otherwise, a
// circular lock
while ((ve = ve.getVariabilityBasedOnElement()) != null) {
if (badguys.contains(ve)) {
return false;
}
}
// anything else ?
return true;
}
}