SLING-7011 fsresource: Detect FileVault <any>.xml JCR XML files
git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1801932 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/sling/fsprovider/internal/FsResourceProvider.java b/src/main/java/org/apache/sling/fsprovider/internal/FsResourceProvider.java
index acc856f..62446d5 100644
--- a/src/main/java/org/apache/sling/fsprovider/internal/FsResourceProvider.java
+++ b/src/main/java/org/apache/sling/fsprovider/internal/FsResourceProvider.java
@@ -314,6 +314,7 @@
List<String> contentFileSuffixes = new ArrayList<>();
if (fsMode == FsMode.FILEVAULT_XML) {
contentFileSuffixes.add("/" + DOT_CONTENT_XML);
+ contentFileSuffixes.add(ContentFileTypes.XML_SUFFIX);
if (StringUtils.isNotBlank(config.provider_filevault_filterxml_path())) {
filterXmlFile = new File(config.provider_filevault_filterxml_path());
}
diff --git a/src/main/java/org/apache/sling/fsprovider/internal/mapper/ContentFile.java b/src/main/java/org/apache/sling/fsprovider/internal/mapper/ContentFile.java
index 184d184..853fe82 100644
--- a/src/main/java/org/apache/sling/fsprovider/internal/mapper/ContentFile.java
+++ b/src/main/java/org/apache/sling/fsprovider/internal/mapper/ContentFile.java
@@ -26,6 +26,7 @@
import org.apache.sling.fsprovider.internal.mapper.valuemap.ValueMapUtil;
import org.apache.sling.fsprovider.internal.parser.ContentElement;
import org.apache.sling.fsprovider.internal.parser.ContentFileCache;
+import org.apache.sling.jcr.contentparser.ContentType;
/**
* Reference to a file that contains a content fragment (e.g. JSON, JCR XML).
@@ -36,6 +37,7 @@
private final String path;
private final String subPath;
private final ContentFileCache contentFileCache;
+ private final ContentType contentType;
private boolean contentInitialized;
private ContentElement content;
private ValueMap valueMap;
@@ -47,10 +49,22 @@
* @param contentFileCache Content file cache
*/
public ContentFile(File file, String path, String subPath, ContentFileCache contentFileCache) {
+ this(file, path, subPath, contentFileCache, null);
+ }
+
+ /**
+ * @param file File with content fragment
+ * @param path Root path of the content file
+ * @param subPath Relative path addressing content fragment inside file
+ * @param contentFileCache Content file cache
+ * @param contentType Content type
+ */
+ public ContentFile(File file, String path, String subPath, ContentFileCache contentFileCache, ContentType contentType) {
this.file = file;
this.path = path;
this.subPath = subPath;
this.contentFileCache = contentFileCache;
+ this.contentType = contentType;
}
/**
@@ -80,7 +94,7 @@
*/
public ContentElement getContent() {
if (!contentInitialized) {
- ContentElement rootContent = contentFileCache.get(path, file);
+ ContentElement rootContent = contentFileCache.get(path, file, contentType);
if (subPath == null) {
content = rootContent;
}
diff --git a/src/main/java/org/apache/sling/fsprovider/internal/mapper/FileVaultResourceMapper.java b/src/main/java/org/apache/sling/fsprovider/internal/mapper/FileVaultResourceMapper.java
index 14f6146..77c5554 100644
--- a/src/main/java/org/apache/sling/fsprovider/internal/mapper/FileVaultResourceMapper.java
+++ b/src/main/java/org/apache/sling/fsprovider/internal/mapper/FileVaultResourceMapper.java
@@ -19,6 +19,7 @@
package org.apache.sling.fsprovider.internal.mapper;
import static org.apache.jackrabbit.vault.util.Constants.DOT_CONTENT_XML;
+import static org.apache.sling.fsprovider.internal.parser.ContentFileTypes.XML_SUFFIX;
import java.io.File;
import java.io.IOException;
@@ -40,13 +41,15 @@
import org.apache.sling.fsprovider.internal.FsResourceMapper;
import org.apache.sling.fsprovider.internal.parser.ContentElement;
import org.apache.sling.fsprovider.internal.parser.ContentFileCache;
+import org.apache.sling.jcr.contentparser.ContentType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class FileVaultResourceMapper implements FsResourceMapper {
private static final String DOT_CONTENT_XML_SUFFIX = "/" + DOT_CONTENT_XML;
- private static final String DOT_DIR_SUFFIX = "/.dir";
+ private static final String DOT_DIR = ".dir";
+ private static final String DOT_DIR_SUFFIX = "/" + DOT_DIR;
private final File providerFile;
private final File filterXmlFile;
@@ -173,6 +176,9 @@
}
File file = new File(providerFile, "." + PlatformNameFormat.getPlatformPath(path));
if (file.exists()) {
+ if (StringUtils.endsWith(path, XML_SUFFIX) && !hasDotDirFile(file)) {
+ return null;
+ }
return file;
}
return null;
@@ -181,7 +187,15 @@
private ContentFile getContentFile(String path, String subPath) {
File file = new File(providerFile, "." + PlatformNameFormat.getPlatformPath(path) + DOT_CONTENT_XML_SUFFIX);
if (file.exists()) {
- ContentFile contentFile = new ContentFile(file, path, subPath, contentFileCache);
+ ContentFile contentFile = new ContentFile(file, path, subPath, contentFileCache, ContentType.JCR_XML);
+ if (contentFile.hasContent()) {
+ return contentFile;
+ }
+ }
+
+ file = new File(providerFile, "." + PlatformNameFormat.getPlatformPath(path) + XML_SUFFIX);
+ if (file.exists() && !hasDotDirFile(file)) {
+ ContentFile contentFile = new ContentFile(file, path, subPath, contentFileCache, ContentType.JCR_XML);
if (contentFile.hasContent()) {
return contentFile;
}
@@ -196,5 +210,13 @@
+ (subPath != null ? "/" + subPath : "");
return getContentFile(parentPath, nextSubPath);
}
+
+ private boolean hasDotDirFile(File file) {
+ File dotDir = new File(file.getPath() + DOT_DIR);
+ if (dotDir.exists() && dotDir.isDirectory()) {
+ return true;
+ }
+ return false;
+ }
}
diff --git a/src/main/java/org/apache/sling/fsprovider/internal/parser/ContentFileCache.java b/src/main/java/org/apache/sling/fsprovider/internal/parser/ContentFileCache.java
index 4222e98..e18a0ff 100644
--- a/src/main/java/org/apache/sling/fsprovider/internal/parser/ContentFileCache.java
+++ b/src/main/java/org/apache/sling/fsprovider/internal/parser/ContentFileCache.java
@@ -23,6 +23,7 @@
import java.util.Map;
import org.apache.commons.collections.map.LRUMap;
+import org.apache.sling.jcr.contentparser.ContentType;
/**
* Cache for parsed content from content files (e.g. JSON, JCR XML).
@@ -52,12 +53,28 @@
* @return Content or null
*/
public ContentElement get(String path, File file) {
+ return get(path, file, null);
+ }
+
+ /**
+ * Get content.
+ * @param path Path (used as cache key).
+ * @param file File
+ * @param contentType Content type - if null type is auto-detected
+ * @return Content or null
+ */
+ public ContentElement get(String path, File file, ContentType contentType) {
ContentElement content = null;
if (contentCache != null) {
content = contentCache.get(path);
}
if (content == null) {
- content = ContentFileParserUtil.parse(file);
+ if (contentType != null) {
+ content = ContentFileParserUtil.parse(file, contentType);
+ }
+ else {
+ content = ContentFileParserUtil.parse(file);
+ }
if (content == null) {
content = NULL_ELEMENT;
}
diff --git a/src/main/java/org/apache/sling/fsprovider/internal/parser/ContentFileParserUtil.java b/src/main/java/org/apache/sling/fsprovider/internal/parser/ContentFileParserUtil.java
index a105dad..e0d0e0c 100644
--- a/src/main/java/org/apache/sling/fsprovider/internal/parser/ContentFileParserUtil.java
+++ b/src/main/java/org/apache/sling/fsprovider/internal/parser/ContentFileParserUtil.java
@@ -75,15 +75,38 @@
if (!file.exists()) {
return null;
}
+ if (StringUtils.endsWith(file.getName(), JSON_SUFFIX)) {
+ return parse(file, ContentType.JSON);
+ }
+ else if (StringUtils.equals(file.getName(), DOT_CONTENT_XML) || StringUtils.endsWith(file.getName(), JCR_XML_SUFFIX)) {
+ return parse(file, ContentType.JCR_XML);
+ }
+ else if (StringUtils.endsWith(file.getName(), XML_SUFFIX) && !StringUtils.endsWith(file.getName(), JCR_XML_SUFFIX)) {
+ return parse(file, ContentType.XML);
+ }
+ return null;
+ }
+
+ /**
+ * Parse content from file.
+ * @param file File. Type is detected automatically.
+ * @param contentType Content type
+ * @return Content or null if content could not be parsed.
+ */
+ public static ContentElement parse(File file, ContentType contentType) {
+ if (!file.exists()) {
+ return null;
+ }
try {
- if (StringUtils.endsWith(file.getName(), JSON_SUFFIX)) {
+ switch (contentType) {
+ case JSON:
return parse(JSON_PARSER, file);
- }
- else if (StringUtils.equals(file.getName(), DOT_CONTENT_XML) || StringUtils.endsWith(file.getName(), JCR_XML_SUFFIX)) {
- return parse(JCR_XML_PARSER, file);
- }
- else if (StringUtils.endsWith(file.getName(), XML_SUFFIX) && !StringUtils.endsWith(file.getName(), JCR_XML_SUFFIX)) {
+ case XML:
return parse(XML_PARSER, file);
+ case JCR_XML:
+ return parse(JCR_XML_PARSER, file);
+ default:
+ throw new IllegalArgumentException("Unexpected content type: " + contentType);
}
}
catch (Throwable ex) {
diff --git a/src/test/java/org/apache/sling/fsprovider/internal/FileVaultContentTest.java b/src/test/java/org/apache/sling/fsprovider/internal/FileVaultContentTest.java
index b2f1514..35b51d1 100644
--- a/src/test/java/org/apache/sling/fsprovider/internal/FileVaultContentTest.java
+++ b/src/test/java/org/apache/sling/fsprovider/internal/FileVaultContentTest.java
@@ -107,7 +107,7 @@
public void testListChildren() {
Resource en = sampleContent.getChild("en");
List<Resource> children = ImmutableList.copyOf(en.listChildren());
- assertEquals(2, children.size());
+ assertEquals(3, children.size());
Resource child1 = children.get(0);
assertEquals("jcr:content", child1.getName());
@@ -117,7 +117,10 @@
assertEquals("tools", child2.getName());
assertEquals("app:Page", child2.getResourceType());
- // child3 (conference) is hidden because of filter
+ Resource child3 = children.get(2);
+ assertEquals("extra", child3.getName());
+
+ // another child (conference) is hidden because of filter
}
@Test
@@ -143,7 +146,22 @@
// list children with mixed content
Resource enResource = sampleContent.getChild("en");
- assertThat(enResource, ResourceMatchers.containsChildren("jcr:content", "tools", "conference"));
+ assertThat(enResource, ResourceMatchers.containsChildren("jcr:content", "tools", "extra", "conference"));
}
+ @Test
+ public void testExtraContent() throws RepositoryException {
+ Resource extraContent = sampleContent.getChild("en/extra/extracontent");
+ assertNotNull(extraContent);
+ assertEquals("apps/app1/components/comp1", extraContent.getResourceType());
+
+ Resource layout = extraContent.getChild("layout");
+ assertNotNull(layout);
+ assertEquals("apps/app1/components/comp2", layout.getResourceType());
+
+ Resource binaryFile = sampleContent.getChild("en/extra/binaryfile.xml");
+ assertNotNull(binaryFile);
+ assertEquals("nt:file", binaryFile.getResourceType());
+ }
+
}
diff --git a/src/test/resources/vaultfs-test/jcr_root/content/samples/en/.content.xml b/src/test/resources/vaultfs-test/jcr_root/content/samples/en/.content.xml
index 83b8626..c394cf9 100644
--- a/src/test/resources/vaultfs-test/jcr_root/content/samples/en/.content.xml
+++ b/src/test/resources/vaultfs-test/jcr_root/content/samples/en/.content.xml
@@ -188,4 +188,8 @@
</jcr:content>
<tools />
<conference />
+ <extra jcr:primaryType="nt:unstructured">
+ <extracontent/>
+ <binaryfile.xml/>
+ </extra>
</jcr:root>
diff --git a/src/test/resources/vaultfs-test/jcr_root/content/samples/en/extra/binaryfile.xml b/src/test/resources/vaultfs-test/jcr_root/content/samples/en/extra/binaryfile.xml
new file mode 100644
index 0000000..63b5974
--- /dev/null
+++ b/src/test/resources/vaultfs-test/jcr_root/content/samples/en/extra/binaryfile.xml
@@ -0,0 +1,28 @@
+<?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"
+ jcr:primaryType="nt:unstructured"
+ sling:resourceType="apps/app1/components/comp1">
+ <layout
+ jcr:primaryType="nt:unstructured"
+ sling:resourceType="apps/app1/components/comp2"/>
+ <field jcr:primaryType="nt:unstructured"/>
+ <action jcr:primaryType="nt:unstructured"/>
+</jcr:root>
diff --git a/src/test/resources/vaultfs-test/jcr_root/content/samples/en/extra/binaryfile.xml.dir/.content.xml b/src/test/resources/vaultfs-test/jcr_root/content/samples/en/extra/binaryfile.xml.dir/.content.xml
new file mode 100644
index 0000000..c0ce9be
--- /dev/null
+++ b/src/test/resources/vaultfs-test/jcr_root/content/samples/en/extra/binaryfile.xml.dir/.content.xml
@@ -0,0 +1,25 @@
+<?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:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
+ jcr:primaryType="nt:file">
+ <jcr:content
+ jcr:mimeType="application/xml"
+ jcr:primaryType="nt:resource" />
+</jcr:root>
diff --git a/src/test/resources/vaultfs-test/jcr_root/content/samples/en/extra/extracontent.xml b/src/test/resources/vaultfs-test/jcr_root/content/samples/en/extra/extracontent.xml
new file mode 100644
index 0000000..63b5974
--- /dev/null
+++ b/src/test/resources/vaultfs-test/jcr_root/content/samples/en/extra/extracontent.xml
@@ -0,0 +1,28 @@
+<?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"
+ jcr:primaryType="nt:unstructured"
+ sling:resourceType="apps/app1/components/comp1">
+ <layout
+ jcr:primaryType="nt:unstructured"
+ sling:resourceType="apps/app1/components/comp2"/>
+ <field jcr:primaryType="nt:unstructured"/>
+ <action jcr:primaryType="nt:unstructured"/>
+</jcr:root>