You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by vr...@apache.org on 2012/02/02 13:47:01 UTC

svn commit: r1239587 [1/9] - in /sling/whiteboard/resourceresolverfactory/jcr-resource: ./ src/ src/main/ src/main/appended-resources/ src/main/appended-resources/META-INF/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/a...

Author: vramdal
Date: Thu Feb  2 12:46:58 2012
New Revision: 1239587

URL: http://svn.apache.org/viewvc?rev=1239587&view=rev
Log:
Copy of current jcr/resource bundle to start work on http://markmail.org/message/wp6cghi5nqprpusn

Added:
    sling/whiteboard/resourceresolverfactory/jcr-resource/README.txt
    sling/whiteboard/resourceresolverfactory/jcr-resource/pom.xml
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/appended-resources/
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/appended-resources/META-INF/
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/JcrModifiablePropertyMap.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/JcrPropertyMap.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceConstants.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceResolverFactory.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceUtil.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrItemAdapterFactory.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceListener.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolver.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverFactoryImpl.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverWebConsolePlugin.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/ResourceDecoratorTracker.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/ResourceIteratorDecorator.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/WorkspaceAuthInfoPostProcessor.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/WorkspaceDecoratedResource.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/JcrPropertyMapCacheEntry.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/LazyInputStream.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/MapEntries.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/MapEntry.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/Mapping.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/RedirectResource.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourceIterator.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourcePathIterator.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntry.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/RootResourceProviderEntry.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/URI.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/URIException.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/WrappedResourceProvider.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrItemResource.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResource.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResourceIterator.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrPropertyResource.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProvider.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProviderEntry.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/starresource/
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/starresource/StarResource.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/scripting/
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/scripting/JcrObjectsBindingsValuesProvider.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/resources/
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/resources/OSGI-INF/
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/resources/OSGI-INF/metatype/
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/resources/OSGI-INF/metatype/metatype.properties
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/resources/SLING-INF/
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/resources/SLING-INF/nodetypes/
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/resources/SLING-INF/nodetypes/folder.cnd
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/resources/SLING-INF/nodetypes/mapping.cnd
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/resources/SLING-INF/nodetypes/redirect.cnd
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/resources/SLING-INF/nodetypes/resource.cnd
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/resources/SLING-INF/nodetypes/vanitypath.cnd
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/test/
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/test/java/
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/test/java/org/
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/test/java/org/apache/
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/test/java/org/apache/sling/
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/test/java/org/apache/sling/jcr/
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/test/java/org/apache/sling/jcr/resource/
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/test/java/org/apache/sling/jcr/resource/internal/
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrModifiablePropertyMapTest.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrPropertyMapTest.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrResourceListenerTest.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverTest.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/test/java/org/apache/sling/jcr/resource/internal/SynchronousJcrResourceListener.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/JcrNodeResourceIteratorTest.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/MapEntryTest.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/RedirectResourceTest.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourcePathIteratorTest.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntryTest.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/jcr/
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrItemResourceTestBase.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResourceTest.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrPropertyResourceTest.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/jcr/MockResourceResolver.java
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/starresource/
    sling/whiteboard/resourceresolverfactory/jcr-resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/starresource/StarResourceTest.java

