diff options
48 files changed, 2257 insertions, 52 deletions
diff --git a/org.eclipse.m2e.binaryproject.tests/META-INF/MANIFEST.MF b/org.eclipse.m2e.binaryproject.tests/META-INF/MANIFEST.MF new file mode 100644 index 00000000..e1f79f6a --- /dev/null +++ b/org.eclipse.m2e.binaryproject.tests/META-INF/MANIFEST.MF @@ -0,0 +1,18 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %Bundle-Name +Bundle-SymbolicName: org.eclipse.m2e.binaryproject.tests;singleton:=true +Bundle-Version: 1.9.0.qualifier +Bundle-Vendor: %Bundle-Vendor +Require-Bundle: org.eclipse.m2e.core;bundle-version="[1.9.0,1.10.0)", + org.eclipse.m2e.maven.runtime;bundle-version="[1.9.0,1.10.0)", + org.eclipse.m2e.binaryproject;bundle-version="[1.9.0,1.10.0)", + org.slf4j.api;bundle-version="1.6.1", + org.junit;bundle-version="4.0.0", + org.eclipse.m2e.tests.common;bundle-version="[1.9.0,1.10.0)", + org.eclipse.equinox.common;bundle-version="3.6.100", + org.eclipse.core.resources;bundle-version="3.8.0", + org.eclipse.m2e.jdt;bundle-version="[1.9.0,1.10.0)", + org.eclipse.jdt.core;bundle-version="3.8.1", + org.eclipse.core.runtime;bundle-version="3.8.0" +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 diff --git a/org.eclipse.m2e.binaryproject.tests/build.properties b/org.eclipse.m2e.binaryproject.tests/build.properties new file mode 100644 index 00000000..ced5f40e --- /dev/null +++ b/org.eclipse.m2e.binaryproject.tests/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = target/classes +bin.includes = META-INF/,\ + . diff --git a/org.eclipse.m2e.binaryproject.tests/plugin_customization.ini b/org.eclipse.m2e.binaryproject.tests/plugin_customization.ini new file mode 100644 index 00000000..cb717545 --- /dev/null +++ b/org.eclipse.m2e.binaryproject.tests/plugin_customization.ini @@ -0,0 +1,10 @@ +# Copyright (c) 2010-2011 Sonatype, 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 + +# +# Add "-pluginCustomization plugin_customization.ini" to your Eclipse command line to apply these settings +# +org.eclipse.m2e.core/eclipse.m2.updateIndexes=false diff --git a/org.eclipse.m2e.binaryproject.tests/pom.xml b/org.eclipse.m2e.binaryproject.tests/pom.xml new file mode 100644 index 00000000..9d9e8254 --- /dev/null +++ b/org.eclipse.m2e.binaryproject.tests/pom.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (c) 2012 Igor Fedorenko + 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 +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.eclipse.m2e</groupId> + <artifactId>m2e-core</artifactId> + <version>1.9.0-SNAPSHOT</version> + </parent> + + <artifactId>org.eclipse.m2e.binaryproject.tests</artifactId> + <packaging>eclipse-test-plugin</packaging> +</project>
\ No newline at end of file diff --git a/org.eclipse.m2e.binaryproject.tests/src/org/eclipse/m2e/binaryproject/tests/BinaryProjectTest.java b/org.eclipse.m2e.binaryproject.tests/src/org/eclipse/m2e/binaryproject/tests/BinaryProjectTest.java new file mode 100644 index 00000000..001d5098 --- /dev/null +++ b/org.eclipse.m2e.binaryproject.tests/src/org/eclipse/m2e/binaryproject/tests/BinaryProjectTest.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2012 Igor Fedorenko + * 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: + * Igor Fedorenko - initial API and implementation + *******************************************************************************/ +package org.eclipse.m2e.binaryproject.tests; + +import org.eclipse.core.resources.ICommand; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jdt.core.IClasspathEntry; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.m2e.binaryproject.internal.BinaryProjectPlugin; +import org.eclipse.m2e.core.MavenPlugin; +import org.eclipse.m2e.core.internal.IMavenConstants; +import org.eclipse.m2e.core.project.IMavenProjectFacade; +import org.eclipse.m2e.jdt.internal.BuildPathManager; +import org.eclipse.m2e.tests.common.AbstractMavenProjectTestCase; +import org.eclipse.m2e.tests.common.ClasspathHelpers; + +@SuppressWarnings({"restriction"}) +public class BinaryProjectTest extends AbstractMavenProjectTestCase { + IProgressMonitor monitor = new NullProgressMonitor(); + + public void testBasic() throws Exception { + IProject project = + BinaryProjectPlugin.getInstance().create("org.apache.maven", "maven-core", "3.0.4", null, monitor); + + assertTrue(project.hasNature(IMavenConstants.NATURE_ID)); + assertTrue(project.hasNature(JavaCore.NATURE_ID)); + assertNotNull(BuildPathManager.getMaven2ClasspathContainer(JavaCore.create(project))); + assertFalse(hasBuilder(project, JavaCore.BUILDER_ID)); + + IMavenProjectFacade facade = MavenPlugin.getMavenProjectRegistry().create(project, monitor); + + assertNotNull(facade); + assertEquals(BinaryProjectPlugin.LIFECYCLE_MAPPING_ID, facade.getLifecycleMappingId()); + + IJavaProject javaProject = JavaCore.create(project); + + ClasspathHelpers.assertClasspath(new String[] {"org.eclipse.jdt.launching.JRE_CONTAINER/.*", + "org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER", ".*/maven-core-3.0.4.jar"}, javaProject.getRawClasspath()); + + IClasspathEntry[] mavenClasspath = BuildPathManager.getMaven2ClasspathContainer(javaProject).getClasspathEntries(); + + assertTrue(mavenClasspath.length > 0); + } + + private boolean hasBuilder(IProject project, String builderId) throws CoreException { + for (ICommand command : project.getDescription().getBuildSpec()) { + if (builderId.equals(command.getBuilderName())) { + return true; + } + } + return false; + } + +} diff --git a/org.eclipse.m2e.binaryproject.ui/META-INF/MANIFEST.MF b/org.eclipse.m2e.binaryproject.ui/META-INF/MANIFEST.MF new file mode 100644 index 00000000..84b3646f --- /dev/null +++ b/org.eclipse.m2e.binaryproject.ui/META-INF/MANIFEST.MF @@ -0,0 +1,15 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %Bundle-Name +Bundle-SymbolicName: org.eclipse.m2e.binaryproject.ui;singleton:=true +Bundle-Version: 1.9.0.qualifier +Bundle-Activator: org.eclipse.m2e.binaryproject.ui.internal.BinaryprojectUIActivator +Bundle-Vendor: %Bundle-Vendor +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.m2e.core.ui;bundle-version="[1.9.0,1.10.0)", + org.eclipse.m2e.binaryproject;bundle-version="[1.9.0,1.10.0)", + org.eclipse.m2e.core;bundle-version="[1.9.0,1.10.0)", + org.eclipse.m2e.maven.runtime;bundle-version="[1.9.0,1.10.0)" +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Bundle-ActivationPolicy: lazy diff --git a/org.eclipse.m2e.binaryproject.ui/build.properties b/org.eclipse.m2e.binaryproject.ui/build.properties new file mode 100644 index 00000000..b806395b --- /dev/null +++ b/org.eclipse.m2e.binaryproject.ui/build.properties @@ -0,0 +1,6 @@ +source.. = src/ +output.. = target/classes/ +bin.includes = META-INF/,\ + .,\ + plugin.xml,\ + icons/ diff --git a/org.eclipse.m2e.binaryproject.ui/icons/binary_project.gif b/org.eclipse.m2e.binaryproject.ui/icons/binary_project.gif Binary files differnew file mode 100644 index 00000000..03c10b0b --- /dev/null +++ b/org.eclipse.m2e.binaryproject.ui/icons/binary_project.gif diff --git a/org.eclipse.m2e.binaryproject.ui/plugin.xml b/org.eclipse.m2e.binaryproject.ui/plugin.xml new file mode 100644 index 00000000..4d764856 --- /dev/null +++ b/org.eclipse.m2e.binaryproject.ui/plugin.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?eclipse version="3.4"?> +<plugin> + <extension + point="org.eclipse.ui.importWizards"> + <wizard + category="org.eclipse.m2e" + class="org.eclipse.m2e.binaryproject.ui.internal.BinaryProjectImportWizard" + icon="icons/binary_project.gif" + id="org.eclipse.m2e.binaryproject.ui.binaryProjectImportWizard" + name="Materialize Maven Binary Project"> + </wizard> + </extension> + <extension + point="org.eclipse.ui.popupMenus"> + <objectContribution + adaptable="true" + id="org.eclipse.m2e.binaryproject.ui.importBinaryProject" + objectClass="org.eclipse.jdt.core.IPackageFragmentRoot"> + <action + class="org.eclipse.m2e.binaryproject.ui.internal.BinaryProjectImportAction" + enablesFor="+" + icon="icons/binary_project.gif" + id="org.eclipse.m2e.binaryproject.ui.action.importBinaryProjects" + label="Materialize Maven Binary Project" + menubarPath="org.eclipse.m2e.classpathMenu/import" + style="push"> + </action> + <enablement> + <and> + <test + property="org.eclipse.m2e.hasArtifactKey"> + </test> + <not> + <test + property="org.eclipse.m2e.hasProjectArtifactKey"> + </test> + </not> + </and> + </enablement> + </objectContribution> + </extension> + +</plugin> diff --git a/org.eclipse.m2e.binaryproject.ui/pom.xml b/org.eclipse.m2e.binaryproject.ui/pom.xml new file mode 100644 index 00000000..0313eab3 --- /dev/null +++ b/org.eclipse.m2e.binaryproject.ui/pom.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (c) 2012 Igor Fedorenko + 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 +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.eclipse.m2e</groupId> + <artifactId>m2e-core</artifactId> + <version>1.9.0-SNAPSHOT</version> + </parent> + + <artifactId>org.eclipse.m2e.binaryproject.ui</artifactId> + <packaging>eclipse-plugin</packaging> +</project>
\ No newline at end of file diff --git a/org.eclipse.m2e.binaryproject.ui/src/org/eclipse/m2e/binaryproject/ui/internal/BinaryProjectImportAction.java b/org.eclipse.m2e.binaryproject.ui/src/org/eclipse/m2e/binaryproject/ui/internal/BinaryProjectImportAction.java new file mode 100644 index 00000000..ae2b3675 --- /dev/null +++ b/org.eclipse.m2e.binaryproject.ui/src/org/eclipse/m2e/binaryproject/ui/internal/BinaryProjectImportAction.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2012 Igor Fedorenko + * 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: + * Igor Fedorenko - initial API and implementation + *******************************************************************************/ +package org.eclipse.m2e.binaryproject.ui.internal; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.ui.IObjectActionDelegate; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchPartSite; + +public class BinaryProjectImportAction implements IObjectActionDelegate { + + private IStructuredSelection selection; + + private IWorkbench workbench; + + private IWorkbenchPartSite site; + + @Override + public void run(IAction action) { + BinaryProjectImportWizard wizard = new BinaryProjectImportWizard(); + wizard.init(workbench, selection); + if (!wizard.getInitialDependencies().isEmpty()) { + WizardDialog dialog = new WizardDialog(site.getShell(), wizard); + dialog.open(); + } else { + wizard.dispose(); + } + } + + @Override + public void selectionChanged(IAction action, ISelection selection) { + if (selection instanceof IStructuredSelection) { + this.selection = (IStructuredSelection) selection; + } else { + selection = null; + } + } + + @Override + public void setActivePart(IAction action, IWorkbenchPart targetPart) { + site = targetPart.getSite(); + workbench = site.getWorkbenchWindow().getWorkbench(); + } + +} diff --git a/org.eclipse.m2e.binaryproject.ui/src/org/eclipse/m2e/binaryproject/ui/internal/BinaryProjectImportWizard.java b/org.eclipse.m2e.binaryproject.ui/src/org/eclipse/m2e/binaryproject/ui/internal/BinaryProjectImportWizard.java new file mode 100644 index 00000000..39a3181c --- /dev/null +++ b/org.eclipse.m2e.binaryproject.ui/src/org/eclipse/m2e/binaryproject/ui/internal/BinaryProjectImportWizard.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright (c) 2012 Igor Fedorenko + * 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: + * Igor Fedorenko - initial API and implementation + *******************************************************************************/ +package org.eclipse.m2e.binaryproject.ui.internal; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +import org.apache.maven.model.Dependency; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.m2e.binaryproject.internal.AbstractBinaryProjectsImportJob; +import org.eclipse.m2e.core.embedder.ArtifactKey; +import org.eclipse.m2e.core.project.ProjectImportConfiguration; +import org.eclipse.m2e.core.ui.internal.actions.SelectionUtil; +import org.eclipse.m2e.core.ui.internal.wizards.MavenDependenciesWizardPage; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IImportWizard; +import org.eclipse.ui.IWorkbench; + +@SuppressWarnings("restriction") +public class BinaryProjectImportWizard extends Wizard implements IImportWizard { + + private MavenDependenciesWizardPage artifactsPage; + + private List<Dependency> initialDependencies; + + public BinaryProjectImportWizard() {} + + @Override + public void init(IWorkbench workbench, IStructuredSelection selection) { + final List<Dependency> dependencies = new ArrayList<Dependency>(); + for (Iterator<?> it = selection.iterator(); it.hasNext();) { + Object element = it.next(); + ArtifactKey artifactKey = SelectionUtil.getType(element, ArtifactKey.class); + if (artifactKey != null) { + Dependency d = new Dependency(); + d.setGroupId(artifactKey.getGroupId()); + d.setArtifactId(artifactKey.getArtifactId()); + d.setVersion(artifactKey.getVersion()); + d.setClassifier(artifactKey.getClassifier()); + dependencies.add(d); + } + } + artifactsPage = + new MavenDependenciesWizardPage(new ProjectImportConfiguration(), "Artifacts", "Select artifacts to import") { + @Override + protected void createAdvancedSettings(Composite composite, GridData gridData) { + // TODO profile can theoretically be usedful + } + }; + artifactsPage.setDependencies(dependencies.toArray(new Dependency[dependencies.size()])); + artifactsPage.addListener(new ISelectionChangedListener() { + @Override + public void selectionChanged(SelectionChangedEvent event) { + getContainer().updateButtons(); + } + }); + this.initialDependencies = Collections.unmodifiableList(dependencies); + } + + @Override + public boolean performFinish() { + final ArrayList<ArtifactKey> artifacts = new ArrayList<ArtifactKey>(); + + for (Dependency dependency : artifactsPage.getDependencies()) { + artifacts.add(new ArtifactKey(dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion(), + dependency.getClassifier())); + } + + if (artifacts.isEmpty()) { + return false; + } + + Job job = new AbstractBinaryProjectsImportJob() { + + @Override + protected Collection<ArtifactKey> getArtifactKeys(IProgressMonitor monitor) throws CoreException { + return artifacts; + } + }; + job.schedule(); + + return true; + } + + @Override + public boolean canFinish() { + return artifactsPage.getDependencies().length > 0; + } + + @Override + public void addPages() { + addPage(artifactsPage); + } + + public List<Dependency> getInitialDependencies() { + return initialDependencies; + } +} diff --git a/org.eclipse.m2e.binaryproject.ui/src/org/eclipse/m2e/binaryproject/ui/internal/BinaryprojectUIActivator.java b/org.eclipse.m2e.binaryproject.ui/src/org/eclipse/m2e/binaryproject/ui/internal/BinaryprojectUIActivator.java new file mode 100644 index 00000000..a552c08d --- /dev/null +++ b/org.eclipse.m2e.binaryproject.ui/src/org/eclipse/m2e/binaryproject/ui/internal/BinaryprojectUIActivator.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2012 Igor Fedorenko + * 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: + * Igor Fedorenko - initial API and implementation + *******************************************************************************/ +package org.eclipse.m2e.binaryproject.ui.internal; + +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class BinaryprojectUIActivator extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "org.eclipse.m2e.binaryproject.ui"; //$NON-NLS-1$ + + // The shared instance + private static BinaryprojectUIActivator plugin; + + /** + * The constructor + */ + public BinaryprojectUIActivator() {} + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static BinaryprojectUIActivator getDefault() { + return plugin; + } + +} diff --git a/org.eclipse.m2e.binaryproject/META-INF/MANIFEST.MF b/org.eclipse.m2e.binaryproject/META-INF/MANIFEST.MF new file mode 100644 index 00000000..4a2067de --- /dev/null +++ b/org.eclipse.m2e.binaryproject/META-INF/MANIFEST.MF @@ -0,0 +1,22 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %Bundle-Name +Bundle-SymbolicName: org.eclipse.m2e.binaryproject;singleton:=true +Bundle-Version: 1.9.0.qualifier +Bundle-Vendor: %Bundle-Vendor +Require-Bundle: org.eclipse.m2e.core;bundle-version="[1.9.0,1.10.0)", + org.eclipse.m2e.maven.runtime;bundle-version="[1.9.0,1.10.0)", + org.eclipse.m2e.sourcelookup;bundle-version="[1.9.0,1.10.0)", + org.slf4j.api;bundle-version="1.6.1", + org.eclipse.equinox.common;bundle-version="3.6.0", + org.eclipse.m2e.jdt;bundle-version="[1.9.0,1.10.0)", + org.eclipse.core.resources;bundle-version="3.7.0", + org.eclipse.jdt.core;bundle-version="3.7.0", + org.eclipse.equinox.registry;bundle-version="3.5.0", + org.eclipse.core.runtime;bundle-version="3.7.0", + org.eclipse.debug.core;bundle-version="3.9.0", + org.eclipse.jdt.launching;bundle-version="3.10.0" +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Export-Package: org.eclipse.m2e.binaryproject.internal;x-friends:="org.eclipse.m2e.sourcelookup,org.eclipse.m2e.sourcelookup.ui" +Bundle-ActivationPolicy: lazy +Bundle-Activator: org.eclipse.m2e.binaryproject.internal.BinaryProjectPlugin diff --git a/org.eclipse.m2e.binaryproject/build.properties b/org.eclipse.m2e.binaryproject/build.properties new file mode 100644 index 00000000..52a5b4fe --- /dev/null +++ b/org.eclipse.m2e.binaryproject/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = target/classes +bin.includes = META-INF/,\ + .,\ + plugin.xml diff --git a/org.eclipse.m2e.binaryproject/plugin.xml b/org.eclipse.m2e.binaryproject/plugin.xml new file mode 100644 index 00000000..55064563 --- /dev/null +++ b/org.eclipse.m2e.binaryproject/plugin.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?eclipse version="3.4"?> +<plugin> + <extension + point="org.eclipse.m2e.core.lifecycleMappings"> + <lifecycleMapping + class="org.eclipse.m2e.binaryproject.internal.BinaryProjectLifecycleMapping" + id="org.eclipse.m2e.binaryproject" + name="Maven Binary Project"> + </lifecycleMapping> + </extension> + <extension + point="org.eclipse.jdt.launching.workspaceProjectDescribers"> + <describer + class="org.eclipse.m2e.binaryproject.internal.sourcelookup.BinaryProjectDescriber"> + </describer> + </extension> + +</plugin> diff --git a/org.eclipse.m2e.binaryproject/pom.xml b/org.eclipse.m2e.binaryproject/pom.xml new file mode 100644 index 00000000..61859cfd --- /dev/null +++ b/org.eclipse.m2e.binaryproject/pom.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (c) 2012 Igor Fedorenko + 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 +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.eclipse.m2e</groupId> + <artifactId>m2e-core</artifactId> + <version>1.9.0-SNAPSHOT</version> + </parent> + + <artifactId>org.eclipse.m2e.binaryproject</artifactId> + <packaging>eclipse-plugin</packaging> +</project>
\ No newline at end of file diff --git a/org.eclipse.m2e.binaryproject/src/org/eclipse/m2e/binaryproject/internal/AbstractBinaryProjectsImportJob.java b/org.eclipse.m2e.binaryproject/src/org/eclipse/m2e/binaryproject/internal/AbstractBinaryProjectsImportJob.java new file mode 100644 index 00000000..e80cb3fa --- /dev/null +++ b/org.eclipse.m2e.binaryproject/src/org/eclipse/m2e/binaryproject/internal/AbstractBinaryProjectsImportJob.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2012 Igor Fedorenko + * 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: + * Igor Fedorenko - initial API and implementation + *******************************************************************************/ +package org.eclipse.m2e.binaryproject.internal; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.m2e.core.embedder.ArtifactKey; + +public abstract class AbstractBinaryProjectsImportJob extends Job { + + public AbstractBinaryProjectsImportJob() { + super("Import binary projects"); + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + Collection<ArtifactKey> artifacts; + try { + artifacts = getArtifactKeys(monitor); + } catch (CoreException e1) { + return e1.getStatus(); + } + + if (!artifacts.isEmpty()) { + List<IStatus> errors = new ArrayList<IStatus>(); + + for (ArtifactKey artifact : artifacts) { + try { + BinaryProjectPlugin.getInstance().create(artifact.getGroupId(), artifact.getArtifactId(), + artifact.getVersion(), null, monitor); + } catch (CoreException e) { + errors.add(e.getStatus()); + } + } + } + return Status.OK_STATUS; + } + + protected abstract Collection<ArtifactKey> getArtifactKeys(IProgressMonitor monitor) throws CoreException; + +} diff --git a/org.eclipse.m2e.binaryproject/src/org/eclipse/m2e/binaryproject/internal/BinaryProjectLifecycleMapping.java b/org.eclipse.m2e.binaryproject/src/org/eclipse/m2e/binaryproject/internal/BinaryProjectLifecycleMapping.java new file mode 100644 index 00000000..867806b9 --- /dev/null +++ b/org.eclipse.m2e.binaryproject/src/org/eclipse/m2e/binaryproject/internal/BinaryProjectLifecycleMapping.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (c) 2012 Igor Fedorenko + * 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: + * Igor Fedorenko - initial API and implementation + *******************************************************************************/ +package org.eclipse.m2e.binaryproject.internal; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.m2e.core.MavenPlugin; +import org.eclipse.m2e.core.internal.MavenPluginActivator; +import org.eclipse.m2e.core.project.IMavenProjectFacade; +import org.eclipse.m2e.core.project.configurator.AbstractBuildParticipant; +import org.eclipse.m2e.core.project.configurator.AbstractLifecycleMapping; +import org.eclipse.m2e.core.project.configurator.AbstractProjectConfigurator; +import org.eclipse.m2e.core.project.configurator.ILifecycleMappingConfiguration; +import org.eclipse.m2e.core.project.configurator.MojoExecutionKey; +import org.eclipse.m2e.core.project.configurator.ProjectConfigurationRequest; + +@SuppressWarnings("restriction") +public class BinaryProjectLifecycleMapping extends AbstractLifecycleMapping { + private final ClasspathConfigurator configurator; + + public BinaryProjectLifecycleMapping() { + ClasspathConfigurator configurator = new ClasspathConfigurator(); + configurator.setProjectManager(MavenPlugin.getMavenProjectRegistry()); + configurator.setMavenConfiguration(MavenPlugin.getMavenConfiguration()); + configurator.setMarkerManager(MavenPluginActivator.getDefault().getMavenMarkerManager()); + + this.configurator = configurator; + } + + @Override + public Map<MojoExecutionKey, List<AbstractBuildParticipant>> getBuildParticipants(IMavenProjectFacade project, + IProgressMonitor monitor) throws CoreException { + return Collections.emptyMap(); + } + + @Override + public List<AbstractProjectConfigurator> getProjectConfigurators(IMavenProjectFacade project, + IProgressMonitor monitor) throws CoreException { + return Collections.emptyList(); + } + + @Override + public boolean hasLifecycleMappingChanged(IMavenProjectFacade newFacade, + ILifecycleMappingConfiguration oldConfiguration, IProgressMonitor monitor) { + return false; + } + + public void configure(ProjectConfigurationRequest request, IProgressMonitor monitor) throws CoreException { + configurator.configure(request, monitor); + } + + public void unconfigure(ProjectConfigurationRequest request, IProgressMonitor monitor) {} +} diff --git a/org.eclipse.m2e.binaryproject/src/org/eclipse/m2e/binaryproject/internal/BinaryProjectPlugin.java b/org.eclipse.m2e.binaryproject/src/org/eclipse/m2e/binaryproject/internal/BinaryProjectPlugin.java new file mode 100644 index 00000000..652f5c13 --- /dev/null +++ b/org.eclipse.m2e.binaryproject/src/org/eclipse/m2e/binaryproject/internal/BinaryProjectPlugin.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright (c) 2012 Igor Fedorenko + * 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: + * Igor Fedorenko - initial API and implementation + *******************************************************************************/ +package org.eclipse.m2e.binaryproject.internal; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.codehaus.plexus.util.FileUtils; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ProjectScope; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.QualifiedName; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.IScopeContext; +import org.eclipse.m2e.core.MavenPlugin; +import org.eclipse.m2e.core.embedder.IMaven; +import org.eclipse.m2e.core.project.IProjectConfigurationManager; +import org.eclipse.m2e.core.project.ResolverConfiguration; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.service.prefs.BackingStoreException; + +public class BinaryProjectPlugin implements BundleActivator { + + public static final String PLUGIN_ID = "org.eclipse.m2e.binaryproject"; + + public static final String LIFECYCLE_MAPPING_ID = "org.eclipse.m2e.binaryproject"; + + public static final String P_GROUPID = "groupId"; + + public static final String P_ARTIFACTID = "artifactId"; + + public static final String P_VERSION = "version"; + + public static final String P_TYPE = "type"; + + public static final String P_CLASSIFIER = "classifier"; + + /** + * Name of IProject persistent property that identifies absolute filesystem path of the target jar artifact of the + * workspace binary project. + */ + public static final QualifiedName QNAME_JAR = new QualifiedName(PLUGIN_ID, "jar"); + + private static BinaryProjectPlugin SELF; + + public static BinaryProjectPlugin getInstance() { + return SELF; + } + + private Bundle bundle; + + public IProject create(String groupId, String artifactId, String version, List<ArtifactRepository> repositories, + IProgressMonitor monitor) throws CoreException { + IMaven maven = MavenPlugin.getMaven(); + + Artifact pomArtifact = + maven.resolve(groupId, artifactId, version, "pom" /* type */, null /* classifier */, repositories, monitor); + + ResolverConfiguration resolverConfig = new ResolverConfiguration(); + resolverConfig.setLifecycleMappingId(LIFECYCLE_MAPPING_ID); + + String projectName = groupId + "_" + artifactId + "_" + version; + + IPath stateLocation = Platform.getStateLocation(bundle); + + IPath projectLocation = stateLocation.append(projectName); + projectLocation.toFile().mkdirs(); + + File pomFile = new File(projectLocation.toFile(), "pom.xml"); + + try { + FileUtils.copyFile(pomArtifact.getFile(), pomFile); + } catch (IOException e) { + throw new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, "Could not create binary project", e)); + } + + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + IWorkspaceRoot root = workspace.getRoot(); + + IProject project = root.getProject(projectName); + + IProjectDescription description = workspace.newProjectDescription(projectName); + description.setLocation(projectLocation); + project.create(description, monitor); + project.open(monitor); + + IScopeContext projectScope = new ProjectScope(project); + IEclipsePreferences projectNode = projectScope.getNode(BinaryProjectPlugin.PLUGIN_ID); + + projectNode.put(P_GROUPID, groupId); + projectNode.put(P_ARTIFACTID, artifactId); + projectNode.put(P_VERSION, version); + // String type = projectNode.get( P_TYPE, "jar" ); + // String classifier = projectNode.get( P_CLASSIFIER, (String) null ); + + try { + projectNode.flush(); + } catch (BackingStoreException e) { + throw new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, "Could not create binary project", e)); + } + + IProjectConfigurationManager configManager = MavenPlugin.getProjectConfigurationManager(); + + configManager.enableMavenNature(project, resolverConfig, monitor); + + return project; + } + + @Override + public void start(BundleContext context) throws Exception { + this.bundle = context.getBundle(); + BinaryProjectPlugin.SELF = this; + } + + @Override + public void stop(BundleContext context) throws Exception { + BinaryProjectPlugin.SELF = null; + this.bundle = null; + } +} diff --git a/org.eclipse.m2e.binaryproject/src/org/eclipse/m2e/binaryproject/internal/ClasspathConfigurator.java b/org.eclipse.m2e.binaryproject/src/org/eclipse/m2e/binaryproject/internal/ClasspathConfigurator.java new file mode 100644 index 00000000..c84c9fc1 --- /dev/null +++ b/org.eclipse.m2e.binaryproject/src/org/eclipse/m2e/binaryproject/internal/ClasspathConfigurator.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2012 Igor Fedorenko + * 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: + * Igor Fedorenko - initial API and implementation + *******************************************************************************/ +package org.eclipse.m2e.binaryproject.internal; + +import java.util.List; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ProjectScope; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.IScopeContext; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.m2e.core.MavenPlugin; +import org.eclipse.m2e.core.embedder.ArtifactKey; +import org.eclipse.m2e.core.embedder.IMaven; +import org.eclipse.m2e.core.project.configurator.ProjectConfigurationRequest; +import org.eclipse.m2e.jdt.IClasspathDescriptor; +import org.eclipse.m2e.jdt.IClasspathEntryDescriptor; +import org.eclipse.m2e.jdt.internal.AbstractJavaProjectConfigurator; +import org.eclipse.m2e.jdt.internal.BuildPathManager; + +@SuppressWarnings("restriction") +public class ClasspathConfigurator extends AbstractJavaProjectConfigurator { + + @Override + protected void addProjectSourceFolders(IClasspathDescriptor classpath, ProjectConfigurationRequest request, + IProgressMonitor monitor) throws CoreException {} + + @Override + protected void addJavaNature(IProject project, IProgressMonitor monitor) throws CoreException { + addNature(project, JavaCore.NATURE_ID, IResource.KEEP_HISTORY | IResource.AVOID_NATURE_CONFIG, monitor); + } + + @Override + protected void invokeJavaProjectConfigurators(IClasspathDescriptor classpath, ProjectConfigurationRequest request, + IProgressMonitor monitor) throws CoreException { + // TODO need repository information + + IProject project = request.getProject(); + + IMaven maven = MavenPlugin.getMaven(); + + IScopeContext projectScope = new ProjectScope(project); + IEclipsePreferences projectNode = projectScope.getNode(BinaryProjectPlugin.PLUGIN_ID); + + String groupId = projectNode.get(BinaryProjectPlugin.P_GROUPID, (String) null); + String artifactId = projectNode.get(BinaryProjectPlugin.P_ARTIFACTID, (String) null); + String version = projectNode.get(BinaryProjectPlugin.P_VERSION, (String) null); + String type = projectNode.get(BinaryProjectPlugin.P_TYPE, "jar"); + String classifier = projectNode.get(BinaryProjectPlugin.P_CLASSIFIER, (String) null); + + List<ArtifactRepository> repositories = null; // TODO store in project preferences + + Artifact jar = maven.resolve(groupId, artifactId, version, type, classifier, repositories, monitor); + String jarLocation = jar.getFile().getAbsolutePath(); + + project.setPersistentProperty(BinaryProjectPlugin.QNAME_JAR, jarLocation); + + Artifact sources = + maven.resolve(groupId, artifactId, version, type, getSourcesClassifier(classifier), repositories, monitor); + IClasspathEntryDescriptor libEntry = classpath.addLibraryEntry(Path.fromOSString(jarLocation)); + libEntry.setExported(true); + libEntry.setSourceAttachment(Path.fromOSString(sources.getFile().getAbsolutePath()), null); + libEntry.setArtifactKey(new ArtifactKey(groupId, artifactId, version, classifier)); + } + + @Override + protected IContainer getOutputLocation(ProjectConfigurationRequest request, IProject project) { + return project; + } + + static String getSourcesClassifier(String baseClassifier) { + return BuildPathManager.CLASSIFIER_TESTS.equals(baseClassifier) + ? BuildPathManager.CLASSIFIER_TESTSOURCES + : BuildPathManager.CLASSIFIER_SOURCES; + } + +} diff --git a/org.eclipse.m2e.binaryproject/src/org/eclipse/m2e/binaryproject/internal/sourcelookup/BinaryProjectContainerResolver.java b/org.eclipse.m2e.binaryproject/src/org/eclipse/m2e/binaryproject/internal/sourcelookup/BinaryProjectContainerResolver.java new file mode 100644 index 00000000..f374a4fd --- /dev/null +++ b/org.eclipse.m2e.binaryproject/src/org/eclipse/m2e/binaryproject/internal/sourcelookup/BinaryProjectContainerResolver.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 2011-2016 Igor Fedorenko + * 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: + * Igor Fedorenko - initial API and implementation + *******************************************************************************/ +package org.eclipse.m2e.binaryproject.internal.sourcelookup; + +import static org.eclipse.jdt.launching.sourcelookup.advanced.AdvancedSourceLookup.getClasspath; +import static org.eclipse.m2e.binaryproject.internal.sourcelookup.BinaryProjectDescriber.getBinaryLocation; + +import java.io.File; +import java.util.Map; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.debug.core.sourcelookup.ISourceContainer; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IPackageFragmentRoot; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.launching.sourcelookup.advanced.ISourceContainerResolver; +import org.eclipse.jdt.launching.sourcelookup.containers.PackageFragmentRootSourceContainer; +import org.eclipse.m2e.core.MavenPlugin; +import org.eclipse.m2e.core.embedder.ArtifactKey; +import org.eclipse.m2e.core.project.IMavenProjectFacade; +import org.eclipse.m2e.core.project.IMavenProjectRegistry; +import org.eclipse.m2e.sourcelookup.internal.launch.MavenSourceContainerResolver; + +// useful to lookup shaded binary projects like wagon-http-2.10-shaded.jar +public class BinaryProjectContainerResolver extends MavenSourceContainerResolver implements ISourceContainerResolver { + + @Override + protected ISourceContainer resolveSourceContainer(ArtifactKey artifact, IProgressMonitor monitor) { + String groupId = artifact.getGroupId(); + String artifactId = artifact.getArtifactId(); + String version = artifact.getVersion(); + + IMavenProjectRegistry projectRegistry = MavenPlugin.getMavenProjectRegistry(); + + IMavenProjectFacade mavenProject = projectRegistry.getMavenProject(groupId, artifactId, version); + if (mavenProject == null) { + return null; + } + + IProject project = mavenProject.getProject(); + + try { + final File binaryLocation = getBinaryLocation(project); + if (binaryLocation == null) { + return null; + } + + IJavaProject javaProject = JavaCore.create(project); + + Map<File, IPackageFragmentRoot> classpath = getClasspath(javaProject); + IPackageFragmentRoot binary = classpath.remove(binaryLocation); + + if (binary == null) { + return null; // this is a bug somewhere in my code + } + + return new PackageFragmentRootSourceContainer(binary); + } catch (CoreException e) { + // ignore, maybe log + } + + return null; + } +} diff --git a/org.eclipse.m2e.binaryproject/src/org/eclipse/m2e/binaryproject/internal/sourcelookup/BinaryProjectDescriber.java b/org.eclipse.m2e.binaryproject/src/org/eclipse/m2e/binaryproject/internal/sourcelookup/BinaryProjectDescriber.java new file mode 100644 index 00000000..5619de39 --- /dev/null +++ b/org.eclipse.m2e.binaryproject/src/org/eclipse/m2e/binaryproject/internal/sourcelookup/BinaryProjectDescriber.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2011-2016 Igor Fedorenko + * 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: + * Igor Fedorenko - initial API and implementation + *******************************************************************************/ +package org.eclipse.m2e.binaryproject.internal.sourcelookup; + +import static org.eclipse.jdt.launching.sourcelookup.advanced.AdvancedSourceLookup.getClasspath; + +import java.io.File; +import java.util.Map; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IPackageFragmentRoot; +import org.eclipse.jdt.launching.sourcelookup.advanced.IWorkspaceProjectDescriber; +import org.eclipse.jdt.launching.sourcelookup.containers.PackageFragmentRootSourceContainer; +import org.eclipse.m2e.binaryproject.internal.BinaryProjectPlugin; + +public class BinaryProjectDescriber implements IWorkspaceProjectDescriber { + + static File getBinaryLocation(IProject project) throws CoreException { + if (!project.isOpen()) { + return null; + } + final String binaryLocation = project.getPersistentProperty(BinaryProjectPlugin.QNAME_JAR); + if (binaryLocation == null) { + return null; + } + return new File(binaryLocation); + } + + @Override + public void describeProject(IJavaProject project, IJavaProjectSourceDescription description) throws CoreException { + final File binaryLocation = getBinaryLocation(project.getProject()); + if (binaryLocation == null) { + return; + } + + Map<File, IPackageFragmentRoot> classpath = getClasspath(project); + IPackageFragmentRoot binary = classpath.remove(binaryLocation); + + if (binary == null) { + return; // this is a bug somewhere in my code + } + + description.addDependencies(classpath); + description.addLocation(binaryLocation); + description.addSourceContainerFactory(() -> new PackageFragmentRootSourceContainer(binary)); + } + +} diff --git a/org.eclipse.m2e.feature/feature.xml b/org.eclipse.m2e.feature/feature.xml index 393caf7c..dd512e97 100644 --- a/org.eclipse.m2e.feature/feature.xml +++ b/org.eclipse.m2e.feature/feature.xml @@ -170,4 +170,32 @@ version="0.0.0" unpack="false"/> + <plugin + id="org.eclipse.m2e.sourcelookup" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.m2e.sourcelookup.ui" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.m2e.binaryproject" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.m2e.binaryproject.ui" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + </feature> diff --git a/org.eclipse.m2e.importer.tests/pom.xml b/org.eclipse.m2e.importer.tests/pom.xml index fbf7340b..07182c6f 100644 --- a/org.eclipse.m2e.importer.tests/pom.xml +++ b/org.eclipse.m2e.importer.tests/pom.xml @@ -24,10 +24,6 @@ Contributors: <name>Tests for Maven Integration for Eclipse Importer framework</name> - <properties> - <tycho.test.jvmArgs>-Xmx800m</tycho.test.jvmArgs> - <tycho.surefire.timeout>300</tycho.surefire.timeout> - </properties> <build> <pluginManagement> <plugins> @@ -38,53 +34,9 @@ Contributors: <configuration> <useUIHarness>true</useUIHarness> <useUIThread>false</useUIThread> - <!-- kill test JVM if tests take more than 10 minutes (600 seconds) to finish --> - <forkedProcessTimeoutInSeconds>${tycho.surefire.timeout}</forkedProcessTimeoutInSeconds> - <argLine>${tycho.test.jvmArgs}</argLine> - <includes> - <include>**/*Test.class</include> - </includes> </configuration> </plugin> </plugins> </pluginManagement> </build> - <profiles> - <profile> - <id>osx</id> - <activation> - <os> - <family>mac</family> - </os> - </activation> - <properties> - <tycho.test.jvmArgs>-Xmx800m -Dosgi.ws=cocoa -XstartOnFirstThread</tycho.test.jvmArgs> - </properties> - <build> - <pluginManagement> - <plugins> - <plugin> - <groupId>org.eclipse.tycho</groupId> - <artifactId>tycho-surefire-plugin</artifactId> - <version>${tycho-version}</version> - <configuration> - <dependencies combine.children="append"> - <dependency> - <artifactId>org.eclipse.jdt.launching.macosx</artifactId> - <version>0.0.0</version> - <type>eclipse-plugin</type> - </dependency> - <dependency> - <type>eclipse-feature</type> - <artifactId>org.eclipse.e4.rcp</artifactId> - <version>0.0.0</version> - </dependency> - </dependencies> - </configuration> - </plugin> - </plugins> - </pluginManagement> - </build> - </profile> - </profiles> </project> diff --git a/org.eclipse.m2e.launching/src/org/eclipse/m2e/internal/launch/MavenLaunchDelegate.java b/org.eclipse.m2e.launching/src/org/eclipse/m2e/internal/launch/MavenLaunchDelegate.java index 42ae7742..ac6bcaed 100644 --- a/org.eclipse.m2e.launching/src/org/eclipse/m2e/internal/launch/MavenLaunchDelegate.java +++ b/org.eclipse.m2e.launching/src/org/eclipse/m2e/internal/launch/MavenLaunchDelegate.java @@ -75,6 +75,10 @@ public class MavenLaunchDelegate extends JavaLaunchDelegate implements MavenLaun private MavenLaunchExtensionsSupport extensionsSupport; + public MavenLaunchDelegate() { + allowAdvancedSourcelookup(); + } + public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException { this.launch = launch; diff --git a/org.eclipse.m2e.sdk.feature/feature.xml b/org.eclipse.m2e.sdk.feature/feature.xml index b8443d9f..9611b6d6 100644 --- a/org.eclipse.m2e.sdk.feature/feature.xml +++ b/org.eclipse.m2e.sdk.feature/feature.xml @@ -144,4 +144,32 @@ version="0.0.0" unpack="false"/> + <plugin + id="org.eclipse.m2e.sourcelookup.source" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.m2e.sourcelookup.ui.source" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.m2e.binaryproject.source" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.m2e.binaryproject.ui.source" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + </feature> diff --git a/org.eclipse.m2e.sourcelookup.ui/META-INF/MANIFEST.MF b/org.eclipse.m2e.sourcelookup.ui/META-INF/MANIFEST.MF new file mode 100644 index 00000000..55329baf --- /dev/null +++ b/org.eclipse.m2e.sourcelookup.ui/META-INF/MANIFEST.MF @@ -0,0 +1,25 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %Bundle-Name +Bundle-SymbolicName: org.eclipse.m2e.sourcelookup.ui;singleton:=true +Bundle-Version: 1.9.0.qualifier +Bundle-Activator: org.eclipse.m2e.sourcelookup.ui.internal.SourceLookupUIActivator +Bundle-Vendor: %Bundle-Vendor +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.debug.ui;bundle-version="3.7.0", + org.eclipse.jdt.debug.ui;bundle-version="3.6.0", + org.eclipse.m2e.core;bundle-version="[1.9.0,1.10.0)", + org.eclipse.jdt.debug;bundle-version="3.7.0", + org.eclipse.m2e.sourcelookup;bundle-version="[1.9.0,1.10.0)", + org.eclipse.m2e.core.ui;bundle-version="[1.9.0,1.10.0)", + org.eclipse.m2e.maven.runtime;bundle-version="[1.9.0,1.10.0)", + org.eclipse.ui.ide;bundle-version="3.7.0", + org.eclipse.m2e.binaryproject;bundle-version="[1.9.0,1.10.0)", + org.eclipse.core.expressions, + org.eclipse.jdt.launching;bundle-version="3.10.0", + org.eclipse.jdt.core;bundle-version="3.9.0", + org.eclipse.core.resources, + org.eclipse.debug.core +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Bundle-ActivationPolicy: lazy diff --git a/org.eclipse.m2e.sourcelookup.ui/build.properties b/org.eclipse.m2e.sourcelookup.ui/build.properties new file mode 100644 index 00000000..b806395b --- /dev/null +++ b/org.eclipse.m2e.sourcelookup.ui/build.properties @@ -0,0 +1,6 @@ +source.. = src/ +output.. = target/classes/ +bin.includes = META-INF/,\ + .,\ + plugin.xml,\ + icons/ diff --git a/org.eclipse.m2e.sourcelookup.ui/icons/binary_project.gif b/org.eclipse.m2e.sourcelookup.ui/icons/binary_project.gif Binary files differnew file mode 100644 index 00000000..03c10b0b --- /dev/null +++ b/org.eclipse.m2e.sourcelookup.ui/icons/binary_project.gif diff --git a/org.eclipse.m2e.sourcelookup.ui/icons/open_pom.gif b/org.eclipse.m2e.sourcelookup.ui/icons/open_pom.gif Binary files differnew file mode 100644 index 00000000..aa4c32cd --- /dev/null +++ b/org.eclipse.m2e.sourcelookup.ui/icons/open_pom.gif diff --git a/org.eclipse.m2e.sourcelookup.ui/plugin.xml b/org.eclipse.m2e.sourcelookup.ui/plugin.xml new file mode 100644 index 00000000..240d8388 --- /dev/null +++ b/org.eclipse.m2e.sourcelookup.ui/plugin.xml @@ -0,0 +1,107 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?eclipse version="3.4"?> +<plugin> + <extension + point="org.eclipse.ui.menus"> + <menuContribution + allPopups="false" + locationURI="popup:org.eclipse.ui.popup.any?after=additions"> + <command + commandId="org.eclipse.m2e.sourcelookup.ui.openPom" + icon="icons/open_pom.gif" + style="push"> + <visibleWhen + checkEnabled="true"> + </visibleWhen> + </command> + <command + commandId="org.eclipse.m2e.sourcelookup.ui.importBinaryProject" + icon="icons/binary_project.gif" + style="push"> + <visibleWhen + checkEnabled="true"> + </visibleWhen> + </command> + <command + commandId="org.eclipse.m2e.sourcelookup.ui.openSourceLookupInfoDialog" + style="push"> + <visibleWhen + checkEnabled="true"> + </visibleWhen> + </command> + </menuContribution> + </extension> + <extension + point="org.eclipse.ui.commands"> + <command + id="org.eclipse.m2e.sourcelookup.ui.openPom" + name="Open Pom"> + </command> + <command + id="org.eclipse.m2e.sourcelookup.ui.importBinaryProject" + name="Import Binary Project"> + </command> + <command + id="org.eclipse.m2e.sourcelookup.ui.openSourceLookupInfoDialog" + name="Source Lookup Info"> + </command> + </extension> + <extension + point="org.eclipse.ui.handlers"> + <handler + class="org.eclipse.m2e.sourcelookup.ui.internal.OpenPomCommandHandler" + commandId="org.eclipse.m2e.sourcelookup.ui.openPom"> + <enabledWhen> + <reference + definitionId="org.eclipse.m2e.sourcelookup.ui.m2estratum"> + </reference> + </enabledWhen> + </handler> + <handler + class="org.eclipse.m2e.sourcelookup.ui.internal.ImportBinaryProjectHandler" + commandId="org.eclipse.m2e.sourcelookup.ui.importBinaryProject"> + <enabledWhen> + <reference + definitionId="org.eclipse.m2e.sourcelookup.ui.m2estratum"> + </reference> + </enabledWhen> + </handler> + <handler + class="org.eclipse.m2e.sourcelookup.ui.internal.OpenSourceLookupInfoDialogCommandHandler" + commandId="org.eclipse.m2e.sourcelookup.ui.openSourceLookupInfoDialog"> + <enabledWhen> + <reference + definitionId="org.eclipse.m2e.sourcelookup.ui.m2estratum"> + </reference> + </enabledWhen> + </handler> + </extension> + <extension + point="org.eclipse.core.expressions.definitions"> + <definition + id="org.eclipse.m2e.sourcelookup.ui.m2estratum"> + <with + variable="selection"> + <count + value="1"> + </count> + <iterate + ifEmpty="false" + operator="or"> + <test + property="org.eclipse.jdt.launching.jdtstratum"> + </test> + </iterate> + </with> + </definition> + </extension> + <extension + point="org.eclipse.ui.preferencePages"> + <page + category="org.eclipse.m2e.core.preferences.Maven2PreferencePage" + class="org.eclipse.m2e.sourcelookup.ui.internal.SourceLookupPreferencePage" + id="org.eclipse.m2e.sourcelookup.ui.internal.SourceLookupPreferencePage" + name="Source Lookup"> + </page> + </extension> +</plugin> diff --git a/org.eclipse.m2e.sourcelookup.ui/pom.xml b/org.eclipse.m2e.sourcelookup.ui/pom.xml new file mode 100644 index 00000000..3a1f18e9 --- /dev/null +++ b/org.eclipse.m2e.sourcelookup.ui/pom.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (c) 2011 Igor Fedorenko + 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 +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.eclipse.m2e</groupId> + <artifactId>m2e-core</artifactId> + <version>1.9.0-SNAPSHOT</version> + </parent> + + <artifactId>org.eclipse.m2e.sourcelookup.ui</artifactId> + <packaging>eclipse-plugin</packaging> +</project>
\ No newline at end of file diff --git a/org.eclipse.m2e.sourcelookup.ui/src/org/eclipse/m2e/sourcelookup/ui/internal/ImportBinaryProjectHandler.java b/org.eclipse.m2e.sourcelookup.ui/src/org/eclipse/m2e/sourcelookup/ui/internal/ImportBinaryProjectHandler.java new file mode 100644 index 00000000..c51aef22 --- /dev/null +++ b/org.eclipse.m2e.sourcelookup.ui/src/org/eclipse/m2e/sourcelookup/ui/internal/ImportBinaryProjectHandler.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2011-2016 Igor Fedorenko + * 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: + * Igor Fedorenko - initial API and implementation + *******************************************************************************/ +package org.eclipse.m2e.sourcelookup.ui.internal; + +import java.io.File; +import java.util.Collection; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.debug.core.DebugException; +import org.eclipse.jdt.launching.sourcelookup.advanced.AdvancedSourceLookup; +import org.eclipse.jdt.launching.sourcelookup.advanced.AdvancedSourceLookupParticipant; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.m2e.binaryproject.internal.AbstractBinaryProjectsImportJob; +import org.eclipse.m2e.core.embedder.ArtifactKey; +import org.eclipse.m2e.sourcelookup.internal.launch.MavenArtifactIdentifier; +import org.eclipse.ui.handlers.HandlerUtil; + +public class ImportBinaryProjectHandler extends AbstractHandler { + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + ISelection selection = HandlerUtil.getCurrentSelectionChecked(event); + + if (selection instanceof IStructuredSelection && !selection.isEmpty()) { + try { + importBinaryProjects(((IStructuredSelection) selection).getFirstElement()); + } catch (DebugException e) { + throw new ExecutionException("Could not import binary project", e); + } + } + + return null; + } + + public static void importBinaryProjects(final Object debugElement) throws DebugException { + + final File location = AdvancedSourceLookup.getClassesLocation(debugElement); + + if (location == null) { + return; + } + + Job job = new AbstractBinaryProjectsImportJob() { + @Override + protected IStatus run(IProgressMonitor monitor) { + IStatus status = super.run(monitor); + + if (status.isOK()) { + AdvancedSourceLookupParticipant sourceLookup = AdvancedSourceLookupParticipant.getSourceLookup(debugElement); + + try { + sourceLookup.getSourceContainer(debugElement, true, monitor); + } catch (CoreException e) { + status = e.getStatus(); + } + } + + return status; + } + + @Override + protected Collection<ArtifactKey> getArtifactKeys(IProgressMonitor monitor) throws CoreException { + return new MavenArtifactIdentifier().identify(location, monitor); + } + + }; + job.setUser(true); + job.schedule(); + } +} diff --git a/org.eclipse.m2e.sourcelookup.ui/src/org/eclipse/m2e/sourcelookup/ui/internal/OpenPomCommandHandler.java b/org.eclipse.m2e.sourcelookup.ui/src/org/eclipse/m2e/sourcelookup/ui/internal/OpenPomCommandHandler.java new file mode 100644 index 00000000..e7e8d3d5 --- /dev/null +++ b/org.eclipse.m2e.sourcelookup.ui/src/org/eclipse/m2e/sourcelookup/ui/internal/OpenPomCommandHandler.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (c) 2011-2012 Igor Fedorenko + * 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: + * Igor Fedorenko - initial API and implementation + *******************************************************************************/ +package org.eclipse.m2e.sourcelookup.ui.internal; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +import org.codehaus.plexus.util.IOUtil; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jdt.launching.sourcelookup.advanced.AdvancedSourceLookup; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.m2e.core.ui.internal.actions.OpenPomAction; +import org.eclipse.m2e.core.ui.internal.actions.OpenPomAction.MavenStorageEditorInput; +import org.eclipse.m2e.sourcelookup.internal.launch.MetaInfMavenScanner; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.handlers.HandlerUtil; + +@SuppressWarnings("restriction") +public class OpenPomCommandHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + ISelection selection = HandlerUtil.getCurrentSelectionChecked(event); + + if (!(selection instanceof IStructuredSelection) || selection.isEmpty()) { + return null; + } + + try { + final File location = + AdvancedSourceLookup.getClassesLocation(((IStructuredSelection) selection).getFirstElement()); + + if (location == null) { + return null; + } + + final String name = location.getName(); + + List<IEditorInput> inputs = new MetaInfMavenScanner<IEditorInput>() { + @Override + protected IEditorInput visitFile(File file) throws IOException { + return toEditorInput(name, new FileInputStream(file)); + } + + @Override + protected IEditorInput visitJarEntry(JarFile jar, JarEntry entry) throws IOException { + return toEditorInput(name, jar.getInputStream(entry)); + } + + }.scan(location, "pom.xml"); + + if (inputs.isEmpty()) { + return null; + } + + OpenPomAction.openEditor(inputs.get(0), "pom.xml"); + } catch (CoreException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return null; + } + + static MavenStorageEditorInput toEditorInput(String name, InputStream is) throws IOException { + try { + return new MavenStorageEditorInput(name, name, null, IOUtil.toByteArray(is)); + } finally { + IOUtil.close(is); + } + } +} diff --git a/org.eclipse.m2e.sourcelookup.ui/src/org/eclipse/m2e/sourcelookup/ui/internal/OpenSourceLookupInfoDialogCommandHandler.java b/org.eclipse.m2e.sourcelookup.ui/src/org/eclipse/m2e/sourcelookup/ui/internal/OpenSourceLookupInfoDialogCommandHandler.java new file mode 100644 index 00000000..991ddd7a --- /dev/null +++ b/org.eclipse.m2e.sourcelookup.ui/src/org/eclipse/m2e/sourcelookup/ui/internal/OpenSourceLookupInfoDialogCommandHandler.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2011-2013 Igor Fedorenko + * 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: + * Igor Fedorenko - initial API and implementation + *******************************************************************************/ +package org.eclipse.m2e.sourcelookup.ui.internal; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jdt.launching.sourcelookup.advanced.AdvancedSourceLookupParticipant; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.handlers.HandlerUtil; + +public class OpenSourceLookupInfoDialogCommandHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + ISelection selection = HandlerUtil.getCurrentSelectionChecked(event); + + if (!(selection instanceof IStructuredSelection) || selection.isEmpty()) { + return null; + } + + Object debugElement = ((IStructuredSelection) selection).getFirstElement(); + + final AdvancedSourceLookupParticipant sourceLookup = AdvancedSourceLookupParticipant.getSourceLookup(debugElement); + + if (debugElement != null && sourceLookup != null) { + new SourceLookupInfoDialog(HandlerUtil.getActiveShell(event), debugElement, sourceLookup).open(); + } + + return null; + } + +} diff --git a/org.eclipse.m2e.sourcelookup.ui/src/org/eclipse/m2e/sourcelookup/ui/internal/SourceLookupInfoDialog.java b/org.eclipse.m2e.sourcelookup.ui/src/org/eclipse/m2e/sourcelookup/ui/internal/SourceLookupInfoDialog.java new file mode 100644 index 00000000..503786ae --- /dev/null +++ b/org.eclipse.m2e.sourcelookup.ui/src/org/eclipse/m2e/sourcelookup/ui/internal/SourceLookupInfoDialog.java @@ -0,0 +1,225 @@ +/******************************************************************************* + * Copyright (c) 2012 Igor Fedorenko + * 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: + * Igor Fedorenko - initial API and implementation + *******************************************************************************/ +package org.eclipse.m2e.sourcelookup.ui.internal; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.debug.core.sourcelookup.ISourceContainer; +import org.eclipse.jdt.launching.sourcelookup.advanced.AdvancedSourceLookup; +import org.eclipse.jdt.launching.sourcelookup.advanced.AdvancedSourceLookupParticipant; +import org.eclipse.jdt.launching.sourcelookup.containers.PackageFragmentRootSourceContainer; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.m2e.core.embedder.ArtifactKey; +import org.eclipse.m2e.sourcelookup.internal.launch.MavenArtifactIdentifier; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.Clipboard; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +public class SourceLookupInfoDialog extends Dialog { + private final Object debugElement; + + private final AdvancedSourceLookupParticipant sourceLookup; + + private Text textLocation; + + private Text textGAV; + + private Text textJavaProject; + + private Text textSourceContainer; + + // FIXME + private IProgressMonitor monitor = new NullProgressMonitor(); + + public SourceLookupInfoDialog(Shell parentShell, Object debugElement, AdvancedSourceLookupParticipant sourceLookup) { + super(parentShell); + setShellStyle(SWT.RESIZE | SWT.TITLE); + this.debugElement = debugElement; + this.sourceLookup = sourceLookup; + } + + @Override + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + newShell.setText("Source lookup properties"); + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite container = (Composite) super.createDialogArea(parent); + container.setLayout(new GridLayout(2, false)); + + Label lblCodeLocation = new Label(container, SWT.NONE); + lblCodeLocation.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); + lblCodeLocation.setText("Code location:"); + + textLocation = new Text(container, SWT.BORDER | SWT.WRAP | SWT.MULTI); + textLocation.setEditable(false); + textLocation.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); + + Label lblGav = new Label(container, SWT.NONE); + lblGav.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); + lblGav.setText("GAV:"); + + textGAV = new Text(container, SWT.BORDER | SWT.WRAP); + textGAV.setEditable(false); + textGAV.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); + + Label lblJavaProject = new Label(container, SWT.NONE); + lblJavaProject.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); + lblJavaProject.setText("Java project:"); + + textJavaProject = new Text(container, SWT.BORDER | SWT.WRAP); + textJavaProject.setEditable(false); + textJavaProject.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); + + Label lblSourceContainer = new Label(container, SWT.NONE); + lblSourceContainer.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); + lblSourceContainer.setText("Source container:"); + + textSourceContainer = new Text(container, SWT.BORDER | SWT.WRAP); + textSourceContainer.setEditable(false); + textSourceContainer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); + + Composite fillerComposite = new Composite(container, SWT.NONE); + fillerComposite.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, true, 2, 1)); + + Composite actionsComposite = new Composite(container, SWT.NONE); + actionsComposite.setLayout(new RowLayout(SWT.HORIZONTAL)); + actionsComposite.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1)); + + Button btnCopy = new Button(actionsComposite, SWT.NONE); + btnCopy.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + copyToClipboard(); + } + }); + btnCopy.setToolTipText("Copy to clipboard"); + btnCopy.setText("Copy"); + + Button btnRefresh = new Button(actionsComposite, SWT.NONE); + btnRefresh.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + try { + sourceLookup.getSourceContainer(debugElement, true, monitor); + } catch (CoreException e1) { + showError(e1); + } + } + }); + btnRefresh.setToolTipText("Force rediscovery of source lookup information for this code location."); + btnRefresh.setText("Refresh"); + + updateDisplay(monitor); + + return container; + } + + @Override + protected void createButtonsForButtonBar(Composite parent) { + + createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); + } + + @Override + protected Point getInitialSize() { + return new Point(450, 300); + } + + private void updateDisplay(IProgressMonitor moninor) { + try { + File location = AdvancedSourceLookup.getClassesLocation(debugElement); + + if (location == null) { + return; + } + + textLocation.setText(location.getAbsolutePath()); + + ISourceContainer container = sourceLookup.getSourceContainer(debugElement, false, moninor /* sync */); + + // TODO consider extracting artifact keys from container + final Collection<ArtifactKey> artifacts = new MavenArtifactIdentifier().identify(location, moninor); + textGAV.setText(artifacts.toString()); + + // TODO extract project(s) from the container + textJavaProject.setText("<not-implemented>"); + + textSourceContainer.setText(toString(container)); + } catch (CoreException e) { + showError(e); + } + } + + void showError(CoreException e) { + ErrorDialog.openError(getParentShell(), "Source lookup info", "Could not determine code maven coordinates", + e.getStatus()); + } + + private String toString(ISourceContainer container) { + if (container == null) { + return ""; + } + + StringBuilder sb = new StringBuilder(); + sb.append(container.getClass().getSimpleName()).append(" ").append(container.getName()); + + if (container instanceof PackageFragmentRootSourceContainer) { + sb.append(" ").append( + ((PackageFragmentRootSourceContainer) container).getPackageFragmentRoot().getJavaProject().getProject()); + } + + return sb.toString(); + } + + void copyToClipboard() { + List<Transfer> dataTypes = new ArrayList<Transfer>(); + List<Object> data = new ArrayList<Object>(); + + Clipboard clipboard = new Clipboard(getShell().getDisplay()); + + StringBuilder sb = new StringBuilder(); + sb.append("Location: ").append(textLocation.getText()).append("\n"); + sb.append("GAV: ").append(textGAV.getText()).append("\n"); + sb.append("Java project: ").append(textJavaProject.getText()).append("\n"); + sb.append("Source container: ").append(textSourceContainer.getText()).append("\n"); + + dataTypes.add(TextTransfer.getInstance()); + data.add(sb.toString()); + + clipboard.setContents(data.toArray(), dataTypes.toArray(new Transfer[dataTypes.size()])); + + clipboard.dispose(); + } +} diff --git a/org.eclipse.m2e.sourcelookup.ui/src/org/eclipse/m2e/sourcelookup/ui/internal/SourceLookupPreferencePage.java b/org.eclipse.m2e.sourcelookup.ui/src/org/eclipse/m2e/sourcelookup/ui/internal/SourceLookupPreferencePage.java new file mode 100644 index 00000000..69f6fbc7 --- /dev/null +++ b/org.eclipse.m2e.sourcelookup.ui/src/org/eclipse/m2e/sourcelookup/ui/internal/SourceLookupPreferencePage.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2014 Igor Fedorenko + * 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: + * Igor Fedorenko - initial API and implementation + *******************************************************************************/ +package org.eclipse.m2e.sourcelookup.ui.internal; + +import org.eclipse.jdt.internal.launching.sourcelookup.advanced.AdvancedSourceLookupSupport; +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; + + +public class SourceLookupPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { + private Text vmArguments; + + private Text launchFileVMArguments; + + private Text launchFileAttribute; + + public SourceLookupPreferencePage() { + setMessage("Manual configuration of dynamic source lookup"); + noDefaultAndApplyButton(); + } + + public void init(IWorkbench workbench) {} + + @Override + protected Control createContents(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE) { + @Override + public Point computeSize(int wHint, int hHint, boolean changed) { + return new Point(0, 0); + } + }; + + GridLayout gl_composite = new GridLayout(1, false); + gl_composite.marginWidth = 0; + gl_composite.marginHeight = 0; + composite.setLayout(gl_composite); + + Label lblVMArguments = new Label(composite, SWT.NONE); + lblVMArguments.setText("VM arguments:"); + + vmArguments = new Text(composite, SWT.BORDER | SWT.READ_ONLY | SWT.WRAP); + vmArguments.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1)); + vmArguments.setText(AdvancedSourceLookupSupport.getJavaagentString()); + + Label lblLaunchVMArguments = new Label(composite, SWT.NONE); + lblLaunchVMArguments.setText(".launch file VM arguments:"); + + launchFileVMArguments = new Text(composite, SWT.BORDER | SWT.READ_ONLY | SWT.WRAP); + launchFileVMArguments.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1)); + launchFileVMArguments.setText("-javaagent:${sourcelookup_agent_path}"); + + Label lblLaunchFileAttribute = new Label(composite, SWT.NONE); + lblLaunchFileAttribute.setText(".launch file attribute:"); + + launchFileAttribute = new Text(composite, SWT.BORDER | SWT.READ_ONLY | SWT.WRAP); + launchFileAttribute.setText( + "<stringAttribute key=\"org.eclipse.debug.core.source_locator_id\" value=\"org.eclipse.m2e.sourcelookupDirector\"/>\n"); + launchFileAttribute.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); + + return composite; + } +} diff --git a/org.eclipse.m2e.sourcelookup.ui/src/org/eclipse/m2e/sourcelookup/ui/internal/SourceLookupUIActivator.java b/org.eclipse.m2e.sourcelookup.ui/src/org/eclipse/m2e/sourcelookup/ui/internal/SourceLookupUIActivator.java new file mode 100644 index 00000000..ef7a2241 --- /dev/null +++ b/org.eclipse.m2e.sourcelookup.ui/src/org/eclipse/m2e/sourcelookup/ui/internal/SourceLookupUIActivator.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2011-2012 Igor Fedorenko + * 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: + * Igor Fedorenko - initial API and implementation + *******************************************************************************/ +package org.eclipse.m2e.sourcelookup.ui.internal; + +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +public class SourceLookupUIActivator extends AbstractUIPlugin { + + public static final String PLUGIN_ID = "org.eclipse.m2e.sourcelookup.ui"; //$NON-NLS-1$ + + private static SourceLookupUIActivator plugin; + + public SourceLookupUIActivator() {} + + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + public static SourceLookupUIActivator getDefault() { + return plugin; + } + +} diff --git a/org.eclipse.m2e.sourcelookup/META-INF/MANIFEST.MF b/org.eclipse.m2e.sourcelookup/META-INF/MANIFEST.MF new file mode 100644 index 00000000..dd4a8fcc --- /dev/null +++ b/org.eclipse.m2e.sourcelookup/META-INF/MANIFEST.MF @@ -0,0 +1,25 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %Bundle-Name +Bundle-SymbolicName: org.eclipse.m2e.sourcelookup;singleton:=true +Bundle-Version: 1.9.0.qualifier +Bundle-Vendor: %Bundle-Vendor +Require-Bundle: org.eclipse.m2e.launching;bundle-version="[1.9.0,1.10.0)", + org.eclipse.m2e.core;bundle-version="[1.9.0,1.10.0)", + org.eclipse.m2e.maven.runtime;bundle-version="[1.9.0,1.10.0)", + org.eclipse.jdt.core;bundle-version="3.7.0", + org.eclipse.jdt.debug;bundle-version="3.8.0", + org.eclipse.jdt.launching;bundle-version="3.9.0", + org.slf4j.api;bundle-version="1.6.1", + org.eclipse.debug.core;bundle-version="3.7.0", + org.eclipse.core.runtime;bundle-version="3.7.0", + org.eclipse.core.expressions;bundle-version="3.4.400", + org.eclipse.debug.ui;bundle-version="3.10.0", + org.eclipse.core.resources, + com.google.guava;bundle-version="15.0.0", + com.google.gson;bundle-version="2.2.4", + org.eclipse.core.variables;bundle-version="3.2.0" +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Bundle-ActivationPolicy: lazy +Eclipse-BundleShape: dir +Export-Package: org.eclipse.m2e.sourcelookup.internal.launch;x-friends:="org.eclipse.m2e.sourcelookup.ui,org.eclipse.m2e.binaryproject" diff --git a/org.eclipse.m2e.sourcelookup/build.properties b/org.eclipse.m2e.sourcelookup/build.properties new file mode 100644 index 00000000..52a5b4fe --- /dev/null +++ b/org.eclipse.m2e.sourcelookup/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = target/classes +bin.includes = META-INF/,\ + .,\ + plugin.xml diff --git a/org.eclipse.m2e.sourcelookup/plugin.xml b/org.eclipse.m2e.sourcelookup/plugin.xml new file mode 100644 index 00000000..13aa85b6 --- /dev/null +++ b/org.eclipse.m2e.sourcelookup/plugin.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?eclipse version="3.4"?> +<plugin> + <extension + point="org.eclipse.jdt.launching.sourceContainerResolvers"> + <resolver + class="org.eclipse.m2e.sourcelookup.internal.launch.MavenSourceContainerResolver"> + </resolver> + </extension> + +</plugin> diff --git a/org.eclipse.m2e.sourcelookup/pom.xml b/org.eclipse.m2e.sourcelookup/pom.xml new file mode 100644 index 00000000..806f4b84 --- /dev/null +++ b/org.eclipse.m2e.sourcelookup/pom.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (c) 2011 Igor Fedorenko + 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 +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.eclipse.m2e</groupId> + <artifactId>m2e-core</artifactId> + <version>1.9.0-SNAPSHOT</version> + </parent> + + <artifactId>org.eclipse.m2e.sourcelookup</artifactId> + <packaging>eclipse-plugin</packaging> +</project>
\ No newline at end of file diff --git a/org.eclipse.m2e.sourcelookup/src/org/eclipse/m2e/sourcelookup/internal/launch/MavenArtifactIdentifier.java b/org.eclipse.m2e.sourcelookup/src/org/eclipse/m2e/sourcelookup/internal/launch/MavenArtifactIdentifier.java new file mode 100644 index 00000000..af625b72 --- /dev/null +++ b/org.eclipse.m2e.sourcelookup/src/org/eclipse/m2e/sourcelookup/internal/launch/MavenArtifactIdentifier.java @@ -0,0 +1,160 @@ +/******************************************************************************* + * Copyright (c) 2011-2016 Igor Fedorenko + * 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: + * Igor Fedorenko - initial API and implementation + *******************************************************************************/ +package org.eclipse.m2e.sourcelookup.internal.launch; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Properties; +import java.util.Set; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.m2e.core.MavenPlugin; +import org.eclipse.m2e.core.embedder.ArtifactKey; +import org.eclipse.m2e.core.internal.index.IIndex; +import org.eclipse.m2e.core.internal.index.IndexedArtifactFile; +import org.eclipse.m2e.core.internal.index.nexus.CompositeIndex; + +import com.google.common.base.Charsets; +import com.google.common.collect.ImmutableSet; +import com.google.common.hash.Hashing; +import com.google.common.io.Files; +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; + +@SuppressWarnings("restriction") +public class MavenArtifactIdentifier { + + // reads META-INF/maven/**/pom.properties + private static final MetaInfMavenScanner<Properties> scanner = new MetaInfMavenScanner<Properties>() { + @Override + protected Properties visitFile(File file) throws IOException { + // TODO validate properties and path match + try (InputStream is = new BufferedInputStream(new FileInputStream(file))) { + return loadProperties(is); + } + } + + @Override + protected Properties visitJarEntry(JarFile jar, JarEntry entry) throws IOException { + // TODO validate properties and path match + try (InputStream is = jar.getInputStream(entry)) { + return loadProperties(is); + } + } + + private Properties loadProperties(InputStream is) throws IOException { + Properties properties = new Properties(); + properties.load(is); + return properties; + } + }; + + public Collection<ArtifactKey> identify(File classesLocation, IProgressMonitor monitor) { + // checksum-based lookup in nexus index + // checksum-based lookup in central + // GAV extracted from pom.properties + + Collection<ArtifactKey> classesArtifacts = identifyNexusIndexer(classesLocation); + if (classesArtifacts == null) { + classesArtifacts = identifyCentralSearch(classesLocation); + } + if (classesArtifacts == null) { + classesArtifacts = scanPomProperties(classesLocation); + } + + return classesArtifacts; + } + + protected Collection<ArtifactKey> identifyNexusIndexer(File file) { + if (!file.isFile()) { + return null; + } + + try { + IIndex index = MavenPlugin.getIndexManager().getAllIndexes(); + + List<IndexedArtifactFile> identified; + if (index instanceof CompositeIndex) { + identified = ((CompositeIndex) index).identifyAll(file); + } else { + IndexedArtifactFile indexed = index.identify(file); + if (indexed != null) { + identified = Collections.singletonList(indexed); + } else { + identified = Collections.emptyList(); + } + } + + for (IndexedArtifactFile indexed : identified) { + if (indexed.sourcesExists == IIndex.PRESENT) { + return Collections.singleton(indexed.getArtifactKey()); + } + } + } catch (CoreException e) { + // TODO maybe log, but ignore otherwise + } + + return null; + } + + protected Collection<ArtifactKey> identifyCentralSearch(File file) { + if (!file.isFile()) { + return null; + } + + try { + String sha1 = Files.hash(file, Hashing.sha1()).toString(); // TODO use Locations for caching + URL url = new URL("https://search.maven.org/solrsearch/select?q=1:" + sha1); + try (InputStreamReader reader = new InputStreamReader(url.openStream(), Charsets.UTF_8)) { + Set<ArtifactKey> result = new LinkedHashSet<>(); + JsonObject container = new Gson().fromJson(reader, JsonObject.class); + JsonArray docs = container.get("response").getAsJsonObject().get("docs").getAsJsonArray(); + for (int i = 0; i < docs.size(); i++) { + JsonObject doc = docs.get(i).getAsJsonObject(); + String g = doc.get("g").getAsString(); + String a = doc.get("a").getAsString(); + String v = doc.get("v").getAsString(); + result.add(new ArtifactKey(g, a, v, null)); + } + return !result.isEmpty() ? ImmutableSet.copyOf(result) : null; + } + } catch (IOException e) { + // TODO maybe log, ignore otherwise + } + return null; + } + + public Collection<ArtifactKey> scanPomProperties(File classesLocation) { + Set<ArtifactKey> artifacts = new LinkedHashSet<>(); + for (Properties pomProperties : scanner.scan(classesLocation, "pom.properties")) { + String groupId = pomProperties.getProperty("groupId"); + String artifactId = pomProperties.getProperty("artifactId"); + String version = pomProperties.getProperty("version"); + if (groupId != null && artifactId != null && version != null) { + artifacts.add(new ArtifactKey(groupId, artifactId, version, /* classifier= */null)); + } + } + return ImmutableSet.copyOf(artifacts); + } +} diff --git a/org.eclipse.m2e.sourcelookup/src/org/eclipse/m2e/sourcelookup/internal/launch/MavenSourceContainerResolver.java b/org.eclipse.m2e.sourcelookup/src/org/eclipse/m2e/sourcelookup/internal/launch/MavenSourceContainerResolver.java new file mode 100644 index 00000000..6b4a6b26 --- /dev/null +++ b/org.eclipse.m2e.sourcelookup/src/org/eclipse/m2e/sourcelookup/internal/launch/MavenSourceContainerResolver.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2011-2016 Igor Fedorenko + * 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: + * Igor Fedorenko - initial API and implementation + *******************************************************************************/ +package org.eclipse.m2e.sourcelookup.internal.launch; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.debug.core.sourcelookup.ISourceContainer; +import org.eclipse.debug.core.sourcelookup.containers.ExternalArchiveSourceContainer; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.launching.sourcelookup.advanced.ISourceContainerResolver; +import org.eclipse.jdt.launching.sourcelookup.containers.JavaProjectSourceContainer; +import org.eclipse.m2e.core.MavenPlugin; +import org.eclipse.m2e.core.embedder.ArtifactKey; +import org.eclipse.m2e.core.embedder.IMaven; +import org.eclipse.m2e.core.project.IMavenProjectFacade; +import org.eclipse.m2e.core.project.IMavenProjectRegistry; + + +public class MavenSourceContainerResolver implements ISourceContainerResolver { + + private static final MavenArtifactIdentifier INDENTIFIER = new MavenArtifactIdentifier(); + + @Override + public Collection<ISourceContainer> resolveSourceContainers(File classesLocation, IProgressMonitor monitor) { + Collection<ArtifactKey> classesArtifacts = INDENTIFIER.identify(classesLocation, monitor); + + if (classesArtifacts == null) { + return null; + } + + List<ISourceContainer> result = new ArrayList<>(); + for (ArtifactKey classesArtifact : classesArtifacts) { + ISourceContainer container = resolveSourceContainer(classesArtifact, monitor); + if (container != null) { + result.add(container); + } + } + return result; + } + + protected ISourceContainer resolveSourceContainer(ArtifactKey artifact, IProgressMonitor monitor) { + String groupId = artifact.getGroupId(); + String artifactId = artifact.getArtifactId(); + String version = artifact.getVersion(); + + IMaven maven = MavenPlugin.getMaven(); + IMavenProjectRegistry projectRegistry = MavenPlugin.getMavenProjectRegistry(); + + IMavenProjectFacade mavenProject = projectRegistry.getMavenProject(groupId, artifactId, version); + if (mavenProject != null) { + return new JavaProjectSourceContainer(JavaCore.create(mavenProject.getProject())); + } + + try { + List<ArtifactRepository> repositories = new ArrayList<ArtifactRepository>(); + repositories.addAll(maven.getArtifactRepositories()); + repositories.addAll(maven.getPluginArtifactRepositories()); + + if (!maven.isUnavailable(groupId, artifactId, version, "jar", "sources", repositories)) { + Artifact resolve = maven.resolve(groupId, artifactId, version, "jar", "sources", null, monitor); + + return new ExternalArchiveSourceContainer(resolve.getFile().getAbsolutePath(), true); + } + } catch (CoreException e) { + // TODO maybe log, ignore otherwise + } + + return null; + } +} diff --git a/org.eclipse.m2e.sourcelookup/src/org/eclipse/m2e/sourcelookup/internal/launch/MavenSourceLookupParticipant.java b/org.eclipse.m2e.sourcelookup/src/org/eclipse/m2e/sourcelookup/internal/launch/MavenSourceLookupParticipant.java new file mode 100644 index 00000000..16954c74 --- /dev/null +++ b/org.eclipse.m2e.sourcelookup/src/org/eclipse/m2e/sourcelookup/internal/launch/MavenSourceLookupParticipant.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2011-2016 Igor Fedorenko + * 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: + * Igor Fedorenko - initial API and implementation + *******************************************************************************/ +package org.eclipse.m2e.sourcelookup.internal.launch; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector; +import org.eclipse.jdt.launching.sourcelookup.advanced.AdvancedSourceLookupParticipant; +import org.eclipse.m2e.core.MavenPlugin; +import org.eclipse.m2e.core.project.IMavenProjectChangedListener; +import org.eclipse.m2e.core.project.MavenProjectChangedEvent; + + +public class MavenSourceLookupParticipant extends AdvancedSourceLookupParticipant + implements + IMavenProjectChangedListener { + + @Override + public void init(ISourceLookupDirector director) { + super.init(director); + MavenPlugin.getMavenProjectRegistry().addMavenProjectChangedListener(this); + } + + @Override + public void dispose() { + MavenPlugin.getMavenProjectRegistry().removeMavenProjectChangedListener(this); + super.dispose(); + } + + @Override + public void mavenProjectChanged(MavenProjectChangedEvent[] events, IProgressMonitor monitor) { + disposeContainers(); + } +} diff --git a/org.eclipse.m2e.sourcelookup/src/org/eclipse/m2e/sourcelookup/internal/launch/MetaInfMavenScanner.java b/org.eclipse.m2e.sourcelookup/src/org/eclipse/m2e/sourcelookup/internal/launch/MetaInfMavenScanner.java new file mode 100644 index 00000000..77ddb23b --- /dev/null +++ b/org.eclipse.m2e.sourcelookup/src/org/eclipse/m2e/sourcelookup/internal/launch/MetaInfMavenScanner.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2011-2012 Igor Fedorenko + * 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: + * Igor Fedorenko - initial API and implementation + *******************************************************************************/ +package org.eclipse.m2e.sourcelookup.internal.launch; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +/** + * Helper to find and extract information from META-INF/maven pom.properties files. + */ +public abstract class MetaInfMavenScanner<T> { + + private static final String META_INF_MAVEN = "META-INF/maven"; + + public List<T> scan(File file, String filename) { + List<T> result = new ArrayList<T>(); + if (file != null) { + if (file.isDirectory()) { + scanFilesystem(new File(file, META_INF_MAVEN), filename, result); + } else if (file.isFile()) { + try { + try (JarFile jar = new JarFile(file)) { + scanJar(jar, filename, result); + } + } catch (IOException e) { + // fall through + } + } + } + return result; + } + + private void scanJar(JarFile jar, String filename, List<T> result) throws IOException { + Enumeration<JarEntry> entries = jar.entries(); + while (entries.hasMoreElements()) { + JarEntry entry = entries.nextElement(); + if (!entry.isDirectory()) { + String name = entry.getName(); + if (name.startsWith(META_INF_MAVEN) && name.endsWith(filename)) { + try { + T t = visitJarEntry(jar, entry); + if (t != null) { + result.add(t); + } + } catch (IOException e) { + // ignore + } + } + } + } + } + + private void scanFilesystem(File dir, String filename, List<T> result) { + File[] files = dir.listFiles(); + if (files == null) { + return; + } + for (File file : files) { + if (file.isDirectory()) { + scanFilesystem(file, filename, result); + } else if (file.isFile() && filename.equals(file.getName())) { + try { + T t = visitFile(file); + if (t != null) { + result.add(t); + } + } catch (IOException e) { + // ignore + } + } + } + } + + protected abstract T visitFile(File file) throws IOException; + + protected abstract T visitJarEntry(JarFile jar, JarEntry entry) throws IOException; +} @@ -43,6 +43,9 @@ <eclipse.stream>photon</eclipse.stream> <eclipse-repo.url>http://download.eclipse.org/eclipse/updates/4.8-I-builds/</eclipse-repo.url> <eclipse-simrel.url>http://download.eclipse.org/releases/${eclipse.stream}</eclipse-simrel.url> + + <tycho.test.jvmArgs>-Xmx800m</tycho.test.jvmArgs> + <tycho.surefire.timeout>7200</tycho.surefire.timeout> </properties> <organization> @@ -106,21 +109,27 @@ <module>org.eclipse.m2e.profiles.core</module> <module>org.eclipse.m2e.profiles.ui</module> <module>org.eclipse.m2e.importer</module> + <module>org.eclipse.m2e.binaryproject</module> + <module>org.eclipse.m2e.binaryproject.ui</module> + <module>org.eclipse.m2e.sourcelookup</module> + <module>org.eclipse.m2e.sourcelookup.ui</module> <!-- common test helpers --> <module>org.eclipse.m2e.tests.common</module> - <module>org.eclipse.m2e.importer.tests</module> <!-- Logging --> <module>org.eclipse.m2e.logback.appender</module> <module>org.eclipse.m2e.logback.configuration</module> - <!-- features --> + <!-- features and update site --> <module>org.eclipse.m2e.feature</module> <module>org.eclipse.m2e.sdk.feature</module> <module>org.eclipse.m2e.logback.feature</module> - <module>org.eclipse.m2e.site</module> + + <!-- testing --> + <module>org.eclipse.m2e.importer.tests</module> + <module>org.eclipse.m2e.binaryproject.tests</module> </modules> @@ -204,7 +213,7 @@ <include>**/*Test.java</include> </includes> <argLine>${tycho.test.jvmArgs}</argLine> - <forkedProcessTimeoutInSeconds>7200</forkedProcessTimeoutInSeconds> + <forkedProcessTimeoutInSeconds>${tycho.surefire.timeout}</forkedProcessTimeoutInSeconds> </configuration> </plugin> <plugin> @@ -317,6 +326,43 @@ <module>m2e-maven-runtime</module> </modules> </profile> + + <profile> + <id>osx</id> + <activation> + <os> + <family>mac</family> + </os> + </activation> + <properties> + <tycho.test.jvmArgs>-Xmx800m -Dosgi.ws=cocoa -XstartOnFirstThread</tycho.test.jvmArgs> + </properties> + <build> + <pluginManagement> + <plugins> + <plugin> + <groupId>org.eclipse.tycho</groupId> + <artifactId>tycho-surefire-plugin</artifactId> + <version>${tycho-version}</version> + <configuration> + <dependencies combine.children="append"> + <dependency> + <artifactId>org.eclipse.jdt.launching.macosx</artifactId> + <version>0.0.0</version> + <type>eclipse-plugin</type> + </dependency> + <dependency> + <type>eclipse-feature</type> + <artifactId>org.eclipse.e4.rcp</artifactId> + <version>0.0.0</version> + </dependency> + </dependencies> + </configuration> + </plugin> + </plugins> + </pluginManagement> + </build> + </profile> </profiles> <developers> |