diff --git a/vscode-extensions/commons/commons-maven/.gitignore b/vscode-extensions/commons/commons-maven/.gitignore new file mode 100644 index 000000000..88b8d0751 --- /dev/null +++ b/vscode-extensions/commons/commons-maven/.gitignore @@ -0,0 +1,2 @@ +/.classpath +/.project diff --git a/vscode-extensions/commons/commons-maven/.settings/org.eclipse.jdt.core.prefs b/vscode-extensions/commons/commons-maven/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..714351aec --- /dev/null +++ b/vscode-extensions/commons/commons-maven/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,5 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/vscode-extensions/commons/commons-maven/.settings/org.eclipse.m2e.core.prefs b/vscode-extensions/commons/commons-maven/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 000000000..f897a7f1c --- /dev/null +++ b/vscode-extensions/commons/commons-maven/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/vscode-extensions/commons/commons-maven/pom.xml b/vscode-extensions/commons/commons-maven/pom.xml new file mode 100644 index 000000000..077227359 --- /dev/null +++ b/vscode-extensions/commons/commons-maven/pom.xml @@ -0,0 +1,58 @@ + + 4.0.0 + + commons + commons-maven + jar + commons-maven + Maven Utilities + + + org.springframework.ide.vscode + commons-parent + 0.0.1-SNAPSHOT + ../pom.xml + + + + + 3.3.9 + + + + + + org.springframework.ide.vscode + commons-util + ${project.version} + + + + + org.apache.maven + maven-core + true + + + + org.apache.maven + maven-embedder + true + + + + + + + + org.apache.maven + maven + ${maven-core.version} + pom + import + + + + + diff --git a/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenBridge.java b/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenBridge.java new file mode 100644 index 000000000..59e7a1670 --- /dev/null +++ b/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenBridge.java @@ -0,0 +1,804 @@ +/******************************************************************************* + * Copyright (c) 2016 Pivotal, 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: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ + +package org.springframework.ide.vscode.commons.maven; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.ConcurrentModificationException; +import java.util.HashSet; +import java.util.List; +import java.util.Properties; + +import org.apache.maven.DefaultMaven; +import org.apache.maven.Maven; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.InvalidRepositoryException; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.cli.configuration.SettingsXmlConfigurationProcessor; +import org.apache.maven.execution.DefaultMavenExecutionRequest; +import org.apache.maven.execution.DefaultMavenExecutionResult; +import org.apache.maven.execution.MavenExecutionRequest; +import org.apache.maven.execution.MavenExecutionRequestPopulationException; +import org.apache.maven.execution.MavenExecutionRequestPopulator; +import org.apache.maven.execution.MavenExecutionResult; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.extension.internal.CoreExports; +import org.apache.maven.extension.internal.CoreExtensionEntry; +import org.apache.maven.model.Model; +import org.apache.maven.model.Plugin; +import org.apache.maven.model.Profile; +import org.apache.maven.model.Repository; +import org.apache.maven.model.building.DefaultModelBuildingRequest; +import org.apache.maven.model.building.ModelBuildingRequest; +import org.apache.maven.model.building.ModelProblemCollector; +import org.apache.maven.model.building.ModelProblemCollectorRequest; +import org.apache.maven.model.interpolation.ModelInterpolator; +import org.apache.maven.model.io.ModelReader; +import org.apache.maven.model.io.ModelWriter; +import org.apache.maven.plugin.MavenPluginManager; +import org.apache.maven.plugin.MojoExecution; +import org.apache.maven.plugin.version.DefaultPluginVersionRequest; +import org.apache.maven.plugin.version.PluginVersionRequest; +import org.apache.maven.plugin.version.PluginVersionResolutionException; +import org.apache.maven.plugin.version.PluginVersionResolver; +import org.apache.maven.project.DuplicateProjectException; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.ProjectBuilder; +import org.apache.maven.project.ProjectBuildingException; +import org.apache.maven.project.ProjectBuildingRequest; +import org.apache.maven.project.ProjectBuildingResult; +import org.apache.maven.project.ProjectSorter; +import org.apache.maven.properties.internal.EnvironmentUtils; +import org.apache.maven.repository.RepositorySystem; +import org.apache.maven.settings.Mirror; +import org.apache.maven.settings.Server; +import org.apache.maven.settings.Settings; +import org.apache.maven.settings.SettingsUtils; +import org.apache.maven.settings.building.DefaultSettingsBuildingRequest; +import org.apache.maven.settings.building.SettingsBuilder; +import org.apache.maven.settings.building.SettingsBuildingException; +import org.apache.maven.settings.building.SettingsBuildingRequest; +import org.apache.maven.settings.building.SettingsProblem; +import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest; +import org.apache.maven.settings.crypto.SettingsDecrypter; +import org.apache.maven.settings.crypto.SettingsDecryptionRequest; +import org.apache.maven.settings.crypto.SettingsDecryptionResult; +import org.apache.maven.settings.io.SettingsWriter; +import org.codehaus.plexus.ContainerConfiguration; +import org.codehaus.plexus.DefaultContainerConfiguration; +import org.codehaus.plexus.DefaultPlexusContainer; +import org.codehaus.plexus.PlexusConstants; +import org.codehaus.plexus.PlexusContainer; +import org.codehaus.plexus.PlexusContainerException; +import org.codehaus.plexus.classworlds.ClassWorld; +import org.codehaus.plexus.classworlds.realm.ClassRealm; +import org.codehaus.plexus.classworlds.realm.NoSuchRealmException; +import org.codehaus.plexus.component.repository.exception.ComponentLookupException; +import org.codehaus.plexus.util.IOUtil; +import org.codehaus.plexus.util.dag.CycleDetectedException; +import org.eclipse.aether.DefaultRepositorySystemSession; +import org.eclipse.aether.RepositorySystemSession; +import org.slf4j.ILoggerFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.inject.AbstractModule; +import com.google.inject.Module; + +/** + * Trimmed down version of M2E MavenImpl class + * + * @author Alex Boyko + * + */ +class MavenBridge { + private static final Logger log = LoggerFactory.getLogger(MavenBridge.class); + + /** + * Id of maven core class realm + */ + public static final String MAVEN_CORE_REALM_ID = "plexus.core"; //$NON-NLS-1$ + + private DefaultPlexusContainer plexus; + + // private final IMavenConfiguration mavenConfiguration; + + /** + * Cached parsed settings.xml instance + */ + private Settings settings; + + /** File length of cached user settings */ + private long settings_length; + + /** Last modified timestamp of cached user settings */ + private long settings_timestamp; + + public MavenBridge(/* IMavenConfiguration mavenConfiguration */) { + // this.mavenConfiguration = mavenConfiguration; + } + + /* package */@SuppressWarnings("deprecation") + MavenExecutionRequest createExecutionRequest() throws MavenException { + MavenExecutionRequest request = new DefaultMavenExecutionRequest(); + + // this causes problems with unexpected "stale project configuration" + // error markers + // need to think how to manage ${maven.build.timestamp} properly inside + // workspace + // request.setStartTime( new Date() ); + + // if(mavenConfiguration.getGlobalSettingsFile() != null) { + // request.setGlobalSettingsFile(new + // File(mavenConfiguration.getGlobalSettingsFile())); + // } + + File userSettingsFile = SettingsXmlConfigurationProcessor.DEFAULT_USER_SETTINGS_FILE; + + // if(mavenConfiguration.getUserSettingsFile() != null) { + // userSettingsFile = new + // File(mavenConfiguration.getUserSettingsFile()); + // } + request.setUserSettingsFile(userSettingsFile); + + try { + lookup(MavenExecutionRequestPopulator.class).populateFromSettings(request, getSettings()); + } catch (MavenExecutionRequestPopulationException ex) { + throw new MavenException(ex); + } + + ArtifactRepository localRepository = getLocalRepository(); + request.setLocalRepository(localRepository); + request.setLocalRepositoryPath(localRepository.getBasedir()); + // request.setOffline(mavenConfiguration.isOffline()); + + // request.getUserProperties().put("m2e.version", + // MavenPluginActivator.getVersion()); //$NON-NLS-1$ + // request.getUserProperties().put(ConfigurationProperties.USER_AGENT, + // MavenPluginActivator.getUserAgent()); + + EnvironmentUtils.addEnvVars(request.getSystemProperties()); + copyProperties(request.getSystemProperties(), System.getProperties()); + + request.setCacheNotFound(true); + request.setCacheTransferError(true); + + // request.setGlobalChecksumPolicy(mavenConfiguration.getGlobalChecksumPolicy()); + // the right way to disable snapshot update + // request.setUpdateSnapshots(false); + return request; + } + + public String getLocalRepositoryPath() { + String path = null; + try { + Settings settings = getSettings(); + path = settings.getLocalRepository(); + } catch (MavenException ex) { + // fall through + } + if (path == null) { + path = RepositorySystem.defaultUserLocalRepository.getAbsolutePath(); + } + return path; + } + + @SuppressWarnings("deprecation") + public MavenSession createSession(MavenExecutionRequest request, MavenProject project) throws MavenException { + RepositorySystemSession repoSession = createRepositorySession(request); + MavenExecutionResult result = new DefaultMavenExecutionResult(); + MavenSession mavenSession = new MavenSession(plexus, repoSession, request, result); + if (project != null) { + mavenSession.setProjects(Collections.singletonList(project)); + } + return mavenSession; + } + + /* package */DefaultRepositorySystemSession createRepositorySession(MavenExecutionRequest request) + throws MavenException { + return (DefaultRepositorySystemSession) ((DefaultMaven) lookup(Maven.class)).newRepositorySession(request); + } + + public void releaseMojo(Object mojo, MojoExecution mojoExecution) throws MavenException { + lookup(MavenPluginManager.class).releaseMojo(mojo, mojoExecution); + } + + public ArtifactRepository getLocalRepository() throws MavenException { + try { + String localRepositoryPath = getLocalRepositoryPath(); + if (localRepositoryPath != null) { + return lookup(RepositorySystem.class).createLocalRepository(new File(localRepositoryPath)); + } + return lookup(RepositorySystem.class).createLocalRepository(RepositorySystem.defaultUserLocalRepository); + } catch (InvalidRepositoryException ex) { + // can't happen + throw new IllegalStateException(ex); + } + } + + public Settings getSettings() throws MavenException { + return getSettings(false); + } + + public synchronized Settings getSettings(final boolean force_reload) throws MavenException { + // MUST NOT use createRequest! + + File userSettingsFile = SettingsXmlConfigurationProcessor.DEFAULT_USER_SETTINGS_FILE; + // if(mavenConfiguration.getUserSettingsFile() != null) { + // userSettingsFile = new + // File(mavenConfiguration.getUserSettingsFile()); + // } + + boolean reload = force_reload || settings == null; + + if (!reload && userSettingsFile != null) { + reload = userSettingsFile.lastModified() != settings_timestamp + || userSettingsFile.length() != settings_length; + } + + if (reload) { + // TODO: Can't that delegate to buildSettings()? + SettingsBuildingRequest request = new DefaultSettingsBuildingRequest(); + // 440696 guard against ConcurrentModificationException + Properties systemProperties = new Properties(); + copyProperties(systemProperties, System.getProperties()); + request.setSystemProperties(systemProperties); + // if(mavenConfiguration.getGlobalSettingsFile() != null) { + // request.setGlobalSettingsFile(new + // File(mavenConfiguration.getGlobalSettingsFile())); + // } + if (userSettingsFile != null) { + request.setUserSettingsFile(userSettingsFile); + } + try { + settings = lookup(SettingsBuilder.class).build(request).getEffectiveSettings(); + } catch (SettingsBuildingException ex) { + String msg = "Could not read settings.xml, assuming default values"; + log.error(msg, ex); + /* + * NOTE: This method provides input for various other core + * functions, just bailing out would make m2e highly unusuable. + * Instead, we fail gracefully and just ignore the broken + * settings, using defaults. + */ + settings = new Settings(); + } + + if (userSettingsFile != null) { + settings_length = userSettingsFile.length(); + settings_timestamp = userSettingsFile.lastModified(); + } + } + return settings; + } + + public Settings buildSettings(String globalSettings, String userSettings) throws MavenException { + SettingsBuildingRequest request = new DefaultSettingsBuildingRequest(); + request.setGlobalSettingsFile(globalSettings != null ? new File(globalSettings) : null); + request.setUserSettingsFile(userSettings != null ? new File(userSettings) + : SettingsXmlConfigurationProcessor.DEFAULT_USER_SETTINGS_FILE); + try { + return lookup(SettingsBuilder.class).build(request).getEffectiveSettings(); + } catch (SettingsBuildingException ex) { + throw new MavenException(ex); + } + } + + public void writeSettings(Settings settings, OutputStream out) throws MavenException { + try { + lookup(SettingsWriter.class).write(out, null, settings); + } catch (IOException ex) { + throw new MavenException(ex); + } + } + + public Server decryptPassword(Server server) throws MavenException { + SettingsDecryptionRequest request = new DefaultSettingsDecryptionRequest(server); + SettingsDecryptionResult result = lookup(SettingsDecrypter.class).decrypt(request); + for (SettingsProblem problem : result.getProblems()) { + log.warn(problem.getMessage(), problem.getException()); + } + return result.getServer(); + } + + public Model readModel(InputStream in) throws MavenException { + try { + return lookup(ModelReader.class).read(in, null); + } catch (IOException e) { + throw new MavenException(e); + } + } + + public Model readModel(File pomFile) throws MavenException { + try { + BufferedInputStream is = new BufferedInputStream(new FileInputStream(pomFile)); + try { + return readModel(is); + } finally { + IOUtil.close(is); + } + } catch (IOException e) { + throw new MavenException(e); + } + } + + public void writeModel(Model model, OutputStream out) throws MavenException { + try { + lookup(ModelWriter.class).write(out, null, model); + } catch (IOException ex) { + throw new MavenException(ex); + } + } + + public MavenProject readProject(final File pomFile, MavenExecutionRequest request) throws MavenException { + try { + lookup(MavenExecutionRequestPopulator.class).populateDefaults(request); + ProjectBuildingRequest configuration = request.getProjectBuildingRequest(); + configuration.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL); + configuration.setRepositorySession(createRepositorySession(request)); + return lookup(ProjectBuilder.class).build(pomFile, configuration).getProject(); + } catch (ProjectBuildingException ex) { + throw new MavenException(ex); + } catch (MavenExecutionRequestPopulationException ex) { + throw new MavenException(ex); + } + } + + public MavenExecutionResult readMavenProject(File pomFile, ProjectBuildingRequest configuration) + throws MavenException { + long start = System.currentTimeMillis(); + + log.debug("Reading Maven project: {}", pomFile.getAbsoluteFile()); //$NON-NLS-1$ + MavenExecutionResult result = new DefaultMavenExecutionResult(); + try { + configuration.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL); + ProjectBuildingResult projectBuildingResult = lookup(ProjectBuilder.class).build(pomFile, configuration); + result.setProject(projectBuildingResult.getProject()); + result.setDependencyResolutionResult(projectBuildingResult.getDependencyResolutionResult()); + } catch (ProjectBuildingException ex) { + if (ex.getResults() != null && ex.getResults().size() == 1) { + ProjectBuildingResult projectBuildingResult = ex.getResults().get(0); + result.setProject(projectBuildingResult.getProject()); + result.setDependencyResolutionResult(projectBuildingResult.getDependencyResolutionResult()); + } + result.addException(ex); + } catch (RuntimeException e) { + result.addException(e); + } finally { + log.debug("Read Maven project: {} in {} ms", pomFile.getAbsoluteFile(), System.currentTimeMillis() - start); //$NON-NLS-1$ + } + return result; + } + + /* package */MavenProject resolveParentProject(RepositorySystemSession repositorySession, MavenProject child, + ProjectBuildingRequest configuration) throws MavenException { + configuration.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL); + configuration.setRepositorySession(repositorySession); + + try { + configuration.setRemoteRepositories(child.getRemoteArtifactRepositories()); + + File parentFile = child.getParentFile(); + if (parentFile != null) { + return lookup(ProjectBuilder.class).build(parentFile, configuration).getProject(); + } + + Artifact parentArtifact = child.getParentArtifact(); + if (parentArtifact != null) { + MavenProject parent = lookup(ProjectBuilder.class).build(parentArtifact, configuration).getProject(); + parentFile = parentArtifact.getFile(); // file is resolved as + // side-effect of the + // prior call + // compensate for apparent bug in maven 3.0.4 which does not set + // parent.file and parent.artifact.file + if (parent.getFile() == null) { + parent.setFile(parentFile); + } + if (parent.getArtifact().getFile() == null) { + parent.getArtifact().setFile(parentFile); + } + return parent; + } + } catch (ProjectBuildingException ex) { + log.error("Could not read parent project", ex); + } + + return null; + } + + /** + * This is a temporary implementation that only works for artifacts resolved + * using #resolve. + */ + public boolean isUnavailable(String groupId, String artifactId, String version, String type, String classifier, + List remoteRepositories) throws MavenException { + Artifact artifact = lookup(RepositorySystem.class).createArtifactWithClassifier(groupId, artifactId, version, + type, classifier); + + ArtifactRepository localRepository = getLocalRepository(); + + File artifactFile = new File(localRepository.getBasedir(), localRepository.pathOf(artifact)); + + if (artifactFile.canRead()) { + // artifact is available locally + return false; + } + + if (remoteRepositories == null || remoteRepositories.isEmpty()) { + // no remote repositories + return true; + } + + // now is the hard part + Properties lastUpdated = loadLastUpdated(localRepository, artifact); + + for (ArtifactRepository repository : remoteRepositories) { + String timestamp = lastUpdated.getProperty(getLastUpdatedKey(repository, artifact)); + if (timestamp == null) { + // availability of the artifact from this repository has not + // been checked yet + return false; + } + } + + // artifact is not available locally and all remote repositories have + // been checked in the past + return true; + } + + private String getLastUpdatedKey(ArtifactRepository repository, Artifact artifact) { + StringBuilder key = new StringBuilder(); + + // repository part + key.append(repository.getId()); + if (repository.getAuthentication() != null) { + key.append('|').append(repository.getAuthentication().getUsername()); + } + key.append('|').append(repository.getUrl()); + + // artifact part + key.append('|').append(artifact.getClassifier()); + + return key.toString(); + } + + private Properties loadLastUpdated(ArtifactRepository localRepository, Artifact artifact) throws MavenException { + Properties lastUpdated = new Properties(); + File lastUpdatedFile = getLastUpdatedFile(localRepository, artifact); + try { + BufferedInputStream is = new BufferedInputStream(new FileInputStream(lastUpdatedFile)); + try { + lastUpdated.load(is); + } finally { + IOUtil.close(is); + } + } catch (FileNotFoundException ex) { + // that's okay + } catch (IOException ex) { + throw new MavenException(ex); + } + return lastUpdated; + } + + private File getLastUpdatedFile(ArtifactRepository localRepository, Artifact artifact) { + return new File(localRepository.getBasedir(), basePathOf(localRepository, artifact) + "/" //$NON-NLS-1$ + + "m2e-lastUpdated.properties"); //$NON-NLS-1$ + } + + private static final char PATH_SEPARATOR = '/'; + + private static final char GROUP_SEPARATOR = '.'; + + private String basePathOf(ArtifactRepository repository, Artifact artifact) { + StringBuilder path = new StringBuilder(128); + + path.append(formatAsDirectory(artifact.getGroupId())).append(PATH_SEPARATOR); + path.append(artifact.getArtifactId()).append(PATH_SEPARATOR); + path.append(artifact.getBaseVersion()).append(PATH_SEPARATOR); + + return path.toString(); + } + + private String formatAsDirectory(String directory) { + return directory.replace(GROUP_SEPARATOR, PATH_SEPARATOR); + } + + public ArtifactRepository createArtifactRepository(String id, String url) throws MavenException { + Repository repository = new Repository(); + repository.setId(id); + repository.setUrl(url); + repository.setLayout("default"); //$NON-NLS-1$ + + ArtifactRepository repo; + try { + repo = lookup(RepositorySystem.class).buildArtifactRepository(repository); + ArrayList repos = new ArrayList(Arrays.asList(repo)); + injectSettings(repos); + } catch (InvalidRepositoryException ex) { + throw new MavenException(ex); + } + return repo; + } + + public List getArtifactRepositories() throws MavenException { + return getArtifactRepositories(true); + } + + public List getArtifactRepositories(boolean injectSettings) throws MavenException { + ArrayList repositories = new ArrayList(); + for (Profile profile : getActiveProfiles()) { + addArtifactRepositories(repositories, profile.getRepositories()); + } + + addDefaultRepository(repositories); + + if (injectSettings) { + injectSettings(repositories); + } + + return removeDuplicateRepositories(repositories); + } + + private List removeDuplicateRepositories(ArrayList repositories) { + ArrayList result = new ArrayList(); + + HashSet keys = new HashSet(); + for (ArtifactRepository repository : repositories) { + StringBuilder key = new StringBuilder(); + if (repository.getId() != null) { + key.append(repository.getId()); + } + key.append(':').append(repository.getUrl()).append(':'); + if (repository.getAuthentication() != null && repository.getAuthentication().getUsername() != null) { + key.append(repository.getAuthentication().getUsername()); + } + if (keys.add(key.toString())) { + result.add(repository); + } + } + return result; + } + + private void injectSettings(ArrayList repositories) throws MavenException { + Settings settings = getSettings(); + RepositorySystem repositorySystem = lookup(RepositorySystem.class); + repositorySystem.injectMirror(repositories, getMirrors()); + repositorySystem.injectProxy(repositories, settings.getProxies()); + repositorySystem.injectAuthentication(repositories, settings.getServers()); + } + + private void addDefaultRepository(ArrayList repositories) throws MavenException { + for (ArtifactRepository repository : repositories) { + if (RepositorySystem.DEFAULT_REMOTE_REPO_ID.equals(repository.getId())) { + return; + } + } + try { + repositories.add(0, lookup(RepositorySystem.class).createDefaultRemoteRepository()); + } catch (InvalidRepositoryException ex) { + log.error("Unexpected exception", ex); + } + } + + private void addArtifactRepositories(ArrayList artifactRepositories, + List repositories) throws MavenException { + for (Repository repository : repositories) { + try { + ArtifactRepository artifactRepository = lookup(RepositorySystem.class) + .buildArtifactRepository(repository); + artifactRepositories.add(artifactRepository); + } catch (InvalidRepositoryException ex) { + throw new MavenException(ex); + } + } + } + + private List getActiveProfiles() throws MavenException { + Settings settings = getSettings(); + List activeProfilesIds = settings.getActiveProfiles(); + ArrayList activeProfiles = new ArrayList(); + for (org.apache.maven.settings.Profile settingsProfile : settings.getProfiles()) { + if ((settingsProfile.getActivation() != null && settingsProfile.getActivation().isActiveByDefault()) + || activeProfilesIds.contains(settingsProfile.getId())) { + Profile profile = SettingsUtils.convertFromSettingsProfile(settingsProfile); + activeProfiles.add(profile); + } + } + return activeProfiles; + } + + public List getPluginArtifactRepositories() throws MavenException { + return getPluginArtifactRepositories(true); + } + + public List getPluginArtifactRepositories(boolean injectSettings) throws MavenException { + ArrayList repositories = new ArrayList(); + for (Profile profile : getActiveProfiles()) { + addArtifactRepositories(repositories, profile.getPluginRepositories()); + } + addDefaultRepository(repositories); + + if (injectSettings) { + injectSettings(repositories); + } + + return removeDuplicateRepositories(repositories); + } + + public Mirror getMirror(ArtifactRepository repo) throws MavenException { + MavenExecutionRequest request = createExecutionRequest(); + populateDefaults(request); + return lookup(RepositorySystem.class).getMirror(repo, request.getMirrors()); + }; + + public void populateDefaults(MavenExecutionRequest request) throws MavenException { + try { + lookup(MavenExecutionRequestPopulator.class).populateDefaults(request); + } catch (MavenExecutionRequestPopulationException ex) { + throw new MavenException(ex); + } + } + + public List getMirrors() throws MavenException { + MavenExecutionRequest request = createExecutionRequest(); + populateDefaults(request); + return request.getMirrors(); + } + + public PlexusContainer getPlexusContainer() throws MavenException { + try { + return getPlexusContainer0(); + } catch (PlexusContainerException ex) { + throw new MavenException(ex); + } + } + + private synchronized PlexusContainer getPlexusContainer0() throws PlexusContainerException { + if (plexus == null) { + plexus = newPlexusContainer(); + // plexus.setLoggerManager(new + // EclipseLoggerManager(mavenConfiguration)); + } + return plexus; + } + + public List getSortedProjects(List projects) throws MavenException { + try { + ProjectSorter rm = new ProjectSorter(projects); + return rm.getSortedProjects(); + } catch (CycleDetectedException ex) { + throw new MavenException(ex); + } catch (DuplicateProjectException ex) { + throw new MavenException(ex); + } + } + + public String resolvePluginVersion(String groupId, String artifactId, MavenSession session) throws MavenException { + Plugin plugin = new Plugin(); + plugin.setGroupId(groupId); + plugin.setArtifactId(artifactId); + PluginVersionRequest request = new DefaultPluginVersionRequest(plugin, session); + try { + return lookup(PluginVersionResolver.class).resolve(request).getVersion(); + } catch (PluginVersionResolutionException ex) { + throw new MavenException(ex); + } + } + + /* package */ T lookup(Class clazz) throws MavenException { + try { + return getPlexusContainer().lookup(clazz); + } catch (ComponentLookupException ex) { + throw new MavenException(ex); + } + } + + /** + * @throws MavenException + * @since 1.5 + */ + public T lookupComponent(Class clazz) throws MavenException { + try { + return getPlexusContainer0().lookup(clazz); + } catch (ComponentLookupException ex) { + throw new MavenException(ex); + } catch (PlexusContainerException ex) { + throw new IllegalStateException(ex); + } + } + + private static DefaultPlexusContainer newPlexusContainer() throws PlexusContainerException { + final ClassWorld classWorld = new ClassWorld(MAVEN_CORE_REALM_ID, ClassWorld.class.getClassLoader()); + final ClassRealm realm; + try { + realm = classWorld.getRealm(MAVEN_CORE_REALM_ID); + } catch (NoSuchRealmException e) { + throw new PlexusContainerException("Could not lookup required class realm", e); + } + final ContainerConfiguration mavenCoreCC = new DefaultContainerConfiguration() // + .setClassWorld(classWorld) // + .setRealm(realm) // + .setClassPathScanning(PlexusConstants.SCANNING_INDEX) // + .setAutoWiring(true) // + .setName("mavenCore"); //$NON-NLS-1$ + + final Module logginModule = new AbstractModule() { + protected void configure() { + bind(ILoggerFactory.class).toInstance(LoggerFactory.getILoggerFactory()); + } + }; + final Module coreExportsModule = new AbstractModule() { + protected void configure() { + ClassRealm realm = mavenCoreCC.getRealm(); + CoreExtensionEntry entry = CoreExtensionEntry.discoverFrom(realm); + CoreExports exports = new CoreExports(entry); + bind(CoreExports.class).toInstance(exports); + } + }; + return new DefaultPlexusContainer(mavenCoreCC, logginModule, coreExportsModule); + } + + public synchronized void disposeContainer() { + if (plexus != null) { + plexus.dispose(); + } + } + + public ClassLoader getProjectRealm(MavenProject project) { + ClassLoader classLoader = project.getClassRealm(); + if (classLoader == null) { + classLoader = plexus.getContainerRealm(); + } + return classLoader; + } + + public void interpolateModel(MavenProject project, Model model) throws MavenException { + ModelBuildingRequest request = new DefaultModelBuildingRequest(); + request.setUserProperties(project.getProperties()); + ModelProblemCollector problems = new ModelProblemCollector() { + @Override + public void add(ModelProblemCollectorRequest req) { + } + }; + lookup(ModelInterpolator.class).interpolateModel(model, project.getBasedir(), request, problems); + } + + /** + * Thread-safe properties copy implementation. + *

+ * {@link Properties#entrySet()} iterator is not thread safe and fails with + * {@link ConcurrentModificationException} if the source properties "is + * structurally modified at any time after the iterator is created". The + * solution is to use thread-safe {@link Properties#stringPropertyNames()} + * enumerate and copy properties. + * + * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=440696 + * @since 1.6 + */ + public static void copyProperties(Properties to, Properties from) { + for (String key : from.stringPropertyNames()) { + String value = from.getProperty(key); + if (value != null) { + to.put(key, value); + } + } + } + +} diff --git a/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenCore.java b/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenCore.java new file mode 100644 index 000000000..9caa67074 --- /dev/null +++ b/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenCore.java @@ -0,0 +1,173 @@ +/******************************************************************************* + * Copyright (c) 2016 Pivotal, 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: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.commons.maven; + +import java.io.File; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Set; + +import org.apache.maven.RepositoryUtils; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.execution.MavenExecutionRequest; +import org.apache.maven.model.DependencyManagement; +import org.apache.maven.project.MavenProject; +import org.eclipse.aether.DefaultRepositorySystemSession; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.artifact.ArtifactTypeRegistry; +import org.eclipse.aether.collection.CollectRequest; +import org.eclipse.aether.collection.DependencyCollectionException; +import org.eclipse.aether.graph.DependencyNode; +import org.eclipse.aether.repository.LocalRepositoryManager; +import org.eclipse.aether.util.filter.ScopeDependencyFilter; +import org.eclipse.aether.util.graph.manager.DependencyManagerUtils; +import org.eclipse.aether.util.graph.transformer.ConflictResolver; +import org.eclipse.aether.util.graph.transformer.JavaScopeDeriver; +import org.eclipse.aether.util.graph.transformer.JavaScopeSelector; +import org.eclipse.aether.util.graph.transformer.NearestVersionSelector; +import org.eclipse.aether.util.graph.transformer.SimpleOptionalitySelector; +import org.eclipse.aether.util.graph.visitor.CloningDependencyVisitor; +import org.eclipse.aether.util.graph.visitor.FilteringDependencyVisitor; + +/** + * Maven Core functionality + * + * @author Alex Boyko + * + */ +public class MavenCore { + + private static MavenCore instance = null; + + private MavenBridge maven = new MavenBridge(); + + public static MavenCore getInstance() { + if (instance == null) { + instance = new MavenCore(); + } + return instance; + } + + /** + * Creates Maven Project descriptor based on the pom file. + * + * @param pom The pom file + * @return Maven project instance + * @throws MavenException + */ + public MavenProject readProject(File pom) throws MavenException { + return maven.readProject(pom, maven.createExecutionRequest()); + } + + /** + * Taken from M2E same named method from MavenModelManager + * + * @param repositorySystem + * @param repositorySession + * @param mavenProject + * @param scope + * @return + */ + private DependencyNode readDependencyTree(org.eclipse.aether.RepositorySystem repositorySystem, + RepositorySystemSession repositorySession, MavenProject mavenProject, String scope) { + DefaultRepositorySystemSession session = new DefaultRepositorySystemSession(repositorySession); + + ConflictResolver transformer = new ConflictResolver(new NearestVersionSelector(), new JavaScopeSelector(), + new SimpleOptionalitySelector(), new JavaScopeDeriver()); + session.setDependencyGraphTransformer(transformer); + session.setConfigProperty(ConflictResolver.CONFIG_PROP_VERBOSE, Boolean.toString(true)); + session.setConfigProperty(DependencyManagerUtils.CONFIG_PROP_VERBOSE, true); + + ArtifactTypeRegistry stereotypes = session.getArtifactTypeRegistry(); + + CollectRequest request = new CollectRequest(); + request.setRequestContext("project"); //$NON-NLS-1$ + request.setRepositories(mavenProject.getRemoteProjectRepositories()); + + for (org.apache.maven.model.Dependency dependency : mavenProject.getDependencies()) { + request.addDependency(RepositoryUtils.toDependency(dependency, stereotypes)); + } + + DependencyManagement depMngt = mavenProject.getDependencyManagement(); + if (depMngt != null) { + for (org.apache.maven.model.Dependency dependency : depMngt.getDependencies()) { + request.addManagedDependency(RepositoryUtils.toDependency(dependency, stereotypes)); + } + } + + DependencyNode node; + try { + node = repositorySystem.collectDependencies(session, request).getRoot(); + } catch (DependencyCollectionException ex) { + node = ex.getResult().getRoot(); + } + + Collection scopes = new HashSet(); + Collections.addAll(scopes, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_COMPILE, Artifact.SCOPE_PROVIDED, + Artifact.SCOPE_RUNTIME, Artifact.SCOPE_TEST); + if (Artifact.SCOPE_COMPILE.equals(scope)) { + scopes.remove(Artifact.SCOPE_COMPILE); + scopes.remove(Artifact.SCOPE_SYSTEM); + scopes.remove(Artifact.SCOPE_PROVIDED); + } else if (Artifact.SCOPE_RUNTIME.equals(scope)) { + scopes.remove(Artifact.SCOPE_COMPILE); + scopes.remove(Artifact.SCOPE_RUNTIME); + } else if (Artifact.SCOPE_COMPILE_PLUS_RUNTIME.equals(scope)) { + scopes.remove(Artifact.SCOPE_COMPILE); + scopes.remove(Artifact.SCOPE_SYSTEM); + scopes.remove(Artifact.SCOPE_PROVIDED); + scopes.remove(Artifact.SCOPE_RUNTIME); + } else { + scopes.clear(); + } + + CloningDependencyVisitor cloner = new CloningDependencyVisitor(); + node.accept(new FilteringDependencyVisitor(cloner, new ScopeDependencyFilter(null, scopes))); + node = cloner.getRootNode(); + + return node; + } + + /** + * Calculates dependency graph for a Maven project provided the scope. + * + * @param project Maven Project descriptor + * @param scope Dependency scope + * @return Set of all dependencies including transient ones + * @throws MavenException + */ + public Set resolveDependencies(MavenProject project, String scope) throws MavenException { + Set artifacts = new LinkedHashSet<>(); + + MavenExecutionRequest request = maven.createExecutionRequest(); + DefaultRepositorySystemSession session = maven.createRepositorySession(request); + + DependencyNode graph = readDependencyTree(maven.lookupComponent(org.eclipse.aether.RepositorySystem.class), session, project, scope); + if (graph != null) { + RepositoryUtils.toArtifacts(artifacts, graph.getChildren(), + Collections.singletonList(project.getArtifact().getId()), null); + + // Maven 2.x quirk: an artifact always points at the local repo, + // regardless whether resolved or not + LocalRepositoryManager lrm = session.getLocalRepositoryManager(); + for (Artifact artifact : artifacts) { + if (!artifact.isResolved()) { + String path = lrm.getPathForLocalArtifact(RepositoryUtils.toArtifact(artifact)); + artifact.setFile(new File(lrm.getRepository().getBasedir(), path)); + } + } + } + + return artifacts; + } +} diff --git a/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenException.java b/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenException.java new file mode 100644 index 000000000..40dc239cd --- /dev/null +++ b/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenException.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2016 Pivotal, 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: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.commons.maven; + +/** + * Wrapper for Maven exceptions + * + * @author Alex Boyko + * + */ +public class MavenException extends Exception { + + private static final long serialVersionUID = 1L; + + private Throwable t; + + public MavenException() { + super(); + } + + public MavenException(Throwable t) { + super(); + this.t = t; + } + + @Override + public String getMessage() { + if (t != null) { + return t.getMessage(); + } + return super.getMessage(); + } + +} diff --git a/vscode-extensions/commons/commons-maven/src/test/java/org/springframework/ide/vscode/commons/maven/DependencyTreeTest.java b/vscode-extensions/commons/commons-maven/src/test/java/org/springframework/ide/vscode/commons/maven/DependencyTreeTest.java new file mode 100644 index 000000000..6c6fc2bbb --- /dev/null +++ b/vscode-extensions/commons/commons-maven/src/test/java/org/springframework/ide/vscode/commons/maven/DependencyTreeTest.java @@ -0,0 +1,75 @@ +package org.springframework.ide.vscode.commons.maven; + +/******************************************************************************* + * Copyright (c) 2016 Pivotal, 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: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +import static org.junit.Assert.*; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.maven.project.MavenProject; +import org.junit.Test; +import org.springframework.ide.vscode.commons.util.ExternalCommand; +import org.springframework.ide.vscode.commons.util.ExternalProcess; + +/** + * Tests for comparing maven calculated dependencies with ours + * + * @author Alex Boyko + * + */ +public class DependencyTreeTest { + + /** + * Build test project if it's not built already + * @throws Exception + */ + private static void buildProject(Path testProjectPath) throws Exception { + if (!Files.exists(testProjectPath.resolve("classpath.txt"))) { + testProjectPath.resolve("mvnw").toFile().setExecutable(true); + ExternalProcess process = new ExternalProcess(testProjectPath.toFile(), new ExternalCommand("./mvnw", "clean", "package"), true); + if (process.getExitValue() != 0) { + throw new RuntimeException("Failed to build test project"); + } + } + } + + private static Set readClassPathFile(Path classPathFilePath) throws IOException { + InputStream in = Files.newInputStream(classPathFilePath); + String text = new BufferedReader(new InputStreamReader(in)).lines().collect(Collectors.joining()); + Path dir = classPathFilePath.getParent(); + return Arrays.stream(text.split(File.pathSeparator)).map(dir::resolve).collect(Collectors.toSet()); + } + + @Test + public void mavenTest() throws Exception { + Path testProjectPath = Paths.get(DependencyTreeTest.class.getResource("/demo-1").toURI()); + buildProject(testProjectPath); + + MavenProject project = MavenCore.getInstance().readProject(testProjectPath.resolve("pom.xml").toFile()); + Set calculatedClassPath = MavenCore.getInstance().resolveDependencies(project, null).stream().map(artifact -> { + return Paths.get(artifact.getFile().toURI()); + }).collect(Collectors.toSet());; + + Set expectedClasspath = readClassPathFile(testProjectPath.resolve("classpath.txt")); + assertEquals(expectedClasspath, calculatedClassPath); + } + +} diff --git a/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/.mvn/wrapper/maven-wrapper.jar b/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 000000000..5fd4d5023 Binary files /dev/null and b/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/.mvn/wrapper/maven-wrapper.jar differ diff --git a/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/.mvn/wrapper/maven-wrapper.properties b/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 000000000..c954cec91 --- /dev/null +++ b/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1 @@ +distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.9/apache-maven-3.3.9-bin.zip diff --git a/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/mvnw b/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/mvnw new file mode 100755 index 000000000..a1ba1bf55 --- /dev/null +++ b/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/mvnw @@ -0,0 +1,233 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven2 Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # + # Look for the Apple JDKs first to preserve the existing behaviour, and then look + # for the new JDKs provided by Oracle. + # + if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then + # + # Apple JDKs + # + export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home + fi + + if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then + # + # Apple JDKs + # + export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home + fi + + if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then + # + # Oracle JDKs + # + export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home + fi + + if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then + # + # Apple JDKs + # + export JAVA_HOME=`/usr/libexec/java_home` + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Migwn, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" + # TODO classpath? +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` +fi + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + local basedir=$(pwd) + local wdir=$(pwd) + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + wdir=$(cd "$wdir/.."; pwd) + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)} +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} "$@" diff --git a/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/mvnw.cmd b/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/mvnw.cmd new file mode 100644 index 000000000..2b934e89d --- /dev/null +++ b/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/mvnw.cmd @@ -0,0 +1,145 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +set MAVEN_CMD_LINE_ARGS=%* + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" + +set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar"" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS% +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% \ No newline at end of file diff --git a/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/pom.xml b/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/pom.xml new file mode 100644 index 000000000..e01f9f26c --- /dev/null +++ b/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/pom.xml @@ -0,0 +1,83 @@ + + + 4.0.0 + + com.example + demo + 0.0.1-SNAPSHOT + jar + + demo-1 + Demo project for Spring Boot + + + org.springframework.boot + spring-boot-starter-parent + 1.4.0.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-configuration-processor + true + + + org.springframework.boot + spring-boot-starter-actuator + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-dependency-plugin + 2.9 + + + build-classpath + generate-sources + + build-classpath + + + + + classpath.txt + + + + + + + diff --git a/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/src/main/java/com/example/Demo1Application.java b/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/src/main/java/com/example/Demo1Application.java new file mode 100644 index 000000000..8f39b2fc2 --- /dev/null +++ b/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/src/main/java/com/example/Demo1Application.java @@ -0,0 +1,12 @@ +package com.example; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Demo1Application { + + public static void main(String[] args) { + SpringApplication.run(Demo1Application.class, args); + } +} diff --git a/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/src/main/java/com/example/DemoProperties.java b/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/src/main/java/com/example/DemoProperties.java new file mode 100644 index 000000000..f05598d03 --- /dev/null +++ b/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/src/main/java/com/example/DemoProperties.java @@ -0,0 +1,30 @@ +package com.example; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@ConfigurationProperties("demo.settings") +@Component +public class DemoProperties { + + private String user = "user"; + + private long timeout = 3000; + + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + + public long getTimeout() { + return timeout; + } + + public void setTimeout(long timeout) { + this.timeout = timeout; + } + +} diff --git a/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/src/main/java/com/example/RestApi.java b/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/src/main/java/com/example/RestApi.java new file mode 100644 index 000000000..1a65edaf8 --- /dev/null +++ b/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/src/main/java/com/example/RestApi.java @@ -0,0 +1,16 @@ +package com.example; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class RestApi { + + @RequestMapping("/hello") + @ResponseBody + public String hello() { + return "hello!"; + } + +} diff --git a/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/src/main/resources/application.properties b/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/src/main/resources/application.properties new file mode 100644 index 000000000..e69de29bb diff --git a/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/src/test/java/com/example/Demo1ApplicationTests.java b/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/src/test/java/com/example/Demo1ApplicationTests.java new file mode 100644 index 000000000..ccc49c598 --- /dev/null +++ b/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/src/test/java/com/example/Demo1ApplicationTests.java @@ -0,0 +1,16 @@ +package com.example; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class Demo1ApplicationTests { + + @Test + public void contextLoads() { + } + +} diff --git a/vscode-extensions/commons/pom.xml b/vscode-extensions/commons/pom.xml index 5892de458..88321ebab 100644 --- a/vscode-extensions/commons/pom.xml +++ b/vscode-extensions/commons/pom.xml @@ -17,6 +17,7 @@ commons-java java-properties application-properties-metadata + commons-maven