Added: sling/whiteboard/resourceresolverfactory/jcr-resource/README.txt
URL: http://svn.apache.org/viewvc/sling/whiteboard/resourceresolverfactory/jcr-resource/README.txt?rev=1239587&view=auto
==============================================================================
--- sling/whiteboard/resourceresolverfactory/jcr-resource/README.txt (added)
+++ sling/whiteboard/resourceresolverfactory/jcr-resource/README.txt Thu Feb  2 12:46:58 2012
@@ -0,0 +1,27 @@
+Apache Sling Resource Resolver
+
+This bundle provides the JCR based Resource Resolver.
+
+Getting Started
+===============
+
+This component uses a Maven 2 (http://maven.apache.org/) build
+environment. It requires a Java 5 JDK (or higher) and Maven (http://maven.apache.org/)
+2.0.7 or later. We recommend to use the latest Maven version.
+
+If you have Maven 2 installed, you can compile and
+package the jar using the following command:
+
+    mvn package
+
+See the Maven 2 documentation for other build features.
+
+The latest source code for this component is available in the
+Subversion (http://subversion.tigris.org/) source repository of
+the Apache Software Foundation. If you have Subversion installed,
+you can checkout the latest source using the following command:
+
+    svn checkout http://svn.apache.org/repos/asf/sling/trunk/jcr/resource
+
+See the Subversion documentation for other source control features.
+

Added: sling/whiteboard/resourceresolverfactory/jcr-resource/pom.xml
URL: http://svn.apache.org/viewvc/sling/whiteboard/resourceresolverfactory/jcr-resource/pom.xml?rev=1239587&view=auto
==============================================================================
--- sling/whiteboard/resourceresolverfactory/jcr-resource/pom.xml (added)
+++ sling/whiteboard/resourceresolverfactory/jcr-resource/pom.xml Thu Feb  2 12:46:58 2012
@@ -0,0 +1,258 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>sling</artifactId>
+        <version>12</version>
+        <relativePath>../../../parent/pom.xml</relativePath>
+    </parent>
+
+    <artifactId>org.apache.sling.jcr.resource</artifactId>
+    <version>2.0.11-SNAPSHOT</version>
+    <packaging>bundle</packaging>
+
+    <name>Apache Sling JCR Resource Resolver</name>
+    <description>
+        This bundle provides the JCR based ResourceResolver.
+    </description>
+
+    <scm>
+        <connection>
+            scm:svn:http://svn.apache.org/repos/asf/sling/trunk/bundles/jcr/resource
+        </connection>
+        <developerConnection>
+            scm:svn:https://svn.apache.org/repos/asf/sling/trunk/bundles/jcr/resource
+        </developerConnection>
+        <url>
+            http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource
+        </url>
+    </scm>
+
+    <properties>
+        <site.jira.version.id>12314286</site.jira.version.id>
+        <site.javadoc.exclude>**.internal.**</site.javadoc.exclude>
+    </properties>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-scr-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.sling</groupId>
+                <artifactId>maven-sling-plugin</artifactId>
+                <version>2.1.0</version>
+                <executions>
+                    <execution>
+                        <id>generate-adapter-metadata</id>
+                        <phase>process-classes</phase>
+                        <goals>
+                            <goal>generate-adapter-metadata</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Import-Package>
+                            javax.script.*;
+                            javax.annotation;resolution:=optional,
+                            org.apache.sling.scripting.api.*;resolution:=optional,
+                            org.apache.sling.api.resource;version="[$(version;==;$(@)),$(version;=+;$(@)))",
+                            org.apache.sling.commons.osgi;version="$(@)",
+                            *
+                        </Import-Package>
+                        <DynamicImport-Package>
+                            org.apache.jackrabbit.api.observation
+                        </DynamicImport-Package>
+                        <Export-Package>
+                            org.apache.sling.jcr.resource;version=2.1
+                        </Export-Package>
+                        <Private-Package>
+                            org.apache.sling.jcr.resource.internal.*
+                        </Private-Package>
+
+                        <!-- Include URL support from Jackrabbit -->
+                        <Embed-Dependency>
+                            jackrabbit-classloader;inline="org/apache/jackrabbit/net/**|org/apache/jackrabbit/classloader/Util.*",
+                            jackrabbit-jcr-commons;inline="org/apache/jackrabbit/util/ISO9075.*|org/apache/jackrabbit/name/QName.*|org/apache/jackrabbit/util/XMLChar.*|org/apache/jackrabbit/util/Text.*",
+                            guava;inline="com/google/common/collect/Maps*.*|com/google/common/base/Preconditions.*|com/google/common/primitives/Ints.*"
+                        </Embed-Dependency>
+
+                        <Sling-Namespaces>
+                            sling=http://sling.apache.org/jcr/sling/1.0
+                        </Sling-Namespaces>
+
+                        <Sling-Nodetypes>
+                            SLING-INF/nodetypes/folder.cnd,
+                            SLING-INF/nodetypes/resource.cnd,
+                            SLING-INF/nodetypes/vanitypath.cnd,
+                            SLING-INF/nodetypes/redirect.cnd,
+                            SLING-INF/nodetypes/mapping.cnd
+                        </Sling-Nodetypes>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.jackrabbit</groupId>
+            <artifactId>jackrabbit-api</artifactId>
+            <version>2.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.scr.annotations</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.jcr</groupId>
+            <artifactId>jcr</artifactId>
+            <version>2.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.api</artifactId>
+            <version>2.1.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.scripting.api</artifactId>
+            <version>2.1.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.jcr.api</artifactId>
+            <version>2.0.6</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.adapter</artifactId>
+            <version>2.0.4</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.osgi</artifactId>
+            <version>2.0.6</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.auth.core</artifactId>
+            <version>1.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.classloader</artifactId>
+            <version>1.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+           <groupId>commons-collections</groupId>
+           <artifactId>commons-collections</artifactId>
+           <version>3.2.1</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>r09</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>adapter-annotations</artifactId>
+            <version>1.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <!-- For the Console Plugin of the JcrResourceResolverFactoryImpl -->
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+        </dependency>
+
+        <!-- for adapting JCR resources to URLs -->
+        <dependency>
+            <groupId>org.apache.jackrabbit</groupId>
+            <artifactId>jackrabbit-classloader</artifactId>
+            <version>1.5.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.jackrabbit</groupId>
+            <artifactId>jackrabbit-jcr-commons</artifactId>
+            <version>2.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <!-- Testing -->
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.testing</artifactId>
+            <version>2.0.6</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-all</artifactId>
+            <version>1.8.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit-addons</groupId>
+            <artifactId>junit-addons</artifactId>
+            <version>1.4</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.jcr.base</artifactId>
+            <version>2.1.0</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>

Added: sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/JcrModifiablePropertyMap.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/JcrModifiablePropertyMap.java?rev=1239587&view=auto
==============================================================================
--- sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/JcrModifiablePropertyMap.java (added)
+++ sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/JcrModifiablePropertyMap.java Thu Feb  2 12:46:58 2012
@@ -0,0 +1,220 @@
+/*
+ * 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;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.nodetype.NodeType;
+
+import org.apache.jackrabbit.util.ISO9075;
+import org.apache.sling.api.resource.PersistableValueMap;
+import org.apache.sling.api.resource.PersistenceException;
+import org.apache.sling.jcr.resource.internal.helper.JcrPropertyMapCacheEntry;
+
+/**
+ * This implementation of the value map allows to change
+ * the properies and save them later on.
+ */
+public final class JcrModifiablePropertyMap
+    extends JcrPropertyMap
+    implements PersistableValueMap {
+
+    /** Set of removed and changed properties. */
+    private Set<String> changedProperties;
+
+    /**
+     * Constructor
+     * @param node The underlying node.
+     */
+    public JcrModifiablePropertyMap(final Node node) {
+        super(node);
+    }
+
+    /**
+     * Constructor
+     * @param node The underlying node.
+     * @param dynamicCL Dynamic class loader for loading serialized objects.
+     * @since 2.0.6
+     */
+    public JcrModifiablePropertyMap(final Node node, final ClassLoader dynamicCL) {
+        super(node, dynamicCL);
+    }
+
+    // ---------- Map
+    /**
+     * @see java.util.Map#clear()
+     */
+    public void clear() {
+        // we have to read all properties first
+        this.readFully();
+        if ( this.changedProperties == null ) {
+            this.changedProperties = new HashSet<String>();
+        }
+        this.changedProperties.addAll(this.cache.keySet());
+        this.cache.clear();
+        this.valueCache.clear();
+    }
+
+    /**
+     * @see java.util.Map#put(java.lang.Object, java.lang.Object)
+     */
+    public Object put(String aKey, Object value) {
+        final String key = checkKey(aKey);
+        if ( key.indexOf('/') != -1 ) {
+            throw new IllegalArgumentException("Invalid key: " + key);
+        }
+        if ( value == null ) {
+            throw new NullPointerException("Value should not be null (key = " + key + ")");
+        }
+        readFully();
+        final Object oldValue = this.get(key);
+        try {
+            this.cache.put(key, new JcrPropertyMapCacheEntry(value, getNode().getSession()));
+        } catch (RepositoryException re) {
+            throw new IllegalArgumentException("Value for key " + key + " can't be put into node: " + value, re);
+        }
+        this.valueCache.put(key, value);
+        if ( this.changedProperties == null ) {
+            this.changedProperties = new HashSet<String>();
+        }
+        this.changedProperties.add(key);
+        return oldValue;
+    }
+
+    /**
+     * @see java.util.Map#putAll(java.util.Map)
+     */
+    public void putAll(Map<? extends String, ? extends Object> t) {
+        readFully();
+        if ( t != null ) {
+            final Iterator<?> i = t.entrySet().iterator();
+            while (i.hasNext() ) {
+                @SuppressWarnings("unchecked")
+                final Map.Entry<? extends String, ? extends Object> entry = (Map.Entry<? extends String, ? extends Object>) i.next();
+                put(entry.getKey(), entry.getValue());
+            }
+        }
+    }
+
+    /**
+     * @see java.util.Map#remove(java.lang.Object)
+     */
+    public Object remove(Object aKey) {
+        final String key = checkKey(aKey.toString());
+        readFully();
+        final Object oldValue = this.cache.remove(key);
+        this.valueCache.remove(key);
+        if ( this.changedProperties == null ) {
+            this.changedProperties = new HashSet<String>();
+        }
+        this.changedProperties.add(key.toString());
+        return oldValue;
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.PersistableValueMap#reset()
+     */
+    public void reset() {
+        if ( this.changedProperties != null ) {
+            this.changedProperties = null;
+        }
+        this.cache.clear();
+        this.valueCache.clear();
+        this.fullyRead = false;
+    }
+
+    /** Property for the mixin node types. */
+    private static final String MIXIN_TYPES = "jcr:mixinTypes";
+
+    /**
+     * Update the mixin node types
+     */
+    private void handleMixinTypes(final Node node, final Value[] mixinTypes) throws RepositoryException {
+        final Set<String> newTypes = new HashSet<String>();
+        if ( mixinTypes != null ) {
+            for(final Value value : mixinTypes ) {
+                newTypes.add(value.getString());
+            }
+        }
+        final Set<String> oldTypes = new HashSet<String>();
+        for(final NodeType mixinType : node.getMixinNodeTypes()) {
+            oldTypes.add(mixinType.getName());
+        }
+        for(final String name : oldTypes) {
+            if ( !newTypes.contains(name) ) {
+                node.removeMixin(name);
+            } else {
+                newTypes.remove(name);
+            }
+        }
+        for(final String name : newTypes) {
+            node.addMixin(name);
+        }
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.PersistableValueMap#save()
+     */
+    public void save() throws PersistenceException {
+        if ( this.changedProperties == null || this.changedProperties.size() == 0 ) {
+            // nothing has changed
+            return;
+        }
+        try {
+            final Node node = getNode();
+            // check for mixin types
+            final String mixinTypesKey = ISO9075.decode(MIXIN_TYPES);
+            if ( this.changedProperties.contains(mixinTypesKey) ) {
+                if ( cache.containsKey(mixinTypesKey) ) {
+                    final JcrPropertyMapCacheEntry entry = cache.get(mixinTypesKey);
+                    handleMixinTypes(node, entry.values);
+                } else {
+                    // remove all mixin types!
+                    handleMixinTypes(node, null);
+                }
+            }
+
+            for(final String key : this.changedProperties) {
+                final String name = ISO9075.encodePath(key);
+                if ( !MIXIN_TYPES.equals(name) ) {
+                    if ( cache.containsKey(key) ) {
+                        final JcrPropertyMapCacheEntry entry = cache.get(key);
+                        if ( entry.isMulti ) {
+                            node.setProperty(name, entry.values);
+                        } else {
+                            node.setProperty(name, entry.values[0]);
+                        }
+                    } else {
+                        node.setProperty(name, (String)null);
+                    }
+                }
+            }
+            node.getSession().save();
+        } catch (RepositoryException re) {
+            throw new PersistenceException("Unable to persist changes.", re);
+        }
+        this.reset();
+    }
+}

Added: sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/JcrPropertyMap.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/JcrPropertyMap.java?rev=1239587&view=auto
==============================================================================
--- sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/JcrPropertyMap.java (added)
+++ sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/JcrPropertyMap.java Thu Feb  2 12:46:58 2012
@@ -0,0 +1,515 @@
+/*
+ * 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;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.ValueFormatException;
+
+import org.apache.jackrabbit.util.ISO9075;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.jcr.resource.internal.helper.JcrPropertyMapCacheEntry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Maps;
+
+/**
+ * An implementation of the value map based on a JCR node.
+ * @see JcrModifiablePropertyMap
+ */
+public class JcrPropertyMap
+    implements ValueMap {
+
+    /** default logger */
+    private static Logger LOGGER = LoggerFactory.getLogger(JcrPropertyMap.class);
+
+    /** The underlying node. */
+    private final Node node;
+
+    /** A cache for the properties. */
+    final Map<String, JcrPropertyMapCacheEntry> cache;
+
+    /** A cache for the values. */
+    final Map<String, Object> valueCache;
+
+    /** Has the node been read completly? */
+    boolean fullyRead;
+
+    private final ClassLoader dynamicClassLoader;
+
+    /**
+     * Constructor
+     * @param node The underlying node.
+     */
+    public JcrPropertyMap(final Node node) {
+        this(node, null);
+    }
+
+    /**
+     * Constructor
+     * @param node The underlying node.
+     * @param dynamicCL Dynamic class loader for loading serialized objects.
+     * @since 2.0.8
+     */
+    public JcrPropertyMap(final Node node, final ClassLoader dynamicCL) {
+        this.node = node;
+        this.cache = new LinkedHashMap<String, JcrPropertyMapCacheEntry>();
+        this.valueCache = new LinkedHashMap<String, Object>();
+        this.fullyRead = false;
+        this.dynamicClassLoader = dynamicCL;
+    }
+
+    /**
+     * Get the node.
+     */
+    Node getNode() {
+        return node;
+    }
+
+    // ---------- ValueMap
+
+    String checkKey(final String key) {
+        if ( key == null ) {
+            throw new NullPointerException("Key must not be null.");
+        }
+        if ( key.startsWith("./") ) {
+            return key.substring(2);
+        }
+        return key;
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.ValueMap#get(java.lang.String, java.lang.Class)
+     */
+    @SuppressWarnings("unchecked")
+    public <T> T get(final String aKey, final Class<T> type) {
+        final String key = checkKey(aKey);
+        if (type == null) {
+            return (T) get(key);
+        }
+
+        JcrPropertyMapCacheEntry entry = cache.get(key);
+        if (entry == null) {
+            entry = read(key);
+        }
+        if ( entry == null ) {
+            return null;
+        }
+        return convertToType(entry, type);
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.ValueMap#get(java.lang.String, java.lang.Object)
+     */
+    @SuppressWarnings("unchecked")
+    public <T> T get(final String aKey,final T defaultValue) {
+        final String key = checkKey(aKey);
+        if (defaultValue == null) {
+            return (T) get(key);
+        }
+
+        // special handling in case the default value implements one
+        // of the interface types supported by the convertToType method
+        Class<T> type = (Class<T>) normalizeClass(defaultValue.getClass());
+
+        T value = get(key, type);
+        if (value == null) {
+            value = defaultValue;
+        }
+
+        return value;
+    }
+
+    // ---------- Map
+
+    /**
+     * @see java.util.Map#get(java.lang.Object)
+     */
+    public Object get(final Object aKey) {
+        final String key = checkKey(aKey.toString());
+        JcrPropertyMapCacheEntry entry = cache.get(key);
+        if (entry == null) {
+            entry = read(key);
+        }
+        final Object value = (entry == null ? null : entry.getDefaultValueOrNull());
+        return value;
+    }
+
+    /**
+     * @see java.util.Map#containsKey(java.lang.Object)
+     */
+    public boolean containsKey(Object key) {
+        return get(key) != null;
+    }
+
+    /**
+     * @see java.util.Map#containsValue(java.lang.Object)
+     */
+    public boolean containsValue(Object value) {
+        readFully();
+        return valueCache.containsValue(value);
+    }
+
+    /**
+     * @see java.util.Map#isEmpty()
+     */
+    public boolean isEmpty() {
+        return size() == 0;
+    }
+
+    /**
+     * @see java.util.Map#size()
+     */
+    public int size() {
+        readFully();
+        return cache.size();
+    }
+
+    /**
+     * @see java.util.Map#entrySet()
+     */
+    public Set<java.util.Map.Entry<String, Object>> entrySet() {
+        readFully();
+        final Map<String, Object> sourceMap;
+        if (cache.size() == valueCache.size()) {
+            sourceMap = valueCache;
+        } else {
+            sourceMap = Maps.transformEntries(cache, entryTransformer);
+        }
+        return Collections.unmodifiableSet(sourceMap.entrySet());
+    }
+
+    /**
+     * @see java.util.Map#keySet()
+     */
+    public Set<String> keySet() {
+        readFully();
+        return cache.keySet();
+    }
+
+    /**
+     * @see java.util.Map#values()
+     */
+    public Collection<Object> values() {
+        readFully();
+        final Map<String, Object> sourceMap;
+        if (cache.size() == valueCache.size()) {
+            sourceMap = valueCache;
+        } else {
+            sourceMap = Maps.transformEntries(cache, entryTransformer);
+        }
+        return Collections.unmodifiableCollection(sourceMap.values());
+    }
+
+    /**
+     * Return the path of the current node.
+     *
+     * @throws IllegalStateException If a repository exception occurs
+     * @deprecated
+     */
+    @Deprecated
+    public String getPath() {
+        try {
+            return node.getPath();
+        } catch (RepositoryException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    // ---------- Helpers to access the node's property ------------------------
+
+    JcrPropertyMapCacheEntry read(final String key) {
+
+        // if the node has been completely read, we need not check
+        // again if the key does not point to a sub node
+        if (fullyRead && key.indexOf('/') == -1 ) {
+            // except if the key contains
+            return null;
+        }
+
+        final String name = ISO9075.encodePath(key);
+        try {
+            if (node.hasProperty(name)) {
+                final Property prop = node.getProperty(name);
+                final JcrPropertyMapCacheEntry entry = new JcrPropertyMapCacheEntry(prop);
+                cache.put(key, entry);
+                Object defaultValue = entry.getDefaultValue();
+                if (defaultValue != null) {
+                    valueCache.put(key, entry.getDefaultValue());
+                }
+                return entry;
+            }
+        } catch (RepositoryException re) {
+            // TODO: log !!
+        }
+
+        // property not found or some error accessing it
+        return null;
+    }
+
+    void readFully() {
+        if (!fullyRead) {
+            try {
+                PropertyIterator pi = node.getProperties();
+                while (pi.hasNext()) {
+                    Property prop = pi.nextProperty();
+                    final String name = prop.getName();
+                    final String key = ISO9075.decode(name);
+                    if (!cache.containsKey(key)) {
+                        final JcrPropertyMapCacheEntry entry = new JcrPropertyMapCacheEntry(prop);
+                        cache.put(key, entry);
+                        Object defaultValue = entry.getDefaultValue();
+                        if (defaultValue != null) {
+                            valueCache.put(key, entry.getDefaultValue());
+                        }
+                    }
+                }
+                fullyRead = true;
+            } catch (RepositoryException re) {
+                // TODO: log !!
+            }
+        }
+    }
+
+    // ---------- Unsupported Modification methods
+
+    public void clear() {
+        throw new UnsupportedOperationException();
+    }
+
+    public Object put(String key, Object value) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void putAll(Map<? extends String, ? extends Object> t) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Object remove(Object key) {
+        throw new UnsupportedOperationException();
+    }
+
+    // ---------- Implementation helper
+
+    @SuppressWarnings("unchecked")
+    private <T> T convertToType(final JcrPropertyMapCacheEntry entry, Class<T> type) {
+        T result = null;
+
+        try {
+            final boolean array = type.isArray();
+
+            if (entry.isMulti) {
+
+                if (array) {
+
+                    result = (T) convertToArray(entry,
+                        type.getComponentType());
+
+                } else if (entry.values.length > 0) {
+
+                    result = convertToType(entry, -1, entry.values[0], type);
+
+                }
+
+            } else {
+
+                if (array) {
+
+                    result = (T) convertToArray(entry,
+                            type.getComponentType());
+
+                } else {
+
+                    result = convertToType(entry, -1, entry.values[0], type);
+
+                }
+            }
+
+        } catch (ValueFormatException vfe) {
+            LOGGER.info("converToType: Cannot convert value of " + entry.getDefaultValueOrNull()
+                + " to " + type, vfe);
+        } catch (RepositoryException re) {
+            LOGGER.info("converToType: Cannot get value of " + entry.getDefaultValueOrNull(), re);
+        }
+
+        // fall back to nothing
+        return result;
+    }
+
+    private <T> T[] convertToArray(final JcrPropertyMapCacheEntry entry, Class<T> type)
+    throws ValueFormatException, RepositoryException {
+        List<T> values = new ArrayList<T>();
+        for (int i = 0; i < entry.values.length; i++) {
+            T value = convertToType(entry, i, entry.values[i], type);
+            if (value != null) {
+                values.add(value);
+            }
+        }
+
+        @SuppressWarnings("unchecked")
+        T[] result = (T[]) Array.newInstance(type, values.size());
+
+        return values.toArray(result);
+    }
+
+    @SuppressWarnings("unchecked")
+    private <T> T convertToType(final JcrPropertyMapCacheEntry entry,
+                                final int index,
+                                final Value jcrValue,
+                                final Class<T> type)
+    throws ValueFormatException, RepositoryException {
+        Object defaultValue = entry.getDefaultValue();
+        if ( type.isInstance(defaultValue) ) {
+            return (T) defaultValue;
+        }
+
+        if (String.class == type) {
+            return (T) jcrValue.getString();
+
+        } else if (Byte.class == type) {
+            return (T) Byte.valueOf((byte) jcrValue.getLong());
+
+        } else if (Short.class == type) {
+            return (T) Short.valueOf((short) jcrValue.getLong());
+
+        } else if (Integer.class == type) {
+            return (T) Integer.valueOf((int) jcrValue.getLong());
+
+        } else if (Long.class == type) {
+            if (jcrValue.getType() == PropertyType.BINARY) {
+                if (index == -1) {
+                    return (T) Long.valueOf(entry.property.getLength());
+                }
+                return (T) Long.valueOf(entry.property.getLengths()[index]);
+            }
+            return (T) Long.valueOf(jcrValue.getLong());
+
+        } else if (Float.class == type) {
+            return (T) Float.valueOf((float) jcrValue.getDouble());
+
+        } else if (Double.class == type) {
+            return (T) Double.valueOf(jcrValue.getDouble());
+
+        } else if (Boolean.class == type) {
+            return (T) Boolean.valueOf(jcrValue.getBoolean());
+
+        } else if (Date.class == type) {
+            return (T) jcrValue.getDate().getTime();
+
+        } else if (Calendar.class == type) {
+            return (T) jcrValue.getDate();
+
+        } else if (Value.class == type) {
+            return (T) jcrValue;
+
+        } else if (Property.class == type) {
+            return (T) entry.property;
+
+        } else if (Serializable.class.isAssignableFrom(type)
+                && jcrValue.getType() == PropertyType.BINARY) {
+            ObjectInputStream ois = null;
+            try {
+                ois = new ObjectInputStream(jcrValue.getStream(), this.dynamicClassLoader);
+                final Object obj = ois.readObject();
+                if ( type.isInstance(obj) ) {
+                    return (T)obj;
+                }
+            } catch (ClassNotFoundException cnfe) {
+                 // ignore and use fallback
+            } catch (IOException ioe) {
+                // ignore and use fallback
+            } finally {
+                if ( ois != null ) {
+                    try {
+                        ois.close();
+                    } catch (IOException ignore) {
+                        // ignore
+                    }
+                }
+            }
+        }
+
+        // fallback in case of unsupported type
+        return null;
+    }
+
+    private Class<?> normalizeClass(Class<?> type) {
+        if (Calendar.class.isAssignableFrom(type)) {
+            type = Calendar.class;
+        } else if (Date.class.isAssignableFrom(type)) {
+            type = Date.class;
+        } else if (Value.class.isAssignableFrom(type)) {
+            type = Value.class;
+        } else if (Property.class.isAssignableFrom(type)) {
+            type = Property.class;
+        }
+        return type;
+    }
+
+    private static Maps.EntryTransformer<String, JcrPropertyMapCacheEntry, Object> entryTransformer = new Maps.EntryTransformer<String, JcrPropertyMapCacheEntry, Object>() {
+
+        public Object transformEntry(String key, JcrPropertyMapCacheEntry value) {
+            return value.getDefaultValueOrNull();
+        }
+    };
+
+    /**
+     * This is an extended version of the object input stream which uses the
+     * thread context class loader.
+     */
+    private static class ObjectInputStream extends java.io.ObjectInputStream {
+
+        private ClassLoader classloader;
+
+        public ObjectInputStream(final InputStream in, final ClassLoader classLoader) throws IOException {
+            super(in);
+            this.classloader = classLoader;
+        }
+
+        /**
+         * @see java.io.ObjectInputStream#resolveClass(java.io.ObjectStreamClass)
+         */
+        @Override
+        protected Class<?> resolveClass(java.io.ObjectStreamClass classDesc) throws IOException, ClassNotFoundException {
+            if ( this.classloader != null ) {
+                return this.classloader.loadClass(classDesc.getName());
+            }
+            return super.resolveClass(classDesc);
+        }
+    }
+}

Added: sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceConstants.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceConstants.java?rev=1239587&view=auto
==============================================================================
--- sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceConstants.java (added)
+++ sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceConstants.java Thu Feb  2 12:46:58 2012
@@ -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;
+
+import org.apache.sling.api.SlingConstants;
+
+/**
+ * The <code>JcrResourceConstants</code> interface provides constant values.
+ */
+public class JcrResourceConstants {
+
+    /**
+     * The namespace URI used by Sling JCR for items and node types used by
+     * Sling (value is "http://sling.apache.org/jcr/sling/1.0"). This URI is
+     * ensured to be mapped to the Sling namespace prefix <em>sling</em> for any
+     * session used by the JCR Resource bundle through the
+     * <code>Sling-Namespaces</code> bundle manifest header.
+     */
+    public static final String SLING_NAMESPACE_URI = SlingConstants.NAMESPACE_URI_ROOT
+        + "jcr/sling/1.0";
+
+    /**
+     * The name of the JCR Property that defines the resource type of this node
+     * (value is "sling:resourceType"). The resource manager implementation of
+     * this bundle uses this property to defined the resource type of a loaded
+     * resource. If this property does not exist the primary node type is used
+     * as the resource type.
+     */
+    public static final String SLING_RESOURCE_TYPE_PROPERTY = "sling:resourceType";
+
+    /**
+     * The name of the JCR Property that defines the resource super type (value
+     * is "sling:resourceSuperType"). The resource manager implementation of
+     * this bundle uses this property to defined the resource type of a loaded
+     * resource. If this property does not exist any non-mixin base type of the
+     * the primary node type is used as the resource super type.
+     */
+    public static final String SLING_RESOURCE_SUPER_TYPE_PROPERTY = "sling:resourceSuperType";
+
+    /**
+     * The name of the property providing the JCR credentials to be used by the
+     * resource resolver factory method instead of the <code>user.name</code>
+     * and <code>user.password</code> properties. If this propery is provided
+     * and set to an object of type <code>javax.jcr.Credentials</code> the
+     * <code>user.name</code> property is ignored.
+     * <p>
+     * This property is ignored by the
+     * {@link org.apache.sling.api.resource.ResourceResolverFactory#getAdministrativeResourceResolver(java.util.Map)}
+     * method or if the authentication info has a
+     * {@link #AUTHENTICATION_INFO_SESSION} property set to a
+     * <code>javax.jcr.Session</code> object.
+     * <p>
+     * The type of this property, if present, is
+     * <code>javax.jcr.Credentials</code>.
+     *
+     * @since 2.1
+     * @see org.apache.sling.api.resource.ResourceResolverFactory#getResourceResolver(java.util.Map)
+     */
+    public static final String AUTHENTICATION_INFO_CREDENTIALS = "user.jcr.credentials";
+
+    /**
+     * The name of the authentication info property containing the workspace
+     * name to which the JCR based resource resolver should provide access.
+     * <p>
+     * The type of this property, if present, is <code>String</code>.
+     *
+     * @since 2.1
+     */
+    public static final String AUTHENTICATION_INFO_WORKSPACE = "user.jcr.workspace";
+
+    /**
+     * The name of the authentication info property containing a JCR Session to
+     * which a JCR based resource resolver should provide access. If this
+     * property is set in the authentication info map, all other properties are
+     * ignored for the creation of the resource resolver with the exception of
+     * the <code>user.impersonation</code> which is still respected.
+     * <p>
+     * The session provided by as this property and used as the basis of newly
+     * created resource resolver must not be logged out before the resource
+     * resolver is closed. On the other closing the resource resolver not logout
+     * this session.
+     * <p>
+     * This property is ignored by the
+     * {@link org.apache.sling.api.resource.ResourceResolverFactory#getAdministrativeResourceResolver(java.util.Map)}
+     * method.
+     * <p>
+     * The type of this property, if present, is <code>javax.jcr.Session</code>.
+     *
+     * @since 2.1
+     */
+    public static final String AUTHENTICATION_INFO_SESSION = "user.jcr.session";
+
+}

Added: sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceResolverFactory.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceResolverFactory.java?rev=1239587&view=auto
==============================================================================
--- sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceResolverFactory.java (added)
+++ sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceResolverFactory.java Thu Feb  2 12:46:58 2012
@@ -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;
+
+import javax.jcr.Session;
+
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceResolverFactory;
+
+/**
+ * The <code>JcrResourceResolverFactory</code> interface defines the service
+ * interface to have JCR-based <code>ResourceResolver</code> instances created
+ * for JCR sessions.
+ * <p>
+ * This interface is not intended to be implemented by client applications. It
+ * is implemented by this bundle and the implementation registered as a service
+ * for use by client applications.
+ *
+ * This interface is deprecated. You should use
+ * {@link org.apache.sling.api.resource.ResourceResolverFactory}
+ * instead. If you need a resource resolver based on an existing session
+ * you can create an authentication map just containing this session
+ * (using the key {@link JcrResourceConstants#AUTHENTICATION_INFO_SESSION})
+ * and then call {@link org.apache.sling.api.resource.ResourceResolverFactory#getResourceResolver(java.util.Map)}
+ * with exactly this map.
+ *
+ * @deprecated Since 2.1. Use the
+ *             {@link org.apache.sling.api.resource.ResourceResolverFactory}
+ */
+@Deprecated
+public interface JcrResourceResolverFactory extends ResourceResolverFactory {
+
+    /**
+     * Returns a <code>ResourceResolver</code> for the given session. Calling
+     * this method repeatedly returns a new instance on each call.
+     * <p>
+     * This method is equivalent to:
+     *
+     * <pre>
+     * Map&lt;String, Object&gt; authInfo = new HashMap&lt;String, Object&gt;();
+     * authInfo.put(SESSION, session);
+     * return getResourceResolver(authInfo);
+     * </pre>
+     * <p>
+     * <b>Note:</b> Closing the <code>ResourceResolver</code> returned by this
+     * method will <b>not</b> close the provided <code>Session</code> ! Likewise
+     * the provided <code>Session</code> should not be logged out before closing
+     * the returned <code>ResourceResolver</code>.
+     *
+     * @param session The JCR <code>Session</code> used by the created resource
+     *            manager to access the repository.
+     */
+    ResourceResolver getResourceResolver(Session session);
+
+}

Added: sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceUtil.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceUtil.java?rev=1239587&view=auto
==============================================================================
--- sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceUtil.java (added)
+++ sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceUtil.java Thu Feb  2 12:46:58 2012
@@ -0,0 +1,329 @@
+/*
+ * 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;
+
+import java.io.InputStream;
+import java.util.Calendar;
+import java.util.StringTokenizer;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.Value;
+import javax.jcr.ValueFactory;
+import javax.jcr.query.Query;
+import javax.jcr.query.QueryManager;
+import javax.jcr.query.QueryResult;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceUtil;
+import org.apache.sling.jcr.resource.internal.helper.LazyInputStream;
+
+/**
+ * The <code>JcrResourceUtil</code> class provides helper methods used
+ * throughout this bundle.
+ */
+public class JcrResourceUtil {
+
+    /** Helper method to execute a JCR query */
+    public static QueryResult query(Session session, String query,
+            String language) throws RepositoryException {
+        QueryManager qManager = session.getWorkspace().getQueryManager();
+        Query q = qManager.createQuery(query, language);
+        return q.execute();
+    }
+
+    /** Converts a JCR Value to a corresponding Java Object */
+    public static Object toJavaObject(Value value) throws RepositoryException {
+        switch (value.getType()) {
+            case PropertyType.BINARY:
+                return new LazyInputStream(value);
+            case PropertyType.BOOLEAN:
+                return value.getBoolean();
+            case PropertyType.DATE:
+                return value.getDate();
+            case PropertyType.DOUBLE:
+                return value.getDouble();
+            case PropertyType.LONG:
+                return value.getLong();
+            case PropertyType.NAME: // fall through
+            case PropertyType.PATH: // fall through
+            case PropertyType.REFERENCE: // fall through
+            case PropertyType.STRING: // fall through
+            case PropertyType.UNDEFINED: // not actually expected
+            default: // not actually expected
+                return value.getString();
+        }
+    }
+
+    /**
+     * Converts the value(s) of a JCR Property to a corresponding Java Object.
+     * If the property has multiple values the result is an array of Java
+     * Objects representing the converted values of the property.
+     */
+    public static Object toJavaObject(Property property)
+            throws RepositoryException {
+        // multi-value property: return an array of values
+        if (property.getDefinition().isMultiple()) {
+            Value[] values = property.getValues();
+            Object[] result = new Object[values.length];
+            for (int i = 0; i < values.length; i++) {
+                Value value = values[i];
+                if (value != null) {
+                    result[i] = toJavaObject(value);
+                }
+            }
+            return result;
+        }
+
+        // single value property
+        return toJavaObject(property.getValue());
+    }
+
+    /**
+     * Creates a {@link javax.jcr.Value JCR Value} for the given object with
+     * the given Session.
+     * Selects the the {@link javax.jcr.PropertyType PropertyType} according
+     * the instance of the object's Class
+     *
+     * @param value object
+     * @param session to create value for
+     * @return the value or null if not convertible to a valid PropertyType
+     * @throws RepositoryException in case of error, accessing the Repository
+     */
+    public static Value createValue(Object value, Session session)
+            throws RepositoryException {
+        Value val;
+        ValueFactory fac = session.getValueFactory();
+        if(value instanceof Calendar) {
+            val = fac.createValue((Calendar)value);
+        } else if (value instanceof InputStream) {
+            val = fac.createValue((InputStream)value);
+        } else if (value instanceof Node) {
+            val = fac.createValue((Node)value);
+        } else if (value instanceof Long) {
+            val = fac.createValue((Long)value);
+        } else if (value instanceof Number) {
+            val = fac.createValue(((Number)value).doubleValue());
+        } else if (value instanceof Boolean) {
+            val = fac.createValue((Boolean) value);
+        } else if ( value instanceof String ){
+            val = fac.createValue((String)value);
+        } else {
+            val = null;
+        }
+        return val;
+    }
+
+    /**
+     * Sets the value of the property.
+     * Selects the {@link javax.jcr.PropertyType PropertyType} according
+     * to the instance of the object's class.
+     * @param node         The node where the property will be set on.
+     * @param propertyName The name of the property.
+     * @param propertyValue The value for the property.
+     */
+    public static void setProperty(final Node node,
+                                   final String propertyName,
+                                   final Object propertyValue)
+    throws RepositoryException {
+        if ( propertyValue == null ) {
+            node.setProperty(propertyName, (String)null);
+        } else if ( propertyValue.getClass().isArray() ) {
+            final Object[] values = (Object[])propertyValue;
+            final Value[] setValues = new Value[values.length];
+            for(int i=0; i<values.length; i++) {
+                setValues[i] = createValue(values[i], node.getSession());
+            }
+            node.setProperty(propertyName, setValues);
+        } else {
+            node.setProperty(propertyName, createValue(propertyValue, node.getSession()));
+        }
+    }
+
+    /**
+     * Helper method, which returns the given resource type as returned from the
+     * {@link org.apache.sling.api.resource.Resource#getResourceType()} as a
+     * relative path.
+     *
+     * @param type The resource type to be converted into a path
+     * @return The resource type as a path.
+     * @deprecated Use {@link ResourceUtil#resourceTypeToPath(String)}
+     */
+    @Deprecated
+    public static String resourceTypeToPath(String type) {
+        return type.replaceAll("\\:", "/");
+    }
+
+    /**
+     * Returns the super type of the given resource type. This is the result of
+     * adapting the child resource
+     * {@link JcrResourceConstants#SLING_RESOURCE_SUPER_TYPE_PROPERTY} of the
+     * <code>Resource</code> addressed by the <code>resourceType</code> to a
+     * string. If no such child resource exists or if the resource does not
+     * adapt to a string, this method returns <code>null</code>.
+     *
+     * @param resourceResolver The <code>ResourceResolver</code> used to
+     *            access the resource whose path (relative or absolute) is given
+     *            by the <code>resourceType</code> parameter.
+     * @param resourceType The resource type whose super type is to be returned.
+     *            This type is turned into a path by calling the
+     *            {@link #resourceTypeToPath(String)} method before trying to
+     *            get the resource through the <code>resourceResolver</code>.
+     * @return the super type of the <code>resourceType</code> or
+     *         <code>null</code> if the resource type does not have a child
+     *         resource
+     *         {@link JcrResourceConstants#SLING_RESOURCE_SUPER_TYPE_PROPERTY}
+     *         adapting to a string.
+     * @deprecated Use {@link ResourceUtil#getResourceSuperType(ResourceResolver, String)}
+     */
+    @Deprecated
+    public static String getResourceSuperType(
+            ResourceResolver resourceResolver, String resourceType) {
+        return ResourceUtil.getResourceSuperType(resourceResolver, resourceType);
+    }
+
+    /**
+     * Returns the resource super type of the given resource. This is either the
+     * child resource
+     * {@link JcrResourceConstants#SLING_RESOURCE_SUPER_TYPE_PROPERTY} if the
+     * given <code>resource</code> adapted to a string or the result of
+     * calling the {@link #getResourceSuperType(ResourceResolver, String)}
+     * method on the resource type of the <code>resource</code>.
+     * <p>
+     * This mechanism allows to specifically set the resource super type on a
+     * per-resource level overwriting any resource super type hierarchy
+     * pre-defined by the actual resource type of the resource.
+     *
+     * @param resource The <code>Resource</code> whose resource super type is
+     *            requested.
+     * @return The resource super type or <code>null</code> if the algorithm
+     *         described above does not yield a resource super type.
+     * @deprecated Call {@link ResourceUtil#findResourceSuperType(Resource)}
+     */
+    @Deprecated
+    public static String getResourceSuperType(Resource resource) {
+        String resourceSuperType = resource.getResourceSuperType();
+        if ( resourceSuperType == null ) {
+            final ResourceResolver resolver = resource.getResourceResolver();
+
+            // try explicit resourceSuperType resource
+            final String resourceType = resource.getResourceType();
+            resourceSuperType = ResourceUtil.getResourceSuperType(resolver, resourceType);
+        }
+
+        return resourceSuperType;
+    }
+
+    /**
+     * Creates or gets the {@link javax.jcr.Node Node} at the given Path.
+     * In case it has to create the Node all non-existent intermediate path-elements
+     * will be create with the given intermediate node type and the returned node
+     * will be created with the given nodeType
+     *
+     * @param path to create
+     * @param intermediateNodeType to use for creation of intermediate nodes (or null)
+     * @param nodeType to use for creation of the final node (or null)
+     * @param session to use
+     * @param autoSave Should save be called when a new node is created?
+     * @return the Node at path
+     * @throws RepositoryException in case of exception accessing the Repository
+     */
+    public static Node createPath(String path,
+                                  String intermediateNodeType,
+                                  String nodeType,
+                                  Session session,
+                                  boolean autoSave)
+    throws RepositoryException {
+        if (path == null || path.length() == 0 || "/".equals(path)) {
+            return session.getRootNode();
+        } else if (!session.itemExists(path)) {
+            return createPath(session.getRootNode(),
+                    path.substring(1),
+                    intermediateNodeType,
+                    nodeType,
+                    autoSave);
+        } else {
+            return (Node) session.getItem(path);
+        }
+    }
+
+    /**
+     * Creates or gets the {@link javax.jcr.Node Node} at the given Path.
+     * In case it has to create the Node all non-existent intermediate path-elements
+     * will be create with the given intermediate node type and the returned node
+     * will be created with the given nodeType
+     *
+     * @param parentNode starting node
+     * @param relativePath to create
+     * @param intermediateNodeType to use for creation of intermediate nodes (or null)
+     * @param nodeType to use for creation of the final node (or null)
+     * @param autoSave Should save be called when a new node is created?
+     * @return the Node at path
+     * @throws RepositoryException in case of exception accessing the Repository
+     */
+    public static Node createPath(Node   parentNode,
+                                  String relativePath,
+                                  String intermediateNodeType,
+                                  String nodeType,
+                                  boolean autoSave)
+    throws RepositoryException {
+        if (relativePath == null || relativePath.length() == 0 || "/".equals(relativePath)) {
+            return parentNode;
+        } else if (!parentNode.hasNode(relativePath)) {
+            Node node = parentNode;
+            int pos = relativePath.lastIndexOf('/');
+            if ( pos != -1 ) {
+                final StringTokenizer st = new StringTokenizer(relativePath.substring(0, pos), "/");
+                while ( st.hasMoreTokens() ) {
+                    final String token = st.nextToken();
+                    if ( !node.hasNode(token) ) {
+                        try {
+                            if ( intermediateNodeType != null ) {
+                                node.addNode(token, intermediateNodeType);
+                            } else {
+                                node.addNode(token);
+                            }
+                            if ( autoSave ) node.getSession().save();
+                        } catch (RepositoryException re) {
+                            // we ignore this as this folder might be created from a different task
+                            node.refresh(false);
+                        }
+                    }
+                    node = node.getNode(token);
+                }
+                relativePath = relativePath.substring(pos + 1);
+            }
+            if ( !node.hasNode(relativePath) ) {
+                if ( nodeType != null ) {
+                    node.addNode(relativePath, nodeType);
+                } else {
+                    node.addNode(relativePath);
+                }
+                if ( autoSave ) node.getSession().save();
+            }
+            return node.getNode(relativePath);
+        } else {
+            return parentNode.getNode(relativePath);
+        }
+    }
+}

Added: sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrItemAdapterFactory.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrItemAdapterFactory.java?rev=1239587&view=auto
==============================================================================
--- sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrItemAdapterFactory.java (added)
+++ sling/whiteboard/resourceresolverfactory/jcr-resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrItemAdapterFactory.java Thu Feb  2 12:46:58 2012
@@ -0,0 +1,91 @@
+/*
+ * 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;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Map;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+
+import org.apache.sling.api.adapter.AdapterFactory;
+import org.apache.sling.api.resource.PersistableValueMap;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.jcr.resource.internal.helper.jcr.JcrNodeResource;
+import org.apache.sling.jcr.resource.internal.helper.jcr.JcrPropertyResource;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * AdapterFactory which adapts JCR Nodes and Properties into Resources.
+ */
+class JcrItemAdapterFactory implements AdapterFactory {
+
+    private final Logger logger = LoggerFactory.getLogger(JcrItemAdapterFactory.class);
+
+    private final JcrResourceResolverFactoryImpl resourceResolverFactory;
+
+    private ServiceRegistration serviceRegsitration;
+
+    public JcrItemAdapterFactory(BundleContext ctx, JcrResourceResolverFactoryImpl resourceResolverFactory) {
+        this.resourceResolverFactory = resourceResolverFactory;
+        Dictionary<Object, Object> properties = new Hashtable<Object, Object>();
+        properties.put(ADAPTABLE_CLASSES, new String[] { Node.class.getName(), Property.class.getName() });
+        properties.put(ADAPTER_CLASSES,
+                new String[] { Resource.class.getName(), Map.class.getName(), ValueMap.class.getName(),
+                        PersistableValueMap.class.getName() });
+        properties.put(Constants.SERVICE_DESCRIPTION, "JCR Item Adapter Factory");
+        properties.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
+        this.serviceRegsitration = ctx.registerService(AdapterFactory.class.getName(), this, properties);
+    }
+
+    public void dispose() {
+        if (this.serviceRegsitration != null) {
+            this.serviceRegsitration.unregister();
+            this.serviceRegsitration = null;
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public <AdapterType> AdapterType getAdapter(Object adaptable, Class<AdapterType> type) {
+        if (type == Resource.class) {
+            try {
+                if (adaptable instanceof Node) {
+                    Node node = (Node) adaptable;
+                    return (AdapterType) new JcrNodeResource(resourceResolverFactory.getResourceResolver(node
+                            .getSession()), node, resourceResolverFactory.getDynamicClassLoader());
+                } else if (adaptable instanceof Property) {
+                    Property property = (Property) adaptable;
+                    return (AdapterType) new JcrPropertyResource(resourceResolverFactory.getResourceResolver(property
+                            .getSession()), property);
+                }
+            } catch (RepositoryException e) {
+                logger.error("Unable to adapt JCR Item to a Resource", e);
+            }
+            return null;
+        } else {
+            return getAdapter(adaptable, Resource.class).adaptTo(type);
+        }
+    }
+
+}