blob: 178c198773297bfc6ae9fc1821fa857495462790 [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.authoring.ui.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.provider.ItemProviderAdapter;
import org.eclipse.emf.edit.ui.action.ValidateAction.EclipseResourcesUtil;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.LibraryServiceListener;
import org.eclipse.epf.library.edit.LibraryEditResources;
import org.eclipse.epf.library.edit.TransientGroupItemProvider;
import org.eclipse.epf.library.edit.element.TransientContentPackageItemProvider;
import org.eclipse.epf.library.edit.navigator.ContentItemProvider;
import org.eclipse.epf.library.edit.navigator.MethodPackagesItemProvider;
import org.eclipse.epf.library.edit.navigator.ProcessesItemProvider;
import org.eclipse.epf.library.edit.util.ModelStructure;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.persistence.FileManager;
import org.eclipse.epf.persistence.util.PersistenceUtil;
import org.eclipse.epf.uma.ContentCategory;
import org.eclipse.epf.uma.ContentPackage;
import org.eclipse.epf.uma.CustomCategory;
import org.eclipse.epf.uma.Discipline;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.RoleSet;
import org.eclipse.epf.uma.util.AssociationHelper;
import org.eclipse.epf.uma.util.UmaUtil;
import org.eclipse.ui.ide.IDE;
/**
* @author Phong Nguyen Le
* @since 1.1
*/
public class LibraryValidationMarkerHelper extends EclipseResourcesUtil {
public static final LibraryValidationMarkerHelper INSTANCE = new LibraryValidationMarkerHelper();
public static final String GUID = "guid"; //$NON-NLS-1$
private static interface IParentProvider {
final IParentProvider containerProvider = new IParentProvider() {
public Collection<?> getParents(Object object) {
if(object instanceof EObject) {
return Collections.singleton(((EObject)object).eContainer());
}
return Collections.emptyList();
}
};
final IParentProvider parentCustomCategoryProvider = new IParentProvider() {
public Collection<?> getParents(Object object) {
if(object instanceof CustomCategory) {
return AssociationHelper.getCustomCategories((CustomCategory)object);
}
return Collections.emptyList();
}
};
final IParentProvider parentStandardCategoryProvider = new IParentProvider() {
public Collection<?> getParents(Object object) {
if(object instanceof Discipline) {
Discipline discipline = (Discipline) object;
List parentDisciplines = AssociationHelper.getDiscipline(discipline);
List disciplineGroupings = AssociationHelper.getDisciplineGroups(discipline);
if(!parentDisciplines.isEmpty() && !disciplineGroupings.isEmpty()) {
Collection<Object> parents = new ArrayList<Object>(disciplineGroupings);
parents.addAll(parentDisciplines);
return parents;
}
else {
return parentDisciplines.isEmpty() ? disciplineGroupings : parentDisciplines;
}
}
else if(object instanceof RoleSet) {
return AssociationHelper.getRoleSetGroups((RoleSet) object);
}
return Collections.emptyList();
}
};
Collection<?> getParents(Object object);
}
private static class ErrorCalculator extends HashMap<MethodPlugin, Set<MethodElement>> {
/**
*
*/
private static final long serialVersionUID = 1L;
public ErrorCalculator() {
super();
initialize();
LibraryService.getInstance().addListener(new LibraryServiceListener() {
public void libraryOpened(MethodLibrary library) {
initialize();
}
public void libraryClosed(MethodLibrary library) {
clear();
}
public void libraryReopened(MethodLibrary library) {
initialize();
}
});
}
private void initialize() {
clear();
// fill this set with containers of marked objects
//
MethodLibrary lib = LibraryService.getInstance().getCurrentMethodLibrary();
if(lib != null) {
IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot();
try {
IMarker[] markers = wsRoot.findMarkers(INSTANCE.getMarkerID(), false, IResource.DEPTH_INFINITE);
for (int i = 0; i < markers.length; i++) {
IMarker marker = markers[i];
String guid = (String) marker.getAttribute(GUID);
MethodElement e = LibraryService.getInstance().getCurrentLibraryManager().getMethodElement(guid);
if(e != null) {
if(e.eIsProxy()) {
e = (MethodElement) PersistenceUtil.resolve(e,
LibraryService.getInstance()
.getCurrentMethodLibrary()
.eResource().getResourceSet());
}
// add the element to this set
//
addError(e);
}
}
} catch (CoreException e) {
}
}
}
public void addError(MethodElement e) {
MethodPlugin plugin = UmaUtil.getMethodPlugin(e);
if(plugin != null) {
Set<MethodElement> elements = get(plugin);
if(elements == null) {
elements = new HashSet<MethodElement>();
put(plugin, elements);
}
elements.add(e);
}
}
public void removeError(MethodElement e) {
MethodPlugin plugin = UmaUtil.getMethodPlugin(e);
if(plugin != null) {
Set<MethodElement> elements = get(plugin);
if(elements != null) {
elements.remove(e);
if(elements.isEmpty()) {
remove(plugin);
}
}
}
}
public boolean hasErrors(MethodElement e) {
MethodPlugin plugin = UmaUtil.getMethodPlugin(e);
if(plugin != null) {
Set<MethodElement> elements = get(plugin);
if(elements != null) {
if(elements.contains(e)) {
return true;
}
// check if e is container of any error element
//
HashSet<Object> processedChildren = null;
for (MethodElement me : elements) {
if(UmaUtil.isContainedBy(me, e)) {
return true;
}
if(me instanceof CustomCategory) {
if(processedChildren == null) {
processedChildren = new HashSet<Object>();
}
else {
processedChildren.clear();
}
if(isParentOf(me, e, IParentProvider.parentCustomCategoryProvider, processedChildren)) {
return true;
}
}
else if(me instanceof ContentCategory) {
// me must be a standard category
// currently all content packages that contain
// standard categories are not contained by
// predefined content package "Standard Categories"
// we need to handle this specially here
//
if(e instanceof ContentPackage && e == UmaUtil.findContentPackage(plugin, ModelStructure.DEFAULT.standardCategoryPath)) {
return true;
}
if(processedChildren == null) {
processedChildren = new HashSet<Object>();
}
else {
processedChildren.clear();
}
if(isParentOf(me, e, IParentProvider.parentStandardCategoryProvider, processedChildren)) {
return true;
}
}
}
}
}
return false;
}
private static boolean isParentOf(Object child, Object parent, IParentProvider parentProvider, Set<Object> processedChildren) {
processedChildren.add(child);
for (Object myParent : parentProvider.getParents(child)) {
if(myParent == parent) {
return true;
}
if(!processedChildren.contains(myParent) && isParentOf(myParent, parent, parentProvider, processedChildren)) {
return true;
}
}
return false;
}
}
private static ErrorCalculator errorCalculator = new ErrorCalculator();
/* (non-Javadoc)
* @see org.eclipse.emf.common.ui.MarkerHelper#getFile(org.eclipse.emf.common.util.URI)
*/
protected IFile getFile(URI uri) {
if(uri.isFile()) {
return (IFile) FileManager.getResourceForLocation(uri.toFileString());
}
return super.getFile(uri);
}
/* (non-Javadoc)
* @see org.eclipse.emf.edit.ui.util.EditUIMarkerHelper#adjustMarker(org.eclipse.core.resources.IMarker, org.eclipse.emf.common.util.Diagnostic)
*/
protected boolean adjustMarker(IMarker marker, Diagnostic diagnostic) throws CoreException {
boolean ret = super.adjustMarker(marker, diagnostic);
if(!diagnostic.getData().isEmpty()) {
Object o = diagnostic.getData().get(0);
if(o instanceof MethodElement) {
marker.setAttribute(GUID, ((MethodElement)o).getGuid());
marker.setAttribute(IMarker.LOCATION, TngUtil.getLabelWithPath(o));
marker.setAttribute(IDE.EDITOR_ID_ATTR, "org.eclipse.epf.authoring.ui.editors.MethodElementEditor"); //$NON-NLS-1$
errorCalculator.addError((MethodElement) o);
}
}
return ret;
}
public static boolean isInvalid(Object object) {
if(object instanceof ProcessesItemProvider) {
// this is an UI object: Processes
//
ProcessesItemProvider ip = (ProcessesItemProvider) object;
MethodElement o;
return ((o = ip.getCapabilityPatternPackage()) != null && errorCalculator.hasErrors(o))
|| ((o = ip.getDeliveryProcessPackage()) != null && errorCalculator.hasErrors(o));
}
else if(object instanceof MethodPackagesItemProvider) {
// this is an UI object
//
object = ((ItemProviderAdapter)object).getTarget();
}
else if(object instanceof ContentItemProvider) {
ContentPackage coreContentPkg = ((ContentItemProvider)object).getCoreContentPackage();
if(coreContentPkg != null) {
object = coreContentPkg.eContainer();
}
}
else if(object instanceof TransientContentPackageItemProvider) {
// this is an UI object: either Tasks, Roles, Work Products, or Guidance
//
Collection<?> children = ((TransientContentPackageItemProvider)object).getChildren(object);
for (Iterator<?> iter = children.iterator(); iter.hasNext();) {
Object child = TngUtil.unwrap(iter.next());
if(child instanceof MethodElement && errorCalculator.hasErrors((MethodElement) child)) {
return true;
}
}
return false;
}
else if(object instanceof TransientGroupItemProvider) {
object = ((TransientGroupItemProvider)object).getTarget();
}
return ((object = TngUtil.unwrap(object)) instanceof MethodElement && errorCalculator
.hasErrors((MethodElement) object));
}
/* (non-Javadoc)
* @see org.eclipse.emf.common.ui.MarkerHelper#hasMarkers(java.lang.Object)
*/
public boolean hasMarkers(Object object) {
if(object instanceof MethodElement) {
IResource resource = getFile(object);
if (resource != null && resource.exists())
{
try
{
String guid = ((MethodElement)object).getGuid();
IMarker[] markers = resource.findMarkers(getMarkerID(), false, IResource.DEPTH_ZERO);
for (int i = 0; i < markers.length; i++) {
IMarker marker = markers[i];
if(guid.equals(marker.getAttribute(GUID))) {
return true;
}
}
}
catch (CoreException e)
{
}
}
return false;
}
return super.hasMarkers(object);
}
@Override
protected IFile getFile(Object datum) {
try {
return super.getFile(datum);
}
catch(Exception e) {
return null;
}
}
public void deleteMarkers(Object object) {
if(object instanceof MethodElement) {
IResource resource = getFile(object);
if (resource != null && resource.exists())
{
try
{
MethodElement e = (MethodElement) object;
String guid = e.getGuid();
IMarker[] markers = resource.findMarkers(getMarkerID(), false, IResource.DEPTH_ZERO);
for (int i = 0; i < markers.length; i++) {
IMarker marker = markers[i];
if(guid.equals(marker.getAttribute(GUID))) {
marker.delete();
errorCalculator.removeError(e);
}
}
}
catch (CoreException e)
{
}
}
return;
}
super.deleteMarkers(object);
}
protected void deleteMarkers(IResource resource, boolean includeSubtypes, int depth) {
if (resource != null && resource.exists()) {
try {
IMarker[] markers = resource.findMarkers(getMarkerID(), false, IResource.DEPTH_ZERO);
for (int i = 0; i < markers.length; i++) {
IMarker marker = markers[i];
String guid = (String) marker.getAttribute(GUID);
MethodElement e = LibraryService.getInstance().getCurrentLibraryManager().getMethodElement(guid);
if(e != null) {
errorCalculator.removeError(e);
}
}
} catch (CoreException e) {
}
}
super.deleteMarkers(resource, includeSubtypes, depth);
}
//Override to seperate error message in error dialog and problems view (bug 174351)
//Note: better fix is to extend BasicDiagnostic to encapsulate both types of msgs -> to do later
protected String composeMessage(Diagnostic diagnostic, Diagnostic parentDiagnostic) {
int ix = diagnostic.getMessage().indexOf(LibraryEditResources.duplicateElementNameError_msg2);
if (ix > 0) {
return diagnostic.getMessage().substring(0, ix);
}
return super.composeMessage(diagnostic, parentDiagnostic);
}
}