repo-reorg-2020: moved sts4-relevant spring-ide bundles from https://github.com/spring-projects/spring-ide/releases/tag/REPO-REORG-2020 into sts4 repo

This commit is contained in:
Martin Lippert
2020-09-29 14:00:01 +02:00
parent 8edfab1a16
commit de16884b60
2210 changed files with 160282 additions and 43 deletions

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src">
<attributes>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.springframework.ide.eclipse.boot.test</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@@ -0,0 +1,7 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.8

View File

@@ -0,0 +1,59 @@
eclipse.preferences.version=1
editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
sp_cleanup.add_default_serial_version_id=true
sp_cleanup.add_generated_serial_version_id=false
sp_cleanup.add_missing_annotations=true
sp_cleanup.add_missing_deprecated_annotations=true
sp_cleanup.add_missing_methods=false
sp_cleanup.add_missing_nls_tags=false
sp_cleanup.add_missing_override_annotations=true
sp_cleanup.add_missing_override_annotations_interface_methods=true
sp_cleanup.add_serial_version_id=false
sp_cleanup.always_use_blocks=true
sp_cleanup.always_use_parentheses_in_expressions=false
sp_cleanup.always_use_this_for_non_static_field_access=false
sp_cleanup.always_use_this_for_non_static_method_access=false
sp_cleanup.convert_functional_interfaces=false
sp_cleanup.convert_to_enhanced_for_loop=false
sp_cleanup.correct_indentation=false
sp_cleanup.format_source_code=false
sp_cleanup.format_source_code_changes_only=false
sp_cleanup.insert_inferred_type_arguments=false
sp_cleanup.make_local_variable_final=true
sp_cleanup.make_parameters_final=false
sp_cleanup.make_private_fields_final=true
sp_cleanup.make_type_abstract_if_missing_method=false
sp_cleanup.make_variable_declarations_final=false
sp_cleanup.never_use_blocks=false
sp_cleanup.never_use_parentheses_in_expressions=true
sp_cleanup.on_save_use_additional_actions=true
sp_cleanup.organize_imports=false
sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
sp_cleanup.remove_private_constructors=true
sp_cleanup.remove_redundant_type_arguments=false
sp_cleanup.remove_trailing_whitespaces=true
sp_cleanup.remove_trailing_whitespaces_all=true
sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
sp_cleanup.remove_unnecessary_casts=false
sp_cleanup.remove_unnecessary_nls_tags=false
sp_cleanup.remove_unused_imports=false
sp_cleanup.remove_unused_local_variables=false
sp_cleanup.remove_unused_private_fields=true
sp_cleanup.remove_unused_private_members=false
sp_cleanup.remove_unused_private_methods=true
sp_cleanup.remove_unused_private_types=true
sp_cleanup.sort_members=false
sp_cleanup.sort_members_all=false
sp_cleanup.use_anonymous_class_creation=false
sp_cleanup.use_blocks=false
sp_cleanup.use_blocks_only_for_return_and_throw=false
sp_cleanup.use_lambda=true
sp_cleanup.use_parentheses_in_expressions=false
sp_cleanup.use_this_for_non_static_field_access=false
sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
sp_cleanup.use_this_for_non_static_method_access=false
sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true

View File

@@ -0,0 +1,42 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Boot Tests
Bundle-SymbolicName: org.springframework.ide.eclipse.boot.test
Bundle-Version: 4.8.1.qualifier
Require-Bundle: org.eclipse.ui,
org.junit,
org.springsource.ide.eclipse.commons.livexp,
org.springframework.ide.eclipse.boot,
org.eclipse.core.resources,
org.springsource.ide.eclipse.commons.frameworks.test.util,
org.eclipse.jdt.core,
org.springsource.ide.eclipse.commons.frameworks.core,
org.springsource.ide.eclipse.commons.core,
org.springsource.ide.eclipse.commons.tests.util,
org.eclipse.ui.ide,
org.eclipse.debug.core,
org.eclipse.jdt.launching,
org.eclipse.buildship.core,
com.fasterxml.jackson.core.jackson-core,
com.fasterxml.jackson.core.jackson-databind,
org.eclipse.m2e.core.ui,
org.eclipse.wst.sse.core,
org.eclipse.wst.xml.core,
org.mockito,
org.springframework.ide.eclipse.boot.wizard;bundle-version="3.8.2",
org.glassfish.jersey.core.jersey-client;bundle-version="2.22.1",
org.glassfish.jersey.core.jersey-common;bundle-version="2.22.1",
org.springframework.ide.eclipse.boot.validation,
org.springframework.ide.eclipse.boot.launch,
org.hamcrest;bundle-version="[1.1.0,1.2.0)",
org.apache.commons.lang3,
com.google.guava
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ActivationPolicy: lazy
Bundle-Vendor: Pivotal Inc.
Export-Package: org.springframework.ide.eclipse.boot.test,
org.springframework.ide.eclipse.boot.test.util
Import-Package: org.eclipse.core.runtime,
org.eclipse.core.runtime.jobs,
org.osgi.framework
Automatic-Module-Name: org.springframework.ide.eclipse.boot.test

View File

