blob: 4abd5df42e8467f737d153a9df7fe5a41b5e79d5 [file] [log] [blame]
/***************************************************************************************************
* Copyright (c) 2003, 2004 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 API and implementation
**************************************************************************************************/
package org.eclipse.jst.j2ee.internal.delete;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jem.util.emf.workbench.JavaProjectUtilities;
import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveManifest;
import org.eclipse.jst.j2ee.commonarchivecore.internal.util.ArchiveUtil;
import org.eclipse.jst.j2ee.internal.earcreation.EARNatureRuntime;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.j2ee.internal.project.J2EECreationResourceHandler;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.wst.common.frameworks.internal.enablement.nonui.WFTWrappedException;
import org.eclipse.wst.common.frameworks.internal.operations.WTPOperation;
public class DeleteModuleDependencyOperation extends WTPOperation {
protected List earNatures;
protected Set projects;
protected Map deleteInfos;
protected IProgressMonitor monitor;
protected static String MOD_DEP_DELETE_ERRORS = J2EECreationResourceHandler.getString("Errors_occurred_deleting_module_dependencies_UI_"); //$NON-NLS-1$
protected List affectedFiles = null;
public DeleteModuleDependencyOperation(List earNatures, Set projects) {
this.earNatures = earNatures;
this.projects = projects;
}
protected Map getDeleteInfos() {
if (deleteInfos == null)
deleteInfos = new HashMap();
return deleteInfos;
}
protected ClasspathDeleteInfo getDeleteInfo(IProject referencingProject) {
ClasspathDeleteInfo info = (ClasspathDeleteInfo) getDeleteInfos().get(referencingProject);
if (info != null)
return info;
info = new ClasspathDeleteInfo(referencingProject);
deleteInfos.put(referencingProject, info);
return info;
}
/**
* @see HeadlessJ2EEOperation#execute(IProgressMonitor)
*/
protected void execute(IProgressMonitor aMonitor) throws CoreException, InvocationTargetException, InterruptedException {
this.monitor = aMonitor;
gatherDeleteInfoIfNecessary();
executeDeleteInfo();
}
/*
* Iterate the edit models; for each edit model, iterate the projects; for each project... find
* the module for the project find all the modules that reference the module for each of those,
* resolve back to a project and cache the runtime classpath entry and project name going away
*/
protected void gatherDeleteInfoIfNecessary() {
if (deleteInfos == null || deleteInfos.isEmpty()) {
for (int i = 0; i < earNatures.size(); i++) {
EARNatureRuntime nature = (EARNatureRuntime) earNatures.get(i);
gatherDeleteInfo(nature);
}
}
}
protected void gatherDeleteInfo(EARNatureRuntime runtime) {
Map urisToProjects = runtime.getAllMappedProjects();
for (Iterator iterator = projects.iterator(); iterator.hasNext();) {
IProject project = (IProject) iterator.next();
gatherDeleteInfo(runtime, urisToProjects, project);
}
}
/*
* If this project is referenced by the EAR iterate all the other projects referenced by the EAR
* for each project p if the p references the referenced project, add the reference to the
* delete info
*/
protected void gatherDeleteInfo(EARNatureRuntime runtime, Map urisToProjects, IProject referencedProject) {
String referencedProjectURI = runtime.getJARUri(referencedProject);
if (referencedProjectURI == null)
return;
Iterator it = urisToProjects.entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String uri = (String) entry.getKey();
IProject project = (IProject) entry.getValue();
if (referencedProject.equals(project) || projects.contains(project))
continue;
gatherDeleteInfo(uri, project, referencedProject, referencedProjectURI);
}
}
protected void gatherDeleteInfo(String testUri, IProject testProject, IProject referencedProject, String moduleUri) {
ArchiveManifest mf = J2EEProjectUtilities.readManifest(testProject);
if (mf == null)
return;
String[] classpath = mf.getClassPathTokenized();
for (int i = 0; i < classpath.length; i++) {
String resolved = ArchiveUtil.deriveEARRelativeURI(classpath[i], testUri);
if (!moduleUri.equals(resolved))
continue;
ClasspathDeleteInfo info = getDeleteInfo(testProject);
info.getManifestEntries().add(classpath[i]);
info.getReferencedProjects().add(referencedProject);
}
}
protected void executeDeleteInfo() throws InvocationTargetException {
if (deleteInfos == null)
return;
Iterator it = deleteInfos.values().iterator();
while (it.hasNext()) {
ClasspathDeleteInfo info = (ClasspathDeleteInfo) it.next();
IProject p = info.getTargetProject();
if (JavaProjectUtilities.isBinaryProject(p)) {
String message = J2EECreationResourceHandler.getString("Can_not_remove_module_dependency_from_project_UI_", new Object[]{p.getName()}); //$NON-NLS-1$
addErrorStatus(message);
continue;
}
try {
replaceManifest(p, info);
replaceBuildPath(p, info);
} catch (Exception ex) {
throw new WFTWrappedException(ex);
}
}
}
protected void replaceManifest(IProject project, ClasspathDeleteInfo info) throws IOException {
ArchiveManifest mf = J2EEProjectUtilities.readManifest(project);
if (mf == null)
return;
String[] entries = mf.getClassPathTokenized();
StringBuffer sb = new StringBuffer();
boolean empty = true;
for (int i = 0; i < entries.length; i++) {
String entry = entries[i];
if (info.getManifestEntries().contains(entry))
continue;
if (!empty)
sb.append(" "); //$NON-NLS-1$
empty = false;
sb.append(entries[i]);
}
mf.setClassPath(sb.toString());
J2EEProjectUtilities.writeManifest(project, mf);
}
protected void replaceBuildPath(IProject project, ClasspathDeleteInfo info) throws JavaModelException {
IJavaProject javaP = JavaProjectUtilities.getJavaProject(project);
if (javaP == null)
return;
List result = new ArrayList();
IClasspathEntry[] entries = javaP.getRawClasspath();
for (int i = 0; i < entries.length; i++) {
IClasspathEntry entry = entries[i];
if (shouldKeepEntry(entry, info))
result.add(entry);
}
IClasspathEntry[] toArray = (IClasspathEntry[]) result.toArray(new IClasspathEntry[result.size()]);
javaP.setRawClasspath(toArray, new SubProgressMonitor(monitor, 1));
}
protected boolean shouldKeepEntry(IClasspathEntry entry, ClasspathDeleteInfo info) {
if (entry.getEntryKind() != IClasspathEntry.CPE_PROJECT)
return true;
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(entry.getPath().toString());
return !info.getReferencedProjects().contains(project);
}
/**
* Return a list of all the files that will get modified as a result of running this operation;
* used for validateEdit
*/
protected List getAffectedFiles() {
if (affectedFiles == null)
affectedFiles = gatherAffectedFiles();
return affectedFiles;
}
protected List gatherAffectedFiles() {
gatherDeleteInfoIfNecessary();
if (deleteInfos == null || deleteInfos.isEmpty())
return Collections.EMPTY_LIST;
List result = new ArrayList();
Iterator it = deleteInfos.values().iterator();
while (it.hasNext()) {
ClasspathDeleteInfo info = (ClasspathDeleteInfo) it.next();
IProject p = info.getTargetProject();
IFile aFile = J2EEProjectUtilities.getManifestFile(p);
if (aFile != null && aFile.exists()) {
result.add(aFile);
result.addAll(ProjectUtilities.getFilesAffectedByClasspathChange(p));
}
}
return result;
}
protected void addErrorStatus(String message) {
IStatus newStatus = J2EEPlugin.newErrorStatus(message, null);
addStatus(newStatus);
// if (status.isOK())
// status = newStatus;
// else if (status.isMultiStatus())
// ((MultiStatus)status).add(newStatus);
// else {
// IStatus[] children = new IStatus[] {status, newStatus};
// status = new MultiStatus(J2EEPlugin.PLUGIN_ID, 0, children, MOD_DEP_DELETE_ERRORS, null);
// }
}
}