| /******************************************************************************* |
| * Copyright (c) 2003, 2005 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.common.operations; |
| |
| import java.lang.reflect.InvocationTargetException; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Set; |
| |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IProjectDescription; |
| import org.eclipse.core.resources.IWorkspaceRoot; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.SubProgressMonitor; |
| import org.eclipse.jdt.core.IClasspathEntry; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.core.JavaCore; |
| import org.eclipse.jface.operation.IRunnableContext; |
| import org.eclipse.jst.j2ee.application.internal.operations.ClassPathSelection; |
| import org.eclipse.jst.j2ee.application.internal.operations.ClasspathElement; |
| import org.eclipse.wst.common.frameworks.internal.DoNotUseMeThisWillBeDeletedPost15; |
| import org.eclipse.wst.common.frameworks.internal.enablement.nonui.WFTWrappedException; |
| import org.eclipse.wst.common.frameworks.internal.operations.IHeadlessRunnableWithProgress; |
| |
| /** |
| * {@link DoNotUseMeThisWillBeDeletedPost15} |
| * |
| * @deprecated This should no longer be necessary because of the new EAR & Web Lib classpath |
| * containers |
| */ |
| public class UpdateJavaBuildPathOperation implements IHeadlessRunnableWithProgress { |
| protected IJavaProject javaProject; |
| protected ClassPathSelection classPathSelection; |
| // All the Java build path entries created by the classpath selection |
| protected Set allClasspathEntries; |
| protected List allUnselectedClasspathEntries; |
| |
| /** |
| * UpdateJavaBuildPathOperation constructor comment. |
| */ |
| public UpdateJavaBuildPathOperation(IJavaProject aJavaProject, ClassPathSelection aClassPathSelection) { |
| super(); |
| javaProject = aJavaProject; |
| classPathSelection = aClassPathSelection; |
| allClasspathEntries = new HashSet(); |
| IClasspathEntry[] classpathEntry = aClassPathSelection.getClasspathEntriesForSelected(); |
| if (classpathEntry != null) |
| allClasspathEntries.addAll(Arrays.asList(classpathEntry)); |
| } |
| |
| /** |
| * UpdateJavaBuildPathOperation constructor comment. |
| */ |
| public UpdateJavaBuildPathOperation(IJavaProject aJavaProject, ClassPathSelection selected, ClassPathSelection unselected) { |
| super(); |
| javaProject = aJavaProject; |
| classPathSelection = selected; |
| allClasspathEntries = new HashSet(); |
| if (selected != null && !selected.getClasspathElements().isEmpty()) |
| allClasspathEntries.addAll(Arrays.asList(selected.getClasspathEntriesForSelected())); |
| |
| allUnselectedClasspathEntries = new ArrayList(); |
| if (unselected != null && !unselected.getClasspathElements().isEmpty()) |
| allUnselectedClasspathEntries.addAll(unselected.getClasspathElements()); |
| } |
| |
| public UpdateJavaBuildPathOperation(IJavaProject aJavaProject, ClassPathSelection selected, List unselected) { |
| super(); |
| javaProject = aJavaProject; |
| classPathSelection = selected; |
| allClasspathEntries = new HashSet(); |
| if (selected != null && !selected.getClasspathElements().isEmpty()) |
| allClasspathEntries.addAll(Arrays.asList(selected.getClasspathEntriesForSelected())); |
| |
| allUnselectedClasspathEntries = new ArrayList(); |
| if (unselected != null && !unselected.isEmpty()) |
| allUnselectedClasspathEntries.addAll(unselected); |
| } |
| |
| protected void ensureClasspathEntryIsExported(List cp, IClasspathEntry entry) { |
| if (entry.isExported()) |
| return; |
| int index = getIndex(cp, entry); |
| IClasspathEntry newEntry = null; |
| switch (entry.getEntryKind()) { |
| case IClasspathEntry.CPE_PROJECT : |
| newEntry = JavaCore.newProjectEntry(entry.getPath(), true); |
| break; |
| case IClasspathEntry.CPE_LIBRARY : |
| newEntry = JavaCore.newLibraryEntry(entry.getPath(), entry.getSourceAttachmentPath(), entry.getSourceAttachmentRootPath(), true); |
| break; |
| case IClasspathEntry.CPE_VARIABLE : |
| newEntry = JavaCore.newVariableEntry(entry.getPath(), entry.getSourceAttachmentPath(), entry.getSourceAttachmentRootPath()); |
| default : |
| break; |
| } |
| if (entry != null) |
| cp.set(index, newEntry); |
| } |
| |
| protected IClasspathEntry ensureElementInList(List cp, ClasspathElement element, IClasspathEntry predecessor) { |
| IClasspathEntry addedEntry = null; |
| // The element might have multiple entries in the case of |
| // the imported_classes.jar file |
| IClasspathEntry[] cpEntries = element.newClasspathEntries(); |
| if (cpEntries == null || cpEntries.length == 0) |
| // indicates an invalid entry |
| return null; |
| |
| int predecessorPos = predecessor == null ? -1 : getIndex(cp, predecessor); |
| addedEntry = cpEntries[0]; |
| // Ensure that the first item is in the list, and follows |
| // the predecessor if specified; preserve existing items in |
| // the case of source attachments |
| int pos = getIndex(cp, addedEntry); |
| if (pos == -1) { |
| if (predecessorPos == -1) |
| cp.add(addedEntry); |
| else |
| cp.add(predecessorPos + 1, addedEntry); |
| } else { |
| addedEntry = (IClasspathEntry) cp.get(pos); |
| if (pos < predecessorPos) { |
| cp.remove(addedEntry); |
| cp.add(predecessorPos, addedEntry); |
| } |
| } |
| ensureClasspathEntryIsExported(cp, addedEntry); |
| |
| // Remove and add so we can ensure the proper order; this |
| // is the case of the imported_classes.jar; we always want it |
| // directly after the project |
| for (int i = 1; i < cpEntries.length; i++) { |
| int index = getIndex(cp, cpEntries[i]); |
| if (index != -1) { |
| addedEntry = (IClasspathEntry) cp.get(index); |
| cp.remove(index); |
| } else |
| addedEntry = cpEntries[i]; |
| pos = getIndex(cp, cpEntries[0]); |
| cp.add(pos + 1, addedEntry); |
| } |
| return addedEntry; |
| } |
| |
| protected int getIndex(List cp, IClasspathEntry entry) { |
| for (int i = 0; i < cp.size(); i++) { |
| IClasspathEntry elmt = (IClasspathEntry) cp.get(i); |
| if (elmt.getPath().equals(entry.getPath())) |
| return i; |
| } |
| return -1; |
| } |
| |
| protected void ensureElementNotInList(List cp, ClasspathElement element) { |
| IClasspathEntry[] cpEntries = element.newClasspathEntries(); |
| if (cpEntries == null || cpEntries.length == 0) |
| return; |
| for (int i = 0; i < cpEntries.length; i++) { |
| if (allClasspathEntries.contains(cpEntries[i])) |
| // This may be included indirectly by a transitive dependency |
| continue; |
| int index = getIndex(cp, cpEntries[i]); |
| if (index != -1) |
| cp.remove(index); |
| } |
| } |
| |
| protected void ensureRemoveElementInList(List cp, ClasspathElement element) { |
| IClasspathEntry[] cpEntries = element.newClasspathEntries(); |
| if (cpEntries == null || cpEntries.length == 0) |
| return; |
| for (int i = 0; i < cpEntries.length; i++) { |
| if (cp.contains(cpEntries[i])) { |
| int index = getIndex(cp, cpEntries[i]); |
| if (index != -1) |
| cp.remove(index); |
| } |
| } |
| } |
| |
| /** |
| * Runs this operation. Progress should be reported to the given progress monitor. This method |
| * is usually invoked by an <code>IRunnableContext</code>'s<code>run</code> method, which |
| * supplies the progress monitor. A request to cancel the operation should be honored and |
| * acknowledged by throwing <code>InterruptedException</code>. |
| * |
| * @param monitor |
| * the progress monitor to use to display progress and receive requests for |
| * cancelation |
| * @exception InvocationTargetException |
| * if the run method must propagate a checked exception, it should wrap it inside |
| * an <code>InvocationTargetException</code>; runtime exceptions are |
| * automatically wrapped in an <code>InvocationTargetException</code> by the |
| * calling context |
| * @exception InterruptedException |
| * if the operation detects a request to cancel, using |
| * <code>IProgressMonitor.isCanceled()</code>, it should exit by throwing |
| * <code>InterruptedException</code> |
| * |
| * @see IRunnableContext#run |
| */ |
| public void run(org.eclipse.core.runtime.IProgressMonitor monitor) throws java.lang.reflect.InvocationTargetException, InterruptedException { |
| try { |
| String[] prevRequiredProjects = javaProject.getRequiredProjectNames(); |
| List cp = new ArrayList(Arrays.asList(javaProject.getRawClasspath())); |
| List classpathElements = classPathSelection.getClasspathElements(); |
| IClasspathEntry predecessor = null; |
| IClasspathEntry result = null; |
| for (int i = 0; i < classpathElements.size(); i++) { |
| ClasspathElement element = (ClasspathElement) classpathElements.get(i); |
| if (element.isSelected()) { |
| result = ensureElementInList(cp, element, predecessor); |
| if (result != null) |
| predecessor = result; |
| } else |
| ensureElementNotInList(cp, element); |
| } |
| filterUnselectedEntries(cp); |
| IClasspathEntry[] newCp = ((IClasspathEntry[]) cp.toArray(new IClasspathEntry[cp.size()])); |
| javaProject.setRawClasspath(newCp, monitor); |
| updateRequiredProjects(javaProject, prevRequiredProjects, new SubProgressMonitor(monitor, 1)); |
| } catch (Exception ex) { |
| throw new WFTWrappedException(ex); |
| } |
| } |
| |
| private void filterUnselectedEntries(List cp) { |
| if (allUnselectedClasspathEntries != null) { |
| for (int i = 0; i < allUnselectedClasspathEntries.size(); i++) { |
| ClasspathElement element = (ClasspathElement) allUnselectedClasspathEntries.get(i); |
| ensureRemoveElementInList(cp, element); |
| } |
| } |
| } |
| |
| protected void updateRequiredProjects(IJavaProject jproject, String[] prevRequiredProjects, IProgressMonitor monitor) throws CoreException { |
| String[] newRequiredProjects = jproject.getRequiredProjectNames(); |
| |
| ArrayList prevEntries = new ArrayList(Arrays.asList(prevRequiredProjects)); |
| ArrayList newEntries = new ArrayList(Arrays.asList(newRequiredProjects)); |
| |
| IProject proj = jproject.getProject(); |
| IProjectDescription projDesc = proj.getDescription(); |
| |
| ArrayList newRefs = new ArrayList(); |
| IProject[] referencedProjects = projDesc.getReferencedProjects(); |
| for (int i = 0; i < referencedProjects.length; i++) { |
| String curr = referencedProjects[i].getName(); |
| if (newEntries.remove(curr) || !prevEntries.contains(curr)) { |
| newRefs.add(referencedProjects[i]); |
| } |
| } |
| IWorkspaceRoot root = proj.getWorkspace().getRoot(); |
| for (int i = 0; i < newEntries.size(); i++) { |
| String curr = (String) newEntries.get(i); |
| newRefs.add(root.getProject(curr)); |
| } |
| projDesc.setReferencedProjects((IProject[]) newRefs.toArray(new IProject[newRefs.size()])); |
| proj.setDescription(projDesc, monitor); |
| } |
| } |