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 2012/07/12 17:11:06 UTC
svn commit: r1360715 - in /sling/trunk/bundles:
api/src/main/java/org/apache/sling/api/resource/
jcr/resource/src/main/java/org/apache/sling/jcr/resource/
jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/
jcr/resource/src/te...
Author: cziegeler
Date: Thu Jul 12 15:11:06 2012
New Revision: 1360715
URL: http://svn.apache.org/viewvc?rev=1360715&view=rev
Log:
SLING-2530 : Implement CRUD based on resources (WiP)
Added:
sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/ModifyingResourceProvider.java (with props)
Modified:
sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/AbstractResource.java
sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/QueriableResourceProvider.java
sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/Resource.java
sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/ResourceResolver.java
sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/ResourceWrapper.java
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceUtil.java
sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProvider.java
sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrResourceListenerTest.java
sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/jcr/MockResourceResolver.java
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceIterator.java
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverContext.java
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/tree/ProviderHandler.java
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderEntry.java
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderHandler.java
sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/tree/ProviderHandlerTest.java
sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderEntryTest.java
Modified: sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/AbstractResource.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/AbstractResource.java?rev=1360715&r1=1360714&r2=1360715&view=diff
==============================================================================
--- sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/AbstractResource.java (original)
+++ sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/AbstractResource.java Thu Jul 12 15:11:06 2012
@@ -114,4 +114,32 @@ public abstract class AbstractResource
//
return ResourceUtil.isA(this, resourceType);
}
+
+ /**
+ * @see org.apache.sling.api.resource.Resource#isModifiable()
+ */
+ public boolean isModifiable() {
+ return false;
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.Resource#remove()
+ */
+ public void remove() {
+ this.getResourceResolver().delete(this);
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.Resource#update(org.apache.sling.api.resource.ValueMap)
+ */
+ public void update(final ValueMap properties) {
+ this.getResourceResolver().update(this, properties);
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.Resource#addChild(java.lang.String, org.apache.sling.api.resource.ValueMap)
+ */
+ public Resource addChild(final String name, final ValueMap properties) {
+ return this.getResourceResolver().addChild(this, name, properties);
+ }
}
Added: sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/ModifyingResourceProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/ModifyingResourceProvider.java?rev=1360715&view=auto
==============================================================================
--- sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/ModifyingResourceProvider.java (added)
+++ sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/ModifyingResourceProvider.java Thu Jul 12 15:11:06 2012
@@ -0,0 +1,49 @@
+/*
+ * 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.api.resource;
+
+
+
+/**
+ * A modifying resource provider is an extension of a resource provider which
+ * is only supported if the resource provider has been created through
+ * a {@link ResourceProviderFactory}.
+ *
+ * A modifying resource provider allows to create, update, and delete
+ * resources.
+ *
+ * TODO - Exception handling, return values
+ *
+ * @see ResourceProviderFactory#getResourceProvider(java.util.Map)
+ * @see ResourceProviderFactory#getAdministrativeResourceProvider(java.util.Map)
+ *
+ * @since 2.2.0
+ */
+public interface ModifyingResourceProvider {
+
+ Resource create(ResourceResolver resolver, String path, ValueMap properties);
+
+ boolean delete(ResourceResolver resolver, String path);
+
+ void update(ResourceResolver resolver, String path, ValueMap properties);
+
+ void revert();
+
+ void commit();
+}
Propchange: sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/ModifyingResourceProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/ModifyingResourceProvider.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Propchange: sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/ModifyingResourceProvider.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/QueriableResourceProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/QueriableResourceProvider.java?rev=1360715&r1=1360714&r2=1360715&view=diff
==============================================================================
--- sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/QueriableResourceProvider.java (original)
+++ sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/QueriableResourceProvider.java Thu Jul 12 15:11:06 2012
@@ -30,6 +30,7 @@ import java.util.Map;
* returned through a {@link ResourceProviderFactory}.
*
* TODO - what should the resource provider do, if the language is not supported?
+ * TODO - is returning null allowed?
*
* @since 2.2.0
*/
Modified: sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/Resource.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/Resource.java?rev=1360715&r1=1360714&r2=1360715&view=diff
==============================================================================
--- sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/Resource.java (original)
+++ sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/Resource.java Thu Jul 12 15:11:06 2012
@@ -140,4 +140,27 @@ public interface Resource extends Adapta
* retrieved.
*/
ResourceResolver getResourceResolver();
+
+ /**
+ * @since 2.2.0
+ */
+ boolean isModifiable();
+
+ /**
+ * @since 2.2.0
+ * @throws UnsupportedOperationException
+ */
+ void remove();
+
+ /**
+ * @since 2.2.0
+ * @throws UnsupportedOperationException
+ */
+ void update(final ValueMap properties);
+
+ /**
+ * @since 2.2.0
+ * @throws UnsupportedOperationException
+ */
+ Resource addChild(final String name, final ValueMap properties);
}
Modified: sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/ResourceResolver.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/ResourceResolver.java?rev=1360715&r1=1360714&r2=1360715&view=diff
==============================================================================
--- sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/ResourceResolver.java (original)
+++ sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/ResourceResolver.java Thu Jul 12 15:11:06 2012
@@ -500,4 +500,14 @@ public interface ResourceResolver extend
* {@link #close() closed}.
*/
Object getAttribute(String name);
+
+ boolean delete(Resource resource);
+
+ Resource addChild(Resource parent, String name, ValueMap properties);
+
+ void update(Resource resource, ValueMap properties);
+
+ void revert();
+
+ void commit();
}
Modified: sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/ResourceWrapper.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/ResourceWrapper.java?rev=1360715&r1=1360714&r2=1360715&view=diff
==============================================================================
--- sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/ResourceWrapper.java (original)
+++ sling/trunk/bundles/api/src/main/java/org/apache/sling/api/resource/ResourceWrapper.java Thu Jul 12 15:11:06 2012
@@ -35,7 +35,7 @@ public class ResourceWrapper implements
* Creates a new wrapper instance delegating all method calls to the given
* <code>resource</code>.
*/
- public ResourceWrapper(Resource resource) {
+ public ResourceWrapper(final Resource resource) {
this.resource = resource;
}
@@ -158,4 +158,31 @@ public class ResourceWrapper implements
+ ", path=" + getPath() + ", resource=[" + getResource() + "]";
}
+ /**
+ * @see org.apache.sling.api.resource.Resource#isModifiable()
+ */
+ public boolean isModifiable() {
+ return getResource().isModifiable();
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.Resource#remove()
+ */
+ public void remove() {
+ getResource().remove();
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.Resource#update(org.apache.sling.api.resource.ValueMap)
+ */
+ public void update(final ValueMap properties) {
+ getResource().update(properties);
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.Resource#addChild(java.lang.String, org.apache.sling.api.resource.ValueMap)
+ */
+ public Resource addChild(final String name, final ValueMap properties) {
+ return getResource().addChild(name, properties);
+ }
}
Modified: sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceUtil.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceUtil.java?rev=1360715&r1=1360714&r2=1360715&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceUtil.java (original)
+++ sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceUtil.java Thu Jul 12 15:11:06 2012
@@ -19,6 +19,7 @@
package org.apache.sling.jcr.resource;
import java.io.InputStream;
+import java.math.BigDecimal;
import java.util.Calendar;
import java.util.StringTokenizer;
@@ -122,6 +123,8 @@ public class JcrResourceUtil {
val = fac.createValue(fac.createBinary((InputStream)value));
} else if (value instanceof Node) {
val = fac.createValue((Node)value);
+ } else if (value instanceof BigDecimal) {
+ val = fac.createValue((BigDecimal)value);
} else if (value instanceof Long) {
val = fac.createValue((Long)value);
} else if (value instanceof Number) {
Modified: sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProvider.java?rev=1360715&r1=1360714&r2=1360715&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProvider.java (original)
+++ sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProvider.java Thu Jul 12 15:11:06 2012
@@ -41,12 +41,14 @@ import org.apache.sling.api.SlingExcepti
import org.apache.sling.api.adapter.SlingAdaptable;
import org.apache.sling.api.resource.AttributableResourceProvider;
import org.apache.sling.api.resource.DynamicResourceProvider;
+import org.apache.sling.api.resource.ModifyingResourceProvider;
import org.apache.sling.api.resource.QueriableResourceProvider;
import org.apache.sling.api.resource.QuerySyntaxException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceProvider;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.jcr.resource.JcrResourceUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -62,7 +64,8 @@ public class JcrResourceProvider
implements ResourceProvider,
DynamicResourceProvider,
AttributableResourceProvider,
- QueriableResourceProvider {
+ QueriableResourceProvider,
+ ModifyingResourceProvider {
/** column name for node path */
private static final String QUERY_COLUMN_PATH = "jcr:path";
@@ -373,4 +376,90 @@ public class JcrResourceProvider
}
return super.adaptTo(type);
}
+
+ /**
+ * @see org.apache.sling.api.resource.ModifyingResourceProvider#create(ResourceResolver, java.lang.String, org.apache.sling.api.resource.ValueMap)
+ */
+ public Resource create(final ResourceResolver resolver, final String path, final ValueMap properties) {
+ // check for node type
+ final String nodeType = (properties != null ? properties.get("jcr:primaryType", String.class) : null);
+ try {
+ final Node node = JcrResourceUtil.createPath(path, null, nodeType, this.session, false);
+
+ // mixin types
+ final String[] mixinTypes = (properties != null ? properties.get("jcr:mixinTypes", String[].class) : null);
+ if ( mixinTypes != null ) {
+ for(final String mixin : mixinTypes ) {
+ if ( !node.isNodeType(mixin) ) {
+ node.addMixin(mixin);
+ }
+ }
+ }
+ this.update(node, properties);
+
+ return new JcrNodeResource(resolver, node, this.dynamicClassLoader);
+ } catch (final RepositoryException e) {
+ log.error("Unable to create node at " + path, e);
+ }
+ return null;
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.ModifyingResourceProvider#delete(ResourceResolver, java.lang.String)
+ */
+ public boolean delete(final ResourceResolver resolver, final String path) {
+ try {
+ if ( session.itemExists(path) ) {
+ session.getItem(path).remove();
+ return true;
+ }
+ } catch (final RepositoryException e) {
+ log.error("Unable to delete item at " + path, e);
+ }
+ return false;
+ }
+
+ private void update(final Node node, final ValueMap properties) throws RepositoryException {
+ for(final Map.Entry<String, Object> entry : properties.entrySet()) {
+ if ( !entry.getKey().equals("jcr:primaryType") && !entry.getKey().equals("jcr:mixinTypes") ) {
+ JcrResourceUtil.setProperty(node, entry.getKey(), entry.getValue());
+ }
+ }
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.ModifyingResourceProvider#update(org.apache.sling.api.resource.ResourceResolver, java.lang.String, org.apache.sling.api.resource.ValueMap)
+ */
+ public void update(final ResourceResolver resolver, final String path, final ValueMap properties) {
+ try {
+ final Node node = this.session.getNode(path);
+
+ this.update(node, properties);
+
+ } catch (final RepositoryException e) {
+ log.error("Unable to update node at " + path, e);
+ }
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.ModifyingResourceProvider#revert()
+ */
+ public void revert() {
+ try {
+ this.session.refresh(false);
+ } catch (final RepositoryException e) {
+ log.error("Unable to refresh session.", e);
+ }
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.ModifyingResourceProvider#commit()
+ */
+ public void commit() {
+ try {
+ this.session.save();
+ } catch (final RepositoryException e) {
+ log.error("Unable to commit changes to session.", e);
+ }
+ }
}
Modified: sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrResourceListenerTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrResourceListenerTest.java?rev=1360715&r1=1360714&r2=1360715&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrResourceListenerTest.java (original)
+++ sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrResourceListenerTest.java Thu Jul 12 15:11:06 2012
@@ -32,6 +32,7 @@ import org.apache.sling.api.resource.Log
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.commons.testing.jcr.EventHelper;
import org.apache.sling.commons.testing.jcr.RepositoryTestBase;
import org.apache.sling.jcr.resource.internal.helper.jcr.JcrNodeResource;
@@ -202,6 +203,30 @@ public class JcrResourceListenerTest ext
return null;
}
+ public boolean delete(Resource resource) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public Resource addChild(Resource parent, String name, ValueMap properties) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void update(Resource resource, ValueMap properties) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void revert() {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void commit() {
+ // TODO Auto-generated method stub
+
+ }
};
final ResourceResolverFactory factory = new ResourceResolverFactory() {
Modified: sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/jcr/MockResourceResolver.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/jcr/MockResourceResolver.java?rev=1360715&r1=1360714&r2=1360715&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/jcr/MockResourceResolver.java (original)
+++ sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/jcr/MockResourceResolver.java Thu Jul 12 15:11:06 2012
@@ -30,6 +30,7 @@ import javax.servlet.http.HttpServletReq
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ValueMap;
public class MockResourceResolver implements ResourceResolver {
@@ -125,4 +126,29 @@ public class MockResourceResolver implem
public Iterator<String> getAttributeNames() {
return Collections.<String> emptyList().iterator();
}
+
+ public boolean delete(Resource resource) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public Resource addChild(Resource parent, String name, ValueMap properties) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void update(Resource resource, ValueMap properties) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void revert() {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void commit() {
+ // TODO Auto-generated method stub
+
+ }
}
Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java?rev=1360715&r1=1360714&r2=1360715&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java Thu Jul 12 15:11:06 2012
@@ -37,6 +37,7 @@ import org.apache.sling.adapter.annotati
import org.apache.sling.api.SlingException;
import org.apache.sling.api.adapter.SlingAdaptable;
import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.api.resource.ModifyingResourceProvider;
import org.apache.sling.api.resource.NonExistingResource;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceNotFoundException;
@@ -994,4 +995,51 @@ public class ResourceResolverImpl extend
return absPath;
}
+
+ /**
+ * @see org.apache.sling.api.resource.ResourceResolver#delete(org.apache.sling.api.resource.Resource)
+ */
+ public boolean delete(final Resource resource) {
+ final String path = resource.getPath();
+ final ModifyingResourceProvider mrp = this.factory.getRootProviderEntry().getModifyingProvider(this.context,
+ this,
+ path);
+ return mrp.delete(this, path);
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.ResourceResolver#addChild(org.apache.sling.api.resource.Resource, java.lang.String, org.apache.sling.api.resource.ValueMap)
+ */
+ public Resource addChild(final Resource parent, final String name, final ValueMap properties) {
+ final String path = parent.getPath() + '/' + name;
+ final ModifyingResourceProvider mrp = this.factory.getRootProviderEntry().getModifyingProvider(this.context,
+ this,
+ path);
+ return mrp.create(this, path, properties);
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.ResourceResolver#update(org.apache.sling.api.resource.Resource, org.apache.sling.api.resource.ValueMap)
+ */
+ public void update(final Resource resource, final ValueMap properties) {
+ final String path = resource.getPath();
+ final ModifyingResourceProvider mrp = this.factory.getRootProviderEntry().getModifyingProvider(this.context,
+ this,
+ path);
+ mrp.update(this, path, properties);
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.ResourceResolver#revert()
+ */
+ public void revert() {
+ this.context.revert();
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.ResourceResolver#commit()
+ */
+ public void commit() {
+ this.context.commit();
+ }
}
Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceIterator.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceIterator.java?rev=1360715&r1=1360714&r2=1360715&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceIterator.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceIterator.java Thu Jul 12 15:11:06 2012
@@ -276,7 +276,7 @@ public class ResourceIterator implements
final Set<ProviderHandler> providers) {
// collect providers along the ancestor path segements
- final String[] elements = ResourceProviderEntry.split(path, '/');
+ final String[] elements = ResourceProviderEntry.split(path);
ResourceProviderEntry base = rootProviderEntry;
for (final String element : elements) {
if (base.containsKey(element)) {
Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverContext.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverContext.java?rev=1360715&r1=1360714&r2=1360715&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverContext.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverContext.java Thu Jul 12 15:11:06 2012
@@ -23,6 +23,7 @@ import java.util.Map;
import java.util.Set;
import org.apache.sling.api.resource.DynamicResourceProvider;
+import org.apache.sling.api.resource.ModifyingResourceProvider;
import org.apache.sling.api.resource.ResourceProvider;
/**
@@ -38,6 +39,9 @@ public class ResourceResolverContext {
/** A set of all dynamic providers (for closing them later on) */
private final Set<DynamicResourceProvider> dynamicProviders = new HashSet<DynamicResourceProvider>();
+ /** A set of all modifying providers */
+ private final Set<ModifyingResourceProvider> modifyingProviders = new HashSet<ModifyingResourceProvider>();
+
/** Is this a resource resolver for an admin? */
private final boolean isAdmin;
@@ -78,6 +82,9 @@ public class ResourceResolverContext {
if (provider instanceof DynamicResourceProvider) {
this.dynamicProviders.add((DynamicResourceProvider) provider);
}
+ if (provider instanceof ModifyingResourceProvider) {
+ this.modifyingProviders.add((ModifyingResourceProvider) provider);
+ }
}
/**
@@ -113,4 +120,22 @@ public class ResourceResolverContext {
this.dynamicProviders.clear();
this.providers.clear();
}
+
+ /**
+ * Revert all transient changes.
+ */
+ public void revert() {
+ for(final ModifyingResourceProvider provider : this.modifyingProviders) {
+ provider.revert();
+ }
+ }
+
+ /**
+ * Commit all transient changes
+ */
+ public void commit() {
+ for(final ModifyingResourceProvider provider : this.modifyingProviders) {
+ provider.commit();
+ }
+ }
}
Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/tree/ProviderHandler.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/tree/ProviderHandler.java?rev=1360715&r1=1360714&r2=1360715&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/tree/ProviderHandler.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/tree/ProviderHandler.java Thu Jul 12 15:11:06 2012
@@ -142,6 +142,8 @@ public abstract class ProviderHandler im
*/
public abstract Iterator<Resource> listChildren(final ResourceResolverContext ctx, final Resource parent);
+ public abstract ResourceProvider getResourceProvider(final ResourceResolverContext ctx);
+
/**
* Return a name of the resource provider/factory.
*/
Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderEntry.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderEntry.java?rev=1360715&r1=1360714&r2=1360715&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderEntry.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderEntry.java Thu Jul 12 15:11:06 2012
@@ -27,6 +27,7 @@ import java.util.List;
import java.util.Set;
import org.apache.commons.collections.FastTreeMap;
+import org.apache.sling.api.resource.ModifyingResourceProvider;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceProvider;
import org.apache.sling.api.resource.ResourceResolver;
@@ -116,32 +117,12 @@ public class ResourceProviderEntry imple
* @throws org.apache.sling.api.SlingException
* if an error occurrs trying to access an existing resource.
*/
- public Resource getResource(final ResourceResolverContext ctx, final ResourceResolver resourceResolver, final String path) {
+ public Resource getResource(final ResourceResolverContext ctx,
+ final ResourceResolver resourceResolver,
+ final String path) {
return getInternalResource(ctx, resourceResolver, path);
}
- /**
- * Adds the given resource provider into the tree for the given prefix.
- *
- * @return <code>true</code> if the provider could be entered into the
- * subtree below this entry. Otherwise <code>false</code> is
- * returned.
- */
- public synchronized boolean addResourceProvider(final String prefix, final ProviderHandler provider) {
- final String[] elements = split(prefix, '/');
- final List<ResourceProviderEntry> entryPath = new ArrayList<ResourceProviderEntry>();
- entryPath.add(this); // add this the start so if the list is empty
- // we have a position to add to
- populateProviderPath(entryPath, elements);
- for (int i = entryPath.size() - 1; i < elements.length; i++) {
- final String stubPrefix = elements[i];
- final ResourceProviderEntry rpe2 = new ResourceProviderEntry(stubPrefix, new ProviderHandler[0]);
- entryPath.get(i).put(stubPrefix, rpe2);
- entryPath.add(rpe2);
- }
- return entryPath.get(elements.length).addInternalProvider(provider);
- }
-
// ------------------ Map methods, here so that we can delegate 2 maps
// together
@SuppressWarnings("unchecked")
@@ -164,19 +145,9 @@ public class ResourceProviderEntry imple
return storageMapValues;
}
- public synchronized boolean removeResourceProvider(final String prefix, final ProviderHandler resourceProvider) {
- final String[] elements = split(prefix, '/');
- final List<ResourceProviderEntry> entryPath = new ArrayList<ResourceProviderEntry>();
- populateProviderPath(entryPath, elements);
- if (entryPath.size() > 0 && entryPath.size() == elements.length) {
- // the last element is a perfect match;
- return entryPath.get(entryPath.size() - 1).removeInternalProvider(resourceProvider);
- }
- return false;
- }
-
- // ---------- Comparable<ResourceProviderEntry> interface ------------------
-
+ /**
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
public int compareTo(final ResourceProviderEntry o) {
return prefix.compareTo(o.prefix);
}
@@ -191,9 +162,8 @@ public class ResourceProviderEntry imple
private boolean addInternalProvider(final ProviderHandler provider) {
final int before = providers.length;
final Set<ProviderHandler> set = new HashSet<ProviderHandler>();
- if (providers != null) {
- set.addAll(Arrays.asList(providers));
- }
+ set.addAll(Arrays.asList(providers));
+
LOGGER.debug("Adding provider {} at {} ", provider, path);
set.add(provider);
providers = conditionalSort(set);
@@ -208,15 +178,54 @@ public class ResourceProviderEntry imple
private boolean removeInternalProvider(final ProviderHandler provider) {
final int before = providers.length;
final Set<ProviderHandler> set = new HashSet<ProviderHandler>();
- if (providers != null) {
- set.addAll(Arrays.asList(providers));
- }
+ set.addAll(Arrays.asList(providers));
+
+ LOGGER.debug("Removing provider {} at {} ", provider, path);
set.remove(provider);
providers = conditionalSort(set);
return providers.length < before;
}
/**
+ * Adds the given resource provider into the tree for the given prefix.
+ *
+ * @return <code>true</code> if the provider could be entered into the
+ * subtree below this entry. Otherwise <code>false</code> is
+ * returned.
+ */
+ protected synchronized boolean addResourceProvider(final String prefix, final ProviderHandler provider) {
+ final String[] elements = split(prefix);
+ final List<ResourceProviderEntry> entries = new ArrayList<ResourceProviderEntry>();
+ this.populateProviderPath(entries, elements);
+
+ // add this=root to the start so if the list is empty
+ // we have a position to add to
+ entries.add(0, this);
+ for (int i = entries.size() - 1; i < elements.length; i++) {
+ final String stubPrefix = elements[i];
+ final ResourceProviderEntry rpe2 = new ResourceProviderEntry(stubPrefix, new ProviderHandler[0]);
+ entries.get(i).put(stubPrefix, rpe2);
+ entries.add(rpe2);
+ }
+ return entries.get(elements.length).addInternalProvider(provider);
+ }
+
+ /**
+ * Remove the given resource provider from the tree
+ */
+ protected synchronized boolean removeResourceProvider(final String prefix, final ProviderHandler resourceProvider) {
+ final String[] elements = split(prefix);
+ final List<ResourceProviderEntry> entries = new ArrayList<ResourceProviderEntry>();
+ this.populateProviderPath(entries, elements);
+
+ if (entries.size() > 0 && entries.size() == elements.length) {
+ // the last element is a perfect match;
+ return entries.get(entries.size() - 1).removeInternalProvider(resourceProvider);
+ }
+ return false;
+ }
+
+ /**
* Return a sorted array of handlers.
*/
private ProviderHandler[] conditionalSort(final Set<ProviderHandler> set) {
@@ -229,23 +238,19 @@ public class ResourceProviderEntry imple
}
/**
- * Get a of ResourceProvidersEntries leading to the fullPath in reverse
- * order.
- *
- * @param fullPath
- * the full path
+ * Get a list of resource provider entries in reverse order.
+ * @param entries List to add the entries to
+ * @param elements The path already split into segments.
*/
- private void populateProviderPath(final List<ResourceProviderEntry> providerEntryPath, final String[] elements) {
+ private void populateProviderPath(final List<ResourceProviderEntry> entries, final String[] elements) {
ResourceProviderEntry base = this;
- if (elements != null) {
- for (final String element : elements) {
- if (element != null) {
- if (base.containsKey(element)) {
- base = base.get(element);
- providerEntryPath.add(base);
- } else {
- break;
- }
+ for (final String element : elements) {
+ if (element != null) {
+ if (base.containsKey(element)) {
+ base = base.get(element);
+ entries.add(base);
+ } else {
+ break;
}
}
}
@@ -254,28 +259,27 @@ public class ResourceProviderEntry imple
/**
* Resolve a resource from a path into a Resource
*
- * @param resolver
- * the ResourceResolver.
- * @param fullPath
- * the Full path
+ * @param ctx The resource resolver context
+ * @param resourceResolver the ResourceResolver.
+ * @param fullPath the Full path
* @return null if no resource was found, a resource if one was found.
*/
- private Resource getInternalResource(final ResourceResolverContext ctx, final ResourceResolver resourceResolver, final String fullPath) {
- final long start = System.currentTimeMillis();
+ private Resource getInternalResource(final ResourceResolverContext ctx,
+ final ResourceResolver resourceResolver,
+ final String fullPath) {
try {
if (fullPath == null || fullPath.length() == 0 || fullPath.charAt(0) != '/') {
- LOGGER.debug("Not absolute {} :{}", fullPath, (System.currentTimeMillis() - start));
+ LOGGER.debug("Not absolute {}", fullPath);
return null; // fullpath must be absolute
}
- final String[] elements = split(fullPath, '/');
+ final String[] elements = split(fullPath);
+ final List<ResourceProviderEntry> entries = new ArrayList<ResourceProviderEntry>();
+ this.populateProviderPath(entries, elements);
- final List<ResourceProviderEntry> list = new ArrayList<ResourceProviderEntry>();
- populateProviderPath(list, elements);
// the path is in reverse order end first
-
- for (int i = list.size() - 1; i >= 0; i--) {
- final ProviderHandler[] rps = list.get(i).getResourceProviders();
+ for (int i = entries.size() - 1; i >= 0; i--) {
+ final ProviderHandler[] rps = entries.get(i).getResourceProviders();
for (final ProviderHandler rp : rps) {
final Resource resource = rp.getResource(ctx, resourceResolver, fullPath);
@@ -284,6 +288,7 @@ public class ResourceProviderEntry imple
return resource;
}
}
+ // TODO stop handling if provider claims subtree!
}
// resolve against this one
@@ -296,8 +301,8 @@ public class ResourceProviderEntry imple
// resource Provider: libs/sling/servlet/default/GET.servlet
// list will match libs, sling, servlet, default
// and there will be no resource provider at the end
- if (list.size() > 0 && list.size() == elements.length) {
- if (list.get(list.size() - 1).getResourceProviders().length == 0) {
+ if (entries.size() > 0 && entries.size() == elements.length) {
+ if (entries.get(entries.size() - 1).getResourceProviders().length == 0) {
LOGGER.debug("Resolved Synthetic {}", fullPath);
return new SyntheticResource(resourceResolver, fullPath, ResourceProvider.RESOURCE_TYPE_SYNTHETIC);
}
@@ -311,7 +316,8 @@ public class ResourceProviderEntry imple
}
}
- public Resource getResourceFromProviders(final ResourceResolverContext ctx, final ResourceResolver resourceResolver, final String fullPath) {
+ public Resource getResourceFromProviders(final ResourceResolverContext ctx,
+ final ResourceResolver resourceResolver, final String fullPath) {
final ProviderHandler[] rps = getResourceProviders();
for (final ProviderHandler rp : rps) {
final Resource resource = rp.getResource(ctx, resourceResolver, fullPath);
@@ -323,32 +329,56 @@ public class ResourceProviderEntry imple
return null;
}
+ public ModifyingResourceProvider getModifyingProvider(final ResourceResolverContext ctx,
+ final ResourceResolver resourceResolver,
+ final String fullPath) {
+ final String[] elements = split(fullPath);
+ final List<ResourceProviderEntry> entries = new ArrayList<ResourceProviderEntry>();
+ this.populateProviderPath(entries, elements);
+
+ for (int i = entries.size() - 1; i >= 0; i--) {
+ final ProviderHandler[] rps = entries.get(i).getResourceProviders();
+ for (final ProviderHandler rp : rps) {
+ final ResourceProvider provider = rp.getResourceProvider(ctx);
+ if ( provider instanceof ModifyingResourceProvider ) {
+ return (ModifyingResourceProvider) provider;
+ }
+ }
+ // TODO stop handling if provider claims subtree!
+ }
+ throw new UnsupportedOperationException();
+ }
+
+ private static final char SPLIT_SEP = '/';
+ private static final String[] EMPTY_RESULT = new String[0];
+
/**
- * @param st
- * @param sep
+ * Split the string by slash.
+ * This method never returns null.
+ * @param st The string to split
* @return an array of the strings between the separator
*/
- public static String[] split(final String st, final char sep) {
+ public static String[] split(final String st) {
if (st == null) {
- return new String[0];
+ return EMPTY_RESULT;
}
final char[] pn = st.toCharArray();
if (pn.length == 0) {
- return new String[0];
+ return EMPTY_RESULT;
}
- if (pn.length == 1 && pn[0] == sep) {
- return new String[0];
+ if (pn.length == 1 && pn[0] == SPLIT_SEP) {
+ return EMPTY_RESULT;
}
int n = 1;
int start = 0;
int end = pn.length;
- while (start < end && sep == pn[start])
+ while (start < end && SPLIT_SEP == pn[start])
start++;
- while (start < end && sep == pn[end - 1])
+ while (start < end && SPLIT_SEP == pn[end - 1])
end--;
for (int i = start; i < end; i++) {
- if (sep == pn[i]) {
+ if (SPLIT_SEP == pn[i]) {
n++;
}
}
@@ -356,7 +386,7 @@ public class ResourceProviderEntry imple
int s = start;
int j = 0;
for (int i = start; i < end; i++) {
- if (pn[i] == sep) {
+ if (pn[i] == SPLIT_SEP) {
e[j++] = new String(pn, s, i - s);
s = i + 1;
}
Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderHandler.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderHandler.java?rev=1360715&r1=1360714&r2=1360715&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderHandler.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderHandler.java Thu Jul 12 15:11:06 2012
@@ -65,6 +65,13 @@ public class ResourceProviderHandler ext
}
/**
+ * @see org.apache.sling.resourceresolver.impl.tree.ProviderHandler#getResourceProvider(org.apache.sling.resourceresolver.impl.helper.ResourceResolverContext)
+ */
+ public ResourceProvider getResourceProvider(final ResourceResolverContext ctx) {
+ return this.getResourceProvider();
+ }
+
+ /**
* {@inheritDoc}
* @see java.lang.Object#hashCode()
*/
Modified: sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/tree/ProviderHandlerTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/tree/ProviderHandlerTest.java?rev=1360715&r1=1360714&r2=1360715&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/tree/ProviderHandlerTest.java (original)
+++ sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/tree/ProviderHandlerTest.java Thu Jul 12 15:11:06 2012
@@ -94,5 +94,11 @@ public class ProviderHandlerTest {
return null;
}
+ @Override
+ public ResourceProvider getResourceProvider(ResourceResolverContext ctx) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
}
}
Modified: sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderEntryTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderEntryTest.java?rev=1360715&r1=1360714&r2=1360715&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderEntryTest.java (original)
+++ sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderEntryTest.java Thu Jul 12 15:11:06 2012
@@ -34,9 +34,7 @@ import org.apache.sling.api.resource.Res
import org.apache.sling.api.resource.ResourceMetadata;
import org.apache.sling.api.resource.ResourceProvider;
import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.resourceresolver.impl.tree.ProviderHandler;
-import org.apache.sling.resourceresolver.impl.tree.ResourceProviderEntry;
-import org.apache.sling.resourceresolver.impl.tree.ResourceProviderHandler;
+import org.apache.sling.api.resource.ValueMap;
import org.junit.Before;
import org.junit.Test;
import org.osgi.framework.Constants;
@@ -301,6 +299,30 @@ public class ResourceProviderEntryTest {
public Iterator<String> getAttributeNames() {
return Collections.<String> emptyList().iterator();
}
+
+ public boolean delete(Resource resource) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public Resource addChild(Resource parent, String name, ValueMap properties) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void update(Resource resource, ValueMap properties) {
+ // TODO Auto-generated method stub
+ }
+
+ public void revert() {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void commit() {
+ // TODO Auto-generated method stub
+
+ }
}
private static class TestResource extends AbstractResource {