| //------------------------------------------------------------------------------ |
| // 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.validation; |
| |
| import java.util.Collection; |
| import java.util.Iterator; |
| |
| import org.eclipse.emf.common.notify.AdapterFactory; |
| import org.eclipse.emf.common.util.URI; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.EStructuralFeature; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.emf.edit.provider.AdapterFactoryTreeIterator; |
| import org.eclipse.emf.edit.provider.ITreeItemContentProvider; |
| import org.eclipse.epf.common.utils.StrUtil; |
| import org.eclipse.epf.library.edit.IFilter; |
| import org.eclipse.epf.library.edit.LibraryEditResources; |
| import org.eclipse.epf.library.edit.process.BSActivityItemProvider; |
| import org.eclipse.epf.library.edit.util.ProcessUtil; |
| import org.eclipse.epf.library.edit.util.Suppression; |
| import org.eclipse.epf.library.edit.util.TngUtil; |
| import org.eclipse.epf.uma.Activity; |
| import org.eclipse.epf.uma.BreakdownElement; |
| import org.eclipse.epf.uma.CapabilityPattern; |
| import org.eclipse.epf.uma.DescribableElement; |
| import org.eclipse.epf.uma.MethodElement; |
| import org.eclipse.epf.uma.MethodLibrary; |
| import org.eclipse.epf.uma.NamedElement; |
| import org.eclipse.epf.uma.Role; |
| import org.eclipse.epf.uma.RoleDescriptor; |
| import org.eclipse.epf.uma.TaskDescriptor; |
| import org.eclipse.epf.uma.TeamProfile; |
| import org.eclipse.epf.uma.UmaPackage; |
| import org.eclipse.epf.uma.VariabilityElement; |
| import org.eclipse.epf.uma.VariabilityType; |
| import org.eclipse.epf.uma.WorkProductDescriptor; |
| import org.eclipse.osgi.util.NLS; |
| |
| /** |
| * This class defines various static methods to validate name of specified |
| * object |
| * |
| * @author Phong Nguyen Le |
| * @since 1.0 |
| */ |
| public final class NameChecker { |
| |
| private static final String ELEMENT_TEXT = LibraryEditResources.element_text; |
| |
| private static final INameProvider presentationNameProvider = new INameProvider() { |
| |
| public String getName(Object object) { |
| if(object instanceof BreakdownElement) { |
| return ProcessUtil.getPresentationName((BreakdownElement) object); |
| } |
| else if(object instanceof DescribableElement) { |
| return ((DescribableElement)object).getPresentationName(); |
| } |
| return null; |
| } |
| |
| }; |
| |
| private static String checkName(AdapterFactory adapterFactory, |
| Object parent, Object e, final Class type, |
| INameProvider nameProvider, String newName, Suppression suppresion, |
| boolean ignoreSuppressed) { |
| IFilter childFilter = new IFilter() { |
| |
| public boolean accept(Object obj) { |
| return type.isInstance(obj); |
| } |
| |
| }; |
| |
| return checkName(adapterFactory, parent, e, childFilter, nameProvider, |
| newName, suppresion, ignoreSuppressed); |
| } |
| |
| private static String checkName(AdapterFactory adapterFactory, |
| Object parent, Object e, IFilter childFilter, |
| EStructuralFeature nameFeature, String newName, |
| Suppression suppression, boolean ignoreSuppressed) { |
| return checkName(adapterFactory, parent, e, childFilter, |
| createNameProvider(nameFeature), newName, suppression, |
| ignoreSuppressed); |
| } |
| |
| private static String checkName(AdapterFactory adapterFactory, |
| Object parent, Object e, IFilter childFilter, |
| INameProvider nameProvider, String newName, |
| Suppression suppression, boolean ignoreSuppressed) |
| { |
| if (ignoreSuppressed) |
| if (suppression != null && suppression.isSuppressed(e)) { |
| return null; |
| } |
| |
| ITreeItemContentProvider adapter = (ITreeItemContentProvider) adapterFactory |
| .adapt(parent, ITreeItemContentProvider.class); |
| Collection children; |
| |
| // get children of the rolled-down dapter |
| // |
| boolean wasRolledUp = false; |
| BSActivityItemProvider bsItemProvider = null; |
| if (adapter instanceof BSActivityItemProvider) { |
| bsItemProvider = ((BSActivityItemProvider) adapter); |
| wasRolledUp = bsItemProvider.isRolledUp(); |
| } |
| try { |
| if (wasRolledUp) { |
| bsItemProvider.setRolledUp(false); |
| } |
| children = adapter.getChildren(parent); |
| } catch (NullPointerException ex) { |
| throw ex; |
| } finally { |
| if (wasRolledUp) { |
| bsItemProvider.basicSetRolledUp(wasRolledUp); |
| } |
| } |
| |
| if (e instanceof BreakdownElement) { |
| return null; |
| } |
| |
| for (Iterator iter = children.iterator(); iter.hasNext();) { |
| Object item = iter.next(); |
| |
| // skip checking on suppressed element |
| // |
| /*170058 if (suppression != null && suppression.isSuppressed(item)) { |
| continue; |
| }*/ |
| |
| Object child = TngUtil.unwrap(item); |
| if (child != e && childFilter.accept(child)) { |
| String name = nameProvider.getName(child); |
| if (name.equalsIgnoreCase(newName)) { |
| // return I18nUtil.formatString(RESOURCE_BUNDLE, key, data); |
| return NLS.bind( |
| LibraryEditResources.duplicateElementNameError_msg, |
| name); |
| } |
| } |
| } |
| return null; |
| } |
| |
| private static INameProvider createNameProvider( |
| final EStructuralFeature nameFeature) { |
| if(nameFeature == UmaPackage.eINSTANCE |
| .getMethodElement_PresentationName()) { |
| return presentationNameProvider; |
| } |
| |
| return new INameProvider() { |
| |
| public String getName(Object object) { |
| if (object instanceof EObject) { |
| return (String) ((EObject) object).eGet(nameFeature); |
| } else { |
| return null; |
| } |
| } |
| |
| }; |
| } |
| |
| public static String checkName(AdapterFactory adapterFactory, |
| final BreakdownElement e, Class type, EStructuralFeature nameFeature, |
| String newName, Suppression suppression) |
| { |
| return checkName(adapterFactory, null, e, type, nameFeature, newName, |
| suppression, false); |
| } |
| |
| public static String checkName(AdapterFactory adapterFactory, Object parent, |
| final BreakdownElement e, Class type, final EStructuralFeature nameFeature, |
| String newName, Suppression suppression, boolean ignoreSuppressed) |
| { |
| String msg = checkEmpty(e, newName); |
| if(msg != null) { |
| return msg; |
| } |
| |
| if(type == null) { |
| type = chooseType(e); |
| } |
| |
| if(parent == null) { |
| ITreeItemContentProvider itemProvider = (ITreeItemContentProvider) adapterFactory |
| .adapt(e, ITreeItemContentProvider.class); |
| parent = itemProvider.getParent(e); |
| if(parent == null) { |
| return null; |
| } |
| } |
| |
| // basic check |
| // |
| msg = checkName(adapterFactory, parent, e, type, |
| createNameProvider(nameFeature), newName, suppression, |
| ignoreSuppressed); |
| |
| if (msg != null) |
| return msg; |
| IFilter childFilter = null; |
| if (e instanceof TeamProfile) { |
| // don't allow team with the same name within the same scope |
| // |
| childFilter = new IFilter() { |
| public boolean accept(Object obj) { |
| return e instanceof TeamProfile; |
| } |
| }; |
| } |
| |
| // PLEASE DON'T CLEAN UP. |
| // Commented out for now, since we change scope of Deliverable. |
| // else if (e instanceof WorkProductDescriptor |
| // && ((WorkProductDescriptor) e).getWorkProduct() instanceof |
| // Deliverable) { |
| // childFilter = new IFilter() { |
| // |
| // public boolean accept(Object obj) { |
| // return e instanceof WorkProductDescriptor |
| // && ((WorkProductDescriptor) e).getWorkProduct() instanceof |
| // Deliverable; |
| // } |
| // }; |
| // } |
| |
| if (childFilter != null) { |
| return checkNameInScope(adapterFactory, parent, e, nameFeature, newName, |
| childFilter, suppression, ignoreSuppressed); |
| } |
| |
| return null; |
| } |
| |
| private static String checkEmpty(Object e, String newName) { |
| // skip checking on activity that is a extender or local contributor |
| // |
| if(e instanceof Activity && ProcessUtil.isExtendingOrLocallyContributing((BreakdownElement) e)) { |
| return null; |
| } |
| |
| String elementType; |
| if (e instanceof NamedElement) { |
| elementType = TngUtil.getTypeText((NamedElement) e); |
| } else { |
| elementType = ELEMENT_TEXT; |
| } |
| if (newName == null || newName.trim().length() == 0) { |
| return NLS.bind(LibraryEditResources.emptyElementNameError_msg, |
| StrUtil.toLower(elementType)); |
| } |
| return null; |
| } |
| |
| /** |
| * Used by |
| * {@link #checkName(AdapterFactory, BreakdownElement, EStructuralFeature, String, Suppression, boolean) checkName()} |
| * |
| * @param e |
| * @return |
| */ |
| private static Class chooseType(BreakdownElement e) { |
| if (e instanceof Activity) { |
| return Activity.class; |
| } else if (e instanceof TaskDescriptor) { |
| return TaskDescriptor.class; |
| } else if (e instanceof RoleDescriptor) { |
| return RoleDescriptor.class; |
| } else if (e instanceof WorkProductDescriptor) { |
| return WorkProductDescriptor.class; |
| } else { |
| return e.getClass(); |
| } |
| // return BreakdownElement.class; |
| } |
| |
| private static String checkNameInScope(AdapterFactory adapterFactory, |
| Object currentParent, BreakdownElement e, |
| EStructuralFeature feature, String name, IFilter childFilter, |
| Suppression suppression, boolean ignoreSuppressed) { |
| // check up |
| for (Object parent = currentParent; parent != null;) { |
| String msg = checkName(adapterFactory, parent, e, childFilter, |
| feature, name, suppression, ignoreSuppressed); |
| if (msg != null) |
| return msg; |
| ITreeItemContentProvider itemProvider = (ITreeItemContentProvider) adapterFactory |
| .adapt(parent, ITreeItemContentProvider.class); |
| parent = itemProvider.getParent(parent); |
| } |
| |
| // check down |
| if (currentParent != null) { |
| Iterator iter = new AdapterFactoryTreeIterator(adapterFactory, |
| currentParent, false); |
| while (iter.hasNext()) { |
| Object child = TngUtil.unwrap(iter.next()); |
| if (child != e && childFilter.accept(child)) { |
| String childName = (String) ((EObject) child).eGet(feature); |
| if (name.equalsIgnoreCase(childName)) { |
| // return I18nUtil.formatString(RESOURCE_BUNDLE, key, |
| // data); |
| return NLS |
| .bind( |
| LibraryEditResources.duplicateElementNameError_msg, |
| name); |
| } |
| |
| } |
| } |
| } |
| |
| return null; |
| } |
| |
| public static String checkName(AdapterFactory adapterFactory, |
| final BreakdownElement e, EStructuralFeature feature, String name, |
| Suppression suppression) { |
| return checkName(adapterFactory, e, feature, name, suppression, false); |
| } |
| |
| /** |
| * Checks the name or presentation name of a breakdown element that is |
| * already part of a process. |
| * |
| * @param adapterFactory |
| * @param e |
| * @param feature |
| * @param name |
| * @param suppression |
| * @param ignoreSuppressed |
| * @return |
| */ |
| public static String checkName(AdapterFactory adapterFactory, |
| final BreakdownElement e, EStructuralFeature feature, String name, |
| Suppression suppression, boolean ignoreSuppressed) |
| { |
| return checkName(adapterFactory, (Object)null, e, (Class)null, feature, name, suppression, ignoreSuppressed); |
| } |
| |
| public static boolean canHaveEmptyPresentationName(DescribableElement e) { |
| if(e instanceof VariabilityElement) { |
| VariabilityType vType = ((VariabilityElement)e).getVariabilityType(); |
| return vType == VariabilityType.EXTENDS |
| || vType == VariabilityType.CONTRIBUTES |
| || vType == VariabilityType.LOCAL_CONTRIBUTION; |
| } |
| return false; |
| } |
| |
| public static boolean checkFilePathLength( |
| MethodElement parentElementWithResource, |
| MethodElement element, |
| String name, |
| int maxLength, |
| String[] filePathName) { |
| Resource res = parentElementWithResource.eResource(); |
| URI uri = res.getURI(); |
| if (filePathName != null && filePathName.length >= 1) { |
| //To do: calculate path |
| //filePathName[0] = ?? |
| } |
| |
| int parentResLen = uri.toFileString().length(); |
| int localGroupLen = 20; |
| if (parentElementWithResource instanceof MethodLibrary) { |
| localGroupLen = 0; |
| } else if (element instanceof Role) { |
| localGroupLen = 5; //"roles" |
| } else if (element instanceof CapabilityPattern) { |
| localGroupLen = 18; //"capabilitypatterns" |
| } |
| //More else if here |
| |
| int totalLen = parentResLen + localGroupLen + name.length(); |
| return totalLen <= maxLength; |
| } |
| } |