blob: 6708297d4f42c2cfec2b348776bfb2aa881a40d4 [file] [log] [blame]
package org.eclipse.epf.library.validation;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.epf.library.LibraryPlugin;
import org.eclipse.epf.library.LibraryResources;
import org.eclipse.epf.library.edit.LibraryEditPlugin;
import org.eclipse.epf.library.edit.LibraryEditResources;
import org.eclipse.epf.library.edit.util.LibraryEditUtil;
import org.eclipse.epf.library.edit.util.Misc;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.edit.validation.ValidationStatus;
import org.eclipse.epf.library.util.LibraryUtil;
import org.eclipse.epf.persistence.FileManager;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.util.UmaUtil;
import org.eclipse.epf.validation.LibraryEValidator;
public class UndeclaredDependencyCheck extends ValidationAction {
private Map<MethodPlugin, Set<MethodPlugin>> baseMap;
private Map<MethodPlugin, Set<MethodPlugin>> problemPluginMap;
private Map<String, Set<MethodElement>> problemElementMap;
private boolean skipContent = true;
public UndeclaredDependencyCheck(ValidationManager mgr) {
super(mgr);
}
@Override
public void run() {
Set<MethodPlugin> pluginSet = getMgr().getPluginSet();
if (pluginSet == null || pluginSet.isEmpty()) {
return;
}
//Initialization
problemPluginMap = new HashMap<MethodPlugin, Set<MethodPlugin>>();
problemElementMap = new HashMap<String, Set<MethodElement>>();
baseMap = new HashMap<MethodPlugin, Set<MethodPlugin>>();
Misc.clearCachedMap();
for (MethodPlugin plugin : pluginSet) {
Set baseSet = new HashSet();
baseSet.addAll(Misc.getAllBase1(plugin));
baseMap.put(plugin, baseSet);
}
Misc.clearCachedMap();
//Validation check
Set<MethodElement> processed = new HashSet<MethodElement>();
for (MethodPlugin plugin : pluginSet) {
checkReferences(plugin, processed);
}
MultiStatus multiStatus = new MultiStatus(LibraryPlugin.PLUGIN_ID, 0, "", null); //$NON-NLS-1$
//Build markers
for (Map.Entry<MethodPlugin, Set<MethodPlugin>> entry : problemPluginMap
.entrySet()) {
MethodPlugin plugin = entry.getKey();
Set<MethodPlugin> set = entry.getValue();
String msg0 = LibraryResources.bind(LibraryResources.UndeclaredDep_MarkerTxt1, (new String[] {plugin.getName()}));
for (MethodPlugin p : set) {
IMarker marker = getMgr().createMarker(plugin);
String msg = msg0 + " '" + p.getName() + "'"; //$NON-NLS-1$ //$NON-NLS-2$
String key = plugin.getGuid() + p.getGuid();
Set<MethodElement> elements = problemElementMap.get(key);
if (elements != null && !elements.isEmpty()) {
String line2msg0 = ". \n" + LibraryResources.UndeclaredDep_MarkerTxt2 + " "; //$NON-NLS-1$ //$NON-NLS-2$
String line2msg = line2msg0;
for (MethodElement e : elements) {
if (line2msg.length() > 155) {
line2msg += " ... "; //$NON-NLS-1$
break;
}
if (line2msg != line2msg0) {
line2msg += "; "; //$NON-NLS-1$
}
line2msg += TngUtil.getLabelWithPath(e);
}
msg += line2msg;
}
try {
marker.setAttribute(IMarker.MESSAGE, msg);
marker.setAttribute(IMarker.SEVERITY,
IMarker.SEVERITY_WARNING);
marker.setAttribute(IMarker.LOCATION, TngUtil.getLabelWithPath(plugin));
marker.setAttribute(ValidationManager.validationType, ValidationManager.validationType_undeclaredDependancyCheck);
MarkerInfo markerInfo = new MarkerInfo(plugin, p, elements);
getMgr().addToMarkInfoMap(marker, markerInfo);
multiStatus.add(new ValidationStatus(IStatus.WARNING, 0, LibraryResources.UndeclaredDep_MarkerTxt0, plugin, null));
} catch (Exception e) {
LibraryPlugin.getDefault().getLogger().logError(e);
}
}
}
LibraryEValidator.appendDiagnostics(multiStatus, getMgr().getDiagnostics());
//Clear
problemPluginMap = null;
problemElementMap = null;
baseMap =null;
}
private void addToProblemPluginMap(MethodPlugin plugin, MethodPlugin referencedPlugin) {
Set<MethodPlugin> set = problemPluginMap.get(plugin);
if (set == null) {
set = new HashSet<MethodPlugin>();
problemPluginMap.put(plugin, set);
}
set.add(referencedPlugin);
}
private void checkReferences(MethodElement me, Set<MethodElement> processed) {
if (processed.contains(me)) {
return;
}
processed.add(me);
MethodPlugin ownerPlugin = UmaUtil.getMethodPlugin(me);
if ( ! getMgr().getPluginSet().contains(ownerPlugin)) {
return;
}
Set<MethodPlugin> baseSet = baseMap.get(ownerPlugin);
EList<EReference> refList = me.eClass().getEAllReferences();
if (refList == null || refList.isEmpty()) {
return;
}
for (EReference ref : refList) {
if (skipContent && LibraryUtil.isContentRef(ref)) {
continue;
}
if (ref == UmaPackage.eINSTANCE.getRole_Modifies()) {
continue;
}
if (ref == UmaPackage.eINSTANCE.getRoleDescriptor_Modifies()) {
continue;
}
Object obj = me.eGet(ref);
if (obj instanceof MethodElement) {
MethodElement referenced = (MethodElement) obj;
recordOneHit(me, ownerPlugin, baseSet, referenced);
checkReferences(referenced, processed);
} else if (obj instanceof List) {
List list = (List) obj;
for (Object itemObj : list) {
if (itemObj instanceof MethodElement) {
MethodElement referenced = (MethodElement) itemObj;
recordOneHit(me, ownerPlugin, baseSet, referenced);
checkReferences(referenced, processed);
}
}
}
}
}
private void recordOneHit(MethodElement me, MethodPlugin ownerPlugin,
Set<MethodPlugin> baseSet, MethodElement referenced) {
MethodPlugin referencedPlugin = UmaUtil.getMethodPlugin(referenced);
if (referencedPlugin != null && referencedPlugin != ownerPlugin && !baseSet.contains(referencedPlugin)) {
addToProblemPluginMap(ownerPlugin, referencedPlugin);
String key = ownerPlugin.getGuid() + referencedPlugin.getGuid();
Set<MethodElement> set = problemElementMap.get(key);
if (set == null) {
set = new HashSet<MethodElement>();
problemElementMap.put(key, set);
}
set.add(me);
}
}
public void clearResults() {
}
public String addPluginFix(IMarker marker) {
String emptyStr = ""; //$NON-NLS-1$
Object obj = getMgr().getMarkInfo(marker);
MarkerInfo info = obj instanceof MarkerInfo ? (MarkerInfo) obj : null;
if (info == null) {
return emptyStr;
}
if (info.referencing == null || info.referenced == null || info.referencing == info.referenced) {
return emptyStr;
}
if (Misc.isBaseOf(info.referencing, info.referenced, new HashMap())) {
return LibraryEditResources.circular_dependency_error_msg;
}
info.referencing.getBases().add(info.referenced);
Resource resource = info.referencing.eResource();
if (resource == null || !LibraryEditUtil.getInstance().save(Collections.singleton(resource))) {
info.referencing.getBases().remove(info.referenced);
LibraryPlugin.getDefault().getLogger().logError("addPluginFix falied at save");//$NON-NLS-1$
return emptyStr;
}
getMgr().removeFromMarkInfoMap(marker);
return emptyStr;
}
public String removeReferenceFix(IMarker marker) {
String emptyStr = ""; //$NON-NLS-1$
Object infoObj = getMgr().getMarkInfo(marker);
MarkerInfo info = infoObj instanceof MarkerInfo ? (MarkerInfo) infoObj : null;
if (info == null || info.referenced == null) {
return emptyStr;
}
Set<MethodElement> offenderElements = info.offenderElements;
if (offenderElements == null || offenderElements.isEmpty()) {
return emptyStr;
}
Set<Resource> resources = new HashSet<Resource>();
for (MethodElement e : offenderElements) {
Resource res = e.eResource();
if (res != null) {
resources.add(res);
}
}
List<String> pathList = new ArrayList<String>();
for (Resource res : resources) {
pathList.add(res.getURI().toFileString());
}
IStatus status = FileManager.getInstance().checkModify(pathList.toArray(new String[pathList.size()]), LibraryPlugin.getDefault().getContext());
if (!status.isOK()) {
info.referencing.getBases().remove(info.referenced);
LibraryPlugin.getDefault().getLogger().logError("addPluginFix falied at file check");//$NON-NLS-1$
return emptyStr;
}
for (MethodElement me : offenderElements) {
EList<EReference> refList = me.eClass().getEAllReferences();
if (refList == null) {
continue;
}
for (EReference ref : refList) {
if (skipContent && LibraryUtil.isContentRef(ref)) {
continue;
}
if (ref == UmaPackage.eINSTANCE.getRole_Modifies()) {
continue;
}
Object obj = me.eGet(ref);
if (obj instanceof MethodElement) {
MethodElement referenced = (MethodElement) obj;
if (info.referenced == UmaUtil.getMethodPlugin(referenced)) {
me.eSet(ref, null);
}
} else if (obj instanceof List) {
List list = (List) obj;
for (int i = list.size() - 1; i >= 0 ; i--) {
Object itemObj = list.get(i);
if (itemObj instanceof MethodElement) {
MethodElement referenced = (MethodElement) itemObj;
if (info.referenced == UmaUtil.getMethodPlugin(referenced)) {
list.remove(i);
}
}
}
}
}
}
if (!LibraryEditUtil.getInstance().save(resources)) {
info.referencing.getBases().remove(info.referenced);
LibraryPlugin.getDefault().getLogger().logError("addPluginFix falied at save");//$NON-NLS-1$
return emptyStr;
}
getMgr().removeFromMarkInfoMap(marker);
return emptyStr;
}
static class MarkerInfo {
MethodPlugin referencing;
MethodPlugin referenced;
Set<MethodElement> offenderElements;
public MarkerInfo(MethodPlugin referencing, MethodPlugin referenced, Set<MethodElement> offenderElements) {
this.referencing = referencing;
this.referenced = referenced;
this.offenderElements = offenderElements;
}
}
}