/*******************************************************************************
* Copyright (c) 2012, 2016 VMware, 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:
* VMware, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.maven;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.apache.maven.model.Model;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.m2e.core.MavenPlugin;
import org.eclipse.m2e.core.project.IMavenProjectImportResult;
import org.eclipse.m2e.core.project.MavenProjectInfo;
import org.eclipse.m2e.core.project.ProjectImportConfiguration;
import org.eclipse.m2e.core.project.ResolverConfiguration;
import org.eclipse.osgi.util.NLS;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.springframework.ide.eclipse.core.SpringCore;
import org.springframework.ide.eclipse.core.SpringCorePreferences;
import org.springframework.ide.eclipse.core.SpringCoreUtils;
import org.springframework.ide.eclipse.maven.internal.core.MavenClasspathUpdateJob;
/**
* @author Christian Dupuis
* @author Andrew Eisenberg
*/
public class MavenCorePlugin extends AbstractUIPlugin {
private static final String M2ECLIPSE_BUNDLE = "org.eclipse.m2e.core";
public static final boolean IS_M2ECLIPSE_PRESENT = isPresent(M2ECLIPSE_BUNDLE);
private static boolean isPresent(String bundleName) {
try {
Bundle bundle = Platform.getBundle(bundleName);
return bundle != null && bundle.getState() != Bundle.INSTALLED && bundle.getState() != Bundle.UNINSTALLED;
} catch (Exception e) {
return false;
}
}
public static final String PLUGIN_ID = "org.springframework.ide.eclipse.maven"; //$NON-NLS-1$
public static final String AUTOMATICALLY_UPDATE_DEPENDENCIES_KEY = "maven.automatically.update";
public static final boolean AUTOMATICALLY_UPDATE_DEPENDENCIES_DEFAULT = false;
public static final String M2ECLIPSE_NATURE = "org.eclipse.m2e.core.maven2Nature";
private static MavenCorePlugin plugin;
private IResourceChangeListener resourceChangeListener;
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
if (IS_M2ECLIPSE_PRESENT) {
resourceChangeListener = new PomResourceChangeListener();
ResourcesPlugin.getWorkspace().addResourceChangeListener(resourceChangeListener);
}
}
public void stop(BundleContext context) throws Exception {
plugin = null;
super.stop(context);
if (resourceChangeListener != null && (IS_M2ECLIPSE_PRESENT)) {
ResourcesPlugin.getWorkspace().removeResourceChangeListener(resourceChangeListener);
}
}
public static MavenCorePlugin getDefault() {
return plugin;
}
public void scheduleClasspathUpdateJob(IProject project) {
if (IS_M2ECLIPSE_PRESENT) {
MavenClasspathUpdateJob.scheduleClasspathContainerUpdateJob(project);
}
}
/**
* {@link IResourceChangeListener} that listens to changes to the pom.xml
* resources.
*/
class PomResourceChangeListener implements IResourceChangeListener {
/**
* Internal resource delta visitor.
*/
protected class PomResourceVisitor implements IResourceDeltaVisitor {
protected int eventType;
public PomResourceVisitor(int eventType) {
this.eventType = eventType;
}
public final boolean visit(IResourceDelta delta) throws CoreException {
IResource resource = delta.getResource();
switch (delta.getKind()) {
case IResourceDelta.ADDED:
return resourceAdded(resource);
case IResourceDelta.OPEN:
return resourceOpened(resource);
case IResourceDelta.CHANGED:
return resourceChanged(resource, delta.getFlags());
case IResourceDelta.REMOVED:
return resourceRemoved(resource);
}
return true;
}
protected boolean resourceAdded(IResource resource) {
if (resource instanceof IFile) {
updateDependenciesIfPom(resource);
return false;
}
return true;
}
protected boolean resourceChanged(IResource resource, int flags) {
if (resource instanceof IFile) {
if ((flags & IResourceDelta.CONTENT) != 0) {
updateDependenciesIfPom(resource);
}
return false;
}
return true;
}
protected boolean resourceOpened(IResource resource) {
return true;
}
protected boolean resourceRemoved(IResource resource) {
return true;
}
private void updateDependenciesIfPom(IResource resource) {
if (resource.getName().equals("pom.xml")
&& SpringCorePreferences.getProjectPreferences(resource.getProject(), PLUGIN_ID).getBoolean(
AUTOMATICALLY_UPDATE_DEPENDENCIES_KEY, AUTOMATICALLY_UPDATE_DEPENDENCIES_DEFAULT)
&& !SpringCoreUtils.hasNature(resource, M2ECLIPSE_NATURE)) {
MavenClasspathUpdateJob.scheduleClasspathContainerUpdateJob(resource.getProject());
}
}
}
public static final int LISTENER_FLAGS = IResourceChangeEvent.PRE_CLOSE | IResourceChangeEvent.PRE_DELETE | IResourceChangeEvent.PRE_BUILD;
private static final int VISITOR_FLAGS = IResourceDelta.ADDED | IResourceDelta.CHANGED | IResourceDelta.REMOVED;
public void resourceChanged(IResourceChangeEvent event) {
if (event.getSource() instanceof IWorkspace) {
int eventType = event.getType();
switch (eventType) {
case IResourceChangeEvent.POST_CHANGE:
IResourceDelta delta = event.getDelta();
if (delta != null) {
try {
delta.accept(getVisitor(eventType), VISITOR_FLAGS);
} catch (CoreException e) {
SpringCore.log("Error while traversing resource change delta", e);
}
}
break;
}
} else if (event.getSource() instanceof IProject) {
int eventType = event.getType();
switch (eventType) {
case IResourceChangeEvent.POST_CHANGE:
IResourceDelta delta = event.getDelta();
if (delta != null) {
try {
delta.accept(getVisitor(eventType), VISITOR_FLAGS);
} catch (CoreException e) {
SpringCore.log("Error while traversing resource change delta", e);
}
}
break;
}
}
}
protected IResourceDeltaVisitor getVisitor(int eventType) {
return new PomResourceVisitor(eventType);
}
}
public static void createEclipseProjectFromExistingMavenProject(File pomFile, IProgressMonitor monitor) throws CoreException {
Model model = MavenPlugin.getMavenModelManager().readMavenModel(pomFile);
String derivedProjectName = model.getName();
if (derivedProjectName == null) {
derivedProjectName = model.getArtifactId();
}
if (derivedProjectName == null) {
String[] groupPieces = model.getGroupId().split("\\.");
int lastIndex = groupPieces.length - 1;
if (lastIndex >= 0) {
derivedProjectName = groupPieces[lastIndex];
} else {
String message = NLS.bind("Bad pom.xml: no name, artifactId, or groupId.", null);
throw new CoreException(new Status(Status.ERROR, MavenCorePlugin.PLUGIN_ID, message));
}
}
MavenProjectInfo parent = null;
MavenProjectInfo projectInfo = new MavenProjectInfo(derivedProjectName, pomFile, model, parent);
ArrayList<MavenProjectInfo> projectInfos = new ArrayList<MavenProjectInfo>();
projectInfos.add(projectInfo);
ResolverConfiguration resolverConfiguration = new ResolverConfiguration();
String activeProfiles = "pom.xml";
resolverConfiguration.setActiveProfiles(activeProfiles);
ProjectImportConfiguration configuration = new ProjectImportConfiguration(resolverConfiguration);
List<IMavenProjectImportResult> importResults = MavenPlugin.getProjectConfigurationManager().importProjects(projectInfos, configuration,
monitor);
for (IMavenProjectImportResult importResult : importResults) {
// skip projects which have not been properly imported
if (importResult.getProject() != null)
MavenPlugin.getProjectConfigurationManager().updateProjectConfiguration(importResult.getProject(), monitor);
}
}
}