blob: 2eece0bc2c1bda3007f8a4c87a1b6e435cb96b29 [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.configuration;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.provider.ItemProviderAdapter;
import org.eclipse.epf.library.edit.IConfigurator;
import org.eclipse.epf.library.edit.IFilter;
import org.eclipse.epf.library.edit.VariabilityInfo;
import org.eclipse.epf.library.edit.configuration.CategoriesItemProvider;
import org.eclipse.epf.library.edit.realization.IRealizationManager;
import org.eclipse.epf.library.edit.util.LibraryEditUtil;
import org.eclipse.epf.library.edit.util.MethodElementPropUtil;
import org.eclipse.epf.library.edit.util.MethodPluginPropUtil;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.util.LibraryUtil;
import org.eclipse.epf.library.util.Log;
import org.eclipse.epf.uma.ContentCategory;
import org.eclipse.epf.uma.CustomCategory;
import org.eclipse.epf.uma.Discipline;
import org.eclipse.epf.uma.DisciplineGrouping;
import org.eclipse.epf.uma.Domain;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodPackage;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.Role;
import org.eclipse.epf.uma.RoleSet;
import org.eclipse.epf.uma.RoleSetGrouping;
import org.eclipse.epf.uma.Task;
import org.eclipse.epf.uma.Tool;
import org.eclipse.epf.uma.ToolMentor;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.WorkProduct;
import org.eclipse.epf.uma.WorkProductType;
import org.eclipse.epf.uma.util.AssociationHelper;
import org.eclipse.epf.uma.util.Scope;
/**
* A method configuration filter to allow filtering element
* and realize the element feature values within a configuration.
*
* @author Phong Nguyen Le
* @author Jinhua Xi
* @since 1.0
*/
public class ConfigurationFilter extends AdapterImpl implements IConfigurator {
protected MethodConfiguration methodConfig;
//private Viewer viewer;
// set the default behavior for configuration view to true, i.e. contributors are discarded.
private boolean discardContributors = true;
/**
* constructor
* @param methodConfig a <code>MethodConfiguration</code>
* @param viewer a <code>Viewer</code>
*/
public ConfigurationFilter(MethodConfiguration methodConfig) {
this.methodConfig = methodConfig;
//this.viewer = viewer;
}
public ConfigurationFilter(MethodConfiguration methodConfig, boolean discardContributors) {
this(methodConfig);
this.discardContributors = discardContributors;
}
/**
* @see org.eclipse.epf.library.edit.IFilter#accept(java.lang.Object)
*/
public boolean accept(Object obj) {
if (methodConfig == null) {
if (obj instanceof MethodPlugin) {
MethodPlugin plugin = (MethodPlugin) obj;
if (null != MethodPluginPropUtil.getMethodPluginPropUtil().getCustomizedParent(plugin)) {
return false;
}
}
return true;
}
obj = LibraryUtil.unwrap(obj);
if (methodConfig instanceof Scope && obj instanceof MethodElement) {
return ((Scope) methodConfig).inScope((MethodElement) obj);
}
if ( (ElementRealizer.isExtendReplaceEnabled() ||
(obj instanceof VariabilityElement) && ConfigurationHelper.isExtendReplacer((VariabilityElement)obj) )
&& FeatureValue.isBlankIndicator(obj) ) {
return false;
}
if (obj instanceof MethodPackage) {
return methodConfig.getMethodPackageSelection().contains(obj);
} else if (obj instanceof MethodElement) {
return ConfigurationHelper.canShow((MethodElement) obj,
methodConfig);
} else if (obj instanceof ItemProviderAdapter) {
return true;
} else {
if (Log.DEBUG) {
System.out
.println("Object filtered: " + (obj == null ? null : obj.toString())); //$NON-NLS-1$
}
}
return false;
}
/**
* get the realized children for the given object and feature
*
* @param obj Object
* @param childFeature EStructuralFeature
*
* @return Collection
*/
public Collection getChildren(Object obj, EStructuralFeature childFeature) {
if (methodConfig == null)
return null;
ElementRealizer realizer = DefaultElementRealizer.newElementRealizer(methodConfig);
// discard the contributors
realizer.setDiscardContributor(this.discardContributors);
if (childFeature != null && childFeature.isMany()) {
if (obj instanceof MethodElement) {
List value = ConfigurationHelper.calc0nFeatureValue(
(MethodElement) obj, childFeature, realizer);
return value;
}
}
return null;
}
/**
* @see org.eclipse.emf.common.notify.impl.AdapterImpl#notifyChanged(org.eclipse.emf.common.notify.Notification)
*/
// public void notifyChanged(final Notification msg) {
// if (viewer == null) {
// return;
// }
//
// SafeUpdateController.syncExec(new Runnable() {
// public void run() {
// switch (msg.getEventType()) {
// case Notification.ADD:
// case Notification.ADD_MANY:
// case Notification.REMOVE:
// case Notification.REMOVE_MANY:
// viewer.refresh();
// }
// }
// });
//
// }
/**
* @see org.eclipse.epf.library.edit.IConfigurator#getMethodConfiguration()
*/
public MethodConfiguration getMethodConfiguration() {
return methodConfig;
}
/**
* @see org.eclipse.epf.library.edit.IConfigurator#setMethodConfiguration(org.eclipse.epf.uma.MethodConfiguration)
*/
public void setMethodConfiguration(MethodConfiguration config) {
methodConfig = config;
}
protected void resolveElementVariabilityList(VariabilityElement element,
VariabilityInfo info, boolean includeBase, ElementRealizer realizer) {
if (methodConfig == null) {
return;
}
//resolve to include contributors
resolveElementContributors(element,info,realizer);
// if the element is an extended element, get the base element's
// contributors
// NOTE: the base element itself should not be included since it's
// already handled
// in the activity realiztion in ItemProviders.
if (ConfigurationHelper.isExtender(element)) {
MethodElement base = element.getVariabilityBasedOnElement();
VariabilityElement e = (VariabilityElement) ConfigurationHelper
.getCalculatedElement(base, realizer);
// if includebase is true, add the element to the inheritance list
if (includeBase) {
List values = info.getInheritanceList();
if (!values.contains(e)) {
values.add(e);
}
}
// resolve the base to include additional contributors and/or base
resolveElementVariabilityList(e, info, includeBase, realizer);
}
}
protected void resolveElementContributors(VariabilityElement element,
VariabilityInfo info, ElementRealizer realizer){
// if the element has contributors in the configuration, get the
// reference properties
// if a contributor has replacer, it's replacer is used
List items = ConfigurationHelper.getContributors(element, methodConfig);
if (items != null && items.size() > 0) {
for (Iterator it = items.iterator(); it.hasNext();) {
VariabilityElement e = (VariabilityElement) it.next();
List values = info.getContributors();
if (!values.contains(e)) {
values.add(e);
}
resolveElementVariabilityList(e, info, false, realizer);
}
}
}
/*
* resolve the variability of the element and get a list of contributors.
*
* This method is used for realizing actitivy breakdown elements in the
* itemProviders.
*
* @see org.eclipse.epf.library.edit.IConfigurator#getVariabilityInfo(org.eclipse.epf.uma.VariabilityElement)
*/
public VariabilityInfo getVariabilityInfo(VariabilityElement ve) {
// calculate the element first
ElementRealizer realizer = DefaultElementRealizer.newElementRealizer(methodConfig, true, true);
return getVariabilityInfo(ve, realizer);
}
protected VariabilityInfo getVariabilityInfo(VariabilityElement ve, ElementRealizer realizer) {
// calculate the element first
VariabilityElement e = (VariabilityElement) ConfigurationHelper
.getCalculatedElement(ve, realizer);
if (e == null) {
return null;
}
VariabilityInfo info = new VariabilityInfo(ve);
info.getInheritanceList().add(e);
resolveElementVariabilityList(e, info, true, realizer);
return info;
}
public Object resolve(Object element) {
if (element instanceof VariabilityElement) {
ElementRealizer realizer = DefaultElementRealizer.newElementRealizer(methodConfig, true, true);
return ConfigurationHelper.getCalculatedElement(
(MethodElement) element, realizer);
}
return element;
}
/**
* get filter for uncategorized tasks
*
* @return IFilter
*/
public IFilter getUncategorizedTaskFilter() {
return new IFilter() {
public boolean accept(Object obj) {
// 158924 - wrong categories in configuration view
// should use the default realizer
// we should not discard the discipline contributors
// instead should realize to the base discipline
return ( obj instanceof Task ) &&
ConfigurationHelper.calc0nFeatureValue(
(Task)obj,
AssociationHelper.Task_Disciplines,
DefaultElementRealizer.newElementRealizer(methodConfig)).isEmpty();
}
};
}
/**
* get filter for workproducts without a domain
*
* @return IFilter
*/
public IFilter getDomainUncategorizedWorkProductFilter(){
return new IFilter() {
public boolean accept(Object obj) {
// 158924 - wrong categories in configuration view
// should use the default realizer
// we should not discard the domain contributors
// instead should realize to the base domain
return ( obj instanceof WorkProduct ) &&
ConfigurationHelper.calc0nFeatureValue(
(WorkProduct)obj,
AssociationHelper.WorkProduct_Domains,
DefaultElementRealizer.newElementRealizer(methodConfig)).isEmpty();
}
};
}
/**
* get filter for workproducts without a WP Type
*
* @return IFilter
*/
public IFilter getWpTypeUncategorizedWorkProductFilter(){
return new IFilter() {
public boolean accept(Object obj) {
// 158924 - wrong categories in configuration view
// should use the default realizer
// we should not discard the WPType contributors
// instead should realize to the base
return ( obj instanceof WorkProduct ) &&
ConfigurationHelper.calc0nFeatureValue(
(WorkProduct)obj,
AssociationHelper.WorkProduct_WorkProductTypes,
DefaultElementRealizer.newElementRealizer(methodConfig)).isEmpty();
}
};
}
/**
* get filter for uncategorized roles
*
* @return IFilter
*/
public IFilter getUncategorizedRoleFilter(){
return new IFilter() {
public boolean accept(Object obj) {
// 158924 - wrong categories in configuration view
// should use the default realizer
// we should not discard the roleset contributors
// instead should realize to the base
return ( obj instanceof Role ) &&
ConfigurationHelper.calc0nFeatureValue(
(Role)obj,
AssociationHelper.Role_RoleSets,
DefaultElementRealizer.newElementRealizer(methodConfig)).isEmpty();
}
};
}
/**
* get filter for uncategorized tool mentors
*
* @return IFilter
*/
public IFilter getUncategorizedToolMentorFilter() {
return new IFilter() {
public boolean accept(Object obj) {
// 158924 - wrong categories in configuration view
// should use the default realizer
// we should not discard the tool contributors
// instead should realize to the base
return ( obj instanceof ToolMentor ) &&
ConfigurationHelper.calc0nFeatureValue(
(ToolMentor)obj,
AssociationHelper.ToolMentor_Tools,
DefaultElementRealizer.newElementRealizer(methodConfig)).isEmpty();
}
};
}
/**
* get filter for disciplines and displine groupings
*
* @return IFilter
*/
public IFilter getDisciplinesFilter() {
return new IFilter() {
public boolean accept(Object obj) {
// [Bug 162603] New: Replacing disciplines do appear inside their replaced elements discipline groupings
// as well as outside of the discipline grouping
if ( obj instanceof DisciplineGrouping ) {
return true;
}
return ( obj instanceof Discipline ) &&
ConfigurationHelper.calc0nFeatureValue(
(MethodElement)obj,
AssociationHelper.Discipline_DisciplineGroupings,
DefaultElementRealizer.newElementRealizer(methodConfig)).isEmpty();
}
};
}
/**
* get filter for rolesets and roleset groupings
*
* @return IFilter
*/
public IFilter getRoleSetsFilter() {
return new IFilter() {
public boolean accept(Object obj) {
// [Bug 162603] New: Replacing disciplines do appear inside their replaced elements discipline groupings
// as well as outside of the discipline grouping
// same for roleset grouping
if ( obj instanceof RoleSetGrouping ) {
return true;
}
return ( obj instanceof RoleSet ) &&
ConfigurationHelper.calc0nFeatureValue(
(MethodElement)obj,
AssociationHelper.RoleSet_RoleSetGrouppings,
DefaultElementRealizer.newElementRealizer(methodConfig)).isEmpty();
}
};
}
/**
* @return an IRealizationManager instance
*/
public IRealizationManager getRealizationManager() {
MethodConfiguration c = getMethodConfiguration();
return ConfigurationHelper.getDelegate().getRealizationManager(c);
}
public Collection<?> getModifiedChildren(Object parentObject, Collection children) {
// if (ConfigurationHelper.getDelegate().isAuthoringMode()) {
// return children;
// }
// if (ConfigurationHelper.getDelegate().isPublishingMode()) {
// return children;
// }
if (! ConfigurationHelper.getDelegate().filterOutEmptyCategories()) {
return children;
}
if (children == null || children.isEmpty()) {
return children;
}
boolean modified = false;
List modifiedChildren = new ArrayList();
if (parentObject instanceof CategoriesItemProvider || TngUtil.unwrap(parentObject) instanceof ContentCategory) {
for (Object child : children) {
if (child instanceof ContentCategory) {
if (! isEmpty((ContentCategory) child)) {
modifiedChildren.add(child);
} else {
modified = true;
}
} else {
modifiedChildren.add(child);
}
}
}
return modified ? modifiedChildren : children;
}
public boolean isEmpty(ContentCategory cc) {
return isEmpty(cc, new HashMap<ContentCategory, Boolean>());
}
public static Object isEmptyCheckLock = new Object();
private boolean isEmpty(ContentCategory cc, Map<ContentCategory, Boolean> processedMap) {
Boolean bvalue = processedMap.get(cc);
if (bvalue == null) {
Map map = MethodElementPropUtil.getMethodElementPropUtil().getExtendedPropertyMap(cc, true);
try {
map.put(isEmptyCheckLock, true);
boolean b = isEmpty_(cc, processedMap);
bvalue = b ? Boolean.TRUE : Boolean.FALSE;
processedMap.put(cc, bvalue);
} finally {
map.remove(isEmptyCheckLock);
}
}
return bvalue.booleanValue();
}
private boolean isEmpty_(ContentCategory cc, Map<ContentCategory, Boolean> processedMap) {
LibraryEditUtil util = LibraryEditUtil.getInstance();
EReference ref = getCategorizedRef(cc);
Object value = ref == null ? null : util.calc0nFeatureValue(cc, ref, getMethodConfiguration());
if (value instanceof List) {
for (Object item : (List) value) {
if (! (item instanceof ContentCategory)) {
return false;
}
}
}
ref = getSubCategoryRef(cc);
value = ref == null ? null : util.calc0nFeatureValue(cc, ref, getMethodConfiguration());
if (value instanceof List) {
for (Object item : (List) value) {
if (item instanceof ContentCategory) {
if (! isEmpty((ContentCategory) item, processedMap)) {
return false;
}
}
}
}
return true;
}
private EReference getSubCategoryRef(ContentCategory cc) {
UmaPackage up = UmaPackage.eINSTANCE;
if (cc instanceof CustomCategory) {
return up.getCustomCategory_CategorizedElements();
}
if (cc instanceof Discipline) {
return up.getDiscipline_Subdiscipline();
}
if (cc instanceof DisciplineGrouping) {
return up.getDisciplineGrouping_Disciplines();
}
if (cc instanceof Domain) {
return up.getDomain_Subdomains();
}
if (cc instanceof RoleSet) {
return null;
}
if (cc instanceof RoleSetGrouping) {
return up.getRoleSetGrouping_RoleSets();
}
if (cc instanceof Tool) {
return null;
}
if (cc instanceof WorkProductType) {
return null;
}
return null;
}
private EReference getCategorizedRef(ContentCategory cc) {
UmaPackage up = UmaPackage.eINSTANCE;
if (cc instanceof CustomCategory) {
return up.getCustomCategory_CategorizedElements();
}
if (cc instanceof Discipline) {
return up.getDiscipline_Tasks();
}
if (cc instanceof DisciplineGrouping) {
return null;
}
if (cc instanceof Domain) {
return up.getDomain_WorkProducts();
}
if (cc instanceof RoleSet) {
return up.getRoleSet_Roles();
}
if (cc instanceof RoleSetGrouping) {
return null;
}
if (cc instanceof Tool) {
return up.getTool_ToolMentors();
}
if (cc instanceof WorkProductType) {
return up.getWorkProductType_WorkProducts();
}
return null;
}
public ElementRealizer getRealizer() {
ElementRealizer realizer = DefaultElementRealizer.newElementRealizer(methodConfig);
return realizer;
}
}