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 2021/09/13 16:16:23 UTC
[sling-scriptingbundle-maven-plugin] 01/01: SLING-10808 - Generate
scripting capabilities from Jackrabbit FileVault content packages
This is an automated email from the ASF dual-hosted git repository.
radu pushed a commit to branch issue/SLING-10808
in repository https://gitbox.apache.org/repos/asf/sling-scriptingbundle-maven-plugin.git
commit 5d1eda4289445774fcfc46e072dd43b427d00aa2
Author: Radu Cotescu <ra...@apache.org>
AuthorDate: Mon Sep 13 18:15:41 2021 +0200
SLING-10808 - Generate scripting capabilities from Jackrabbit FileVault content packages
* started implementation; requires more thorough testing
---
pom.xml | 22 ++-
.../plugin/processor/Constants.java | 4 +
.../plugin/processor/FileProcessor.java | 167 ++++++++++++---------
.../processor/ResourceTypeFolderAnalyser.java | 2 +
.../processor/ResourceTypeFolderPredicate.java | 2 +
.../processor/filevault/VaultContentXmlReader.java | 106 +++++++++++++
.../scriptingbundle/plugin/AbstractPluginTest.java | 10 ++
.../filevault/VaultContentXmlReaderTest.java | 40 +++++
src/test/resources/filevault-1/bnd.bnd | 17 +++
src/test/resources/filevault-1/pom.xml | 49 ++++++
.../jcr_root/apps/my-scripts/image/.content.xml | 23 +++
.../jcr_root/apps/my-scripts/image/image.html | 18 +++
12 files changed, 391 insertions(+), 69 deletions(-)
diff --git a/pom.xml b/pom.xml
index 8ffdb54..3813525 100644
--- a/pom.xml
+++ b/pom.xml
@@ -54,7 +54,7 @@
</properties>
<prerequisites>
- <maven>${mavenVersion}</maven>
+ <maven>${maven.version}</maven>
</prerequisites>
<build>
@@ -217,7 +217,25 @@
<version>4.3.0</version>
<scope>compile</scope>
</dependency>
-
+ <!-- FileVault -->
+ <dependency>
+ <groupId>org.apache.jackrabbit.vault</groupId>
+ <artifactId>org.apache.jackrabbit.vault</artifactId>
+ <version>3.5.0</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.jcr</groupId>
+ <artifactId>jcr</artifactId>
+ <version>2.0</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.jackrabbit</groupId>
+ <artifactId>oak-jackrabbit-api</artifactId>
+ <version>1.40.0</version>
+ <scope>compile</scope>
+ </dependency>
<dependency>
<groupId>org.apache.maven.plugin-testing</groupId>
<artifactId>maven-plugin-testing-harness</artifactId>
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 c9da665..cf4f711 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,6 +53,10 @@ public final class Constants {
public static final String BND_SCRIPT_ENGINE_MAPPINGS = "scriptEngineMappings";
public static final String BND_SEARCH_PATHS = "searchPaths";
+ public static final String VAULT_CONTEXT_XML = ".content.xml";
+ public static final String SLING_RESOURCE_SUPER_TYPE = "sling:resourceSuperType";
+ public static final String SLING_REQUIRED_RESOURCE_TYPES = "sling:requiredResourceTypes";
+
public static final Map<String, String> DEFAULT_EXTENSION_TO_SCRIPT_ENGINE_MAPPING;
public static final Set<String> DEFAULT_SEARCH_PATHS;
public static final Set<String> DEFAULT_SOURCE_DIRECTORIES;
diff --git a/src/main/java/org/apache/sling/scriptingbundle/plugin/processor/FileProcessor.java b/src/main/java/org/apache/sling/scriptingbundle/plugin/processor/FileProcessor.java
index 2ddc24b..4b64467 100644
--- a/src/main/java/org/apache/sling/scriptingbundle/plugin/processor/FileProcessor.java
+++ b/src/main/java/org/apache/sling/scriptingbundle/plugin/processor/FileProcessor.java
@@ -19,6 +19,7 @@
package org.apache.sling.scriptingbundle.plugin.processor;
import java.io.IOException;
+import java.io.Reader;
import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
@@ -38,6 +39,7 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.resource.type.ResourceType;
import org.apache.sling.scriptingbundle.plugin.capability.ProvidedResourceTypeCapability;
import org.apache.sling.scriptingbundle.plugin.capability.RequiredResourceTypeCapability;
+import org.apache.sling.scriptingbundle.plugin.processor.filevault.VaultContentXmlReader;
import org.jetbrains.annotations.NotNull;
import org.osgi.framework.VersionRange;
@@ -61,88 +63,102 @@ public class FileProcessor {
this.scriptEngineMappings = scriptEngineMappings;
}
- public void processExtendsFile(@NotNull ResourceType resourceType, @NotNull Path extendsFile,
+ public void processExtendsFile(@NotNull ResourceType resourceType, @NotNull Path file,
@NotNull Set<ProvidedResourceTypeCapability> providedCapabilities,
@NotNull Set<RequiredResourceTypeCapability> requiredCapabilities) throws IllegalArgumentException {
try {
- List<String> extendResources = Files.readAllLines(extendsFile, StandardCharsets.UTF_8);
- if (extendResources.size() == 1) {
- String extend = extendResources.get(0);
- Parameters parameters = OSGiHeader.parseHeader(extend);
- if (parameters.size() < 1 || parameters.size() > 1) {
- throw new IllegalArgumentException(String.format("The file '%s' must contain one clause only (not multiple ones separated by ',')", extendsFile));
- }
- Entry<String, Attrs> extendsParameter = parameters.entrySet().iterator().next();
- for (String attributeName : extendsParameter.getValue().keySet()) {
- if (!EXTENDS_ALLOWED_ATTRIBUTE_NAMES.contains(attributeName)) {
- throw new IllegalArgumentException(String.format("Found unsupported attribute/directive '%s' in file '%s'. Only the following attributes or directives may be used in the extends file: %s", attributeName, extendsFile, String.join(",", EXTENDS_ALLOWED_ATTRIBUTE_NAMES)));
- }
- }
- String extendedResourceType = FilenameUtils.normalize(extendsParameter.getKey(), true);
- boolean isOptional = aQute.bnd.osgi.Constants.OPTIONAL.equals(extendsParameter.getValue().get(aQute.bnd.osgi.Constants.RESOLUTION_DIRECTIVE));
- Set<String> searchPathResourceTypes = processSearchPathResourceTypes(resourceType);
- Optional<ProvidedResourceTypeCapability> rootCapability = providedCapabilities.stream().filter(capability ->
- capability.getResourceTypes().equals(searchPathResourceTypes) && capability.getSelectors().isEmpty() &&
- StringUtils.isEmpty(capability.getRequestMethod()) && StringUtils.isEmpty(capability.getRequestExtension())
- ).findFirst();
- rootCapability.ifPresent(capability -> {
- providedCapabilities.remove(capability);
- ProvidedResourceTypeCapability replacement =
- ProvidedResourceTypeCapability.builder().fromCapability(capability)
- .withExtendsResourceType(extendedResourceType).build();
- providedCapabilities.add(replacement);
-
- });
- if (!rootCapability.isPresent()) {
- providedCapabilities.add(
- ProvidedResourceTypeCapability.builder()
- .withResourceTypes(processSearchPathResourceTypes(resourceType))
- .withVersion(resourceType.getVersion())
- .withExtendsResourceType(extendedResourceType)
- .build());
- }
- RequiredResourceTypeCapability.Builder requiredBuilder =
- RequiredResourceTypeCapability.builder().withResourceType(extendedResourceType);
- if (isOptional) {
- requiredBuilder.withIsOptional();
- }
- extractVersionRange(extendsFile, requiredBuilder, extendsParameter.getValue().getVersion());
- requiredCapabilities.add(requiredBuilder.build());
+ List<String> extendedResources = Files.readAllLines(file, StandardCharsets.UTF_8);
+ if (extendedResources.size() == 1) {
+ processExtendedResourceType(resourceType, file, providedCapabilities, requiredCapabilities, extendedResources.get(0));
} else {
- throw new IllegalArgumentException(String.format("The file '%s' must contain one line only (not multiple ones)", extendsFile));
+ throw new IllegalArgumentException(String.format("The file '%s' must contain one line only (not multiple ones)", file));
}
} catch (IOException e) {
- throw new UncheckedIOException(String.format("Unable to read file %s.", extendsFile.toString()), e);
+ throw new UncheckedIOException(String.format("Unable to read file %s.", file.toString()), e);
}
}
+ private void processExtendedResourceType(@NotNull ResourceType resourceType, @NotNull Path extendsFile,
+ @NotNull Set<ProvidedResourceTypeCapability> providedCapabilities,
+ @NotNull Set<RequiredResourceTypeCapability> requiredCapabilities, @NotNull String extendedResource) {
+ Parameters parameters = OSGiHeader.parseHeader(extendedResource);
+ if (parameters.size() != 1) {
+ throw new IllegalArgumentException(String.format("The file '%s' must contain one clause only (not multiple ones separated by ',')",
+ extendsFile));
+ }
+ Entry<String, Attrs> extendsParameter = parameters.entrySet().iterator().next();
+ for (String attributeName : extendsParameter.getValue().keySet()) {
+ if (!EXTENDS_ALLOWED_ATTRIBUTE_NAMES.contains(attributeName)) {
+ throw new IllegalArgumentException(String.format("Found unsupported attribute/directive '%s' in file '%s'. Only the following attributes or directives may be used in the extends file: %s", attributeName,
+ extendsFile, String.join(",", EXTENDS_ALLOWED_ATTRIBUTE_NAMES)));
+ }
+ }
+ String extendedResourceType = FilenameUtils.normalize(extendsParameter.getKey(), true);
+ boolean isOptional = aQute.bnd.osgi.Constants.OPTIONAL.equals(extendsParameter.getValue().get(aQute.bnd.osgi.Constants.RESOLUTION_DIRECTIVE));
+ Set<String> searchPathResourceTypes = processSearchPathResourceTypes(resourceType);
+ Optional<ProvidedResourceTypeCapability> rootCapability = providedCapabilities.stream().filter(capability ->
+ capability.getResourceTypes().equals(searchPathResourceTypes) && capability.getSelectors().isEmpty() &&
+ StringUtils.isEmpty(capability.getRequestMethod()) && StringUtils.isEmpty(capability.getRequestExtension())
+ ).findFirst();
+ rootCapability.ifPresent(capability -> {
+ providedCapabilities.remove(capability);
+ ProvidedResourceTypeCapability replacement =
+ ProvidedResourceTypeCapability.builder().fromCapability(capability)
+ .withExtendsResourceType(extendedResourceType).build();
+ providedCapabilities.add(replacement);
+
+ });
+ if (!rootCapability.isPresent()) {
+ providedCapabilities.add(
+ ProvidedResourceTypeCapability.builder()
+ .withResourceTypes(processSearchPathResourceTypes(resourceType))
+ .withVersion(resourceType.getVersion())
+ .withExtendsResourceType(extendedResourceType)
+ .build());
+ }
+ RequiredResourceTypeCapability.Builder requiredBuilder =
+ RequiredResourceTypeCapability.builder().withResourceType(extendedResourceType);
+ if (isOptional) {
+ requiredBuilder.withIsOptional();
+ }
+ extractVersionRange(extendsFile, requiredBuilder, extendsParameter.getValue().getVersion());
+ requiredCapabilities.add(requiredBuilder.build());
+ }
+
void processRequiresFile(@NotNull Path requiresFile,
@NotNull Set<RequiredResourceTypeCapability> requiredCapabilities) {
try {
List<String> requiredResourceTypes = Files.readAllLines(requiresFile, StandardCharsets.UTF_8);
- for (String requiredResourceType : requiredResourceTypes) {
- Parameters parameters = OSGiHeader.parseHeader(requiredResourceType);
- if (parameters.size() < 1 || parameters.size() > 1) {
- throw new IllegalArgumentException(String.format("Each line in file '%s' must contain one clause only (not multiple ones separated by ',')", requiresFile));
- }
- Entry<String, Attrs> requiresParameter = parameters.entrySet().iterator().next();
- for (String attributeName : requiresParameter.getValue().keySet()) {
- if (!REQUIRES_ALLOWED_ATTRIBUTE_NAMES.contains(attributeName)) {
- throw new IllegalArgumentException(String.format("Found unsupported attribute/directive '%s' in file '%s'. Only the following attributes or directives may be used in the requires file: %s", attributeName, requiresFile, String.join(",", REQUIRES_ALLOWED_ATTRIBUTE_NAMES)));
- }
- }
- String resourceType = FilenameUtils.normalize(requiresParameter.getKey(), true);
- boolean isOptional = aQute.bnd.osgi.Constants.OPTIONAL.equals(requiresParameter.getValue().get(aQute.bnd.osgi.Constants.RESOLUTION_DIRECTIVE));
- RequiredResourceTypeCapability.Builder requiredBuilder =
- RequiredResourceTypeCapability.builder().withResourceType(resourceType);
- if (isOptional) {
- requiredBuilder.withIsOptional();
+ processRequiredResourceTypes(requiresFile, requiredCapabilities, requiredResourceTypes);
+ } catch (IOException e) {
+ throw new UncheckedIOException(String.format("Unable to read file %s.", requiresFile), e);
+ }
+ }
+
+ private void processRequiredResourceTypes(@NotNull Path requiresFile, @NotNull Set<RequiredResourceTypeCapability> requiredCapabilities,
+ List<String> requiredResourceTypes) {
+ for (String requiredResourceType : requiredResourceTypes) {
+ Parameters parameters = OSGiHeader.parseHeader(requiredResourceType);
+ if (parameters.size() != 1) {
+ throw new IllegalArgumentException(String.format("Each line in file '%s' must contain one clause only (not multiple ones separated by ',')",
+ requiresFile));
+ }
+ Entry<String, Attrs> requiresParameter = parameters.entrySet().iterator().next();
+ for (String attributeName : requiresParameter.getValue().keySet()) {
+ if (!REQUIRES_ALLOWED_ATTRIBUTE_NAMES.contains(attributeName)) {
+ throw new IllegalArgumentException(String.format("Found unsupported attribute/directive '%s' in file '%s'. Only the following attributes or directives may be used in the requires file: %s", attributeName,
+ requiresFile, String.join(",", REQUIRES_ALLOWED_ATTRIBUTE_NAMES)));
}
- extractVersionRange(requiresFile, requiredBuilder, requiresParameter.getValue().getVersion());
- requiredCapabilities.add(requiredBuilder.build());
}
- } catch (IOException e) {
- throw new UncheckedIOException(String.format("Unable to read file %s.", requiresFile.toString()), e);
+ String resourceType = FilenameUtils.normalize(requiresParameter.getKey(), true);
+ boolean isOptional = aQute.bnd.osgi.Constants.OPTIONAL.equals(requiresParameter.getValue().get(aQute.bnd.osgi.Constants.RESOLUTION_DIRECTIVE));
+ RequiredResourceTypeCapability.Builder requiredBuilder =
+ RequiredResourceTypeCapability.builder().withResourceType(resourceType);
+ if (isOptional) {
+ requiredBuilder.withIsOptional();
+ }
+ extractVersionRange(requiresFile, requiredBuilder, requiresParameter.getValue().getVersion());
+ requiredCapabilities.add(requiredBuilder.build());
}
}
@@ -236,4 +252,21 @@ public class FileProcessor {
log.warn(String.format("Invalid version range format %s in file %s.", version, requiresFile));
}
}
+
+ public void processVaultFile(@NotNull Path entry, @NotNull ResourceType resourceType,
+ @NotNull Set<ProvidedResourceTypeCapability> providedCapabilities,
+ @NotNull Set<RequiredResourceTypeCapability> requiredCapabilities) {
+ try {
+ VaultContentXmlReader reader = new VaultContentXmlReader(entry);
+ if (reader.getSlingResourceSuperType().isPresent()) {
+ processExtendedResourceType(resourceType, entry, providedCapabilities, requiredCapabilities,
+ reader.getSlingResourceSuperType().get());
+ }
+ if (!reader.getSlingRequiredResourceTypes().isEmpty()) {
+ processRequiredResourceTypes(entry, requiredCapabilities, new ArrayList<>(reader.getSlingRequiredResourceTypes()));
+ }
+ } catch (IOException e) {
+ throw new UncheckedIOException(String.format("Unable to read file %s.", entry), e);
+ }
+ }
}
diff --git a/src/main/java/org/apache/sling/scriptingbundle/plugin/processor/ResourceTypeFolderAnalyser.java b/src/main/java/org/apache/sling/scriptingbundle/plugin/processor/ResourceTypeFolderAnalyser.java
index b7b6820..77f8ee8 100644
--- a/src/main/java/org/apache/sling/scriptingbundle/plugin/processor/ResourceTypeFolderAnalyser.java
+++ b/src/main/java/org/apache/sling/scriptingbundle/plugin/processor/ResourceTypeFolderAnalyser.java
@@ -66,6 +66,8 @@ public class ResourceTypeFolderAnalyser {
fileProcessor.processExtendsFile(resourceType, entry, providedCapabilities, requiredCapabilities);
} else if (Constants.REQUIRES_FILE.equals(file.toString())) {
fileProcessor.processRequiresFile(entry, requiredCapabilities);
+ } else if (Constants.VAULT_CONTEXT_XML.equals(file.toString())) {
+ fileProcessor.processVaultFile(entry, resourceType, providedCapabilities, requiredCapabilities);
} else {
fileProcessor.processScriptFile(resourceTypeDirectory, entry, resourceType, providedCapabilities);
}
diff --git a/src/main/java/org/apache/sling/scriptingbundle/plugin/processor/ResourceTypeFolderPredicate.java b/src/main/java/org/apache/sling/scriptingbundle/plugin/processor/ResourceTypeFolderPredicate.java
index 684c685..69ca1a2 100644
--- a/src/main/java/org/apache/sling/scriptingbundle/plugin/processor/ResourceTypeFolderPredicate.java
+++ b/src/main/java/org/apache/sling/scriptingbundle/plugin/processor/ResourceTypeFolderPredicate.java
@@ -24,6 +24,7 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.util.function.Predicate;
+import org.apache.sling.scriptingbundle.plugin.processor.filevault.VaultContentXmlReader;
import org.osgi.framework.Version;
public class ResourceTypeFolderPredicate implements Predicate<Path> {
@@ -69,6 +70,7 @@ public class ResourceTypeFolderPredicate implements Predicate<Path> {
Script script = Script.parseScript(childName);
if (
Constants.EXTENDS_FILE.equals(childName) ||
+ Constants.VAULT_CONTEXT_XML.equals(childName) && new VaultContentXmlReader(path).getSlingResourceSuperType().isPresent() ||
(
script != null &&
(
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
new file mode 100644
index 0000000..95a627a
--- /dev/null
+++ b/src/main/java/org/apache/sling/scriptingbundle/plugin/processor/filevault/VaultContentXmlReader.java
@@ -0,0 +1,106 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ 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.plugin.processor.filevault;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Optional;
+import java.util.Set;
+
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.jackrabbit.vault.util.DocViewProperty;
+import org.apache.sling.scriptingbundle.plugin.processor.Constants;
+import org.jetbrains.annotations.NotNull;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+public class VaultContentXmlReader {
+
+ private static final DocumentBuilderFactory documentBuilderFactory;
+
+ static {
+ try {
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
+ dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
+ dbf.setAttribute(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
+ dbf.setExpandEntityReferences(false);
+ documentBuilderFactory = dbf;
+ } catch (IllegalArgumentException e) {
+ throw new IllegalStateException("Cannot disable DTD features.", e);
+ }
+ }
+
+ private final Path path;
+ private final String resourceSuperType;
+ private final Set<String> requiredResourceTypes;
+
+ public VaultContentXmlReader(@NotNull Path path) throws IOException {
+ this.path = path;
+ this.requiredResourceTypes = new HashSet<>();
+ try (BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
+ DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
+ Document document = documentBuilder.parse(new InputSource(reader));
+ Element documentElement = document.getDocumentElement();
+ if ("jcr:root".equals(documentElement.getTagName())) {
+ this.resourceSuperType = document.getDocumentElement().getAttribute(Constants.SLING_RESOURCE_SUPER_TYPE);
+ String requiredResourceTypesValue = document.getDocumentElement().getAttribute(Constants.SLING_REQUIRED_RESOURCE_TYPES);
+ if (requiredResourceTypesValue != null) {
+ DocViewProperty requiredResourceTypesDocView = DocViewProperty.parse(Constants.SLING_REQUIRED_RESOURCE_TYPES,
+ requiredResourceTypesValue);
+ requiredResourceTypes.addAll(Arrays.asList(requiredResourceTypesDocView.values));
+ }
+ } else {
+ throw new IllegalArgumentException(String.format("Path %s does not seem to be a valid Vault .content.xml file.", path));
+ }
+ } catch (ParserConfigurationException | SAXException e) {
+ throw new IOException(e);
+ }
+
+
+ }
+
+ public Path getPath() {
+ return path;
+ }
+
+ @NotNull
+ public Optional<String> getSlingResourceSuperType() {
+ return Optional.ofNullable(resourceSuperType);
+ }
+
+ @NotNull
+ public Set<String> getSlingRequiredResourceTypes() {
+ return Collections.unmodifiableSet(requiredResourceTypes);
+ }
+
+
+}
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 fa35391..f84aef8 100644
--- a/src/test/java/org/apache/sling/scriptingbundle/plugin/AbstractPluginTest.java
+++ b/src/test/java/org/apache/sling/scriptingbundle/plugin/AbstractPluginTest.java
@@ -204,6 +204,16 @@ public abstract class AbstractPluginTest {
}
}
+ @Test
+ public void testFileVault1() throws Exception {
+ try {
+ PluginExecution execution = executePluginOnProject("filevault-1");
+ Capabilities capabilities = execution.getCapabilities();
+ } finally {
+ cleanUp("filevault-1");
+ }
+ }
+
private void verifyCapabilities(Capabilities capabilities, Set<ProvidedResourceTypeCapability> pExpected, Set<RequiredResourceTypeCapability> rExpected, Set<ProvidedScriptCapability> sExpected, Set<RequiredResourceTypeCapability> urExpected) {
Set<ProvidedResourceTypeCapability> provided = new HashSet<>(capabilities.getProvidedResourceTypeCapabilities());
StringBuilder missingProvided = new StringBuilder();
diff --git a/src/test/java/org/apache/sling/scriptingbundle/plugin/processor/filevault/VaultContentXmlReaderTest.java b/src/test/java/org/apache/sling/scriptingbundle/plugin/processor/filevault/VaultContentXmlReaderTest.java
new file mode 100644
index 0000000..477f56a
--- /dev/null
+++ b/src/test/java/org/apache/sling/scriptingbundle/plugin/processor/filevault/VaultContentXmlReaderTest.java
@@ -0,0 +1,40 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ 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.plugin.processor.filevault;
+
+import java.io.IOException;
+import java.nio.file.Paths;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class VaultContentXmlReaderTest {
+
+ @Test
+ public void testReader() throws IOException {
+ VaultContentXmlReader vaultContentXmlReader = new VaultContentXmlReader(Paths.get("src/test/resources/filevault-1/src/main" +
+ "/content/jcr_root/apps/my-scripts/image/.content.xml"));
+ assertNotNull(vaultContentXmlReader);
+ assertEquals("generic/image", vaultContentXmlReader.getSlingResourceSuperType().get());
+
+ }
+
+}
diff --git a/src/test/resources/filevault-1/bnd.bnd b/src/test/resources/filevault-1/bnd.bnd
new file mode 100644
index 0000000..fea7d0f
--- /dev/null
+++ b/src/test/resources/filevault-1/bnd.bnd
@@ -0,0 +1,17 @@
+# 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.
+-plugin: org.apache.sling.scriptingbundle.plugin.bnd.BundledScriptsScannerPlugin
diff --git a/src/test/resources/filevault-1/pom.xml b/src/test/resources/filevault-1/pom.xml
new file mode 100644
index 0000000..c9f6949
--- /dev/null
+++ b/src/test/resources/filevault-1/pom.xml
@@ -0,0 +1,49 @@
+<?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-filevault-1</artifactId>
+ <version>0.0.1</version>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>scriptingbundle-maven-plugin</artifactId>
+ <configuration>
+ <sourceDirectories>src/main/content/jcr_root</sourceDirectories>
+ </configuration>
+ <executions>
+ <execution>
+ <phase>prepare-package</phase>
+ <goals>
+ <goal>metadata</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/src/test/resources/filevault-1/src/main/content/jcr_root/apps/my-scripts/image/.content.xml b/src/test/resources/filevault-1/src/main/content/jcr_root/apps/my-scripts/image/.content.xml
new file mode 100644
index 0000000..e5fedc0
--- /dev/null
+++ b/src/test/resources/filevault-1/src/main/content/jcr_root/apps/my-scripts/image/.content.xml
@@ -0,0 +1,23 @@
+<?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.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
+ sling:resourceSuperType="generic/image"
+ sling:requiredResourceTypes="[required/one,required/two]"
+ />
diff --git a/src/test/resources/filevault-1/src/main/content/jcr_root/apps/my-scripts/image/image.html b/src/test/resources/filevault-1/src/main/content/jcr_root/apps/my-scripts/image/image.html
new file mode 100644
index 0000000..2853663
--- /dev/null
+++ b/src/test/resources/filevault-1/src/main/content/jcr_root/apps/my-scripts/image/image.html
@@ -0,0 +1,18 @@
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ 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.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->