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 <[email protected]>
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.
+  
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->

Reply via email to