You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2017/08/25 15:21:20 UTC
svn commit: r1806184 - in /sling/trunk/bundles/extensions/bundleresource: ./
src/main/java/org/apache/sling/bundleresource/impl/
Author: cziegeler
Date: Fri Aug 25 15:21:20 2017
New Revision: 1806184
URL: http://svn.apache.org/viewvc?rev=1806184&view=rev
Log:
SLING-6878 : Bundle resource provider: support mounting of JSON files
Modified:
sling/trunk/bundles/extensions/bundleresource/README.txt
sling/trunk/bundles/extensions/bundleresource/pom.xml
sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/Activator.java
sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResource.java
sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceCache.java
sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceIterator.java
sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceProvider.java
sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/MappedPath.java
Modified: sling/trunk/bundles/extensions/bundleresource/README.txt
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/bundleresource/README.txt?rev=1806184&r1=1806183&r2=1806184&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/bundleresource/README.txt (original)
+++ sling/trunk/bundles/extensions/bundleresource/README.txt Fri Aug 25 15:21:20 2017
@@ -6,16 +6,16 @@ based resources.
Getting Started
===============
-This component uses a Maven 2 (http://maven.apache.org/) build
-environment. It requires a Java 5 JDK (or higher) and Maven (http://maven.apache.org/)
-2.0.7 or later. We recommend to use the latest Maven version.
+This component uses a Maven 3 (http://maven.apache.org/) build
+environment. It requires a Java 7 JDK (or higher) and Maven (http://maven.apache.org/)
+3.5.0 or later. We recommend to use the latest Maven version.
-If you have Maven 2 installed, you can compile and
+If you have Maven 3 installed, you can compile and
package the jar using the following command:
mvn package
-See the Maven 2 documentation for other build features.
+See the Maven 3 documentation for other build features.
The latest source code for this component is available in the
Subversion (http://subversion.tigris.org/) source repository of
Modified: sling/trunk/bundles/extensions/bundleresource/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/bundleresource/pom.xml?rev=1806184&r1=1806183&r2=1806184&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/bundleresource/pom.xml (original)
+++ sling/trunk/bundles/extensions/bundleresource/pom.xml Fri Aug 25 15:21:20 2017
@@ -78,6 +78,10 @@
</build>
<dependencies>
<dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
@@ -88,6 +92,12 @@
<scope>provided</scope>
</dependency>
<dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-json_1.0_spec</artifactId>
+ <version>1.0-alpha-1</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.commons.osgi</artifactId>
<version>2.0.6</version>
@@ -97,6 +107,7 @@
<groupId>org.osgi</groupId>
<artifactId>osgi.core</artifactId>
</dependency>
+ <!-- This is only used for some constants, no runtime dependency -->
<dependency>
<groupId>org.apache.jackrabbit</groupId>
<artifactId>jackrabbit-jcr-commons</artifactId>
@@ -105,11 +116,23 @@
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
+ <artifactId>slf4j-simple</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <version>1.10.19</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.johnzon</groupId>
+ <artifactId>johnzon-core</artifactId>
+ <version>1.0.0</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
Modified: sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/Activator.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/Activator.java?rev=1806184&r1=1806183&r2=1806184&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/Activator.java (original)
+++ sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/Activator.java Fri Aug 25 15:21:20 2017
@@ -120,7 +120,7 @@ public class Activator implements Bundle
new Object[] { prefixes, bundle.getSymbolicName(), bundle.getVersion(),
bundle.getBundleId() });
- final MappedPath[] roots = BundleResourceProvider.getRoots(bundle, prefixes);
+ final MappedPath[] roots = MappedPath.getRoots(prefixes);
providers = new BundleResourceProvider[roots.length];
int index = 0;
Modified: sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResource.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResource.java?rev=1806184&r1=1806183&r2=1806184&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResource.java (original)
+++ sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResource.java Fri Aug 25 15:21:20 2017
@@ -21,14 +21,27 @@ import static org.apache.jackrabbit.JcrC
import java.io.IOException;
import java.io.InputStream;
+import java.io.StringWriter;
import java.net.MalformedURLException;
import java.net.URL;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.Iterator;
+import java.util.Map;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonNumber;
+import javax.json.JsonObject;
+import javax.json.JsonString;
+import javax.json.JsonValue;
import org.apache.sling.api.resource.AbstractResource;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceMetadata;
import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.api.wrappers.ValueMapDecorator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -40,103 +53,124 @@ public class BundleResource extends Abst
private final ResourceResolver resourceResolver;
- private final BundleResourceCache bundle;
+ private final BundleResourceCache cache;
private final MappedPath mappedPath;
private final String path;
- private URL url;
-
- private final String resourceType;
+ private URL resourceUrl;
private final ResourceMetadata metadata;
- public static BundleResource getResource(ResourceResolver resourceResolver,
- BundleResourceCache bundle, MappedPath mappedPath,
- String resourcePath) {
-
- String entryPath = mappedPath.getEntryPath(resourcePath);
-
- // first try, whether the bundle has an entry with a trailing slash
- // which would be a folder. In this case we check whether the
- // repository contains an item with the same path. If so, we
- // don't create a BundleResource but instead return null to be
- // able to return an item-based resource
- URL entry = bundle.getEntry(entryPath.concat("/"));
- if (entry != null) {
-
- // append the slash to path for next steps
- resourcePath = resourcePath.concat("/");
- }
-
- // if there is no entry with a trailing slash, try plain name
- // which would then of course be a file
- if (entry == null) {
- entry = bundle.getEntry(entryPath);
- }
-
- // here we either have a folder for which no same-named item exists
- // or a bundle file
- if (entry != null) {
- return new BundleResource(resourceResolver, bundle, mappedPath,
- resourcePath);
- }
+ private final ValueMap valueMap;
- // the bundle does not contain the path
- return null;
- }
-
- public BundleResource(ResourceResolver resourceResolver,
- BundleResourceCache bundle, MappedPath mappedPath,
- String resourcePath) {
+ public BundleResource(final ResourceResolver resourceResolver,
+ final BundleResourceCache cache,
+ final MappedPath mappedPath,
+ final String resourcePath,
+ final String propsPath,
+ final boolean isFolder) {
this.resourceResolver = resourceResolver;
- this.bundle = bundle;
+ this.cache = cache;
this.mappedPath = mappedPath;
metadata = new ResourceMetadata();
metadata.setResolutionPath(resourcePath);
- metadata.setCreationTime(bundle.getBundle().getLastModified());
- metadata.setModificationTime(bundle.getBundle().getLastModified());
+ metadata.setCreationTime(this.cache.getBundle().getLastModified());
+ metadata.setModificationTime(this.cache.getBundle().getLastModified());
+
+ this.path = resourcePath;
- if (resourcePath.endsWith("/")) {
+ final Map<String, Object> properties = new HashMap<>();
+ this.valueMap = new ValueMapDecorator(Collections.unmodifiableMap(properties));
+ if (isFolder) {
- this.path = resourcePath.substring(0, resourcePath.length() - 1);
- this.resourceType = NT_FOLDER;
- metadata.put(ResourceMetadata.INTERNAL_CONTINUE_RESOLVING, Boolean.TRUE);
+ properties.put(ResourceResolver.PROPERTY_RESOURCE_TYPE, NT_FOLDER);
} else {
- this.path = resourcePath;
- this.resourceType = NT_FILE;
+ properties.put(ResourceResolver.PROPERTY_RESOURCE_TYPE, NT_FILE);
try {
- URL url = bundle.getEntry(mappedPath.getEntryPath(resourcePath));
- metadata.setContentLength(url.openConnection().getContentLength());
- } catch (Exception e) {
+ final URL url = this.cache.getEntry(mappedPath.getEntryPath(resourcePath));
+ if ( url != null ) {
+ metadata.setContentLength(url.openConnection().getContentLength());
+ }
+ } catch (final Exception e) {
// don't care, we just have no content length
}
}
+
+ if ( propsPath != null ) {
+ try {
+ final URL url = this.cache.getEntry(mappedPath.getEntryPath(propsPath));
+ if (url != null) {
+ final JsonObject obj = Json.createReader(url.openStream()).readObject();
+ for(final Map.Entry<String, JsonValue> entry : obj.entrySet()) {
+ final Object value = getValue(entry.getValue());
+ if ( value != null ) {
+ properties.put(entry.getKey(), value);
+ }
+ }
+ }
+ } catch (final IOException ioe) {
+ log.error(
+ "getInputStream: Cannot get input stream for " + mappedPath.getEntryPath(propsPath), ioe);
+ }
+
+ }
+ }
+
+ private static Object getValue(final JsonValue value) {
+ switch ( value.getValueType() ) {
+ // type NULL -> return null
+ case NULL : return null;
+ // type TRUE or FALSE -> return boolean
+ case FALSE : return false;
+ case TRUE : return true;
+ // type String -> return String
+ case STRING : return ((JsonString)value).getString();
+ // type Number -> return long or double
+ case NUMBER : final JsonNumber num = (JsonNumber)value;
+ if (num.isIntegral()) {
+ return num.longValue();
+ }
+ return num.doubleValue();
+ // type ARRAY -> return JSON string
+ case ARRAY : final StringWriter writer = new StringWriter();
+ Json.createWriter(writer).writeArray((JsonArray)value);
+ return writer.toString();
+ // type OBJECT -> return JSON string
+ case OBJECT : final StringWriter mapWriter = new StringWriter();
+ Json.createWriter(mapWriter).writeObject((JsonObject)value);
+ return mapWriter.toString();
+ }
+ return null;
}
+ @Override
public String getPath() {
return path;
}
+ @Override
public String getResourceType() {
- return resourceType;
+ return this.valueMap.get(ResourceResolver.PROPERTY_RESOURCE_TYPE, String.class);
}
- /** Returns <code>null</code>, bundle resources have no super type */
+ @Override
public String getResourceSuperType() {
- return null;
+ return this.valueMap.get("sling:resourceSuperType", String.class);
}
+ @Override
public ResourceMetadata getResourceMetadata() {
return metadata;
}
+ @Override
public ResourceResolver getResourceResolver() {
return resourceResolver;
}
@@ -148,9 +182,11 @@ public class BundleResource extends Abst
return (Type) getInputStream(); // unchecked cast
} else if (type == URL.class) {
return (Type) getURL(); // unchecked cast
+ } else if (type == ValueMap.class) {
+ return (Type) valueMap; // unchecked cast
}
- // fall back to nothing
+ // fall back to adapter factories
return super.adaptTo(type);
}
@@ -185,17 +221,20 @@ public class BundleResource extends Abst
}
private URL getURL() {
- if (url == null) {
- try {
- url = new URL(BundleResourceURLStreamHandler.PROTOCOL, null,
- -1, path, new BundleResourceURLStreamHandler(
- bundle.getBundle(), mappedPath.getEntryPath(path)));
- } catch (MalformedURLException mue) {
- log.error("getURL: Cannot get URL for " + this, mue);
+ if (resourceUrl == null) {
+ final URL url = this.cache.getEntry(mappedPath.getEntryPath(this.path));
+ if ( url != null ) {
+ try {
+ resourceUrl = new URL(BundleResourceURLStreamHandler.PROTOCOL, null,
+ -1, path, new BundleResourceURLStreamHandler(
+ cache.getBundle(), mappedPath.getEntryPath(path)));
+ } catch (MalformedURLException mue) {
+ log.error("getURL: Cannot get URL for " + this, mue);
+ }
}
}
- return url;
+ return resourceUrl;
}
@Override
@@ -204,7 +243,7 @@ public class BundleResource extends Abst
}
BundleResourceCache getBundle() {
- return bundle;
+ return cache;
}
MappedPath getMappedPath() {
Modified: sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceCache.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceCache.java?rev=1806184&r1=1806183&r2=1806184&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceCache.java (original)
+++ sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceCache.java Fri Aug 25 15:21:20 2017
@@ -166,10 +166,9 @@ class BundleResourceCache {
List<String> list = listCache.get(path);
if (list == null) {
- @SuppressWarnings("unchecked")
Enumeration<String> entries = bundle.getEntryPaths(path);
if (entries != null && entries.hasMoreElements()) {
- list = new LinkedList<String>();
+ list = new LinkedList<>();
while (entries.hasMoreElements()) {
list.add(entries.nextElement());
}
Modified: sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceIterator.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceIterator.java?rev=1806184&r1=1806183&r2=1806184&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceIterator.java (original)
+++ sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceIterator.java Fri Aug 25 15:21:20 2017
@@ -56,7 +56,7 @@ class BundleResourceIterator implements
/**
* Creates an instance using the given parent bundle resource.
*/
- BundleResourceIterator(BundleResource parent) {
+ BundleResourceIterator(final BundleResource parent) {
if (parent.isFile()) {
@@ -75,9 +75,9 @@ class BundleResourceIterator implements
this.resourceResolver = parent.getResourceResolver();
this.bundle = parent.getBundle();
this.mappedPath = parent.getMappedPath();
-
+
parentPath = mappedPath.getEntryPath(parentPath);
-
+
this.entries = parent.getBundle().getEntryPaths(parentPath);
this.prefixLength = parentPath.length();
@@ -103,11 +103,13 @@ class BundleResourceIterator implements
}
/** Returns true if there is another Resource available */
+ @Override
public boolean hasNext() {
return nextResult != null;
}
/** Returns the next resource in the iterator */
+ @Override
public Resource next() {
if (!hasNext()) {
throw new NoSuchElementException();
@@ -122,6 +124,7 @@ class BundleResourceIterator implements
* Throws <code>UnsupportedOperationException</code> as this method is not
* supported by this implementation.
*/
+ @Override
public void remove() {
throw new UnsupportedOperationException();
}
@@ -136,14 +139,22 @@ class BundleResourceIterator implements
// require leading slash
if (!entry.startsWith("/")) {
- entry = "/" + entry;
+ entry = "/".concat(entry);
}
int slash = entry.indexOf('/', prefixLength);
- if (slash < 0 || slash == entry.length() - 1) {
+ if ((slash < 0 || slash == entry.length() - 1)
+ && (mappedPath.getJSONPropertiesExtension() == null || !entry.endsWith(mappedPath.getJSONPropertiesExtension()))) {
log.debug("seek: Using entry {}", entry);
+ final boolean isFolder = entry.endsWith("/");
+ String propsPath = null;
+ if ( mappedPath.getJSONPropertiesExtension() != null ) {
+ propsPath = entry.concat(mappedPath.getJSONPropertiesExtension());
+ }
return new BundleResource(resourceResolver, bundle, mappedPath,
- entry);
+ isFolder ? entry.substring(0, entry.length()-1): entry,
+ propsPath,
+ isFolder);
}
log.debug("seek: Ignoring entry {}", entry);
Modified: sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceProvider.java?rev=1806184&r1=1806183&r2=1806184&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceProvider.java (original)
+++ sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceProvider.java Fri Aug 25 15:21:20 2017
@@ -18,15 +18,12 @@
*/
package org.apache.sling.bundleresource.impl;
-import java.util.ArrayList;
-import java.util.Collections;
+import java.net.URL;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Iterator;
-import java.util.List;
import org.apache.sling.api.resource.Resource;
-import org.apache.sling.commons.osgi.ManifestHeader;
import org.apache.sling.spi.resource.provider.ResolveContext;
import org.apache.sling.spi.resource.provider.ResourceContext;
import org.apache.sling.spi.resource.provider.ResourceProvider;
@@ -38,8 +35,8 @@ public class BundleResourceProvider exte
public static final String PROP_BUNDLE = BundleResourceProvider.class.getName();
- /** The bundle providing the resources */
- private final BundleResourceCache bundle;
+ /** The cache with the bundle providing the resources */
+ private final BundleResourceCache cache;
/** The root path */
private final MappedPath root;
@@ -47,49 +44,35 @@ public class BundleResourceProvider exte
@SuppressWarnings("rawtypes")
private volatile ServiceRegistration<ResourceProvider> serviceRegistration;
- public static MappedPath[] getRoots(final Bundle bundle, final String rootList) {
- List<MappedPath> prefixList = new ArrayList<>();
-
- final ManifestHeader header = ManifestHeader.parse(rootList);
- for (final ManifestHeader.Entry entry : header.getEntries()) {
- final String resourceRoot = entry.getValue();
- final String pathDirective = entry.getDirectiveValue("path");
- if (pathDirective != null) {
- prefixList.add(new MappedPath(resourceRoot, pathDirective));
- } else {
- prefixList.add(MappedPath.create(resourceRoot));
- }
- }
- return prefixList.toArray(new MappedPath[prefixList.size()]);
- }
-
/**
* Creates Bundle resource provider accessing entries in the given Bundle an
* supporting resources below root paths given by the rootList which is a
* comma (and whitespace) separated list of absolute paths.
*/
public BundleResourceProvider(final Bundle bundle, final MappedPath root) {
- this.bundle = new BundleResourceCache(bundle);
+ this.cache = new BundleResourceCache(bundle);
this.root = root;
}
//---------- Service Registration
long registerService() {
+ final Bundle bundle = this.cache.getBundle();
final Dictionary<String, Object> props = new Hashtable<>();
props.put(Constants.SERVICE_DESCRIPTION,
- "Provider of bundle based resources");
+ "Provider of bundle based resources from bundle " + String.valueOf(bundle.getBundleId()));
props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
- props.put(ResourceProvider.PROPERTY_ROOT, getRoot());
- props.put(PROP_BUNDLE, this.bundle.getBundle().getBundleId());
+ props.put(ResourceProvider.PROPERTY_ROOT, this.root.getResourceRoot());
+ props.put(PROP_BUNDLE,bundle.getBundleId());
- serviceRegistration = this.bundle.getBundle().getBundleContext().registerService(ResourceProvider.class, this, props);
+ serviceRegistration = bundle.getBundleContext().registerService(ResourceProvider.class, this, props);
return (Long) serviceRegistration.getReference().getProperty(Constants.SERVICE_ID);
}
void unregisterService() {
if (serviceRegistration != null) {
serviceRegistration.unregister();
+ serviceRegistration = null;
}
}
@@ -106,39 +89,78 @@ public class BundleResourceProvider exte
final Resource parent) {
final MappedPath mappedPath = getMappedPath(path);
if (mappedPath != null) {
- return BundleResource.getResource(ctx.getResourceResolver(), bundle,
- mappedPath, path);
+ final String entryPath = mappedPath.getEntryPath(path);
+
+ // first try, whether the bundle has an entry with a trailing slash
+ // which would be a folder. In this case we check whether the
+ // repository contains an item with the same path. If so, we
+ // don't create a BundleResource but instead return null to be
+ // able to return an item-based resource
+ URL entry = cache.getEntry(entryPath.concat("/"));
+ final boolean isFolder = entry != null;
+
+ // if there is no entry with a trailing slash, try plain name
+ // which would then of course be a file
+ if (entry == null) {
+ entry = cache.getEntry(entryPath);
+ if ( entry == null && this.root.getJSONPropertiesExtension() != null ) {
+ entry = cache.getEntry(entryPath + this.root.getJSONPropertiesExtension());
+ }
+ }
+
+ // here we either have a folder for which no same-named item exists
+ // or a bundle file
+ if (entry != null) {
+ // check if a JSON props file is directly requested
+ // if so, we deny the access
+ if ( this.root.getJSONPropertiesExtension() == null
+ || !entryPath.endsWith(this.root.getJSONPropertiesExtension()) ) {
+
+ String propsPath = null;
+ if ( this.root.getJSONPropertiesExtension() != null ) {
+ propsPath = entryPath.concat(this.root.getJSONPropertiesExtension());
+ }
+ return new BundleResource(ctx.getResourceResolver(),
+ cache,
+ mappedPath,
+ path,
+ propsPath,
+ isFolder);
+ }
+ }
+
+ // the bundle does not contain the path
}
return null;
}
@Override
- public Iterator<Resource> listChildren(ResolveContext<Object> ctx, Resource parent) {
- if (parent instanceof BundleResource && ((BundleResource)parent).getBundle() == this.bundle) {
+ public Iterator<Resource> listChildren(final ResolveContext<Object> ctx, final Resource parent) {
+ if (parent instanceof BundleResource && ((BundleResource)parent).getBundle() == this.cache) {
// bundle resources can handle this request directly when the parent
- // resource is in the same bundle as this provider.
+ // resource is in the same bundle as this provider.
return ((BundleResource) parent).listChildren();
- }
+ }
// ensure this provider may have children of the parent
String parentPath = parent.getPath();
MappedPath mappedPath = getMappedPath(parentPath);
if (mappedPath != null) {
return new BundleResourceIterator(parent.getResourceResolver(),
- bundle, mappedPath, parentPath);
+ cache, mappedPath, parentPath);
}
// the parent resource cannot have children in this provider,
// though this is basically not expected, we still have to
// be prepared for such a situation
- return Collections.<Resource> emptyList().iterator();
+ return null;
}
// ---------- Web Console plugin support
BundleResourceCache getBundleResourceCache() {
- return bundle;
+ return cache;
}
MappedPath getMappedPath() {
@@ -147,17 +169,11 @@ public class BundleResourceProvider exte
// ---------- internal
- /** Returns the root path */
- private String getRoot() {
- return this.root.getResourceRoot();
- }
-
- private MappedPath getMappedPath(String resourcePath) {
+ private MappedPath getMappedPath(final String resourcePath) {
if (this.root.isChild(resourcePath)) {
return root;
}
return null;
}
-
}
Modified: sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/MappedPath.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/MappedPath.java?rev=1806184&r1=1806183&r2=1806184&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/MappedPath.java (original)
+++ sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/MappedPath.java Fri Aug 25 15:21:20 2017
@@ -18,15 +18,44 @@
*/
package org.apache.sling.bundleresource.impl;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.sling.commons.osgi.ManifestHeader;
+
class MappedPath {
+ public static final String DIR_PATH = "path";
+ public static final String DIR_JSON = "propsJSON";
+
private static final char prefixSeparatorChar = '!';
private final String resourceRoot;
private final String resourceRootPrefix;
private final String entryRoot;
private final String entryRootPrefix;
- static MappedPath create(String configPath) {
+ private final String jsonExpandExtension;
+
+ public static MappedPath[] getRoots(final String rootList) {
+ List<MappedPath> prefixList = new ArrayList<>();
+
+ final ManifestHeader header = ManifestHeader.parse(rootList);
+ for (final ManifestHeader.Entry entry : header.getEntries()) {
+ final String resourceRoot = entry.getValue();
+ final String pathDirective = entry.getDirectiveValue(DIR_PATH);
+ final String expandDirective = entry.getDirectiveValue(DIR_JSON);
+ if (pathDirective != null) {
+ prefixList.add(new MappedPath(resourceRoot, pathDirective, expandDirective));
+ } else {
+ prefixList.add(MappedPath.create(resourceRoot, expandDirective));
+ }
+ }
+ return prefixList.toArray(new MappedPath[prefixList.size()]);
+ }
+
+
+ static MappedPath create(final String configPath,
+ final String expandDirective) {
String resourceRoot;
String entryRoot;
int prefixSep = configPath.indexOf(prefixSeparatorChar);
@@ -37,63 +66,94 @@ class MappedPath {
resourceRoot = configPath;
entryRoot = null;
}
- return new MappedPath(resourceRoot, entryRoot);
+ return new MappedPath(resourceRoot, entryRoot, expandDirective);
}
-
- MappedPath(String resourceRoot, String entryRoot) {
- this.resourceRoot = resourceRoot;
+
+ MappedPath(final String resourceRoot,
+ final String entryRoot,
+ final String expandDirective) {
+ this.resourceRoot = ensureNoTrailingSlash(resourceRoot);
this.resourceRootPrefix = ensureTrailingSlash(resourceRoot);
- this.entryRoot = entryRoot;
+ this.entryRoot = ensureNoTrailingSlash(entryRoot);
this.entryRootPrefix = ensureTrailingSlash(entryRoot);
+ this.jsonExpandExtension = ensureLeadingDot(expandDirective);
}
-
- boolean isChild(String resourcePath) {
+
+ String getJSONPropertiesExtension() {
+ return this.jsonExpandExtension;
+ }
+
+ boolean isChild(final String resourcePath) {
return resourcePath.startsWith(resourceRootPrefix)
|| resourcePath.equals(resourceRoot);
}
-
- String getEntryPath(String resourcePath) {
+
+ String getEntryPath(final String resourcePath) {
if (entryRootPrefix == null) {
return resourcePath;
}
-
+
if (resourcePath.startsWith(resourceRootPrefix)) {
return entryRootPrefix.concat(resourcePath.substring(resourceRootPrefix.length()));
} else if (resourcePath.equals(resourceRoot)) {
return entryRoot;
}
-
+
return null;
}
-
+
String getResourceRoot() {
return resourceRoot;
}
-
+
String getResourceRootPrefix() {
return resourceRootPrefix;
}
-
+
String getEntryRoot() {
return entryRoot;
}
-
+
String getEntryRootPrefix() {
return entryRootPrefix;
}
-
- private static String ensureTrailingSlash(String path) {
+
+ private static String ensureLeadingDot(final String path) {
+ if (path == null || path.length() == 0) {
+ return null;
+ }
+
+ if (!path.startsWith(".")) {
+ return ".".concat(path);
+ }
+
+ return path;
+ }
+
+ private static String ensureNoTrailingSlash(final String path) {
if (path == null || path.length() == 0) {
return null;
}
-
+
+ if (path.endsWith("/")) {
+ return ensureNoTrailingSlash(path.substring(0, path.length() - 1));
+ }
+
+ return path;
+ }
+
+ private static String ensureTrailingSlash(final String path) {
+ if (path == null || path.length() == 0) {
+ return null;
+ }
+
if (!path.endsWith("/")) {
return path.concat("/");
}
-
+
return path;
}
-
+
@Override
public String toString() {
return "MappedPath: " + getResourceRoot() + " -> " + getEntryRoot();