You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by fm...@apache.org on 2007/12/05 21:38:26 UTC
svn commit: r601511 - in /incubator/sling/trunk/jcr/resource/src:
main/java/org/apache/sling/jcr/resource/
main/java/org/apache/sling/jcr/resource/internal/
main/java/org/apache/sling/jcr/resource/internal/helper/
main/java/org/apache/sling/jcr/resourc...
Author: fmeschbe
Date: Wed Dec 5 12:38:23 2007
New Revision: 601511
URL: http://svn.apache.org/viewvc?rev=601511&view=rev
Log:
SLING-122 Add support Bundle based resources and adapt resource resolution to be
pluggable also supporting other resource providers in the future
Added:
incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourceProvider.java
incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntry.java
incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/bundle/
incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/bundle/BundleResource.java
incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/bundle/BundleResourceIterator.java
incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/bundle/BundleResourceProvider.java
incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/bundle/BundleResourceURLConnection.java
incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/bundle/BundleResourceURLStreamHandler.java
incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/
incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResource.java
- copied, changed from r600523, incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/JcrNodeResource.java
incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResourceIterator.java
- copied, changed from r600457, incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/JcrNodeResourceIterator.java
incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntryTest.java
Removed:
incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/JcrNodeResource.java
incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/JcrNodeResourceIterator.java
Modified:
incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceConstants.java
incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceManager.java
incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceManagerFactoryImpl.java
incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/JcrNodeResourceIteratorTest.java
Modified: incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceConstants.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceConstants.java?rev=601511&r1=601510&r2=601511&view=diff
==============================================================================
--- incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceConstants.java (original)
+++ incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceConstants.java Wed Dec 5 12:38:23 2007
@@ -88,5 +88,17 @@
*/
public static final String MAPPING_NODE_TYPE = "MAPPED_NODE_TYPE";
+ /**
+ * The name of the bundle manifest header listing the bundle entries
+ * providing Object Content Mapping configurations (value is
+ * "Sling-Mappings").
+ */
public static final String MAPPER_BUNDLE_HEADER = "Sling-Mappings";
+
+ /**
+ * The name of the bundle manifest header listing the resource provider root
+ * paths provided by the bundle (value is "Sling-Bundle-Resources").
+ */
+ public static final String BUNDLE_RESOURCE_ROOTS = "Sling-Bundle-Resources";
+
}
Modified: incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceManager.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceManager.java?rev=601511&r1=601510&r2=601511&view=diff
==============================================================================
--- incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceManager.java (original)
+++ incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceManager.java Wed Dec 5 12:38:23 2007
@@ -48,10 +48,11 @@
import org.apache.sling.jcr.resource.JcrResourceUtil;
import org.apache.sling.jcr.resource.PathResolver;
import org.apache.sling.jcr.resource.internal.helper.Descendable;
-import org.apache.sling.jcr.resource.internal.helper.JcrNodeResource;
-import org.apache.sling.jcr.resource.internal.helper.JcrNodeResourceIterator;
import org.apache.sling.jcr.resource.internal.helper.Mapping;
import org.apache.sling.jcr.resource.internal.helper.ResourcePathIterator;
+import org.apache.sling.jcr.resource.internal.helper.ResourceProvider;
+import org.apache.sling.jcr.resource.internal.helper.jcr.JcrNodeResource;
+import org.apache.sling.jcr.resource.internal.helper.jcr.JcrNodeResourceIterator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -147,7 +148,8 @@
return ((Descendable) parent).listChildren();
}
} catch (SlingException se) {
- log.warn("listChildren: Error trying to resolve parent resource " + parent.getURI(), se);
+ log.warn("listChildren: Error trying to resolve parent resource "
+ + parent.getURI(), se);
}
// return an empty iterator if parent has no node
@@ -158,7 +160,8 @@
public Iterator<Resource> findResources(String query, String language)
throws SlingException {
try {
- QueryResult res = JcrResourceUtil.query(getSession(), query, language);
+ QueryResult res = JcrResourceUtil.query(getSession(), query,
+ language);
return new JcrNodeResourceIterator(this, res.getNodes());
} catch (javax.jcr.query.InvalidQueryException iqe) {
throw new SlingException(iqe);
@@ -170,7 +173,8 @@
public Iterator<Map<String, Object>> queryResources(String query,
String language) throws SlingException {
try {
- QueryResult result = JcrResourceUtil.query(getSession(), query, language);
+ QueryResult result = JcrResourceUtil.query(getSession(), query,
+ language);
final String[] colNames = result.getColumnNames();
final RowIterator rows = result.getRows();
return new Iterator<Map<String, Object>>() {
@@ -207,7 +211,7 @@
/**
* @throws AccessControlException If an item would exist but is not readable
- * to this manager's session.
+ * to this manager's session.
*/
public Resource resolve(String uri) throws SlingException {
@@ -220,7 +224,6 @@
log.error("Failed to decode request URI " + uri, e);
}
-
// resolve virtual uri
String realUrl = factory.virtualToRealUri(uri);
if (realUrl != null) {
@@ -322,10 +325,14 @@
path = JcrResourceUtil.normalize(path);
if (path != null) {
try {
- return getResourceInternal(path, type);
- } catch (RepositoryException re) {
+ Resource resource = getResourceInternal(path);
+ if (type != null && resource instanceof JcrNodeResource) {
+ ((JcrNodeResource) resource).setObjectType(type);
+ }
+ return resource;
+ } catch (Exception ex) {
throw new SlingException("Problem accessing resource" + path,
- re);
+ ex);
}
}
@@ -359,9 +366,9 @@
getSession().getWorkspace().copy(source, destination);
} else {
// TODO: Create node at destination:
- // - same primary node type
- // - same mixins
- // - same non-protected properties
+ // - same primary node type
+ // - same mixins
+ // - same non-protected properties
}
} catch (AccessControlException ace) {
@@ -461,8 +468,7 @@
* {@link #DEFAULT_CONTENT_CLASS default content class}.
*
* @param type Load the node's content into an object of the given type if
- * not <code>null</code>.
- *
+ * not <code>null</code>.
* @return the <code>Content</code> object loaded from the node or
* <code>null</code> if no node exists at the given path.
*/
@@ -501,7 +507,7 @@
return null;
}
- protected Session getSession() {
+ public Session getSession() {
return session;
}
@@ -542,11 +548,11 @@
final ResourcePathIterator it = new ResourcePathIterator(uriPath);
while (it.hasNext() && resource == null) {
curPath = it.next();
- resource = getResourceInternal(curPath, null);
+ resource = getResourceInternal(curPath);
}
- } catch (RepositoryException re) {
+ } catch (Exception ex) {
throw new SlingException("Problem trying " + curPath
- + " for request path " + uriPath, re);
+ + " for request path " + uriPath, ex);
}
return resource;
@@ -558,19 +564,21 @@
* @throws AccessControlException If an item exists but this manager has no
* read access
*/
- protected Resource getResourceInternal(String path, Class<?> type)
- throws RepositoryException {
+ protected Resource getResourceInternal(String path) throws Exception {
- // check JCR repository
- if (itemExists(path)) {
- Resource result = new JcrNodeResource(this, getSession(), path, type);
- result.getResourceMetadata().put(ResourceMetadata.RESOLUTION_PATH,
- path);
- log.info("Found JCR Node Resource at path '{}'", path);
- return result;
+ ResourceProvider rp = factory.getResourceProvider(path);
+ Resource resource = rp.getResource(this, path);
+ if (resource == null && rp != factory) {
+ resource = factory.getResource(this, path);
}
- log.debug("Path '{}' does not resolve to an Item", path);
+ if (resource != null) {
+ resource.getResourceMetadata().put(
+ ResourceMetadata.RESOLUTION_PATH, path);
+ return resource;
+ }
+
+ log.debug("Cannot resolve path '{}' to a resource", path);
return null;
}
@@ -587,7 +595,7 @@
* @throws AccessControlException If the item really exists but this content
* manager's session has no read access to it.
*/
- protected boolean itemExists(String path) throws RepositoryException {
+ public boolean itemExists(String path) throws RepositoryException {
if (factory.itemReallyExists(getSession(), path)) {
checkPermission(path, ACTION_READ);
return true;
@@ -597,12 +605,11 @@
}
/**
- *
* @param path
* @param actions
* @throws RepositoryException
- * @throws AccessControlException if this manager does not have the permission
- * for the listed action(s).
+ * @throws AccessControlException if this manager does not have the
+ * permission for the listed action(s).
*/
protected void checkPermission(String path, String actions)
throws RepositoryException {
Modified: incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceManagerFactoryImpl.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceManagerFactoryImpl.java?rev=601511&r1=601510&r2=601511&view=diff
==============================================================================
--- incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceManagerFactoryImpl.java (original)
+++ incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceManagerFactoryImpl.java Wed Dec 5 12:38:23 2007
@@ -18,13 +18,14 @@
*/
package org.apache.sling.jcr.resource.internal;
+import static org.apache.sling.jcr.resource.JcrResourceConstants.BUNDLE_RESOURCE_ROOTS;
+
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
-import java.util.StringTokenizer;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
@@ -32,11 +33,16 @@
import org.apache.commons.collections.BidiMap;
import org.apache.commons.collections.bidimap.TreeBidiMap;
import org.apache.jackrabbit.ocm.manager.ObjectContentManager;
+import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceManager;
import org.apache.sling.commons.mime.MimeTypeService;
import org.apache.sling.jcr.api.SlingRepository;
import org.apache.sling.jcr.resource.JcrResourceManagerFactory;
import org.apache.sling.jcr.resource.internal.helper.Mapping;
+import org.apache.sling.jcr.resource.internal.helper.ResourceProvider;
+import org.apache.sling.jcr.resource.internal.helper.ResourceProviderEntry;
+import org.apache.sling.jcr.resource.internal.helper.bundle.BundleResourceProvider;
+import org.apache.sling.jcr.resource.internal.helper.jcr.JcrNodeResource;
import org.apache.sling.jcr.resource.internal.loader.Loader;
import org.apache.sling.jcr.resource.internal.mapping.ObjectContentManagerFactory;
import org.osgi.framework.Bundle;
@@ -69,7 +75,7 @@
* @scr.service interface="org.apache.sling.jcr.resource.JcrResourceManagerFactory"
*/
public class JcrResourceManagerFactoryImpl implements
- JcrResourceManagerFactory, SynchronousBundleListener {
+ JcrResourceManagerFactory, SynchronousBundleListener, ResourceProvider {
/**
* @scr.property value="true" type="Boolean"
@@ -119,7 +125,10 @@
*/
private MimeTypeService mimeTypeService;
- /** This services ServiceReference for use in {@link #fireEvent(Bundle, String, Map)} */
+ /**
+ * This services ServiceReference for use in
+ * {@link #fireEvent(Bundle, String, Map)}
+ */
private ServiceReference serviceReference;
/** all mappings */
@@ -152,6 +161,14 @@
*/
private Loader initialContentLoader;
+ private ResourceProviderEntry rootProviderEntry;
+
+ private Map<Long, BundleResourceProvider> bundleResourceProviderMap = new HashMap<Long, BundleResourceProvider>();
+
+ public JcrResourceManagerFactoryImpl() {
+ this.rootProviderEntry = new ResourceProviderEntry("/", this);
+ }
+
// ---------- JcrResourceManagerFactory ------------------------------------
/**
@@ -200,13 +217,13 @@
case BundleEvent.STARTING: // STARTED:
// register mappings before the bundle gets activated
objectContentManagerFactory.registerMapperClient(event.getBundle());
- addBundleResources(event.getBundle());
+ addBundleResourceProvider(event.getBundle());
break;
case BundleEvent.STOPPED:
// remove mappings after the bundle has stopped
objectContentManagerFactory.unregisterMapperClient(event.getBundle());
- removeBundleResources(event.getBundle());
+ removeBundleResourceProvider(event.getBundle());
break;
case BundleEvent.UNINSTALLED:
@@ -215,6 +232,23 @@
}
}
+ // ---------- ResourceProvider ---------------------------------------------
+
+ public String[] getRoots() {
+ return new String[] { "/" };
+ }
+
+ public Resource getResource(JcrResourceManager jcrResourceManager,
+ String path) throws RepositoryException {
+
+ if (jcrResourceManager.itemExists(path)) {
+ log.info("getResource: Found JCR Node Resource at path '{}'", path);
+ return new JcrNodeResource(jcrResourceManager, path);
+ }
+
+ return null;
+ }
+
// ---------- EventAdmin Event Dispatching ---------------------------------
/**
@@ -313,45 +347,26 @@
// ---------- Bundle provided resources -----------------------------------
- private Map<String, Bundle> bundleResourcesByPrefix = new HashMap<String, Bundle>();
- private Map<Long, String[]> bundleResourcesByBundleId = new HashMap<Long, String[]>();
-
- private void addBundleResources(Bundle bundle) {
- String prefixes = (String) bundle.getHeaders().get("Sling-Resource-Prefixes");
+ private void addBundleResourceProvider(Bundle bundle) {
+ String prefixes = (String) bundle.getHeaders().get(
+ BUNDLE_RESOURCE_ROOTS);
if (prefixes != null) {
- StringTokenizer pt = new StringTokenizer(prefixes, ", \t\n\r\f");
- List<String> prefixList = new ArrayList<String>();
- while (pt.hasMoreTokens()) {
- String prefix = pt.nextToken().trim();
- if (prefix.length() > 0) {
- bundleResourcesByPrefix.put(prefix, bundle);
- prefixList.add(prefix);
- }
- }
- if (prefixList.size() > 0) {
- bundleResourcesByBundleId.put(bundle.getBundleId(),
- prefixList.toArray(new String[prefixList.size()]));
- }
+ BundleResourceProvider brp = new BundleResourceProvider(bundle,
+ prefixes);
+ rootProviderEntry.addResourceProvider(brp);
+ bundleResourceProviderMap.put(bundle.getBundleId(), brp);
}
}
- private void removeBundleResources(Bundle bundle) {
- String[] prefixes = bundleResourcesByBundleId.get(bundle.getBundleId());
- if (prefixes != null) {
- for (String prefix : prefixes) {
- bundleResourcesByPrefix.remove(prefix);
- }
+ private void removeBundleResourceProvider(Bundle bundle) {
+ BundleResourceProvider brp = bundleResourceProviderMap.get(bundle.getBundleId());
+ if (brp != null) {
+ rootProviderEntry.removeResourceProvider(brp);
}
}
- Bundle getBundleForResource(String path) {
- for (Map.Entry<String, Bundle> entry : bundleResourcesByPrefix.entrySet()) {
- if (path.startsWith(entry.getKey())) {
- return entry.getValue();
- }
- }
-
- return null;
+ ResourceProvider getResourceProvider(String path) {
+ return rootProviderEntry.getResourceProvider(path);
}
// ---------- SCR Integration ---------------------------------------------
@@ -379,14 +394,13 @@
if (bundle.getState() == Bundle.ACTIVE) {
// register active bundles with the mapper client
objectContentManagerFactory.registerMapperClient(bundle);
- addBundleResources(bundle);
+ addBundleResourceProvider(bundle);
}
}
} catch (Throwable t) {
log.error("activate: Problem while loading initial content and"
+ " registering mappings for existing bundles", t);
}
-
Dictionary<?, ?> properties = componentContext.getProperties();
Added: incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourceProvider.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourceProvider.java?rev=601511&view=auto
==============================================================================
--- incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourceProvider.java (added)
+++ incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourceProvider.java Wed Dec 5 12:38:23 2007
@@ -0,0 +1,53 @@
+/*
+ * 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.jcr.resource.internal.helper;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.jcr.resource.internal.JcrResourceManager;
+
+/**
+ * API for providers of resources. Used by the {@link JcrResourceManager} and
+ * {@link org.apache.sling.jcr.resource.internal.JcrResourceManagerFactoryImpl}
+ * classes to transparently access resources from different locations such as a
+ * JCR repository (the default) or OSGi bundles.
+ * <p>
+ * This is an internal interface not available outside this bundle. It refers to
+ * the internal {@link JcrResourceManager} class, which is also not visible from
+ * outside of this bundle.
+ */
+public interface ResourceProvider {
+
+ /**
+ * A list of absolute path prefixes of resources available through this
+ * provider.
+ */
+ String[] getRoots();
+
+ /**
+ * Returns a resource from this resource provider or <code>null</code> if
+ * the resource provider cannot find it. The path should have one of the
+ * {@link #getRoots()} strings as its prefix.
+ *
+ * @throws Exception may be thrown in case of any problem creating the
+ * <code>Resource</code> instance.
+ */
+ Resource getResource(JcrResourceManager jcrResourceManager, String path)
+ throws Exception;
+
+}
Added: incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntry.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntry.java?rev=601511&view=auto
==============================================================================
--- incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntry.java (added)
+++ incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntry.java Wed Dec 5 12:38:23 2007
@@ -0,0 +1,189 @@
+/*
+ * 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.jcr.resource.internal.helper;
+
+import java.util.Arrays;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+public class ResourceProviderEntry implements Comparable<ResourceProviderEntry> {
+
+ private final String path;
+
+ private final String prefix;
+
+ private final ResourceProvider provider;
+
+ private ResourceProviderEntry[] entries;
+
+ public ResourceProviderEntry(String path, ResourceProvider provider) {
+ if (path.endsWith("/")) {
+ this.path = path.substring(0, path.length() - 1);
+ this.prefix = path;
+ } else {
+ this.path = path;
+ this.prefix = path + "/";
+ }
+ this.provider = provider;
+ }
+
+ public void addResourceProvider(ResourceProvider provider) {
+ String[] roots = provider.getRoots();
+ for (int i = 0; i < roots.length; i++) {
+ addResourceProvider(roots[i], provider);
+ }
+ }
+
+ public void removeResourceProvider(ResourceProvider provider) {
+ String[] roots = provider.getRoots();
+ for (int i = 0; i < roots.length; i++) {
+ removeResourceProvider(roots[i]);
+ }
+ }
+
+ public ResourceProvider getResourceProvider(String path) {
+ if (path.equals(this.path)) {
+ return provider;
+ } else if (match(path)) {
+ if (entries != null) {
+
+ // consider relative path for further checks
+ path = path.substring(this.prefix.length());
+
+ for (ResourceProviderEntry entry : entries) {
+ ResourceProvider provider = entry.getResourceProvider(path);
+ if (provider != null) {
+ return provider;
+ }
+ }
+ }
+
+ // no more specific provider, return mine
+ return provider;
+ }
+
+ // no match for my prefix, return null
+ return null;
+ }
+
+ public boolean match(String path) {
+ return path.startsWith(prefix);
+ }
+
+ // ---------- Comparable<ResourceProviderEntry> interface ------------------
+
+ public int compareTo(ResourceProviderEntry o) {
+ return prefix.compareTo(o.prefix);
+ }
+
+ // ---------- internal -----------------------------------------------------
+
+ private boolean addResourceProvider(String prefix, ResourceProvider provider) {
+ if (prefix.equals(this.path)) {
+ throw new IllegalStateException(
+ "ResourceProviderEntry for prefix already exists");
+ } else if (match(prefix)) {
+
+ // consider relative path for further checks
+ prefix = prefix.substring(this.prefix.length());
+
+ // check whether there is a better suited place
+ if (entries != null) {
+ for (int i = 0; i < entries.length; i++) {
+ ResourceProviderEntry entry = entries[i];
+ if (entry.addResourceProvider(prefix, provider)) {
+ return true;
+ } else if (entry.prefix.startsWith(prefix)
+ && entry.prefix.charAt(prefix.length()) == '/') {
+ ResourceProviderEntry newEntry = new ResourceProviderEntry(
+ prefix, provider);
+ newEntry.addResourceProvider(entry.path, entry.provider);
+ entries[i] = newEntry;
+ return true;
+ }
+
+ }
+ }
+
+ // none found, so add it here
+ ResourceProviderEntry entry = new ResourceProviderEntry(prefix,
+ provider);
+ if (entries == null) {
+ entries = new ResourceProviderEntry[] { entry };
+ } else {
+ SortedSet<ResourceProviderEntry> set = new TreeSet<ResourceProviderEntry>();
+ set.addAll(Arrays.asList(entries));
+ set.add(entry);
+ entries = set.toArray(new ResourceProviderEntry[set.size()]);
+ }
+
+ return true;
+ }
+
+ // the prefix does not match this prefix
+ return false;
+ }
+
+ private boolean removeResourceProvider(String prefix) {
+ if (prefix.equals(path)) {
+ return true;
+ } else if (match(prefix)) {
+ // consider relative path for further checks
+ prefix = prefix.substring(this.prefix.length());
+
+ // check whether there is a better suited place
+ if (entries != null) {
+ for (int i = 0; i < entries.length; i++) {
+ ResourceProviderEntry entry = entries[i];
+ if (entry.removeResourceProvider(prefix)) {
+ if (entries.length == 1) {
+ entries = null;
+ } else {
+ int newEntriesLen = entries.length - 1;
+ ResourceProviderEntry[] newEntries = new ResourceProviderEntry[newEntriesLen];
+ if (i > 0) {
+ System.arraycopy(entries, 0, newEntries, 0, i);
+ }
+ if (i < newEntriesLen) {
+ System.arraycopy(entries, i + 1, newEntries, i,
+ newEntriesLen - i);
+ }
+ entries = newEntries;
+ }
+
+ // reinsert children
+ ResourceProviderEntry[] children = entry.entries;
+ if (children != null) {
+ String pathPrefix = this.prefix + entry.prefix;
+ for (ResourceProviderEntry child : children) {
+ String path = pathPrefix + child.path;
+ addResourceProvider(path, child.provider);
+ }
+ }
+
+ return false;
+ }
+
+ }
+ }
+ }
+
+ return false;
+ }
+}
Added: incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/bundle/BundleResource.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/bundle/BundleResource.java?rev=601511&view=auto
==============================================================================
--- incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/bundle/BundleResource.java (added)
+++ incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/bundle/BundleResource.java Wed Dec 5 12:38:23 2007
@@ -0,0 +1,179 @@
+/*
+ * 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.jcr.resource.internal.helper.bundle;
+
+import static org.apache.jackrabbit.JcrConstants.NT_FILE;
+import static org.apache.jackrabbit.JcrConstants.NT_FOLDER;
+import static org.apache.sling.api.resource.ResourceMetadata.CREATION_TIME;
+import static org.apache.sling.api.resource.ResourceMetadata.MODIFICATION_TIME;
+import static org.apache.sling.api.resource.ResourceMetadata.RESOLUTION_PATH;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Iterator;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceMetadata;
+import org.apache.sling.jcr.resource.internal.helper.Descendable;
+import org.osgi.framework.Bundle;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/** A Resource that wraps a Bundle entry */
+public class BundleResource implements Resource, Descendable {
+
+ /** default log */
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ private final Bundle bundle;
+
+ private final String path;
+
+ private URL url;
+
+ private final String resourceType;
+
+ private final ResourceMetadata metadata;
+
+ public static BundleResource getResource(Bundle bundle, String path) {
+
+ // if the entry has no trailing slash, try to with a trailing
+ // slash in case the entry would be a folder
+ if (!path.endsWith("/")) {
+ BundleResource br = getResource(bundle, path + "/");
+ if (br != null) {
+ return br;
+ }
+ }
+
+ // has trailing slash or not a folder, try path itself
+ URL entry = bundle.getEntry(path);
+ if (entry != null) {
+ return new BundleResource(bundle, path);
+ }
+
+ // the bundle does not contain the path
+ return null;
+ }
+
+ public BundleResource(Bundle bundle, String path) {
+ this.bundle = bundle;
+ this.path = path.endsWith("/")
+ ? path.substring(0, path.length() - 1)
+ : path;
+ this.resourceType = path.endsWith("/") ? NT_FOLDER : NT_FILE;
+
+ metadata = new ResourceMetadata();
+ metadata.put(RESOLUTION_PATH, path);
+ metadata.put(CREATION_TIME, bundle.getLastModified());
+ metadata.put(MODIFICATION_TIME, bundle.getLastModified());
+ }
+
+ public String getURI() {
+ return path;
+ }
+
+ public String getResourceType() {
+ return resourceType;
+ }
+
+ public ResourceMetadata getResourceMetadata() {
+ return metadata;
+ }
+
+ @SuppressWarnings("unchecked")
+ public <Type> Type adaptTo(Class<Type> type) {
+ if (type == InputStream.class) {
+ return (Type) getInputStream(); // unchecked cast
+ } else if (type == URL.class) {
+ return (Type) getURL(); // unchecked cast
+ }
+
+ // fall back to nothing
+ return null;
+ }
+
+ public String toString() {
+ return "BundleResource, type=" + resourceType + ", path=" + path;
+ }
+
+ // ---------- internal -----------------------------------------------------
+
+ /**
+ * Returns a stream to the bundle entry if it is a file. Otherwise returns
+ * <code>null</code>.
+ */
+ private InputStream getInputStream() {
+ // implement this for files only
+ if (isFile()) {
+ try {
+ URL url = getURL();
+ if (url != null) {
+ return url.openStream();
+ }
+ } catch (IOException ioe) {
+ log.error(
+ "getInputStream: Cannot get input stream for " + this, ioe);
+ }
+ }
+
+ // otherwise there is no stream
+ return null;
+ }
+
+ private URL getURL() {
+ if (url == null) {
+ try {
+ url = new URL(BundleResourceURLStreamHandler.PROTOCOL, null,
+ -1, path, new BundleResourceURLStreamHandler(bundle));
+ } catch (MalformedURLException mue) {
+ log.error("getURL: Cannot get URL for " + this, mue);
+ }
+ }
+
+ return url;
+ }
+
+ // ---------- Descendable interface ----------------------------------------
+
+ public Iterator<Resource> listChildren() {
+ return new BundleResourceIterator(this);
+ }
+
+ public Resource getDescendent(String relPath) {
+
+ // only consider folder resources for descendents
+ if (!isFile()) {
+ URL descendent = bundle.getEntry(path + relPath);
+ if (descendent != null) {
+ new BundleResource(bundle, descendent.getPath());
+ }
+ }
+
+ return null;
+ }
+
+ Bundle getBundle() {
+ return bundle;
+ }
+
+ boolean isFile() {
+ return NT_FILE.equals(getResourceType());
+ }
+}
Added: incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/bundle/BundleResourceIterator.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/bundle/BundleResourceIterator.java?rev=601511&view=auto
==============================================================================
--- incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/bundle/BundleResourceIterator.java (added)
+++ incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/bundle/BundleResourceIterator.java Wed Dec 5 12:38:23 2007
@@ -0,0 +1,128 @@
+/*
+ * 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.jcr.resource.internal.helper.bundle;
+
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.apache.sling.api.resource.Resource;
+import org.osgi.framework.Bundle;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The <code>BundleResourceIterator</code> class is a resource iterator, which
+ * returns resources for each Bundle entry of an underlying enumeration of
+ * Bundle entry paths.
+ */
+class BundleResourceIterator implements Iterator<Resource> {
+
+ /** default log */
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ /** Bundle providing the entry resources */
+ private Bundle bundle;
+
+ /** Underlying bundle entry path enumeration */
+ private Enumeration<String> entries;
+
+ /** The length of the parent entry path, see seek() */
+ private int prefixLength;
+
+ /** The prefetched next iterator entry, null at the end of iterating */
+ private Resource nextResult;
+
+ /**
+ * Creates an instance using the given parent bundle resource.
+ */
+ @SuppressWarnings("unchecked")
+ BundleResourceIterator(BundleResource parent) {
+
+ if (parent.isFile()) {
+
+ // if the parent is a file, the iterator is empty
+ this.bundle = null;
+ this.entries = null;
+ this.prefixLength = 0;
+ this.nextResult = null;
+
+ } else {
+ // trailing slash to enumerate children
+ String parentPath = parent.getURI() + "/";
+
+ this.bundle = parent.getBundle();
+ // unchecked cast
+ this.entries = parent.getBundle().getEntryPaths(parentPath);
+ this.prefixLength = parentPath.length();
+ this.nextResult = seek();
+ }
+ }
+
+ /** Returns true if there is another Resource available */
+ public boolean hasNext() {
+ return nextResult != null;
+ }
+
+ /** Returns the next resource in the iterator */
+ public Resource next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+
+ Resource result = nextResult;
+ nextResult = seek();
+ return result;
+ }
+
+ /**
+ * Throws <code>UnsupportedOperationException</code> as this method is not
+ * supported by this implementation.
+ */
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Scans the entry path enumeration looking for the next entry being a
+ * direct child of the parent resource.
+ */
+ private Resource seek() {
+ while (entries.hasMoreElements()) {
+ String entry = entries.nextElement();
+
+ // require leading slash
+ if (!entry.startsWith("/")) {
+ entry = "/" + entry;
+ }
+
+ int slash = entry.indexOf('/', prefixLength);
+ if (slash < 0 || slash == entry.length() - 1) {
+ log.debug("seek: Using entry {}", entry);
+ return new BundleResource(bundle, entry);
+ }
+
+ log.debug("seek: Ignoring entry {}", entry);
+ }
+
+ // no more results
+ log.debug("seek: No more nodes, iterator exhausted");
+ return null;
+ }
+}
Added: incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/bundle/BundleResourceProvider.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/bundle/BundleResourceProvider.java?rev=601511&view=auto
==============================================================================
--- incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/bundle/BundleResourceProvider.java (added)
+++ incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/bundle/BundleResourceProvider.java Wed Dec 5 12:38:23 2007
@@ -0,0 +1,71 @@
+/*
+ * 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.jcr.resource.internal.helper.bundle;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.jcr.resource.internal.JcrResourceManager;
+import org.apache.sling.jcr.resource.internal.helper.ResourceProvider;
+import org.osgi.framework.Bundle;
+
+public class BundleResourceProvider implements ResourceProvider {
+
+ /** The bundle providing the resources */
+ private final Bundle bundle;
+
+ /** The root paths */
+ private final String[] roots;
+
+ /**
+ * 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(Bundle bundle, String rootList) {
+ this.bundle = bundle;
+
+ StringTokenizer pt = new StringTokenizer(rootList, ", \t\n\r\f");
+ List<String> prefixList = new ArrayList<String>();
+ while (pt.hasMoreTokens()) {
+ String prefix = pt.nextToken().trim();
+ if (prefix.length() > 0) {
+ prefixList.add(prefix);
+ }
+ }
+ this.roots = prefixList.toArray(new String[prefixList.size()]);
+ }
+
+ /** Returns the root paths */
+ public String[] getRoots() {
+ return roots;
+ }
+
+ /**
+ * Returns a BundleResource for the path if such an entry exists in the
+ * bundle of this provider. The JcrResourceManager is ignored by this
+ * implementation.
+ */
+ public Resource getResource(JcrResourceManager jrm, String path) {
+ return BundleResource.getResource(bundle, path);
+ }
+
+}
Added: incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/bundle/BundleResourceURLConnection.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/bundle/BundleResourceURLConnection.java?rev=601511&view=auto
==============================================================================
--- incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/bundle/BundleResourceURLConnection.java (added)
+++ incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/bundle/BundleResourceURLConnection.java Wed Dec 5 12:38:23 2007
@@ -0,0 +1,109 @@
+/*
+ * 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.jcr.resource.internal.helper.bundle;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import org.osgi.framework.Bundle;
+
+/**
+ * A Bundle based <code>UIRLConnection</code> which uses the bundle's last
+ * modification time as the last modification time of the URL in contrast to the
+ * (Apache Felix) URLConnection used for the bundle entry, which always returns
+ * zero.
+ */
+public class BundleResourceURLConnection extends URLConnection {
+
+ /** The bundle owning the resource underlying the URLConnection */
+ private Bundle bundle;
+
+ /** The original URLConnection */
+ URLConnection delegatee;
+
+ protected BundleResourceURLConnection(Bundle bundle, URL url) {
+ super(url);
+
+ this.bundle = bundle;
+ }
+
+ /**
+ * Connects this URLConnection to access the data and metadata such as the
+ * content length, last modification time and content type.
+ */
+ public synchronized void connect() throws IOException {
+ if (!connected) {
+ String path = url.getPath();
+ URL url = bundle.getEntry(getURL().getPath());
+ if (url == null) {
+ throw new IOException("Cannot find entry " + path
+ + " in bundle " + bundle);
+ }
+
+ delegatee = url.openConnection();
+
+ connected = true;
+ }
+ }
+
+ /** Returns the input stream of the Bundle provided URLConnection */
+ public InputStream getInputStream() throws IOException {
+ connect();
+
+ return delegatee.getInputStream();
+ }
+
+ /** Returns the content length of the Bundle provided URLConnection */
+ public int getContentLength() {
+ try {
+ connect();
+ } catch (IOException ex) {
+ return -1;
+ }
+
+ return delegatee.getContentLength();
+ }
+
+ /**
+ * Returns the last modification time of the underlying bundle, which is the
+ * last time the bundle was installed or updated
+ */
+ public long getLastModified() {
+ try {
+ connect();
+ } catch (IOException ex) {
+ return 0;
+ }
+
+ return bundle.getLastModified();
+ }
+
+ /** Returns the content type of the Bundle provided URLConnection */
+ public String getContentType() {
+ try {
+ connect();
+ } catch (IOException ex) {
+ return null;
+ }
+
+ return delegatee.getContentType();
+ }
+
+}
Added: incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/bundle/BundleResourceURLStreamHandler.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/bundle/BundleResourceURLStreamHandler.java?rev=601511&view=auto
==============================================================================
--- incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/bundle/BundleResourceURLStreamHandler.java (added)
+++ incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/bundle/BundleResourceURLStreamHandler.java Wed Dec 5 12:38:23 2007
@@ -0,0 +1,48 @@
+/*
+ * 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.jcr.resource.internal.helper.bundle;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+
+import org.osgi.framework.Bundle;
+
+class BundleResourceURLStreamHandler extends URLStreamHandler {
+
+ static final String PROTOCOL = "bundle";
+
+ private final Bundle bundle;
+
+ BundleResourceURLStreamHandler(Bundle bundle) {
+ this.bundle = bundle;
+ }
+
+ @Override
+ protected URLConnection openConnection(URL u) throws IOException {
+ if (!PROTOCOL.equals(u.getProtocol())) {
+ throw new IOException("Cannot open connection to " + u
+ + ", wrong protocol");
+ }
+
+ return new BundleResourceURLConnection(bundle, u);
+ }
+
+}
Copied: incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResource.java (from r600523, incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/JcrNodeResource.java)
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResource.java?p2=incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResource.java&p1=incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/JcrNodeResource.java&r1=600523&r2=601511&rev=601511&view=diff
==============================================================================
--- incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/JcrNodeResource.java (original)
+++ incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResource.java Wed Dec 5 12:38:23 2007
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.sling.jcr.resource.internal.helper;
+package org.apache.sling.jcr.resource.internal.helper.jcr;
import static org.apache.jackrabbit.JcrConstants.JCR_CONTENT;
import static org.apache.jackrabbit.JcrConstants.JCR_CREATED;
@@ -30,20 +30,17 @@
import static org.apache.sling.api.resource.ResourceMetadata.RESOLUTION_PATH;
import static org.apache.sling.jcr.resource.JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY;
-import java.io.IOException;
import java.io.InputStream;
-import java.net.MalformedURLException;
import java.net.URL;
import java.util.Iterator;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
import org.apache.jackrabbit.net.URLFactory;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceMetadata;
import org.apache.sling.jcr.resource.internal.JcrResourceManager;
+import org.apache.sling.jcr.resource.internal.helper.Descendable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -72,14 +69,13 @@
private final ResourceMetadata metadata;
- public JcrNodeResource(JcrResourceManager cMgr, Session s, String path,
- Class<?> type) throws RepositoryException {
+ public JcrNodeResource(JcrResourceManager cMgr, String path)
+ throws RepositoryException {
this.resourceManager = cMgr;
- node = (Node) s.getItem(path);
+ node = (Node) cMgr.getSession().getItem(path);
this.path = node.getPath();
metadata = new ResourceMetadata();
resourceType = getResourceTypeForNode(node);
- objectType = type;
// check for nt:file metadata
setMetaData(node, metadata);
@@ -137,7 +133,7 @@
Node getNode() {
return node;
}
-
+
// ---------- internal -----------------------------------------------------
/**
@@ -178,7 +174,7 @@
} catch (Exception ex) {
log.error("getURL: Cannot create URL for " + this, ex);
}
-
+
return null;
}
@@ -203,6 +199,10 @@
+ path, re);
return null;
}
+ }
+
+ public void setObjectType(Class<?> objectType) {
+ this.objectType = objectType;
}
/**
Copied: incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResourceIterator.java (from r600457, incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/JcrNodeResourceIterator.java)
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResourceIterator.java?p2=incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResourceIterator.java&p1=incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/JcrNodeResourceIterator.java&r1=600457&r2=601511&rev=601511&view=diff
==============================================================================
--- incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/JcrNodeResourceIterator.java (original)
+++ incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResourceIterator.java Wed Dec 5 12:38:23 2007
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.sling.jcr.resource.internal.helper;
+package org.apache.sling.jcr.resource.internal.helper.jcr;
import java.util.Iterator;
import java.util.NoSuchElementException;
Modified: incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/JcrNodeResourceIteratorTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/JcrNodeResourceIteratorTest.java?rev=601511&r1=601510&r2=601511&view=diff
==============================================================================
--- incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/JcrNodeResourceIteratorTest.java (original)
+++ incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/JcrNodeResourceIteratorTest.java Wed Dec 5 12:38:23 2007
@@ -27,6 +27,7 @@
import junit.framework.TestCase;
import org.apache.sling.api.resource.Resource;
+import org.apache.sling.jcr.resource.internal.helper.jcr.JcrNodeResourceIterator;
import org.apache.sling.jcr.resource.testhelper.MockNode;
import org.apache.sling.jcr.resource.testhelper.MockNodeIterator;
Added: incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntryTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntryTest.java?rev=601511&view=auto
==============================================================================
--- incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntryTest.java (added)
+++ incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntryTest.java Wed Dec 5 12:38:23 2007
@@ -0,0 +1,169 @@
+/*
+ * 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.jcr.resource.internal.helper;
+
+import junit.framework.TestCase;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.jcr.resource.internal.JcrResourceManager;
+import org.apache.sling.jcr.resource.internal.helper.ResourceProvider;
+import org.apache.sling.jcr.resource.internal.helper.ResourceProviderEntry;
+
+public class ResourceProviderEntryTest extends TestCase {
+
+ private ResourceProvider rootProvider;
+
+ private ResourceProviderEntry root;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ rootProvider = new TestResourceProvider("/");
+ root = new ResourceProviderEntry("/", rootProvider);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testRootProvider() {
+ assertNull(root.getResourceProvider("relpath"));
+ assertEquals(rootProvider, root.getResourceProvider("/"));
+ assertEquals(rootProvider, root.getResourceProvider("/rootel"));
+ assertEquals(rootProvider, root.getResourceProvider("/rootel/child"));
+ assertEquals(rootProvider,
+ root.getResourceProvider("/apps/sling/sample/html.js"));
+ assertEquals(rootProvider,
+ root.getResourceProvider("/apps/sling/microsling/html.js"));
+ }
+
+ public void testAdd1Provider() {
+ String firstPath = "/rootel";
+ ResourceProvider first = new TestResourceProvider(firstPath);
+ root.addResourceProvider(first);
+
+ assertEquals(rootProvider, root.getResourceProvider("/"));
+ assertEquals(first, root.getResourceProvider("/rootel"));
+ assertEquals(first, root.getResourceProvider("/rootel/html.js"));
+ assertEquals(first, root.getResourceProvider("/rootel/child"));
+ assertEquals(first, root.getResourceProvider("/rootel/child/html.js"));
+ assertEquals(rootProvider,
+ root.getResourceProvider("/apps/sling/sample/html.js"));
+ assertEquals(rootProvider,
+ root.getResourceProvider("/apps/sling/microsling/html.js"));
+ }
+
+ public void testAdd3Providers() {
+ String firstPath = "/rootel";
+ String thirdPath = "/apps/sling/sample";
+ String secondPath = firstPath + "/child";
+
+ ResourceProvider first = new TestResourceProvider(firstPath);
+ ResourceProvider second = new TestResourceProvider(secondPath);
+ ResourceProvider third = new TestResourceProvider(thirdPath);
+
+ root.addResourceProvider(first);
+ root.addResourceProvider(second);
+ root.addResourceProvider(third);
+
+ assertEquals(rootProvider, root.getResourceProvider("/"));
+ assertEquals(first, root.getResourceProvider("/rootel"));
+ assertEquals(first, root.getResourceProvider("/rootel/html.js"));
+ assertEquals(second, root.getResourceProvider("/rootel/child"));
+ assertEquals(second, root.getResourceProvider("/rootel/child/html.js"));
+ assertEquals(third,
+ root.getResourceProvider("/apps/sling/sample/html.js"));
+ assertEquals(rootProvider,
+ root.getResourceProvider("/apps/sling/microsling/html.js"));
+ }
+
+ public void testAdd3ProvidersReverse() {
+ String firstPath = "/rootel";
+ String thirdPath = "/apps/sling/sample";
+ String secondPath = firstPath + "/child";
+
+ ResourceProvider first = new TestResourceProvider(firstPath);
+ ResourceProvider second = new TestResourceProvider(secondPath);
+ ResourceProvider third = new TestResourceProvider(thirdPath);
+
+ root.addResourceProvider(third);
+ root.addResourceProvider(second);
+ root.addResourceProvider(first);
+
+ assertEquals(rootProvider, root.getResourceProvider("/"));
+ assertEquals(first, root.getResourceProvider("/rootel"));
+ assertEquals(first, root.getResourceProvider("/rootel/html.js"));
+ assertEquals(second, root.getResourceProvider("/rootel/child"));
+ assertEquals(second, root.getResourceProvider("/rootel/child/html.js"));
+ assertEquals(third,
+ root.getResourceProvider("/apps/sling/sample/html.js"));
+ assertEquals(rootProvider,
+ root.getResourceProvider("/apps/sling/microsling/html.js"));
+ }
+
+ public void testRemoveProviders() {
+ String firstPath = "/rootel";
+ String thirdPath = "/apps/sling/sample";
+ String secondPath = firstPath + "/child";
+
+ ResourceProvider first = new TestResourceProvider(firstPath);
+ ResourceProvider second = new TestResourceProvider(secondPath);
+ ResourceProvider third = new TestResourceProvider(thirdPath);
+
+ root.addResourceProvider(first);
+ root.addResourceProvider(second);
+ root.addResourceProvider(third);
+
+ assertEquals(rootProvider, root.getResourceProvider("/"));
+ assertEquals(first, root.getResourceProvider("/rootel/html.js"));
+ assertEquals(second, root.getResourceProvider("/rootel/child/html.js"));
+
+ root.removeResourceProvider(first);
+
+ assertEquals(rootProvider, root.getResourceProvider("/"));
+ assertEquals(rootProvider, root.getResourceProvider("/rootel/html.js"));
+ assertEquals(second, root.getResourceProvider("/rootel/child/html.js"));
+
+ root.addResourceProvider(first);
+
+ assertEquals(rootProvider, root.getResourceProvider("/"));
+ assertEquals(first, root.getResourceProvider("/rootel/html.js"));
+ assertEquals(second, root.getResourceProvider("/rootel/child/html.js"));
+ }
+
+ private static class TestResourceProvider implements ResourceProvider {
+
+ private final String[] roots;
+
+ TestResourceProvider(String root) {
+ roots = new String[] { root };
+ }
+
+ public Resource getResource(JcrResourceManager jcrResourceManager, String path) {
+ return null;
+ }
+
+ public String[] getRoots() {
+ return roots;
+ }
+
+ }
+}