diff --git a/.sling-module.json b/.sling-module.json index b83f728..966a2fe 100644 --- a/.sling-module.json +++ b/.sling-module.json @@ -1,5 +1,5 @@ { "jenkins": { - "jdks": [8, 11, 13] + "jdks": [11, 17, 21] } } diff --git a/README.md b/README.md index 24a8ce9..128a92e 100644 --- a/README.md +++ b/README.md @@ -13,4 +13,7 @@ Sling application. When executed, the plugin will define two project properties `org.apache.sling.scriptingbundle.maven.plugin.Provide-Capability`) which can be used to populate the corresponding bundle headers. +An optional `serviceRanking` can be configured to apply a service ranking to all bundled +scripts in the bundle via the `Sling-Bundled-Scripts-Ranking` bundle header. + For more details head over to the documentation page from https://sling.apache.org/components/scriptingbundle-maven-plugin/. diff --git a/pom.xml b/pom.xml index 5d351dd..9219e04 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ 8 - 3.6.0 + 3.9.16 12344664,12347157,12348422,12350010,12350474,12350606 ${project.artifactId}-archives/${project.artifactId}-LATEST 2021-12-16T14:04:46Z @@ -108,7 +108,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.3.0 + 4.10.3.0 Max true @@ -167,23 +167,28 @@ org.jetbrains annotations + provided org.apache.maven maven-plugin-api + compile org.apache.maven maven-model + compile org.apache.maven maven-core + compile org.apache.maven maven-compat + compile org.apache.maven.plugin-tools @@ -191,6 +196,18 @@ 3.4 provided + + org.apache.commons + commons-lang3 + 3.20.0 + compile + + + commons-io + commons-io + 2.22.0 + compile + org.osgi org.osgi.framework diff --git a/src/main/java/org/apache/sling/scriptingbundle/plugin/bnd/BundledScriptsScannerPlugin.java b/src/main/java/org/apache/sling/scriptingbundle/plugin/bnd/BundledScriptsScannerPlugin.java index d7893cc..aa914c5 100644 --- a/src/main/java/org/apache/sling/scriptingbundle/plugin/bnd/BundledScriptsScannerPlugin.java +++ b/src/main/java/org/apache/sling/scriptingbundle/plugin/bnd/BundledScriptsScannerPlugin.java @@ -79,7 +79,10 @@ public boolean analyzeJar(Analyzer analyzer) throws Exception { try { if (!Files.isDirectory(file)) { Path workingCopy = Paths.get(workDirectory.toString(), sourceDirectoryPath.relativize(file).toString()); - Files.createDirectories(workingCopy.getParent()); + Path parentDir = workingCopy.getParent(); + if (parentDir != null) { + Files.createDirectories(parentDir); + } Files.copy(file, workingCopy, StandardCopyOption.REPLACE_EXISTING); } } catch (IOException e) { @@ -113,6 +116,11 @@ public boolean analyzeJar(Analyzer analyzer) throws Exception { requiredCapabilities = requiredCapabilitiesDefinition; } analyzer.set(aQute.bnd.osgi.Constants.REQUIRE_CAPABILITY, requiredCapabilities); + + Integer serviceRanking = getConfiguredServiceRanking(); + if (serviceRanking != null) { + analyzer.set(Constants.SLING_BUNDLED_SCRIPTS_RANKING_HEADER, serviceRanking.toString()); + } return false; } @@ -198,6 +206,18 @@ private boolean getMissingRequirementsOptional() { return true; } + private Integer getConfiguredServiceRanking() { + String serviceRankingString = pluginProperties.get(Constants.BND_SERVICE_RANKING); + if (StringUtils.isNotEmpty(serviceRankingString)) { + try { + return Integer.valueOf(serviceRankingString.trim()); + } catch (NumberFormatException e) { + logger.error(String.format("Invalid service ranking: %s.", serviceRankingString)); + } + } + return null; + } + private Stream walkPath(Path path, Set includes, Set excludes) throws IOException { return Files.walk(path).filter(file -> { boolean include = includes.isEmpty(); diff --git a/src/main/java/org/apache/sling/scriptingbundle/plugin/maven/MetadataMojo.java b/src/main/java/org/apache/sling/scriptingbundle/plugin/maven/MetadataMojo.java index 1a562e4..b6d54dd 100644 --- a/src/main/java/org/apache/sling/scriptingbundle/plugin/maven/MetadataMojo.java +++ b/src/main/java/org/apache/sling/scriptingbundle/plugin/maven/MetadataMojo.java @@ -175,6 +175,17 @@ public class MetadataMojo extends AbstractMojo { @Parameter(property = "scriptingbundle.missingRequirementsOptional", defaultValue = "true") private boolean missingRequirementsOptional = true; + /** + * When set, the given numeric value is exposed via the {@code org.apache.sling.scriptingbundle.maven.plugin.Sling-Bundled-Scripts-Ranking} + * Maven project property, which can be used to generate the {@code Sling-Bundled-Scripts-Ranking} OSGi bundle header. That header + * applies globally to all scripts in the bundle and allows influencing the service ranking of the servlets registered for the + * bundled scripts. When not set, the property is not generated. + * + * @since 0.6.0 + */ + @Parameter(property = "scriptingbundle.serviceRanking") + private Integer serviceRanking; + private Capabilities capabilities; public void execute() { @@ -199,7 +210,10 @@ public void execute() { try { if (!Files.isDirectory(file)) { Path workingCopy = workDirectory.resolve(sourceDirectoryPath.relativize(file)); - Files.createDirectories(workingCopy.getParent()); + Path parentDir = workingCopy.getParent(); + if (parentDir != null) { + Files.createDirectories(parentDir); + } Files.copy(file, workingCopy, StandardCopyOption.REPLACE_EXISTING); } } catch (IOException e) { @@ -236,6 +250,10 @@ public void execute() { providedCapabilitiesDefinition); project.getProperties().put("org.apache.sling.scriptingbundle.maven.plugin." + org.osgi.framework.Constants.REQUIRE_CAPABILITY, requiredCapabilitiesDefinition); + if (serviceRanking != null) { + project.getProperties().put("org.apache.sling.scriptingbundle.maven.plugin." + Constants.SLING_BUNDLED_SCRIPTS_RANKING_HEADER, + serviceRanking.toString()); + } } catch (IOException e) { logger.error("Unable to generate working directory.", e); } diff --git a/src/main/java/org/apache/sling/scriptingbundle/plugin/processor/Constants.java b/src/main/java/org/apache/sling/scriptingbundle/plugin/processor/Constants.java index 0c38ba8..fcd8962 100644 --- a/src/main/java/org/apache/sling/scriptingbundle/plugin/processor/Constants.java +++ b/src/main/java/org/apache/sling/scriptingbundle/plugin/processor/Constants.java @@ -53,7 +53,9 @@ private Constants() {} public static final String BND_SCRIPT_ENGINE_MAPPINGS = "scriptEngineMappings"; public static final String BND_SEARCH_PATHS = "searchPaths"; public static final String BND_MISSING_REQUIREMENTS_OPTIONAL = "missingRequirementsOptional"; + public static final String BND_SERVICE_RANKING = "serviceRanking"; + public static final String SLING_BUNDLED_SCRIPTS_RANKING_HEADER = "Sling-Bundled-Scripts-Ranking"; public static final String SLING_RESOURCE_SUPER_TYPE_XML_LOCAL_NAME = "resourceSuperType"; public static final String SLING_REQUIRED_RESOURCE_TYPES = "sling:requiredResourceTypes"; public static final String SLING_REQUIRED_RESOURCE_TYPES_XML_LOCAL_NAME = "requiredResourceTypes"; diff --git a/src/main/java/org/apache/sling/scriptingbundle/plugin/processor/filevault/VaultContentXmlReader.java b/src/main/java/org/apache/sling/scriptingbundle/plugin/processor/filevault/VaultContentXmlReader.java index edee6bc..ddb286e 100644 --- a/src/main/java/org/apache/sling/scriptingbundle/plugin/processor/filevault/VaultContentXmlReader.java +++ b/src/main/java/org/apache/sling/scriptingbundle/plugin/processor/filevault/VaultContentXmlReader.java @@ -47,7 +47,7 @@ import org.xml.sax.InputSource; import org.xml.sax.SAXException; -public class VaultContentXmlReader { +public final class VaultContentXmlReader { private static final DocumentBuilderFactory documentBuilderFactory; diff --git a/src/site/markdown/usage.md.vm b/src/site/markdown/usage.md.vm index 2cdaa10..a860951 100644 --- a/src/site/markdown/usage.md.vm +++ b/src/site/markdown/usage.md.vm @@ -111,3 +111,17 @@ writing instructions of another plugin like the `maven-bundle-plugin`: The `osgi.extender` requirement is mandatory to have the bundle wired up to the Apache Sling Servlets Resolver, but this should be manually defined by the developers, so that their bundle is correctly wired up to whatever version of the Servlets Resolver is available on the destination platform. + +$h3 Setting a service ranking for the bundled scripts + +Starting with version 0.6.0, a numeric `serviceRanking` can be configured. It is applied globally to all scripts in the bundle and +influences the service ranking of the servlets that the Apache Sling Servlets Resolver registers for the bundled scripts. When used as a +bnd plugin, the ranking is written directly into the `Sling-Bundled-Scripts-Ranking` bundle header. When used as a Maven plugin, the value +is exposed via the `org.apache.sling.scriptingbundle.maven.plugin.Sling-Bundled-Scripts-Ranking` project property, which has to be added +to the manifest writing instructions of the plugin that generates the bundle, e.g.: + +``` + + ${org.apache.sling.scriptingbundle.maven.plugin.Sling-Bundled-Scripts-Ranking} + +``` diff --git a/src/test/java/org/apache/sling/scriptingbundle/plugin/AbstractPluginTest.java b/src/test/java/org/apache/sling/scriptingbundle/plugin/AbstractPluginTest.java index ee5adb2..ec643f6 100644 --- a/src/test/java/org/apache/sling/scriptingbundle/plugin/AbstractPluginTest.java +++ b/src/test/java/org/apache/sling/scriptingbundle/plugin/AbstractPluginTest.java @@ -19,6 +19,7 @@ package org.apache.sling.scriptingbundle.plugin; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; import java.util.Arrays; @@ -31,6 +32,7 @@ import org.apache.sling.scriptingbundle.plugin.capability.ProvidedResourceTypeCapability; import org.apache.sling.scriptingbundle.plugin.capability.ProvidedScriptCapability; import org.apache.sling.scriptingbundle.plugin.capability.RequiredResourceTypeCapability; +import org.apache.sling.scriptingbundle.plugin.processor.Constants; import org.junit.Test; import org.osgi.framework.Version; import org.osgi.framework.VersionRange; @@ -158,6 +160,7 @@ public void testProject2() throws Exception { PluginExecution execution = executePluginOnProject("project-2"); Capabilities capabilities = execution.getCapabilities(); Map scriptEngineMappings = execution.getScriptEngineMappings(); + assertEquals("100", execution.getHeaderValue(Constants.SLING_BUNDLED_SCRIPTS_RANKING_HEADER)); Set pExpected = new HashSet<>(Arrays.asList( ProvidedResourceTypeCapability.builder().withResourceType("libs/sling/test").withScriptEngine("thymeleaf") .withScriptExtension("html").build(), diff --git a/src/test/java/org/apache/sling/scriptingbundle/plugin/PluginExecution.java b/src/test/java/org/apache/sling/scriptingbundle/plugin/PluginExecution.java index 8c17036..c1d2374 100644 --- a/src/test/java/org/apache/sling/scriptingbundle/plugin/PluginExecution.java +++ b/src/test/java/org/apache/sling/scriptingbundle/plugin/PluginExecution.java @@ -19,17 +19,20 @@ package org.apache.sling.scriptingbundle.plugin; import java.util.Map; +import java.util.function.Function; import org.apache.sling.scriptingbundle.plugin.capability.Capabilities; public class PluginExecution { private final Capabilities capabilities; private final Map scriptEngineMappings; + private final Function valueGetter; - public PluginExecution(Capabilities capabilities, Map scriptEngineMappings) { + public PluginExecution(Capabilities capabilities, Map scriptEngineMappings, Function valueGetter) { super(); this.capabilities = capabilities; this.scriptEngineMappings = scriptEngineMappings; + this.valueGetter = valueGetter; } public Capabilities getCapabilities() { @@ -40,4 +43,7 @@ public Map getScriptEngineMappings() { return scriptEngineMappings; } + public String getHeaderValue(String key) { + return valueGetter.apply(key); + } } diff --git a/src/test/java/org/apache/sling/scriptingbundle/plugin/bnd/BundledScriptsScannerPluginTest.java b/src/test/java/org/apache/sling/scriptingbundle/plugin/bnd/BundledScriptsScannerPluginTest.java index 12a2976..7170fdc 100644 --- a/src/test/java/org/apache/sling/scriptingbundle/plugin/bnd/BundledScriptsScannerPluginTest.java +++ b/src/test/java/org/apache/sling/scriptingbundle/plugin/bnd/BundledScriptsScannerPluginTest.java @@ -25,6 +25,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.function.Function; import java.util.jar.Manifest; import org.apache.commons.io.FileUtils; @@ -66,8 +67,9 @@ public PluginExecution executePluginOnProject(String projectName) throws Excepti try (Builder builder = prepareBuilder(projectName)) { BundledScriptsScannerPlugin plugin = builder.getPlugin(BundledScriptsScannerPlugin.class); assertNotNull(plugin); - builder.build(); - return new PluginExecution(plugin.getCapabilities(), plugin.getScriptEngineMappings()); + Jar jar = builder.build(); + Function headerGetter = jar.getManifest().getMainAttributes()::getValue; + return new PluginExecution(plugin.getCapabilities(), plugin.getScriptEngineMappings(), headerGetter); } } diff --git a/src/test/java/org/apache/sling/scriptingbundle/plugin/maven/MetadataMojoTest.java b/src/test/java/org/apache/sling/scriptingbundle/plugin/maven/MetadataMojoTest.java index 7b1327e..f6524e0 100644 --- a/src/test/java/org/apache/sling/scriptingbundle/plugin/maven/MetadataMojoTest.java +++ b/src/test/java/org/apache/sling/scriptingbundle/plugin/maven/MetadataMojoTest.java @@ -20,9 +20,7 @@ import java.io.File; import java.nio.file.Paths; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; +import java.util.function.Function; import org.apache.commons.io.FileUtils; import org.apache.maven.execution.MavenSession; @@ -68,7 +66,9 @@ private static class MojoProject { public PluginExecution executePluginOnProject(String projectName) throws Exception { MojoProject mojoProject = getMojoProject(projectName); mojoProject.mojo.execute(); - return new PluginExecution(mojoProject.mojo.getCapabilities(), mojoProject.mojo.getScriptEngineMappings()); + Function propertyGetter = key -> mojoProject.project.getProperties() + .getProperty("org.apache.sling.scriptingbundle.maven.plugin." + key); + return new PluginExecution(mojoProject.mojo.getCapabilities(), mojoProject.mojo.getScriptEngineMappings(), propertyGetter); } @Override diff --git a/src/test/resources/project-2/bnd.bnd b/src/test/resources/project-2/bnd.bnd index fe12e69..d242650 100644 --- a/src/test/resources/project-2/bnd.bnd +++ b/src/test/resources/project-2/bnd.bnd @@ -16,4 +16,5 @@ # under the License. -plugin: org.apache.sling.scriptingbundle.plugin.bnd.BundledScriptsScannerPlugin; \ scriptEngineMappings="html:thymeleaf,js:rhino"; \ - searchPaths=/bin + searchPaths=/bin; \ + serviceRanking=100 diff --git a/src/test/resources/project-2/pom.xml b/src/test/resources/project-2/pom.xml index d8aa4ca..10b0254 100644 --- a/src/test/resources/project-2/pom.xml +++ b/src/test/resources/project-2/pom.xml @@ -40,6 +40,7 @@ thymeleaf rhino + 100