You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ra...@apache.org on 2020/02/28 18:13:29 UTC
[sling-scriptingbundle-maven-plugin] 01/01: SLING-9161 - The
Scripting Bundle Maven Plugin should allow more flexible ways for the
project structure
This is an automated email from the ASF dual-hosted git repository.
radu pushed a commit to branch issue/SLING-9161
in repository https://gitbox.apache.org/repos/asf/sling-scriptingbundle-maven-plugin.git
commit a1d1aa77a178f750063657d29ab60a917a4d869c
Author: Radu Cotescu <ra...@apache.org>
AuthorDate: Fri Feb 28 19:12:27 2020 +0100
SLING-9161 - The Scripting Bundle Maven Plugin should allow more flexible ways for the project structure
* started refactoring (WIP)
---
pom.xml | 163 +++++++++++++--
.../scriptingbundle/maven/plugin/Capabilities.java | 41 ++++
.../scriptingbundle/maven/plugin/MetadataMojo.java | 227 +++++++++++++++++++++
.../maven/plugin/ProvidedCapability.java | 134 ++++++++++++
.../maven/plugin/RequiredCapability.java | 78 +++++++
.../maven/plugin/ResourceTypeFolderAnalyser.java | 190 +++++++++++++++++
.../maven/plugin/ResourceTypeFolderPredicate.java | 76 +++++++
.../maven/plugin/ScriptingMavenPlugin.java | 213 -------------------
.../plugin/MetadataMojoCapabilityFindingTest.java | 148 ++++++++++++++
.../maven/plugin/MetadataMojoTest.java | 79 +++++++
.../maven/plugin/ScriptingMavenPluginTest.java | 80 --------
src/test/resources/project-1/pom.xml | 46 +++++
.../org.apache.sling.foobar/1.0.0/extends | 1 +
.../org.apache.sling.foobar/1.0.0/foobar.html | 0
.../org.apache.sling.foobar/1.0.0/requires | 1 +
.../javax.script/org.apache.sling.foobar/GET.html | 0
.../org/apache/sling/bar/1.0.0/bar.html | 0
.../org/apache/sling/foo/foo.GET.html.html | 19 ++
src/test/resources/spotbugs-exclude.xml | 24 +++
19 files changed, 1215 insertions(+), 305 deletions(-)
diff --git a/pom.xml b/pom.xml
index d0d4654..886c700 100644
--- a/pom.xml
+++ b/pom.xml
@@ -39,39 +39,178 @@
</scm>
<properties>
- <sling.java.version>8</sling.java.version>
+ <sling.java.version>11</sling.java.version>
+ <maven.version>3.6.0</maven.version>
</properties>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>${maven.version}</version>
+ <executions>
+ <execution>
+ <id>mojo-descriptor</id>
+ <phase>process-classes</phase>
+ <goals>
+ <goal>descriptor</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>generated-helpmojo</id>
+ <goals>
+ <goal>helpmojo</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-metadata</artifactId>
+ <version>2.1.0</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>generate-metadata</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.rat</groupId>
+ <artifactId>apache-rat-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <exclude>**/*.iml</exclude>
+ <exclude>**/target/**/*</exclude>
+ <exclude>src/site/markdown/**</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-scm-publish-plugin</artifactId>
+ <configuration>
+ <checkoutDirectory>${user.home}/maven-sites/${maven.site.path}</checkoutDirectory>
+ <tryUpdate>true</tryUpdate>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>com.github.spotbugs</groupId>
+ <artifactId>spotbugs-maven-plugin</artifactId>
+ <version>3.1.12.2</version>
+ <configuration>
+ <effort>Max</effort>
+ <xmlOutput>true</xmlOutput>
+ <excludeFilterFile>src/test/resources/spotbugs-exclude.xml</excludeFilterFile>
+ </configuration>
+ <executions>
+ <execution>
+ <id>find-bugs</id>
+ <phase>process-classes</phase>
+ <goals>
+ <goal>check</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+ <!-- force maven-plugin-testing-harness to use newer plexus container (https://issues.apache.org/jira/browse/MPLUGINTESTING-53) -->
+ <dependencyManagement>
+ <dependencies>
+ <!-- maven -->
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-core</artifactId>
+ <version>${maven.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-compat</artifactId>
+ <version>${maven.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-model</artifactId>
+ <version>${maven.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>${maven.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-aether-provider</artifactId>
+ <version>${maven.version}</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
<dependencies>
<dependency>
- <groupId>org.apache.maven</groupId>
- <artifactId>maven-plugin-api</artifactId>
- <version>3.0</version>
+ <groupId>org.jetbrains</groupId>
+ <artifactId>annotations</artifactId>
</dependency>
- <!-- dependencies to annotations -->
<dependency>
- <groupId>org.apache.maven.plugin-tools</groupId>
- <artifactId>maven-plugin-annotations</artifactId>
- <version>3.4</version>
- <scope>provided</scope>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
- <artifactId>maven-project</artifactId>
- <version>2.2.1</version>
+ <artifactId>maven-model</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
- <version>3.5.0</version>
</dependency>
<dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-compat</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.plugin-tools</groupId>
+ <artifactId>maven-plugin-annotations</artifactId>
+ <version>3.4</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.core</artifactId>
<version>7.0.0</version>
<scope>compile</scope>
</dependency>
+
+ <dependency>
+ <groupId>org.apache.maven.plugin-testing</groupId>
+ <artifactId>maven-plugin-testing-harness</artifactId>
+ <version>3.3.0</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <version>3.3.0</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.sonatype.plexus</groupId>
+ <artifactId>plexus-build-api</artifactId>
+ <version>0.0.7</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
diff --git a/src/main/java/org/apache/sling/scriptingbundle/maven/plugin/Capabilities.java b/src/main/java/org/apache/sling/scriptingbundle/maven/plugin/Capabilities.java
new file mode 100644
index 0000000..b885fb7
--- /dev/null
+++ b/src/main/java/org/apache/sling/scriptingbundle/maven/plugin/Capabilities.java
@@ -0,0 +1,41 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+package org.apache.sling.scriptingbundle.maven.plugin;
+
+import java.util.Collections;
+import java.util.List;
+
+public class Capabilities {
+
+ private final List<ProvidedCapability> providedCapabilities;
+ private final List<RequiredCapability> requiredCapabilities;
+
+ Capabilities(List<ProvidedCapability> providedCapabilities, List<RequiredCapability> requiredCapabilities) {
+ this.providedCapabilities = providedCapabilities;
+ this.requiredCapabilities = requiredCapabilities;
+ }
+
+ public List<ProvidedCapability> getProvidedCapabilities() {
+ return Collections.unmodifiableList(providedCapabilities);
+ }
+
+ public List<RequiredCapability> getRequiredCapabilities() {
+ return Collections.unmodifiableList(requiredCapabilities);
+ }
+}
diff --git a/src/main/java/org/apache/sling/scriptingbundle/maven/plugin/MetadataMojo.java b/src/main/java/org/apache/sling/scriptingbundle/maven/plugin/MetadataMojo.java
new file mode 100644
index 0000000..02109e1
--- /dev/null
+++ b/src/main/java/org/apache/sling/scriptingbundle/maven/plugin/MetadataMojo.java
@@ -0,0 +1,227 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+package org.apache.sling.scriptingbundle.maven.plugin;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.shared.utils.io.DirectoryScanner;
+import org.osgi.framework.Version;
+
+/**
+ * The {@code metadata} goal will generate two Maven project properties, namely {@code org.apache.sling.scriptingbundle.maven.plugin
+ * .Require-Capability} and {@code org.apache.sling.scriptingbundle.maven.plugin.Provide-Capability} which can be used to generate the
+ * corresponding OSGi bundle headers for bundles providing scripts executable by a {@link javax.script.ScriptEngine}.
+ */
+@Mojo(name = "metadata",
+ defaultPhase = LifecyclePhase.PACKAGE)
+public class MetadataMojo extends AbstractMojo {
+
+ @Parameter(defaultValue = "${project}",
+ readonly = true)
+ private MavenProject project;
+
+ @Parameter(defaultValue = "${session}",
+ readonly = true)
+ private MavenSession session;
+
+ /**
+ * Defines where this goal will look for scripts in the project.
+ *
+ * @since 0.1.0
+ */
+ @Parameter(defaultValue = "${project.basedir}/src/main/resources/javax.script")
+ private String scriptsDirectory;
+
+ static final Set<String> METHODS = new HashSet<>(Arrays.asList("TRACE", "OPTIONS", "GET", "HEAD", "POST", "PUT",
+ "DELETE", "PATCH"));
+ static final String EXTENDS_FILE = "extends";
+ static final String REQUIRES_FILE = "requires";
+
+ private final Log log;
+
+ public MetadataMojo() {
+ log = getLog();
+ }
+
+ public void execute() throws MojoExecutionException {
+ File sdFile = new File(scriptsDirectory);
+ if (!sdFile.exists()) {
+ sdFile = new File(project.getBasedir(), scriptsDirectory);
+ if (!sdFile.exists()) {
+ throw new MojoExecutionException("Cannot find file " + scriptsDirectory + ".");
+ }
+ }
+ final AtomicReference<File> scriptsDirectoryReference = new AtomicReference<>();
+ scriptsDirectoryReference.set(sdFile);
+ DirectoryScanner scanner = new DirectoryScanner();
+ scanner.setBasedir(sdFile);
+ scanner.setIncludes("**");
+ scanner.setExcludes("**/*.class");
+ scanner.addDefaultExcludes();
+ scanner.scan();
+
+ List<String> includedDirectories = Arrays.asList(scanner.getIncludedDirectories());
+ includedDirectories.sort(Collections.reverseOrder());
+ List<Path> resourceTypeDirectories =
+ includedDirectories.stream()
+ .map(includedDirectory -> Paths.get(scriptsDirectoryReference.get().getAbsolutePath(), includedDirectory))
+ .filter(new ResourceTypeFolderPredicate()).collect(Collectors.toList());
+ ResourceTypeFolderAnalyser analyser = new ResourceTypeFolderAnalyser(log, Paths.get(sdFile.getAbsolutePath()));
+ log.info("Detected resource type directories: " + resourceTypeDirectories);
+ for (Path resourceTypeDirectory : resourceTypeDirectories) {
+ Capabilities capabilities = analyser.getCapabilities(resourceTypeDirectory);
+ log.info(String.format("folder: %s, require: %s, provide: %s", resourceTypeDirectory.toString(),
+ capabilities.getRequiredCapabilities(), capabilities.getProvidedCapabilities()));
+ }
+ }
+
+ ProvidedCapability getScript(String script) {
+ String[] parts = script.split(Pattern.quote(File.separator));
+ String scriptName = null;
+ String resourceType = null;
+ String scriptExtension = null;
+ String extension = null;
+ String method = null;
+ String version = null;
+ List<String> selectors = new ArrayList<>();
+ if (parts.length > 2) {
+ Version v = null;
+ int versionIndex = -1;
+ for (int i = parts.length - 1; i >= 1; i--) {
+ try {
+ v = new Version(parts[i]);
+ versionIndex = i;
+ } catch (IllegalArgumentException e) {
+ // do nothing
+ }
+ }
+ if (v != null) {
+ version = v.toString();
+ resourceType = String.join("/", Arrays.copyOfRange(parts, 0, versionIndex - 1));
+ if (parts.length - versionIndex > 2) {
+ Collections.addAll(selectors, Arrays.copyOfRange(parts, versionIndex + 1, parts.length - 1));
+ }
+ } else {
+ resourceType = String.join("/", Arrays.copyOfRange(parts, 0, versionIndex - 1));
+ if (parts.length - versionIndex > 2) {
+ Collections.addAll(selectors, Arrays.copyOfRange(parts, versionIndex + 1, parts.length - 1));
+ }
+ }
+ scriptName = parts[parts.length - 1];
+ String[] scriptParts = scriptName.split("\\.");
+ if (scriptParts.length < 2) {
+ throw new IllegalStateException("Missing script extension.");
+ }
+ scriptExtension = scriptParts[scriptParts.length - 1];
+ String resourceTypeLabel;
+ int index = resourceType.lastIndexOf('.') == -1 ? resourceType.lastIndexOf('/') : -1;
+ if (index == -1) {
+ resourceTypeLabel = resourceType;
+ } else {
+ resourceTypeLabel = resourceType.substring(index + 1);
+ }
+ String first = scriptParts[0];
+ if (!first.equals(resourceTypeLabel)) {
+ int selectorsStart;
+ if (METHODS.contains(first)) {
+ method = first;
+ selectorsStart = 1;
+ } else {
+ selectorsStart = 0;
+ }
+ for (int i = selectorsStart; i < scriptParts.length - 3; i++) {
+ selectors.add(scriptParts[i]);
+ }
+ if (scriptParts.length >= 3) {
+ extension = scriptParts[scriptParts.length - 2];
+ }
+ }
+ } else if (parts.length == 2) {
+ resourceType = parts[0];
+ }
+
+
+ if (parts.length >= 2) {
+ scriptName = parts[parts.length - 1];
+ Version v = null;
+ try {
+ if (parts.length > 2) {
+ v = new Version(parts[parts.length - 2]);
+ }
+ } catch (IllegalArgumentException e) {
+ log.debug(String.format("No resource type version available for script %s.", script));
+ }
+ version = v == null ? null : v.toString();
+ resourceType = version == null ? String.join("/", Arrays.copyOfRange(parts, 0, parts.length - 1)) : String.join("/",
+ Arrays.copyOfRange(parts, 0, parts.length - 2));
+ int idx = scriptName.lastIndexOf('.');
+ if (idx != -1) {
+ scriptExtension = scriptName.substring(idx + 1);
+ scriptName = scriptName.substring(0, idx);
+ if (scriptExtension.isEmpty()) {
+ scriptExtension = null;
+ }
+ }
+
+ idx = scriptName.lastIndexOf('.');
+ if (idx != -1) {
+ extension = scriptName.substring(idx + 1);
+ scriptName = scriptName.substring(0, idx);
+ if (extension.isEmpty() || extension.equalsIgnoreCase("html")) {
+ extension = null;
+ }
+ } else {
+ extension = null;
+ }
+
+ idx = scriptName.indexOf('.');
+ if (idx != -1) {
+ String methodString = scriptName.substring(0, idx).toUpperCase();
+ if (METHODS.contains(methodString)) {
+ method = methodString;
+ scriptName = scriptName.substring(idx + 1);
+ }
+ } else if (METHODS.contains(scriptName.toUpperCase())) {
+ method = scriptName.toUpperCase();
+ }
+ }
+// return Capability.builder().withName(scriptName).withResourceType(resourceType).withScriptExtension(scriptExtension)
+// .withVersion(version).withExtension(extension).withMethod(method).build();
+ return null;
+ }
+}
diff --git a/src/main/java/org/apache/sling/scriptingbundle/maven/plugin/ProvidedCapability.java b/src/main/java/org/apache/sling/scriptingbundle/maven/plugin/ProvidedCapability.java
new file mode 100644
index 0000000..70b304d
--- /dev/null
+++ b/src/main/java/org/apache/sling/scriptingbundle/maven/plugin/ProvidedCapability.java
@@ -0,0 +1,134 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+package org.apache.sling.scriptingbundle.maven.plugin;
+
+import java.util.Objects;
+
+import org.apache.commons.lang3.StringUtils;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+class ProvidedCapability {
+ private final String resourceType;
+ private final String extendsResourceType;
+ private final String version;
+ private final String requestExtension;
+ private final String requestMethod;
+
+ private ProvidedCapability(@NotNull String resourceType, @Nullable String extendsResourceType,
+ @Nullable String version, @Nullable String requestExtension, @Nullable String requestMethod) {
+ this.resourceType = resourceType;
+ this.extendsResourceType = extendsResourceType;
+ this.version = version;
+ this.requestExtension = requestExtension;
+ this.requestMethod = requestMethod;
+ }
+
+ static Builder builder() {
+ return new Builder();
+ }
+
+ @NotNull
+ public String getResourceType() {
+ return resourceType;
+ }
+
+ @Nullable
+ public String getVersion() {
+ return version;
+ }
+
+ @Nullable
+ public String getRequestExtension() {
+ return requestExtension;
+ }
+
+ @Nullable
+ public String getExtendsResourceType() {
+ return extendsResourceType;
+ }
+
+ @Nullable
+ public String getRequestMethod() {
+ return requestMethod;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(resourceType, version, requestExtension, requestMethod);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof ProvidedCapability) {
+ ProvidedCapability other = (ProvidedCapability) obj;
+ return Objects.equals(resourceType, other.resourceType) && Objects.equals(version, other.version) && Objects.equals(requestExtension, other.requestExtension) && Objects.equals(requestMethod, other.requestMethod);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s{resourceType=%s, version=%s, requestExtension=%s, requestMethod=%s}", this.getClass().getSimpleName(),
+ resourceType, version, requestExtension, requestMethod);
+ }
+
+ static class Builder {
+ private String resourceType;
+ private String extendsResourceType;
+ private String version;
+ private String requestExtension;
+ private String requestMethod;
+
+ Builder withResourceType(String resourceType) {
+ if (StringUtils.isEmpty(resourceType)) {
+ throw new NullPointerException("The script's resourceType cannot be null or empty.");
+ }
+ this.resourceType = resourceType;
+ return this;
+ }
+
+ Builder withExtendsResourceType(String extendsResourceType) {
+ this.extendsResourceType = extendsResourceType;
+ return this;
+ }
+
+ Builder withVersion(String version) {
+ this.version = version;
+ return this;
+ }
+
+ Builder withRequestExtension(String requestExtension) {
+ this.requestExtension = requestExtension;
+ return this;
+ }
+
+ Builder withRequestMethod(String requestMethod) {
+ this.requestMethod = requestMethod;
+ return this;
+ }
+
+ ProvidedCapability build() {
+ return new ProvidedCapability(resourceType, extendsResourceType, version, requestExtension, requestMethod);
+ }
+ }
+}
diff --git a/src/main/java/org/apache/sling/scriptingbundle/maven/plugin/RequiredCapability.java b/src/main/java/org/apache/sling/scriptingbundle/maven/plugin/RequiredCapability.java
new file mode 100644
index 0000000..4c738bd
--- /dev/null
+++ b/src/main/java/org/apache/sling/scriptingbundle/maven/plugin/RequiredCapability.java
@@ -0,0 +1,78 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+package org.apache.sling.scriptingbundle.maven.plugin;
+
+import org.apache.commons.lang3.StringUtils;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.osgi.framework.VersionRange;
+
+public class RequiredCapability {
+
+ private final String resourceType;
+ private final VersionRange versionRange;
+
+ private RequiredCapability(@NotNull String resourceType, @Nullable VersionRange versionRange) {
+ this.resourceType = resourceType;
+ this.versionRange = versionRange;
+ }
+
+ static Builder builder() {
+ return new Builder();
+ }
+
+ @NotNull
+ public String getResourceType() {
+ return resourceType;
+ }
+
+ @Nullable
+ public VersionRange getVersionRange() {
+ return versionRange;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s{resourceType=%s, versionRange=%s}", this.getClass().getSimpleName(),
+ resourceType, versionRange);
+ }
+
+ static class Builder {
+ private String resourceType;
+ private VersionRange versionRange;
+
+ RequiredCapability build() {
+ return new RequiredCapability(resourceType, versionRange);
+ }
+
+ Builder withResourceType(String resourceType) {
+ if (StringUtils.isEmpty(resourceType)) {
+ throw new NullPointerException("The required resourceType cannot be null or empty.");
+ }
+ this.resourceType = resourceType;
+ return this;
+ }
+
+ Builder withVersionRange(VersionRange versionRange) {
+ this.versionRange = versionRange;
+ return this;
+ }
+ }
+
+}
diff --git a/src/main/java/org/apache/sling/scriptingbundle/maven/plugin/ResourceTypeFolderAnalyser.java b/src/main/java/org/apache/sling/scriptingbundle/maven/plugin/ResourceTypeFolderAnalyser.java
new file mode 100644
index 0000000..a6cce74
--- /dev/null
+++ b/src/main/java/org/apache/sling/scriptingbundle/maven/plugin/ResourceTypeFolderAnalyser.java
@@ -0,0 +1,190 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+package org.apache.sling.scriptingbundle.maven.plugin;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.maven.plugin.logging.Log;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.osgi.framework.Version;
+import org.osgi.framework.VersionRange;
+
+
+class ResourceTypeFolderAnalyser {
+
+ private final Log log;
+ private final Path scriptsDirectory;
+
+ ResourceTypeFolderAnalyser(@NotNull Log log, @NotNull Path scriptsDirectory) {
+ this.log = log;
+ this.scriptsDirectory = scriptsDirectory;
+ }
+
+ Capabilities getCapabilities(@NotNull Path resourceTypeDirectory) {
+ var providedCapabilities = new ArrayList<ProvidedCapability>();
+ var requiredCapabilities = new ArrayList<RequiredCapability>();
+ String version = null;
+ String resourceType = null;
+ try {
+ version = Version.parseVersion(resourceTypeDirectory.getFileName().toString()).toString();
+ } catch (IllegalArgumentException ignored) {
+ // no version
+ }
+ if (StringUtils.isNotEmpty(version)) {
+ Path parent = resourceTypeDirectory.getParent();
+ if (parent != null) {
+ resourceType = getResourceType(parent);
+ }
+ } else {
+ resourceType = getResourceType(resourceTypeDirectory);
+ }
+ if (resourceType != null) {
+ String resourceTypeLabel = getResourceTypeLabel(resourceType);
+ try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(scriptsDirectory.resolve(resourceTypeDirectory))) {
+ for (Path child : directoryStream) {
+ if (Files.isRegularFile(child)) {
+ Path file = child.getFileName();
+ if (file != null) {
+ String[] scriptNameParts = file.toString().split("\\.");
+ if (scriptNameParts.length == 1) {
+ if (MetadataMojo.EXTENDS_FILE.equals(file.toString())) {
+ processExtendsFile(resourceType, version, child, providedCapabilities, requiredCapabilities);
+ } else if (MetadataMojo.REQUIRES_FILE.equals(file.toString())) {
+ processRequiresFile(child, requiredCapabilities);
+ }
+ } else {
+
+ }
+ }
+ } else if (Files.isDirectory(child)) {
+
+ }
+ }
+ } catch (IOException | IllegalArgumentException e) {
+ log.warn(String.format("Cannot analyser folder %s.", scriptsDirectory.resolve(resourceTypeDirectory).toString()));
+ if (log.isDebugEnabled()) {
+ log.debug(e);
+ }
+ }
+ }
+
+ return new Capabilities(providedCapabilities, requiredCapabilities);
+ }
+
+ private void processExtendsFile(@NotNull String resourceType, @Nullable String version, @NotNull Path extendsFile,
+ @NotNull ArrayList<ProvidedCapability> providedCapabilities,
+ @NotNull ArrayList<RequiredCapability> requiredCapabilities)
+ throws IOException {
+ List<String> extendResources = Files.readAllLines(extendsFile, StandardCharsets.UTF_8);
+ if (extendResources.size() == 1) {
+ String extend = extendResources.get(0);
+ if (StringUtils.isNotEmpty(extend)) {
+ String[] extendParts = extend.split(";");
+ String extendedResourceType = extendParts[0];
+ String extendedResourceTypeVersion = extendParts.length > 1 ? extendParts[1] : null;
+ providedCapabilities.add(
+ ProvidedCapability.builder()
+ .withResourceType(resourceType)
+ .withVersion(version)
+ .withExtendsResourceType(extendedResourceType)
+ .build());
+ RequiredCapability.Builder requiredBuilder =
+ RequiredCapability.builder().withResourceType(extendedResourceType);
+ try {
+ if (extendedResourceTypeVersion != null) {
+ requiredBuilder.withVersionRange(VersionRange.valueOf(extendedResourceTypeVersion));
+ }
+ } catch (IllegalArgumentException ignored) {
+ log.warn(String.format("Invalid version range '%s' defined for extended resourceType '%s'" +
+ " in file %s.", extendedResourceTypeVersion, extendedResourceType,
+ extendsFile.toString()));
+ }
+ requiredCapabilities.add(requiredBuilder.build());
+ }
+ }
+ }
+
+ private void processRequiresFile(@NotNull Path requiresFile,
+ @NotNull ArrayList<RequiredCapability> requiredCapabilities)
+ throws IOException {
+ List<String> requiredResourceTypes = Files.readAllLines(requiresFile, StandardCharsets.UTF_8);
+ for (String requiredResourceType : requiredResourceTypes) {
+ if (StringUtils.isNotEmpty(requiredResourceType)) {
+ String[] requireParts = requiredResourceType.split(";");
+ String resourceType = requireParts[0];
+ String version = requireParts.length > 1 ? requireParts[1] : null;
+ RequiredCapability.Builder requiredBuilder =
+ RequiredCapability.builder().withResourceType(resourceType);
+ try {
+ if (version != null) {
+ requiredBuilder.withVersionRange(VersionRange.valueOf(version));
+ }
+ } catch (IllegalArgumentException ignored) {
+ log.warn(String.format("Invalid version range '%s' defined for required resourceType '%s'" +
+ " in file %s.", version, resourceType,
+ requiresFile.toString()));
+ }
+ requiredCapabilities.add(requiredBuilder.build());
+ }
+ }
+ }
+
+ private String getResourceType(@NotNull Path resourceTypeFolder) {
+ StringBuilder stringBuilder = new StringBuilder();
+ Path relativeResourceTypePath = scriptsDirectory.relativize(resourceTypeFolder);
+ if (StringUtils.isNotEmpty(relativeResourceTypePath.toString())) {
+ int parts = relativeResourceTypePath.getNameCount();
+ for (int i = 0; i < parts; i++) {
+ stringBuilder.append(relativeResourceTypePath.getName(i));
+ if (i < parts - 1) {
+ stringBuilder.append('/');
+ }
+ }
+ }
+ return stringBuilder.toString();
+ }
+
+ private @NotNull String getResourceTypeLabel(@NotNull String resourceType) {
+ String resourceTypeLabel = null;
+ if (resourceType.contains("/")) {
+ int lastIndex = resourceType.lastIndexOf('/');
+ if (lastIndex < resourceType.length() - 2) {
+ resourceTypeLabel = resourceType.substring(++lastIndex);
+ }
+ } else if (resourceType.contains(".")) {
+ int lastIndex = resourceType.lastIndexOf('.');
+ if (lastIndex < resourceType.length() - 2) {
+ resourceTypeLabel = resourceType.substring(++lastIndex);
+ }
+ }
+ if (StringUtils.isEmpty(resourceTypeLabel)) {
+ throw new IllegalArgumentException(String.format("Resource type '%s' does not provide a resourceTypeLabel.", resourceType));
+ }
+ return resourceTypeLabel;
+ }
+
+}
diff --git a/src/main/java/org/apache/sling/scriptingbundle/maven/plugin/ResourceTypeFolderPredicate.java b/src/main/java/org/apache/sling/scriptingbundle/maven/plugin/ResourceTypeFolderPredicate.java
new file mode 100644
index 0000000..f84b4b5
--- /dev/null
+++ b/src/main/java/org/apache/sling/scriptingbundle/maven/plugin/ResourceTypeFolderPredicate.java
@@ -0,0 +1,76 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+package org.apache.sling.scriptingbundle.maven.plugin;
+
+import java.io.IOException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.function.Predicate;
+
+import org.osgi.framework.Version;
+
+public class ResourceTypeFolderPredicate implements Predicate<Path> {
+
+ @Override
+ public boolean test(Path folder) {
+ if (folder == null) {
+ return false;
+ }
+ Path lastSegment = folder.getFileName();
+ if (lastSegment == null) {
+ return false;
+ }
+ try {
+ Version.parseVersion(lastSegment.toString());
+ Path parent = folder.getParent();
+ if (parent != null) {
+ lastSegment = parent.getFileName();
+ }
+ } catch (IllegalArgumentException ignored) {
+ // last segment does not denote a version
+ }
+ String resourceTypeLabel;
+ if (lastSegment != null) {
+ String lastSegmentString = lastSegment.toString();
+ int lastDotIndex = lastSegmentString.lastIndexOf('.');
+ if (lastDotIndex != -1 && lastDotIndex < lastSegmentString.length() - 1) {
+ resourceTypeLabel = lastSegmentString.substring(++lastDotIndex);
+ } else {
+ resourceTypeLabel = lastSegmentString;
+ }
+ try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(folder, Files::isRegularFile)) {
+ for (Path path : directoryStream) {
+ Path fileName = path.getFileName();
+ if (fileName != null) {
+ String childName = fileName.toString();
+ String scriptName = childName.indexOf('.') != -1 ? childName.substring(0, childName.indexOf('.')) : null;
+ if (resourceTypeLabel.equals(scriptName) || MetadataMojo.EXTENDS_FILE.equals(childName) ||
+ MetadataMojo.METHODS.contains(scriptName)) {
+ return true;
+ }
+ }
+ }
+ } catch (IOException ignored) {
+ // ignore; will return false anyways
+ }
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/org/apache/sling/scriptingbundle/maven/plugin/ScriptingMavenPlugin.java b/src/main/java/org/apache/sling/scriptingbundle/maven/plugin/ScriptingMavenPlugin.java
deleted file mode 100644
index 1c13d5e..0000000
--- a/src/main/java/org/apache/sling/scriptingbundle/maven/plugin/ScriptingMavenPlugin.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you under the Apache License, Version 2.0 (the
- ~ "License"); you may not use this file except in compliance
- ~ with the License. You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing,
- ~ software distributed under the License is distributed on an
- ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- ~ KIND, either express or implied. See the License for the
- ~ specific language governing permissions and limitations
- ~ under the License.
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-package org.apache.sling.scriptingbundle.maven.plugin;
-
-import org.apache.commons.lang3.StringEscapeUtils;
-import org.apache.maven.execution.MavenSession;
-import org.apache.maven.plugin.AbstractMojo;
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugins.annotations.LifecyclePhase;
-import org.apache.maven.plugins.annotations.Mojo;
-import org.apache.maven.plugins.annotations.Parameter;
-import org.apache.maven.project.MavenProject;
-import org.apache.maven.shared.utils.io.DirectoryScanner;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Version;
-import org.osgi.framework.VersionRange;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-@Mojo(name = "metadata",
- defaultPhase = LifecyclePhase.PACKAGE)
-public class ScriptingMavenPlugin extends AbstractMojo {
-
- @Parameter(defaultValue = "${project}",
- readonly = true)
- private MavenProject project;
-
- @Parameter(defaultValue = "${session}",
- readonly = true)
- private MavenSession session;
-
- @Parameter(defaultValue = "${project.basedir}/src/main/resources/javax.script")
- private String scriptsDirectory;
-
- private static final Set<String> METHODS = new HashSet<>(Arrays.asList(new String[]{"TRACE", "OPTIONS", "GET", "HEAD", "POST", "PUT",
- "DELETE", "PATCH"}));
-
- private static final Set<String> FILE_SEPARATORS = new HashSet<>(Arrays.asList("\\", "/"));
-
- public void execute() throws MojoExecutionException {
- File sdFile = new File(scriptsDirectory);
- if (!sdFile.exists()) {
- sdFile = new File(project.getBasedir(), scriptsDirectory);
- if (!sdFile.exists()) {
- throw new MojoExecutionException("Cannot find file " + scriptsDirectory + ".");
- }
- }
- final AtomicReference<File> scriptsDirectoryReference = new AtomicReference<>();
- scriptsDirectoryReference.set(sdFile);
- ;
- DirectoryScanner scanner = new DirectoryScanner();
- scanner.setBasedir(sdFile);
- scanner.setIncludes("**");
- scanner.setExcludes("**/*.class");
- scanner.addDefaultExcludes();
- scanner.scan();
-
- List<String> scriptPaths = Stream.of(scanner.getIncludedFiles()).map(path -> new File(scriptsDirectoryReference.get(), path))
- .map(file -> file.getPath().substring((scriptsDirectoryReference.get().getPath() + File.pathSeparatorChar).length()))
- .collect(Collectors.toList());
-
-
- List<String> requires = new ArrayList<>();
-
- List<String> capabilities = new ArrayList<>();
- for (String scriptPath : scriptPaths) {
- Script script = getScripts(scriptPath);
-
- String capability = "sling.resourceType;sling.resourceType=\"" + script.rt.replace("\"", "\\\"") + "\"";
-
- if (!(script.rt.equals(script.name) || script.rt.endsWith("." + script.name) || script.name.isEmpty())) {
- if (!script.name.equalsIgnoreCase("requires")) {
- if (!script.name.equalsIgnoreCase("extends")) {
- capability += ";sling.resourceType.selectors:List<String>=\"" + script.name.replace("\"", "\\\"") + "\"";
- } else {
- try (BufferedReader input = new BufferedReader(
- new FileReader(new File(scriptsDirectoryReference.get(), scriptPath)))) {
- String extend = input.readLine();
-
- capability += ";extends=\"" + extend.split(";")[0].replace("\"", "\\\"") + "\"";
- requires.add(extend + ";extends=true");
- } catch (Exception ex) {
- getLog().error(ex);
- }
- }
- } else {
- try (BufferedReader input = new BufferedReader(new FileReader(new File(scriptsDirectoryReference.get(), scriptPath)))) {
- for (String line = input.readLine(); line != null; line = input.readLine()) {
- requires.add(line);
- }
- } catch (Exception ex) {
- getLog().error(ex);
- }
- }
- }
- if (script.extension != null) {
- capability += ";sling.resourceType.extensions:List<String>=\"" + script.extension.replace("\"", "\\\"") + "\"";
- }
-
- if (script.method != null) {
- capability += ";sling.servlet.methods:List<String>=\"" + script.method.replace("\"", "\\\"") + "\"";
- }
- if (script.version != null) {
- capability += ";version:Version=\"" + script.version + "\"";
- }
- capabilities.add(capability);
- }
- List<String> requirements = new ArrayList<>();
- for (String require : requires) {
- String[] parts = require.split(";");
- String rt = parts[0];
- String filter = "(sling.resourceType=" + rt.replace("\"", "\\\"") + ")";
-
- if (parts.length > 1) {
- VersionRange range = new VersionRange(parts[1].substring(parts[1].indexOf("=") + 1).replace("\"", "").trim());
- filter = "(&" + filter + range.toFilterString("version") + ")";
- }
- if (parts.length > 2) {
- filter = "(&" + filter + "(!(sling.resourceType.selectors=*)))";
- }
- requirements.add("sling.resourceType;filter:=\"" + filter + "\"");
- }
-
- project.getProperties().setProperty(ScriptingMavenPlugin.class.getPackage().getName() + "." + Constants.PROVIDE_CAPABILITY,
- String.join(",", capabilities));
- project.getProperties().setProperty(ScriptingMavenPlugin.class.getPackage().getName() + "." + Constants.REQUIRE_CAPABILITY,
- String.join(",", requirements));
- }
-
- static class Script {
- String rt;
- String version;
- String name;
- String extension;
- String scriptExtension;
- String method;
- }
-
- static Script getScripts(String script) {
- String fileSeparator = null;
- for (String sep : FILE_SEPARATORS) {
- if (script.contains(sep)) {
- fileSeparator = sep;
- break;
- }
- }
- Script result = new Script();
- String[] parts = script.split(Pattern.quote(fileSeparator));
-
- result.rt = parts[0];
- result.version = parts.length > 2 ? new Version(parts[1]).toString() : null;
- result.name = parts.length > 2 ? parts[2] : parts[1];
- int idx = result.name.lastIndexOf('.');
- if (idx != -1) {
- result.scriptExtension = result.name.substring(idx + 1);
- result.name = result.name.substring(0, idx);
- if (result.scriptExtension.isEmpty()) {
- result.scriptExtension = null;
- }
- }
-
- idx = result.name.lastIndexOf('.');
- if (idx != -1) {
- result.extension = result.name.substring(idx + 1);
- result.name = result.name.substring(0, idx);
- if (result.extension.isEmpty() || result.extension.equalsIgnoreCase("html")) {
- result.extension = null;
- }
- } else {
- result.extension = null;
- }
-
- idx = result.name.indexOf('.');
- if (idx != -1) {
- String methodString = result.name.substring(0, idx).toUpperCase();
- if (METHODS.contains(methodString)) {
- result.method = methodString;
- result.name = result.name.substring(idx + 1);
- }
- } else if (METHODS.contains(result.name.toUpperCase())) {
- result.method = result.name.toUpperCase();
- result.name = "";
- }
- return result;
- }
-}
diff --git a/src/test/java/org/apache/sling/scriptingbundle/maven/plugin/MetadataMojoCapabilityFindingTest.java b/src/test/java/org/apache/sling/scriptingbundle/maven/plugin/MetadataMojoCapabilityFindingTest.java
new file mode 100644
index 0000000..5f06a1f
--- /dev/null
+++ b/src/test/java/org/apache/sling/scriptingbundle/maven/plugin/MetadataMojoCapabilityFindingTest.java
@@ -0,0 +1,148 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+package org.apache.sling.scriptingbundle.maven.plugin;
+
+import org.apache.maven.plugin.logging.Log;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+@Ignore
+public class MetadataMojoCapabilityFindingTest {
+
+ private MetadataMojo plugin;
+
+ @Rule
+ public ExpectedException thrown= ExpectedException.none();
+
+ @Before
+ public void setUp() {
+ plugin = spy(new MetadataMojo());
+ when(plugin.getLog()).thenReturn(mock(Log.class));
+ }
+
+ @After
+ public void tearDown() {
+ plugin = null;
+ }
+
+ @Test
+ public void testScriptNameFullCalculation() {
+ String scriptPath = "org.apache.foo/1.0.0/POST.hi.xml.jsp";
+
+ ProvidedCapability expected = ProvidedCapability.builder()
+ .withResourceType("org.apache.foo")
+ .withVersion("1.0.0")
+// .withName("hi")
+// .withMethod("POST")
+// .withExtension("xml")
+// .withScriptExtension("jsp")
+ .build();
+ assertEquals(expected, plugin.getScript(scriptPath));
+ }
+
+ @Test
+ public void testScriptNameFullCalculationFolderHierarchy() {
+ String scriptPath = "org/apache/foo/1.0.0/POST.hi.xml.jsp";
+
+ ProvidedCapability expected = ProvidedCapability.builder()
+ .withResourceType("org/apache/foo")
+ .withVersion("1.0.0")
+// .withName("hi")
+// .withMethod("POST")
+// .withExtension("xml")
+// .withScriptExtension("jsp")
+ .build();
+ assertEquals(expected, plugin.getScript(scriptPath));
+ }
+
+ @Test
+ public void testScriptNameMinCalculation() {
+ String scriptPath = "org.apache.foo/foo.jsp";
+
+ ProvidedCapability expected = ProvidedCapability.builder()
+ .withResourceType("org.apache.foo")
+// .withName("foo")
+// .withScriptExtension("jsp")
+ .build();
+
+ assertEquals(expected, plugin.getScript(scriptPath));
+ }
+
+ @Test
+ public void testScriptNameMinCalculationFolderHierarchy() {
+ String scriptPath = "org/apache/foo/foo.jsp";
+
+ ProvidedCapability expected = ProvidedCapability.builder()
+ .withResourceType("org/apache/foo")
+// .withName("foo")
+// .withScriptExtension("jsp")
+ .build();
+
+ assertEquals(expected, plugin.getScript(scriptPath));
+ }
+
+ @Test
+ public void testScriptNameVersionAndMethodCalculation() {
+ String scriptPath = "org.apache.foo/1.2.0/Post.jsp";
+
+ ProvidedCapability expected = ProvidedCapability.builder()
+ .withResourceType("org.apache.foo")
+ .withVersion("1.2.0")
+// .withMethod("POST")
+// .withScriptExtension("jsp")
+ .build();
+ assertEquals(expected, plugin.getScript(scriptPath));
+ }
+
+ @Test()
+ public void testScriptNameVersionAndMethodMinCalculation() {
+ thrown.expect(NullPointerException.class);
+ thrown.expectMessage("The script's scriptExtension cannot be null");
+
+ String scriptPath = "org.apache.foo/1.2.0/Post";
+ plugin.getScript(scriptPath);
+ }
+
+ @Test()
+ public void testScriptNameMinCalculationInvalidPath() {
+ thrown.expect(NullPointerException.class);
+ thrown.expectMessage("The script's scriptExtension cannot be null");
+
+ String scriptPath = "org.apache.foo/1.2.0/foo.";
+ plugin.getScript(scriptPath);
+ }
+
+ @Test()
+ public void testScriptNameMinCalculationNoResourceType() {
+ thrown.expect(NullPointerException.class);
+ thrown.expectMessage("The script's resourceType cannot be null");
+
+ String scriptPath = "foo.html";
+ plugin.getScript(scriptPath);
+ }
+}
diff --git a/src/test/java/org/apache/sling/scriptingbundle/maven/plugin/MetadataMojoTest.java b/src/test/java/org/apache/sling/scriptingbundle/maven/plugin/MetadataMojoTest.java
new file mode 100644
index 0000000..8530695
--- /dev/null
+++ b/src/test/java/org/apache/sling/scriptingbundle/maven/plugin/MetadataMojoTest.java
@@ -0,0 +1,79 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+package org.apache.sling.scriptingbundle.maven.plugin;
+
+import java.io.File;
+import java.nio.file.Paths;
+import java.util.Properties;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.plugin.testing.MojoRule;
+import org.apache.maven.plugin.testing.SilentLog;
+import org.apache.maven.project.MavenProject;
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.osgi.framework.Constants;
+import org.sonatype.plexus.build.incremental.DefaultBuildContext;
+
+import static org.junit.Assert.assertTrue;
+
+public class MetadataMojoTest {
+
+ @Rule
+ public MojoRule mojoRule = new MojoRule();
+
+ @After
+ public void after() {
+ System.clearProperty("basedir");
+ }
+
+ @Test
+ public void testProject1() throws Exception {
+ MojoProject mojoProject = getMojoProject(getProjectLocation("project-1"));
+ mojoProject.mojo.execute();
+ Properties properties = mojoProject.project.getProperties();
+ assertTrue(properties.containsKey(MetadataMojo.class.getPackage() + "." + Constants.PROVIDE_CAPABILITY));
+ }
+
+ private MojoProject getMojoProject(File projectDirectory) throws Exception {
+ SilentLog log = new SilentLog();
+ DefaultBuildContext buildContext = new DefaultBuildContext();
+ buildContext.enableLogging(log);
+ MavenProject project = mojoRule.readMavenProject(projectDirectory);
+ MavenSession session = mojoRule.newMavenSession(project);
+ MojoExecution execution = mojoRule.newMojoExecution("metadata");
+ MetadataMojo validateMojo = (MetadataMojo) mojoRule.lookupConfiguredMojo(session, execution);
+ validateMojo.setLog(log);
+ MojoProject mojoProject = new MojoProject();
+ mojoProject.mojo = validateMojo;
+ mojoProject.project = project;
+ return mojoProject;
+ }
+
+ private class MojoProject {
+ MetadataMojo mojo;
+ MavenProject project;
+ }
+
+ private File getProjectLocation(String projectName) {
+ return Paths.get("src", "test", "resources", projectName).toFile();
+ }
+}
diff --git a/src/test/java/org/apache/sling/scriptingbundle/maven/plugin/ScriptingMavenPluginTest.java b/src/test/java/org/apache/sling/scriptingbundle/maven/plugin/ScriptingMavenPluginTest.java
deleted file mode 100644
index abc4f7b..0000000
--- a/src/test/java/org/apache/sling/scriptingbundle/maven/plugin/ScriptingMavenPluginTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you under the Apache License, Version 2.0 (the
- ~ "License"); you may not use this file except in compliance
- ~ with the License. You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing,
- ~ software distributed under the License is distributed on an
- ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- ~ KIND, either express or implied. See the License for the
- ~ specific language governing permissions and limitations
- ~ under the License.
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-package org.apache.sling.scriptingbundle.maven.plugin;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-public class ScriptingMavenPluginTest {
- @Test
- public void testScriptNameFullCalculation() {
- String scriptPath = "org.apache.foo/1.0.0/POST.hi.xml.jsp";
-
- ScriptingMavenPlugin.Script script = ScriptingMavenPlugin.getScripts(scriptPath);
-
- Assert.assertEquals("org.apache.foo", script.rt);
- Assert.assertEquals("1.0.0", script.version);
- Assert.assertEquals("hi", script.name);
- Assert.assertEquals("POST", script.method);
- Assert.assertEquals("xml", script.extension);
- Assert.assertEquals("jsp", script.scriptExtension);
- }
-
- @Test
- public void testScriptNameMinCalculation() {
- String scriptPath = "org.apache.foo/foo";
-
- ScriptingMavenPlugin.Script script = ScriptingMavenPlugin.getScripts(scriptPath);
-
- Assert.assertEquals("org.apache.foo", script.rt);
- Assert.assertNull("1.0.0", script.version);
- Assert.assertEquals("foo", script.name);
- Assert.assertNull(script.method);
- Assert.assertNull(script.extension);
- Assert.assertNull(script.scriptExtension);
- }
-
- @Test
- public void testScriptNameVersionAndMethodCalculation() {
- String scriptPath = "org.apache.foo/1.2.0/Post.jsp";
-
- ScriptingMavenPlugin.Script script = ScriptingMavenPlugin.getScripts(scriptPath);
-
- Assert.assertEquals("org.apache.foo", script.rt);
- Assert.assertEquals("1.2.0", script.version);
- Assert.assertEquals("", script.name);
- Assert.assertEquals("POST", script.method);
- Assert.assertNull(script.extension);
- Assert.assertEquals("jsp", script.scriptExtension);
- }
-
- @Test
- public void testScriptNameVersionAndMethodMinCalculation() {
- String scriptPath = "org.apache.foo/1.2.0/Post.";
-
- ScriptingMavenPlugin.Script script = ScriptingMavenPlugin.getScripts(scriptPath);
-
- Assert.assertEquals("org.apache.foo", script.rt);
- Assert.assertEquals("1.2.0", script.version);
- Assert.assertEquals("", script.name);
- Assert.assertEquals("POST", script.method);
- Assert.assertNull(script.extension);
- Assert.assertNull(script.scriptExtension);
- }
-}
diff --git a/src/test/resources/project-1/pom.xml b/src/test/resources/project-1/pom.xml
new file mode 100644
index 0000000..0718199
--- /dev/null
+++ b/src/test/resources/project-1/pom.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.sling</groupId>
+ <artifactId>scriptingbundle-maven-plugin-project-1</artifactId>
+ <version>0.0.1</version>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>scriptingbundle-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>prepare-package</phase>
+ <goals>
+ <goal>metadata</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/src/test/resources/project-1/src/main/resources/javax.script/org.apache.sling.foobar/1.0.0/extends b/src/test/resources/project-1/src/main/resources/javax.script/org.apache.sling.foobar/1.0.0/extends
new file mode 100644
index 0000000..2d24f10
--- /dev/null
+++ b/src/test/resources/project-1/src/main/resources/javax.script/org.apache.sling.foobar/1.0.0/extends
@@ -0,0 +1 @@
+org/apache/sling/bar
diff --git a/src/test/resources/project-1/src/main/resources/javax.script/org.apache.sling.foobar/1.0.0/foobar.html b/src/test/resources/project-1/src/main/resources/javax.script/org.apache.sling.foobar/1.0.0/foobar.html
new file mode 100644
index 0000000..e69de29
diff --git a/src/test/resources/project-1/src/main/resources/javax.script/org.apache.sling.foobar/1.0.0/requires b/src/test/resources/project-1/src/main/resources/javax.script/org.apache.sling.foobar/1.0.0/requires
new file mode 100644
index 0000000..437b4ae
--- /dev/null
+++ b/src/test/resources/project-1/src/main/resources/javax.script/org.apache.sling.foobar/1.0.0/requires
@@ -0,0 +1 @@
+sling/default
diff --git a/src/test/resources/project-1/src/main/resources/javax.script/org.apache.sling.foobar/GET.html b/src/test/resources/project-1/src/main/resources/javax.script/org.apache.sling.foobar/GET.html
new file mode 100644
index 0000000..e69de29
diff --git a/src/test/resources/project-1/src/main/resources/javax.script/org/apache/sling/bar/1.0.0/bar.html b/src/test/resources/project-1/src/main/resources/javax.script/org/apache/sling/bar/1.0.0/bar.html
new file mode 100644
index 0000000..e69de29
diff --git a/src/test/resources/project-1/src/main/resources/javax.script/org/apache/sling/foo/foo.GET.html.html b/src/test/resources/project-1/src/main/resources/javax.script/org/apache/sling/foo/foo.GET.html.html
new file mode 100644
index 0000000..93f1f4d
--- /dev/null
+++ b/src/test/resources/project-1/src/main/resources/javax.script/org/apache/sling/foo/foo.GET.html.html
@@ -0,0 +1,19 @@
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<span>It works!</span>
diff --git a/src/test/resources/spotbugs-exclude.xml b/src/test/resources/spotbugs-exclude.xml
new file mode 100644
index 0000000..fd5f18d
--- /dev/null
+++ b/src/test/resources/spotbugs-exclude.xml
@@ -0,0 +1,24 @@
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<FindBugsFilter>
+ <!-- false positive in Java 11, see https://github.com/spotbugs/spotbugs/issues/756 -->
+ <Match>
+ <Bug pattern="RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE"/>
+ </Match>
+</FindBugsFilter>