From 4ca92c9bc4580b77420b7bbd27fa69fa4aa9d7d4 Mon Sep 17 00:00:00 2001 From: Artem Zatsarynnyi Date: Wed, 6 Dec 2017 16:46:41 +0200 Subject: [PATCH] Made it possible to extend Che IDE GWT app in custom assemblies by including additional plugins and/or excluding existing (standard) ones (#7746) Signed-off-by: Artem Zatsarynnyi --- core/che-core-gwt-maven-plugin/pom.xml | 161 ++++++++++ .../che/plugin/gwt/ProcessExcludesMojo.java | 277 ++++++++++++++++++ .../org/eclipse/che/plugin/gwt/Utils.java | 53 ++++ .../plugin/gwt/ProcessExcludesMojoTest.java | 108 +++++++ .../che/plugin/gwt/stub/ProjectStub.java | 125 ++++++++ .../stub/ProjectWithoutExclusionsStub.java | 19 ++ .../classes/org/eclipse/che/ide/IDE.gwt.xml | 20 ++ .../project-without-exclusions/pom.xml | 48 +++ .../classes/org/eclipse/che/ide/IDE.gwt.xml | 20 ++ .../src/test/projects/project/pom.xml | 54 ++++ core/pom.xml | 1 + ide/README.md | 54 ++++ ide/che-ide-full/pom.xml | 243 +++++++++++++++ ide/che-ide-gwt-app/pom.xml | 189 +----------- pom.xml | 22 ++ 15 files changed, 1206 insertions(+), 188 deletions(-) create mode 100644 core/che-core-gwt-maven-plugin/pom.xml create mode 100644 core/che-core-gwt-maven-plugin/src/main/java/org/eclipse/che/plugin/gwt/ProcessExcludesMojo.java create mode 100644 core/che-core-gwt-maven-plugin/src/main/java/org/eclipse/che/plugin/gwt/Utils.java create mode 100644 core/che-core-gwt-maven-plugin/src/test/java/org/eclipse/che/plugin/gwt/ProcessExcludesMojoTest.java create mode 100644 core/che-core-gwt-maven-plugin/src/test/java/org/eclipse/che/plugin/gwt/stub/ProjectStub.java create mode 100644 core/che-core-gwt-maven-plugin/src/test/java/org/eclipse/che/plugin/gwt/stub/ProjectWithoutExclusionsStub.java create mode 100644 core/che-core-gwt-maven-plugin/src/test/projects/project-without-exclusions/classes/org/eclipse/che/ide/IDE.gwt.xml create mode 100644 core/che-core-gwt-maven-plugin/src/test/projects/project-without-exclusions/pom.xml create mode 100644 core/che-core-gwt-maven-plugin/src/test/projects/project/classes/org/eclipse/che/ide/IDE.gwt.xml create mode 100644 core/che-core-gwt-maven-plugin/src/test/projects/project/pom.xml create mode 100644 ide/che-ide-full/pom.xml diff --git a/core/che-core-gwt-maven-plugin/pom.xml b/core/che-core-gwt-maven-plugin/pom.xml new file mode 100644 index 0000000000..54a1a9f1d5 --- /dev/null +++ b/core/che-core-gwt-maven-plugin/pom.xml @@ -0,0 +1,161 @@ + + + + 4.0.0 + + che-core-parent + org.eclipse.che.core + 6.0.0-M3-SNAPSHOT + + che-core-gwt-maven-plugin + maven-plugin + Che Core :: IDE :: GWT Maven Plugin + + + org.apache.commons + commons-compress + + + org.apache.maven + maven-artifact + + + org.apache.maven + maven-core + + + jsr250-api + javax.annotation + + + + + org.apache.maven + maven-plugin-api + + + org.apache.maven.plugin-tools + maven-plugin-annotations + + + org.codehaus.plexus + plexus-utils + + + junit + junit + test + + + org.apache.maven + maven-compat + test + + + org.apache.maven + maven-model + test + + + org.apache.maven.plugin-testing + maven-plugin-testing-harness + test + + + org.eclipse.che.core + che-ide-full + test + + + org.eclipse.che.plugin + che-plugin-help-ext-client + test + + + org.mockito + mockito-core + test + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + ${project.version} + + + + + org.apache.maven.plugins + maven-plugin-plugin + + + mojo-descriptor + + descriptor + + + + help-goal + + helpmojo + + + + + true + + + + net.ltgt.gwt.maven + gwt-maven-plugin + true + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-dependencies-for-tests + generate-test-resources + + copy + + + + + org.eclipse.che.core + che-ide-full + ${project.version} + che-ide-full-${project.version}.jar + ${project.build.directory}/local-repo/org/eclipse/che/core/che-ide-full/${project.version} + + + org.eclipse.che.plugin + che-plugin-help-ext-client + ${project.version} + che-plugin-help-ext-client-${project.version}.jar + ${project.build.directory}/local-repo/org/eclipse/che/plugin/che-plugin-help-ext-client/${project.version} + + + + + + + + + diff --git a/core/che-core-gwt-maven-plugin/src/main/java/org/eclipse/che/plugin/gwt/ProcessExcludesMojo.java b/core/che-core-gwt-maven-plugin/src/main/java/org/eclipse/che/plugin/gwt/ProcessExcludesMojo.java new file mode 100644 index 0000000000..e2d9b87eff --- /dev/null +++ b/core/che-core-gwt-maven-plugin/src/main/java/org/eclipse/che/plugin/gwt/ProcessExcludesMojo.java @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.plugin.gwt; + +import static java.lang.String.format; +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.eclipse.che.plugin.gwt.Utils.getFileContent; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; +import java.io.Writer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.zip.ZipFile; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.artifact.resolver.ArtifactResolutionRequest; +import org.apache.maven.artifact.resolver.ArtifactResolutionResult; +import org.apache.maven.artifact.resolver.filter.ArtifactFilter; +import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugins.annotations.Component; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.plugins.annotations.ResolutionScope; +import org.apache.maven.project.MavenProject; +import org.apache.maven.repository.RepositorySystem; +import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter; +import org.codehaus.plexus.util.xml.XMLWriter; +import org.codehaus.plexus.util.xml.Xpp3Dom; +import org.codehaus.plexus.util.xml.Xpp3DomBuilder; +import org.codehaus.plexus.util.xml.Xpp3DomWriter; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; + +/** + * Detects if Full IDE dependency with excluded plugins declared in pom.xml and modifies the IDE GWT + * module to avoid inheriting modules of the excluded plugins. + */ +@Mojo( + name = "process-excludes", + defaultPhase = LifecyclePhase.PROCESS_RESOURCES, + requiresDependencyResolution = ResolutionScope.COMPILE +) +public class ProcessExcludesMojo extends AbstractMojo { + + public static final String FULL_IDE_ARTIFACT_ID = "che-ide-full"; + public static final String FULL_IDE_GWT_MODULE_SUFFIX = "-with-excludes"; + + @Component private RepositorySystem repositorySystem; + + /** The local repository to use for the artifacts resolution. */ + @Parameter(defaultValue = "${localRepository}", required = true, readonly = true) + private ArtifactRepository localRepository; + + /** The remote repositories to use for the artifacts resolution. */ + @Parameter( + defaultValue = "${project.remoteArtifactRepositories}", + required = true, + readonly = true + ) + private List remoteRepositories; + + @Parameter(defaultValue = "${project.build.outputDirectory}", required = true) + private File outputDirectory; + + @Parameter(defaultValue = "${project}", required = true, readonly = true) + private MavenProject project; + + /** Full IDE maven artifact. */ + private Artifact fullIdeArtifact; + + /** Name of the Full IDE GWT module. */ + private String fullIdeGwtModule; + + @Override + public void execute() throws MojoExecutionException { + if (!init()) { + getLog().debug(format("No dependency on '%s'. Skipping the execution", FULL_IDE_ARTIFACT_ID)); + return; + } + + getLog().debug("Detected dependency on " + fullIdeArtifact.getArtifactId()); + + try { + Set excludedModules = detectExcludedGwtModules(); + + if (excludedModules.isEmpty()) { + getLog().debug("No excluded GWT modules detected. Skipping the execution"); + return; + } + + createFullIdeModuleWithExcludes(excludedModules); + patchGwtModule(); + } catch (XmlPullParserException | IOException e) { + throw new MojoExecutionException(e.getMessage(), e); + } + } + + /** + * Initializes mojo with the essential information about Full IDE dependency. + * + * @return {@code true} if there is a dependency on Full IDE in pom.xml; otherwise - {@code false} + * @throws IllegalStateException if error occurs during getting Full IDE dependency information + */ + private boolean init() { + Optional fullIdeArtifactOpt = + project + .getDependencyArtifacts() + .stream() + .filter(artifact -> FULL_IDE_ARTIFACT_ID.equals(artifact.getArtifactId())) + .findAny(); + + if (!fullIdeArtifactOpt.isPresent()) { + return false; + } + + fullIdeArtifact = fullIdeArtifactOpt.get(); + + try { + fullIdeGwtModule = readGwtModuleName(fullIdeArtifact); + } catch (IOException e) { + throw new IllegalStateException(e.getMessage(), e); + } + + return true; + } + + /** + * Detects the GWT modules that should be excluded from the IDE GWT app. + * + * @return detected GWT modules + */ + private Set detectExcludedGwtModules() throws IOException { + Set modules = new HashSet<>(); + + ArtifactFilter dependencyFilter = fullIdeArtifact.getDependencyFilter(); + + if (dependencyFilter instanceof ExcludesArtifactFilter) { + ExcludesArtifactFilter excludesDependencyFilter = (ExcludesArtifactFilter) dependencyFilter; + + for (String pattern : excludesDependencyFilter.getPatterns()) { + String[] split = pattern.split(":"); + String groupId = split[0]; + String artifactId = split[1]; + String version = fullIdeArtifact.getVersion(); + + Artifact artifact = repositorySystem.createArtifact(groupId, artifactId, version, "jar"); + String gwtModule = readGwtModuleName(artifact); + + modules.add(gwtModule); + + getLog().info("Detected GWT module to exclude: " + gwtModule); + } + } + + return modules; + } + + /** Creates copy of the Full.gwt.xml with removed '' for the excluded GWT modules. */ + private void createFullIdeModuleWithExcludes(Set modulesToExclude) + throws XmlPullParserException, IOException { + String fullIdeGwtModulePath = fullIdeGwtModule.replace('.', '/') + ".gwt.xml"; + String fullIdeGwtModuleContent = + getFileContent(new ZipFile(fullIdeArtifact.getFile()), fullIdeGwtModulePath); + + InputStream in = new ByteArrayInputStream(fullIdeGwtModuleContent.getBytes(UTF_8.name())); + Xpp3Dom module = Xpp3DomBuilder.build(in, UTF_8.name()); + + for (int i = module.getChildCount() - 1; i >= 0; i--) { + Xpp3Dom child = module.getChild(i); + + if ("inherits".equals(child.getName())) { + String moduleName = child.getAttribute("name"); + + if (modulesToExclude.contains(moduleName)) { + module.removeChild(i); + } + } + } + + String moduleRelPath = + fullIdeGwtModulePath.replace(".gwt.xml", FULL_IDE_GWT_MODULE_SUFFIX + ".gwt.xml"); + + Path modulePath = Paths.get(outputDirectory.getPath(), moduleRelPath); + + try (Writer writer = new StringWriter()) { + XMLWriter xmlWriter = new PrettyPrintXMLWriter(writer); + Xpp3DomWriter.write(xmlWriter, module); + Files.write(modulePath, writer.toString().getBytes()); + } + } + + /** + * Patches the IDE GWT module by replacing inheritance of Full.gwt.xml by + * Full-with-excludes.gwt.xml. + */ + private void patchGwtModule() throws XmlPullParserException, IOException { + String gwtModuleFileRelPath = getGwtModule().replace('.', '/') + ".gwt.xml"; + Path gwtModuleFilePath = Paths.get(outputDirectory.getPath(), gwtModuleFileRelPath); + + Xpp3Dom module = Xpp3DomBuilder.build(Files.newInputStream(gwtModuleFilePath), UTF_8.name()); + + for (int i = module.getChildCount() - 1; i >= 0; i--) { + Xpp3Dom child = module.getChild(i); + + if ("inherits".equals(child.getName())) { + String moduleName = child.getAttribute("name"); + + if (moduleName.equals(fullIdeGwtModule)) { + child.setAttribute("name", fullIdeGwtModule + FULL_IDE_GWT_MODULE_SUFFIX); + break; + } + } + } + + try (Writer writer = new StringWriter()) { + XMLWriter xmlWriter = new PrettyPrintXMLWriter(writer); + Xpp3DomWriter.write(xmlWriter, module); + Files.write(gwtModuleFilePath, writer.toString().getBytes()); + } + } + + /** Returns GWT module name specified in the configuration of the gwt-maven-plugin. */ + private String getGwtModule() { + Xpp3Dom configuration = + project.getGoalConfiguration("net.ltgt.gwt.maven", "gwt-maven-plugin", null, null); + + return configuration.getChild("moduleName").getValue(); + } + + /** Reads name of GWT module from the given artifact. */ + private String readGwtModuleName(Artifact artifact) throws IOException { + if (artifact.getFile() == null) { + resolveArtifact(artifact); + } + + return getFileContent(new ZipFile(artifact.getFile()), "META-INF/gwt/mainModule"); + } + + /** + * Resolves the given artifact from a repository. + * + * @param artifact artifact to resolve + * @throws IllegalStateException if unable to resolve artifact + */ + private void resolveArtifact(Artifact artifact) { + ArtifactResolutionRequest resolutionRequest = + new ArtifactResolutionRequest() + .setLocalRepository(localRepository) + .setRemoteRepositories(remoteRepositories) + .setArtifact(artifact); + + ArtifactResolutionResult resolutionResult = repositorySystem.resolve(resolutionRequest); + + if (!resolutionResult.isSuccess()) { + throw new IllegalStateException("Unable to resolve artifact " + artifact.toString()); + } + } +} diff --git a/core/che-core-gwt-maven-plugin/src/main/java/org/eclipse/che/plugin/gwt/Utils.java b/core/che-core-gwt-maven-plugin/src/main/java/org/eclipse/che/plugin/gwt/Utils.java new file mode 100644 index 0000000000..3722425a52 --- /dev/null +++ b/core/che-core-gwt-maven-plugin/src/main/java/org/eclipse/che/plugin/gwt/Utils.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.plugin.gwt; + +import static java.lang.String.format; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Enumeration; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import org.apache.commons.compress.utils.IOUtils; + +public class Utils { + + private Utils() {} + + /** + * Reads content of the file from ZIP archive. + * + * @param zipFile ZIP file + * @param path path of the file to read content + * @return content of the file with the given path + * @throws IOException if error occurs while reading + * @throws IllegalArgumentException if file not found in ZIP archive + */ + public static String getFileContent(ZipFile zipFile, String path) throws IOException { + Enumeration entries = zipFile.entries(); + + while (entries.hasMoreElements()) { + ZipEntry entry = entries.nextElement(); + + if (path.equals(entry.getName())) { + try (InputStream in = zipFile.getInputStream(entry)) { + byte[] bytes = IOUtils.toByteArray(in); + + return new String(bytes); + } + } + } + + throw new IllegalArgumentException( + format("Cannot find file '%s' in '%s'", path, zipFile.getName())); + } +} diff --git a/core/che-core-gwt-maven-plugin/src/test/java/org/eclipse/che/plugin/gwt/ProcessExcludesMojoTest.java b/core/che-core-gwt-maven-plugin/src/test/java/org/eclipse/che/plugin/gwt/ProcessExcludesMojoTest.java new file mode 100644 index 0000000000..22bedf288b --- /dev/null +++ b/core/che-core-gwt-maven-plugin/src/test/java/org/eclipse/che/plugin/gwt/ProcessExcludesMojoTest.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.plugin.gwt; + +import static org.eclipse.che.plugin.gwt.ProcessExcludesMojo.FULL_IDE_GWT_MODULE_SUFFIX; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import org.apache.maven.plugin.testing.MojoRule; +import org.apache.maven.plugin.testing.resources.TestResources; +import org.codehaus.plexus.util.FileUtils; +import org.codehaus.plexus.util.StringUtils; +import org.junit.Rule; +import org.junit.Test; + +public class ProcessExcludesMojoTest { + + /** Rule to manage the mojo (set/get values of variables of mojo). */ + @Rule public MojoRule rule = new MojoRule(); + + /** Resources of each test mapped on the name of the method. */ + @Rule public TestResources resources = new TestResources(); + + /** + * Injects data in mojo. + * + * @param mojo the mojo + * @param baseDir root dir on which we extract files + * @throws IllegalAccessException if unable to set variables + */ + private void configureMojo(ProcessExcludesMojo mojo, File baseDir) throws Exception { + rule.setVariableValueToObject(mojo, "outputDirectory", new File(baseDir, "classes")); + } + + /** + * Tests the ability of the plugin to process IDE GWT module (IDE.gwt.xml) to prevent inheriting + * the GWT modules of the excluded IDE plugins. + */ + @Test + public void testProcessingExcludes() throws Exception { + File projectCopy = resources.getBasedir("project"); + File pom = new File(projectCopy, "pom.xml"); + assertTrue(pom.exists()); + + ProcessExcludesMojo mojo = (ProcessExcludesMojo) rule.lookupMojo("process-excludes", pom); + assertNotNull(mojo); + + configureMojo(mojo, projectCopy); + mojo.execute(); + + File fullGwtXml = + new File( + projectCopy, + "classes/org/eclipse/che/ide/Full" + FULL_IDE_GWT_MODULE_SUFFIX + ".gwt.xml"); + assertTrue(fullGwtXml.exists()); + + String fullGwtXmlContent = FileUtils.fileRead(fullGwtXml); + assertFalse(fullGwtXmlContent.contains("org.eclipse.che.ide.ext.help.HelpAboutExtension")); + + File ideGwtXml = new File(projectCopy, "classes/org/eclipse/che/ide/IDE.gwt.xml"); + assertTrue(ideGwtXml.exists()); + + String ideGwtXmlContent = FileUtils.fileRead(ideGwtXml); + assertFalse(ideGwtXmlContent.contains("")); + assertTrue( + ideGwtXmlContent.contains( + "")); + } + + /** + * Tests that plugins doesn't modify the IDE GWT module (IDE.gwt.xml) if there are no excluded + * plugins. + */ + @Test + public void testWithoutExcludes() throws Exception { + File projectCopy = resources.getBasedir("project-without-exclusions"); + File pom = new File(projectCopy, "pom.xml"); + assertTrue(pom.exists()); + + ProcessExcludesMojo mojo = (ProcessExcludesMojo) rule.lookupMojo("process-excludes", pom); + assertNotNull(mojo); + + configureMojo(mojo, projectCopy); + mojo.execute(); + + File outputDirectory = (File) rule.getVariableValueFromObject(mojo, "outputDirectory"); + File expected = + new File( + "src/test/projects/project-without-exclusions/classes/org/eclipse/che/ide/IDE.gwt.xml"); + File actual = new File(outputDirectory, "org/eclipse/che/ide/IDE.gwt.xml"); + + assertEquals( + "IDE.gwt.xml is changed but it shouldn't.", + StringUtils.getNestedString(FileUtils.fileRead(expected), ""), + StringUtils.getNestedString(FileUtils.fileRead(actual), "")); + } +} diff --git a/core/che-core-gwt-maven-plugin/src/test/java/org/eclipse/che/plugin/gwt/stub/ProjectStub.java b/core/che-core-gwt-maven-plugin/src/test/java/org/eclipse/che/plugin/gwt/stub/ProjectStub.java new file mode 100644 index 0000000000..5eecb71e25 --- /dev/null +++ b/core/che-core-gwt-maven-plugin/src/test/java/org/eclipse/che/plugin/gwt/stub/ProjectStub.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.plugin.gwt.stub; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter; +import org.apache.maven.model.Build; +import org.apache.maven.model.Dependency; +import org.apache.maven.model.Model; +import org.apache.maven.model.Plugin; +import org.apache.maven.model.io.xpp3.MavenXpp3Reader; +import org.apache.maven.plugin.testing.ArtifactStubFactory; +import org.apache.maven.plugin.testing.stubs.MavenProjectStub; +import org.codehaus.plexus.util.ReaderFactory; +import org.codehaus.plexus.util.xml.Xpp3Dom; + +public class ProjectStub extends MavenProjectStub { + + public ProjectStub() { + MavenXpp3Reader pomReader = new MavenXpp3Reader(); + Model model; + try { + model = pomReader.read(ReaderFactory.newXmlReader(new File(getBasedir(), "pom.xml"))); + setModel(model); + } catch (Exception e) { + throw new RuntimeException(e); + } + + setGroupId(model.getGroupId()); + setArtifactId(model.getArtifactId()); + setVersion(model.getVersion()); + setName(model.getName()); + setUrl(model.getUrl()); + setPackaging(model.getPackaging()); + + List compileSourceRoots = new ArrayList<>(); + compileSourceRoots.add(getBasedir() + "/src/main/java"); + setCompileSourceRoots(compileSourceRoots); + + List testCompileSourceRoots = new ArrayList<>(); + testCompileSourceRoots.add(getBasedir() + "/src/test/java"); + setTestCompileSourceRoots(testCompileSourceRoots); + + setupBuild(model); + setupDependencyArtifacts(model); + } + + private void setupDependencyArtifacts(Model model) { + Set artifacts = new HashSet<>(); + ArtifactStubFactory artifactStubFactory = new ArtifactStubFactory(); + + for (Dependency dependency : model.getDependencies()) { + Artifact artifact; + + try { + artifact = + artifactStubFactory.createArtifact( + dependency.getGroupId(), + dependency.getArtifactId(), + System.getProperty("currentVersion")); + } catch (IOException e) { + throw new RuntimeException(e); + } + + List patterns = + dependency + .getExclusions() + .stream() + .map(exclusion -> exclusion.getGroupId() + ":" + exclusion.getArtifactId()) + .collect(Collectors.toList()); + + artifact.setDependencyFilter(new ExcludesArtifactFilter(patterns)); + artifacts.add(artifact); + } + + setDependencyArtifacts(artifacts); + } + + private void setupBuild(Model model) { + Build build = new Build(); + + build.setFinalName(model.getArtifactId()); + build.setDirectory(getBasedir() + "/target"); + build.setSourceDirectory(getBasedir() + "/src/main/java"); + build.setOutputDirectory(getBasedir() + "/target/classes"); + build.setTestSourceDirectory(getBasedir() + "/src/test/java"); + build.setTestOutputDirectory(getBasedir() + "/target/test-classes"); + build.setPlugins(model.getBuild().getPlugins()); + + setBuild(build); + } + + @Override + public File getBasedir() { + return new File(super.getBasedir() + "/src/test/projects/" + getProjectFolder()); + } + + @Override + public Xpp3Dom getGoalConfiguration( + String pluginGroupId, String pluginArtifactId, String executionId, String goalId) { + Plugin plugin = getPlugin(pluginGroupId + ':' + pluginArtifactId); + Object configuration = plugin.getConfiguration(); + + return (Xpp3Dom) configuration; + } + + protected String getProjectFolder() { + return "project"; + } +} diff --git a/core/che-core-gwt-maven-plugin/src/test/java/org/eclipse/che/plugin/gwt/stub/ProjectWithoutExclusionsStub.java b/core/che-core-gwt-maven-plugin/src/test/java/org/eclipse/che/plugin/gwt/stub/ProjectWithoutExclusionsStub.java new file mode 100644 index 0000000000..40e0702d6e --- /dev/null +++ b/core/che-core-gwt-maven-plugin/src/test/java/org/eclipse/che/plugin/gwt/stub/ProjectWithoutExclusionsStub.java @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2012-2017 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.plugin.gwt.stub; + +public class ProjectWithoutExclusionsStub extends ProjectStub { + + @Override + protected String getProjectFolder() { + return "project-without-exclusions"; + } +} diff --git a/core/che-core-gwt-maven-plugin/src/test/projects/project-without-exclusions/classes/org/eclipse/che/ide/IDE.gwt.xml b/core/che-core-gwt-maven-plugin/src/test/projects/project-without-exclusions/classes/org/eclipse/che/ide/IDE.gwt.xml new file mode 100644 index 0000000000..83b0025e5c --- /dev/null +++ b/core/che-core-gwt-maven-plugin/src/test/projects/project-without-exclusions/classes/org/eclipse/che/ide/IDE.gwt.xml @@ -0,0 +1,20 @@ + + + + + + + + + diff --git a/core/che-core-gwt-maven-plugin/src/test/projects/project-without-exclusions/pom.xml b/core/che-core-gwt-maven-plugin/src/test/projects/project-without-exclusions/pom.xml new file mode 100644 index 0000000000..3737d35a80 --- /dev/null +++ b/core/che-core-gwt-maven-plugin/src/test/projects/project-without-exclusions/pom.xml @@ -0,0 +1,48 @@ + + + 4.0.0 + org.eclipse.che.test + test-module + 1.0.0-SNAPSHOT + pom + Test Maven project for Che GWT Maven plugin + + + org.eclipse.che.core + che-ide-full + + + + + + net.ltgt.gwt.maven + gwt-maven-plugin + + org.eclipse.che.ide.IDE + + + + org.eclipse.che.core + che-core-gwt-maven-plugin + + + ${localRepository} + + true + + + + diff --git a/core/che-core-gwt-maven-plugin/src/test/projects/project/classes/org/eclipse/che/ide/IDE.gwt.xml b/core/che-core-gwt-maven-plugin/src/test/projects/project/classes/org/eclipse/che/ide/IDE.gwt.xml new file mode 100644 index 0000000000..83b0025e5c --- /dev/null +++ b/core/che-core-gwt-maven-plugin/src/test/projects/project/classes/org/eclipse/che/ide/IDE.gwt.xml @@ -0,0 +1,20 @@ + + + + + + + + + diff --git a/core/che-core-gwt-maven-plugin/src/test/projects/project/pom.xml b/core/che-core-gwt-maven-plugin/src/test/projects/project/pom.xml new file mode 100644 index 0000000000..4f3d384cb1 --- /dev/null +++ b/core/che-core-gwt-maven-plugin/src/test/projects/project/pom.xml @@ -0,0 +1,54 @@ + + + 4.0.0 + org.eclipse.che.test + test-module + 1.0.0-SNAPSHOT + pom + Test Maven project for Che GWT Maven plugin + + + org.eclipse.che.core + che-ide-full + + + che-plugin-help-ext-client + org.eclipse.che.plugin + + + + + + + + net.ltgt.gwt.maven + gwt-maven-plugin + + org.eclipse.che.ide.IDE + + + + org.eclipse.che.core + che-core-gwt-maven-plugin + + + ${localRepository} + + true + + + + diff --git a/core/pom.xml b/core/pom.xml index 41e54b9b8a..4b34b6261e 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -30,6 +30,7 @@ che-core-api-dto-maven-plugin che-core-typescript-dto-maven-plugin che-core-dynamodule-maven-plugin + che-core-gwt-maven-plugin che-core-api-core che-core-api-model che-core-db diff --git a/ide/README.md b/ide/README.md index 8768473052..84df595974 100644 --- a/ide/README.md +++ b/ide/README.md @@ -6,6 +6,7 @@ * [Consuming the shared libraries](#consuming-the-shared-libraries) - [Including an IDE plugin to the IDE GWT app](#including-an-ide-plugin-to-the-ide-gwt-app) - [GWT Super DevMode](#gwt-super-devmode) +- [Extending IDE GWT app](#extending-ide-gwt-app) ## Making a GWT library for the IDE GWT app GWT library it's a JAR that contains compiled classes, project's (re-)sources, GWT module descriptor (*.gwt.xml) and possibly other GWT-specific files. @@ -67,3 +68,56 @@ There are two options available to launch GWT Super DevMode, depending on the st The second one requires *more time* to launch GWT CodeServer since the second one it executes `process-classes` build phase for each maven module. So using the first command is preferable. **Note**, both commands have to be performed in the root folder of the Che project. + +## Extending IDE GWT app +There're two GWT libraries provided which allows you to easily extend IDE GWT app: Basic IDE and Full IDE. + +Basic IDE represents IDE without any plugins. It allows you to compile IDE GWT app with your own IDE plugins only, e.g.: + ```xml + + + org.eclipse.che.core + che-ide-core + + + my.ide.plugin + my-ide-plugin + + + ``` +Full IDE represents IDE with full set of the standard plugins. It allows you to compile IDE GWT app excluding some of the standard plugins and/or including your own IDE plugins, e.g.: + ```xml + + + org.eclipse.che.core + che-ide-full + + + che-plugin-product-info + org.eclipse.che.plugin + + + + + my.ide.plugin + my-ide-plugin + + + + + + org.eclipse.che.core + che-core-gwt-maven-plugin + ${project.version} + + + + process-excludes + + + + + + + ``` +Note that `che-core-gwt-maven-plugin` have to be added in order to correctly process the IDE plugins exclusions. diff --git a/ide/che-ide-full/pom.xml b/ide/che-ide-full/pom.xml new file mode 100644 index 0000000000..aa5878dae4 --- /dev/null +++ b/ide/che-ide-full/pom.xml @@ -0,0 +1,243 @@ + + + + 4.0.0 + + che-parent + org.eclipse.che + 6.0.0-M3-SNAPSHOT + ../../pom.xml + + org.eclipse.che.core + che-ide-full + gwt-lib + Che Core IDE :: Full IDE + Che IDE includes all plugins + + + org.eclipse.che.core + che-ide-core + gwt-lib + + + org.eclipse.che.multiuser + che-multiuser-keycloak-ide + gwt-lib + + + org.eclipse.che.multiuser + che-multiuser-machine-authentication-ide + gwt-lib + + + org.eclipse.che.plugin + che-plugin-activity-ide + gwt-lib + + + org.eclipse.che.plugin + che-plugin-composer-ide + gwt-lib + + + org.eclipse.che.plugin + che-plugin-cpp-lang-ide + gwt-lib + + + org.eclipse.che.plugin + che-plugin-csharp-lang-ide + gwt-lib + + + org.eclipse.che.plugin + che-plugin-debugger-ide + gwt-lib + + + org.eclipse.che.plugin + che-plugin-ext-dashboard-client + gwt-lib + + + org.eclipse.che.plugin + che-plugin-gdb-ide + gwt-lib + + + org.eclipse.che.plugin + che-plugin-git-ext-git + gwt-lib + + + org.eclipse.che.plugin + che-plugin-github-ide + gwt-lib + + + org.eclipse.che.plugin + che-plugin-github-pullrequest + gwt-lib + + + org.eclipse.che.plugin + che-plugin-gwt-ext-gwt + gwt-lib + + + org.eclipse.che.plugin + che-plugin-help-ext-client + gwt-lib + + + org.eclipse.che.plugin + che-plugin-java-debugger-ide + gwt-lib + + + org.eclipse.che.plugin + che-plugin-java-ext-lang-client + gwt-lib + + + org.eclipse.che.plugin + che-plugin-java-plain-ide + gwt-lib + + + org.eclipse.che.plugin + che-plugin-keybinding-eclipse-ide + gwt-lib + + + org.eclipse.che.plugin + che-plugin-languageserver-ide + gwt-lib + + + org.eclipse.che.plugin + che-plugin-machine-ssh-client + gwt-lib + + + org.eclipse.che.plugin + che-plugin-maven-ide + gwt-lib + + + org.eclipse.che.plugin + che-plugin-nodejs-debugger-ide + gwt-lib + + + org.eclipse.che.plugin + che-plugin-nodejs-lang-ide + gwt-lib + + + org.eclipse.che.plugin + che-plugin-orion-compare + gwt-lib + + + org.eclipse.che.plugin + che-plugin-php-lang-ide + gwt-lib + + + org.eclipse.che.plugin + che-plugin-product-info + gwt-lib + + + org.eclipse.che.plugin + che-plugin-pullrequest-ide + gwt-lib + + + org.eclipse.che.plugin + che-plugin-python-lang-ide + gwt-lib + + + org.eclipse.che.plugin + che-plugin-sdk-ext-plugins + gwt-lib + + + org.eclipse.che.plugin + che-plugin-ssh-key-ide + gwt-lib + + + org.eclipse.che.plugin + che-plugin-testing-ide + gwt-lib + + + org.eclipse.che.plugin + che-plugin-testing-junit-ide + gwt-lib + + + org.eclipse.che.plugin + che-plugin-testing-phpunit-ide + gwt-lib + + + org.eclipse.che.plugin + che-plugin-testing-testng-ide + gwt-lib + + + org.eclipse.che.plugin + che-plugin-web-ext-web + gwt-lib + + + org.eclipse.che.plugin + che-plugin-yaml-ide + gwt-lib + + + org.eclipse.che.plugin + che-plugin-zend-debugger-ide + gwt-lib + + + + + + net.ltgt.gwt.maven + gwt-maven-plugin + true + + org.eclipse.che.ide.Full + + + + org.apache.maven.plugins + maven-dependency-plugin + + + analyze + + true + + + + + + + diff --git a/ide/che-ide-gwt-app/pom.xml b/ide/che-ide-gwt-app/pom.xml index aa870f7ca2..702b414514 100644 --- a/ide/che-ide-gwt-app/pom.xml +++ b/ide/che-ide-gwt-app/pom.xml @@ -25,202 +25,15 @@ Compiles Che IDE GWT application and packages it as a WAR-like archive which contains pure output of the GWT compiler ${project.build.directory}/generated-sources/gen - UTF-8 - com.google.gwt gwt-dev org.eclipse.che.core - che-ide-core - gwt-lib - - - org.eclipse.che.multiuser - che-multiuser-keycloak-ide - gwt-lib - - - org.eclipse.che.multiuser - che-multiuser-machine-authentication-ide - gwt-lib - - - org.eclipse.che.plugin - che-plugin-activity-ide - gwt-lib - - - org.eclipse.che.plugin - che-plugin-composer-ide - gwt-lib - - - org.eclipse.che.plugin - che-plugin-cpp-lang-ide - gwt-lib - - - org.eclipse.che.plugin - che-plugin-csharp-lang-ide - gwt-lib - - - org.eclipse.che.plugin - che-plugin-debugger-ide - gwt-lib - - - org.eclipse.che.plugin - che-plugin-ext-dashboard-client - gwt-lib - - - org.eclipse.che.plugin - che-plugin-gdb-ide - gwt-lib - - - org.eclipse.che.plugin - che-plugin-git-ext-git - gwt-lib - - - org.eclipse.che.plugin - che-plugin-github-ide - gwt-lib - - - org.eclipse.che.plugin - che-plugin-github-pullrequest - gwt-lib - - - org.eclipse.che.plugin - che-plugin-gwt-ext-gwt - gwt-lib - - - org.eclipse.che.plugin - che-plugin-help-ext-client - gwt-lib - - - org.eclipse.che.plugin - che-plugin-java-debugger-ide - gwt-lib - - - org.eclipse.che.plugin - che-plugin-java-ext-lang-client - gwt-lib - - - org.eclipse.che.plugin - che-plugin-java-plain-ide - gwt-lib - - - org.eclipse.che.plugin - che-plugin-keybinding-eclipse-ide - gwt-lib - - - org.eclipse.che.plugin - che-plugin-languageserver-ide - gwt-lib - - - org.eclipse.che.plugin - che-plugin-machine-ssh-client - gwt-lib - - - org.eclipse.che.plugin - che-plugin-maven-ide - gwt-lib - - - org.eclipse.che.plugin - che-plugin-nodejs-debugger-ide - gwt-lib - - - org.eclipse.che.plugin - che-plugin-nodejs-lang-ide - gwt-lib - - - org.eclipse.che.plugin - che-plugin-orion-compare - gwt-lib - - - org.eclipse.che.plugin - che-plugin-php-lang-ide - gwt-lib - - - org.eclipse.che.plugin - che-plugin-product-info - gwt-lib - - - org.eclipse.che.plugin - che-plugin-pullrequest-ide - gwt-lib - - - org.eclipse.che.plugin - che-plugin-python-lang-ide - gwt-lib - - - org.eclipse.che.plugin - che-plugin-sdk-ext-plugins - gwt-lib - - - org.eclipse.che.plugin - che-plugin-ssh-key-ide - gwt-lib - - - org.eclipse.che.plugin - che-plugin-testing-ide - gwt-lib - - - org.eclipse.che.plugin - che-plugin-testing-junit-ide - gwt-lib - - - org.eclipse.che.plugin - che-plugin-testing-phpunit-ide - gwt-lib - - - org.eclipse.che.plugin - che-plugin-testing-testng-ide - gwt-lib - - - org.eclipse.che.plugin - che-plugin-web-ext-web - gwt-lib - - - org.eclipse.che.plugin - che-plugin-yaml-ide - gwt-lib - - - org.eclipse.che.plugin - che-plugin-zend-debugger-ide + che-ide-full gwt-lib diff --git a/pom.xml b/pom.xml index b14c97b982..1f7c491616 100644 --- a/pom.xml +++ b/pom.xml @@ -33,6 +33,7 @@ infrastructures plugins ide/che-ide-core + ide/che-ide-full ide/che-ide-gwt-app dashboard assembly @@ -605,6 +606,11 @@ ${che.version} gwt-lib + + org.eclipse.che.core + che-core-gwt-maven-plugin + ${che.version} + org.eclipse.che.core che-core-ide-api @@ -680,6 +686,17 @@ ${che.version} gwt-lib + + org.eclipse.che.core + che-ide-full + ${che.version} + + + org.eclipse.che.core + che-ide-full + ${che.version} + gwt-lib + org.eclipse.che.core che-wsagent-core @@ -1184,6 +1201,11 @@ ${che.version} gwt-lib + + org.eclipse.che.plugin + che-plugin-help-ext-client + ${che.version} + org.eclipse.che.plugin che-plugin-help-ext-client