org.eclipse.jst.j2ee.project.facet.J2EEFacetRuntimeChangedDelegate.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.jst.j2ee.project.facet.J2EEFacetRuntimeChangedDelegate.java

Source

/******************************************************************************
 * Copyright (c) 2005 BEA Systems, Inc.
 * 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:
 *    Konstantin Komissarchik - initial API and implementation
 ******************************************************************************/

package org.eclipse.jst.j2ee.project.facet;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
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.ProjectScope;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jst.common.project.facet.core.ClasspathHelper;
import org.eclipse.jst.common.project.facet.core.IClasspathProvider;
import org.eclipse.jst.common.project.facet.core.internal.FacetCorePlugin;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
import org.eclipse.wst.common.project.facet.core.IDelegate;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
import org.eclipse.wst.common.project.facet.core.IRuntimeChangedEvent;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
import org.eclipse.wst.common.project.facet.core.runtime.IRuntime;
import org.osgi.service.prefs.BackingStoreException;

/**
 * @author <a href="mailto:kosta@bea.com">Konstantin Komissarchik</a>
 */

public final class J2EEFacetRuntimeChangedDelegate

        implements IDelegate

{
    public static final String LEGACY_METADATA_FILE_NAME = ".settings/org.eclipse.jst.common.project.facet.core.prefs"; //$NON-NLS-1$
    private static final String OWNER_PROJECT_FACETS_ATTR = "owner.project.facets"; //$NON-NLS-1$

    public void execute(final IProject project, final IProjectFacetVersion fv, final Object cfg,
            final IProgressMonitor monitor)

            throws CoreException

    {
        if (monitor != null) {
            monitor.beginTask("", 11); //$NON-NLS-1$
        }

        try {
            IRuntimeChangedEvent event = (IRuntimeChangedEvent) cfg;
            // Using our remove Utility to first check for missing preferences
            removeClasspathEntries(project, fv, event.getOldRuntime());

            if (!ClasspathHelper.addClasspathEntries(project, fv)) {
                // TODO: Support the no runtime case.
                // ClasspathHelper.addClasspathEntries( project, fv, <something> );
            }

            if (monitor != null) {
                monitor.worked(1);
            }

            // Cascade this runtime change to projects referenced by this project

            // Compile the list of projects referenced by this project.
            final Set<IProject> childProjects = new HashSet<IProject>();

            final IVirtualComponent projectVC = ComponentCore.createComponent(project);

            Map<String, Object> options = new HashMap<String, Object>();
            options.put(IVirtualComponent.REQUESTED_REFERENCE_TYPE, IVirtualComponent.HARD_REFERENCES);
            final IVirtualReference[] vrefs = projectVC.getReferences(options);

            for (int i = 0; i < vrefs.length; i++) {
                final IVirtualReference vref = vrefs[i];
                final IVirtualComponent vc = vref.getReferencedComponent();
                childProjects.add(vc.getProject());
            }

            if (monitor != null) {
                monitor.worked(1);
            }

            // Attempt to change the runtime for each of the referenced projects.                
            updateProjectRuntime(project, childProjects, submon(monitor, 9));
        } finally {
            if (monitor != null) {
                monitor.done();
            }
        }
    }

    private void removeClasspathEntries(IProject project, IProjectFacetVersion fv, IRuntime oldRuntime)
            throws CoreException {
        IJavaProject jproj = JavaCore.create(project);
        List cp = getClasspath(jproj);
        boolean hasPrefs = hasClasspathPreferencesNode(project);

        // In the case where no prefs exists... make sure the entries of the
        // oldRuntime are removed before continuing
        if (!hasPrefs) {
            removeOnlyCPEntries(project, fv, jproj, cp, oldRuntime);
        } else
            ClasspathHelper.removeClasspathEntries(project, fv);
    }

    private boolean hasClasspathPreferencesNode(IProject project) {

        IProject pj = project.getProject();
        IFile legacyMetadataFile = pj.getFile(LEGACY_METADATA_FILE_NAME);
        // First check if file exists
        if (legacyMetadataFile.exists()) {
            ProjectScope scope = new ProjectScope(project);
            IEclipsePreferences pluginRoot = scope.getNode(FacetCorePlugin.PLUGIN_ID);
            try {
                return pluginRoot.nodeExists("classpath.helper"); //$NON-NLS-1$
            } catch (BackingStoreException e) {
                org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin.logError(e);
            }
        }
        //Now check classpath entries for new attributes
        IJavaProject jproj = JavaCore.create(project);
        return hasClasspathPreferencesNode(jproj);

    }

    private boolean hasClasspathPreferencesNode(IJavaProject jproj) {

        boolean attributeFound = false;
        IClasspathEntry[] entries = null;
        try {
            entries = jproj.getRawClasspath();
        } catch (JavaModelException e) {
            org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin.logError(e);
        }
        int i = 0;
        if (entries != null) {
            while (!attributeFound && i < entries.length) {
                IClasspathEntry cpe = entries[i];
                attributeFound = hasOwnerAttribute(cpe);
                i++;
            }
        }
        return attributeFound;

    }

    private boolean hasOwnerAttribute(IClasspathEntry cpe) {
        if (cpe != null) {
            for (IClasspathAttribute attr : cpe.getExtraAttributes()) {
                if (attr.getName().equals(OWNER_PROJECT_FACETS_ATTR))
                    return true;
            }
        }
        return false;
    }

    private void removeOnlyCPEntries(final IProject project, final IProjectFacetVersion fv,
            final IJavaProject jproj, final List cp, IRuntime oldRuntime) throws CoreException {
        IFacetedProject fproj = ProjectFacetsManager.create(project);
        IRuntime runtime = (oldRuntime != null) ? oldRuntime : fproj.getPrimaryRuntime();

        if (runtime != null) {
            IClasspathProvider cpprov = (IClasspathProvider) runtime.getAdapter(IClasspathProvider.class);
            List cpentries = cpprov.getClasspathEntries(fv);
            boolean realCPChanged = false;
            if (cpentries != null) {
                for (Iterator itr = cpentries.iterator(); itr.hasNext();) {
                    IClasspathEntry cpentry = (IClasspathEntry) itr.next();
                    IPath path = cpentry.getPath();
                    boolean contains = cp.contains(cpentry);

                    if (contains) {
                        for (Iterator itr2 = cp.iterator(); itr2.hasNext();) {
                            final IClasspathEntry realEntry = (IClasspathEntry) itr2.next();

                            if (realEntry.getPath().equals(path)) {
                                itr2.remove();
                                realCPChanged = true;
                                break;
                            }
                        }
                    }
                }
            }
            if (realCPChanged) {
                IClasspathEntry[] newcp = (IClasspathEntry[]) cp.toArray(new IClasspathEntry[cp.size()]);
                jproj.setRawClasspath(newcp, null);
            }
        }
    }

    private List getClasspath(final IJavaProject jproj)

            throws CoreException

    {
        ArrayList list = new ArrayList();
        IClasspathEntry[] cp = jproj.getRawClasspath();

        for (int i = 0; i < cp.length; i++) {
            list.add(cp[i]);
        }

        return list;
    }

    private static IProgressMonitor submon(final IProgressMonitor parent, final int ticks) {
        return (parent == null ? null : new SubProgressMonitor(parent, ticks));
    }

    public static void updateProjectRuntime(final IProject project, final IProject childProject,
            final IProgressMonitor monitor) throws CoreException {
        if (monitor != null) {
            monitor.beginTask("", 1); //$NON-NLS-1$
        }

        try {
            final IFacetedProject facetedProject = ProjectFacetsManager.create(project);

            final IRuntime projectRuntime = facetedProject.getRuntime();

            final IFacetedProject childFacetedProject = ProjectFacetsManager.create(childProject);

            if (childFacetedProject != null && !equals(projectRuntime, childFacetedProject.getRuntime())) {
                boolean supports = true;

                if (projectRuntime != null) {
                    for (Iterator itr = childFacetedProject.getProjectFacets().iterator(); itr.hasNext();) {
                        final IProjectFacetVersion fver = (IProjectFacetVersion) itr.next();

                        if (!projectRuntime.supports(fver)) {
                            supports = false;
                            break;
                        }
                    }
                }

                if (supports) {
                    childFacetedProject.setRuntime(projectRuntime, submon(monitor, 1));
                }
            }
        } finally {
            if (monitor != null) {
                monitor.done();
            }
        }
    }

    public static void updateProjectRuntime(final IProject project, final Set<IProject> childProjects,
            final IProgressMonitor monitor) throws CoreException {
        if (monitor != null) {
            monitor.beginTask("", childProjects.size()); //$NON-NLS-1$
        }

        try {
            for (final IProject childProject : childProjects) {
                updateProjectRuntime(project, childProject, submon(monitor, 1));
            }
        } finally {
            if (monitor != null) {
                monitor.done();
            }
        }
    }

    private static boolean equals(final Object obj1, final Object obj2) {
        if (obj1 == obj2) {
            return true;
        } else if (obj1 == null || obj2 == null) {
            return false;
        } else {
            return obj1.equals(obj2);
        }
    }
}