org.eclipse.jst.j2ee.internal.common.operations.UpdateJavaBuildPathOperation.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.jst.j2ee.internal.common.operations.UpdateJavaBuildPathOperation.java

Source

/*******************************************************************************
 * Copyright (c) 2003, 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 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.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());
        }
        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);
    }
}