@@ -0,0 +1,248 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<title>About Spring IDE</title>
<meta name="author" content="Spring IDE Developers">
</head>
<body>
<h2>About Spring IDE</h2>
<p>March 26, 2007</p>
<h3>Abstract</h3>
<p>Spring IDE is a set of plugins which provide a user interface for
<a href="https://www.springframework.org">The Spring Framework</a>'s bean
factory XML configuration files including support for Spring 2.0
namespaces, AOP configuration and Spring Web Flow.</p>
<h3>License</h3>
<p>The Spring IDE Project makes available all content in this
plug-in (&quot;Content&quot;). Unless otherwise indicated below, the
Content is provided to you under the terms and conditions of the Eclipse
Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is
available at <a href="https://www.eclipse.org/legal/epl-v10.html">https://www.eclipse.org/legal/epl-v10.html</a>.
For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
<p>If you did not receive this Content directly from the Spring IDE
Project, the Content is being redistributed by another party
(&quot;Redistributor&quot;) and different terms and conditions may apply
to your use of any object code in the Content. Check the Redistributor's
license that was provided with the Content. If no such license exists,
contact the Redistributor. Unless otherwise indicated below, the terms
and conditions of the EPL still apply to any source code in the Content
and such source code may be obtained at <a href="https://www.eclipse.org">https://www.eclipse.org</a>.</p>
<h3>Third Party Content</h3>
<p>The Content includes items that have been sourced from third
parties as set out below. If you did not receive this Content directly
from the Spring IDE Project, the following is provided for informational
purposes only, and you should look to the Redistributor's license for
terms and conditions of use.</p>
<p><em> <strong>The Spring Framework v3.0.5</strong>
<p>This product includes software developed by the Spring Framework
Project (<a href="https://www.springframework.org">https://www.springframework.org</a>).</p>
<p><em> <strong>Spring Web Flow v2.0.7.A</strong>
<p>This product includes software developed by the Spring Framework
Project (<a href="https://www.springframework.org">https://www.springframework.org</a>).</p>
<p><em> <strong>Spring Web Services v1.5.8</strong>
<p>This product includes software developed by the Spring Framework
Project (<a href="https://www.springframework.org">https://www.springframework.org</a>).</p>
<p><em> <strong>Spring Security v3.0.2</strong>
<p>This product includes software developed by the Spring Framework
Project (<a href="https://www.springframework.org">https://www.springframework.org</a>).</p>
<p><em> <strong>Spring Dynamic Modules for OSGi(TM) Runtimes v2.0.0.M2</strong>
<p>This product includes software developed by the Spring Framework
Project (<a href="https://www.springframework.org">https://www.springframework.org</a>).</p>
<p><em> <strong>Spring Batch v2.1.0</strong>
<p>This product includes software developed by the Spring Framework
Project (<a href="https://www.springframework.org">https://www.springframework.org</a>).</p>
<p><em> <strong>Commons Codec v1.3.0</strong>
<p>This product includes software developed by The Apache Software
Foundation (<a href="https://www.apache.org/">https://www.apache.org/</a>).</p>
<p><em> <strong>Commons Collections v3.2.0</strong>
<p>This product includes software developed by The Apache Software
Foundation (<a href="https://www.apache.org/">https://www.apache.org/</a>).</p>
<p><em> <strong>Commons Logging v1.1.1</strong>
<p>This product includes software developed by The Apache Software
Foundation (<a href="https://www.apache.org/">https://www.apache.org/</a>).</p>
<p><em> <strong>Apache MyFaces v1.2.2</strong>
<p>This product includes software developed by The Apache Software
Foundation (<a href="https://www.apache.org/">https://www.apache.org/</a>).</p>
<p><em> <strong>AspectJ Weaver v1.6.10</strong>
<p>This product includes software developed by The Eclipse Software
Foundation (<a href="https://www.eclipse.org/">https://www.eclipse.org/</a>).</p>
<p><em> <strong>Antlr v3.0.1</strong>
<p>Spring IDE includes a binary version of Antlr v3.0.1 (<a
href="https://www.antlr.org">https://www.antlr.org/</a>).
The source code for Antlr is available from the Antlr download site at
<a href="https://www.antlr.org/download.html">https://www.antlr.org/download.html</a>.
<p>The Antlr license is available at <a
href="https://www.antlr.org/license.html">https://www.antlr.org/license.html</a>.
The license is also reproduced here:</p>
<pre>Copyright (c) 2003-2007, Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions
and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions
and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of the author nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</pre></p>
<p><em> <strong>ASM v2.2.3</strong>
<p>Spring IDE includes a binary version of ASM v2.2.3 (<a
href="https://asm.objectweb.org/index.html">https://asm.objectweb.org/</a>).
The source code for ASM is available from the ObjectWeb download site at
<a href="https://asm.objectweb.org/download/">https://asm.objectweb.org/download/</a>.
<p>The ASM license is available at <a
href="https://asm.objectweb.org/license.html">https://asm.objectweb.org/license.html</a>.
The license is also reproduced here:</p>
<pre>Copyright (c) 2000-2005 INRIA, France Telecom
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
</pre></p>
<p><em> <strong>backport-util-concurrent 3.1.0</strong>
<p>Spring IDE includes a binary version of backport-util-concurrent v3.1.0 (<a
href="https://dcl.mathcs.emory.edu/util/backport-util-concurrent/">https://dcl.mathcs.emory.edu/util/backport-util-concurrent/</a>).
The source code for backport-util-concurrent is available from the download site at
<a href="https://dcl.mathcs.emory.edu/util/backport-util-concurrent/dist/">https://dcl.mathcs.emory.edu/util/backport-util-concurrent/dist/</a>.
<p>The backport-util-concurrent license is available at <a
href="https://creativecommons.org/licenses/publicdomain">https://creativecommons.org/licenses/publicdomain</a>.
The license is also reproduced here:</p>
<pre><em>Copyright-Only Dedication (based on United States law) or Public Domain Certification</em>
The person or persons who have associated work with this document (the
"Dedicator" or "Certifier") hereby either (a) certifies that, to the
best of his knowledge, the work of authorship identified is in the public
domain of the country from which the work is published, or (b) hereby
dedicates whatever copyright the dedicators holds in the work of authorship
identified below (the "Work") to the public domain. A certifier, moreover,
dedicates any copyright interest he may have in the associated work, and
for these purposes, is described as a "dedicator" below.
A certifier has taken reasonable steps to verify the copyright status of
this work. Certifier recognizes that his good faith efforts may not shield
him from liability if in fact the work certified is not in the public domain.
Dedicator makes this dedication for the benefit of the public at large and
to the detriment of the Dedicator's heirs and successors. Dedicator intends
this dedication to be an overt act of relinquishment in perpetuity of all
present and future rights under copyright law, whether vested or contingent,
in the Work. Dedicator understands that such relinquishment of all rights
includes the relinquishment of all rights to enforce (by lawsuit or otherwise)
those copyrights in the Work.
Dedicator recognizes that, once placed in the public domain, the Work may be
freely reproduced, distributed, transmitted, used, modified, built upon, or
otherwise exploited by anyone for any purpose, commercial or non-commercial,
and in any way, including by methods that have not yet been invented or
conceived.
</pre></p>
<p><em> <strong>AOP Alliance</strong>
<p>LICENCE: all the source code provided by AOP Alliance is Public Domain.
</p>
<p><em> <strong>javax.el v1.0.0</strong>
<p>This product includes software distributed by Sun (meanwhile Oracle) under CDDL license
(<a href="https://www.sun.com/cddl/cddl.html">https://www.sun.com/cddl/cddl.html</a>).</p>
<p><em> <strong>javax.jms v1.1.0</strong>
<p>This product includes software distributed by Sun (meanwhile Oracle) under CDDL license
(<a href="https://www.sun.com/cddl/cddl.html">https://www.sun.com/cddl/cddl.html</a>).</p>
<p><em> <strong>javax.servlet v2.5.0</strong>
<p>This product includes software distributed by Sun (meanwhile Oracle) under CDDL license
(<a href="https://www.sun.com/cddl/cddl.html">https://www.sun.com/cddl/cddl.html</a>).</p>
<p><em> <strong>javax.servlet.jsp v2.1.0</strong>
<p>This product includes software distributed by Sun (meanwhile Oracle) under CDDL license
(<a href="https://www.sun.com/cddl/cddl.html">https://www.sun.com/cddl/cddl.html</a>).</p>
<p><em> <strong>javax.servlet.jsp.jstl v1.2.0</strong>
<p>This product includes software distributed by Sun (meanwhile Oracle) under CDDL license
(<a href="https://www.sun.com/cddl/cddl.html">https://www.sun.com/cddl/cddl.html</a>).</p>
<p><em> <strong>javax.activation v1.1.0</strong>
<p>This product includes software distributed by Sun (meanwhile Oracle) under CDDL license
(<a href="https://www.sun.com/cddl/cddl.html">https://www.sun.com/cddl/cddl.html</a>).</p>
<p><em> <strong>javax.annotation v1.0.0</strong>
<p>This product includes software distributed by Sun (meanwhile Oracle) under CDDL license
(<a href="https://www.sun.com/cddl/cddl.html">https://www.sun.com/cddl/cddl.html</a>).</p>
<p><em> <strong>javax.mail v1.4.0</strong>
<p>This product includes software distributed by Sun (meanwhile Oracle) under CDDL license
(<a href="https://www.sun.com/cddl/cddl.html">https://www.sun.com/cddl/cddl.html</a>).</p>
<p><em> <strong>javax.xml.stream v1.0.1</strong>
<p>This product includes software distributed by Sun (meanwhile Oracle) under CDDL license
(<a href="https://www.sun.com/cddl/cddl.html">https://www.sun.com/cddl/cddl.html</a>).</p>
<p><em> <strong>javax.xml.ws v2.1.0</strong>
<p>This product includes software distributed by Sun (meanwhile Oracle) under CDDL license
(<a href="https://www.sun.com/cddl/cddl.html">https://www.sun.com/cddl/cddl.html</a>).</p>
</em></p>
<address>Copyright (c) 2005, 2011 Spring IDE Developers</address>
</body>
</html>

View File

@@ -0,0 +1,5 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
about.html

View File

@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot.ide</groupId>
<artifactId>org.springframework.boot.ide</artifactId>
<version>4.8.1-SNAPSHOT</version>
<relativePath>../../eclipse-distribution/pom.xml</relativePath>
</parent>
<groupId>org.springframework.ide.eclipse</groupId>
<artifactId>org.springframework.ide.eclipse.boot.test</artifactId>
<packaging>eclipse-test-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-surefire-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<forkedProcessTimeoutInSeconds>7200</forkedProcessTimeoutInSeconds>
<testSuite>org.springframework.ide.eclipse.boot.test</testSuite>
<testClass>org.springframework.ide.eclipse.boot.test.AllSpringBootTests</testClass>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>target-platform-configuration</artifactId>
<version>${tycho-version}</version>
<configuration>
<dependency-resolution>
<extraRequirements>
<requirement>
<type>eclipse-plugin</type>
<id>org.eclipse.equinox.event</id>
<versionRange>0.0.0</versionRange>
</requirement>
<requirement>
<type>eclipse-plugin</type>
<id>org.apache.felix.scr</id>
<versionRange>0.0.0</versionRange>
</requirement>
<requirement>
<type>eclipse-feature</type>
<id>org.eclipse.m2e.feature</id>
<versionRange>0.0.0</versionRange>
</requirement>
<requirement>
<type>eclipse-plugin</type>
<id>org.springframework.ide.eclipse.buildship30</id>
<versionRange>0.0.0</versionRange>
</requirement>
</extraRequirements>
</dependency-resolution>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>e45</id>
<repositories>
<repository>
<id>buildship2</id>
<layout>p2</layout>
<url>https://download.eclipse.org/buildship/updates/e45/releases/2.x/</url>
</repository>
</repositories>
</profile>
<profile>
<id>e46</id>
<repositories>
<repository>
<id>buildship2</id>
<layout>p2</layout>
<url>https://download.eclipse.org/buildship/updates/e46/snapshots/2.x</url>
</repository>
</repositories>
</profile>
</profiles>
</project>

View File

@@ -0,0 +1,186 @@
/*******************************************************************************
* Copyright (c) 2005, 2012, 2015 Spring IDE Developers
* 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Spring IDE Developers - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.test;
import static org.junit.Assert.fail;
import static org.springframework.ide.eclipse.boot.test.BootProjectTestHarness.buildMavenProject;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.springsource.ide.eclipse.commons.frameworks.core.util.IOUtil;
import org.springsource.ide.eclipse.commons.tests.util.StsTestUtil;
/**
* @author Christian Dupuis
* @author Martin Lippert
* @author Tomasz Zarna
* @author Kris De Volder
*/
public abstract class AbstractBootValidationTest {
private static final String BUNDLE_ID = "org.springframework.ide.eclipse.boot.test";
private static boolean wasAutobuilding;
@BeforeClass
public static void setupClass() throws Exception {
wasAutobuilding = StsTestUtil.isAutoBuilding();
}
@AfterClass
public static void tearDownClass() throws Exception {
StsTestUtil.setAutoBuilding(wasAutobuilding);
}
@Before
public void setup() throws Exception {
StsTestUtil.setAutoBuilding(false);
}
@After
public void tearDown() throws Exception {
StsTestUtil.deleteAllProjects();
}
/**
* Returns the IWorkspace this test suite is running on.
*/
public IWorkspace getWorkspace() {
return ResourcesPlugin.getWorkspace();
}
public IWorkspaceRoot getWorkspaceRoot() {
return getWorkspace().getRoot();
}
protected IProject createPredefinedProject(final String projectName)
throws Exception {
StsTestUtil.createPredefinedProject(projectName, BUNDLE_ID);
IProject project = getProject(projectName);
buildMavenProject(project);
return project;
}
public static void assertNoMarkers(IMarker[] markers) throws Exception {
assertNoMarkers(new LinkedHashSet<IMarker>(Arrays.asList(markers)));
}
public static void assertNoMarkers(Set<IMarker> markers) throws Exception {
if (markers.size()>0) {
StringBuilder messages = new StringBuilder("Expected no markers but found: \n");
for (IMarker m : markers) {
messages.append(m.getAttribute(IMarker.MESSAGE)+"\n");
}
fail(messages.toString());
}
}
/**
* @return Matcher that check whether a IMarker instance text range covers an area of
* its corresponding resource that contains a specific piece of text exactly.
*/
public static Matcher<IMarker> markerWithAreaCovering(final String expectedTextInMarkerRange) {
return new TypeSafeMatcher<IMarker>(IMarker.class) {
public void describeTo(Description description) {
description.appendText("markerWithAreaCovering("+expectedTextInMarkerRange+")");
}
public void describeMismatchSafely(IMarker item, Description description) {
try {
int start = (Integer) item.getAttribute(IMarker.CHAR_START);
int end = (Integer) item.getAttribute(IMarker.CHAR_END);
IFile f = (IFile) item.getResource();
String resourceContent = getContents(f);
String actual = resourceContent.substring(start, end);
description.appendDescriptionOf(this);
description.appendText(" but found ");
description.appendValue(actual);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
protected boolean matchesSafely(IMarker item) {
try {
int start = (Integer) item.getAttribute(IMarker.CHAR_START);
int end = (Integer) item.getAttribute(IMarker.CHAR_END);
IFile f = (IFile) item.getResource();
String resourceContent = getContents(f);
String actual = resourceContent.substring(start, end);
return actual.equals(expectedTextInMarkerRange);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
};
}
public static String getContents(IFile r) throws Exception {
InputStream contents = r.getContents();
ByteArrayOutputStream capture = new ByteArrayOutputStream();
IOUtil.pipe(contents, capture);
return capture.toString(r.getCharset());
}
public static Matcher<IMarker> markerWithMessageSnippet(final String expectSnippet) {
return new TypeSafeMatcher<IMarker>(IMarker.class) {
public void describeTo(Description description) {
description.appendText("markerWithMessageSnippet("+expectSnippet+")");
}
public boolean matchesSafely(IMarker item) {
try {
String actualMessage = (String)item.getAttribute(IMarker.MESSAGE);
return actualMessage.contains(expectSnippet);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
};
}
public IMarker[] getAllMarkers(IResource rsrc, String markerType) throws Exception {
return rsrc.findMarkers(markerType, true, IResource.DEPTH_INFINITE);
}
protected IProject getProject(String project) {
return getWorkspaceRoot().getProject(project);
}
protected IJavaProject getJavaProject(String projectName) {
return JavaCore.create(getProject(projectName));
}
protected IResource createPredefinedProjectAndGetResource(
String projectName, String resourcePath) throws Exception {
IProject project = createPredefinedProject(projectName);
return project.findMember(resourcePath);
}
}

View File

@@ -0,0 +1,313 @@
/*******************************************************************************
* Copyright (c) 2020 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.springframework.ide.eclipse.boot.test.BootProjectTestHarness.latestBootReleaseVersion;
import java.util.List;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.ide.eclipse.boot.core.initializr.InitializrServiceSpec.Dependency;
import org.springframework.ide.eclipse.boot.test.util.TestBracketter;
import org.springframework.ide.eclipse.boot.wizard.CheckBoxesSection.CheckBoxModel;
import org.springframework.ide.eclipse.boot.wizard.HierarchicalMultiSelectionFieldModel;
import org.springframework.ide.eclipse.boot.wizard.starters.AddStartersCompareModel;
import org.springframework.ide.eclipse.boot.wizard.starters.AddStartersCompareResult;
import org.springframework.ide.eclipse.boot.wizard.starters.AddStartersError;
import org.springframework.ide.eclipse.boot.wizard.starters.AddStartersInitializrService;
import org.springframework.ide.eclipse.boot.wizard.starters.AddStartersPreferences;
import org.springframework.ide.eclipse.boot.wizard.starters.AddStartersWizardModel;
import org.springframework.ide.eclipse.boot.wizard.starters.InitializrModel;
import org.springsource.ide.eclipse.commons.livexp.core.ValidationResult;
import org.springsource.ide.eclipse.commons.tests.util.StsTestUtil;
public class AddStartersModelTest extends AddStartersTestHarness {
private static boolean wasAutobuilding;
@BeforeClass
public static void setupClass() throws Exception {
wasAutobuilding = StsTestUtil.isAutoBuilding();
StsTestUtil.setAutoBuilding(false);
}
@AfterClass
public static void teardownClass() throws Exception {
StsTestUtil.setAutoBuilding(wasAutobuilding);
}
@Before
public void setup() throws Exception {
StsTestUtil.cleanUpProjects();
}
@Rule
public TestBracketter testBracketer = new TestBracketter();
/**
* Tests that the initializr model with dependencies is loaded in the wizard
*/
@Test
public void selectDependenciesInWizard() throws Exception {
IProject project = harness.createBootProject("selectDependenciesInWizard", latestBootReleaseVersion());
String starterZipFile = STARTER_ZIP_WEB_ACTUATOR;
String validInitializrUrl = MOCK_VALID_INITIALIZR_URL;
String[] supportedBootVersions = harness.getInitializrSupportedBootVersions();
String[] dependenciesToSelect = new String[] {"web", "actuator"};
MockInitializrService wrappedService = new MockInitializrService(supportedBootVersions, mavenStartersHarness,
INITIALIZR_INFO_INPUT);
AddStartersInitializrService initializrService = new MockAddStartersInitializrService(starterZipFile,
validInitializrUrl, supportedBootVersions, dependenciesToSelect, wrappedService);
String projectBootVersion = getProjectBootVersion(initializrService, validInitializrUrl, project);
AddStartersPreferences preferences = createPreferences(validInitializrUrl, prefs);
AddStartersWizardModel wizard = createAndLoadWizard(project, preferences, initializrService,
dependenciesToSelect);
// Verify the fields and model are set in the wizard after loading
assertEquals(validInitializrUrl, wizard.getServiceUrl().getValue());
assertEquals(projectBootVersion, wizard.getBootVersion().getValue());
assertEquals(ValidationResult.OK, wizard.getValidator().getValue());
assertInitializrAndCompareModelsNotNull(wizard);
// Ensure dependency info are loaded in the initializr Model
// and dependencies are selected
InitializrModel initializrModel = wizard.getInitializrModel().getValue();
HierarchicalMultiSelectionFieldModel<Dependency> dependencies = initializrModel.dependencies;
List<CheckBoxModel<Dependency>> allDependencies = dependencies.getAllBoxes();
assertTrue(!allDependencies.isEmpty());
// Check that the actual selected dependencies in the wizard match the expected dependencies
List<Dependency> currentSelection = dependencies.getCurrentSelection();
assertTrue(currentSelection.size() > 0);
assertEquals(dependenciesToSelect.length, currentSelection.size());
for (Dependency selected : currentSelection) {
assertNotNull(getExpectedDependency(selected, dependenciesToSelect));
}
// There should be no comparison, as we haven't downloaded the project to compare to in this test
AddStartersCompareModel compareModel = wizard.getCompareModel().getValue();
assertNull(compareModel.getComparison().getValue());
}
@Test
public void changeBetweenInvalidAndValidUrl() throws Exception {
IProject project = harness.createBootProject("changeBetweenInvalidAndValidUrl", latestBootReleaseVersion());
String[] supportedBootVersions = harness.getInitializrSupportedBootVersions();
String starterZipFile = STARTER_ZIP_WEB_ACTUATOR;
String validInitializrUrl = MOCK_VALID_INITIALIZR_URL;
String[] dependenciesToSelect = new String[] {"web", "actuator"};
MockInitializrService wrappedService = new MockInitializrService(supportedBootVersions, mavenStartersHarness,
INITIALIZR_INFO_INPUT);
AddStartersInitializrService initializrService = new MockAddStartersInitializrService(starterZipFile,
validInitializrUrl, supportedBootVersions, dependenciesToSelect, wrappedService);
String projectBootVersion = getProjectBootVersion(initializrService, validInitializrUrl, project);
AddStartersPreferences preferences = createPreferences(validInitializrUrl, prefs);
AddStartersWizardModel wizard = createAndLoadWizard(project, preferences, initializrService,
dependenciesToSelect);
// Verify the fields and model are set in the wizard after loading
assertEquals(validInitializrUrl, wizard.getServiceUrl().getValue());
assertEquals(projectBootVersion, wizard.getBootVersion().getValue());
assertEquals(ValidationResult.OK, wizard.getValidator().getValue());
assertInitializrAndCompareModelsNotNull(wizard);
// Set a valid URL that is not a valid initializr URL
wizard.getServiceUrl().setValue("https://www.google.ca");
waitForWizardJob();
// There should be no valid initializr model available
assertInitializrAndCompareModelsNull(wizard);
AddStartersError result = (AddStartersError)wizard.getValidator().getValue();
assertTrue(result.status == IStatus.ERROR);
assertTrue(result.details.contains("ConnectException"));
// Set a valid URL again. Should load a valid model and validate
wizard.getServiceUrl().setValue(validInitializrUrl);
waitForWizardJob();
assertInitializrAndCompareModelsNotNull(wizard);
assertEquals(ValidationResult.OK, wizard.getValidator().getValue());
}
@Test
public void malformedUrlError() throws Exception {
IProject project = harness.createBootProject("malformedUrlError", latestBootReleaseVersion());
String[] supportedBootVersions = harness.getInitializrSupportedBootVersions();
String starterZipFile = STARTER_ZIP_WEB_ACTUATOR;
String validInitializrUrl = MOCK_VALID_INITIALIZR_URL;
String[] dependenciesToSelect = new String[] {"web", "actuator"};
MockInitializrService wrappedService = new MockInitializrService(supportedBootVersions, mavenStartersHarness,
INITIALIZR_INFO_INPUT);
AddStartersInitializrService initializrService = new MockAddStartersInitializrService(starterZipFile,
validInitializrUrl, supportedBootVersions, dependenciesToSelect, wrappedService);
String projectBootVersion = getProjectBootVersion(initializrService, validInitializrUrl, project);
AddStartersPreferences preferences = createPreferences(validInitializrUrl, prefs);
AddStartersWizardModel wizard = createAndLoadWizard(project, preferences, initializrService,
dependenciesToSelect);
// Verify the fields and model are set in the wizard after loading
assertEquals(validInitializrUrl, wizard.getServiceUrl().getValue());
assertEquals(projectBootVersion, wizard.getBootVersion().getValue());
assertEquals(ValidationResult.OK, wizard.getValidator().getValue());
assertInitializrAndCompareModelsNotNull(wizard);
// Set a malformed URL
wizard.getServiceUrl().setValue("wlwlwlw");
waitForWizardJob();
// There should be no valid initializr model available
assertInitializrAndCompareModelsNull(wizard);
AddStartersError result = (AddStartersError)wizard.getValidator().getValue();
assertTrue(result.status == IStatus.ERROR);
assertTrue(result.details.contains("MalformedURLException"));
// Set a valid URL again. Should load a valid model and validate
wizard.getServiceUrl().setValue(validInitializrUrl);
waitForWizardJob();
assertEquals(ValidationResult.OK, wizard.getValidator().getValue());
assertInitializrAndCompareModelsNotNull(wizard);
}
@Test
public void missingUrlError() throws Exception {
IProject project = harness.createBootProject("missingUrlError", latestBootReleaseVersion());
String[] supportedBootVersions = harness.getInitializrSupportedBootVersions();
String starterZipFile = STARTER_ZIP_WEB_ACTUATOR;
String validInitializrUrl = MOCK_VALID_INITIALIZR_URL;
String[] dependenciesToSelect = new String[] {"web", "actuator"};
MockInitializrService wrappedService = new MockInitializrService(supportedBootVersions, mavenStartersHarness,
INITIALIZR_INFO_INPUT);
AddStartersInitializrService initializrService = new MockAddStartersInitializrService(starterZipFile,
validInitializrUrl, supportedBootVersions, dependenciesToSelect, wrappedService);
String projectBootVersion = getProjectBootVersion(initializrService, validInitializrUrl, project);
AddStartersPreferences preferences = createPreferences(validInitializrUrl, prefs);
AddStartersWizardModel wizard = createAndLoadWizard(project, preferences, initializrService,
dependenciesToSelect);
// Verify the fields and model are set in the wizard after loading
assertEquals(validInitializrUrl, wizard.getServiceUrl().getValue());
assertEquals(projectBootVersion, wizard.getBootVersion().getValue());
assertEquals(ValidationResult.OK, wizard.getValidator().getValue());
assertInitializrAndCompareModelsNotNull(wizard);
// Set empty URL
wizard.getServiceUrl().setValue("");
waitForWizardJob();
// There should be no valid initializr model available
AddStartersError result = (AddStartersError)wizard.getValidator().getValue();
assertTrue(result.status == IStatus.ERROR);
assertTrue(result.details.contains("Missing initializr service URL"));
assertInitializrAndCompareModelsNull(wizard);
// Set a valid URL again. Should load a valid model and validate
wizard.getServiceUrl().setValue(validInitializrUrl);
waitForWizardJob();
assertEquals(ValidationResult.OK, wizard.getValidator().getValue());
assertInitializrAndCompareModelsNotNull(wizard);
}
@Test
public void unsupportedBootVersionError() throws Exception {
// Create a project with a valid boot version as the harness
// doesn't allow creating a project with old unsupported boot version
// However we will change the list of supported boot versions to exclude this boot version
// to simulate a case where there is a unsupported boot version in the add starters wizard
IProject project = harness.createBootProject("unsupportedBootVersionError", latestBootReleaseVersion());
String starterZipFile = STARTER_ZIP_WEB_ACTUATOR;
String validInitializrUrl = MOCK_VALID_INITIALIZR_URL;
// List supported versions that do not include the version used to create the project
String[] supportedBootVersions = new String[] { "1.0.0.RELEASE", "1.1.0.RELEASE", "1.5.3.RELEASE"};
// No dependencies to select, as in this test, there should be no initializr information because boot version is not supported
String[] dependenciesToSelect = null;
MockInitializrService wrappedService = new MockInitializrService(supportedBootVersions, mavenStartersHarness,
INITIALIZR_INFO_INPUT);
AddStartersInitializrService initializrService = new MockAddStartersInitializrService(starterZipFile,
validInitializrUrl, supportedBootVersions, dependenciesToSelect, wrappedService);
AddStartersPreferences preferences = createPreferences(validInitializrUrl, prefs);
AddStartersWizardModel wizard = createAndLoadWizard(project, preferences, initializrService,
dependenciesToSelect);
AddStartersError result = (AddStartersError)wizard.getValidator().getValue();
assertTrue(result.status == IStatus.ERROR);
assertTrue(result.details.contains("FileNotFoundException"));
// Also verify that the error message details lists all the supported boot versions that a user should update to
assertTrue(result.details.contains("1.0.0.RELEASE"));
assertTrue(result.details.contains("1.1.0.RELEASE"));
assertTrue(result.details.contains("1.5.3.RELEASE"));
}
@Test
public void basicComparison() throws Exception {
IProject project = harness.createBootProject("basicComparison", latestBootReleaseVersion());
String[] supportedBootVersions = harness.getInitializrSupportedBootVersions();
String starterZipFile = STARTER_ZIP_WEB_ACTUATOR;
String validInitializrUrl = MOCK_VALID_INITIALIZR_URL;
String[] dependenciesToSelect = new String[] {"web", "actuator"};
MockInitializrService wrappedService = new MockInitializrService(supportedBootVersions, mavenStartersHarness,
INITIALIZR_INFO_INPUT);
AddStartersInitializrService initializrService = new MockAddStartersInitializrService(starterZipFile,
validInitializrUrl, supportedBootVersions, dependenciesToSelect, wrappedService);
AddStartersPreferences preferences = createPreferences(validInitializrUrl, prefs);
AddStartersWizardModel wizard = createAndLoadWizard(project, preferences, initializrService,
dependenciesToSelect);
assertInitializrAndCompareModelsNotNull(wizard);
AddStartersCompareModel compareModel = wizard.getCompareModel().getValue();
AddStartersCompareResult comparison = compareModel.getComparison().getValue();
assertNull(comparison);
compareModel.generateComparison(new NullProgressMonitor());
comparison = compareModel.getComparison().getValue();
assertNotNull(comparison);
// Verify that the comparison contains the "mocked" downloaded zip file as a comparison source
assertTrue(comparison.getDownloadedProject().getPath().contains(starterZipFile));
// Verify that the comparison contains the local project as a comparison source
assertTrue(comparison.getLocalResource().getProject().equals(project));
}
}

View File

@@ -0,0 +1,193 @@
/*******************************************************************************
* Copyright (c) 2020 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.preference.IPreferenceStore;
import org.springframework.ide.eclipse.boot.core.ISpringBootProject;
import org.springframework.ide.eclipse.boot.core.SpringBootCore;
import org.springframework.ide.eclipse.boot.core.initializr.InitializrProjectDownloader;
import org.springframework.ide.eclipse.boot.core.initializr.InitializrService;
import org.springframework.ide.eclipse.boot.core.initializr.InitializrServiceSpec.Dependency;
import org.springframework.ide.eclipse.boot.core.initializr.InitializrUrl;
import org.springframework.ide.eclipse.boot.test.util.TestResourcesUtil;
import org.springframework.ide.eclipse.boot.wizard.starters.AddStartersCompareModel;
import org.springframework.ide.eclipse.boot.wizard.starters.AddStartersInitializrService;
import org.springframework.ide.eclipse.boot.wizard.starters.AddStartersPreferences;
import org.springframework.ide.eclipse.boot.wizard.starters.AddStartersWizardModel;
import org.springframework.ide.eclipse.boot.wizard.starters.InitializrModel;
import org.springsource.ide.eclipse.commons.frameworks.core.downloadmanager.URLConnectionFactory;
public class AddStartersTestHarness {
protected BootProjectTestHarness harness = new BootProjectTestHarness(ResourcesPlugin.getWorkspace());
protected MavenStartersHarness mavenStartersHarness = new MavenStartersHarness();
protected IPreferenceStore prefs = new MockPrefsStore();
protected static final String MOCK_VALID_INITIALIZR_URL = "https://add.starters.start.spring.io";
// A starter zip file containing "selected" web and actuator dependencies
protected static final String STARTER_ZIP_WEB_ACTUATOR = "/initializr/boot-web-actuator/starter.zip";
protected static final String INITIALIZR_INFO_INPUT = "sample";
protected void loadInitializrModel(AddStartersWizardModel wizard) throws Exception {
wizard.addModelLoader(() -> wizard.createInitializrModel(new NullProgressMonitor()));
// Wait for it to finish
waitForWizardJob();
}
protected ISpringBootProject getBootProject(AddStartersInitializrService service, String url, IProject project) throws Exception {
InitializrService initializr = service.getService(() -> url);
SpringBootCore core = new SpringBootCore(initializr);
return core.project(project);
}
protected String getProjectBootVersion(AddStartersInitializrService service, String url, IProject project) throws Exception {
ISpringBootProject bootProject = getBootProject(service, url, project);
return bootProject.getBootVersion();
}
protected void waitForWizardJob() throws InterruptedException {
Job.getJobManager().join(AddStartersWizardModel.JOB_FAMILY, null);
}
protected void assertInitializrAndCompareModelsNull(AddStartersWizardModel wizard) {
InitializrModel initializrModel = wizard.getInitializrModel().getValue();
assertNull(initializrModel);
AddStartersCompareModel compareModel = wizard.getCompareModel().getValue();
assertNull(compareModel);
}
protected void assertInitializrAndCompareModelsNotNull(AddStartersWizardModel wizard) {
InitializrModel initializrModel = wizard.getInitializrModel().getValue();
assertNotNull(initializrModel);
AddStartersCompareModel compareModel = wizard.getCompareModel().getValue();
assertNotNull(compareModel);
}
protected void selectDependenciesInWizard(AddStartersWizardModel wizard, String... dependencies) {
InitializrModel initializrModel = wizard.getInitializrModel().getValue();
for (String dep : dependencies) {
initializrModel.addDependency(dep);
}
}
protected AddStartersWizardModel createAndLoadWizard(IProject project, AddStartersPreferences preferences,
AddStartersInitializrService initializrService, String[] dependenciesToSelect) throws Exception {
AddStartersWizardModel wizard = new AddStartersWizardModel(project, preferences, initializrService);
// Wizard model is not available until it is loaded
assertInitializrAndCompareModelsNull(wizard);
loadInitializrModel(wizard);
// Select the dependencies in the "Dependencies" section of the wizard
if (dependenciesToSelect != null) {
selectDependenciesInWizard(wizard, dependenciesToSelect);
}
return wizard;
}
protected AddStartersPreferences createPreferences(String validInitializrUrl, IPreferenceStore prefs) {
return new MockAddStartersPreferences(validInitializrUrl, prefs);
}
protected void performOk(AddStartersWizardModel wizard) throws Exception {
wizard.performOk();
waitForWizardJob();
}
public static class MockAddStartersPreferences extends AddStartersPreferences {
private final List<String> storedUrls = new ArrayList<>();
public MockAddStartersPreferences(String validUrl, IPreferenceStore prefs) {
super(prefs);
storedUrls.add(validUrl);
}
@Override
public String getInitializrUrl() {
return storedUrls.get(0);
}
@Override
public String[] getInitializrUrls() {
return storedUrls.toArray(new String[] {});
}
@Override
public void addInitializrUrl(String url) {
storedUrls.add(url);
}
}
public static class MockProjectDownloader extends InitializrProjectDownloader {
private final String starterZipPath;
private final String[] expectedSelectedDependencies;
public MockProjectDownloader(URLConnectionFactory urlConnectionFactory, InitializrUrl url,
String starterZipPath, String[] expectedSelectedDependencies) {
super(urlConnectionFactory, url);
this.starterZipPath = starterZipPath;
this.expectedSelectedDependencies = expectedSelectedDependencies;
}
@Override
public File getProject(List<Dependency> dependencies, ISpringBootProject bootProject) throws Exception {
// selected dependencies from the wizard don't actually get used in the mock
// project downloader
// as we dont actually need to download the zip file from initializr using a
// constructed URL that
// contains the dependencies.
// However, we can at least test that the dependencies that were selected in the
// wizard match the expected ones
assertSelectedDependencies(dependencies);
return TestResourcesUtil.getTestFile(starterZipPath);
}
private void assertSelectedDependencies(List<Dependency> dependencies) {
assertEquals(expectedSelectedDependencies.length, dependencies.size());
for (Dependency actual : dependencies) {
assertNotNull(getExpectedDependency(actual, expectedSelectedDependencies));
}
}
}
public static String getExpectedDependency(Dependency dep, String... expectedDependencies) {
for (String expected : expectedDependencies) {
if (expected.equals(dep.getId())) {
return expected;
}
}
return null;
}
}

View File

@@ -0,0 +1,28 @@
package org.springframework.ide.eclipse.boot.test;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
@SuiteClasses({
//SpringBootProjectTests.class: removed for now
// functionality for this is now tested via EditStartersModelTest, and
// other tests that use the functionalities provided by ISpringBootProject
// EditStartersModelTest.class,
EnableDisableBootDevtoolsTest.class,
NewSpringBootWizardModelTest.class,
NewSpringBootWizardTest.class,
InitializrDependencySpecTest.class,
SpringBootValidationTest.class,
GSGWizardModelTest.class,
InitializrFactoryModelTest.class,
DependencyTooltipContentTest.class,
BootPropertyTesterTest.class,
AddStartersModelTest.class
})
public class AllSpringBootTests {
public static final String PLUGIN_ID = "org.springframework.ide.eclipse.boot.test";
}

View File

@@ -0,0 +1,47 @@
/*******************************************************************************
* Copyright (c) 2015 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.test;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.springsource.ide.eclipse.commons.tests.util.StsTestUtil;
/**
* Test rule that enables or disables autobuilding before test exeuction and
* restores this setting back to its original state at end of test.
*
* @author Kris De Volder
*/
public class AutobuildingEnablement implements TestRule {
private boolean enable;
public AutobuildingEnablement(boolean enable) {
this.enable = enable;
}
@Override
public Statement apply(final Statement base, Description description) {
return new Statement() {
public void evaluate() throws Throwable {
boolean wasAutoBuilding = StsTestUtil.isAutoBuilding();
StsTestUtil.setAutoBuilding(enable);
try {
base.evaluate();
} finally {
StsTestUtil.setAutoBuilding(wasAutoBuilding);
}
}
};
}
}

View File

@@ -0,0 +1,462 @@
/*******************************************************************************
* Copyright (c) 2015, 2020 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.test;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import static org.springsource.ide.eclipse.commons.livexp.ui.ProjectLocationSection.getDefaultProjectLocation;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.launching.IVMInstall2;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.m2e.core.ui.internal.UpdateMavenProjectJob;
import org.osgi.framework.Version;
import org.osgi.framework.VersionRange;
import org.springframework.ide.eclipse.boot.core.ISpringBootProject;
import org.springframework.ide.eclipse.boot.core.SpringBootCore;
import org.springframework.ide.eclipse.boot.test.util.CopyFromFolder;
import org.springframework.ide.eclipse.boot.util.RetryUtil;
import org.springframework.ide.eclipse.boot.wizard.NewSpringBootWizardModel;
import org.springframework.ide.eclipse.boot.wizard.RadioGroup;
import org.springframework.ide.eclipse.boot.wizard.RadioInfo;
import org.springframework.ide.eclipse.boot.wizard.content.BuildType;
import org.springframework.ide.eclipse.boot.wizard.content.CodeSet;
import org.springframework.ide.eclipse.boot.wizard.importing.ImportConfiguration;
import org.springframework.ide.eclipse.boot.wizard.importing.ImportStrategies;
import org.springframework.ide.eclipse.boot.wizard.importing.ImportStrategy;
import org.springframework.ide.eclipse.boot.wizard.starters.AddStartersInitializrService;
import org.springsource.ide.eclipse.commons.frameworks.test.util.ACondition;
import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil;
import org.springsource.ide.eclipse.commons.tests.util.StsTestUtil;
/**
* @author Kris De Volder
*/
@SuppressWarnings("restriction")
public class BootProjectTestHarness {
private static final boolean DEBUG = true;
private String[] supportedBootVersions = null;
private String latestReleaseVersion = null;
private static void debug(String string) {
if (DEBUG) {
System.out.println(string);
}
}
public static final long BOOT_PROJECT_CREATION_TIMEOUT = 2*60*1000; // long, may download maven dependencies
private IWorkspace workspace;
public BootProjectTestHarness(IWorkspace workspace) {
this.workspace = workspace;
}
@FunctionalInterface
public interface WizardConfigurer {
void apply(NewSpringBootWizardModel wizard);
WizardConfigurer NULL = new WizardConfigurer(){
@Override
public void apply(NewSpringBootWizardModel wizard) {/*do nothing*/}
};
}
public static WizardConfigurer withImportStrategy(final String id) {
final ImportStrategy is = ImportStrategies.withId(id);
Assert.isNotNull(is, "Import strategy not found: "+id+ " in "+ImportStrategies.all());
return new WizardConfigurer() {
@Override
public void apply(NewSpringBootWizardModel wizard) {
wizard.setImportStrategy(is);
}
};
}
public static WizardConfigurer withPackaging(final String packagingTypeName) {
return (wizard) -> {
RadioGroup packagingRadio = wizard.getRadioGroups().getGroup("packaging");
assertNotNull("Couldn't find 'packaging' radiogroup in the wizard model", packagingRadio);
for (RadioInfo r : packagingRadio.getRadios()) {
if (r.getValue().equals(packagingTypeName)) {
packagingRadio.getSelection().selection.setValue(r);
return;
}
}
fail("Couldn't find packaging type '"+packagingTypeName+"' in the wizard model");
};
}
public static WizardConfigurer withLanguage(final String language) {
return (wizard) -> {
RadioGroup languageRadio = wizard.getRadioGroups().getGroup("language");
assertNotNull("Couldn't find 'language' radiogroup in the wizard model", languageRadio);
RadioInfo l = languageRadio.getRadio(language);
assertNotNull("Couldn't find language '"+language+"' in the wizard model", l);
languageRadio.setValue(l);
};
}
public static WizardConfigurer withStarters(final String... ids) {
if (ids.length>0) {
return new WizardConfigurer() {
@Override
public void apply(NewSpringBootWizardModel wizard) {
for (String id : ids) {
wizard.addDependency(id);
}
}
};
}
return WizardConfigurer.NULL;
}
public static WizardConfigurer setPackage(final String pkgName) {
return new WizardConfigurer() {
@Override
public void apply(NewSpringBootWizardModel wizard) {
wizard.getStringInput("packageName").setValue(pkgName);
}
};
}
/**
* @return A wizard configurer that ensures the selected 'boot version' is exactly
* a given version of boot.
*/
public static WizardConfigurer bootVersion(final String wantedVersion) throws Exception {
return new WizardConfigurer() {
@Override
public void apply(NewSpringBootWizardModel wizard) {
RadioGroup bootVersionRadio = wizard.getBootVersion();
for (RadioInfo option : bootVersionRadio.getRadios()) {
if (option.getValue().equals(wantedVersion)) {
bootVersionRadio.setValue(option);
return;
}
}
fail("The wanted bootVersion '"+wantedVersion+"'is not found in the wizard");
}
};
}
public static WizardConfigurer withJavaVersion(String version) {
return new WizardConfigurer() {
@Override
public void apply(NewSpringBootWizardModel wizard) {
List<String> availableVersions = new ArrayList<>();
RadioGroup javaVersionRadio = wizard.getJavaVersion();
RadioInfo[] radios = javaVersionRadio.getRadios();
for (RadioInfo option : radios) {
if (option.getValue().equals(version)) {
javaVersionRadio.setValue(option);
return;
}
availableVersions.add(option.getValue());
}
fail("Java version '"+version+"' not found in "+availableVersions);
}
};
}
public static WizardConfigurer latestBootReleaseVersion() throws Exception {
return new WizardConfigurer() {
@Override
public void apply(NewSpringBootWizardModel wizard) {
RadioGroup bootVersionRadio = wizard.getBootVersion();
RadioInfo[] radios = bootVersionRadio.getRadios();
for (RadioInfo option : radios) {
if (AddStartersInitializrService.isRelease(option.getValue())) {
bootVersionRadio.setValue(option);
return;
}
}
fail("No boot versions found in the wizard. Unable to set the latest release version");
}
};
}
/**
* @return A wizard configurer that ensures the selected 'boot version' is at least
* a given version of boot.
*/
public static WizardConfigurer bootVersionAtLeast(final String wantedVersion) throws Exception {
final VersionRange WANTED_RANGE = new VersionRange(wantedVersion);
return new WizardConfigurer() {
@Override
public void apply(NewSpringBootWizardModel wizard) {
RadioGroup bootVersionRadio = wizard.getBootVersion();
RadioInfo selected = bootVersionRadio.getValue();
Version selectedVersion = getVersion(selected);
if (WANTED_RANGE.includes(selectedVersion)) {
//existing selection is fine
} else {
//try to select the latest available version and verify it meets the requirement
bootVersionRadio.setValue(selected = getLatestVersion(bootVersionRadio, WANTED_RANGE));
selectedVersion = getVersion(selected);
Assert.isTrue(WANTED_RANGE.includes(selectedVersion));
}
}
private RadioInfo getLatestVersion(RadioGroup bootVersionRadio, VersionRange versionRange) {
RadioInfo[] infos = bootVersionRadio.getRadios();
Arrays.sort(infos, new Comparator<RadioInfo>() {
@Override
public int compare(RadioInfo o1, RadioInfo o2) {
Version v1 = getVersion(o1);
Version v2 = getVersion(o2);
return v2.compareTo(v1);
}
});
for (int i = 0; i < infos.length; i++) {
if (versionRange == null || versionRange.includes(getVersion(infos[i]))) {
return infos[i];
}
}
return null;
}
private Version getVersion(RadioInfo info) {
String versionString = info.getValue();
Version v = new Version(versionString);
if ("BUILD-SNAPSHOT".equals(v.getQualifier())) {
// Caveat "M1" will be treated as 'later' than "BUILD-SNAPSHOT" so that is wrong.
return new Version(v.getMajor(), v.getMinor(), v.getMicro(), "SNAPSHOT"); //Comes after "MX" but before "RELEASE"
}
return v;
}
};
}
public IProject createBootWebProject(final String projectName, final WizardConfigurer... extraConfs) throws Exception {
return createBootProject(projectName, merge(extraConfs, withStarters("web")));
}
private WizardConfigurer[] merge(WizardConfigurer[] confs, WizardConfigurer... moreConfs) {
WizardConfigurer[] merged = new WizardConfigurer[confs.length + moreConfs.length];
System.arraycopy(confs, 0, merged, 0, confs.length);
System.arraycopy(moreConfs, 0, merged, confs.length, moreConfs.length);
return merged;
}
public IProject createBootProject(final String projectName, final WizardConfigurer... _extraConfs) throws Exception {
List<WizardConfigurer> extraConfs = new ArrayList<>(Arrays.asList(_extraConfs));
IVMInstall2 jvm = (IVMInstall2) JavaRuntime.getDefaultVMInstall();
String version = jvm.getJavaVersion();
if (version.startsWith("1.8.")) {
System.out.println("Warning! Workspace JRE is Java 8. Downgrading test project");
extraConfs.add(withJavaVersion("1.8"));
}
try {
RetryUtil.retryWhen("createBootProject("+projectName+")", 3, RetryUtil.errorWithMsg("Read timed out"), () -> {
final Job job = new Job("Create boot project '"+projectName+"'") {
@Override
protected IStatus run(IProgressMonitor monitor) {
try {
//No point doing a retry if we will just fail because project already exists!
IProject p = getProject(projectName);
if (p.exists()) {
p.delete(true, true, new NullProgressMonitor());
}
NewSpringBootWizardModel wizard = new NewSpringBootWizardModel(new MockPrefsStore());
wizard.allowUIThread(true);
wizard.getProjectName().setValue(projectName);
wizard.getArtifactId().setValue(projectName);
//Note: unlike most of the rest of the wizard's behavior, the 'use default location'
// checkbox and its effect is not part of the model but part of the GUI code (this is
// wrong, really, but that's how it is, so we have to explictly set the project
// location in the model.
wizard.getLocation().setValue(getDefaultProjectLocation(projectName));
for (WizardConfigurer extraConf : extraConfs) {
extraConf.apply(wizard);
}
RadioInfo[] radios = wizard.getBootVersion().getRadios();
List<String> supportedBootVersions = new ArrayList<>();
String latestRelease = null;
for (RadioInfo info : radios) {
supportedBootVersions.add(info.getValue());
if (latestRelease == null && AddStartersInitializrService.isRelease(info.getValue())) {
latestRelease = info.getValue();
}
}
BootProjectTestHarness.this.latestReleaseVersion = latestRelease;
BootProjectTestHarness.this.supportedBootVersions = supportedBootVersions.toArray(new String[0]);
wizard.performFinish(new NullProgressMonitor()/*new SysOutProgressMonitor()*/);
return Status.OK_STATUS;
} catch (Throwable e) {
return ExceptionUtil.status(e);
}
}
};
//job.setRule(workspace.getRuleFactory().buildRule());
job.schedule();
waitForImportJob(getProject(projectName), job);
});
return getProject(projectName);
} finally {
CodeSet.afterCreateHook = null;
}
}
public static void waitForImportJob(final IProject project, final Job job) throws Exception {
new ACondition("Wait for import of "+project.getName(), BOOT_PROJECT_CREATION_TIMEOUT) {
@Override
public boolean test() throws Exception {
assertOk(job.getResult());
if (project.hasNature("org.eclipse.m2e.core.maven2Nature")) {
updateMavenProjectDependencies(project);
}
StsTestUtil.assertNoErrors(project);
return true;
}
};
}
public IProject getProject(String projectName) {
return workspace.getRoot().getProject(projectName);
}
public static void updateMavenProjectDependencies(IProject project) throws InterruptedException {
// debug("updateMavenProjectDependencies("+project.getName()+") ...");
boolean refreshFromLocal = true;
boolean cleanProjects = true;
boolean updateConfig = true;
IProject[] projects = {project};
boolean offline = false;
boolean forceUpdateDeps = true;
UpdateMavenProjectJob job = new UpdateMavenProjectJob(projects, offline, forceUpdateDeps,
updateConfig, cleanProjects, refreshFromLocal);
job.schedule();
job.join();
// debug("updateMavenProjectDependencies("+project.getName()+") DONE");
}
public static IProject createPredefinedMavenProject(final String projectName, final String bundleName)
throws CoreException, Exception {
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
if (project.exists()) {
return project;
}
StsTestUtil.setAutoBuilding(false);
ImportConfiguration importConf = new ImportConfiguration() {
@Override
public String getProjectName() {
return projectName;
}
@Override
public String getLocation() {
return ResourcesPlugin.getWorkspace().getRoot().getLocation().append(projectName).toString();
}
@Override
public CodeSet getCodeSet() {
File sourceWorkspace = new File(StsTestUtil.getSourceWorkspacePath(bundleName));
File sourceProject = new File(sourceWorkspace, projectName);
return new CopyFromFolder(projectName, sourceProject);
}
};
final IRunnableWithProgress importOp = BuildType.MAVEN.getDefaultStrategy().createOperation(importConf);
Job runner = new Job("Import "+projectName) {
@Override
protected IStatus run(IProgressMonitor monitor) {
try {
importOp.run(monitor);
} catch (Throwable e) {
return ExceptionUtil.status(e);
}
return Status.OK_STATUS;
}
};
runner.setRule(ResourcesPlugin.getWorkspace().getRuleFactory().buildRule());
runner.schedule();
waitForImportJob(project, runner);
// BootProjectTestHarness.assertNoErrors(project);
return project;
}
public static void buildMavenProject(IProject p) throws Exception {
ISpringBootProject bp = SpringBootCore.create(p);
updateMavenProjectDependencies(bp.getProject());
bp.getProject().build(IncrementalProjectBuilder.FULL_BUILD, new NullProgressMonitor());
}
public static void assertOk(IStatus result) throws Exception {
if (result==null || !result.isOK()) {
throw ExceptionUtil.coreException(result);
}
}
/**
* Create the most basic project possible. It has no natures, no builders, not nothing.
* This project is suitable as a test fixture for a test that only needs a project to
* exist and nothing more.
*/
public IProject createProject(String projectName) throws Exception {
IProject project = workspace.getRoot().getProject(projectName);
project.create(new NullProgressMonitor());
project.open(new NullProgressMonitor());
return project;
}
public IProject rename(IProject project, String newName) throws Exception {
IProjectDescription description = project.getDescription();
description.setName(newName);
project.move(description, true, new NullProgressMonitor());
return workspace.getRoot().getProject(newName);
}
public String[] getInitializrSupportedBootVersions() {
if (supportedBootVersions == null) {
fail("Must first create a project before initializr supported versions are resolved.");
}
return supportedBootVersions;
}
public String getLatestBootReleaseVersion() {
if (latestReleaseVersion == null) {
fail("Must first create a project before latest boot version from initializr is resolved.");
}
return latestReleaseVersion;
}
}

View File

@@ -0,0 +1,29 @@
package org.springframework.ide.eclipse.boot.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import org.springframework.ide.eclipse.boot.core.BootPropertyTester;
import org.springframework.ide.eclipse.boot.util.version.VersionParser;
public class BootPropertyTesterTest {
@Test
public void getVersionFromJarName() {
//Example: (old format) spring-boot-starter-web-1.2.3.RELEASE.jar
// (new format) spring-boot-starter-web-2.4.0.jar
// (new format) spring-boot-starter-web-2.4.0-SNAPSHOT.jar
assertVersion("1.2.3.RELEASE", "spring-boot-starter-web-1.2.3.RELEASE.jar");
assertVersion("2.4.0", "spring-boot-starter-web-2.4.0.jar");
assertVersion("2.4.0-SNAPSHOT", "spring-boot-starter-web-2.4.0-SNAPSHOT.jar");
}
private void assertVersion(String versionStr, String jarName) {
String actualVersionStr = BootPropertyTester.getVersionFromJarName(jarName);
assertEquals(versionStr, actualVersionStr);
assertNotNull(VersionParser.DEFAULT.parse(actualVersionStr));
}
}

View File

@@ -0,0 +1,41 @@
/*******************************************************************************
* Copyright (c) 2018 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.test;
import static org.junit.Assert.assertEquals;
import org.springframework.ide.eclipse.boot.core.initializr.InitializrServiceSpec.Dependency;
import org.springframework.ide.eclipse.boot.wizard.DependencyTooltipContent;
import org.junit.Test;
public class DependencyTooltipContentTest {
@Test public void generateRequirementTooltip_common_cases() throws Exception {
assertTooltip("Requires Spring Boot >=1.0.0", "1.0.0");
assertTooltip("Requires Spring Boot >=1.0.0 and <=2.0.0", "[1.0.0,2.0.0]");
assertTooltip("Requires Spring Boot >=1.0.0 and <2.0.0", "[1.0.0,2.0.0)");
assertTooltip("Requires Spring Boot >1.0.0 and <2.0.0", "(1.0.0,2.0.0)");
}
@Test public void generateRequirementTooltip_edge_cases() throws Exception {
assertTooltip(null, null);
assertTooltip(null, "");
assertEquals(null, DependencyTooltipContent.generateRequirements(null));
}
private void assertTooltip(String expectedTooltip, String versionRange) {
Dependency dep = new Dependency();
dep.setVersionRange(versionRange);
assertEquals(expectedTooltip, DependencyTooltipContent.generateRequirements(dep));
}
}

View File

@@ -0,0 +1,777 @@
///*******************************************************************************
// * Copyright (c) 2015, 2020 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
// * https://www.eclipse.org/legal/epl-v10.html
// *
// * Contributors:
// * Pivotal, Inc. - initial API and implementation
// *******************************************************************************/
//package org.springframework.ide.eclipse.boot.test;
//
//import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.ARTIFACT_ID;
//import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.DEPENDENCIES;
//import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.DEPENDENCY;
//import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.DEPENDENCY_MANAGEMENT;
//import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.GROUP_ID;
//import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.SCOPE;
//import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.TYPE;
//import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.VERSION;
//import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.childEquals;
//import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.findChild;
//import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.findChilds;
//import static org.junit.Assert.assertEquals;
//import static org.junit.Assert.assertNotNull;
//import static org.junit.Assert.assertNull;
//import static org.junit.Assert.fail;
//import static org.springframework.ide.eclipse.boot.test.BootProjectTestHarness.bootVersion;
//import static org.springframework.ide.eclipse.boot.test.BootProjectTestHarness.withStarters;
//import static org.springframework.ide.eclipse.boot.util.PomUtils.getArtifactId;
//import static org.springframework.ide.eclipse.boot.util.PomUtils.getGroupId;
//import static org.springframework.ide.eclipse.boot.util.PomUtils.getScope;
//import static org.springframework.ide.eclipse.boot.util.PomUtils.getTextChild;
//
//import java.util.ArrayList;
//import java.util.Arrays;
//import java.util.Collection;
//import java.util.HashMap;
//import java.util.HashSet;
//import java.util.List;
//import java.util.Map;
//import java.util.Map.Entry;
//import java.util.Set;
//import java.util.stream.Collectors;
//import java.util.stream.Stream;
//
//import org.apache.commons.lang3.tuple.Pair;
//import org.eclipse.core.resources.IProject;
//import org.eclipse.core.runtime.jobs.Job;
//import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
//import org.junit.AfterClass;
//import org.junit.Before;
//import org.junit.BeforeClass;
//import org.junit.Ignore;
//import org.junit.Rule;
//import org.junit.Test;
//import org.springframework.ide.eclipse.boot.core.ISpringBootProject;
//import org.springframework.ide.eclipse.boot.core.MavenId;
//import org.springframework.ide.eclipse.boot.core.SpringBootCore;
//import org.springframework.ide.eclipse.boot.core.initializr.InitializrService;
//import org.springframework.ide.eclipse.boot.core.initializr.InitializrServiceSpec.Dependency;
//import org.springframework.ide.eclipse.boot.test.util.TestBracketter;
//import org.springframework.ide.eclipse.boot.wizard.CheckBoxesSection.CheckBoxModel;
//import org.springframework.ide.eclipse.boot.wizard.NewSpringBootWizardModel;
//import org.springframework.ide.eclipse.boot.wizard.PopularityTracker;
//import org.springframework.ide.eclipse.boot.wizard.starters.AddStartersInitializrService;
//import org.springframework.ide.eclipse.boot.wizard.starters.AddStartersPreferences;
//import org.springframework.ide.eclipse.boot.wizard.starters.AddStartersWizardModel;
//import org.springsource.ide.eclipse.commons.frameworks.core.util.IOUtil;
//import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil;
//import org.springsource.ide.eclipse.commons.tests.util.StsTestUtil;
//import org.w3c.dom.Element;
//
//import com.google.common.collect.ImmutableSet;
//
//import junit.framework.AssertionFailedError;
//
///**
// * @author Kris De Volder
// */
//@SuppressWarnings("restriction")
//public class EditStartersModelTest extends AddStartersTestHarness {
//
// private static final String REPOSITORY = "repository";
// private static final String REPOSITORIES = "repositories";
//
//
// private static boolean wasAutobuilding;
//
// @BeforeClass
// public static void setupClass() throws Exception {
// wasAutobuilding = StsTestUtil.isAutoBuilding();
// StsTestUtil.setAutoBuilding(false);
// }
//
// @AfterClass
// public static void teardownClass() throws Exception {
// StsTestUtil.setAutoBuilding(wasAutobuilding);
// }
//
// @Before
// public void setup() throws Exception {
// StsTestUtil.cleanUpProjects();
// }
//
// @Rule
// public TestBracketter testBracketer = new TestBracketter();
//
//
//
// /**
// * Tests that we are able to remove a starter.
// */
// @Test
// public void removeStarter() throws Exception {
// IProject project = harness.createBootProject("removeStarter", withStarters("web", "actuator"));
// String starterZipFile = STARTER_ZIP_WEB_ACTUATOR;
// String validInitializrUrl = MOCK_VALID_INITIALIZR_URL;
// String[] supportedBootVersions = SUPPORTED_BOOT_VERSIONS;
// String[] dependenciesToSelect = new String[] {"web", "actuator"};
//
//
// InitializrService wrappedService = new MockInitializrService(supportedBootVersions, mavenStartersHarness,
// INITIALIZR_INFO_INPUT);
//
// ISpringBootProject bootProject = new SpringBootCore(wrappedService).project(project);
//
// AddStartersInitializrService initializrService = new MockAddStartersInitializrService(starterZipFile,
// validInitializrUrl, supportedBootVersions, dependenciesToSelect, (MockInitializrService)wrappedService);
// AddStartersPreferences preferences = createPreferences(validInitializrUrl, prefs);
// AddStartersWizardModel wizard = createAndLoadWizard(project, preferences, initializrService,
// dependenciesToSelect);
//
//
// initializrHarness.assertStarterDeps(wizard.dependencies.getCurrentSelection(), "web", "actuator");
//
// wizard.removeDependency("web");
// initializrHarness.assertStarterDeps(wizard.dependencies.getCurrentSelection(), /* removed: "web",*/ "actuator");
// performOk(wizard);
//
// StsTestUtil.assertNoErrors(project); //force project build
//
// initializrHarness.assertStarters(bootProject.getBootStarters(), "actuator");
// }
//
// private void performOk(EditStartersModel wizard) throws Exception {
// wizard.performOk();
// Job.getJobManager().join(EditStartersModel.JOB_FAMILY, null);
// }
//
// @Test
// public void crossSelection() throws Exception {
// //Test case derived from bug report: https://www.pivotaltracker.com/story/show/157257493
//
// IProject project = harness.createBootProject("cross-select", withStarters());
// initializrHarness.assertMavenDeps(project,
// "org.springframework.boot:spring-boot-starter",
// "org.springframework.boot:spring-boot-starter-test@test"
// );
//
// { //Add 'cloud-stream'
// EditStartersModel wizard = createWizard(project);
// initializrHarness.assertStarterDeps(wizard.dependencies.getCurrentSelection() /*NONE*/);
// wizard.addDependency("cloud-stream");
// performOk(wizard);
// StsTestUtil.assertNoErrors(project); //force project build
//
// initializrHarness.assertMavenDeps(project,
// "org.springframework.cloud:spring-cloud-stream",
// "org.springframework.boot:spring-boot-starter-test@test",
// "org.springframework.cloud:spring-cloud-stream-test-support@test" //comes in automatically with spring-cloud-stream
// );
// }
//
//
// { //Add 'rabbitmq'
// EditStartersModel wizard = createWizard(project);
// initializrHarness.assertStarterDeps(wizard.dependencies.getCurrentSelection(), "cloud-stream");
// wizard.addDependency("amqp");
// performOk(wizard);
// StsTestUtil.assertNoErrors(project); //force project build
//
// initializrHarness.assertMavenDeps(project,
// //old:
// "org.springframework.cloud:spring-cloud-stream",
// "org.springframework.boot:spring-boot-starter-test@test",
// "org.springframework.cloud:spring-cloud-stream-test-support@test",
// //added:
// "org.springframework.boot:spring-boot-starter-amqp", //by user selection (amqp)
// "org.springframework.amqp:spring-rabbit-test@test", //by user selection (amqp)
// "org.springframework.cloud:spring-cloud-stream-binder-rabbit" // cross-selection from rabbit + spring-cloud-stream
// );
// }
// }
//
// @Test
// public void addCloudFunctionWebDependency() throws Exception {
// //Test case derived from bug report: https://github.com/spring-projects/sts4/issues/313
// IProject project;
//
// project = harness.createBootProject("web-function", withStarters("webflux"));
// initializrHarness.assertMavenDeps(project,
// "io.projectreactor:reactor-test@test",
// "org.springframework.boot:spring-boot-starter-test@test",
// "org.springframework.boot:spring-boot-starter-webflux"
// );
// initializrHarness.assertBoms(project /*NONE*/);
//
// EditStartersModel wizard = createWizard(project);
// wizard.addDependency("cloud-function");
// performOk(wizard);
//
// System.out.println(">>> pom.xml (after dialog closed)");
// System.out.println(IOUtil.toString(project.getFile("pom.xml").getContents()));
// System.out.println("<<< pom.xml (after dialog closed)");
//
// StsTestUtil.assertNoErrors(project); //force project build
//
// initializrHarness.assertMavenDeps(project,
// "io.projectreactor:reactor-test@test",
// "org.springframework.boot:spring-boot-starter-test@test",
// "org.springframework.boot:spring-boot-starter-webflux",
// "org.springframework.cloud:spring-cloud-function-web"
// );
//
// initializrHarness.assertBoms(project, "org.springframework.cloud:spring-cloud-dependencies");
// }
//
// //Unfortunately this test takes much too long to run to be practical. There's 6961 pairs to check,
// // each pair creates and imports the project to verify the 'reverse' pom analysis returns
// // the initial selection. This takes 3 to 4 seconds each. So to this test would take around
// // 6 to 7 hours to run.
// // If we want to make this test more practical we would have to try and implement it more directly
// // (using only the pom and metadata from initializer app) and not do a full on maven project
// // creation (this is what takes most of the time).
// // In the mean time this test has been replaced with a more focussed test, see focussedCrossSelectionTest
// // below.
// @Test
// @Ignore
// public void exhaustiveCrossSelectionTest() throws Exception {
// //Creates a project for every possible pairs of two dependencies. Then verifies whether we
// //EditStartersModel correctly detects that pair as 'selected'.
// List<Pair<CheckBoxModel<Dependency>, CheckBoxModel<Dependency>>> allPairs = allDependencyPairs();
// doMultiplCrossSelectionTests(allPairs);
// }
//
// private List<Pair<CheckBoxModel<Dependency>, CheckBoxModel<Dependency>>> allDependencyPairs() throws Exception {
// NewSpringBootWizardModel newWizard = new NewSpringBootWizardModel(new MockPrefsStore());
// Collection<CheckBoxModel<Dependency>> allDependencies = newWizard.dependencies.getAllBoxes();
// List<Pair<CheckBoxModel<Dependency>, CheckBoxModel<Dependency>>> allPairs = new ArrayList<>();
// for (CheckBoxModel<Dependency> cb1 : allDependencies) {
// for (CheckBoxModel<Dependency> cb2 : allDependencies) {
// Dependency d1 = cb1.getValue();
// Dependency d2 = cb2.getValue();
// if (d1.getId().compareTo(d2.getId())<=0) {
// allPairs.add(Pair.of(cb1, cb2));
// }
// }
// }
// return allPairs;
// }
//
// @Test
// @Ignore //Not normally run during builds to save some time. You can run it manually
// // to determine the values of the 'badIds' in 'focussedCrossSelectionTest'.
// // If this test passes then the badIds is empty. Otherwise, you can chech the failure message
// // to see which ids result in project import issues, if they are not already on the list
// // report them to the intializer team.
// public void isolatedDependencies() throws Exception {
// doMultiplCrossSelectionTests(allDependencyPairs().stream().filter(pair -> pair.getLeft().equals(pair.getRight())).collect(Collectors.toList()));
// }
//
// @Test
// public void webAndFunctionCrossSelectionTest() throws Exception {
// NewSpringBootWizardModel newWizard = new NewSpringBootWizardModel(new MockPrefsStore());
// doSingleCrossSelectionTest(newWizard.getDependencyBox("cloud-function"), newWizard.getDependencyBox("web"));
// }
//
// @Test
// @Ignore //Initializer folks want us to discontinue this feaure so why worry about it's test any more?
// public void focussedCrossSelectionTest() throws Exception {
// ImmutableSet<String> badIds = ImmutableSet.of(
// //See: https://github.com/spring-io/start.spring.io/issues/191
// //"cloud-starter-zookeeper-config", "cloud-starter-consul-config", "data-rest-hal"
// );
//
// ImmutableSet<Pair<String,String>> badPairs = ImmutableSet.of();
//
// ImmutableSet<String> interestingIds = ImmutableSet.of(
// "cloud-function", "session"
// );
//
// Stream<Pair<CheckBoxModel<Dependency>, CheckBoxModel<Dependency>>> webPairs = allDependencyPairs().stream()
// .filter(pair ->
// interestingIds.contains(pair.getLeft().getValue().getId()) ||
// interestingIds.contains(pair.getRight().getValue().getId())
//// )
//// .filter(pair ->
//// !badIds.contains(pair.getLeft().getValue().getId()) &&
//// !badIds.contains(pair.getRight().getValue().getId())
// );
// doMultiplCrossSelectionTests(webPairs.collect(Collectors.toList()), badIds, badPairs);
// }
//
// private void doMultiplCrossSelectionTests(Collection<Pair<CheckBoxModel<Dependency>,CheckBoxModel<Dependency>>> pairs) {
// doMultiplCrossSelectionTests(pairs, ImmutableSet.of(), ImmutableSet.of());
// }
//
// private void doMultiplCrossSelectionTests(Collection<Pair<CheckBoxModel<Dependency>,CheckBoxModel<Dependency>>> pairs, ImmutableSet<String> expectedBadIds, ImmutableSet<Pair<String,String>> expectedBadPairs) {
// Map<Pair<Dependency, Dependency>, String> badPairs = new HashMap<>();
// Set<String> actualBadIds = new HashSet<>();
// System.out.println("Number of pairs to test: "+pairs.size());
// int testedPairs = 0;
// for (Pair<CheckBoxModel<Dependency>, CheckBoxModel<Dependency>> pair : pairs) {
// try {
// testedPairs++;
// System.out.println(testedPairs+"/"+pairs.size()+": "+describe(pair.getLeft().getValue())+" + "+describe(pair.getRight().getValue()));
// doSingleCrossSelectionTest(pair.getLeft(), pair.getRight());
// } catch (Throwable e) {
// System.err.println(ExceptionUtil.getMessage(e));
// if (pair.getLeft().getValue().getId().equals(pair.getRight().getValue().getId())) {
// actualBadIds.add(pair.getLeft().getValue().getId());
// }
// boolean expectedProblem = expectedBadIds.contains(pair.getLeft().getValue().getId()) ||
// expectedBadIds.contains(pair.getRight().getValue().getId());
// if (!expectedProblem) {
// badPairs.put(Pair.of(pair.getLeft().getValue(), pair.getRight().getValue()), ExceptionUtil.getMessage(e));
// }
// }
// }
// ImmutableSet.Builder<Pair<String,String>> actualBadPairs = ImmutableSet.builder();
// for (Pair<Dependency, Dependency> badPair : badPairs.keySet()) {
// actualBadPairs.add(Pair.of(badPair.getLeft().getId(), badPair.getRight().getId()));
// }
//
// if (!expectedBadPairs.equals(actualBadPairs.build())) {
// StringBuilder message = new StringBuilder("--- Problem summary ----\n");
// for (Entry<Pair<Dependency, Dependency>, String> badEndtry : badPairs.entrySet()) {
// Pair<Dependency, Dependency> pair = badEndtry.getKey();
// message.append(describe(pair.getLeft()) +" + "+describe(pair.getRight())+": "+badEndtry.getValue());
// message.append("\n");
// }
// fail(message.toString());
// }
// assertEquals(expectedBadIds, actualBadIds);
// }
//
// private void doSingleCrossSelectionTest(
// CheckBoxModel<Dependency> cb1,
// CheckBoxModel<Dependency> cb2) throws Exception {
// Dependency d1 = cb1.getValue();
// Dependency d2 = cb2.getValue();
// String projectName = "test-"+d1.getId()+"-"+d2.getId();
// //Assuming that it doesn't matter what order two deps are selected so
// //only test one of a pairs (d1,d2) and (d2,d1)
// if (!cb1.getEnablement().getValue()) {
// System.out.println("Skipping because "+d1+" is not enabled");
// return;
// }
// if (!cb2.getEnablement().getValue()) {
// System.out.println("Skipping because "+d2+" is not enabled");
// return;
// }
// Set<String> starters = new HashSet<>(Arrays.asList(d1.getId(), d2.getId()));
// try {
// IProject project;
// try {
// project = harness.createBootProject(projectName, withStarters(starters.toArray(new String[starters.size()])));
// } catch (Throwable e) {
// throw new AssertionFailedError("Project creation failed");
// }
// EditStartersModel wizard = createWizard(project);
// Set<String> selectedDeps = wizard.dependencies.getCurrentSelection().stream().map(d -> d.getId()).collect(Collectors.toSet());
// assertEquals(starters, selectedDeps);
// System.out.println("OK");
// } finally {
// StsTestUtil.deleteAllProjects();
// }
// }
//
// private String describe(Dependency d) {
// return d.getId() +"["+d.getName()+"]";
// }
//
// /**
// * Tests that we are able to add a basic starter.
// */
// @Test
// public void addStarter() throws Exception {
// IProject project = harness.createBootProject("addStarter", withStarters("web"));
// final ISpringBootProject bootProject = springBootCore.project(project);
// EditStartersModel wizard = createWizard(project);
// assertEquals(bootProject.getBootVersion(), wizard.getBootVersion());
// initializrHarness.assertStarterDeps(wizard.dependencies.getCurrentSelection(), "web");
//
// PopularityTracker popularities = new PopularityTracker(prefs);
// initializrHarness.assertUsageCounts(bootProject, popularities /*none*/);
//
// wizard.addDependency("actuator");
// initializrHarness.assertStarterDeps(wizard.dependencies.getCurrentSelection(), "web", "actuator");
// performOk(wizard);
//
// initializrHarness.assertUsageCounts(bootProject, popularities, "actuator:1");
//
// StsTestUtil.assertNoErrors(project); //force project build
//
// initializrHarness.assertStarters(bootProject.getBootStarters(), "web", "actuator");
//
// //check that the 'scope' is not set in the pom.xml:
// IDOMDocument pom = initializrHarness.parsePom(project);
//
// Element depEl = initializrHarness.findDependency(bootProject, pom, "actuator");
// assertEquals("org.springframework.boot", getGroupId(depEl));
// assertEquals("spring-boot-starter-actuator", getArtifactId(depEl));
// assertEquals(null, getScope(depEl));
// }
//
// @Test
// public void addStarterWithTestScope() throws Exception {
// IProject project = harness.createBootProject("addStarterWithTestScope", withStarters("web"));
// final ISpringBootProject bootProject = springBootCore.project(project);
// EditStartersModel wizard = createWizard(project);
// wizard.addDependency("restdocs");
// performOk(wizard);
//
// StsTestUtil.assertNoErrors(project); //force project build
//
// initializrHarness.assertStarters(bootProject.getBootStarters(), "web", "restdocs");
//
// //check that the 'scope' is set properly
// IDOMDocument pom = initializrHarness.parsePom(project);
// Element depEl = initializrHarness.findDependency(bootProject, pom, "restdocs");
// assertEquals("spring-restdocs-mockmvc", getArtifactId(depEl));
// assertEquals("test", getScope(depEl));
// }
//
// @Test
// public void addStarterWithBom() throws Exception {
//// We'll be adding this starter:
//// "id": "cloud-eureka",
//// "groupId": "org.springframework.cloud",
//// "artifactId": "spring-cloud-starter-eureka",
//// "scope": "compile",
//// "bom": "cloud-bom"
//
// IProject project = harness.createBootProject("addStarterWithBom", withStarters("web"));
// final ISpringBootProject bootProject = springBootCore.project(project);
// EditStartersModel wizard = createWizard(project);
// wizard.addDependency("cloud-eureka");
// performOk(wizard);
//
// System.out.println(">>> pom.xml (after dialog closed)");
// System.out.println(IOUtil.toString(project.getFile("pom.xml").getContents()));
// System.out.println("<<< pom.xml (after dialog closed)");
//
// StsTestUtil.assertNoErrors(project); //force project build
//
// initializrHarness.assertStarters(bootProject.getBootStarters(), "web", "cloud-eureka");
// }
//
// @Test
// public void addMultipleStartersWithSameBom() throws Exception {
// //This test uses more 'controlled' parameters:
// IProject project = harness.createBootProject("addMultipleStartersWithSameBom",
// bootVersion(BOOT_CURRENT_RELEASE), // boot version fixed
// withStarters("web")
// );
// initializr.setInputs("sample"); // sample intializr json captured for this version
// final ISpringBootProject bootProject = springBootCore.project(project);
// int initialBomCount = getBomCount(initializrHarness.parsePom(project));
//
// EditStartersModel wizard = createWizard(project);
// wizard.addDependency("cloud-eureka");
// wizard.addDependency("cloud-config-client");
// performOk(wizard);
//
// StsTestUtil.assertNoErrors(project); //force project build
//
// initializrHarness.assertStarters(bootProject.getBootStarters(), "web", "cloud-eureka", "cloud-config-client");
//
// IDOMDocument pom = initializrHarness.parsePom(project);
// int finalBomCount = getBomCount(pom);
// assertEquals(initialBomCount+1, finalBomCount);
//
// //check that one repo got added
// assertRepoCount(1, pom);
//
//// Element repo = getRepo(pom, "spring-snapshots");
//// assertNotNull(repo);
//// assertEquals("Spring Snapshots", getTextChild(repo, "name"));
//// assertEquals("https://repo.spring.io/snapshot", getTextChild(repo, "url"));
//// assertEquals("true", getSnapshotsEnabled(repo));
//
// Element repo = getRepo(pom, "spring-milestones");
// assertNotNull(repo);
// assertEquals("Spring Milestones", getTextChild(repo, "name"));
// assertEquals("https://repo.spring.io/milestone", getTextChild(repo, "url"));
// assertEquals("false", getSnapshotsEnabled(repo));
// }
//
// @Test
// public void addMultipleStartersWithDifferentBom() throws Exception {
// //This test uses more 'controlled' parameters:
// IProject project = harness.createBootProject("addMultipleStartersWithDifferentBom",
// bootVersion(BOOT_CURRENT_RELEASE), // boot version fixed
// withStarters("web")
// );
// initializr.setInputs("sample"); // sample intializr json captured for this version
// initializr.enableFakePomGenerator();
// final ISpringBootProject bootProject = springBootCore.project(project);
// int initialBomCount = getBomCount(initializrHarness.parsePom(project));
// StsTestUtil.assertNoErrors(project); //force project build
//
// EditStartersModel wizard = createWizard(project);
// wizard.addDependency("cloud-eureka");
// wizard.addDependency("vaadin");
// performOk(wizard);
//
//// System.out.println("-- pom after ---");
//// System.out.println(IOUtil.toString(project.getFile("pom.xml").getContents()));
//
//// Note Doing 'fake' stuff causes broken project. So the below will fail. We should test
//// pom content more directly for this test.
//// StsTestUtil.assertNoErrors(project); //force project build
//// assertStarters(bootProject.getBootStarters(), "web", "cloud-eureka", "vaadin");
//
// IDOMDocument pom = initializrHarness.parsePom(project);
// initializrHarness.assertMavenDeps(project,
// "org.springframework.boot:spring-boot-starter-web",
// "org.springframework.boot:spring-boot-starter-test@test",
// "org.springframework.cloud:spring-cloud-starter-netflix-eureka-client",
// "com.vaadin:vaadin-spring-boot-starter"
// );
// int finalBomCount = getBomCount(pom);
// assertEquals(initialBomCount+2, finalBomCount);
// {
// Element bom = getBom(pom, "spring-cloud-dependencies");
// assertEquals("org.springframework.cloud", getTextChild(bom,GROUP_ID));
// assertEquals("Finchley.RC2", getTextChild(bom,VERSION));
// assertEquals("pom", getTextChild(bom,TYPE));
// assertEquals("import", getTextChild(bom,SCOPE));
// }
// {
// Element bom = getBom(pom, "vaadin-bom");
// assertEquals("com.vaadin", getTextChild(bom,GROUP_ID));
// assertEquals("8.4.1", getTextChild(bom,VERSION));
// assertEquals("pom", getTextChild(bom,TYPE));
// assertEquals("import", getTextChild(bom,SCOPE));
// }
// }
//
// @Test
// public void addBomWithSubsetOfRepos() throws Exception {
// //This test uses more 'controlled' parameters:
// String bootVersion = BOOT_CURRENT_RELEASE;
// IProject project = harness.createBootProject("addBomWithSubsetOfRepos",
// bootVersion(bootVersion), // boot version fixed
// withStarters("web")
// );
//
// initializr.setInputs("sample-with-fakes"); // must use 'fake' data because the situation we are after doesn't exist in the real data
// initializr.enableFakePomGenerator();
//
// EditStartersModel wizard = createWizard(project);
// wizard.addDependency("cloud-eureka");
// performOk(wizard);
//
// System.out.println("-- pom after ---");
// System.out.println(IOUtil.toString(project.getFile("pom.xml").getContents()));
//
// //!!! fake data may not produce a project that builds without
// //!!! problem so don't check for build errors in this test
//
// //check that only ONE repo got added
// IDOMDocument pom = initializrHarness.parsePom(project);
//
// //check the dependency got added to the pom
// assertNotNull(initializrHarness.findDependency(pom, new MavenId("org.springframework.cloud", "spring-cloud-starter-eureka")));
//
// //check that both repos got added
// assertRepoCount(2, pom);
//
// Element repo = getRepo(pom, "spring-snapshots");
// assertNotNull(repo);
// assertEquals("Spring Snapshots", getTextChild(repo, "name"));
// assertEquals("https://repo.spring.io/snapshot", getTextChild(repo, "url"));
// assertEquals("true", getSnapshotsEnabled(repo));
//
// repo = getRepo(pom, "spring-milestones");
// assertNotNull(repo);
// assertEquals("Spring Milestones", getTextChild(repo, "name"));
// assertEquals("https://repo.spring.io/milestone", getTextChild(repo, "url"));
// assertEquals("false", getSnapshotsEnabled(repo));
// }
//
// @Test
// public void addDependencyWithRepo() throws Exception {
// //This test uses more 'controlled' parameters:
// String bootVersion = BOOT_CURRENT_RELEASE;
// IProject project = harness.createBootProject("addDependencyWithRepo",
// bootVersion(bootVersion), // boot version fixed
// withStarters("web")
// );
//
// initializr.setInputs("sample-with-fakes"); // must use 'fake' data because the situation we are after doesn't exist in the real data
// initializr.enableFakePomGenerator();
//
// EditStartersModel wizard = createWizard(project);
// wizard.addDependency("fake-dep");
// performOk(wizard);
//
// //!!! fake data may not produce a project that builds without
// //!!! problem so don't check for build errors in this test
//
// IDOMDocument pom = initializrHarness.parsePom(project);
//
// //check the dependency got added to the pom
// assertNotNull(initializrHarness.findDependency(pom, new MavenId("org.springframework.fake", "spring-fake-dep")));
//
// //check that just the expected repo got added
// assertNotNull(getRepo(pom, "spring-milestones"));
// assertNull(getRepo(pom, "spring-snapshots"));
// assertRepoCount(1, pom);
// }
//
// @Test
// public void unselectAllDependencies() throws Exception {
// //See: https://github.com/spring-projects/sts4/issues/52
// IProject project = harness.createBootProject("projectToUnselectoAll", withStarters("web", "actuator"));
// StsTestUtil.assertNoErrors(project); //force project build
//
// EditStartersModel wizard = createAndLoadWizard(project);
// wizard.removeDependency("web");
// wizard.removeDependency("actuator");
//
// performOk(wizard);
//
// final ISpringBootProject bootProject = springBootCore.project(project);
// StsTestUtil.assertNoErrors(project);
// initializrHarness.assertStarters(bootProject.getBootStarters() /*NONE*/);
//
// IDOMDocument pom = initializrHarness.parsePom(project);
// assertNotNull(initializrHarness.findDependency(pom, new MavenId("org.springframework.boot", "spring-boot-starter")));
// }
//
// @Test
// public void addDependenciesFromEmpty() throws Exception {
// //See: https://github.com/spring-projects/sts4/issues/52
// IProject project = harness.createBootProject("projectToUnselectoAll");
// final ISpringBootProject bootProject = springBootCore.project(project);
// StsTestUtil.assertNoErrors(project); //force project build
// initializrHarness.assertStarters(bootProject.getBootStarters() /*NONE*/);
// { //Check the state of the default dependencies
// IDOMDocument pom = initializrHarness.parsePom(project);
// assertNotNull(initializrHarness.findDependency(pom, new MavenId("org.springframework.boot", "spring-boot-starter")));
// assertEquals("test", getScope(initializrHarness.findDependency(pom, new MavenId("org.springframework.boot", "spring-boot-starter-test"))));
// }
//
// EditStartersModel wizard = createWizard(project);
// wizard.addDependency("web");
// wizard.addDependency("actuator");
//
//// System.out.println("-- pom before ---");
//// System.out.println(IOUtil.toString(project.getFile("pom.xml").getContents()));
//
// performOk(wizard);
//
//// System.out.println("-- pom after ---");
//// System.out.println(IOUtil.toString(project.getFile("pom.xml").getContents()));
//
// StsTestUtil.assertNoErrors(project);
// initializrHarness.assertStarters(bootProject.getBootStarters(), "web", "actuator");
// { //Check the state of the default dependencies
// IDOMDocument pom = initializrHarness.parsePom(project);
// assertNull(initializrHarness.findDependency(pom, new MavenId("org.springframework.boot", "spring-boot-starter")));
// assertEquals("test", getScope(initializrHarness.findDependency(pom, new MavenId("org.springframework.boot", "spring-boot-starter-test"))));
// }
// }
//
//// @Test
//// public void serviceUnavailable() throws Exception {
//// String bootVersion = BOOT_1_3_X_RELEASE;
//// IProject project = harness.createBootProject("serviceUnavailable",
//// bootVersion(bootVersion), // boot version fixed
//// withStarters("web")
//// );
////
//// initializr.makeUnavailable();
////
//// EditStartersModel wizard = createWizard(project);
//// assertFalse(wizard.isSupported());
//// }
//
// //TODO: testing of...
// // - repository field in individual dependency taken into account?
//
// ////////////// Harness code below ///////////////////////////////////////////////
//
//
// private String getSnapshotsEnabled(Element repo) {
// if (repo!=null) {
// Element snapshots = findChild(repo, "snapshots");
// if (snapshots!=null) {
// return getTextChild(snapshots, "enabled");
// }
// }
// return null;
// }
//
// private Element getRepo(IDOMDocument pom, String id) {
// Element doc = pom.getDocumentElement();
// Element repos = findChild(doc, REPOSITORIES);
// if (repos!=null) {
// return findChild(repos, REPOSITORY, childEquals("id", id));
// }
// return null;
// }
//
//
//
//
//
//
// private void assertRepoCount(int expect, IDOMDocument pom) {
// assertEquals(expect, getRepoCount(pom));
// }
//
// private int getRepoCount(IDOMDocument pom) {
// Element reposEl = findChild(pom.getDocumentElement(), REPOSITORIES);
// if (reposEl!=null) {
// List<Element> repos = findChilds(reposEl, REPOSITORY);
// if (repos!=null) {
// return repos.size();
// }
// }
// return 0;
// }
//
// /**
// * Find a bom element in pom based on its artifactId (can't use its own id as that isn't
// * found anywhere in the element's xml).
// */
// private Element getBom(IDOMDocument pom, String aid) {
// Element depman = findChild(pom.getDocumentElement(), DEPENDENCY_MANAGEMENT);
// if (depman!=null) {
// Element deps = findChild(depman, DEPENDENCIES);
// if (deps!=null) {
// return findChild(deps, DEPENDENCY, childEquals(ARTIFACT_ID, aid));
// }
// }
// return null;
// }
//
// private int getBomCount(IDOMDocument pom) {
// Element depman = findChild(pom.getDocumentElement(), DEPENDENCY_MANAGEMENT);
// if (depman!=null) {
// Element deps = findChild(depman, DEPENDENCIES);
// if (deps!=null) {
// List<Element> boms = findChilds(deps, DEPENDENCY);
// if (boms!=null) {
// return boms.size();
// }
// }
// }
// return 0;
// }
//
//
//
//
//
//
//
//
//
//
//}

View File

@@ -0,0 +1,123 @@
/*******************************************************************************
* Copyright (c) 2015, 2018 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.test;
import static org.junit.Assert.fail;
import static org.springframework.ide.eclipse.boot.test.BootProjectTestHarness.bootVersionAtLeast;
import static org.springframework.ide.eclipse.boot.test.BootProjectTestHarness.withStarters;
import java.util.List;
import java.util.Map;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.jface.viewers.StructuredSelection;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.ide.eclipse.boot.core.BootPropertyTester;
import org.springframework.ide.eclipse.boot.core.IMavenCoordinates;
import org.springframework.ide.eclipse.boot.core.ISpringBootProject;
import org.springframework.ide.eclipse.boot.core.SpringBootCore;
import org.springframework.ide.eclipse.boot.core.SpringBootStarters;
import org.springframework.ide.eclipse.boot.core.initializr.InitializrService;
import org.springframework.ide.eclipse.boot.ui.EnableDisableBootDevtools;
import org.springsource.ide.eclipse.commons.frameworks.test.util.ACondition;
import org.springsource.ide.eclipse.commons.tests.util.StsTestUtil;
public class EnableDisableBootDevtoolsTest {
//TODO: better test coverage for EnableDisableBootDevtools
private static final long MAVEN_POM_REFRESH_TIMEOUT = 3*60*1000;
/**
* We want the devtools enablement action not to depend on initializr service.
* So lets explicitly mock it with a 'unavalailable' service.
*/
private InitializrService initializr = new InitializrService() {
@Override
public SpringBootStarters getStarters(String bootVersion) {
return null;
}
@Override
public String getPom(Map<String, ?> parameters) throws Exception {
throw new UnsupportedOperationException();
}
};
private SpringBootCore springBootCore = new SpringBootCore(initializr);
private BootProjectTestHarness projects = new BootProjectTestHarness(ResourcesPlugin.getWorkspace());
private EnableDisableBootDevtools handler = new EnableDisableBootDevtools(springBootCore);
@Rule
public AutobuildingEnablement autobuilding = new AutobuildingEnablement(true);
@Before
public void setUp() throws Exception {
StsTestUtil.deleteAllProjects();
}
@Test
public void addBootDevtools() throws Exception {
final ISpringBootProject project = springBootCore.project(
projects.createBootWebProject("dev-starters-tester", bootVersionAtLeast("1.3.0")));
StructuredSelection selection = new StructuredSelection(new IProject[] {project.getProject() });
assertNoDependency(project.getDependencies(), BootPropertyTester.SPRING_BOOT_DEVTOOLS_GID, BootPropertyTester.SPRING_BOOT_DEVTOOLS_AID);
handler.execute(selection, null);
ACondition.waitFor("Wait for 'devtools' starter to be added", MAVEN_POM_REFRESH_TIMEOUT, () -> {
assertDependency(project.getDependencies(), BootPropertyTester.SPRING_BOOT_DEVTOOLS_GID, BootPropertyTester.SPRING_BOOT_DEVTOOLS_AID);
});
}
@Test
public void removeBootDevtools() throws Exception {
final ISpringBootProject project = springBootCore.project(
projects.createBootWebProject("dev-starters-tester",
bootVersionAtLeast("1.3.0"),
withStarters("devtools")
)
);
StructuredSelection selection = new StructuredSelection(new IProject[] {project.getProject() });
assertDependency(project.getDependencies(), BootPropertyTester.SPRING_BOOT_DEVTOOLS_GID, BootPropertyTester.SPRING_BOOT_DEVTOOLS_AID);
handler.execute(selection, null);
ACondition.waitFor("Wait for 'devtools' starter to be removed", MAVEN_POM_REFRESH_TIMEOUT, () -> {
assertNoDependency(project.getDependencies(), BootPropertyTester.SPRING_BOOT_DEVTOOLS_GID, BootPropertyTester.SPRING_BOOT_DEVTOOLS_AID);
});
}
///////////////////////////////////////////////////////////////////////////////
private void assertDependency(List<IMavenCoordinates> dependencies, String gid, String aid) {
for (IMavenCoordinates d : dependencies) {
if (gid.equals(d.getGroupId()) && aid.equals(d.getArtifactId())) {
return; //okay!
}
}
fail("No dependency "+gid+":"+aid+" in "+dependencies);
}
private void assertNoDependency(List<IMavenCoordinates> dependencies, String gid, String aid) {
for (IMavenCoordinates d : dependencies) {
if (gid.equals(d.getGroupId()) && aid.equals(d.getArtifactId())) {
fail("Dependency found but not expected "+gid+":"+aid+" in "+dependencies);
}
}
}
}

View File

@@ -0,0 +1,257 @@
/*******************************************************************************
* 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.jface.operation.IRunnableContext;
import org.junit.Test;
import org.springframework.ide.eclipse.boot.wizard.content.ContentManager;
import org.springframework.ide.eclipse.boot.wizard.content.ContentManager.DownloadState;
import org.springframework.ide.eclipse.boot.wizard.content.ContentType;
import org.springframework.ide.eclipse.boot.wizard.github.GithubClient;
import org.springframework.ide.eclipse.boot.wizard.guides.GSImportWizardModel;
import org.springsource.ide.eclipse.commons.frameworks.core.util.JobUtil;
import org.springsource.ide.eclipse.commons.frameworks.test.util.ACondition;
import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression;
import org.springsource.ide.eclipse.commons.livexp.core.LiveVariable;
import org.springsource.ide.eclipse.commons.livexp.core.ValueListener;
import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil;
public class GSGWizardModelTest {
@Test
public void testPrefetchingGettingStartedContent() throws Exception {
if (!isEnoughRateLimitAvailable()) {
System.out.println("Skipping testPrefetchingGettingStartedContent: not enough github api limit available!");
// skip test if we'r running low on github rest api rate limit.
return;
}
// Prefetching involves testing the download "states" for two different
// steps that occur in series (prefetching content provider properties,
// followed by prefetching actual content):
// 1. Not started any prefetching
// 2. Is downloading content provider properties
// 3. content provider properties downloading completed
// 4. content provider properties downloaded (final state)
// 5. is downloading actual content
// 6. actual content downloading completed (this tests a distinct state
// that is used for
// refreshing views right after a downloading session has completed)
// 7. actual content downloaded. This is a post-downloading "final"
// state
final GSImportWizardModel model = getModel();
final ContentManager contentManager = model.getContentManager();
// Test the prefetching content provider properties tracker
assertEquals(DownloadState.NOT_STARTED,
contentManager.getPrefetchContentProviderPropertiesTracker().getValue());
// Test the prefetching content tracker
assertEquals(DownloadState.NOT_STARTED, contentManager.getPrefetchContentTracker().getValue());
ContentType<?>[] types = contentManager.getTypes();
assertTrue("Expected no content types registered before prefetching.", types == null || types.length == 0);
List<?> allContent = getContent(types, contentManager);
assertTrue("Expected no content for getting started guides before prefetching.", allContent.size() == 0);
// States to test in order encountered by the listener
final List<DownloadState> actualContentPropertiesDownloadState = new ArrayList<>(0);
final List<DownloadState> actualContentDownloadStates = new ArrayList<>(0);
// Listener tests that each of the expected states occur during content
// provider properties downloading
ValueListener<DownloadState> contentProviderPropertiesDownloadStateListener = new ValueListener<DownloadState>() {
@Override
public void gotValue(LiveExpression<DownloadState> exp, DownloadState actualDownloadState) {
// Add states in the order they are received as the listener
// should be invoked multiple times during the prefetching
// operation
if (!actualContentPropertiesDownloadState.contains(actualDownloadState)) {
actualContentPropertiesDownloadState.add(actualDownloadState);
}
}
};
contentManager.getPrefetchContentProviderPropertiesTracker()
.addListener(contentProviderPropertiesDownloadStateListener);
// Listener tests that each of the expected states occur during content
// downloading
LiveVariable<Throwable> error = new LiveVariable<>(null);
ValueListener<DownloadState> contentDownloadStateListener = new ValueListener<DownloadState>() {
@Override
public void gotValue(LiveExpression<DownloadState> exp, DownloadState actualDownloadState) {
// Add states in the order they are received as the listener
// should be invoked multiple times during the prefetching
// operation
if (!actualContentDownloadStates.contains(actualDownloadState)) {
if (actualDownloadState==DownloadState.DOWNLOADING_FAILED) {
error.setValue(contentManager.getPrefetchContentError());
}
actualContentDownloadStates.add(actualDownloadState);
}
}
};
contentManager.getPrefetchContentTracker().addListener(contentDownloadStateListener);
// BEGIN ACTUAL PREFETCH
contentManager.prefetchInBackground(getRunnableContext());
// Test that the listener gets notified when content provider properties
// has been downloaded
new ACondition(30 * 1000) {
@Override
public boolean test() throws Exception {
if (actualContentPropertiesDownloadState.size() == 4) {
assertEquals(
"Expected the first state when prefetching content provider properties: "
+ DownloadState.NOT_STARTED,
actualContentPropertiesDownloadState.get(0), DownloadState.NOT_STARTED);
assertEquals(
"Expected the second state when prefetching content provider properties: "
+ DownloadState.IS_DOWNLOADING,
actualContentPropertiesDownloadState.get(1), DownloadState.IS_DOWNLOADING);
assertEquals(
"Expected the third state when prefetching content provider properties: "
+ DownloadState.DOWNLOADING_COMPLETED,
actualContentPropertiesDownloadState.get(2), DownloadState.DOWNLOADING_COMPLETED);
assertEquals(
"Expected the fourth state when prefetching content provider properties: "
+ DownloadState.DOWNLOADED,
actualContentPropertiesDownloadState.get(3), DownloadState.DOWNLOADED);
// Final state must be "post downloaded" states
assertEquals(
"Expected final download state for content provider properties to be: "
+ DownloadState.DOWNLOADED,
DownloadState.DOWNLOADED,
contentManager.getPrefetchContentProviderPropertiesTracker().getValue());
ContentType<?>[] types = contentManager.getTypes();
assertTrue("Expected content types for getting started guides after downloading completed.",
types != null && types.length > 0);
return true;
} else {
return false;
}
}
};
// Test that the listener gets notified when content has been downloaded
new ACondition(30 * 1000) {
@Override
public boolean test() throws Exception {
if (actualContentDownloadStates.contains(DownloadState.DOWNLOADING_FAILED)) {
Throwable e = contentManager.getPrefetchContentError();
if (e!=null) {
throw new RuntimeException("Problem downloading: ", e);
}
}
if (actualContentDownloadStates.size() == 4) {
assertEquals(
"First prefetching content download state", DownloadState.NOT_STARTED,
actualContentDownloadStates.get(0));
assertEquals(
"Second prefetching content download state", DownloadState.IS_DOWNLOADING,
actualContentDownloadStates.get(1));
assertEquals(
"Third prefetching content download state", DownloadState.DOWNLOADING_COMPLETED,
actualContentDownloadStates.get(2));
assertEquals(
"Fourth prefetching content download state", DownloadState.DOWNLOADED,
actualContentDownloadStates.get(3));
// Final state must be "post downloaded" state
assertEquals(
"Expected final download state for content provider properties to be: "
+ DownloadState.DOWNLOADED,
DownloadState.DOWNLOADED,
contentManager.getPrefetchContentProviderPropertiesTracker().getValue());
assertEquals("Expected final download state for content to be: " + DownloadState.DOWNLOADED,
DownloadState.DOWNLOADED, contentManager.getPrefetchContentTracker().getValue());
ContentType<?>[] types = contentManager.getTypes();
assertTrue("Expected content types for getting started guides after downloading completed.",
types != null && types.length > 0);
List<?> allContent = getContent(types, contentManager);
assertTrue("Expected content for getting started guides after downloading completed.",
allContent.size() > 0);
return true;
} else {
fail(
"Expected downloadStates not reached.\n" +
"Actual states: "+actualContentDownloadStates+"\n" +
error.getValue()==null
? ""
: "Error: "+ExceptionUtil.stacktrace(error.getValue())
);
return false;
}
}
};
}
/**
* Check github api rate limit has some requests available.
* @return true if there's enough requests limit available to run the test.
*/
private boolean isEnoughRateLimitAvailable() throws IOException {
GithubClient github = new GithubClient();
int remaining = github.getRateLimit().getRate().getRemaining();
System.out.println("github rate-limit remaining: "+remaining);
return remaining > 8; // Test needs 4 requests... add a bit of margin above that.
}
public static GSImportWizardModel getModel() throws Exception {
return new GSImportWizardModel();
}
public static IRunnableContext getRunnableContext() {
return JobUtil.DEFAULT_BACKGROUND_RUNNABLE_CONTEXT;
}
protected List<?> getContent(ContentType<?>[] types, ContentManager contentManager) {
List<Object> content = new ArrayList<>();
for (ContentType<?> type : types) {
Object[] typeContent = contentManager.get(type);
content.addAll(Arrays.asList(typeContent));
}
return content;
}
}

View File

@@ -0,0 +1,55 @@
/*******************************************************************************
* Copyright (c) 2015 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.test;
import static org.junit.Assert.assertNotNull;
import java.io.InputStream;
import org.junit.Test;
import org.springframework.ide.eclipse.boot.core.initializr.InitializrDependencySpec;
/**
* @author Kris De Volder
*/
public class InitializrDependencySpecTest {
/**
* Basic test, parses data from initialzr dependencies endpoint
*/
@Test
public void parseInitializrDependencies() throws Exception {
InitializrDependencySpec spec = parseDependencies("edit-starters-test-inputs/sample-dependencies.json");
assertNotNull(spec);
}
private InitializrDependencySpec parseDependencies(String resourceName) throws Exception {
InputStream rsrc = this.getClass().getResourceAsStream(resourceName);
try {
return InitializrDependencySpec.parseFrom(rsrc);
} finally {
rsrc.close();
}
}
//TODO: EditStartersModel testing
// - most popular section doesn't add duplicate checkboxes
// - most popular section always adds all the initially selected checkboxes
// - dependencies already selected in pom are correctly reflected as initial selection
// - popularity tracker only updates count for newly selected dependencies, not those that where there before
// - edit starters performApply modifies the pom correctly to a
// - add dependencies
// with scope
// with version
// - add boms
// - add repository
}

View File

@@ -0,0 +1,68 @@
/*******************************************************************************
* Copyright (c) 2018 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.test;
import static org.junit.Assert.assertEquals;
import java.util.concurrent.ExecutionException;
import org.junit.Test;
import org.springframework.ide.eclipse.boot.core.initializr.HttpRedirectionException;
import org.springframework.ide.eclipse.boot.wizard.InitializrFactoryModel;
import org.springsource.ide.eclipse.commons.frameworks.test.util.ACondition;
public class InitializrFactoryModelTest {
public static class MockModel {
public final String url;
public MockModel(String url) {
super();
this.url = url;
}
}
@Test
public void handlesHttpRedirectionException() throws Exception {
InitializrFactoryModel<MockModel> factoryModel = new InitializrFactoryModel<MockModel>((url) -> {
if (url.startsWith("https")) {
return new MockModel(url);
} else {
throw new HttpRedirectionException(url.replaceFirst("http", "https"));
}
});
factoryModel.getServiceUrlField().setValue("http"+"://accept.only.https.com");
ACondition.waitFor("Follows the redirection", 200, () -> {
assertEquals("https://accept.only.https.com", factoryModel.getServiceUrlField().getValue());
assertEquals(factoryModel.getModel().getValue().url, "https://accept.only.https.com");
});
}
@Test
public void handlesWrappedHttpRedirectionException() throws Exception {
//Check that it also works if the exception becomes wrapped, as may happen if it passes
// through futures or caches or whatnot.
InitializrFactoryModel<MockModel> factoryModel = new InitializrFactoryModel<MockModel>((url) -> {
if (url.startsWith("https")) {
return new MockModel(url);
} else {
throw new ExecutionException(new HttpRedirectionException(url.replaceFirst("http", "https")));
}
});
factoryModel.getServiceUrlField().setValue("http"+"://accept.only.https.com");
ACondition.waitFor("Follows the redirection", 200, () -> {
assertEquals("https://accept.only.https.com", factoryModel.getServiceUrlField().getValue());
assertEquals(factoryModel.getModel().getValue().url, "https://accept.only.https.com");
});
}
}

View File

@@ -0,0 +1,229 @@
/*******************************************************************************
* Copyright (c) 2020 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.test;
import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.ARTIFACT_ID;
import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.DEPENDENCIES;
import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.DEPENDENCY;
import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.DEPENDENCY_MANAGEMENT;
import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.GROUP_ID;
import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.childEquals;
import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.findChild;
import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.findChilds;
import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.getChild;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.springframework.ide.eclipse.boot.util.PomUtils.getArtifactId;
import static org.springframework.ide.eclipse.boot.util.PomUtils.getGroupId;
import static org.springframework.ide.eclipse.boot.util.PomUtils.getScope;
import static org.springframework.ide.eclipse.boot.util.PomUtils.getTextChild;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.springframework.ide.eclipse.boot.core.ISpringBootProject;
import org.springframework.ide.eclipse.boot.core.MavenId;
import org.springframework.ide.eclipse.boot.core.SpringBootStarter;
import org.springframework.ide.eclipse.boot.core.SpringBootStarters;
import org.springframework.ide.eclipse.boot.core.initializr.InitializrServiceSpec.Dependency;
import org.springframework.ide.eclipse.boot.wizard.PopularityTracker;
import org.springsource.ide.eclipse.commons.livexp.util.Log;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@SuppressWarnings("restriction")
public class MavenStartersHarness {
public void assertStarters(List<SpringBootStarter> starters, String... expectedIds) {
Set<String> expecteds = new HashSet<>(Arrays.asList(expectedIds));
for (SpringBootStarter starter : starters) {
String id = starter.getId();
if (expecteds.remove(id)) {
//okay
} else {
fail("Unexpected starter found: "+starter);
}
}
if (!expecteds.isEmpty()) {
fail("Expected starters not found: "+expecteds);
}
}
public void assertStarterDeps(List<Dependency> starters, String... expectedIds) {
Set<String> expecteds = new HashSet<>(Arrays.asList(expectedIds));
for (Dependency starter : starters) {
String id = starter.getId();
if (expecteds.remove(id)) {
//okay
} else {
fail("Unexpected starter found: "+starter);
}
}
if (!expecteds.isEmpty()) {
fail("Expected starters not found: "+expecteds);
}
}
/**
* Deps are string in this format "<gid>:<aid>@<scope>". The '@<scope>' part can be omited
* to indicate a dependency with default scope.
*/
public void assertMavenDeps(IProject project, String... _expectedDeps) throws IOException, CoreException {
IDOMDocument pom = parsePom(project);
Element depsEl = findChild(pom.getDocumentElement(), DEPENDENCIES);
List<Element> depNodes = findChilds(depsEl, DEPENDENCY);
List<String> actualDeps = new ArrayList<>();
for (Element depEl : depNodes) {
String dep = getGroupId(depEl) + ":" + getArtifactId(depEl);
String scope = getScope(depEl) ;
if (scope!=null) {
dep = dep + "@" + scope;
}
actualDeps.add(dep);
}
Collections.sort(actualDeps);
List<String> expectedDeps = new ArrayList<>(Arrays.asList(_expectedDeps));
Collections.sort(expectedDeps);
assertEquals(onePerLine(expectedDeps), onePerLine(actualDeps));
}
public void assertBoms(IProject project, String... _expectedDeps) throws IOException, CoreException {
IDOMDocument pom = parsePom(project);
Element depsEl = getChild(pom.getDocumentElement(), DEPENDENCY_MANAGEMENT, DEPENDENCIES);
List<Element> depNodes = findChilds(depsEl, DEPENDENCY);
List<String> actualDeps = new ArrayList<>();
for (Element depEl : depNodes) {
String dep = getGroupId(depEl) + ":" + getArtifactId(depEl);
if ("import".equals(getTextChild(depEl, "scope")) && "pom".equals(getTextChild(depEl, "type"))) {
actualDeps.add(dep);
}
}
Collections.sort(actualDeps);
List<String> expectedDeps = new ArrayList<>(Arrays.asList(_expectedDeps));
Collections.sort(expectedDeps);
assertEquals(onePerLine(expectedDeps), onePerLine(actualDeps));
}
public IDOMDocument parsePom(IProject project) throws IOException, CoreException {
return ((IDOMModel) StructuredModelManager.getModelManager().createUnManagedStructuredModelFor(project.getFile("pom.xml"))).getDocument();
}
public static Element findDependency(Document document, MavenId dependency) {
Element dependenciesElement = findChild(document.getDocumentElement(), DEPENDENCIES);
return findChild(dependenciesElement, DEPENDENCY, childEquals(GROUP_ID, dependency.getGroupId()),
childEquals(ARTIFACT_ID, dependency.getArtifactId()));
}
public void assertUsageCounts(ISpringBootProject project, PopularityTracker popularities, String... idAndCount) throws Exception {
Map<String, Integer> expect = new HashMap<>();
for (String pair : idAndCount) {
String[] pieces = pair.split(":");
assertEquals(2, pieces.length);
String id = pieces[0];
int count = Integer.parseInt(pieces[1]);
expect.put(id, count);
}
List<SpringBootStarter> knownStarters = project.getKnownStarters();
assertFalse(knownStarters.isEmpty());
for (SpringBootStarter starter : knownStarters) {
String id = starter.getId();
Integer expectedCountOrNull = expect.get(id);
int expectedCount = expectedCountOrNull==null ? 0 : expectedCountOrNull;
assertEquals("Usage count for '"+id+"'", expectedCount, popularities.getUsageCount(id));
expect.remove(id);
}
assertTrue("Expected usage counts not found: "+expect, expect.isEmpty());
}
public Element findDependency(ISpringBootProject project, Document pom, String id) {
try {
SpringBootStarters starters = project.getStarterInfos();
MavenId mid = starters.getMavenId(id);
if (mid!=null) {
return findDependency(pom, mid);
}
} catch (Exception e) {
Log.log(e);
}
return null;
}
private String onePerLine(List<String> strings) {
StringBuilder builder = new StringBuilder();
for (String string : strings) {
builder.append(string);
builder.append('\n');
}
return builder.toString();
}
public String generateFakePom(SpringBootStarters knownStarters, List<String> starters) throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
Document pom = dbf.newDocumentBuilder().newDocument();
Element rootElement = pom.createElement("project");
pom.appendChild(rootElement);
Element depsEl = pom.createElement(DEPENDENCIES);
rootElement.appendChild(depsEl);
for (String starterId : starters) {
SpringBootStarter starter = knownStarters.getStarter(starterId);
Element dep = pom.createElement(DEPENDENCY);
depsEl.appendChild(dep);
{
Element gid = pom.createElement(GROUP_ID);
gid.appendChild(pom.createTextNode(starter.getGroupId()));
dep.appendChild(gid);
}
{
Element aid = pom.createElement(ARTIFACT_ID);
aid.appendChild(pom.createTextNode(starter.getArtifactId()));
dep.appendChild(aid);
}
}
Transformer tf = TransformerFactory.newInstance().newTransformer();
StringWriter stringWriter = new StringWriter();
tf.transform(new DOMSource(pom), new StreamResult(stringWriter));
return stringWriter.toString();
}
}

View File

@@ -0,0 +1,134 @@
/*******************************************************************************
* Copyright (c) 2020 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.test;
import java.io.IOException;
import java.net.ConnectException;
import java.net.URL;
import java.net.URLConnection;
import java.util.function.Supplier;
import org.springframework.ide.eclipse.boot.core.initializr.InitializrProjectDownloader;
import org.springframework.ide.eclipse.boot.core.initializr.InitializrService;
import org.springframework.ide.eclipse.boot.core.initializr.InitializrUrl;
import org.springframework.ide.eclipse.boot.core.initializr.InitializrServiceSpec.Option;
import org.springframework.ide.eclipse.boot.test.AddStartersTestHarness.MockProjectDownloader;
import org.springframework.ide.eclipse.boot.wizard.starters.AddStartersInitializrService;
import org.springsource.ide.eclipse.commons.frameworks.core.downloadmanager.URLConnectionFactory;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
public class MockAddStartersInitializrService extends AddStartersInitializrService {
private final String starterZipPath;
private final String validInitializrUrl;
private final String[] expectedSelectedDependencies;
private final MockInitializrService wrappedService;
private final String[] supportedBootVersions;
// Empty URL factory. Shouldn't do anything as an actual URL connection is not
// needed for testing
private static final URLConnectionFactory EMPTY_URL_FACTORY = new URLConnectionFactory() {
@Override
public URLConnection createConnection(URL url) throws IOException {
return null;
}
};
/**
*
*
* @param starterZipPath path to an starter zip file representing
* a project that would otherwise be
* downloaded from an actual initializr
* `/starter.zip` endpoint
* @param validInitializrUrl an initializr service URL that is
* considered "valid" for the wizard (does
* not have to be a real-life initializr URL
* as no connection will be attempted), and
* read by the wizard when it initially is
* created. Mocks having a valid URL like
* "https://start.spring.io " in an actual
* boot initializr preference that is
* initially read by the real wizard when it
* opens.
* @param supportedBootVersions list of supported boot versions
* associated with the "valid" initializr
* URL. This is used by the wizard to check
* against the boot version of the local
* project. Used for testing error
* conditions (e.g. unsupported boot version
* errors that a wizard may throw)
* @param expectedSelectedDependencies List of selected dependencies that are
* expected when a request is made to
* download a project within the wizard
* mechanics
*/
public MockAddStartersInitializrService(String starterZipPath, String validInitializrUrl,
String[] supportedBootVersions, String[] expectedSelectedDependencies,
MockInitializrService wrappedService) {
super(EMPTY_URL_FACTORY);
this.starterZipPath = starterZipPath;
this.validInitializrUrl = validInitializrUrl;
this.expectedSelectedDependencies = expectedSelectedDependencies != null ? expectedSelectedDependencies
: new String[0];
this.wrappedService = wrappedService;
this.supportedBootVersions = supportedBootVersions;
}
@Override
public InitializrService getService(Supplier<String> url) {
try {
wrappedService.loadInfo();
} catch (Exception e) {
// print the error so its visible during tests
e.printStackTrace();
return null;
}
return wrappedService;
}
@Override
public InitializrProjectDownloader getProjectDownloader(InitializrUrl url) {
return new MockProjectDownloader(urlConnectionFactory, url, starterZipPath, expectedSelectedDependencies);
}
@Override
protected Option[] resolveAllBootVersions(String url) throws Exception {
Builder<Object> options = ImmutableList.builder();
for (String v : supportedBootVersions) {
Option option = new Option();
option.setId(v);
options.add(option);
}
return options.build().toArray(new Option[0]);
}
@Override
public void checkBasicConnection(URL url) throws Exception {
// Tests an actual error thrown by initializr service: a valid URL (e.g.
// https://www.google.com) that is
// not an initializr URL
if (!validInitializrUrl.equals(url.toString())) {
throw new ConnectException();
}
}
}

View File

@@ -0,0 +1,117 @@
/*******************************************************************************
* Copyright (c) 2020 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.test;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.ide.eclipse.boot.core.SpringBootStarters;
import org.springframework.ide.eclipse.boot.core.initializr.InitializrDependencySpec;
import org.springframework.ide.eclipse.boot.core.initializr.InitializrService;
import org.springframework.ide.eclipse.boot.core.initializr.InitializrServiceSpec;
import com.google.common.collect.ImmutableSet;
public class MockInitializrService implements InitializrService {
private SpringBootStarters starters;
private boolean unavailable = false;
private boolean generateFakePom = false;
private Set<String> supportedBootVersions;
private MavenStartersHarness mavenHarness;
private String initializrInfoInputFile;
/**
*
* @param supportedBootVersions list of supported boot versions associated with
* the "valid" initializr URL. This is used by the
* wizard to check against the boot version of the
* local project. Used for testing error conditions
* (e.g. unsupported boot version errors that a
* wizard may throw)
* @param initializrInfoInput a JSON test file that contains initializr info,
* like all available dependencies, that would
* otherwise be downloaded from a real initializr
* service.
*/
public MockInitializrService(String[] supportedBootVersions, MavenStartersHarness mavenHarness,
String initializrInfoInputFile) {
this.supportedBootVersions = ImmutableSet.copyOf(supportedBootVersions);
this.mavenHarness = mavenHarness;
this.initializrInfoInputFile = initializrInfoInputFile;
}
public void enableFakePomGenerator() {
generateFakePom = true;
}
private InputStream getResource(String name, String endPoint) {
return getClass().getResourceAsStream("edit-starters-test-inputs/" + name + "-" + endPoint + ".json");
}
@Override
public SpringBootStarters getStarters(String bootVersion) throws Exception {
// Mock unsupported boot version. This is an actual error thrown in the real
// wizard
if (!supportedBootVersions.contains(bootVersion)) {
throw new FileNotFoundException();
} else {
if (unavailable) {
throw new IOException("Initializr Service Unavailable");
} else if (starters != null) {
return starters;
} else {
return InitializrService.DEFAULT.getStarters(bootVersion);
}
}
}
/**
* Make the mock behave as if the 'dependencies' endpoint is not available
* (either the service is down, there is no internet connection, or this is an
* old service that doesn't implement the endpoint yet).
*/
public void makeUnavailable() {
this.unavailable = true;
}
@SuppressWarnings("unchecked")
@Override
public String getPom(Map<String, ?> parameters) throws Exception {
if (unavailable) {
throw new IOException("Initializr Service Unavailable");
} else if (generateFakePom) {
String bootVersion = (String) parameters.get("bootVersion");
return mavenHarness.generateFakePom(getStarters(bootVersion),
(List<String>) parameters.get("dependencies"));
} else {
return InitializrService.DEFAULT.getPom(parameters);
}
}
public void loadInfo() throws Exception {
setInputs(getResource(initializrInfoInputFile, "main"), getResource(initializrInfoInputFile, "dependencies"));
}
/**
* Causes the mock to parse input from given input streams instead of calling
* out to the real web service.
*/
private void setInputs(InputStream main, InputStream dependencies) throws Exception {
starters = new SpringBootStarters(InitializrServiceSpec.parseFrom(main),
InitializrDependencySpec.parseFrom(dependencies));
}
}

View File

@@ -0,0 +1,35 @@
/*******************************************************************************
* Copyright (c) 2015 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.test;
import java.io.IOException;
import java.lang.reflect.Field;
import org.eclipse.jface.preference.PreferenceStore;
/**
* @author Kris De Volder
*/
public class MockPrefsStore extends PreferenceStore {
@Override
public void save() throws IOException {
//Override save or it will throw unless we provide a file to save to.
try {
Field f = PreferenceStore.class.getDeclaredField("dirty");
f.setAccessible(true);
f.set(this, false);
} catch (Exception e) {
throw new Error(e);
}
}
}

View File

@@ -0,0 +1,855 @@
/*******************************************************************************
* Copyright (c) 2013, 2017 Pivotal Software, 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* GoPivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.test;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.preference.IPreferenceStore;
import org.springframework.ide.eclipse.boot.core.initializr.InitializrServiceSpec;
import org.springframework.ide.eclipse.boot.core.initializr.InitializrServiceSpec.Dependency;
import org.springframework.ide.eclipse.boot.wizard.CheckBoxesSection.CheckBoxModel;
import org.springframework.ide.eclipse.boot.wizard.HierarchicalMultiSelectionFieldModel;
import org.springframework.ide.eclipse.boot.wizard.MultiSelectionFieldModel;
import org.springframework.ide.eclipse.boot.wizard.NewSpringBootWizardModel;
import org.springframework.ide.eclipse.boot.wizard.PopularityTracker;
import org.springframework.ide.eclipse.boot.wizard.RadioGroup;
import org.springframework.ide.eclipse.boot.wizard.RadioGroups;
import org.springframework.ide.eclipse.boot.wizard.RadioInfo;
import org.springframework.ide.eclipse.boot.wizard.content.BuildType;
import org.springframework.ide.eclipse.boot.wizard.importing.ImportStrategy;
import org.springsource.ide.eclipse.commons.frameworks.core.downloadmanager.URLConnectionFactory;
import org.springsource.ide.eclipse.commons.frameworks.core.util.StringUtils;
import org.springsource.ide.eclipse.commons.livexp.core.FieldModel;
import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression;
import org.springsource.ide.eclipse.commons.livexp.core.LiveVariable;
import org.springsource.ide.eclipse.commons.livexp.core.ValidationResult;
import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil;
import org.springsource.ide.eclipse.commons.livexp.util.Filter;
import org.springsource.ide.eclipse.commons.livexp.util.Filters;
import org.springsource.ide.eclipse.commons.livexp.util.Log;
import org.springsource.ide.eclipse.commons.tests.util.StsTestUtil;
import junit.framework.TestCase;
/**
* Tests whether NewSpringBootWizardModel adequately parses initializer form data.
*
* @author Kris De Volder
*/
public class NewSpringBootWizardModelTest extends TestCase {
//private static final String INITIALIZR_JSON = "initializr.json";
private static final String INITIALIZR_JSON = "initializr-v2.1.json";
private static final String INITIALIZR_V_2_2_JSON = "initializr-v2.2.json";
private static final String[] testDataFiles = {
INITIALIZR_JSON, INITIALIZR_V_2_2_JSON
};
@Override
protected void setUp() throws Exception {
super.setUp();
StsTestUtil.cleanUpProjects();
}
public static NewSpringBootWizardModel parseFrom(String resourcePath, IPreferenceStore store) throws Exception {
AtomicReference<Throwable> firstError = new AtomicReference<>();
Log.errorHandler = error -> {
firstError.getAndUpdate(existing -> existing!=null?existing:error);
};
try {
URL formUrl = resourceUrl(resourcePath);
return new NewSpringBootWizardModel(new URLConnectionFactory(), formUrl.toString(), store) {
@Override
protected void importProject(org.eclipse.core.runtime.IProgressMonitor mon) throws java.lang.reflect.InvocationTargetException ,InterruptedException {
//do nothing (this is a fake wizard, not meant to create real projects).
}
};
} finally {
Log.errorHandler = null;
if (firstError.get()!=null) {
throw ExceptionUtil.exception(firstError.get());
}
}
}
public static NewSpringBootWizardModel parseFrom(String resourcePath) throws Exception {
return parseFrom(resourcePath, new MockPrefsStore());
}
public static URL resourceUrl(String resourcePath) {
URL formUrl = NewSpringBootWizardModelTest.class.getResource(resourcePath);
return formUrl;
}
public void testParsedRadios() throws Exception {
NewSpringBootWizardModel model = parseFrom(INITIALIZR_JSON);
RadioGroups radioGroups = model.getRadioGroups();
assertGroupNames(radioGroups, "type", "packaging", "javaVersion", "language", "bootVersion");
}
public void testPackagingRadios() throws Exception {
for (String f : testDataFiles) {
NewSpringBootWizardModel model = parseFrom(f);
RadioGroup packagingTypes = model.getRadioGroups().getGroup("packaging");
assertNotNull(packagingTypes);
assertGroupValues(packagingTypes, "jar", "war");
assertEquals("jar", packagingTypes.getDefaultValue().getValue());
}
}
public void testJavaVersionRadios() throws Exception {
for (String f : testDataFiles) {
NewSpringBootWizardModel model = parseFrom(f);
RadioGroup group = model.getRadioGroups().getGroup("javaVersion");
assertNotNull(group);
assertGroupValues(group, "1.6", "1.7", "1.8");
assertEquals("1.8", group.getDefaultValue().getValue());
}
}
public void testBuildTypeRadios() throws Exception {
for (String jsonFile : testDataFiles) {
NewSpringBootWizardModel model = parseFrom(jsonFile);
String starterZipUrl = resourceUrl(jsonFile).toURI().resolve("/starter.zip").toString();
assertEquals(starterZipUrl, model.baseUrl.getValue());
RadioGroup group = model.getRadioGroups().getGroup("type");
assertNotNull(group);
assertGroupValues(group, "MAVEN", "GRADLE");
assertEquals("MAVEN", group.getDefaultValue().getValue());
group.getSelection().selection.setValue(group.getRadio("MAVEN"));
assertEquals(BuildType.MAVEN, model.getBuildType());
assertEquals(starterZipUrl, model.baseUrl.getValue());
for (ImportStrategy gradleStrategy : BuildType.GRADLE.getImportStrategies()) {
group.getSelection().selection.setValue(group.getRadio(gradleStrategy.getId()));
assertEquals(BuildType.GRADLE, model.getBuildType());
assertEquals(gradleStrategy, model.getImportStrategy());
assertEquals(starterZipUrl, model.baseUrl.getValue());
}
}
}
public void testBuildTypeRadiosVariant() throws Exception {
//Hypothetical variant where the json "types" lists different actions for maven and gradle zip
String jsonFile = "initializr-variant.json";
String mavenZipUrl = resourceUrl(jsonFile).toURI().resolve("/maven.zip").toString();
String gradleZipUrl = resourceUrl(jsonFile).toURI().resolve("/gradle.zip").toString();
NewSpringBootWizardModel model = parseFrom(jsonFile);
RadioGroup group = model.getRadioGroups().getGroup("type");
assertNotNull(group);
assertGroupValues(group, "MAVEN", "GRADLE");
assertEquals("MAVEN", group.getDefaultValue().getValue());
assertEquals(mavenZipUrl, model.baseUrl.getValue());
for (ImportStrategy gradleStrat : BuildType.GRADLE.getImportStrategies()) {
group.getSelection().selection.setValue(group.getRadio(gradleStrat.getId()));
assertEquals(BuildType.GRADLE, model.getBuildType());
assertEquals(gradleStrat, model.getImportStrategy());
assertEquals(gradleZipUrl, model.baseUrl.getValue());
}
group.getSelection().selection.setValue(group.getRadio("MAVEN"));
assertEquals(BuildType.MAVEN, model.getBuildType());
assertEquals(mavenZipUrl, model.baseUrl.getValue());
}
public void testStarters() throws Exception {
for (String jsonFile : testDataFiles) {
NewSpringBootWizardModel model = parseFrom(jsonFile);
Collection<Dependency> styles = getAllChoices(model.dependencies);
assertNotNull(styles);
assertTrue(styles.size()>7);
for (String catName : model.dependencies.getCategories()) {
String lastLabel = null; //check that style labels are sorted within each category
MultiSelectionFieldModel<Dependency> cat = model.dependencies.getContents(catName);
for (Dependency choice : cat.getChoices()) {
String label = cat.getLabel(choice);
if (lastLabel!=null) {
assertTrue("Labels not sorted: '"+lastLabel+"' > '"+label+"'", lastLabel.compareTo(label)<0);
}
lastLabel = label;
assertNotNull("No tooltip for: "+choice+" ["+label+"]", cat.getTooltipHtml(choice).get());
}
}
}
}
public static <T> Collection<T> getAllChoices(
HierarchicalMultiSelectionFieldModel<T> dependencies) {
ArrayList<T> choices = new ArrayList<>();
for (String catName : dependencies.getCategories()) {
MultiSelectionFieldModel<T> cat = dependencies.getContents(catName);
choices.addAll(Arrays.asList(cat.getChoices()));
}
return choices;
}
public void testVersionRangesBuildSnaphotBug() throws Exception {
//See https://www.pivotaltracker.com/story/show/100963226
NewSpringBootWizardModel model = parseFrom(INITIALIZR_JSON);
Dependency devtools = getDependencyById(model, "devtools");
RadioGroup bootVersion = model.getBootVersion();
RadioInfo newer1 = bootVersion.getRadio("1.3.0.M2");
RadioInfo newer2 = bootVersion.getRadio("1.3.0.BUILD-SNAPSHOT");
RadioInfo older = bootVersion.getRadio("1.2.6.BUILD-SNAPSHOT");
LiveExpression<Boolean> devtoolsEnabled = getEnablement(model.dependencies, devtools);
bootVersion.setValue(older);
assertFalse(devtoolsEnabled.getValue());
bootVersion.setValue(newer1);
assertTrue(devtoolsEnabled.getValue());
bootVersion.setValue(newer2);
assertTrue(devtoolsEnabled.getValue());
}
public void testVersionRanges() throws Exception {
NewSpringBootWizardModel model = parseFrom(INITIALIZR_JSON);
Dependency bitronix = getDependencyById(model, "jta-bitronix");
Dependency thymeleaf = getDependencyById(model, "thymeleaf");
assertEquals("1.2.0.M1", bitronix.getVersionRange());
assertFalse(StringUtils.hasText(thymeleaf.getVersionRange()));
RadioGroup bootVersion = model.getBootVersion();
assertNotNull(bootVersion);
assertGroupValues(bootVersion,
"1.3.0.M2",
"1.3.0.BUILD-SNAPSHOT",
"1.2.6.BUILD-SNAPSHOT",
"1.2.5.RELEASE",
"1.1.12.RELEASE"
);
RadioInfo older = bootVersion.getRadio("1.1.12.RELEASE");
RadioInfo newer = bootVersion.getRadio("1.2.5.RELEASE");
LiveExpression<Boolean> bitronixEnabled = getEnablement(model.dependencies, bitronix);
LiveExpression<Boolean> thymeleafEnabled = getEnablement(model.dependencies, thymeleaf);
bootVersion.setValue(older);
assertFalse(bitronixEnabled.getValue());
CheckBoxModel<Dependency> bitronixChekbox = getCheckboxById(model.dependencies.getAllBoxes(), "jta-bitronix");
assertEquals("Requires Spring Boot >=1.2.0.M1", bitronixChekbox.getRequirementTooltip());
assertTrue(thymeleafEnabled.getValue());
bootVersion.setValue(newer);
assertTrue(bitronixEnabled.getValue());
assertTrue(thymeleafEnabled.getValue());
bootVersion.setValue(older);
Set<Dependency> selectedDepedencies = getSelecteds(model.dependencies);
assertTrue(selectedDepedencies.isEmpty());
select(model.dependencies, bitronix);
select(model.dependencies, thymeleaf);
selectedDepedencies = getSelecteds(model.dependencies);
assertEquals(2, selectedDepedencies.size());
String url = model.downloadUrl.getValue();
assertContains("thymeleaf", url);
assertFalse(url.contains("bitronix"));
}
public void testVersionRanges_V2_2() throws Exception {
NewSpringBootWizardModel model = parseFrom(INITIALIZR_V_2_2_JSON);
Dependency acmeBiz = getDependencyById(model, "org.acme:biz");
Dependency web = getDependencyById(model, "web");
assertEquals("2.2.0.BUILD-SNAPSHOT", acmeBiz.getVersionRange());
assertFalse(StringUtils.hasText(web.getVersionRange()));
RadioGroup bootVersion = model.getBootVersion();
assertNotNull(bootVersion);
assertGroupValues(bootVersion,
"2.4.0-SNAPSHOT",
"2.1.4.RELEASE",
"1.5.17.RELEASE"
);
RadioInfo older = bootVersion.getRadio("1.5.17.RELEASE");
RadioInfo newer = bootVersion.getRadio("2.4.0-SNAPSHOT");
LiveExpression<Boolean> acmeBizEnabled = getEnablement(model.dependencies, acmeBiz);
LiveExpression<Boolean> webEnabled = getEnablement(model.dependencies, web);
bootVersion.setValue(older);
assertFalse(acmeBizEnabled.getValue());
CheckBoxModel<Dependency> acmeBizChekbox = getCheckboxById(model.dependencies.getAllBoxes(), "org.acme:biz");
assertEquals("Requires Spring Boot >=2.2.0.BUILD-SNAPSHOT", acmeBizChekbox.getRequirementTooltip());
assertTrue(webEnabled.getValue());
bootVersion.setValue(newer);
assertTrue(acmeBizEnabled.getValue());
assertTrue(webEnabled.getValue());
bootVersion.setValue(older);
Set<Dependency> selectedDepedencies = getSelecteds(model.dependencies);
assertTrue(selectedDepedencies.isEmpty());
select(model.dependencies, acmeBiz);
select(model.dependencies, web);
selectedDepedencies = getSelecteds(model.dependencies);
assertEquals(2, selectedDepedencies.size());
String url = model.downloadUrl.getValue();
assertContains("web", url);
assertFalse(url.contains("acme"));
}
public void testPopularityTracking() throws Exception {
IPreferenceStore store = new MockPrefsStore();
NewSpringBootWizardModel model = parseFrom(INITIALIZR_JSON, store);
assertTrue(model.getMostPopular(10).isEmpty());
Dependency web = getDependencyById(model, "web");
Dependency actuator = getDependencyById(model, "actuator");
Dependency thymeleaf = getDependencyById(model, "thymeleaf");
select(model.dependencies, web);
select(model.dependencies, thymeleaf);
select(model.dependencies, actuator);
model.updateUsageCounts();
PopularityTracker tracker = new PopularityTracker(store);
assertEquals(1, tracker.getUsageCount(web));
assertEquals(1, tracker.getUsageCount(thymeleaf));
assertEquals(1, tracker.getUsageCount(actuator));
model.updateUsageCounts();
assertEquals(2, tracker.getUsageCount(web));
assertEquals(2, tracker.getUsageCount(thymeleaf));
assertEquals(2, tracker.getUsageCount(actuator));
unselect(model.dependencies, actuator);
model.updateUsageCounts();
unselect(model.dependencies, thymeleaf);
model.updateUsageCounts();
assertEquals(4, tracker.getUsageCount(web));
assertEquals(3, tracker.getUsageCount(thymeleaf));
assertEquals(2, tracker.getUsageCount(actuator));
assertCheckboxes(model.getMostPopular(10),
web, thymeleaf, actuator);
/////////////////////////////////////////////////////////////////////////////
// check that model counts are limitted according to 'howMany' argument
assertCheckboxes(model.getMostPopular(3),
web, thymeleaf, actuator);
assertCheckboxes(model.getMostPopular(2),
web, thymeleaf);
assertCheckboxes(model.getMostPopular(1),
web);
assertCheckboxes(model.getMostPopular(0)
/*nothing*/);
}
public void testPopularCheckboxSharesSelectionState() throws Exception {
for (String f : testDataFiles) {
IPreferenceStore store = new MockPrefsStore();
NewSpringBootWizardModel model = parseFrom(f, store);
assertTrue(model.getMostPopular(10).isEmpty());
Dependency web = getDependencyById(model, "web");
PopularityTracker tracker = new PopularityTracker(store);
tracker.incrementUsageCount(web);
String webCat = getCategory(model.dependencies, web);
MultiSelectionFieldModel<Dependency> webGroup = model.dependencies.getContents(webCat);
List<CheckBoxModel<Dependency>> allWebBoxes = webGroup.getCheckBoxModels();
CheckBoxModel<Dependency> normalBox = getCheckboxById(allWebBoxes, web.getId());
CheckBoxModel<Dependency> popularBox = getCheckboxById(model.getMostPopular(10), web.getId());
assertFalse(normalBox.getSelection().getValue());
assertFalse(popularBox.getSelection().getValue());
normalBox.getSelection().setValue(true);
assertTrue(normalBox.getSelection().getValue());
assertTrue(popularBox.getSelection().getValue());
popularBox.getSelection().setValue(false);
assertFalse(normalBox.getSelection().getValue());
assertFalse(popularBox.getSelection().getValue());
}
}
public void testDefaultDependencies() throws Exception {
IPreferenceStore store = new MockPrefsStore();
NewSpringBootWizardModel model = parseFrom(INITIALIZR_JSON, store);
assertTrue(model.getDefaultDependencies().isEmpty());
select(model.dependencies, getDependencyById(model, "web"));
select(model.dependencies, getDependencyById(model, "actuator"));
select(model.dependencies, getDependencyById(model, "thymeleaf"));
assertTrue(model.saveDefaultDependencies());
// Initialize new model and check if default dependencies are selected
model = parseFrom(INITIALIZR_JSON, store);
assertEquals(3, model.getDefaultDependencies().size());
Set<String> selectedIds = model.dependencies.getCurrentSelection().stream().map(Dependency::getId).collect(Collectors.toSet());
Set<String> defaultIds = model.getDefaultDependencies().stream().map(checkboxModel -> {
return checkboxModel.getValue().getId();
}).collect(Collectors.toSet());
assertEquals(defaultIds, selectedIds);
}
public void testUnselectAll() throws Exception {
IPreferenceStore store = new MockPrefsStore();
NewSpringBootWizardModel model = parseFrom(INITIALIZR_JSON, store);
assertTrue(model.getDefaultDependencies().isEmpty());
select(model.dependencies, getDependencyById(model, "web"));
select(model.dependencies, getDependencyById(model, "actuator"));
select(model.dependencies, getDependencyById(model, "thymeleaf"));
assertEquals(3, model.dependencies.getCurrentSelection().size());
model.dependencies.clearSelection();
assertTrue(model.dependencies.getCurrentSelection().isEmpty());
}
public void testDependencySearchBox() throws Exception {
// The trickies bit of implementing the search box is, unfortunately, making the
// SWT gui widgetry apply the filter and hide / show corresponding ui elements.
// This unfortunately not tested here. This test only verifies the filter's
// matching logic.
NewSpringBootWizardModel model = parseFrom(INITIALIZR_JSON);
LiveVariable<String> searchBox = model.getDependencyFilterBoxText();
LiveExpression<Filter<Dependency>> filter = model.getDependencyFilter();
assertEquals("", searchBox.getValue());
assertEquals(Filters.acceptAll(),filter.getValue());
assertFilterAccepts(model, true, "web", "web", "Web", "Full stack yada yada");
assertFilterAccepts(model, true, "WeB", "web", "Web", "Full stack yada yada");
assertFilterAccepts(model, false, "ZZZZZZZZZZ", "web", "Web", "Full stack yada yada");
assertFilterAccepts(model, true, "foo", "something", "label FoO label", "desc");
assertFilterAccepts(model, true, "foo", "something", "label", "desc FOO desc");
assertFilterAccepts(model, false, "foo", "foo", "label", "desc");
}
public void testValidDefaultProjectName() throws Exception {
ensureProject("demo");
ensureProject("demo-1");
NewSpringBootWizardModel model = parseFrom(INITIALIZR_JSON);
assertEquals("demo-2", model.getProjectName().getValue());
assertEquals("demo-2", model.getArtifactId().getValue());
assertEquals(ValidationResult.OK, model.getProjectName().getValidator().getValue());
}
private void ensureProject(String name) throws CoreException {
IProject p1 = ResourcesPlugin.getWorkspace().getRoot().getProject(name);
if (!p1.exists()) {
p1.create(new NullProgressMonitor());
}
}
public void testArtifactIdSyncWithProjectName() throws Exception {
NewSpringBootWizardModel model = parseFrom(INITIALIZR_JSON);
assertEquals("demo", model.getProjectName().getValue());
assertEquals("demo", model.getArtifactId().getValue());
model.getProjectName().setValue("demo-1");
assertEquals("demo-1", model.getProjectName().getValue());
assertEquals("demo-1", model.getArtifactId().getValue());
model.getArtifactId().setValue("demo-project");
assertEquals("demo-1", model.getProjectName().getValue());
assertEquals("demo-project", model.getArtifactId().getValue());
model.getProjectName().setValue("demo-2");
assertEquals("demo-2", model.getProjectName().getValue());
assertEquals("demo-project", model.getArtifactId().getValue());
model.getArtifactId().setValue("demo-2");
assertEquals("demo-2", model.getProjectName().getValue());
assertEquals("demo-2", model.getArtifactId().getValue());
model.getProjectName().setValue("demo-3");
assertEquals("demo-3", model.getProjectName().getValue());
assertEquals("demo-3", model.getArtifactId().getValue());
}
public void testProjectNameSavedAndRestored() throws Exception {
//See: https://www.pivotaltracker.com/story/show/145645973
IPreferenceStore prefs = new MockPrefsStore();
{
NewSpringBootWizardModel model = parseFrom(INITIALIZR_JSON, prefs);
model.getProjectName().setValue("another-name");
model.performFinish(new NullProgressMonitor());
assertEquals("another-name", model.getProjectName().getValue());
}
{
NewSpringBootWizardModel model = parseFrom(INITIALIZR_JSON, prefs);
assertEquals("another-name", model.getProjectName().getValue());
}
ensureProject("another-name");
{
NewSpringBootWizardModel model = parseFrom(INITIALIZR_JSON, prefs);
assertEquals("another-name-1", model.getProjectName().getValue());
}
}
public void testRestoreFromOldBuildtypePreference() throws Exception {
//We here test a weak requirement that the wizard model 'handles' it okay when
// the preference saved in the workspace is from before the buildship refactoring.
//The requirements are:
// - it doesn't crash
// - it just chooses the maven build type / strategy by default. We do not
// attempt to map the old type-ids to the new ones.
MockPrefsStore prefs = new MockPrefsStore();
prefs.putValue("org.springframework.ide.eclipse.wizard.gettingstarted.boot.PreferredSelections.type", "gradle-project");
NewSpringBootWizardModel wizard = parseFrom(INITIALIZR_JSON, prefs);
assertEquals(BuildType.MAVEN, wizard.getBuildType());
assertEquals(BuildType.MAVEN.getDefaultStrategy(), wizard.getImportStrategy());
}
// private CheckBoxModel<Dependency> getCheckboxById(NewSpringBootWizardModel model, String id) {
// CheckBoxModel<Dependency> found = null;
// for (String cat : model.dependencies.getCategories()) {
// for (CheckBoxModel<Dependency> cb : model.dependencies.getContents(cat).getCheckBoxModels()) {
// if (cb.getValue().getId().equals(id)) {
// Assert.assertNull(found);
// found = cb;
// }
// }
// }
// return found;
// }
private void assertFilterAccepts(NewSpringBootWizardModel model, boolean expect, String pattern,
String id, String label, String desc) {
LiveVariable<String> searchBox = model.getDependencyFilterBoxText();
searchBox.setValue(pattern);
Filter<Dependency> filter = model.getDependencyFilter().getValue();
Dependency dep = new Dependency();
dep.setId(id);
dep.setName(label);
dep.setDescription(desc);
assertEquals(expect, filter.accept(dep));
}
private CheckBoxModel<Dependency> getCheckboxById(List<CheckBoxModel<Dependency>> list, String id) {
for (CheckBoxModel<Dependency> cb : list) {
if (id.equals(cb.getValue().getId())) {
return cb;
}
}
return null;
}
private void assertCheckboxes(List<CheckBoxModel<Dependency>> actuals, Dependency... expecteds) {
StringBuilder expectedIds = new StringBuilder();
for (Dependency e : expecteds) {
expectedIds.append(e.getId()+"\n");
}
StringBuilder actualIds = new StringBuilder();
for (CheckBoxModel<Dependency> cb : actuals) {
actualIds.append(cb.getValue().getId()+"\n");
}
assertEquals(expectedIds.toString(), actualIds.toString());
}
private void unselect(HierarchicalMultiSelectionFieldModel<Dependency> dependencies,
Dependency dep) {
String cat = getCategory(dependencies, dep);
MultiSelectionFieldModel<Dependency> selecteds = dependencies.getContents(cat);
selecteds.unselect(dep);
}
private void select(HierarchicalMultiSelectionFieldModel<Dependency> dependencies,
Dependency dep) {
String cat = getCategory(dependencies, dep);
MultiSelectionFieldModel<Dependency> selecteds = dependencies.getContents(cat);
selecteds.select(dep);
}
private Set<Dependency> getSelecteds(HierarchicalMultiSelectionFieldModel<Dependency> dependencies) {
HashSet<Dependency> selecteds = new HashSet<>();
for (String catName : dependencies.getCategories()) {
MultiSelectionFieldModel<Dependency> cat = dependencies.getContents(catName);
selecteds.addAll(cat.getCurrentSelection());
}
return selecteds;
}
private LiveExpression<Boolean> getEnablement(HierarchicalMultiSelectionFieldModel<Dependency> dependencies, Dependency dep) {
String cat = getCategory(dependencies, dep);
return dependencies.getContents(cat).getEnablement(dep);
}
private String getCategory( HierarchicalMultiSelectionFieldModel<Dependency> dependencies, Dependency dep) {
for (String cat : dependencies.getCategories()) {
if (contains(dependencies.getContents(cat).getChoices(), dep)) {
return cat;
}
}
throw new Error("Shouldn't get here");
}
private boolean contains(Dependency[] deps, Dependency find) {
for (Dependency dep : deps) {
if (find.equals(dep)) {
return true;
}
}
return false;
}
public void assertContains(String needle, String haystack) {
if (haystack==null || !haystack.contains(needle)) {
fail("Not found: "+needle+"\n in \n"+haystack);
}
}
private Dependency getDependencyById(NewSpringBootWizardModel model, String depId) {
for (Dependency dep : getAllChoices(model.dependencies)) {
if (dep.getId().equals(depId)) {
return dep;
}
}
return null;
}
public void testLabels() throws Exception {
NewSpringBootWizardModel model = parseFrom(INITIALIZR_JSON);
Iterator<FieldModel<String>> stringInputs = model.stringInputs.iterator();
while (stringInputs.hasNext()) {
FieldModel<String> input = stringInputs.next();
assertRealLabel(input.getLabel());
}
for (RadioGroup group : model.getRadioGroups().getGroups()) {
String label = group.getLabel();
assertRealLabel(label);
for (RadioInfo radio : group.getRadios()) {
label = radio.getLabel();
assertRealLabel(label);
}
}
}
public void testPrintLabels() throws Exception {
//print all radios in groups with lable for quick visual inspection.
NewSpringBootWizardModel model = parseFrom(INITIALIZR_JSON);
for (RadioGroup group : model.getRadioGroups().getGroups()) {
String label = group.getLabel();
System.out.println(group + " -> "+label);
for (RadioInfo radio : group.getRadios()) {
label = radio.getLabel();
System.out.println(" " + radio + " -> "+label);
}
}
}
/**
* Basic test of the 'spec parser'. Just check that it accepts a well-formed
* json spec document and doesn't crash on it.
*/
public void testInitializrSpecParser() throws Exception {
for (String f : testDataFiles) {
doParseTest(f);
}
}
private void doParseTest(String resource) throws IOException, Exception {
URL url = NewSpringBootWizardModelTest.class.getResource(resource);
URLConnection conn = new URLConnectionFactory().createConnection(url);
conn.connect();
InputStream input = conn.getInputStream();
try {
InitializrServiceSpec spec = InitializrServiceSpec.parseFrom(input);
assertNotNull(spec);
} finally {
input.close();
}
}
/**
* Test that radio params are wired up in the model so that selecting them changes the downloadUrl.
*/
public void testRadioQueryParams() throws Exception {
NewSpringBootWizardModel model = parseFrom(INITIALIZR_JSON);
RadioGroup packaging = model.getRadioGroups().getGroup("packaging");
LiveVariable<RadioInfo> selection = packaging.getSelection().selection;
assertEquals("jar", selection.getValue().getValue());
String urlParam = getUrlParam(model.downloadUrl.getValue(), "packaging");
assertEquals("jar", urlParam);
selection.setValue(packaging.getRadio("war"));
urlParam = getUrlParam(model.downloadUrl.getValue(), "packaging");
assertEquals("war", urlParam);
}
/**
* Test that radio params for 'type' properly use the typenames from start.spring.io spec
* and not the ids used internally to distinguish between grade+buildship versus gradle+sts
*/
public void testTypeRadioQueryParams() throws Exception {
NewSpringBootWizardModel model = parseFrom(INITIALIZR_JSON);
RadioGroup type = model.getRadioGroups().getGroup("type");
LiveVariable<RadioInfo> selection = type.getSelection().selection;
assertEquals("MAVEN", selection.getValue().getValue());
String urlParam = getUrlParam(model.downloadUrl.getValue(), "type");
assertEquals("maven-project", urlParam);
selection.setValue(type.getRadio("GRADLE"));
urlParam = getUrlParam(model.downloadUrl.getValue(), "type");
assertEquals("gradle-project", urlParam);
}
public static Map<String, List<String>> getQueryParams(String url) throws Exception {
Map<String, List<String>> params = new HashMap<>();
String[] urlParts = url.split("\\?");
if (urlParts.length > 1) {
String query = urlParts[1];
for (String param : query.split("&")) {
String[] pair = param.split("=");
String key = URLDecoder.decode(pair[0], "UTF-8");
String value = "";
if (pair.length > 1) {
value = URLDecoder.decode(pair[1], "UTF-8");
}
List<String> values = params.get(key);
if (values == null) {
values = new ArrayList<>();
params.put(key, values);
}
values.add(value);
}
}
return params;
}
private String getUrlParam(String url, String name) throws Exception {
Map<String, List<String>> params = getQueryParams(url);
List<String> values = params.get(name);
if (values!=null && !values.isEmpty()) {
assertEquals(1, values.size());
return values.get(0);
}
return null;
}
private void assertRealLabel(String label) {
assertNotNull("Label is null", label); //have a label
assertFalse("Label is empty", "".equals(label.trim())); //label not empty
if (Character.isDigit(label.charAt(0))) {
//labels like '1.6.' are okay too.
return;
}
assertTrue("Label doesn't start with uppercase: '"+label+"'", Character.isUpperCase(label.charAt(0))); //'real' label, not just the default taken from the name.
}
private void assertGroupValues(RadioGroup group, String... expecteds) {
Set<String> expectedSet = new HashSet<>(Arrays.asList(expecteds));
RadioInfo[] radios = group.getRadios();
StringBuilder found = new StringBuilder();
for (int i = 0; i < radios.length; i++) {
String actual = radios[i].getValue();
found.append(" "+actual);
if (!expectedSet.contains(actual)) {
fail("Unexpected: "+actual);
}
expectedSet.remove(actual);
}
if (!expectedSet.isEmpty()) {
StringBuilder notFound = new StringBuilder();
for (String missing : expectedSet) {
notFound.append(" "+missing);
}
fail("Missing: "+notFound+"\n Found: "+found);
}
}
private void assertGroupNames(RadioGroups radioGroups, String... expectNames) {
List<RadioGroup> groups = radioGroups.getGroups();
assertEquals(expectNames.length, groups.size());
for (int i = 0; i < expectNames.length; i++) {
assertEquals(expectNames[i], groups.get(i).getName());
}
}
public void testTemplateVariableSubstitution() throws Exception {
Map<String, String> values = new HashMap<>();
values.put("bootVersion", "2.0.0");
values.put("stars", "5");
String actual = InitializrServiceSpec.substituteTemplateVariables("Here is Spring Boot {bootVersion} version. It's rated with {stars} stars.", values);
assertEquals("Here is Spring Boot 2.0.0 version. It's rated with 5 stars.", actual);
actual = InitializrServiceSpec.substituteTemplateVariables("Here is Spring Boot {bootVersion} version.", values);
assertEquals("Here is Spring Boot 2.0.0 version.", actual);
try {
InitializrServiceSpec.substituteTemplateVariables("Here is Spring Boot {bootVersion} version. It's really {awesome} stuff!", values);
fail("Should have failed the template string variable substitution! Unknown variable expected!");
} catch (CoreException e) {
// ignore - let the test pass
}
}
}

View File

@@ -0,0 +1,69 @@
/*******************************************************************************
* Copyright (c) 2015 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.test;
import java.io.File;
import org.eclipse.core.resources.ResourcesPlugin;
import org.springsource.ide.eclipse.commons.frameworks.test.util.ExternalCommand;
import org.springsource.ide.eclipse.commons.frameworks.test.util.ExternalProcess;
import org.springsource.ide.eclipse.commons.tests.util.StsTestUtil;
import junit.framework.TestCase;
public class NewSpringBootWizardTest extends TestCase {
private BootProjectTestHarness harness;
@Override
protected void setUp() throws Exception {
StsTestUtil.cleanUpProjects();
harness = new BootProjectTestHarness(ResourcesPlugin.getWorkspace());
}
// public void test_STS_4260() throws Exception {
// if (OsUtils.isWindows()) {
// return;
// }
// //This test / bug is about unix file permissions so skip it
// // for windows.
// IProject project = harness.createBootProject("simple-boot");
// IFile mavenWrapper = project.getFile("mvnw");
// assertTrue(mavenWrapper.exists());
// assertExecutable(mavenWrapper);
// }
//
// public void testBuildshipProjectCreation() throws Exception {
// IProject project = harness.createBootProject("simple-buildship",
// withImportStrategy("GRADLE-Buildship 2.x")
// );
// assertTrue(project.hasNature(org.eclipse.buildship.core.configuration.GradleProjectNature.ID));
// assertTrue(project.hasNature(SpringCore.NATURE_ID));
// }
//
// private void assertExecutable(IFile eclipseFile) throws Exception {
// File file = eclipseFile.getRawLocation().toFile();
// assertTrue("File does not exist: "+file, file.exists());
// if (!file.canExecute()) {
// ExternalCommand cmd = new ExternalCommand("ls", "-la", file.getParent());
// ExternalProcess process = new ExternalProcess(new File("."), cmd, true);
// fail("File is not executable: "+file+"\n"+process);
// }
// }
//
public void testEchoJavaHome() throws Exception {
ExternalCommand cmd = new ExternalCommand("echo", "$JAVA_HOME");
File currentworkingFolder = new File(".").getCanonicalFile();
System.out.println("JAVA_HOME=" + new ExternalProcess(currentworkingFolder, cmd, true).getErr());
System.out.println("JAVA_HOME=" + new ExternalProcess(currentworkingFolder, cmd, true).getOut());
}
}

View File

@@ -0,0 +1,171 @@
/*******************************************************************************
* Copyright (c) 2015 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Kris De Volder - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.test;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.array;
import static org.hamcrest.Matchers.arrayWithSize;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.ui.IMarkerResolution;
import org.eclipse.ui.ide.IDE;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.Test;
import org.springsource.ide.eclipse.commons.frameworks.test.util.ACondition;
import org.springframework.ide.eclipse.boot.validation.framework.SpringBootProjectBuilder;
@SuppressWarnings("unchecked")
public class SpringBootValidationTest extends AbstractBootValidationTest {
public static final String MARKER_ID = SpringBootProjectBuilder.MARKER_ID;
@Test
public void testScaffolding() throws Exception {
String projectName = "simple-boot-project";
createPredefinedProject(projectName);
IJavaProject jp = getJavaProject(projectName);
assertNotNull(jp.findType("demo.FooProperties"));
}
@Test
public void testMissingConfigurationProcessorRuleOnClass() throws Exception {
String projectName = "simple-boot-project";
String resourcePath = "src/main/java/demo/FooProperties.java";
IProject p = createPredefinedProject(projectName);
IFile r = (IFile) p.findMember(resourcePath);
IMarker[] markers = getAllMarkers(r, MARKER_ID);
//Finds @ConfigrationProperties on Class?
assertThat(markers, array(
allOf(
markerWithMessageSnippet("@ConfigurationProperties"),
markerWithAreaCovering("ConfigurationProperties")
)
));
}
@Test
public void testMissingConfigurationProcessorRuleOnMethod() throws Exception {
String projectName = "simple-boot-project";
String resourcePath = "src/main/java/demo/FooConfiguration.java";
IProject p = createPredefinedProject(projectName);
IFile r = (IFile) p.findMember(resourcePath);
IMarker[] markers = getAllMarkers(r, MARKER_ID);
//Finds @ConfigrationProperties on Class?
assertThat(markers, array(
allOf(
markerWithMessageSnippet("@ConfigurationProperties"),
markerWithAreaCovering("ConfigurationProperties")
)
));
}
@Test
public void testMissingConfigurationProcessorQuickfix() throws Exception {
String projectName = "simple-boot-project";
String resourcePath = "src/main/java/demo/FooProperties.java";
final IProject p = createPredefinedProject(projectName);
final IFile r = (IFile) p.findMember(resourcePath);
IMarker[] markers = getAllMarkers(r, MARKER_ID);
//Finds @ConfigrationProperties on Class?
assertThat(markers, array(
allOf(
markerWithMessageSnippet("@ConfigurationProperties"),
markerWithAreaCovering("ConfigurationProperties")
)
));
IMarker marker = markers[0];
assertTrue(hasResolutions(marker));
IMarkerResolution[] resolutions = IDE.getMarkerHelpRegistry().getResolutions(marker);
assertThat(resolutions, array(
resolutionWithLabel("Add spring-boot-configuration-processor to pom.xml")
));
IFile pom = (IFile) p.findMember("pom.xml");
assertThat(getContents(pom), not(containsString("spring-boot-configuration-processor")));
IMarkerResolution quickfix = resolutions[0];
quickfix.run(marker);
assertThat(getContents(pom), containsString("<artifactId>spring-boot-configuration-processor</artifactId>"));
new ACondition("marker disapears after quickfix") {
public boolean test() throws Exception {
buildProject(p);
assertNoMarkers(getAllMarkers(r, MARKER_ID));
return true;
}
}.waitFor(10000);
}
private void buildProject(IProject p) throws Exception {
ISchedulingRule rule =ResourcesPlugin.getWorkspace().getRuleFactory().buildRule();
Job.getJobManager().beginRule(rule, new NullProgressMonitor());
try {
p.build(IncrementalProjectBuilder.FULL_BUILD, new NullProgressMonitor());
} finally {
Job.getJobManager().endRule(rule);
}
}
private Matcher<IMarkerResolution> resolutionWithLabel(final String snippet) {
return new TypeSafeMatcher<IMarkerResolution>() {
public void describeTo(Description description) {
description.appendText("resolutionWithLabel("+snippet+")");
}
protected void describeMismatchSafely(IMarkerResolution item,
Description mismatchDescription) {
String actual = item.getLabel();
mismatchDescription.appendText("[expected ");
mismatchDescription.appendDescriptionOf(this);
mismatchDescription.appendText(" but label is: ");
mismatchDescription.appendText(actual);
mismatchDescription.appendText("]");
}
protected boolean matchesSafely(IMarkerResolution item) {
String actual = item.getLabel();
return actual.equals(snippet);
}
};
}
protected boolean hasResolutions(IMarker marker) {
return IDE.getMarkerHelpRegistry().hasResolutions(marker);
}
}

View File

@@ -0,0 +1,49 @@
package org.springframework.ide.eclipse.boot.test;
import org.eclipse.core.runtime.IProgressMonitor;
public class SysOutProgressMonitor implements IProgressMonitor {
private String task;
@Override
public void beginTask(String task, int arg1) {
System.out.println("beginTask: "+task);
this.task = task;
}
@Override
public void done() {
System.out.println("beginTask"+task);
task = null;
}
@Override
public void internalWorked(double arg0) {
}
@Override
public boolean isCanceled() {
return false;
}
@Override
public void setCanceled(boolean arg0) {
}
@Override
public void setTaskName(String task) {
System.out.println("taskName = "+task);
}
@Override
public void subTask(String task) {
System.out.println("subTask = "+task);
}
@Override
public void worked(int arg0) {
System.err.print(".");
}
}

View File

@@ -0,0 +1,659 @@
{
"bootVersion": "2.0.3.RELEASE",
"dependencies": {
"aop": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-aop",
"scope": "compile"
},
"actuator": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-actuator",
"scope": "compile"
},
"data-redis-reactive": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-data-redis-reactive",
"scope": "compile"
},
"cloud-contract-stub-runner": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-starter-contract-stub-runner",
"scope": "test",
"bom": "spring-cloud"
},
"data-rest-hal": {
"groupId": "org.springframework.data",
"artifactId": "spring-data-rest-hal-browser",
"scope": "compile"
},
"azure-support": {
"groupId": "com.microsoft.azure",
"artifactId": "azure-spring-boot",
"scope": "compile",
"bom": "azure"
},
"validation": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-validation",
"scope": "compile"
},
"cloud-starter-zookeeper-config": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-starter-zookeeper-config",
"scope": "compile",
"bom": "spring-cloud"
},
"cloud-turbine": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-starter-netflix-turbine",
"scope": "compile",
"bom": "spring-cloud"
},
"cloud-hystrix": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-starter-netflix-hystrix",
"scope": "compile",
"bom": "spring-cloud"
},
"cache": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-cache",
"scope": "compile"
},
"spring-shell": {
"groupId": "org.springframework.shell",
"artifactId": "spring-shell-starter",
"version": "2.0.0.RELEASE",
"scope": "compile",
"repository": "spring-milestones"
},
"codecentric-spring-boot-admin-client": {
"groupId": "de.codecentric",
"artifactId": "spring-boot-admin-starter-client",
"scope": "compile",
"bom": "codecentric-spring-boot-admin"
},
"cloud-starter-consul-discovery": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-starter-consul-discovery",
"scope": "compile",
"bom": "spring-cloud"
},
"data-cassandra": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-data-cassandra",
"scope": "compile"
},
"azure-active-directory": {
"groupId": "com.microsoft.azure",
"artifactId": "azure-active-directory-spring-boot-starter",
"scope": "compile",
"bom": "azure"
},
"scs-circuit-breaker": {
"groupId": "io.pivotal.spring.cloud",
"artifactId": "spring-cloud-services-starter-circuit-breaker",
"scope": "compile",
"bom": "spring-cloud-services"
},
"kafka": {
"groupId": "org.springframework.kafka",
"artifactId": "spring-kafka",
"scope": "compile"
},
"scs-config-client": {
"groupId": "io.pivotal.spring.cloud",
"artifactId": "spring-cloud-services-starter-config-client",
"scope": "compile",
"bom": "spring-cloud-services"
},
"integration": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-integration",
"scope": "compile"
},
"cloud-security": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-starter-security",
"scope": "compile",
"bom": "spring-cloud"
},
"cloud-connectors": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-cloud-connectors",
"scope": "compile",
"bom": "spring-cloud"
},
"cloud-config-server": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-config-server",
"scope": "compile",
"bom": "spring-cloud"
},
"jta-atomikos": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-jta-atomikos",
"scope": "compile"
},
"cloud-turbine-stream": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-starter-netflix-turbine-stream",
"scope": "compile",
"bom": "spring-cloud"
},
"freemarker": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-freemarker",
"scope": "compile"
},
"vaadin": {
"groupId": "com.vaadin",
"artifactId": "vaadin-spring-boot-starter",
"scope": "compile",
"bom": "vaadin"
},
"web": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-web",
"scope": "compile"
},
"data-cassandra-reactive": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-data-cassandra-reactive",
"scope": "compile"
},
"cloud-ribbon": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-starter-netflix-ribbon",
"scope": "compile",
"bom": "spring-cloud"
},
"hsql": {
"groupId": "org.hsqldb",
"artifactId": "hsqldb",
"scope": "runtime"
},
"groovy-templates": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-groovy-templates",
"scope": "compile"
},
"data-couchbase-reactive": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-data-couchbase-reactive",
"scope": "compile"
},
"devtools": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-devtools",
"scope": "runtime"
},
"activemq": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-activemq",
"scope": "compile"
},
"cloud-starter": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-starter",
"scope": "compile",
"bom": "spring-cloud"
},
"amqp": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-amqp",
"scope": "compile"
},
"cloud-task": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-starter-task",
"scope": "compile",
"bom": "spring-cloud-task"
},
"cloud-bus": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-bus",
"scope": "compile",
"bom": "spring-cloud"
},
"kafka-streams": {
"groupId": "org.apache.kafka",
"artifactId": "kafka-streams",
"version": "1.0.1",
"scope": "compile"
},
"data-ldap": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-data-ldap",
"scope": "compile"
},
"data-neo4j": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-data-neo4j",
"scope": "compile"
},
"data-rest": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-data-rest",
"scope": "compile"
},
"mail": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-mail",
"scope": "compile"
},
"cloud-stream": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-stream",
"scope": "compile",
"bom": "spring-cloud"
},
"liquibase": {
"groupId": "org.liquibase",
"artifactId": "liquibase-core",
"scope": "compile"
},
"jta-bitronix": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-jta-bitronix",
"scope": "compile"
},
"reactive-cloud-stream": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-stream-reactive",
"scope": "compile",
"bom": "spring-cloud"
},
"websocket": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-websocket",
"scope": "compile"
},
"derby": {
"groupId": "org.apache.derby",
"artifactId": "derby",
"scope": "runtime"
},
"cloud-starter-zipkin": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-starter-zipkin",
"scope": "compile",
"bom": "spring-cloud"
},
"mysql": {
"groupId": "mysql",
"artifactId": "mysql-connector-java",
"scope": "runtime"
},
"cloud-starter-consul-config": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-starter-consul-config",
"scope": "compile",
"bom": "spring-cloud"
},
"data-couchbase": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-data-couchbase",
"scope": "compile"
},
"web-services": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-web-services",
"scope": "compile"
},
"cloud-oauth2": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-starter-oauth2",
"scope": "compile",
"bom": "spring-cloud"
},
"flyway": {
"groupId": "org.flywaydb",
"artifactId": "flyway-core",
"scope": "compile"
},
"configuration-processor": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-configuration-processor",
"scope": "compileOnly"
},
"batch": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-batch",
"scope": "compile"
},
"cloud-hystrix-dashboard": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-starter-netflix-hystrix-dashboard",
"scope": "compile",
"bom": "spring-cloud"
},
"data-jpa": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-data-jpa",
"scope": "compile"
},
"cloud-cloudfoundry-discovery": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-cloudfoundry-discovery",
"scope": "compile",
"bom": "spring-cloud"
},
"cloud-eureka": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-starter-netflix-eureka-client",
"scope": "compile",
"bom": "spring-cloud"
},
"thymeleaf": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-thymeleaf",
"scope": "compile"
},
"lombok": {
"groupId": "org.projectlombok",
"artifactId": "lombok",
"scope": "compileOnly"
},
"data-solr": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-data-solr",
"scope": "compile"
},
"jta-narayana": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-jta-narayana",
"scope": "compile"
},
"cloud-starter-vault-config": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-starter-vault-config",
"scope": "compile",
"bom": "spring-cloud"
},
"codecentric-spring-boot-admin-server": {
"groupId": "de.codecentric",
"artifactId": "spring-boot-admin-starter-server",
"scope": "compile",
"bom": "codecentric-spring-boot-admin"
},
"data-redis": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-data-redis",
"scope": "compile"
},
"cloud-starter-zookeeper-discovery": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-starter-zookeeper-discovery",
"scope": "compile",
"bom": "spring-cloud"
},
"session": {
"groupId": "org.springframework.session",
"artifactId": "spring-session-core",
"scope": "compile"
},
"mybatis": {
"groupId": "org.mybatis.spring.boot",
"artifactId": "mybatis-spring-boot-starter",
"version": "1.3.2",
"scope": "compile"
},
"data-mongodb": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-data-mongodb",
"scope": "compile"
},
"webflux": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-webflux",
"scope": "compile"
},
"flapdoodle-mongo": {
"groupId": "de.flapdoodle.embed",
"artifactId": "de.flapdoodle.embed.mongo",
"scope": "test"
},
"jdbc": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-jdbc",
"scope": "compile"
},
"h2": {
"groupId": "com.h2database",
"artifactId": "h2",
"scope": "runtime"
},
"azure-keyvault-secrets": {
"groupId": "com.microsoft.azure",
"artifactId": "azure-keyvault-secrets-spring-boot-starter",
"scope": "compile",
"bom": "azure"
},
"cloud-contract-verifier": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-starter-contract-verifier",
"scope": "test",
"bom": "spring-cloud"
},
"cloud-gateway": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-starter-gateway",
"scope": "compile",
"bom": "spring-cloud"
},
"mustache": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-mustache",
"scope": "compile"
},
"cloud-gcp-pubsub": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-gcp-starter-pubsub",
"scope": "compile",
"bom": "spring-cloud-gcp"
},
"data-mongodb-reactive": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-data-mongodb-reactive",
"scope": "compile"
},
"cloud-feign": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-starter-openfeign",
"scope": "compile",
"bom": "spring-cloud"
},
"security": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-security",
"scope": "compile"
},
"cloud-zuul": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-starter-netflix-zuul",
"scope": "compile",
"bom": "spring-cloud"
},
"sqlserver": {
"groupId": "com.microsoft.sqlserver",
"artifactId": "mssql-jdbc",
"scope": "runtime"
},
"postgresql": {
"groupId": "org.postgresql",
"artifactId": "postgresql",
"scope": "runtime"
},
"jooq": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-jooq",
"scope": "compile"
},
"jersey": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-jersey",
"scope": "compile"
},
"hateoas": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-hateoas",
"scope": "compile"
},
"scs-service-registry": {
"groupId": "io.pivotal.spring.cloud",
"artifactId": "spring-cloud-services-starter-service-registry",
"scope": "compile",
"bom": "spring-cloud-services"
},
"statemachine": {
"groupId": "org.springframework.statemachine",
"artifactId": "spring-statemachine-starter",
"scope": "compile",
"bom": "spring-statemachine"
},
"retry": {
"groupId": "org.springframework.retry",
"artifactId": "spring-retry",
"scope": "compile"
},
"cloud-aws-messaging": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-starter-aws-messaging",
"scope": "compile",
"bom": "spring-cloud"
},
"cloud-starter-sleuth": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-starter-sleuth",
"scope": "compile",
"bom": "spring-cloud"
},
"data-elasticsearch": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-data-elasticsearch",
"scope": "compile"
},
"cloud-aws": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-starter-aws",
"scope": "compile",
"bom": "spring-cloud"
},
"artemis": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-artemis",
"scope": "compile"
},
"restdocs": {
"groupId": "org.springframework.restdocs",
"artifactId": "spring-restdocs-mockmvc",
"scope": "test"
},
"quartz": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter-quartz",
"scope": "compile"
},
"cloud-gcp-storage": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-gcp-starter-storage",
"scope": "compile",
"bom": "spring-cloud-gcp"
},
"azure-storage": {
"groupId": "com.microsoft.azure",
"artifactId": "azure-storage-spring-boot-starter",
"scope": "compile",
"bom": "azure"
},
"cloud-eureka-server": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-starter-netflix-eureka-server",
"scope": "compile",
"bom": "spring-cloud"
},
"cloud-aws-jdbc": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-starter-aws-jdbc",
"scope": "compile",
"bom": "spring-cloud"
},
"cloud-gcp": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-gcp-starter",
"scope": "compile",
"bom": "spring-cloud-gcp"
},
"cloud-config-client": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-starter-config",
"scope": "compile",
"bom": "spring-cloud"
}
},
"repositories": {
"spring-milestones": {
"name": "Spring Milestones",
"url": "https://repo.spring.io/milestone",
"snapshotEnabled": false
}
},
"boms": {
"codecentric-spring-boot-admin": {
"groupId": "de.codecentric",
"artifactId": "spring-boot-admin-dependencies",
"version": "2.0.0",
"repositories": []
},
"spring-cloud-task": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-task-dependencies",
"version": "2.0.0.RELEASE",
"repositories": []
},
"spring-cloud": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-dependencies",
"version": "Finchley.RC2",
"repositories": [
"spring-milestones"
]
},
"vaadin": {
"groupId": "com.vaadin",
"artifactId": "vaadin-bom",
"version": "8.4.1",
"repositories": []
},
"spring-statemachine": {
"groupId": "org.springframework.statemachine",
"artifactId": "spring-statemachine-bom",
"version": "2.0.1.RELEASE",
"repositories": []
},
"spring-cloud-services": {
"groupId": "io.pivotal.spring.cloud",
"artifactId": "spring-cloud-services-dependencies",
"version": "2.0.0.RC1",
"repositories": [
"spring-milestones"
]
},
"spring-cloud-gcp": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-gcp-dependencies",
"version": "1.0.0.M3",
"repositories": [
"spring-milestones"
]
},
"azure": {
"groupId": "com.microsoft.azure",
"artifactId": "azure-spring-boot-bom",
"version": "2.0.3",
"repositories": []
}
}
}

View File

@@ -0,0 +1,40 @@
{
"bootVersion": "2.0.3.RELEASE",
"dependencies": {
"cloud-eureka": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-starter-eureka",
"scope": "compile",
"bom": "cloud-bom"
},
"fake-dep": {
"groupId": "org.springframework.fake",
"artifactId": "spring-fake-dep",
"scope": "compile",
"repository": "spring-milestones"
}
},
"repositories": {
"spring-snapshots": {
"name": "Spring Snapshots",
"url": "https:\/\/repo.spring.io\/snapshot",
"snapshotEnabled": true
},
"spring-milestones": {
"name": "Spring Milestones",
"url": "https:\/\/repo.spring.io\/milestone",
"snapshotEnabled": false
}
},
"boms": {
"cloud-bom": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-dependencies",
"version": "Finchley.RC2",
"repositories": [
"spring-milestones",
"spring-snapshots"
]
}
}
}

View File

@@ -0,0 +1,190 @@
{
"_links": {
"maven-project": {
"href": "https://start.spring.io/starter.zip?type=maven-project{&dependencies,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated": true
},
"maven-build": {
"href": "https://start.spring.io/pom.xml?type=maven-build{&dependencies,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated": true
},
"gradle-project": {
"href": "https://start.spring.io/starter.zip?type=gradle-project{&dependencies,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated": true
},
"gradle-build": {
"href": "https://start.spring.io/build.gradle?type=gradle-build{&dependencies,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated": true
},
"dependencies": {
"href": "https://start.spring.io/dependencies{?bootVersion}",
"templated": true
}
},
"dependencies": {
"type": "hierarchical-multi-select",
"values": [
{
"name": "Cloud Discovery",
"values": [
{
"id": "cloud-eureka",
"name": "Eureka Discovery",
"description": "Service discovery using spring-cloud-netflix and Eureka",
"versionRange": "1.2.3.RELEASE"
},
{
"id": "fake-dep",
"name": "Fake Dependency",
"description": "Does not really exist"
}
]
}
]
},
"type": {
"type": "action",
"default": "maven-project",
"values": [
{
"id": "maven-project",
"name": "Maven Project",
"description": "Generate a Maven based project archive",
"action": "/starter.zip",
"tags": {
"build": "maven",
"format": "project"
}
},
{
"id": "maven-build",
"name": "Maven POM",
"description": "Generate a Maven pom.xml",
"action": "/pom.xml",
"tags": {
"build": "maven",
"format": "build"
}
},
{
"id": "gradle-project",
"name": "Gradle Project",
"description": "Generate a Gradle based project archive",
"action": "/starter.zip",
"tags": {
"build": "gradle",
"format": "project"
}
},
{
"id": "gradle-build",
"name": "Gradle Config",
"description": "Generate a Gradle build file",
"action": "/build.gradle",
"tags": {
"build": "gradle",
"format": "build"
}
}
]
},
"packaging": {
"type": "single-select",
"default": "jar",
"values": [
{
"id": "jar",
"name": "Jar"
},
{
"id": "war",
"name": "War"
}
]
},
"javaVersion": {
"type": "single-select",
"default": "1.8",
"values": [
{
"id": "10",
"name": "10"
},
{
"id": "1.8",
"name": "8"
}
]
},
"language": {
"type": "single-select",
"default": "java",
"values": [
{
"id": "java",
"name": "Java"
},
{
"id": "kotlin",
"name": "Kotlin"
},
{
"id": "groovy",
"name": "Groovy"
}
]
},
"bootVersion": {
"type": "single-select",
"default": "2.0.3.RELEASE",
"values": [
{
"id": "2.1.0.BUILD-SNAPSHOT",
"name": "2.1.0 (SNAPSHOT)"
},
{
"id": "2.0.4.BUILD-SNAPSHOT",
"name": "2.0.4 (SNAPSHOT)"
},
{
"id": "2.0.3.RELEASE",
"name": "2.0.3"
},
{
"id": "1.5.15.BUILD-SNAPSHOT",
"name": "1.5.15 (SNAPSHOT)"
},
{
"id": "1.5.14.RELEASE",
"name": "1.5.14"
}
]
},
"groupId": {
"type": "text",
"default": "com.example"
},
"artifactId": {
"type": "text",
"default": "demo"
},
"version": {
"type": "text",
"default": "0.0.1-SNAPSHOT"
},
"name": {
"type": "text",
"default": "demo"
},
"description": {
"type": "text",
"default": "Demo project for Spring Boot"
},
"packageName": {
"type": "text",
"default": "com.example.demo"
}
}

View File

@@ -0,0 +1,315 @@
{
"dependencies": {
"type": "hierarchical-multi-select",
"values": [
{
"name": "Core",
"values": [
{
"id": "security",
"name": "Security",
"description": "Support for spring-security"
},
{
"id": "aop",
"name": "AOP",
"description": "Support for aspect-oriented programming including spring-aop and AspectJ"
}
]
},
{
"name": "Data",
"values": [
{
"id": "jdbc",
"name": "JDBC",
"description": "Support for JDBC databases"
},
{
"id": "data-jpa",
"name": "JPA",
"description": "Support for the Java Persistence API including spring-data-jpa, spring-orm and Hibernate"
},
{
"id": "data-mongodb",
"name": "MongoDB",
"description": "Support for the MongoDB NoSQL Database, including spring-data-mongodb"
},
{
"id": "redis",
"name": "Redis",
"description": "Support for the REDIS key-value data store, including spring-redis"
},
{
"id": "data-gemfire",
"name": "Gemfire",
"description": "Support for the GemFire distributed data store including spring-data-gemfire"
},
{
"id": "data-solr",
"name": "Solr",
"description": "Support for the Apache Solr search platform, including spring-data-solr"
},
{
"id": "data-elasticsearch",
"name": "Elasticsearch",
"description": "Support for the Elasticsearch search and analytics engine including spring-data-elasticsearch"
}
]
},
{
"name": "I/O",
"values": [
{
"id": "batch",
"name": "Batch",
"description": "Support for Spring Batch including HSQLDB database"
},
{
"id": "integration",
"name": "Integration",
"description": "Support for common spring-integration modules"
},
{
"id": "hornetq",
"name": "JMS",
"description": "Support for Java Message Service API via HornetQ"
},
{
"id": "amqp",
"name": "AMQP",
"description": "Support for the Advanced Message Queuing Protocol via spring-rabbit"
}
]
},
{
"name": "Web",
"values": [
{
"id": "web",
"name": "Web",
"description": "Support for full-stack web development, including Tomcat and spring-webmvc"
},
{
"id": "websocket",
"name": "Websocket",
"description": "Support for websocket development with Tomcat"
},
{
"id": "ws",
"name": "WS",
"description": "Support for Spring Web Services"
},
{
"id": "data-rest",
"name": "Rest Repositories",
"description": "Support for exposing Spring Data repositories over REST via spring-data-rest-webmvc"
},
{
"id": "mobile",
"name": "Mobile",
"description": "Support for spring-mobile"
}
]
},
{
"name": "Template Engines",
"values": [
{
"id": "freemarker",
"name": "Freemarker",
"description": "Support for the FreeMarker templating engine"
},
{
"id": "velocity",
"name": "Velocity",
"description": "Support for the Velocity templating engine"
},
{
"id": "groovy-templates",
"name": "Groovy Templates",
"description": "Support for the Groovy templating engine"
},
{
"id": "thymeleaf",
"name": "Thymeleaf",
"description": "Support for the Thymeleaf templating engine, including integration with Spring"
}
]
},
{
"name": "Social",
"values": [
{
"id": "social-facebook",
"name": "Facebook",
"description": "Support for spring-social-facebook"
},
{
"id": "social-linkedin",
"name": "LinkedIn",
"description": "Support for spring-social-linkedin"
},
{
"id": "social-twitter",
"name": "Twitter",
"description": "Support for spring-social-twitter"
}
]
},
{
"name": "Ops",
"values": [
{
"id": "actuator",
"name": "Actuator",
"description": "Production ready features to help you monitor and manage your application"
},
{
"id": "remote-shell",
"name": "Remote Shell",
"description": "Support for CRaSH"
}
]
}
]
},
"type": {
"type": "action",
"default": "maven-project",
"values": [
{
"id": "maven-build",
"name": "Maven POM",
"action": "/pom.xml",
"tags": {
"build": "maven",
"format": "build"
}
},
{
"id": "maven-project",
"name": "Maven Project",
"action": "/starter.zip",
"tags": {
"format": "project",
"build": "maven"
}
},
{
"id": "gradle-build",
"name": "Gradle Config",
"action": "/build.gradle",
"tags": {
"build": "gradle",
"format": "build"
}
},
{
"id": "gradle-project",
"name": "Gradle Project",
"action": "/starter.zip",
"tags": {
"format": "project",
"build": "gradle"
}
}
]
},
"packaging": {
"type": "single-select",
"default": "jar",
"values": [
{
"id": "jar",
"name": "Jar"
},
{
"id": "war",
"name": "War"
}
]
},
"javaVersion": {
"type": "single-select",
"default": "1.7",
"values": [
{
"id": "1.6",
"name": "1.6"
},
{
"id": "1.7",
"name": "1.7"
},
{
"id": "1.8",
"name": "1.8"
}
]
},
"language": {
"type": "single-select",
"default": "java",
"values": [
{
"id": "groovy",
"name": "Groovy"
},
{
"id": "java",
"name": "Java"
}
]
},
"bootVersion": {
"type": "single-select",
"default": "1.1.9.RELEASE",
"values": [
{
"id": "1.2.0.RC1",
"name": "1.2.0 RC1"
},
{
"id": "1.2.0.BUILD-SNAPSHOT",
"name": "1.2.0 (SNAPSHOT)"
},
{
"id": "1.1.9.RELEASE",
"name": "1.1.9"
},
{
"id": "1.1.8.BUILD-SNAPSHOT",
"name": "1.1.8 (SNAPSHOT)"
},
{
"id": "1.0.2.RELEASE",
"name": "1.0.2"
}
]
},
"groupId": {
"type": "text",
"default": "org.test"
},
"artifactId": {
"type": "text",
"default": "demo"
},
"version": {
"type": "text",
"default": "0.0.1-SNAPSHOT"
},
"name": {
"type": "text",
"default": "demo"
},
"description": {
"type": "text",
"default": "Demo project for Spring Boot"
},
"packageName": {
"type": "text",
"default": "demo"
}
}

View File

@@ -0,0 +1,540 @@
{
"_links": {
"maven-build": {
"href": "https:\/\/start.spring.io\/pom.xml?type=maven-build{&dependencies,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated": true
},
"maven-project": {
"href": "https:\/\/start.spring.io\/starter.zip?type=maven-project{&dependencies,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated": true
},
"gradle-build": {
"href": "https:\/\/start.spring.io\/build.gradle?type=gradle-build{&dependencies,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated": true
},
"gradle-project": {
"href": "https:\/\/start.spring.io\/starter.zip?type=gradle-project{&dependencies,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated": true
}
},
"dependencies": {
"type": "hierarchical-multi-select",
"values": [
{
"name": "Core",
"values": [
{
"id": "security",
"name": "Security",
"description": "Support for spring-security"
},
{
"id": "aop",
"name": "AOP",
"description": "Support for aspect-oriented programming including spring-aop and AspectJ"
},
{
"id": "jta-atomikos",
"name": "Atomikos (JTA)",
"description": "Support for JTA distributed transactions via Atomikos",
"versionRange": "1.2.0.M1"
},
{
"id": "jta-bitronix",
"name": "Bitronix (JTA)",
"description": "Support for JTA distributed transactions via Bitronix",
"versionRange": "1.2.0.M1"
},
{
"id": "cache",
"name": "Cache",
"description": "Support for Spring's Cache abstraction",
"versionRange": "1.3.0.M1"
},
{
"id": "devtools",
"name": "DevTools",
"description": "Support for Spring Boot Development Tools.",
"versionRange": "1.3.0.M1"
}
]
},
{
"name": "Web",
"values": [
{
"id": "web",
"name": "Web",
"description": "Support for full-stack web development, including Tomcat and spring-webmvc"
},
{
"id": "websocket",
"name": "Websocket",
"description": "Support for websocket development with Tomcat"
},
{
"id": "ws",
"name": "WS",
"description": "Support for Spring Web Services"
},
{
"id": "jersey",
"name": "Jersey (JAX-RS)",
"description": "Support for the Jersey RESTful Web Services framework",
"versionRange": "1.2.0.RELEASE"
},
{
"id": "vaadin",
"name": "Vaadin",
"description": "Support for Vaadin"
},
{
"id": "data-rest",
"name": "Rest Repositories",
"description": "Support for exposing Spring Data repositories over REST via spring-data-rest-webmvc"
},
{
"id": "hateoas",
"name": "HATEOAS",
"description": "Support for HATEOAS-based RESTful services",
"versionRange": "1.2.2.RELEASE"
},
{
"id": "mobile",
"name": "Mobile",
"description": "Support for spring-mobile"
}
]
},
{
"name": "Template Engines",
"values": [
{
"id": "freemarker",
"name": "Freemarker",
"description": "Support for the FreeMarker templating engine"
},
{
"id": "velocity",
"name": "Velocity",
"description": "Support for the Velocity templating engine"
},
{
"id": "groovy-templates",
"name": "Groovy Templates",
"description": "Support for the Groovy templating engine"
},
{
"id": "thymeleaf",
"name": "Thymeleaf",
"description": "Support for the Thymeleaf templating engine, including integration with Spring"
},
{
"id": "mustache",
"name": "Mustache",
"description": "Support for the Mustache templating engine",
"versionRange": "1.2.2.RELEASE"
}
]
},
{
"name": "Data",
"values": [
{
"id": "jdbc",
"name": "JDBC",
"description": "Support for JDBC databases"
},
{
"id": "data-jpa",
"name": "JPA",
"description": "Support for the Java Persistence API including spring-data-jpa, spring-orm and Hibernate"
},
{
"id": "data-mongodb",
"name": "MongoDB",
"description": "Support for the MongoDB NoSQL Database, including spring-data-mongodb"
},
{
"id": "redis",
"name": "Redis",
"description": "Support for the REDIS key-value data store, including spring-redis"
},
{
"id": "data-gemfire",
"name": "Gemfire",
"description": "Support for the GemFire distributed data store including spring-data-gemfire"
},
{
"id": "data-solr",
"name": "Solr",
"description": "Support for the Apache Solr search platform, including spring-data-solr"
},
{
"id": "data-elasticsearch",
"name": "Elasticsearch",
"description": "Support for the Elasticsearch search and analytics engine including spring-data-elasticsearch"
}
]
},
{
"name": "Cloud",
"values": [
{
"id": "cloud-connectors",
"name": "Cloud Connectors",
"description": "Simplifies connecting to services in cloud platforms",
"versionRange": "1.2.0.RELEASE"
},
{
"id": "cloud-starter",
"name": "Cloud Bootstrap",
"description": "Support for spring-cloud-context (e.g. Bootstrap context and @RefreshScope)",
"versionRange": "1.2.3.RELEASE"
},
{
"id": "cloud-config-client",
"name": "Config Client",
"description": "Support for spring-cloud-config Client",
"versionRange": "1.2.3.RELEASE"
},
{
"id": "cloud-config-server",
"name": "Config Server",
"description": "Support for spring-cloud-config Server",
"versionRange": "1.2.3.RELEASE"
},
{
"id": "cloud-eureka",
"name": "Eureka",
"description": "Support for spring-cloud-netflix Eureka",
"versionRange": "1.2.3.RELEASE"
},
{
"id": "cloud-eureka-server",
"name": "Eureka Server",
"description": "Support for spring-cloud-netflix Eureka Server",
"versionRange": "1.2.3.RELEASE"
},
{
"id": "cloud-aws",
"name": "AWS",
"description": "Support for spring-cloud-aws",
"versionRange": "1.2.3.RELEASE"
},
{
"id": "cloud-feign",
"name": "Feign",
"description": "Support for spring-cloud-netflix Feign",
"versionRange": "1.2.3.RELEASE"
},
{
"id": "cloud-hystrix",
"name": "Hystrix",
"description": "Support for spring-cloud-netflix Hystrix",
"versionRange": "1.2.3.RELEASE"
},
{
"id": "cloud-hystrix-dashboard",
"name": "Hystrix Dashboard",
"description": "Support for spring-cloud-netflix Hystrix Dashboard",
"versionRange": "1.2.3.RELEASE"
},
{
"id": "cloud-oauth2",
"name": "OAuth2",
"description": "Support for spring-cloud-security OAuth2",
"versionRange": "1.2.3.RELEASE"
},
{
"id": "cloud-ribbon",
"name": "Ribbon",
"description": "Support for spring-cloud-netflix Ribbon",
"versionRange": "1.2.3.RELEASE"
},
{
"id": "cloud-turbine",
"name": "Turbine",
"description": "Support for spring-cloud-netflix Turbine",
"versionRange": "1.2.3.RELEASE"
},
{
"id": "cloud-turbine-amqp",
"name": "Turbine AMQP",
"description": "Support for spring-cloud-netflix Turbine AMQP",
"versionRange": "1.2.3.RELEASE"
},
{
"id": "cloud-zuul",
"name": "Zuul",
"description": "Support for spring-cloud-netflix Zuul",
"versionRange": "1.2.3.RELEASE"
},
{
"id": "cloud-aws-jdbc",
"name": "AWS JDBC",
"description": "Support for spring-cloud-aws-jdbc",
"versionRange": "1.2.3.RELEASE"
},
{
"id": "cloud-aws-messaging",
"name": "AWS Messaging",
"description": "Support for spring-cloud-aws-messaging",
"versionRange": "1.2.3.RELEASE"
},
{
"id": "cloud-bus-amqp",
"name": "Cloud Bus AMQP",
"description": "Support for spring-cloud-bus-amqp",
"versionRange": "1.2.3.RELEASE"
},
{
"id": "cloud-security",
"name": "Cloud Security",
"description": "Support for spring-cloud-security",
"versionRange": "1.2.3.RELEASE"
}
]
},
{
"name": "Database",
"values": [
{
"id": "h2",
"name": "H2",
"description": "Support for the H2 database (with embedded support)"
},
{
"id": "hsql",
"name": "HSQLDB",
"description": "Support for the HSQLDB database (with embedded support)"
},
{
"id": "derby",
"name": "Apache Derby",
"description": "Support for the Apache Derby database (with embedded support)",
"versionRange": "1.2.2.RELEASE"
},
{
"id": "mysql",
"name": "MySQL",
"description": "Support for the MySQL jdbc driver"
},
{
"id": "postgresql",
"name": "PostgreSQL",
"description": "Support for the PostgreSQL jdbc driver"
}
]
},
{
"name": "Social",
"values": [
{
"id": "social-facebook",
"name": "Facebook",
"description": "Support for spring-social-facebook"
},
{
"id": "social-linkedin",
"name": "LinkedIn",
"description": "Support for spring-social-linkedin"
},
{
"id": "social-twitter",
"name": "Twitter",
"description": "Support for spring-social-twitter"
}
]
},
{
"name": "I\/O",
"values": [
{
"id": "batch",
"name": "Batch",
"description": "Support for Spring Batch including HSQLDB database"
},
{
"id": "integration",
"name": "Integration",
"description": "Support for common spring-integration modules"
},
{
"id": "hornetq",
"name": "JMS",
"description": "Support for Java Message Service API via HornetQ"
},
{
"id": "amqp",
"name": "AMQP",
"description": "Support for the Advanced Message Queuing Protocol via spring-rabbit"
},
{
"id": "mail",
"name": "Mail",
"description": "Support for javax.mail",
"versionRange": "1.2.0.RC1"
}
]
},
{
"name": "Ops",
"values": [
{
"id": "actuator",
"name": "Actuator",
"description": "Production ready features to help you monitor and manage your application"
},
{
"id": "remote-shell",
"name": "Remote Shell",
"description": "Support for CRaSH"
}
]
}
]
},
"type": {
"type": "action",
"default": "maven-project",
"values": [
{
"id": "maven-build",
"name": "Maven POM",
"description": "Generate a Maven pom.xml",
"action": "\/pom.xml",
"tags": {
"build": "maven",
"format": "build"
}
},
{
"id": "maven-project",
"name": "Maven Project",
"description": "Generate a Maven based project archive",
"action": "\/starter.zip",
"tags": {
"build": "maven",
"format": "project"
}
},
{
"id": "gradle-build",
"name": "Gradle Config",
"description": "Generate a Gradle build file",
"action": "\/build.gradle",
"tags": {
"build": "gradle",
"format": "build"
}
},
{
"id": "gradle-project",
"name": "Gradle Project",
"description": "Generate a Gradle based project archive",
"action": "\/starter.zip",
"tags": {
"build": "gradle",
"format": "project"
}
}
]
},
"packaging": {
"type": "single-select",
"default": "jar",
"values": [
{
"id": "jar",
"name": "Jar"
},
{
"id": "war",
"name": "War"
}
]
},
"javaVersion": {
"type": "single-select",
"default": "1.8",
"values": [
{
"id": "1.6",
"name": "1.6"
},
{
"id": "1.7",
"name": "1.7"
},
{
"id": "1.8",
"name": "1.8"
}
]
},
"language": {
"type": "single-select",
"default": "java",
"values": [
{
"id": "groovy",
"name": "Groovy"
},
{
"id": "java",
"name": "Java"
}
]
},
"bootVersion": {
"type": "single-select",
"default": "1.2.5.RELEASE",
"values": [
{
"id": "1.3.0.M2",
"name": "1.3.0 M2"
},
{
"id": "1.3.0.BUILD-SNAPSHOT",
"name": "1.3.0 (SNAPSHOT)"
},
{
"id": "1.2.6.BUILD-SNAPSHOT",
"name": "1.2.6 (SNAPSHOT)"
},
{
"id": "1.2.5.RELEASE",
"name": "1.2.5"
},
{
"id": "1.1.12.RELEASE",
"name": "1.1.12"
}
]
},
"groupId": {
"type": "text",
"default": "org.test"
},
"artifactId": {
"type": "text",
"default": "demo"
},
"version": {
"type": "text",
"default": "0.0.1-SNAPSHOT"
},
"name": {
"type": "text",
"default": "demo"
},
"description": {
"type": "text",
"default": "Demo project for Spring Boot"
},
"packageName": {
"type": "text",
"default": "demo"
}
}

View File

@@ -0,0 +1,196 @@
{
"_links" : {
"maven-build" : {
"href" : "https://start.spring.io/pom.xml?type=maven-build{&dependencies,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated" : true
},
"maven-project" : {
"href" : "https://start.spring.io/starter.zip?type=maven-project{&dependencies,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated" : true
},
"gradle-build" : {
"href" : "https://start.spring.io/build.gradle?type=gradle-build{&dependencies,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated" : true
},
"gradle-project" : {
"href" : "https://start.spring.io/starter.zip?type=gradle-project{&dependencies,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated" : true
},
"dependencies" : {
"href" : "https://start.spring.io/dependencies{?bootVersion}",
"templated" : true
}
},
"dependencies" : {
"type" : "hierarchical-multi-select",
"values" : [ {
"name" : "Core",
"values" : [ {
"id" : "web",
"name" : "Web",
"description" : "Web dependency description",
"_links" : {
"guide" : {
"href" : "https://example.com/guide",
"title" : "Building a RESTful Web Service"
},
"reference" : {
"href" : "https://example.com/doc"
}
}
}, {
"id" : "security",
"name" : "Security"
}, {
"id" : "data-jpa",
"name" : "Data JPA"
} ]
}, {
"name" : "Other",
"values" : [ {
"id" : "org.acme:foo",
"name" : "Foo",
"_links" : {
"guide" : [ {
"href" : "https://example.com/guide1"
}, {
"href" : "https://example.com/guide2",
"title" : "Some guide for foo"
} ],
"reference" : {
"href" : "https://example.com/{bootVersion}/doc",
"templated" : true
}
}
}, {
"id" : "org.acme:bar",
"name" : "Bar"
}, {
"id" : "org.acme:biz",
"name" : "Biz",
"versionRange" : "2.2.0.BUILD-SNAPSHOT"
}, {
"id" : "org.acme:bur",
"name" : "Bur",
"versionRange" : "[2.1.4.RELEASE,2.4.0-SNAPSHOT)"
}, {
"id" : "my-api",
"name" : "My API"
} ]
} ]
},
"type" : {
"type" : "action",
"default" : "maven-project",
"values" : [ {
"id" : "maven-build",
"name" : "Maven POM",
"action" : "/pom.xml",
"tags" : {
"build" : "maven",
"format" : "build"
}
}, {
"id" : "maven-project",
"name" : "Maven Project",
"action" : "/starter.zip",
"tags" : {
"format" : "project",
"build" : "maven"
}
}, {
"id" : "gradle-build",
"name" : "Gradle Config",
"action" : "/build.gradle",
"tags" : {
"build" : "gradle",
"format" : "build"
}
}, {
"id" : "gradle-project",
"name" : "Gradle Project",
"action" : "/starter.zip",
"tags" : {
"format" : "project",
"build" : "gradle"
}
} ]
},
"packaging" : {
"type" : "single-select",
"default" : "jar",
"values" : [ {
"id" : "jar",
"name" : "Jar"
}, {
"id" : "war",
"name" : "War"
} ]
},
"javaVersion" : {
"type" : "single-select",
"default" : "1.8",
"values" : [ {
"id" : "1.6",
"name" : "1.6"
}, {
"id" : "1.7",
"name" : "1.7"
}, {
"id" : "1.8",
"name" : "1.8"
} ]
},
"language" : {
"type" : "single-select",
"default" : "java",
"values" : [ {
"id" : "groovy",
"name" : "Groovy"
}, {
"id" : "java",
"name" : "Java"
}, {
"id" : "kotlin",
"name" : "Kotlin"
} ]
},
"bootVersion" : {
"type" : "single-select",
"default" : "2.1.4.RELEASE",
"values" : [ {
"id" : "2.4.0-SNAPSHOT",
"name" : "Latest SNAPSHOT"
}, {
"id" : "2.1.4.RELEASE",
"name" : "2.1.4"
}, {
"id" : "1.5.17.RELEASE",
"name" : "1.5.17"
} ]
},
"groupId" : {
"type" : "text",
"default" : "com.example"
},
"artifactId" : {
"type" : "text",
"default" : "demo"
},
"version" : {
"type" : "text",
"default" : "0.0.1-SNAPSHOT"
},
"name" : {
"type" : "text",
"default" : "demo"
},
"description" : {
"type" : "text",
"default" : "Demo project for Spring Boot"
},
"packageName" : {
"type" : "text",
"default" : "com.example.demo"
}
}

View File

@@ -0,0 +1,333 @@
{
"_links": {
"maven-build": {
"href": "https://start.spring.io/pom.xml{?dependencies,type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated": true
},
"maven-project": {
"href": "https://start.spring.io/maven.zip{?dependencies,type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated": true
},
"gradle-build": {
"href": "https://start.spring.io/build.gradle{?dependencies,type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated": true
},
"gradle-project": {
"href": "https://start.spring.io/gradle.zip{?dependencies,type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
"templated": true
}
},
"dependencies": {
"type": "hierarchical-multi-select",
"values": [
{
"name": "Core",
"values": [
{
"id": "security",
"name": "Security",
"description": "Support for spring-security"
},
{
"id": "aop",
"name": "AOP",
"description": "Support for aspect-oriented programming including spring-aop and AspectJ"
}
]
},
{
"name": "Data",
"values": [
{
"id": "jdbc",
"name": "JDBC",
"description": "Support for JDBC databases"
},
{
"id": "data-jpa",
"name": "JPA",
"description": "Support for the Java Persistence API including spring-data-jpa, spring-orm and Hibernate"
},
{
"id": "data-mongodb",
"name": "MongoDB",
"description": "Support for the MongoDB NoSQL Database, including spring-data-mongodb"
},
{
"id": "redis",
"name": "Redis",
"description": "Support for the REDIS key-value data store, including spring-redis"
},
{
"id": "data-gemfire",
"name": "Gemfire",
"description": "Support for the GemFire distributed data store including spring-data-gemfire"
},
{
"id": "data-solr",
"name": "Solr",
"description": "Support for the Apache Solr search platform, including spring-data-solr"
},
{
"id": "data-elasticsearch",
"name": "Elasticsearch",
"description": "Support for the Elasticsearch search and analytics engine including spring-data-elasticsearch"
}
]
},
{
"name": "I/O",
"values": [
{
"id": "batch",
"name": "Batch",
"description": "Support for Spring Batch including HSQLDB database"
},
{
"id": "integration",
"name": "Integration",
"description": "Support for common spring-integration modules"
},
{
"id": "hornetq",
"name": "JMS",
"description": "Support for Java Message Service API via HornetQ"
},
{
"id": "amqp",
"name": "AMQP",
"description": "Support for the Advanced Message Queuing Protocol via spring-rabbit"
}
]
},
{
"name": "Web",
"values": [
{
"id": "web",
"name": "Web",
"description": "Support for full-stack web development, including Tomcat and spring-webmvc"
},
{
"id": "websocket",
"name": "Websocket",
"description": "Support for websocket development with Tomcat"
},
{
"id": "ws",
"name": "WS",
"description": "Support for Spring Web Services"
},
{
"id": "data-rest",
"name": "Rest Repositories",
"description": "Support for exposing Spring Data repositories over REST via spring-data-rest-webmvc"
},
{
"id": "mobile",
"name": "Mobile",
"description": "Support for spring-mobile"
}
]
},
{
"name": "Template Engines",
"values": [
{
"id": "freemarker",
"name": "Freemarker",
"description": "Support for the FreeMarker templating engine"
},
{
"id": "velocity",
"name": "Velocity",
"description": "Support for the Velocity templating engine"
},
{
"id": "groovy-templates",
"name": "Groovy Templates",
"description": "Support for the Groovy templating engine"
},
{
"id": "thymeleaf",
"name": "Thymeleaf",
"description": "Support for the Thymeleaf templating engine, including integration with Spring"
}
]
},
{
"name": "Social",
"values": [
{
"id": "social-facebook",
"name": "Facebook",
"description": "Support for spring-social-facebook"
},
{
"id": "social-linkedin",
"name": "LinkedIn",
"description": "Support for spring-social-linkedin"
},
{
"id": "social-twitter",
"name": "Twitter",
"description": "Support for spring-social-twitter"
}
]
},
{
"name": "Ops",
"values": [
{
"id": "actuator",
"name": "Actuator",
"description": "Production ready features to help you monitor and manage your application"
},
{
"id": "remote-shell",
"name": "Remote Shell",
"description": "Support for CRaSH"
}
]
}
]
},
"type": {
"type": "action",
"default": "maven-project",
"values": [
{
"id": "maven-build",
"name": "Maven POM",
"action": "/pom.xml",
"tags": {
"build": "maven",
"format": "build"
}
},
{
"id": "maven-project",
"name": "Maven Project",
"action": "/maven.zip",
"tags": {
"format": "project",
"build": "maven"
}
},
{
"id": "gradle-build",
"name": "Gradle Config",
"action": "/build.gradle",
"tags": {
"build": "gradle",
"format": "build"
}
},
{
"id": "gradle-project",
"name": "Gradle Project",
"action": "/gradle.zip",
"tags": {
"format": "project",
"build": "gradle"
}
}
]
},
"packaging": {
"type": "single-select",
"default": "jar",
"values": [
{
"id": "jar",
"name": "Jar"
},
{
"id": "war",
"name": "War"
}
]
},
"javaVersion": {
"type": "single-select",
"default": "1.7",
"values": [
{
"id": "1.6",
"name": "1.6"
},
{
"id": "1.7",
"name": "1.7"
},
{
"id": "1.8",
"name": "1.8"
}
]
},
"language": {
"type": "single-select",
"default": "java",
"values": [
{
"id": "groovy",
"name": "Groovy"
},
{
"id": "java",
"name": "Java"
}
]
},
"bootVersion": {
"type": "single-select",
"default": "1.1.9.RELEASE",
"values": [
{
"id": "1.2.0.RC1",
"name": "1.2.0 RC1"
},
{
"id": "1.2.0.BUILD-SNAPSHOT",
"name": "1.2.0 (SNAPSHOT)"
},
{
"id": "1.1.9.RELEASE",
"name": "1.1.9"
},
{
"id": "1.1.8.BUILD-SNAPSHOT",
"name": "1.1.8 (SNAPSHOT)"
},
{
"id": "1.0.2.RELEASE",
"name": "1.0.2"
}
]
},
"groupId": {
"type": "text",
"default": "org.test"
},
"artifactId": {
"type": "text",
"default": "demo"
},
"version": {
"type": "text",
"default": "0.0.1-SNAPSHOT"
},
"name": {
"type": "text",
"default": "demo"
},
"description": {
"type": "text",
"default": "Demo project for Spring Boot"
},
"packageName": {
"type": "text",
"default": "demo"
}
}

View File

@@ -0,0 +1,5 @@
/*global require console*/
var fs = require('fs');
var file = fs.readFileSync("initializr-v2.1.json", "utf8");
var obj = JSON.parse(file);
console.log(JSON.stringify(obj, null, " "));

View File

@@ -0,0 +1,224 @@
<!DOCTYPE html>
<html>
<head>
<title>Spring Initializr</title>
<link rel="stylesheet" href="/css/bootstrap-sts.min.css"/>
</head>
<body>
<div class="container">
<div class="navbar">
<div class="navbar-inner">
<a class="brand" href="https://spring.io">
Spring
</a>
<ul class="nav">
<li>
<a href="/" title="Download a template project or build file with some very basic content.">
Projects
</a>
</li>
<li>
<a href="/spring.zip" title="Download the spring CLI as a zip distribution (unpack and run bin/spring on a command line).">
Download
</a>
</li>
<li>
<a href="/install.sh" title="Installer for the spring CLI command on Un*x-like system (should work on Linux, Mac or Cygwin). Curl this link and pipe to bash, or download the script and run it.">
Installer
</a>
</li>
</ul>
</div>
</div>
<h1>Spring Initializr</h1>
<div>
<form id="form" action="/starter.zip" method="get">
<label for="groupId">Group:</label> <input id="groupId" type="text" value="org.test" name="groupId"/>
<label for="artifactId">Artifact:</label> <input id="artifactId" type="text" value="demo" name="artifactId"/>
<label for="name">Name:</label> <input id="name" type="text" value="demo" name="name"/>
<label for="name">Description:</label> <input id="description" type="text" value="Demo project for Spring Boot" name="description"/>
<label for="packageName">Package Name:</label> <input id="packageName" type="text" value="demo" name="packageName"/>
<label>Styles:</label>
<label class="checkbox">
<input type="checkbox" name="style" value="security"/>
Security
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="aop"/>
AOP
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="jdbc"/>
JDBC
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="data-jpa"/>
JPA
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="data-mongodb"/>
MongoDB
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="redis"/>
Redis
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="data-gemfire"/>
Gemfire
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="data-solr"/>
Solr
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="data-elasticsearch"/>
Elasticsearch
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="batch"/>
Batch
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="integration"/>
Integration
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="hornetq"/>
JMS
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="amqp"/>
AMQP
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="web"/>
Web
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="websocket"/>
Websocket
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="ws"/>
WS
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="data-rest"/>
Rest Repositories
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="mobile"/>
Mobile
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="freemarker"/>
Freemarker
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="velocity"/>
Velocity
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="groovy-templates"/>
Groovy Templates
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="thymeleaf"/>
Thymeleaf
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="social-facebook"/>
Facebook
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="social-linkedin"/>
LinkedIn
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="social-twitter"/>
Twitter
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="actuator"/>
Actuator
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="remote-shell"/>
Remote Shell
</label>
<label>Type:</label>
<label class="radio">
<input type="radio" name="type" value="maven-build" onclick="javascript:this.form.action='/pom.xml'"/>
Maven POM
</label>
<label class="radio">
<input type="radio" name="type" value="maven-project" checked="true" onclick="javascript:this.form.action='/starter.zip'"/>
Maven Project
</label>
<label class="radio">
<input type="radio" name="type" value="gradle-build" onclick="javascript:this.form.action='/build.gradle'"/>
Gradle Config
</label>
<label class="radio">
<input type="radio" name="type" value="gradle-project" onclick="javascript:this.form.action='/starter.zip'"/>
Gradle Project
</label>
<label>Packaging:</label>
<label class="radio">
<input type="radio" name="packaging" value="jar" checked="true"/>
Jar
</label>
<label class="radio">
<input type="radio" name="packaging" value="war"/>
War
</label>
<label>Java Version:</label>
<label class="radio">
<input type="radio" name="javaVersion" value="1.6"/>
1.6
</label>
<label class="radio">
<input type="radio" name="javaVersion" value="1.7" checked="true"/>
1.7
</label>
<label class="radio">
<input type="radio" name="javaVersion" value="1.8"/>
1.8
</label>
<label>Language:</label>
<label class="radio">
<input type="radio" name="language" value="groovy"/>
Groovy
</label>
<label class="radio">
<input type="radio" name="language" value="java" checked="true"/>
Java
</label>
<label>Spring Boot Version:</label>
<label class="radio">
<input type="radio" name="bootVersion" value="1.2.0.M2"/>
1.2.0 M2
</label>
<label class="radio">
<input type="radio" name="bootVersion" value="1.2.0.BUILD-SNAPSHOT"/>
1.2.0 (SNAPSHOT)
</label>
<label class="radio">
<input type="radio" name="bootVersion" value="1.1.8.RELEASE" checked="true"/>
1.1.8
</label>
<label class="radio">
<input type="radio" name="bootVersion" value="1.1.8.BUILD-SNAPSHOT"/>
1.1.8 (SNAPSHOT)
</label>
<label class="radio">
<input type="radio" name="bootVersion" value="1.0.2.RELEASE"/>
1.0.2
</label>
<button name="generate-project" type="submit" class="btn">Generate</button>
</form>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,198 @@
<!DOCTYPE html>
<html>
<head>
<title>Spring Initializr</title>
<link rel="stylesheet"
href="/css/bootstrap.min.css"/>
</head>
<body>
<div class="container">
<div class="navbar">
<div class="navbar-inner">
<a class="brand"
href="https://spring.io">
Spring
</a>
<ul class="nav">
<li>
<a href="/">
Projects
</a>
</li>
<li>
<a href="/spring.zip">
Download
</a>
</li>
<li>
<a href="/install.sh">
Installer
</a>
</li>
</ul>
</div>
</div>
<h1>Spring Initializr</h1>
<div>
<form id="form" action="/starter.zip" method="get">
<label for="groupId">Group:</label> <input id="groupId" type="text" value="org.demo" name="groupId"/>
<label for="artifactId">Artifact:</label> <input id="artifactId" type="text" value="demo" name="artifactId"/>
<label for="name">Name:</label> <input id="name" type="text" value="demo" name="name"/>
<label for="name">Description:</label> <input id="description" type="text" value="Demo project" name="description"/>
<label for="packageName">Package Name:</label> <input id="packageName" type="text" value="demo" name="packageName"/>
<label>Styles:</label>
<label class="checkbox">
<input type="checkbox" name="style" value="amqp"/>
AMQP
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="aop"/>
AOP
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="actuator"/>
Actuator
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="batch"/>
Batch
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="social-facebook"/>
Facebook
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="freemarker"/>
Freemarker
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="data-gemfire"/>
Gemfire
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="groovy-templates"/>
Groovy Templates
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="integration"/>
Integration
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="jdbc"/>
JDBC
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="data-jpa"/>
JPA
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="social-linkedin"/>
LinkedIn
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="mobile"/>
Mobile
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="data-mongodb"/>
MongoDB
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="redis"/>
Redis
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="remote-shell"/>
Remote Shell
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="data-rest"/>
Rest Repositories
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="security"/>
Security
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="data-solr"/>
Solr
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="thymeleaf"/>
Thymeleaf
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="social-twitter"/>
Twitter
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="velocity"/>
Velocity
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="web"/>
Web
</label>
<label class="checkbox">
<input type="checkbox" name="style" value="websocket"/>
Websocket
</label>
<label>Type:</label>
<label class="radio">
<input type="radio" name="type" value="build.gradle" onclick="javascript:this.form.action='/build.gradle'"/>
Gradle Config
</label>
<label class="radio">
<input type="radio" name="type" value="gradle.zip" onclick="javascript:this.form.action='/starter.zip'"/>
Gradle Project
</label>
<label class="radio">
<input type="radio" name="type" value="pom.xml" onclick="javascript:this.form.action='/pom.xml'"/>
Maven POM
</label>
<label class="radio">
<input type="radio" name="type" value="starter.zip" checked="true" onclick="javascript:this.form.action='/starter.zip'"/>
Maven Project
</label>
<label>Packaging:</label>
<label class="radio">
<input type="radio" name="packaging" value="jar" checked="true"/>
Jar
</label>
<label class="radio">
<input type="radio" name="packaging" value="war"/>
War
</label>
<label>Java Version:</label>
<label class="radio">
<input type="radio" name="javaVersion" value="1.6"/>
Java 1.6
</label>
<label class="radio">
<input type="radio" name="javaVersion" value="1.7" checked="true"/>
Java 1.7
</label>
<label class="radio">
<input type="radio" name="javaVersion" value="1.8"/>
Java 1.8
</label>
<label>Language:</label>
<label class="radio">
<input type="radio" name="language" value="groovy"/>
Groovy
</label>
<label class="radio">
<input type="radio" name="language" value="java" checked="true"/>
Java
</label>
<button type="submit" class="btn">Generate</button>
</form>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,145 @@
/*******************************************************************************
* 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.test.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.springframework.ide.eclipse.boot.wizard.content.CodeSet;
import org.springsource.ide.eclipse.commons.frameworks.core.downloadmanager.UIThreadDownloadDisallowed;
public class CopyFromFolder extends CodeSet {
public class FileEntry extends CodeSetEntry {
private File file;
public FileEntry(File file) {
this.file = file;
}
@Override
public IPath getPath() {
return new Path(file.toString()).makeRelativeTo(rootPath());
}
@Override
public boolean isDirectory() {
return false;
}
@Override
public InputStream getData() throws IOException {
return new FileInputStream(file);
}
}
public class DirEntry extends CodeSetEntry {
private File dir;
public DirEntry(File dir) {
this.dir = dir;
}
@Override
public IPath getPath() {
return new Path(dir.toString()).makeRelativeTo(rootPath()).makeAbsolute();
}
@Override
public boolean isDirectory() {
return true;
}
@Override
public InputStream getData() throws IOException {
throw new IOException("Not a file");
}
}
private File root;
private IPath rootPath() {
return new Path(root.toString());
}
public CopyFromFolder(String name, File root) {
super(name);
this.root = root;
}
@Override
public boolean exists() throws Exception {
return root.exists();
}
@Override
public boolean hasFile(IPath path) throws UIThreadDownloadDisallowed {
return file(path).isFile();
}
private File file(IPath path) {
return new File(rootPath().append(path).toString());
}
@Override
public boolean hasFolder(IPath path) {
return file(path).isDirectory();
}
@Override
public <T> T each(Processor<T> processor) throws Exception {
return each(root, processor);
}
private <T> T each(File target, Processor<T> processor) throws Exception {
T result = null;
if (target.isDirectory()) {
result = processor.doit(new DirEntry(target));
if (result!=null) {
return result;
}
for (File child : target.listFiles()) {
result = each(child, processor);
if (result!=null) {
return result;
}
}
return result;
} else if (target.isFile()) {
return processor.doit(new FileEntry(target));
} else {
throw new IOException("What is this? Not a file, not a directory?"+target);
}
}
@Override
public <T> T readFileEntry(final String path, Processor<T> processor) throws Exception {
File f = file(path);
if (f.isFile()) {
FileEntry entry = new FileEntry(f);
return processor.doit(entry);
} else {
throw new IOException("Not a file: "+path);
}
}
private File file(String path) {
return null;
}
}

View File

@@ -0,0 +1,77 @@
/*******************************************************************************
* Copyright (c) 2012 Pivotal Software, 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal Software, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.test.util;
import java.io.File;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.JavaRuntime;
import org.springsource.ide.eclipse.commons.frameworks.test.util.ExternalCommand;
import org.springsource.ide.eclipse.commons.frameworks.test.util.ExternalProcess;
import org.springsource.ide.eclipse.commons.tests.util.StsTestUtil;
/**
* Wrapper around a Eclipse IVMInstall to make it easier to launch
* 'plain' JVM processes in testing code. I.e. not using the Eclipse
* debug framework but using simple JRE ProcessBuilder api.
*
* @author Kris De Volder
*/
public class JavaUtils {
private IVMInstall jvm;
public JavaUtils(IVMInstall jvm) {
this.jvm = jvm;
}
public JavaUtils() {
this(JavaRuntime.getDefaultVMInstall());
}
/**
* Run an executable jar as an external Java process.
*/
public LaunchResult runJar(File jarFile) throws Exception {
File java = getJavaExecutable();
Assert.isNotNull(java, "Couldn't find a 'java' executable");
File workdir = StsTestUtil.createTempDirectory("javalaunch-work", "dir");
ExternalCommand cmd = new ExternalCommand(java.toString(), "-jar", jarFile.toString());
ExternalProcess process = new ExternalProcess(workdir, cmd, true);
return new LaunchResult(process.getExitValue(), process.getOut(),process.getErr());
}
public File getJavaExecutable() {
File javaHome = getJavaHome();
for (String exePath : getJavaExecutableLocations()) {
File exe = new File(javaHome, exePath);
if (exe.isFile()) {
return exe;
}
}
return null;
}
/**
* Paths relative to Java home where we will look for the 'java' executable
*/
protected String[] getJavaExecutableLocations() {
return new String[] {
"bin/java",
"bin/java.exe"
};
}
public File getJavaHome() {
return jvm.getInstallLocation();
}
}

View File

@@ -0,0 +1,34 @@
/*******************************************************************************
* Copyright (c) 2015 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.test.util;
public class LaunchResult {
public final int terminationCode;
public final String out;
public final String err;
LaunchResult(int terminationCode, String out, String err) {
super();
this.terminationCode = terminationCode;
this.out = out;
this.err = err;
}
@Override
public String toString() {
StringBuilder buf = new StringBuilder();
buf.append("---- Sys.out ---\n");
buf.append(out);
buf.append("---- Sys.err ---\n");
buf.append(err);
return buf.toString();
}
}

View File

@@ -0,0 +1,92 @@
/*******************************************************************************
* Copyright (c) 2012, 2014, 2015 Pivotal Software, 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal Software, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.test.util;
import java.time.Duration;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchesListener;
import org.eclipse.debug.core.ILaunchesListener2;
import org.eclipse.debug.core.model.IProcess;
/**
* A DebugEvent listener that is used for testing purposes. The listener provides a way to
* Grab a hold of and then wait for the termination of a IProcess that is expected to
* be started soon after the listener is added to the Eclipse {@link DebugPlugin}.
* <p>
* Typically, you don't use this class directly but rather call a method in {@link LaunchUtil}.
*
* @author Kris De Volder
*/
class LaunchTerminationListener implements ILaunchesListener, ILaunchesListener2 {
private ILaunch launch;
public LaunchTerminationListener(ILaunch launch) {
this.launch = launch;
}
private synchronized boolean isTerminated() {
return launch.isTerminated();
}
public synchronized void waitForProcessTermination(Duration timeout) {
long start = System.currentTimeMillis();
long end = start+timeout.toMillis();
while (!isTerminated()) {
if (System.currentTimeMillis()>end) {
try {
//The process may be stuck, try to kill it forcibly to avoid stuck tests
launch.terminate();
} catch (DebugException e) {
}
}
try {
wait(Math.max(500, end - System.currentTimeMillis()));
} catch (InterruptedException e) {
}
}
}
public void launchesRemoved(ILaunch[] launches) {
notifyMaybe(launches);
}
private void notifyMaybe(ILaunch[] launches) {
for (ILaunch iLaunch : launches) {
if (iLaunch==this.launch) {
synchronized (this) {
notifyAll();
}
}
}
}
public void launchesAdded(ILaunch[] launches) {
notifyMaybe(launches);
}
public void launchesChanged(ILaunch[] launches) {
notifyMaybe(launches);
}
public void launchesTerminated(ILaunch[] launches) {
notifyMaybe(launches);
}
public IProcess waitForProcess(Duration timeout) {
waitForProcessTermination(timeout);
return LaunchUtil.findProcess(launch);
}
}

View File

@@ -0,0 +1,120 @@
/*******************************************************************************
* Copyright (c) 2012, 2014, 2015 Pivotal Software, 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal Software, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.test.util;
import java.time.Duration;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.IStreamListener;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.core.model.IStreamMonitor;
import org.eclipse.debug.core.model.IStreamsProxy;
import org.springframework.ide.eclipse.boot.launch.BootLaunchConfigurationDelegate;
import org.springframework.ide.eclipse.boot.launch.process.BootProcessFactory;
import org.springsource.ide.eclipse.commons.livexp.core.LiveVariable;
import org.springsource.ide.eclipse.commons.livexp.ui.Disposable;
/**
* Utility class providing methods to help launching a process from a ILauncConfiguration and waiting for it to
* terminate while capturing the output for testing purposes.
*
* @author Kris De Volder
*/
public class LaunchUtil {
public static LaunchResult synchLaunch(ILaunchConfiguration launchConf) throws CoreException {
return synchLaunch(launchConf, Duration.ofMinutes(2));
}
@SuppressWarnings("resource")
public static LaunchResult synchLaunch(ILaunchConfiguration launchConf, Duration timeout) throws CoreException {
//The way we capture output only works for BootLaunchConfigurationDelegate so make sure that's what this is being used
// for:
if (launchConf.getType().getIdentifier().equals(BootLaunchConfigurationDelegate.TYPE_ID)) {
LiveVariable<StringBuilder> out = new LiveVariable<>();
LiveVariable<StringBuilder> err = new LiveVariable<>();
Disposable disposable = BootProcessFactory.addStreamsProxyListener((streams, launch) -> {
if (launch.getLaunchConfiguration().equals(launchConf)) {
out.setValue(capture(streams.getOutputStreamMonitor()));
err.setValue(capture(streams.getErrorStreamMonitor()));
}
});
try {
ILaunch l = launchConf.launch("run", new NullProgressMonitor(), false, true);
IProcess p = synchLaunch(l, timeout);
return new LaunchResult(p.getExitValue(), out.getValue().toString(), err.getValue().toString());
} finally {
disposable.dispose();
}
} else {
//This code has a known race condition, (it is not certain we grab all the output because we can only attach
// listeners *after* process already started). We attempted to address this above. But above approach only
// works if BootLaunchConfgurationDeletate is used. So we still keep this slightly broken old solution as
// a fallback.
ILaunch l = launchConf.launch("run", new NullProgressMonitor(), false, true);
IProcess process = findProcess(l);
IStreamsProxy streams = process.getStreamsProxy();
StringBuilder out = capture(streams.getOutputStreamMonitor());
StringBuilder err = capture(streams.getErrorStreamMonitor());
IProcess p = synchLaunch(l, timeout);
return new LaunchResult(p.getExitValue(), out.toString(), err.toString());
}
}
private static StringBuilder capture(IStreamMonitor stream) {
final StringBuilder out = new StringBuilder();
synchronized (stream) {
out.append(stream.getContents());
stream.addListener(new IStreamListener() {
public void streamAppended(String text, IStreamMonitor monitor) {
out.append(text);
}
});
}
return out;
}
private static IProcess synchLaunch(ILaunch launch, Duration timeout) {
DebugPlugin mgr = DebugPlugin.getDefault();
LaunchTerminationListener listener = null;
try {
//DebugUITools.launch(launchConf, "run");
listener = new LaunchTerminationListener(launch);
mgr.getLaunchManager().addLaunchListener(listener);
return listener.waitForProcess(timeout);
} finally {
if (listener!=null) {
mgr.getLaunchManager().removeLaunchListener(listener);
}
}
}
public static ILaunchManager getLaunchManager() {
return DebugPlugin.getDefault().getLaunchManager();
}
public static IProcess findProcess(ILaunch launch) {
IProcess[] processes = launch.getProcesses();
if (processes!=null && processes.length>0) {
Assert.isTrue(processes.length==1);
return processes[0];
}
return null;
}
}

View File

@@ -0,0 +1,44 @@
/*******************************************************************************
* Copyright (c) 2015 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.test.util;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
/**
* JUnit 4 style test 'rule' that marks the beginning and ending of
* a test execution by printing some recognizable markers/brackets
* to System.out.
* <p>
* This is very helpful when trying to find a specific test's
* output in the logs on bamboo builds which do not attach
* individual test output to test results.
*
* @author Kris De Volder
*/
public class TestBracketter implements TestRule {
@Override
public Statement apply(final Statement base, final Description description) {
return new Statement() {
public void evaluate() throws Throwable {
System.out.println(">>>> beg: "+description.getDisplayName());
try {
base.evaluate();
} finally {
System.out.println("<<<< end: "+description.getDisplayName());
}
}
};
}
}

View File

@@ -0,0 +1,38 @@
/*******************************************************************************
* Copyright (c) 2020 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.test.util;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Platform;
import org.junit.Assert;
import org.osgi.framework.Bundle;
import org.springframework.ide.eclipse.boot.test.AllSpringBootTests;
public class TestResourcesUtil {
public static File getTestFile(String path) throws IOException {
Bundle bundle = Platform.getBundle(AllSpringBootTests.PLUGIN_ID);
File bundleFile = FileLocator.getBundleFile(bundle);
Assert.assertNotNull(bundleFile);
Assert.assertTrue("The bundle "+bundle.getBundleId()+" must be unpacked to allow using the embedded test resources", bundleFile.isDirectory());
File file = new File(bundleFile, path);
if (!file.exists()) {
throw new FileNotFoundException("Test file : " + file.getAbsolutePath() + " not found");
}
return file;
}
}

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>simple-boot-project</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.wst.common.project.facet.core.builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.springframework.ide.eclipse.core.springbuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.springframework.ide.eclipse.boot.validation.springbootbuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.springframework.ide.eclipse.core.springnature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
</natures>
</projectDescription>

View File

@@ -0,0 +1,5 @@
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/main/resources=UTF-8
encoding//src/test/java=UTF-8
encoding/<project>=UTF-8

View File

@@ -0,0 +1,5 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.7

View File

@@ -0,0 +1,4 @@
activeProfiles=pom.xml
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<installed facet="cloudfoundry.standalone.app" version="1.0"/>
</faceted-project>

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.test</groupId>
<artifactId>empty-boot-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>empty-boot-project</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<start-class>demo.EmptyBootProjectApplication</start-class>
<java.version>1.7</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,12 @@
package demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class AlternateMain {
public static void main(String[] args) {
SpringApplication.run(AlternateMain.class, args);
}
}

View File

@@ -0,0 +1,12 @@
package demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class EmptyBootProjectApplication {
public static void main(String[] args) {
SpringApplication.run(EmptyBootProjectApplication.class, args);
}
}

View File

@@ -0,0 +1,16 @@
package demo;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FooConfiguration {
@Bean
@ConfigurationProperties("bar")
public Bar barProperties() {
return new Bar();
}
}

View File

@@ -0,0 +1,8 @@
package demo;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("foo")
public class FooProperties {
}

View File

@@ -0,0 +1,16 @@
package demo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = EmptyBootProjectApplication.class)
public class EmptyBootProjectApplicationTests {
@Test
public void contextLoads() {
}
}