diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/build/impl/OpenRewriteMavenBuildFile.java b/components/sbm-core/src/main/java/org/springframework/sbm/build/impl/OpenRewriteMavenBuildFile.java index a86ba7432..cc41a1cec 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/build/impl/OpenRewriteMavenBuildFile.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/build/impl/OpenRewriteMavenBuildFile.java @@ -48,6 +48,7 @@ import org.springframework.sbm.build.api.Plugin; import org.springframework.sbm.build.api.RepositoryDefinition; import org.springframework.sbm.build.api.RewriteMavenParentDeclaration; +import org.springframework.sbm.build.impl.inner.PluginRepositoryHandler; import org.springframework.sbm.build.migration.recipe.AddMavenPlugin; import org.springframework.sbm.build.migration.recipe.RemoveMavenPlugin; import org.springframework.sbm.build.migration.visitor.AddOrUpdateDependencyManagement; @@ -77,9 +78,8 @@ @Slf4j public class OpenRewriteMavenBuildFile extends RewriteSourceFileHolder implements BuildFile { - public static final String PLUGIN_REPOSITORIES = "pluginRepositories"; - public static final String PLUGIN_REPOSITORY = "pluginRepository"; private final ApplicationEventPublisher eventPublisher; + private PluginRepositoryHandler pluginRepositoryHandler = new PluginRepositoryHandler(); // TODO: #7 clarify if RefreshPomModel is still required? // Execute separately since RefreshPomModel caches the refreshed maven files after the first visit @@ -739,17 +739,8 @@ public List getRepositories() { @Override public List getPluginRepositories() { - List tags = getSourceFile() - .getRoot() - .getChild(PLUGIN_REPOSITORIES) - .map(t -> t.getChildren(PLUGIN_REPOSITORY)) - .orElse(List.of()); - - return tags.stream() - .map(k -> k.getChild("url")) - .map(k -> k.orElseThrow(() -> new RuntimeException("url is not set for plugin repository")).getValue()) - .map(k -> k.orElseThrow(() -> new RuntimeException("url value is not set"))) - .map(k -> RepositoryDefinition.builder().url(k).build()).collect(Collectors.toList()); + + return pluginRepositoryHandler.getRepositoryDefinitions(getSourceFile()); } private boolean anyRegexMatchesCoordinate(Plugin p, String... regex) { diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/build/impl/inner/PluginRepositoryHandler.java b/components/sbm-core/src/main/java/org/springframework/sbm/build/impl/inner/PluginRepositoryHandler.java new file mode 100644 index 000000000..6d2e9906b --- /dev/null +++ b/components/sbm-core/src/main/java/org/springframework/sbm/build/impl/inner/PluginRepositoryHandler.java @@ -0,0 +1,74 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.sbm.build.impl.inner; + +import org.openrewrite.xml.tree.Xml; +import org.springframework.sbm.build.api.RepositoryDefinition; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.function.Consumer; + +public class PluginRepositoryHandler { + public static final String PLUGIN_REPOSITORIES = "pluginRepositories"; + public static final String PLUGIN_REPOSITORY = "pluginRepository"; + + public List getRepositoryDefinitions(Xml.Document sourceFile) { + List tags = sourceFile + .getRoot() + .getChild(PLUGIN_REPOSITORIES) + .map(t -> t.getChildren(PLUGIN_REPOSITORY)) + .orElse(List.of()); + + List result = new ArrayList<>(); + for (Xml.Tag t : tags) { + RepositoryDefinition.RepositoryDefinitionBuilder builder = RepositoryDefinition.builder(); + getRepositoryAttribute(t, "url", builder::url, true); + getRepositoryAttribute(t, "id", builder::id, true); + getRepositoryAttribute(t, "layout", builder::layout, false); + getRepositoryAttribute(t, "snapshots.enabled", (k) -> builder.snapshotsEnabled(Boolean.valueOf(k)), false); + getRepositoryAttribute(t, "snapshots.checksumPolicy", builder::snapshotsChecksumPolicy, false); + getRepositoryAttribute(t, "snapshots.updatePolicy", builder::snapShotsUpdatePolicy, false); + getRepositoryAttribute(t, "releases.enabled", (k) -> builder.releasesEnabled(Boolean.valueOf(k)), false); + getRepositoryAttribute(t, "releases.checksumPolicy", builder::releasesChecksumPolicy, false); + getRepositoryAttribute(t, "releases.updatePolicy", builder::releasesUpdatePolicy, false); + result.add(builder.build()); + } + return result; + } + + private void getRepositoryAttribute(Xml.Tag tag, String attributeName, Consumer initDefinition, boolean mandatory) { + + String[] hierarchy = attributeName.split("\\."); + + for (int i = 0; i < hierarchy.length - 1; i++) { + Optional tagOptional = tag.getChild(hierarchy[i]); + + if (tagOptional.isPresent()) { + tag = tagOptional.get(); + } + } + + attributeName = hierarchy[hierarchy.length - 1]; + Optional attributeValue = tag.getChildValue(attributeName); + if (mandatory && attributeValue.isEmpty()) { + throw new RuntimeException(attributeName + " is not set for plugin repository"); + } + attributeValue.ifPresent(initDefinition); + } +} diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/build/impl/inner/PluginRepositoryHandlerTest.java b/components/sbm-core/src/test/java/org/springframework/sbm/build/impl/inner/PluginRepositoryHandlerTest.java new file mode 100644 index 000000000..3b3bba7bb --- /dev/null +++ b/components/sbm-core/src/test/java/org/springframework/sbm/build/impl/inner/PluginRepositoryHandlerTest.java @@ -0,0 +1,137 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.sbm.build.impl.inner; + +import org.intellij.lang.annotations.Language; +import org.junit.jupiter.api.Test; +import org.openrewrite.maven.MavenParser; +import org.openrewrite.xml.tree.Xml; +import org.springframework.sbm.build.api.RepositoryDefinition; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class PluginRepositoryHandlerTest { + + private final PluginRepositoryHandler sut = new PluginRepositoryHandler(); + private final MavenParser mavenParser = MavenParser.builder().build(); + + @Test + public void shouldConvertAllFieldsOfPluginRepo() { + + Xml.Document sourceFile = getSourceFile(""" + + + 4.0.0 + com.example + boot-upgrade-27_30 + 0.0.1-SNAPSHOT + boot-upgrade-27_30 + boot-upgrade-27_30 + + + + spring-milestone + https://repo.spring.io/milestone + default + + fail + true + daily + + + warn + false + always + + + + + """); + List output = sut.getRepositoryDefinitions(sourceFile); + assertThat(output).hasSize(1); + + assertThat(output.get(0).getUrl()).isEqualTo("https://repo.spring.io/milestone"); + assertThat(output.get(0).getId()).isEqualTo("spring-milestone"); + assertThat(output.get(0).getLayout()).isEqualTo("default"); + assertThat(output.get(0).getSnapshotsEnabled()).isTrue(); + assertThat(output.get(0).getSnapshotsChecksumPolicy()).isEqualTo("fail"); + assertThat(output.get(0).getSnapShotsUpdatePolicy()).isEqualTo("daily"); + assertThat(output.get(0).getReleasesEnabled()).isFalse(); + assertThat(output.get(0).getReleasesChecksumPolicy()).isEqualTo("warn"); + assertThat(output.get(0).getReleasesUpdatePolicy()).isEqualTo("always"); + } + + @Test + public void shouldThrowExceptionForMissingIdMandatoryAttribute() { + + Xml.Document sourceFile = getSourceFile(""" + + + 4.0.0 + com.example + boot-upgrade-27_30 + 0.0.1-SNAPSHOT + boot-upgrade-27_30 + boot-upgrade-27_30 + + + + https://repo.spring.io/milestone + + + + + """); + RuntimeException runtimeException = assertThrows(RuntimeException.class, () -> sut.getRepositoryDefinitions(sourceFile)); + assertThat(runtimeException).hasMessageContaining("id"); + } + + @Test + public void shouldThrowExceptionForMissingUrlMandatoryAttribute() { + + Xml.Document sourceFile = getSourceFile(""" + + + 4.0.0 + com.example + boot-upgrade-27_30 + 0.0.1-SNAPSHOT + boot-upgrade-27_30 + boot-upgrade-27_30 + + + + someId + + + + + """); + RuntimeException runtimeException = assertThrows(RuntimeException.class, () -> sut.getRepositoryDefinitions(sourceFile)); + assertThat(runtimeException).hasMessageContaining("url"); + } + + private Xml.Document getSourceFile(@Language("xml") String xml) { + + return mavenParser.parse(xml).get(0); + } +} diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/build/migration/conditions/NoPluginRepositoryExistsConditionTest.java b/components/sbm-core/src/test/java/org/springframework/sbm/build/migration/conditions/NoPluginRepositoryExistsConditionTest.java index a790dfbd4..558c01bf6 100644 --- a/components/sbm-core/src/test/java/org/springframework/sbm/build/migration/conditions/NoPluginRepositoryExistsConditionTest.java +++ b/components/sbm-core/src/test/java/org/springframework/sbm/build/migration/conditions/NoPluginRepositoryExistsConditionTest.java @@ -39,6 +39,7 @@ void repositoryWithSameUrlAndSnapshotsAndReleasesNotSet() { " \n" + " \n" + " https://repo.spring.io/milestone\n" + + " milestone\n" + " \n" + " \n" + ""; @@ -69,6 +70,7 @@ void repositoryWithSameUrlAndSnapshotsFalseAndReleasesNotSet() { " \n" + " \n" + " https://repo.spring.io/milestone\n" + + " milestone\n" + " \n" + " false\n" + " \n" + @@ -102,6 +104,7 @@ void repositoryWithSameUrlAndSnapshotsTrueAndReleasesNotSet() { " \n" + " \n" + " https://repo.spring.io/milestone\n" + + " milestone\n" + " \n" + " true\n" + " \n" + @@ -135,6 +138,7 @@ void repositoryWithSameUrlAndSnapshotsNotSetAndReleasesTrue() { " \n" + " \n" + " https://repo.spring.io/milestone\n" + + " milestone\n" + " \n" + " true\n" + " \n" + @@ -168,6 +172,7 @@ void repositoryWithSameUrlAndSnapshotsNotSetAndReleasesFalse() { " \n" + " \n" + " https://repo.spring.io/milestone\n" + + " milestone\n" + " \n" + " false\n" + " \n" + @@ -201,6 +206,7 @@ void repositoryWithDifferentUrlAndSnapshotsSetToFalse() { " \n" + " \n" + " https://repo.spring.io/milestone\n" + + " milestone\n" + " \n" + " \n" + "";