//------------------------------------------------------------------------------ // 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.LibraryEditPlugin; import org.eclipse.epf.library.edit.util.PracticePropUtil; 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; import org.eclipse.epf.uma.util.UserDefinedTypeMeta; /** * 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; } if (element instanceof Practice && ve instanceof Practice) { Practice p1 = (Practice) element; Practice p2 = (Practice) ve; PracticePropUtil propUtil = PracticePropUtil.getPracticePropUtil(); UserDefinedTypeMeta meta1 = null; UserDefinedTypeMeta meta2 = null; try { meta1 = propUtil.getUtdData(p1); meta2 = propUtil.getUtdData(p2); } catch (Exception e) { LibraryEditPlugin.getDefault().getLogger().logError(e); } if (meta1 != null && meta2 != null) { if (! meta1.getId().equals(meta2.getId())) { return false; } } else if (!(meta1 == null && meta2 == null)) { 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; } }