You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 09:45:53 UTC

[sling-org-apache-sling-jcr-contentloader] annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator created (now 63e22af)

This is an automated email from the ASF dual-hosted git repository.

rombert pushed a change to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git.


      at 63e22af  (tag)
 tagging 74ed6faf4f5ff7887c6d445edf147cfe6600eb7d (commit)
      by Felix Meschberger
      on Thu Jun 18 09:21:02 2009 +0000

- Log -----------------------------------------------------------------
org.apache.sling.jcr.contentloader-2.0.2-incubator
-----------------------------------------------------------------------

This annotated tag includes the following new commits:

     new 089d630  Start new module for content loading.
     new e7c3f36  SLING-400: Move content loading to own bundle.
     new 37489b3  SLING-400: Move content loading to own bundle.
     new 6adfd33  SLING-400: Move content loading to own bundle.
     new 6ba13f4  Eclude maven-eclipse.xml generated by the maven eclipse plugin.
     new 96424e1  SLING-413: Get sling.id only once; handling start and stop should be sufficient.
     new 525d242  SLING-413: Handle bundle update and correctly handle overwrite flag.
     new 76f7b76  SLING-412: Remove support for "name" property which defines the name of the root node imported through json.
     new 5e6f6b9  Use new manifest parser in content loader.
     new 1a9cb53  #SLING-414: Move generation and managing of the sling id to own service in the engine.
     new 55e5771  SLING-453: Initial content loading to target location https://issues.apache.org/jira/browse/SLING-453
     new 97fa605  SLING-365 Implement support for initial checkin of mix:versionable nodes on-demand
     new 7a2d4b1  Add explicit dependency to JUnit library
     new d8971e5  SLING-479 Fix @scr.tags:   - normalize metadata attribute settings to "no"   - ensure proper metadata and ds attributes are set   - create metatype.properties files where required   - fix metatype.properties files
     new 66b1860  SLING-483: Add excludes for javadocs (WiP)
     new 7857ffd  SLING-495 - NOTICE files generated using mknotice script
     new 74d5c76  SLING-495 - NOTICE files updated according to changes in revision 662927
     new 60e1c27  SLING-495 - NOTICE files regenerated with revision 663097 changes
     new 9b24eb4  Use released version of parent pom.
     new 538a808  Use released versions (or soon to be released versions).
     new ffa3b1c  [maven-release-plugin] prepare release org.apache.sling.jcr.contentloader-2.0.0-incubator
     new 11176fe  [maven-release-plugin] prepare for next development iteration
     new 9e8c1dc  Set version to next development version.
     new 9fe2a8e  Fix reference to parent pom.
     new 5f28fb6  SLING-521: Restore more notice files.
     new b037f12  SLING-521: Separate between notice files for bin and src dists.
     new 289aa18  SLING-521: Separate between notice files for bin and src dists.
     new 7085ebf  Change copyright year to 2008.
     new 5773655  SLING-539: Merge LICENSE.* information to LICENSE files     - kXML license
     new d21d415  [maven-release-plugin]  copy for tag org.apache.sling.jcr.contentloader-2.0.2-incubator
     new 769b49c  Move Sling to new TLP location
     new 74ed6fa  Move Sling to new TLP location

The 32 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


-- 
To stop receiving notification emails like this one, please contact
['"commits@sling.apache.org" <co...@sling.apache.org>'].

[sling-org-apache-sling-jcr-contentloader] 05/32: Eclude maven-eclipse.xml generated by the maven eclipse plugin.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit 6ba13f4a3a90f30fcdb0f87fad7493494fb632e2
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Mon May 5 07:09:17 2008 +0000

    Eclude maven-eclipse.xml generated by the maven eclipse plugin.
    
    git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader@653322 13f79535-47bb-0310-9956-ffa450edef68

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-jcr-contentloader] 23/32: Set version to next development version.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit 9e8c1dce206afb51b759338a4bf42e18bb37a57f
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Jun 4 17:27:58 2008 +0000

    Set version to next development version.
    
    git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader@663320 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/pom.xml b/pom.xml
index 849083b..e325d9c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -92,27 +92,27 @@
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.jcr.api</artifactId>
-            <version>2.0.0-incubator</version>
+            <version>2.0.1-incubator-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.commons.json</artifactId>
-            <version>2.0.0-incubator</version>
+            <version>2.0.1-incubator-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.commons.mime</artifactId>
-            <version>2.0.0-incubator</version>
+            <version>2.0.1-incubator-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.commons.osgi</artifactId>
-            <version>2.0.0-incubator</version>
+            <version>2.0.1-incubator-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.engine</artifactId>
-            <version>2.0.0-incubator</version>
+            <version>2.0.1-incubator-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.slf4j</groupId>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-jcr-contentloader] 27/32: SLING-521: Separate between notice files for bin and src dists.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit 289aa18ee4847dc452fb13bae08ff30e5f9ea1cd
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Fri Jun 13 13:43:34 2008 +0000

    SLING-521: Separate between notice files for bin and src dists.
    
    git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader@667538 13f79535-47bb-0310-9956-ffa450edef68
---
 README.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.txt b/README.txt
index 7b3e5ab..9c00331 100644
--- a/README.txt
+++ b/README.txt
@@ -1,6 +1,6 @@
 Apache Sling Initial Content Loader
 
-WE NEED A LOT MORE HERE!!!!!!!!!!!!!!!!!!
+This bundle provides initial content installation through bundles.
 
 
 Disclaimer

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-jcr-contentloader] 29/32: SLING-539: Merge LICENSE.* information to LICENSE files - kXML license

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit 577365502716fa4df7989d7ba605d8b00e751c6c
Author: Jukka Zitting <ju...@apache.org>
AuthorDate: Mon Jun 16 15:06:24 2008 +0000

    SLING-539: Merge LICENSE.* information to LICENSE files
        - kXML license
    
    git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader@668182 13f79535-47bb-0310-9956-ffa450edef68
---
 src/main/resources/META-INF/LICENSE       | 30 ++++++++++++++++++++++++++++++
 src/main/resources/META-INF/LICENSE.kxml2 | 19 -------------------
 2 files changed, 30 insertions(+), 19 deletions(-)

diff --git a/src/main/resources/META-INF/LICENSE b/src/main/resources/META-INF/LICENSE
index d645695..1a45730 100644
--- a/src/main/resources/META-INF/LICENSE
+++ b/src/main/resources/META-INF/LICENSE
@@ -200,3 +200,33 @@
    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.
+
+
+APACHE SLING SUBCOMPONENTS:
+
+Apache Sling includes subcomponents with separate copyright notices and
+license terms. Your use of these subcomponents is subject to the terms
+and conditions of the following licenses.
+
+kXML parser
+
+   Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   "Software"), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to permit
+   persons to whom the Software is furnished to do so, subject to the
+   following conditions:
+
+   The above copyright notice and this permission notice shall be included in
+   all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+   IN THE SOFTWARE. 
diff --git a/src/main/resources/META-INF/LICENSE.kxml2 b/src/main/resources/META-INF/LICENSE.kxml2
deleted file mode 100644
index 1fe595b..0000000
--- a/src/main/resources/META-INF/LICENSE.kxml2
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or
-sell copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The  above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-IN THE SOFTWARE. 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-jcr-contentloader] 09/32: Use new manifest parser in content loader.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit 5e6f6b94f2309ea07ca03176d9de6944c345ac5a
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Thu May 15 07:30:37 2008 +0000

    Use new manifest parser in content loader.
    
    git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader@656528 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                            |  5 +++
 .../jcr/contentloader/internal/PathEntry.java      | 41 +++++++---------------
 2 files changed, 18 insertions(+), 28 deletions(-)

diff --git a/pom.xml b/pom.xml
index 8b9958a..21cc719 100644
--- a/pom.xml
+++ b/pom.xml
@@ -98,6 +98,11 @@
             <version>2.0.0-incubator-SNAPSHOT</version>
         </dependency>
         <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.osgi</artifactId>
+            <version>2.0.0-incubator-SNAPSHOT</version>
+        </dependency>
+        <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
         </dependency>
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/PathEntry.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/PathEntry.java
index e70b561..c85a0b2 100644
--- a/src/main/java/org/apache/sling/jcr/contentloader/internal/PathEntry.java
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/PathEntry.java
@@ -21,8 +21,8 @@ package org.apache.sling.jcr.contentloader.internal;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
-import java.util.StringTokenizer;
 
+import org.apache.sling.commons.osgi.ManifestHeader;
 import org.osgi.framework.Bundle;
 
 /**
@@ -53,10 +53,9 @@ public class PathEntry {
 
         final String root = (String) bundle.getHeaders().get(CONTENT_HEADER);
         if (root != null) {
-            final StringTokenizer tokener = new StringTokenizer(root, ",");
-            while (tokener.hasMoreTokens()) {
-                final String path = tokener.nextToken().trim();
-                entries.add(new PathEntry(path));
+            final ManifestHeader header = ManifestHeader.parse(root);
+            for(final ManifestHeader.Entry entry : header.getEntries()) {
+                entries.add(new PathEntry(entry));
             }
         }
 
@@ -66,32 +65,18 @@ public class PathEntry {
         return entries.iterator();
     }
 
-    public PathEntry(String path) {
-        // check for overwrite flag
+    public PathEntry(ManifestHeader.Entry entry) {
+        // check for overwrite and uninstall flag
+        final String overwriteValue = entry.getDirectiveValue(OVERWRITE_FLAG);
+        final String uninstallValue = entry.getDirectiveValue(UNINSTALL_FLAG);
         boolean overwriteFlag = false;
-        Boolean uninstallFlag = null;
-        int flagPos = path.indexOf(";");
-        if ( flagPos != -1 ) {
-            final StringTokenizer flagTokenizer = new StringTokenizer(path.substring(flagPos+1), ";");
-            while ( flagTokenizer.hasMoreTokens() ) {
-                final String token = flagTokenizer.nextToken();
-                int pos = token.indexOf(":=");
-                if ( pos != -1 ) {
-                    final String name = token.substring(0, pos);
-                    final String value = token.substring(pos+2);
-                    if ( name.equals(OVERWRITE_FLAG) ) {
-                        overwriteFlag = Boolean.valueOf(value).booleanValue();
-                    } else if (name.equals(UNINSTALL_FLAG) ) {
-                        uninstallFlag = Boolean.valueOf(value);
-                    }
-                }
-            }
-            path = path.substring(0, flagPos);
+        if ( overwriteValue != null ) {
+            overwriteFlag = Boolean.valueOf(overwriteValue).booleanValue();
         }
-        this.path = path;
+        this.path =  entry.getValue();
         this.overwrite = overwriteFlag;
-        if ( uninstallFlag != null ) {
-            this.uninstall = uninstallFlag;
+        if ( uninstallValue != null ) {
+            this.uninstall = Boolean.valueOf(uninstallValue);
         } else {
             this.uninstall = this.overwrite;
         }

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-jcr-contentloader] 22/32: [maven-release-plugin] prepare for next development iteration

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit 11176fe12a13952ea2d486dd11fdc123c1ef45be
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Jun 4 15:33:26 2008 +0000

    [maven-release-plugin] prepare for next development iteration
    
    git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader@663218 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/pom.xml b/pom.xml
index 921ad59..849083b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -27,7 +27,7 @@
     </parent>
 
     <artifactId>org.apache.sling.jcr.contentloader</artifactId>
-    <version>2.0.0-incubator</version>
+    <version>2.0.1-incubator-SNAPSHOT</version>
     <packaging>bundle</packaging>
 
     <name>Sling - Initial Content Loader</name>
@@ -36,9 +36,9 @@
     </description>
 
     <scm>
-        <connection>scm:svn:http://svn.apache.org/repos/asf/incubator/sling/tags/org.apache.sling.jcr.contentloader-2.0.0-incubator</connection>
-        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/incubator/sling/tags/org.apache.sling.jcr.contentloader-2.0.0-incubator</developerConnection>
-        <url>http://svn.apache.org/viewvc/incubator/sling/tags/org.apache.sling.jcr.contentloader-2.0.0-incubator</url>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader</developerConnection>
+        <url>http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/contentloader</url>
     </scm>
 
     <build>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-jcr-contentloader] 06/32: SLING-413: Get sling.id only once; handling start and stop should be sufficient.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit 96424e1f4302e01531d435715a60fd82213ed150
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Mon May 5 09:26:38 2008 +0000

    SLING-413: Get sling.id only once; handling start and stop should be sufficient.
    
    git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader@653383 13f79535-47bb-0310-9956-ffa450edef68
---
 .../internal/ContentLoaderService.java              | 21 ++++++++-------------
 1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java
index 57874f3..0091df1 100644
--- a/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java
@@ -85,6 +85,11 @@ public class ContentLoaderService implements SynchronousBundleListener {
      */
     private Loader initialContentLoader;
 
+    /**
+     * The id of the current instance
+     */
+    private String slingId;
+
     // ---------- BundleListener -----------------------------------------------
 
     /**
@@ -117,17 +122,6 @@ public class ContentLoaderService implements SynchronousBundleListener {
                             + event.getBundle().getBundleId() + ")", t);
                 }
                 break;
-            case BundleEvent.UPDATED:
-                try {
-                    Session session = getAdminSession();
-                    initialContentLoader.registerBundle(session, event.getBundle(), true);
-                } catch (Throwable t) {
-                    log.error(
-                        "bundleChanged: Problem updating initial content of bundle "
-                            + event.getBundle().getSymbolicName() + " ("
-                            + event.getBundle().getBundleId() + ")", t);
-                }
-                break;
             case BundleEvent.STOPPED:
                 try {
                     Session session = getAdminSession();
@@ -181,6 +175,7 @@ public class ContentLoaderService implements SynchronousBundleListener {
 
     /** Activates this component, called by SCR before registering as a service */
     protected void activate(ComponentContext componentContext) {
+        this.slingId = componentContext.getBundleContext().getProperty("sling.id");
         this.initialContentLoader = new Loader(this);
 
         componentContext.getBundleContext().addBundleListener(this);
@@ -300,7 +295,7 @@ public class ContentLoaderService implements SynchronousBundleListener {
         if ( contentLoaded ) {
             bcNode.setProperty(ContentLoaderService.PROPERTY_CONTENT_LOADED, contentLoaded);
             bcNode.setProperty("content-load-time", Calendar.getInstance());
-            bcNode.setProperty("content-loaded-by", bundle.getBundleContext().getProperty("sling.id"));
+            bcNode.setProperty("content-loaded-by", this.slingId);
             bcNode.setProperty("content-unload-time", (String)null);
             bcNode.setProperty("content-unloaded-by", (String)null);
             bcNode.save();
@@ -317,7 +312,7 @@ public class ContentLoaderService implements SynchronousBundleListener {
                 final Node bcNode = parentNode.getNode(nodeName);
                 bcNode.setProperty(ContentLoaderService.PROPERTY_CONTENT_LOADED, false);
                 bcNode.setProperty("content-unload-time", Calendar.getInstance());
-                bcNode.setProperty("content-unloaded-by", bundle.getBundleContext().getProperty("sling.id"));
+                bcNode.setProperty("content-unloaded-by", this.slingId);
                 bcNode.save();
             }
         } catch (RepositoryException re) {

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-jcr-contentloader] 14/32: SLING-479 Fix @scr.tags: - normalize metadata attribute settings to "no" - ensure proper metadata and ds attributes are set - create metatype.properties files where required - fix metatype.properties files

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit d8971e5a0b49000fd7f49c77dcba298e71909ef6
Author: Felix Meschberger <fm...@apache.org>
AuthorDate: Tue May 27 10:42:20 2008 +0000

    SLING-479 Fix @scr.tags:
      - normalize metadata attribute settings to "no"
      - ensure proper metadata and ds attributes are set
      - create metatype.properties files where required
      - fix metatype.properties files
    
    git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader@660460 13f79535-47bb-0310-9956-ffa450edef68
---
 .../apache/sling/jcr/contentloader/internal/ContentLoaderService.java   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java
index 2d0612b..347ce30 100644
--- a/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java
@@ -48,7 +48,7 @@ import org.slf4j.LoggerFactory;
  * <li>Fires OSGi EventAdmin events on behalf of internal helper objects
  * </ul>
  *
- * @scr.component metatype="false"
+ * @scr.component metatype="no"
  * @scr.property name="service.description" value="Sling
  *               Content Loader Implementation"
  * @scr.property name="service.vendor" value="The Apache Software Foundation"

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-jcr-contentloader] 03/32: SLING-400: Move content loading to own bundle.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit 37489b3fdcd205f6f6e61eaa102a20c5fc8d4d87
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Apr 30 07:08:40 2008 +0000

    SLING-400: Move content loading to own bundle.
    
    git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader@652310 13f79535-47bb-0310-9956-ffa450edef68
---
 .../jcr/contentloader/internal/JsonReaderTest.java | 374 +++++++++++++++++++++
 1 file changed, 374 insertions(+)

diff --git a/src/main/test/org/apache/sling/jcr/contentloader/internal/JsonReaderTest.java b/src/main/test/org/apache/sling/jcr/contentloader/internal/JsonReaderTest.java
new file mode 100644
index 0000000..a975d3e
--- /dev/null
+++ b/src/main/test/org/apache/sling/jcr/contentloader/internal/JsonReaderTest.java
@@ -0,0 +1,374 @@
+/*
+ * 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.contentloader.internal;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.jcr.PropertyType;
+
+import junit.framework.TestCase;
+
+import org.apache.sling.commons.json.JSONArray;
+import org.apache.sling.commons.json.JSONException;
+import org.apache.sling.commons.json.JSONObject;
+import org.apache.sling.jcr.contentloader.internal.JsonReader;
+import org.apache.sling.jcr.contentloader.internal.NodeDescription;
+import org.apache.sling.jcr.contentloader.internal.PropertyDescription;
+
+public class JsonReaderTest extends TestCase {
+
+    JsonReader jsonReader;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        this.jsonReader = new JsonReader();
+    }
+
+    protected void tearDown() throws Exception {
+        this.jsonReader = null;
+        super.tearDown();
+    }
+
+    public void testEmptyObject() {
+        try {
+            this.parse("");
+        } catch (IOException ioe) {
+            fail("Expected IOException from empty JSON");
+        }
+    }
+
+    public void testEmpty() throws IOException {
+        NodeDescription node = this.parse("{}");
+        assertNotNull("Expecting node", node);
+        assertNull("No name expected", node.getName());
+    }
+
+    public void testDefaultPrimaryNodeType() throws IOException {
+        String json = "{}";
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertNull(node.getPrimaryNodeType());
+        assertNull("No mixins expected", node.getMixinNodeTypes());
+        assertNull("No properties expected", node.getProperties());
+        assertNull("No children expected", node.getChildren());
+    }
+
+    public void testDefaultPrimaryNodeTypeWithSurroundWhitespace() throws IOException {
+        String json = "     {  }     ";
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertNull(node.getPrimaryNodeType());
+        assertNull("No mixins expected", node.getMixinNodeTypes());
+        assertNull("No properties expected", node.getProperties());
+        assertNull("No children expected", node.getChildren());
+    }
+
+    public void testDefaultPrimaryNodeTypeWithoutEnclosingBraces() throws IOException {
+        String json = "";
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertNull(node.getPrimaryNodeType());
+        assertNull("No mixins expected", node.getMixinNodeTypes());
+        assertNull("No properties expected", node.getProperties());
+        assertNull("No children expected", node.getChildren());
+    }
+
+    public void testDefaultPrimaryNodeTypeWithoutEnclosingBracesWithSurroundWhitespace() throws IOException {
+        String json = "             ";
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertNull(node.getPrimaryNodeType());
+        assertNull("No mixins expected", node.getMixinNodeTypes());
+        assertNull("No properties expected", node.getProperties());
+        assertNull("No children expected", node.getChildren());
+    }
+
+    public void testExplicitePrimaryNodeType() throws IOException {
+        String type = "xyz:testType";
+        String json = "{ \"jcr:primaryType\": \"" + type + "\" }";
+
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertEquals(type, node.getPrimaryNodeType());
+    }
+
+    public void testMixinNodeTypes1() throws JSONException, IOException {
+        Set<Object> mixins = this.toSet(new Object[]{ "xyz:mix1" });
+        String json = "{ \"jcr:mixinTypes\": " + this.toJsonArray(mixins) + "}";
+
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertEquals(mixins, node.getMixinNodeTypes());
+    }
+
+    public void testMixinNodeTypes2() throws JSONException, IOException {
+        Set<Object> mixins = this.toSet(new Object[]{ "xyz:mix1", "abc:mix2" });
+        String json = "{ \"jcr:mixinTypes\": " + this.toJsonArray(mixins) + "}";
+
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertEquals(mixins, node.getMixinNodeTypes());
+    }
+
+    public void testPropertiesNone() throws IOException, JSONException {
+        List<PropertyDescription> properties = null;
+        String json = "{ \"properties\": " + this.toJsonObject(properties) + "}";
+
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertEquals(properties, node.getProperties());
+    }
+
+    public void testPropertiesSingleValue() throws IOException, JSONException {
+        List<PropertyDescription> properties = new ArrayList<PropertyDescription>();
+        PropertyDescription prop = new PropertyDescription();
+        prop.setName("p1");
+        prop.setValue("v1");
+        properties.add(prop);
+        
+        String json = this.toJsonObject(properties).toString();
+        
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertEquals(new HashSet<PropertyDescription>(properties), new HashSet<PropertyDescription>(node.getProperties()));
+    }
+    
+    public void testPropertiesTwoSingleValue() throws IOException, JSONException {
+        List<PropertyDescription> properties = new ArrayList<PropertyDescription>();
+        PropertyDescription prop = new PropertyDescription();
+        prop.setName("p1");
+        prop.setValue("v1");
+        properties.add(prop);
+        prop = new PropertyDescription();
+        prop.setName("p2");
+        prop.setValue("v2");
+        properties.add(prop);
+
+        String json = this.toJsonObject(properties).toString();
+
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertEquals(new HashSet<PropertyDescription>(properties), new HashSet<PropertyDescription>(node.getProperties()));
+    }
+
+    public void testPropertiesMultiValue() throws IOException, JSONException {
+        List<PropertyDescription> properties = new ArrayList<PropertyDescription>();
+        PropertyDescription prop = new PropertyDescription();
+        prop.setName("p1");
+        prop.addValue("v1");
+        properties.add(prop);
+
+        String json = this.toJsonObject(properties).toString();
+
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertEquals(new HashSet<PropertyDescription>(properties), new HashSet<PropertyDescription>(node.getProperties()));
+    }
+
+    public void testPropertiesMultiValueEmpty() throws IOException, JSONException {
+        List<PropertyDescription> properties = new ArrayList<PropertyDescription>();
+        PropertyDescription prop = new PropertyDescription();
+        prop.setName("p1");
+        prop.addValue(null); // empty multivalue property
+        properties.add(prop);
+
+        String json = this.toJsonObject(properties).toString();
+
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertEquals(new HashSet<PropertyDescription>(properties), new HashSet<PropertyDescription>(node.getProperties()));
+    }
+
+    public void testChildrenNone() throws IOException, JSONException {
+        List<NodeDescription> nodes = null;
+        String json = this.toJsonObject(nodes).toString();
+
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertEquals(nodes, node.getChildren());
+    }
+
+    public void testChild() throws IOException, JSONException {
+        List<NodeDescription> nodes = new ArrayList<NodeDescription>();
+        NodeDescription child = new NodeDescription();
+        child.setName("p1");
+        nodes.add(child);
+
+        String json = this.toJsonObject(nodes).toString();
+
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertEquals(nodes, node.getChildren());
+    }
+
+    public void testChildWithMixin() throws IOException, JSONException {
+        List<NodeDescription> nodes = new ArrayList<NodeDescription>();
+        NodeDescription child = new NodeDescription();
+        child.setName("p1");
+        child.addMixinNodeType("p1:mix");
+        nodes.add(child);
+
+        String json = this.toJsonObject(nodes).toString();
+
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertEquals(nodes, node.getChildren());
+    }
+
+    public void testTwoChildren() throws IOException, JSONException {
+        List<NodeDescription> nodes = new ArrayList<NodeDescription>();
+        NodeDescription child = new NodeDescription();
+        child.setName("p1");
+        nodes.add(child);
+        child = new NodeDescription();
+        child.setName("p2");
+        nodes.add(child);
+
+        String json = this.toJsonObject(nodes).toString();
+
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertEquals(nodes, node.getChildren());
+    }
+
+    public void testChildWithProperty() throws IOException, JSONException {
+        List<NodeDescription> nodes = new ArrayList<NodeDescription>();
+        NodeDescription child = new NodeDescription();
+        child.setName("c1");
+        PropertyDescription prop = new PropertyDescription();
+        prop.setName("c1p1");
+        prop.setValue("c1v1");
+        child.addProperty(prop);
+        nodes.add(child);
+
+        String json = this.toJsonObject(nodes).toString();
+
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertEquals(nodes, node.getChildren());
+    }
+
+    //---------- internal helper ----------------------------------------------
+
+    private NodeDescription parse(String json) throws IOException {
+        String charSet = "ISO-8859-1";
+        json = "#" + charSet + "\r\n" + json;
+        InputStream ins = new ByteArrayInputStream(json.getBytes(charSet));
+        return this.jsonReader.parse(ins);
+    }
+
+    private Set<Object> toSet(Object[] content) {
+        Set<Object> set = new HashSet<Object>();
+        for (int i=0; content != null && i < content.length; i++) {
+            set.add(content[i]);
+        }
+
+        return set;
+    }
+
+    private JSONArray toJsonArray(Collection<?> set) throws JSONException {
+        List<Object> list = new ArrayList<Object>();
+        for (Object item : set) {
+            if (item instanceof NodeDescription) {
+                list.add(this.toJsonObject((NodeDescription) item));
+            } else {
+                list.add(item);
+            }
+        }
+        return new JSONArray(list);
+    }
+
+    private JSONObject toJsonObject(Collection<?> set) throws JSONException {
+        JSONObject obj = new JSONObject();
+        if (set != null) {
+            for (Object next: set) {
+                String name = this.getName(next);
+                obj.putOpt(name, this.toJsonObject(next));
+            }
+        }
+        return obj;
+    }
+
+    private Object toJsonObject(Object object) throws JSONException {
+        if (object instanceof NodeDescription) {
+            return this.toJsonObject((NodeDescription) object);
+        } else if (object instanceof PropertyDescription) {
+            return this.toJsonObject((PropertyDescription) object);
+        }
+
+        // fall back to string representation
+        return String.valueOf(object);
+    }
+
+    private JSONObject toJsonObject(NodeDescription node) throws JSONException {
+        JSONObject obj = new JSONObject();
+
+        if (node.getPrimaryNodeType() != null) {
+            obj.putOpt("jcr:primaryType", node.getPrimaryNodeType());
+        }
+
+        if (node.getMixinNodeTypes() != null) {
+            obj.putOpt("jcr:mixinTypes", this.toJsonArray(node.getMixinNodeTypes()));
+        }
+
+        if (node.getProperties() != null) {
+            for (PropertyDescription prop : node.getProperties()) {
+                obj.put(prop.getName(), toJsonObject(prop));
+            }
+        }
+
+        if (node.getChildren() != null) {
+            for (NodeDescription child : node.getChildren()) {
+                obj.put(child.getName(), toJsonObject(child));
+            }
+        }
+
+        return obj;
+    }
+
+    private Object toJsonObject(PropertyDescription property) throws JSONException {
+        if (!property.isMultiValue() && PropertyType.TYPENAME_STRING.equals(property.getType())) {
+            return this.toJsonObject(property.getValue());
+        }
+        Object obj;
+        if (property.isMultiValue()) {
+            obj = this.toJsonArray(property.getValues());
+        } else {
+            obj = this.toJsonObject(property.getValue());
+        }
+
+        return obj;
+    }
+
+    private String getName(Object object) {
+        if (object instanceof NodeDescription) {
+            return ((NodeDescription) object).getName();
+        } else if (object instanceof PropertyDescription) {
+            return ((PropertyDescription) object).getName();
+        }
+
+        // fall back to string representation
+        return String.valueOf(object);
+    }
+}

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-jcr-contentloader] 07/32: SLING-413: Handle bundle update and correctly handle overwrite flag.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit 525d242cd113069a9bba23db3f64afa56bb51841
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Mon May 5 10:14:26 2008 +0000

    SLING-413: Handle bundle update and correctly handle overwrite flag.
    
    git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader@653411 13f79535-47bb-0310-9956-ffa450edef68
---
 .../contentloader/internal/ContentLoaderService.java  | 15 ++++++++++++++-
 .../sling/jcr/contentloader/internal/Loader.java      | 19 ++++++++++++-------
 2 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java
index 0091df1..b3c05c6 100644
--- a/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java
@@ -20,7 +20,9 @@ package org.apache.sling.jcr.contentloader.internal;
 
 import java.util.Calendar;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 import java.util.StringTokenizer;
 
 import javax.jcr.Node;
@@ -90,6 +92,11 @@ public class ContentLoaderService implements SynchronousBundleListener {
      */
     private String slingId;
 
+    /**
+     * List of currently updated bundles.
+     */
+    private final Set<String> updatedBundles = new HashSet<String>();
+
     // ---------- BundleListener -----------------------------------------------
 
     /**
@@ -114,7 +121,8 @@ public class ContentLoaderService implements SynchronousBundleListener {
                 // we can safely add the content at this point.
                 try {
                     Session session = getAdminSession();
-                    initialContentLoader.registerBundle(session, event.getBundle(), false);
+                    final boolean isUpdate = this.updatedBundles.remove(event.getBundle().getSymbolicName());
+                    initialContentLoader.registerBundle(session, event.getBundle(), isUpdate);
                 } catch (Throwable t) {
                     log.error(
                         "bundleChanged: Problem loading initial content of bundle "
@@ -122,6 +130,11 @@ public class ContentLoaderService implements SynchronousBundleListener {
                             + event.getBundle().getBundleId() + ")", t);
                 }
                 break;
+            case BundleEvent.UPDATED:
+                // we just add the symbolic name to the list of updated bundles
+                // we will use this info when the new start event is triggered
+                this.updatedBundles.add(event.getBundle().getSymbolicName());
+                break;
             case BundleEvent.STOPPED:
                 try {
                     Session session = getAdminSession();
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/Loader.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/Loader.java
index 7a3355c..0f287cf 100644
--- a/src/main/java/org/apache/sling/jcr/contentloader/internal/Loader.java
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/Loader.java
@@ -152,7 +152,7 @@ public class Loader {
                 if ( !isUpdate && contentAlreadyLoaded ) {
                     log.info("Content of bundle already loaded {}.", bundle.getSymbolicName());
                 } else {
-                    this.installContent(session, bundle, pathIter);
+                    this.installContent(session, bundle, pathIter, contentAlreadyLoaded);
                     if (isRetry) {
                         // log success of retry
                         log.info(
@@ -197,20 +197,23 @@ public class Loader {
 
     // ---------- internal -----------------------------------------------------
 
-    private void installContent(Session session, Bundle bundle, final Iterator<PathEntry> pathIter)
+    private void installContent(final Session session,
+                                final Bundle bundle,
+                                final Iterator<PathEntry> pathIter,
+                                final boolean contentAlreadyLoaded)
     throws RepositoryException {
-        try {
-            log.debug("Installing initial content from bundle {}",
+        log.debug("Installing initial content from bundle {}",
                 bundle.getSymbolicName());
+        try {
             while (pathIter.hasNext() ) {
                 final PathEntry entry = pathIter.next();
-                this.installFromPath(bundle, entry.getPath(), entry.isOverwrite(), session.getRootNode());
+                if ( !contentAlreadyLoaded || entry.isOverwrite() ) {
+                    this.installFromPath(bundle, entry.getPath(), entry.isOverwrite(), session.getRootNode());
+                }
             }
 
             // persist modifications now
             session.save();
-            log.debug("Done installing initial content from bundle {}",
-                bundle.getSymbolicName());
         } finally {
             try {
                 if (session.hasPendingChanges()) {
@@ -222,6 +225,8 @@ public class Loader {
                     bundle.getSymbolicName(), re);
             }
         }
+        log.debug("Done installing initial content from bundle {}",
+                bundle.getSymbolicName());
 
     }
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-jcr-contentloader] 04/32: SLING-400: Move content loading to own bundle.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit 6adfd33834caa041231d1c1b802eff7a9bc403e7
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Apr 30 11:31:40 2008 +0000

    SLING-400: Move content loading to own bundle.
    
    git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader@652339 13f79535-47bb-0310-9956-ffa450edef68
---
 .../sling/jcr/contentloader/internal/Loader.java   |  2 +-
 .../jcr/contentloader/internal/PathEntry.java      | 28 ++++++++++++++++++----
 2 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/Loader.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/Loader.java
index 300b2f8..7a3355c 100644
--- a/src/main/java/org/apache/sling/jcr/contentloader/internal/Loader.java
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/Loader.java
@@ -658,7 +658,7 @@ public class Loader {
                 bundle.getSymbolicName());
             while (pathIter.hasNext() ) {
                 final PathEntry entry = pathIter.next();
-                if ( entry.isOverwrite() ) {
+                if ( entry.isUninstall() ) {
                     this.uninstallFromPath(bundle, entry.getPath(), session.getRootNode());
                 } else {
                     log.debug("Ignoring to uninstall content at {}, overwrite flag is not set.", entry.getPath());
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/PathEntry.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/PathEntry.java
index b9a0633..e70b561 100644
--- a/src/main/java/org/apache/sling/jcr/contentloader/internal/PathEntry.java
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/PathEntry.java
@@ -36,12 +36,18 @@ public class PathEntry {
     /** The overwrite flag specifying if content should be overwritten or just initially added. */
     public static final String OVERWRITE_FLAG = "overwrite";
 
+    /** The uninstall flag specifying if content should be uninstalled. */
+    public static final String UNINSTALL_FLAG = "uninstall";
+
     /** The path for the initial content. */
     private final String path;
 
     /** Should existing content be overwritten? */
     private final boolean overwrite;
 
+    /** Should existing content be uninstalled? */
+    private final boolean uninstall;
+
     public static Iterator<PathEntry> getContentPaths(final Bundle bundle) {
         final List<PathEntry> entries = new ArrayList<PathEntry>();
 
@@ -62,7 +68,8 @@ public class PathEntry {
 
     public PathEntry(String path) {
         // check for overwrite flag
-        boolean overwrite = false;
+        boolean overwriteFlag = false;
+        Boolean uninstallFlag = null;
         int flagPos = path.indexOf(";");
         if ( flagPos != -1 ) {
             final StringTokenizer flagTokenizer = new StringTokenizer(path.substring(flagPos+1), ";");
@@ -70,15 +77,24 @@ public class PathEntry {
                 final String token = flagTokenizer.nextToken();
                 int pos = token.indexOf(":=");
                 if ( pos != -1 ) {
-                    if ( token.substring(0, pos).equals(OVERWRITE_FLAG) ) {
-                        overwrite = Boolean.valueOf(token.substring(pos+2));
+                    final String name = token.substring(0, pos);
+                    final String value = token.substring(pos+2);
+                    if ( name.equals(OVERWRITE_FLAG) ) {
+                        overwriteFlag = Boolean.valueOf(value).booleanValue();
+                    } else if (name.equals(UNINSTALL_FLAG) ) {
+                        uninstallFlag = Boolean.valueOf(value);
                     }
                 }
             }
             path = path.substring(0, flagPos);
         }
         this.path = path;
-        this.overwrite = overwrite;
+        this.overwrite = overwriteFlag;
+        if ( uninstallFlag != null ) {
+            this.uninstall = uninstallFlag;
+        } else {
+            this.uninstall = this.overwrite;
+        }
     }
 
     public String getPath() {
@@ -88,4 +104,8 @@ public class PathEntry {
     public boolean isOverwrite() {
         return this.overwrite;
     }
+
+    public boolean isUninstall() {
+        return this.uninstall;
+    }
 }

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-jcr-contentloader] 17/32: SLING-495 - NOTICE files updated according to changes in revision 662927

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit 74d5c760abce0d8ddbbcbe17cb2e755a012311b2
Author: Bertrand Delacretaz <bd...@apache.org>
AuthorDate: Wed Jun 4 08:05:20 2008 +0000

    SLING-495 - NOTICE files updated according to changes in revision 662927
    
    git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader@663025 13f79535-47bb-0310-9956-ffa450edef68
---
 NOTICE | 20 ++++----------------
 1 file changed, 4 insertions(+), 16 deletions(-)

diff --git a/NOTICE b/NOTICE
index b2d1f0a..4a9b2df 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,23 +1,11 @@
 Apache Sling - Initial Content Loader
-Copyright 2007-2008 The Apache Software Foundation
 
-Based on source code originally developed by
-Day Software (http://www.day.com/).
+Apache Sling
+Copyright 2008 The Apache Software Foundation
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).
-Licensed under the Apache License 2.0.
-
-See http://www.apache.org/legal/3party.html for the ASF policy on 
-third-party licenses.
-
-This product includes software developed under the JCP from 
-http://www.jcp.org. Copyright 2005 Day Management AG.
 
-This product includes kXML2 software developed at 
-http://kxml.sourceforge.net/, under BSD license. 
-Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany.
-
-This product includes software developed at http://slf4j.org, distributed
-under the slf4j MIT-like license (http://slf4j.org/license.html). 
+Based on source code originally developed by
+Day Software (http://www.day.com/).
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-jcr-contentloader] 20/32: Use released versions (or soon to be released versions).

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit 538a808f9a012164f699acf954a8e78562c71a72
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Jun 4 15:06:54 2008 +0000

    Use released versions (or soon to be released versions).
    
    git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader@663157 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/pom.xml b/pom.xml
index 5aeb960..2326e0c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -98,27 +98,27 @@
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.jcr.api</artifactId>
-            <version>2.0.0-incubator-SNAPSHOT</version>
+            <version>2.0.0-incubator</version>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.commons.json</artifactId>
-            <version>2.0.0-incubator-SNAPSHOT</version>
+            <version>2.0.0-incubator</version>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.commons.mime</artifactId>
-            <version>2.0.0-incubator-SNAPSHOT</version>
+            <version>2.0.0-incubator</version>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.commons.osgi</artifactId>
-            <version>2.0.0-incubator-SNAPSHOT</version>
+            <version>2.0.0-incubator</version>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.engine</artifactId>
-            <version>2.0.0-incubator-SNAPSHOT</version>
+            <version>2.0.0-incubator</version>
         </dependency>
         <dependency>
             <groupId>org.slf4j</groupId>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-jcr-contentloader] 24/32: Fix reference to parent pom.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit 9fe2a8e74ac2f1f5acbb90f758c5a0970d6a403e
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Thu Jun 5 05:51:38 2008 +0000

    Fix reference to parent pom.
    
    git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader@663458 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index e325d9c..9bdddb2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
-        <version>1-incubator</version>
+        <version>2-incubator-SNAPSHOT</version>
         <relativePath>../../parent/pom.xml</relativePath>
     </parent>
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-jcr-contentloader] 12/32: SLING-365 Implement support for initial checkin of mix:versionable nodes on-demand

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit 97fa6059301d398d6a37cf6b30e426db1ce8fd07
Author: Felix Meschberger <fm...@apache.org>
AuthorDate: Wed May 21 08:43:58 2008 +0000

    SLING-365 Implement support for initial checkin of mix:versionable nodes on-demand
    
    git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader@658601 13f79535-47bb-0310-9956-ffa450edef68
---
 .../internal/ContentLoaderService.java             |   2 +-
 .../sling/jcr/contentloader/internal/Loader.java   | 420 +++++++++++++--------
 .../jcr/contentloader/internal/PathEntry.java      |  60 ++-
 3 files changed, 300 insertions(+), 182 deletions(-)

diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java
index af3c267..2d0612b 100644
--- a/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java
@@ -303,7 +303,7 @@ public class ContentLoaderService implements SynchronousBundleListener {
         return info;
     }
 
-    public void unlockBundleContentInto(final Session session,
+    public void unlockBundleContentInfo(final Session session,
                                         final Bundle  bundle,
                                         final boolean contentLoaded)
     throws RepositoryException {
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/Loader.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/Loader.java
index 6dd1cb0..ca6c28f 100644
--- a/src/main/java/org/apache/sling/jcr/contentloader/internal/Loader.java
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/Loader.java
@@ -88,48 +88,56 @@ public class Loader {
     }
 
     public void dispose() {
-        this.delayedReferences = null;
-        if (this.delayedBundles != null) {
-            this.delayedBundles.clear();
-            this.delayedBundles = null;
+        delayedReferences = null;
+        if (delayedBundles != null) {
+            delayedBundles.clear();
+            delayedBundles = null;
         }
-        this.jcrContentHelper = null;
-        this.importProviders.clear();
+        jcrContentHelper = null;
+        importProviders.clear();
     }
 
     /**
      * Register a bundle and install its content.
+     * 
      * @param session
      * @param bundle
      */
-    public void registerBundle(final Session session, final Bundle bundle, final boolean isUpdate) {
-        log.debug("Registering bundle {} for content loading.", bundle.getSymbolicName());
-        if (this.registerBundleInternal(session, bundle, false, isUpdate)) {
+    public void registerBundle(final Session session, final Bundle bundle,
+            final boolean isUpdate) {
+
+        log.debug("Registering bundle {} for content loading.",
+            bundle.getSymbolicName());
+
+        if (registerBundleInternal(session, bundle, false, isUpdate)) {
+
             // handle delayed bundles, might help now
             int currentSize = -1;
-            for (int i = this.delayedBundles.size(); i > 0
-                && currentSize != this.delayedBundles.size()
-                && !this.delayedBundles.isEmpty(); i--) {
-                for (Iterator<Bundle> di = this.delayedBundles.iterator(); di.hasNext();) {
+            for (int i = delayedBundles.size(); i > 0
+                && currentSize != delayedBundles.size()
+                && !delayedBundles.isEmpty(); i--) {
+
+                for (Iterator<Bundle> di = delayedBundles.iterator(); di.hasNext();) {
+
                     Bundle delayed = di.next();
-                    if (this.registerBundleInternal(session, delayed, true, false)) {
+                    if (registerBundleInternal(session, delayed, true, false)) {
                         di.remove();
                     }
+
                 }
-                currentSize = this.delayedBundles.size();
+
+                currentSize = delayedBundles.size();
             }
-        } else {
+
+        } else if (!isUpdate) {
             // add to delayed bundles - if this is not an update!
-            if ( !isUpdate ) {
-                this.delayedBundles.add(bundle);
-            }
+            delayedBundles.add(bundle);
         }
     }
 
     private boolean registerBundleInternal(final Session session,
-                                           final Bundle  bundle,
-                                           final boolean isRetry,
-                                           final boolean isUpdate) {
+            final Bundle bundle, final boolean isRetry, final boolean isUpdate) {
+
         // check if bundle has initial content
         final Iterator<PathEntry> pathIter = PathEntry.getContentPaths(bundle);
         if (pathIter == null) {
@@ -139,32 +147,48 @@ public class Loader {
         }
 
         try {
+            
             // check if the content has already been loaded
-            final Map<String, Object> bundleContentInfo = this.jcrContentHelper.getBundleContentInfo(session, bundle);
+            final Map<String, Object> bundleContentInfo = jcrContentHelper.getBundleContentInfo(
+                session, bundle);
+            
             // if we don't get an info, someone else is currently loading
-            if ( bundleContentInfo == null ) {
+            if (bundleContentInfo == null) {
                 return false;
             }
 
             boolean success = false;
             try {
-                final boolean contentAlreadyLoaded = ((Boolean)bundleContentInfo.get(ContentLoaderService.PROPERTY_CONTENT_LOADED)).booleanValue();
-                if ( !isUpdate && contentAlreadyLoaded ) {
-                    log.info("Content of bundle already loaded {}.", bundle.getSymbolicName());
+                
+                final boolean contentAlreadyLoaded = ((Boolean) bundleContentInfo.get(ContentLoaderService.PROPERTY_CONTENT_LOADED)).booleanValue();
+                
+                if (!isUpdate && contentAlreadyLoaded) {
+                    
+                    log.info("Content of bundle already loaded {}.",
+                        bundle.getSymbolicName());
+                    
                 } else {
-                    this.installContent(session, bundle, pathIter, contentAlreadyLoaded);
+                    
+                    installContent(session, bundle, pathIter,
+                        contentAlreadyLoaded);
+                    
                     if (isRetry) {
                         // log success of retry
                         log.info(
                             "Retrytring to load initial content for bundle {} succeeded.",
                             bundle.getSymbolicName());
                     }
+                    
                 }
+                
                 success = true;
                 return true;
+                
             } finally {
-                this.jcrContentHelper.unlockBundleContentInto(session, bundle, success);
+                jcrContentHelper.unlockBundleContentInfo(session, bundle,
+                    success);
             }
+            
         } catch (RepositoryException re) {
             // if we are retrying we already logged this message once, so we
             // won't log it again
@@ -178,44 +202,62 @@ public class Loader {
     }
 
     /**
-     * Unregister a bundle.
-     * Remove installed content.
+     * Unregister a bundle. Remove installed content.
+     * 
      * @param bundle The bundle.
      */
     public void unregisterBundle(final Session session, final Bundle bundle) {
+        
         // check if bundle has initial content
         final Iterator<PathEntry> pathIter = PathEntry.getContentPaths(bundle);
-        if (this.delayedBundles.contains(bundle)) {
-            this.delayedBundles.remove(bundle);
+        if (delayedBundles.contains(bundle)) {
+            
+            delayedBundles.remove(bundle);
+            
         } else {
-            if ( pathIter != null ) {
-                this.uninstallContent(session, bundle, pathIter);
-                this.jcrContentHelper.contentIsUninstalled(session, bundle);
+            
+            if (pathIter != null) {
+                uninstallContent(session, bundle, pathIter);
+                jcrContentHelper.contentIsUninstalled(session, bundle);
             }
+            
         }
     }
 
     // ---------- internal -----------------------------------------------------
 
-    private void installContent(final Session session,
-                                final Bundle bundle,
-                                final Iterator<PathEntry> pathIter,
-                                final boolean contentAlreadyLoaded)
-    throws RepositoryException {
+    private void installContent(final Session session, final Bundle bundle,
+            final Iterator<PathEntry> pathIter,
+            final boolean contentAlreadyLoaded) throws RepositoryException {
         log.debug("Installing initial content from bundle {}",
-                bundle.getSymbolicName());
+            bundle.getSymbolicName());
         try {
-            while (pathIter.hasNext() ) {
+
+            // the nodes marked to be checked-in after import
+            List<Node> versionables = new ArrayList<Node>();
+
+            while (pathIter.hasNext()) {
                 final PathEntry entry = pathIter.next();
-                if ( !contentAlreadyLoaded || entry.isOverwrite() ) {
-                	Node targetNode = this.getTargetNode(session, entry.getTarget());
-                	if (targetNode != null)
-                		this.installFromPath(bundle, entry.getPath(), entry.isOverwrite(), targetNode);
+                if (!contentAlreadyLoaded || entry.isOverwrite()) {
+                    
+                    Node targetNode = getTargetNode(session, entry.getTarget());
+
+                    if (targetNode != null) {
+                        installFromPath(bundle, entry.getPath(),
+                            entry.isOverwrite(), versionables,
+                            entry.isCheckin(), targetNode);
+                    }
                 }
             }
 
             // persist modifications now
             session.save();
+
+            // finally checkin versionable nodes
+            for (Node versionable : versionables) {
+                versionable.checkin();
+            }
+
         } finally {
             try {
                 if (session.hasPendingChanges()) {
@@ -228,23 +270,24 @@ public class Loader {
             }
         }
         log.debug("Done installing initial content from bundle {}",
-                bundle.getSymbolicName());
+            bundle.getSymbolicName());
 
     }
 
     /**
      * Handle content installation for a single path.
+     * 
      * @param bundle The bundle containing the content.
-     * @param path   The path
+     * @param path The path
      * @param overwrite Should the content be overwritten.
      * @param parent The parent node.
      * @throws RepositoryException
      */
-    private void installFromPath(final Bundle bundle,
-                                 final String path,
-                                 final boolean overwrite,
-                                 final Node parent)
-    throws RepositoryException {
+    private void installFromPath(final Bundle bundle, final String path,
+            final boolean overwrite, List<Node> versionables,
+            final boolean checkin, final Node parent)
+            throws RepositoryException {
+        
         @SuppressWarnings("unchecked")
         Enumeration<String> entries = bundle.getEntryPaths(path);
         if (entries == null) {
@@ -255,7 +298,8 @@ public class Loader {
         Set<URL> ignoreEntry = new HashSet<URL>();
 
         // potential root node import/extension
-        URL rootNodeDescriptor = importRootNode(parent.getSession(), bundle, path);
+        URL rootNodeDescriptor = importRootNode(parent.getSession(), bundle,
+            path, versionables, checkin);
         if (rootNodeDescriptor != null) {
             ignoreEntry.add(rootNodeDescriptor);
         }
@@ -264,9 +308,10 @@ public class Loader {
             final String entry = entries.nextElement();
             log.debug("Processing initial content entry {}", entry);
             if (entry.endsWith("/")) {
+                
                 // dir, check for node descriptor , else create dir
                 String base = entry.substring(0, entry.length() - 1);
-                String name = this.getName(base);
+                String name = getName(base);
 
                 URL nodeDescriptor = null;
                 for (String ext : importProviders.keySet()) {
@@ -282,18 +327,21 @@ public class Loader {
                 Node node = null;
                 if (nodeDescriptor != null
                     && !ignoreEntry.contains(nodeDescriptor)) {
-                    node = this.createNode(parent, name, nodeDescriptor, overwrite);
+                    node = createNode(parent, name, nodeDescriptor, overwrite,
+                        versionables, checkin);
                     ignoreEntry.add(nodeDescriptor);
                 } else {
-                    node = this.createFolder(parent, name, overwrite);
+                    node = createFolder(parent, name, overwrite);
                 }
 
                 // walk down the line
                 if (node != null) {
-                    this.installFromPath(bundle, entry, overwrite, node);
+                    installFromPath(bundle, entry, overwrite, versionables,
+                        checkin, node);
                 }
 
             } else {
+                
                 // file => create file
                 URL file = bundle.getEntry(entry);
                 if (ignoreEntry.contains(file)) {
@@ -303,15 +351,16 @@ public class Loader {
 
                 // install if it is a descriptor
                 boolean foundProvider = false;
-                final Iterator<String> ipIter = this.importProviders.keySet().iterator();
-                while ( !foundProvider && ipIter.hasNext() ) {
+                final Iterator<String> ipIter = importProviders.keySet().iterator();
+                while (!foundProvider && ipIter.hasNext()) {
                     final String ext = ipIter.next();
-                    if ( entry.endsWith(ext) ) {
+                    if (entry.endsWith(ext)) {
                         foundProvider = true;
                     }
                 }
                 if (foundProvider) {
-                    if (this.createNode(parent, this.getName(entry), file, overwrite) != null) {
+                    if (createNode(parent, getName(entry), file, overwrite,
+                        versionables, checkin) != null) {
                         ignoreEntry.add(file);
                         continue;
                     }
@@ -319,7 +368,7 @@ public class Loader {
 
                 // otherwise just place as file
                 try {
-                    this.createFile(parent, file);
+                    createFile(parent, file);
                 } catch (IOException ioe) {
                     log.warn("Cannot create file node for {}", file, ioe);
                 }
@@ -327,29 +376,9 @@ public class Loader {
         }
     }
 
-    /**
-     * Create a folder
-     * @param parent The parent node.
-     * @param name   The name of the folder
-     * @param overwrite If set to true, an existing folder is removed first.
-     * @return The node pointing to the folder.
-     * @throws RepositoryException
-     */
-    private Node createFolder(Node parent, String name, final boolean overwrite)
-    throws RepositoryException {
-        if (parent.hasNode(name)) {
-            if ( overwrite ) {
-                parent.getNode(name).remove();
-            } else {
-                return parent.getNode(name);
-            }
-        }
-
-        return parent.addNode(name, "nt:folder");
-    }
-
-    private Node createNode(Node parent, String name, URL nodeXML, boolean overwrite)
-    throws RepositoryException {
+    private Node createNode(Node parent, String name, URL nodeXML,
+            boolean overwrite, List<Node> versionables, boolean checkin)
+            throws RepositoryException {
 
         InputStream ins = null;
         try {
@@ -359,7 +388,7 @@ public class Loader {
             }
 
             NodeReader nodeReader = null;
-            for (Map.Entry<String, ImportProvider> e: importProviders.entrySet()) {
+            for (Map.Entry<String, ImportProvider> e : importProviders.entrySet()) {
                 if (nodeXML.getPath().toLowerCase().endsWith(e.getKey())) {
                     nodeReader = e.getValue().getReader();
                     break;
@@ -384,7 +413,7 @@ public class Loader {
                 clNode.setName(toPlainName(name));
             }
 
-            return this.createNode(parent, clNode, overwrite);
+            return createNode(parent, clNode, overwrite, versionables, checkin);
         } catch (RepositoryException re) {
             throw re;
         } catch (Throwable t) {
@@ -401,24 +430,25 @@ public class Loader {
 
     /**
      * Delete the node from the initial content.
+     * 
      * @param parent
      * @param name
      * @param nodeXML
      * @throws RepositoryException
      */
     private void deleteNode(Node parent, String name)
-    throws RepositoryException {
-        if ( parent.hasNode(name) ) {
+            throws RepositoryException {
+        if (parent.hasNode(name)) {
             parent.getNode(name).remove();
         }
     }
 
-    private Node createNode(Node parentNode,
-                            NodeDescription clNode,
-                            final boolean overwrite)
-    throws RepositoryException {
+    private Node createNode(Node parentNode, NodeDescription clNode,
+            final boolean overwrite, List<Node> versionables, boolean checkin)
+            throws RepositoryException {
+        
         // if node already exists but should be overwritten, delete it
-        if ( overwrite && parentNode.hasNode(clNode.getName()) ) {
+        if (overwrite && parentNode.hasNode(clNode.getName())) {
             parentNode.getNode(clNode.getName()).remove();
         }
 
@@ -441,11 +471,11 @@ public class Loader {
                 clNode.getPrimaryNodeType());
         }
 
-        return setupNode(node, clNode);
+        return setupNode(node, clNode, versionables, checkin);
     }
 
-    private Node setupNode(Node node,
-            NodeDescription clNode)
+    private Node setupNode(Node node, NodeDescription clNode,
+            List<Node> versionables, boolean checkin)
             throws RepositoryException {
 
         // ammend mixin node types
@@ -457,6 +487,10 @@ public class Loader {
             }
         }
 
+        // check if node is versionable
+        boolean addToVersionables = checkin
+            && node.isNodeType("mix:versionable");
+
         if (clNode.getProperties() != null) {
             for (PropertyDescription prop : clNode.getProperties()) {
                 if (node.hasProperty(prop.getName())
@@ -466,44 +500,91 @@ public class Loader {
 
                 int type = PropertyType.valueFromName(prop.getType());
                 if (prop.isMultiValue()) {
+
                     String[] values = prop.getValues().toArray(
                         new String[prop.getValues().size()]);
                     node.setProperty(prop.getName(), values, type);
+
                 } else if (type == PropertyType.REFERENCE) {
+
                     // need to resolve the reference
                     String propPath = node.getPath() + "/" + prop.getName();
-                    String uuid = this.getUUID(node.getSession(), propPath,
+                    String uuid = getUUID(node.getSession(), propPath,
                         prop.getValue());
                     if (uuid != null) {
                         node.setProperty(prop.getName(), uuid, type);
                     }
+
+                } else if ("jcr:isCheckedOut".equals(prop.getName())) {
+
+                    // don't try to write the property but record its state
+                    // for later checkin if set to false
+                    boolean checkedout = Boolean.valueOf(prop.getValue());
+                    if (!checkedout) {
+                        addToVersionables = true;
+                    }
+
                 } else {
+
                     node.setProperty(prop.getName(), prop.getValue(), type);
+
                 }
             }
         }
 
+        // add the current node to the list of versionables to be checked
+        // in at the end. This is done if checkin is true and the node is
+        // versionable or if the jcr:isCheckedOut property is false
+        if (addToVersionables) {
+            versionables.add(node);
+        }
+
+        // create child nodes from the descriptor
         if (clNode.getChildren() != null) {
             for (NodeDescription child : clNode.getChildren()) {
-                this.createNode(node, child, false);
+                createNode(node, child, false, versionables, checkin);
             }
         }
 
-        this.resolveReferences(node);
+        // resolve REFERENCE property values pointing to this node
+        resolveReferences(node);
 
         return node;
     }
 
     /**
+     * Create a folder
+     * 
+     * @param parent The parent node.
+     * @param name The name of the folder
+     * @param overwrite If set to true, an existing folder is removed first.
+     * @return The node pointing to the folder.
+     * @throws RepositoryException
+     */
+    private Node createFolder(Node parent, String name, final boolean overwrite)
+            throws RepositoryException {
+        if (parent.hasNode(name)) {
+            if (overwrite) {
+                parent.getNode(name).remove();
+            } else {
+                return parent.getNode(name);
+            }
+        }
+
+        return parent.addNode(name, "nt:folder");
+    }
+
+    /**
      * Create a file from the given url.
+     * 
      * @param parent
      * @param source
      * @throws IOException
      * @throws RepositoryException
      */
-    private void createFile(Node parent, URL source)
-    throws IOException, RepositoryException {
-        String name = this.getName(source.getPath());
+    private void createFile(Node parent, URL source) throws IOException,
+            RepositoryException {
+        String name = getName(source.getPath());
         if (parent.hasNode(name)) {
             return;
         }
@@ -515,7 +596,7 @@ public class Loader {
 
         // ensure content type
         if (type == null) {
-            type = this.jcrContentHelper.getMimeType(name);
+            type = jcrContentHelper.getMimeType(name);
             if (type == null) {
                 log.info(
                     "createFile: Cannot find content type for {}, using {}",
@@ -538,14 +619,15 @@ public class Loader {
 
     /**
      * Delete the file from the given url.
+     * 
      * @param parent
      * @param source
      * @throws IOException
      * @throws RepositoryException
      */
-    private void deleteFile(Node parent, URL source)
-    throws IOException, RepositoryException {
-        String name = this.getName(source.getPath());
+    private void deleteFile(Node parent, URL source) throws IOException,
+            RepositoryException {
+        String name = getName(source.getPath());
         if (parent.hasNode(name)) {
             parent.getNode(name).remove();
         }
@@ -563,10 +645,10 @@ public class Loader {
             }
         } else {
             // not existing yet, keep for delayed setting
-            List<String> current = this.delayedReferences.get(referencePath);
+            List<String> current = delayedReferences.get(referencePath);
             if (current == null) {
                 current = new ArrayList<String>();
-                this.delayedReferences.put(referencePath, current);
+                delayedReferences.put(referencePath, current);
             }
             current.add(propPath);
         }
@@ -576,7 +658,7 @@ public class Loader {
     }
 
     private void resolveReferences(Node node) throws RepositoryException {
-        List<String> props = this.delayedReferences.remove(node.getPath());
+        List<String> props = delayedReferences.remove(node.getPath());
         if (props == null || props.size() == 0) {
             return;
         }
@@ -590,8 +672,8 @@ public class Loader {
         String uuid = node.getUUID();
 
         for (String property : props) {
-            String name = this.getName(property);
-            Node parentNode = this.getParentNode(session, property);
+            String name = getName(property);
+            Node parentNode = getParentNode(session, property);
             if (parentNode != null) {
                 parentNode.setProperty(name, uuid, PropertyType.REFERENCE);
             }
@@ -607,7 +689,7 @@ public class Loader {
      * encoding. In this case, this method decodes the name using the
      * <code>java.netURLDecoder</code> class with the <i>UTF-8</i> character
      * encoding.
-     *
+     * 
      * @param path The path from which to extract the name part.
      * @return The URL decoded name part.
      */
@@ -658,36 +740,37 @@ public class Loader {
         Item item = session.getItem(path);
         return (item.isNode()) ? (Node) item : null;
     }
-    
+
     private Node getTargetNode(Session session, String path)
-    		throws RepositoryException {
-    	
-    	// not specyfied path directive
-    	if (path == null)
-    		return session.getRootNode();
-    	
-    	int firstSlash = path.indexOf("/");
-    	
-    	// it´s a relative path
-    	if (firstSlash != 0)
-    		path = "/" + path;
-    	
-    	Item item = session.getItem(path);
-    	return (item.isNode()) ? (Node) item : null;
+            throws RepositoryException {
+
+        // not specyfied path directive
+        if (path == null) return session.getRootNode();
+
+        int firstSlash = path.indexOf("/");
+
+        // it´s a relative path
+        if (firstSlash != 0) path = "/" + path;
+
+        Item item = session.getItem(path);
+        return (item.isNode()) ? (Node) item : null;
     }
 
-    private void uninstallContent(final Session session, final Bundle bundle, final Iterator<PathEntry> pathIter) {
+    private void uninstallContent(final Session session, final Bundle bundle,
+            final Iterator<PathEntry> pathIter) {
         try {
             log.debug("Uninstalling initial content from bundle {}",
                 bundle.getSymbolicName());
-            while (pathIter.hasNext() ) {
+            while (pathIter.hasNext()) {
                 final PathEntry entry = pathIter.next();
-                if ( entry.isUninstall() ) {
-                	Node targetNode = this.getTargetNode(session, entry.getTarget());
-                	if (targetNode != null)
-                		this.uninstallFromPath(bundle, entry.getPath(), targetNode);
+                if (entry.isUninstall()) {
+                    Node targetNode = getTargetNode(session, entry.getTarget());
+                    if (targetNode != null)
+                        uninstallFromPath(bundle, entry.getPath(), targetNode);
                 } else {
-                    log.debug("Ignoring to uninstall content at {}, uninstall directive is not set.", entry.getPath());
+                    log.debug(
+                        "Ignoring to uninstall content at {}, uninstall directive is not set.",
+                        entry.getPath());
                 }
             }
 
@@ -696,7 +779,8 @@ public class Loader {
             log.debug("Done uninstalling initial content from bundle {}",
                 bundle.getSymbolicName());
         } catch (RepositoryException re) {
-            log.error("Unable to uninstall initial content from bundle " + bundle.getSymbolicName(), re);
+            log.error("Unable to uninstall initial content from bundle "
+                + bundle.getSymbolicName(), re);
         } finally {
             try {
                 if (session.hasPendingChanges()) {
@@ -712,15 +796,14 @@ public class Loader {
 
     /**
      * Handle content uninstallation for a single path.
+     * 
      * @param bundle The bundle containing the content.
-     * @param path   The path
+     * @param path The path
      * @param parent The parent node.
      * @throws RepositoryException
      */
-    private void uninstallFromPath(final Bundle bundle,
-                                   final String path,
-                                   final Node parent)
-    throws RepositoryException {
+    private void uninstallFromPath(final Bundle bundle, final String path,
+            final Node parent) throws RepositoryException {
         @SuppressWarnings("unchecked")
         Enumeration<String> entries = bundle.getEntryPaths(path);
         if (entries == null) {
@@ -730,7 +813,7 @@ public class Loader {
         Set<URL> ignoreEntry = new HashSet<URL>();
 
         // potential root node import/extension
-        Descriptor rootNodeDescriptor = this.getRootNodeDescriptor(bundle, path);
+        Descriptor rootNodeDescriptor = getRootNodeDescriptor(bundle, path);
         if (rootNodeDescriptor != null) {
             ignoreEntry.add(rootNodeDescriptor.rootNodeDescriptor);
         }
@@ -741,7 +824,7 @@ public class Loader {
             if (entry.endsWith("/")) {
                 // dir, check for node descriptor , else create dir
                 String base = entry.substring(0, entry.length() - 1);
-                String name = this.getName(base);
+                String name = getName(base);
 
                 URL nodeDescriptor = null;
                 for (String ext : importProviders.keySet()) {
@@ -755,19 +838,21 @@ public class Loader {
                 boolean delete = false;
                 if (nodeDescriptor != null
                     && !ignoreEntry.contains(nodeDescriptor)) {
-                    node = (parent.hasNode(toPlainName(name)) ? parent.getNode(toPlainName(name)) : null);
+                    node = (parent.hasNode(toPlainName(name))
+                            ? parent.getNode(toPlainName(name))
+                            : null);
                     delete = true;
                 } else {
                     node = (parent.hasNode(name) ? parent.getNode(name) : null);
                 }
 
-                if ( node != null ) {
+                if (node != null) {
                     // walk down the line
-                    this.uninstallFromPath(bundle, entry, node);
+                    uninstallFromPath(bundle, entry, node);
                 }
 
                 if (delete) {
-                    this.deleteNode(parent, toPlainName(name));
+                    deleteNode(parent, toPlainName(name));
                     ignoreEntry.add(nodeDescriptor);
                 }
 
@@ -781,22 +866,22 @@ public class Loader {
 
                 // uninstall if it is a descriptor
                 boolean foundProvider = false;
-                final Iterator<String> ipIter = this.importProviders.keySet().iterator();
-                while ( !foundProvider && ipIter.hasNext() ) {
+                final Iterator<String> ipIter = importProviders.keySet().iterator();
+                while (!foundProvider && ipIter.hasNext()) {
                     final String ext = ipIter.next();
-                    if ( entry.endsWith(ext) ) {
+                    if (entry.endsWith(ext)) {
                         foundProvider = true;
                     }
                 }
                 if (foundProvider) {
-                    this.deleteNode(parent, toPlainName(this.getName(entry)));
+                    deleteNode(parent, toPlainName(getName(entry)));
                     ignoreEntry.add(file);
                     continue;
                 }
 
                 // otherwise just delete the file
                 try {
-                    this.deleteFile(parent, file);
+                    deleteFile(parent, file);
                 } catch (IOException ioe) {
                     log.warn("Cannot delete file node for {}", file, ioe);
                 }
@@ -808,7 +893,7 @@ public class Loader {
      * Import the XML file as JCR system or document view import. If the XML
      * file is not a valid system or document view export/import file,
      * <code>false</code> is returned.
-     *
+     * 
      * @param parent The parent node below which to import
      * @param nodeXML The URL to the XML file to import
      * @return <code>true</code> if the import succeeds, <code>false</code>
@@ -868,18 +953,21 @@ public class Loader {
 
     protected static final class Descriptor {
         public URL rootNodeDescriptor;
+
         public NodeReader nodeReader;
     }
 
     /**
      * Return the root node descriptor.
      */
-    private Descriptor getRootNodeDescriptor(final Bundle bundle, final String path) {
+    private Descriptor getRootNodeDescriptor(final Bundle bundle,
+            final String path) {
         URL rootNodeDescriptor = null;
 
         for (Map.Entry<String, ImportProvider> e : importProviders.entrySet()) {
             if (e.getValue() != null) {
-                rootNodeDescriptor = bundle.getEntry(path + ROOT_DESCRIPTOR + e.getKey());
+                rootNodeDescriptor = bundle.getEntry(path + ROOT_DESCRIPTOR
+                    + e.getKey());
                 if (rootNodeDescriptor != null) {
                     try {
                         final Descriptor d = new Descriptor();
@@ -887,7 +975,8 @@ public class Loader {
                         d.nodeReader = e.getValue().getReader();
                         return d;
                     } catch (IOException ioe) {
-                        this.log.error("Unable to setup node reader for " + e.getKey(), ioe);
+                        log.error("Unable to setup node reader for "
+                            + e.getKey(), ioe);
                         return null;
                     }
                 }
@@ -900,9 +989,10 @@ public class Loader {
      * Imports mixin nodes and properties (and optionally child nodes) of the
      * root node.
      */
-    private URL importRootNode(Session session, Bundle bundle, String path)
-    throws RepositoryException {
-        final Descriptor descriptor = this.getRootNodeDescriptor(bundle, path);
+    private URL importRootNode(Session session, Bundle bundle, String path,
+            List<Node> versionables, boolean checkin)
+            throws RepositoryException {
+        final Descriptor descriptor = getRootNodeDescriptor(bundle, path);
         // no root descriptor found
         if (descriptor == null) {
             return null;
@@ -914,7 +1004,7 @@ public class Loader {
             ins = descriptor.rootNodeDescriptor.openStream();
             NodeDescription clNode = descriptor.nodeReader.parse(ins);
 
-            setupNode(session.getRootNode(), clNode);
+            setupNode(session.getRootNode(), clNode, versionables, checkin);
 
             return descriptor.rootNodeDescriptor;
         } catch (RepositoryException re) {
@@ -934,10 +1024,10 @@ public class Loader {
 
     private String toPlainName(String name) {
         String providerExt = null;
-        final Iterator<String> ipIter = this.importProviders.keySet().iterator();
-        while ( providerExt == null && ipIter.hasNext() ) {
+        final Iterator<String> ipIter = importProviders.keySet().iterator();
+        while (providerExt == null && ipIter.hasNext()) {
             final String ext = ipIter.next();
-            if ( name.endsWith(ext) ) {
+            if (name.endsWith(ext)) {
                 providerExt = ext;
             }
         }
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/PathEntry.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/PathEntry.java
index 6369bc4..cfb8c24 100644
--- a/src/main/java/org/apache/sling/jcr/contentloader/internal/PathEntry.java
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/PathEntry.java
@@ -33,15 +33,27 @@ public class PathEntry {
     /** The manifest header to specify initial content to be loaded. */
     public static final String CONTENT_HEADER = "Sling-Initial-Content";
 
-    /** The overwrite directive specifying if content should be overwritten or just initially added. */
+    /**
+     * The overwrite directive specifying if content should be overwritten or
+     * just initially added.
+     */
     public static final String OVERWRITE_DIRECTIVE = "overwrite";
 
     /** The uninstall directive specifying if content should be uninstalled. */
     public static final String UNINSTALL_DIRECTIVE = "uninstall";
-    
-    /** The path directive specifying the target node where initial content will be loaded. */
+
+    /**
+     * The path directive specifying the target node where initial content will
+     * be loaded.
+     */
     public static final String PATH_DIRECTIVE = "path";
 
+    /**
+     * The checkin directive specifying whether versionable nodes should be
+     * checked in
+     */
+    public static final String CHECKIN_DIRECTIVE = "checkin";
+
     /** The path for the initial content. */
     private final String path;
 
@@ -51,7 +63,13 @@ public class PathEntry {
     /** Should existing content be uninstalled? */
     private final boolean uninstall;
     
-    /** Target path where initial content will be loaded. If it´s null then target node is the root node */
+    /** Should versionable nodes be checked in? */
+    private final boolean checkin;
+
+    /**
+     * Target path where initial content will be loaded. If it´s null then
+     * target node is the root node
+     */
     private final String target;
 
     public static Iterator<PathEntry> getContentPaths(final Bundle bundle) {
@@ -60,12 +78,12 @@ public class PathEntry {
         final String root = (String) bundle.getHeaders().get(CONTENT_HEADER);
         if (root != null) {
             final ManifestHeader header = ManifestHeader.parse(root);
-            for(final ManifestHeader.Entry entry : header.getEntries()) {
+            for (final ManifestHeader.Entry entry : header.getEntries()) {
                 entries.add(new PathEntry(entry));
             }
         }
 
-        if ( entries.size() == 0 ) {
+        if (entries.size() == 0) {
             return null;
         }
         return entries.iterator();
@@ -76,21 +94,27 @@ public class PathEntry {
         final String overwriteValue = entry.getDirectiveValue(OVERWRITE_DIRECTIVE);
         final String uninstallValue = entry.getDirectiveValue(UNINSTALL_DIRECTIVE);
         final String pathValue = entry.getDirectiveValue(PATH_DIRECTIVE);
+        final String checkinValue = entry.getDirectiveValue(CHECKIN_DIRECTIVE);
         boolean overwriteFlag = false;
-        if ( overwriteValue != null ) {
-            overwriteFlag = Boolean.valueOf(overwriteValue).booleanValue();
+        if (overwriteValue != null) {
+            overwriteFlag = Boolean.valueOf(overwriteValue);
         }
-        this.path =  entry.getValue();
+        this.path = entry.getValue();
         this.overwrite = overwriteFlag;
-        if ( uninstallValue != null ) {
+        if (uninstallValue != null) {
             this.uninstall = Boolean.valueOf(uninstallValue);
         } else {
             this.uninstall = this.overwrite;
         }
-        if ( pathValue != null ) {
-        	this.target = pathValue;
+        if (pathValue != null) {
+            this.target = pathValue;
         } else {
-        	this.target = null;
+            this.target = null;
+        }
+        if (checkinValue != null) {
+            this.checkin = Boolean.valueOf(checkinValue);
+        } else {
+            this.checkin = false;
         }
     }
 
@@ -106,7 +130,11 @@ public class PathEntry {
         return this.uninstall;
     }
 
-	public String getTarget() {
-		return target;
-	}
+    public boolean isCheckin() {
+        return this.checkin;
+    }
+    
+    public String getTarget() {
+        return target;
+    }
 }

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-jcr-contentloader] 19/32: Use released version of parent pom.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit 9b24eb4166c0b2aa912d8c3de99a03953add301d
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Jun 4 14:16:40 2008 +0000

    Use released version of parent pom.
    
    git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader@663109 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index 7a6ebf7..5aeb960 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
-        <version>1-incubator-SNAPSHOT</version>
+        <version>1-incubator</version>
         <relativePath>../../parent/pom.xml</relativePath>
     </parent>
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-jcr-contentloader] 21/32: [maven-release-plugin] prepare release org.apache.sling.jcr.contentloader-2.0.0-incubator

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit ffa3b1ca8025f4e364f21ee1bfa12619d9aea6b9
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Jun 4 15:33:17 2008 +0000

    [maven-release-plugin] prepare release org.apache.sling.jcr.contentloader-2.0.0-incubator
    
    git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader@663216 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/pom.xml b/pom.xml
index 2326e0c..921ad59 100644
--- a/pom.xml
+++ b/pom.xml
@@ -27,7 +27,7 @@
     </parent>
 
     <artifactId>org.apache.sling.jcr.contentloader</artifactId>
-    <version>2.0.0-incubator-SNAPSHOT</version>
+    <version>2.0.0-incubator</version>
     <packaging>bundle</packaging>
 
     <name>Sling - Initial Content Loader</name>
@@ -36,15 +36,9 @@
     </description>
 
     <scm>
-        <connection>
-            scm:svn:http://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader
-        </connection>
-        <developerConnection>
-            scm:svn:https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader
-        </developerConnection>
-        <url>
-            http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/contentloader
-        </url>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/incubator/sling/tags/org.apache.sling.jcr.contentloader-2.0.0-incubator</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/incubator/sling/tags/org.apache.sling.jcr.contentloader-2.0.0-incubator</developerConnection>
+        <url>http://svn.apache.org/viewvc/incubator/sling/tags/org.apache.sling.jcr.contentloader-2.0.0-incubator</url>
     </scm>
 
     <build>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-jcr-contentloader] 30/32: [maven-release-plugin] copy for tag org.apache.sling.jcr.contentloader-2.0.2-incubator

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit d21d415c540b647f7dc8c46de1690636e7046430
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Tue Jun 17 07:27:44 2008 +0000

    [maven-release-plugin]  copy for tag org.apache.sling.jcr.contentloader-2.0.2-incubator
    
    git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/tags/org.apache.sling.jcr.contentloader-2.0.2-incubator@668474 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/pom.xml b/pom.xml
index 9bdddb2..55725f2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,12 +22,12 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
-        <version>2-incubator-SNAPSHOT</version>
+        <version>3-incubator</version>
         <relativePath>../../parent/pom.xml</relativePath>
     </parent>
 
     <artifactId>org.apache.sling.jcr.contentloader</artifactId>
-    <version>2.0.1-incubator-SNAPSHOT</version>
+    <version>2.0.2-incubator</version>
     <packaging>bundle</packaging>
 
     <name>Sling - Initial Content Loader</name>
@@ -36,9 +36,9 @@
     </description>
 
     <scm>
-        <connection>scm:svn:http://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader</connection>
-        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader</developerConnection>
-        <url>http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/contentloader</url>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/incubator/sling/tags/org.apache.sling.jcr.contentloader-2.0.2-incubator</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/incubator/sling/tags/org.apache.sling.jcr.contentloader-2.0.2-incubator</developerConnection>
+        <url>http://svn.apache.org/viewvc/incubator/sling/tags/org.apache.sling.jcr.contentloader-2.0.2-incubator</url>
     </scm>
 
     <build>
@@ -92,27 +92,27 @@
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.jcr.api</artifactId>
-            <version>2.0.1-incubator-SNAPSHOT</version>
+            <version>2.0.2-incubator</version>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.commons.json</artifactId>
-            <version>2.0.1-incubator-SNAPSHOT</version>
+            <version>2.0.2-incubator</version>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.commons.mime</artifactId>
-            <version>2.0.1-incubator-SNAPSHOT</version>
+            <version>2.0.2-incubator</version>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.commons.osgi</artifactId>
-            <version>2.0.1-incubator-SNAPSHOT</version>
+            <version>2.0.2-incubator</version>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.engine</artifactId>
-            <version>2.0.1-incubator-SNAPSHOT</version>
+            <version>2.0.2-incubator</version>
         </dependency>
         <dependency>
             <groupId>org.slf4j</groupId>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-jcr-contentloader] 16/32: SLING-495 - NOTICE files generated using mknotice script

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit 7857ffdcba0ea1e64988fff845097410c00d3d1b
Author: Bertrand Delacretaz <bd...@apache.org>
AuthorDate: Tue Jun 3 12:24:26 2008 +0000

    SLING-495 - NOTICE files generated using mknotice script
    
    git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader@662766 13f79535-47bb-0310-9956-ffa450edef68
---
 NOTICE | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/NOTICE b/NOTICE
index 627ed1f..b2d1f0a 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,4 +1,4 @@
-Apache Sling Initial Content Loader
+Apache Sling - Initial Content Loader
 Copyright 2007-2008 The Apache Software Foundation
 
 Based on source code originally developed by
@@ -8,5 +8,16 @@ This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).
 Licensed under the Apache License 2.0.
 
-This product includes software from http://kxml.sourceforge.net.
+See http://www.apache.org/legal/3party.html for the ASF policy on 
+third-party licenses.
+
+This product includes software developed under the JCP from 
+http://www.jcp.org. Copyright 2005 Day Management AG.
+
+This product includes kXML2 software developed at 
+http://kxml.sourceforge.net/, under BSD license. 
 Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany.
+
+This product includes software developed at http://slf4j.org, distributed
+under the slf4j MIT-like license (http://slf4j.org/license.html). 
+

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-jcr-contentloader] 18/32: SLING-495 - NOTICE files regenerated with revision 663097 changes

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit 60e1c2760e79206fb49c81c6f6cc4709c761419c
Author: Bertrand Delacretaz <bd...@apache.org>
AuthorDate: Wed Jun 4 13:50:29 2008 +0000

    SLING-495 - NOTICE files regenerated with revision 663097 changes
    
    git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader@663098 13f79535-47bb-0310-9956-ffa450edef68
---
 NOTICE | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/NOTICE b/NOTICE
index 4a9b2df..20ac2e3 100644
--- a/NOTICE
+++ b/NOTICE
@@ -6,6 +6,6 @@ Copyright 2008 The Apache Software Foundation
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).
 
-Based on source code originally developed by
-Day Software (http://www.day.com/).
+Apache Sling is based on source code originally developed 
+by Day Software (http://www.day.com/).
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-jcr-contentloader] 08/32: SLING-412: Remove support for "name" property which defines the name of the root node imported through json.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit 76f7b769214271b93035579a6b8a9b923e6f79af
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Mon May 5 10:16:45 2008 +0000

    SLING-412: Remove support for "name" property which defines the name of the root node imported through json.
    
    git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader@653413 13f79535-47bb-0310-9956-ffa450edef68
---
 .../apache/sling/jcr/contentloader/internal/JsonReader.java   | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/JsonReader.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/JsonReader.java
index 4b5a1e5..ef5c4b4 100644
--- a/src/main/java/org/apache/sling/jcr/contentloader/internal/JsonReader.java
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/JsonReader.java
@@ -59,7 +59,7 @@ class JsonReader implements NodeReader {
             return jsonReader;
         }
     };
-    
+
     public NodeDescription parse(InputStream ins) throws IOException {
         try {
             String jsonString = toString(ins).trim();
@@ -68,8 +68,7 @@ class JsonReader implements NodeReader {
             }
 
             JSONObject json = new JSONObject(jsonString);
-            String name = json.optString("name", null); // allow for no name !
-            return this.createNode(name, json);
+            return this.createNode(null, json);
 
         } catch (JSONException je) {
             throw (IOException) new IOException(je.getMessage()).initCause(je);
@@ -156,12 +155,12 @@ class JsonReader implements NodeReader {
         // fall back to default
         return PropertyType.TYPENAME_STRING;
     }
-    
+
     private String toString(InputStream ins) throws IOException {
         if (!ins.markSupported()) {
             ins = new BufferedInputStream(ins);
         }
-        
+
         String encoding;
         ins.mark(5);
         int c = ins.read();
@@ -184,7 +183,7 @@ class JsonReader implements NodeReader {
             bos.write(buf, 0, rd);
         }
         bos.close(); // just to comply with the contract
-        
+
         return new String(bos.toByteArray(), encoding);
     }
 }

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-jcr-contentloader] 28/32: Change copyright year to 2008.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit 7085ebfe301b653856d8e32dd1a777862597a3a9
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Mon Jun 16 12:08:14 2008 +0000

    Change copyright year to 2008.
    
    git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader@668130 13f79535-47bb-0310-9956-ffa450edef68
---
 NOTICE                             | 2 +-
 src/main/resources/META-INF/NOTICE | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/NOTICE b/NOTICE
index e88123e..f31ecff 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,5 +1,5 @@
 Apache Sling Initial Content Loader
-Copyright 2007-2008 The Apache Software Foundation
+Copyright 2008 The Apache Software Foundation
 
 Apache Sling is based on source code originally developed 
 by Day Software (http://www.day.com/).
diff --git a/src/main/resources/META-INF/NOTICE b/src/main/resources/META-INF/NOTICE
index b501150..fdc2970 100644
--- a/src/main/resources/META-INF/NOTICE
+++ b/src/main/resources/META-INF/NOTICE
@@ -1,5 +1,5 @@
 Apache Sling Initial Content Loader
-Copyright 2007-2008 The Apache Software Foundation
+Copyright 2008 The Apache Software Foundation
 
 Apache Sling is based on source code originally developed 
 by Day Software (http://www.day.com/).

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-jcr-contentloader] 26/32: SLING-521: Separate between notice files for bin and src dists.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit b037f128b776e954b2e13234df8b12de6c6b82d0
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Fri Jun 13 12:55:50 2008 +0000

    SLING-521: Separate between notice files for bin and src dists.
    
    git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader@667512 13f79535-47bb-0310-9956-ffa450edef68
---
 NOTICE                                             |   4 -
 README.txt                                         |  38 ++++
 .../main/resources/META-INF/DISCLAIMER             |   0
 src/main/resources/META-INF/LICENSE                | 202 +++++++++++++++++++++
 .../main/resources/META-INF/LICENSE.kxml2          |   0
 NOTICE => src/main/resources/META-INF/NOTICE       |   1 -
 6 files changed, 240 insertions(+), 5 deletions(-)

diff --git a/NOTICE b/NOTICE
index 15f72f3..e88123e 100644
--- a/NOTICE
+++ b/NOTICE
@@ -6,7 +6,3 @@ by Day Software (http://www.day.com/).
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).
-Licensed under the Apache License 2.0.
-
-This product includes software from http://kxml.sourceforge.net.
-Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany.
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..7b3e5ab
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,38 @@
+Apache Sling Initial Content Loader
+
+WE NEED A LOT MORE HERE!!!!!!!!!!!!!!!!!!
+
+
+Disclaimer
+==========
+Apache Sling is an effort undergoing incubation at The Apache Software Foundation (ASF),
+sponsored by the Apache Jackrabbit PMC. Incubation is required of all newly accepted
+projects until a further review indicates that the infrastructure, communications,
+and decision making process have stabilized in a manner consistent with other
+successful ASF projects. While incubation status is not necessarily a reflection of
+the completeness or stability of the code, it does indicate that the project has yet
+to be fully endorsed by the ASF.
+
+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/incubator/sling/trunk/jcr/contentloader
+
+See the Subversion documentation for other source control features.
+
diff --git a/DISCLAIMER b/src/main/resources/META-INF/DISCLAIMER
similarity index 100%
rename from DISCLAIMER
rename to src/main/resources/META-INF/DISCLAIMER
diff --git a/src/main/resources/META-INF/LICENSE b/src/main/resources/META-INF/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/src/main/resources/META-INF/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/LICENSE.kxml2 b/src/main/resources/META-INF/LICENSE.kxml2
similarity index 100%
rename from LICENSE.kxml2
rename to src/main/resources/META-INF/LICENSE.kxml2
diff --git a/NOTICE b/src/main/resources/META-INF/NOTICE
similarity index 91%
copy from NOTICE
copy to src/main/resources/META-INF/NOTICE
index 15f72f3..b501150 100644
--- a/NOTICE
+++ b/src/main/resources/META-INF/NOTICE
@@ -6,7 +6,6 @@ by Day Software (http://www.day.com/).
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).
-Licensed under the Apache License 2.0.
 
 This product includes software from http://kxml.sourceforge.net.
 Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany.

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-jcr-contentloader] 11/32: SLING-453: Initial content loading to target location https://issues.apache.org/jira/browse/SLING-453

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit 55e57718ba318c1172ec8776c9cefd24f7b860cb
Author: Juan Vazquez <jv...@apache.org>
AuthorDate: Tue May 20 10:29:07 2008 +0000

    SLING-453: Initial content loading to target location
    https://issues.apache.org/jira/browse/SLING-453
    
    git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader@658192 13f79535-47bb-0310-9956-ffa450edef68
---
 .../sling/jcr/contentloader/internal/Loader.java   | 27 ++++++++++++++++---
 .../jcr/contentloader/internal/PathEntry.java      | 30 +++++++++++++++++-----
 2 files changed, 47 insertions(+), 10 deletions(-)

diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/Loader.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/Loader.java
index 0f287cf..6dd1cb0 100644
--- a/src/main/java/org/apache/sling/jcr/contentloader/internal/Loader.java
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/Loader.java
@@ -208,7 +208,9 @@ public class Loader {
             while (pathIter.hasNext() ) {
                 final PathEntry entry = pathIter.next();
                 if ( !contentAlreadyLoaded || entry.isOverwrite() ) {
-                    this.installFromPath(bundle, entry.getPath(), entry.isOverwrite(), session.getRootNode());
+                	Node targetNode = this.getTargetNode(session, entry.getTarget());
+                	if (targetNode != null)
+                		this.installFromPath(bundle, entry.getPath(), entry.isOverwrite(), targetNode);
                 }
             }
 
@@ -656,6 +658,23 @@ public class Loader {
         Item item = session.getItem(path);
         return (item.isNode()) ? (Node) item : null;
     }
+    
+    private Node getTargetNode(Session session, String path)
+    		throws RepositoryException {
+    	
+    	// not specyfied path directive
+    	if (path == null)
+    		return session.getRootNode();
+    	
+    	int firstSlash = path.indexOf("/");
+    	
+    	// it´s a relative path
+    	if (firstSlash != 0)
+    		path = "/" + path;
+    	
+    	Item item = session.getItem(path);
+    	return (item.isNode()) ? (Node) item : null;
+    }
 
     private void uninstallContent(final Session session, final Bundle bundle, final Iterator<PathEntry> pathIter) {
         try {
@@ -664,9 +683,11 @@ public class Loader {
             while (pathIter.hasNext() ) {
                 final PathEntry entry = pathIter.next();
                 if ( entry.isUninstall() ) {
-                    this.uninstallFromPath(bundle, entry.getPath(), session.getRootNode());
+                	Node targetNode = this.getTargetNode(session, entry.getTarget());
+                	if (targetNode != null)
+                		this.uninstallFromPath(bundle, entry.getPath(), targetNode);
                 } else {
-                    log.debug("Ignoring to uninstall content at {}, overwrite flag is not set.", entry.getPath());
+                    log.debug("Ignoring to uninstall content at {}, uninstall directive is not set.", entry.getPath());
                 }
             }
 
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/PathEntry.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/PathEntry.java
index c85a0b2..6369bc4 100644
--- a/src/main/java/org/apache/sling/jcr/contentloader/internal/PathEntry.java
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/PathEntry.java
@@ -33,11 +33,14 @@ public class PathEntry {
     /** The manifest header to specify initial content to be loaded. */
     public static final String CONTENT_HEADER = "Sling-Initial-Content";
 
-    /** The overwrite flag specifying if content should be overwritten or just initially added. */
-    public static final String OVERWRITE_FLAG = "overwrite";
+    /** The overwrite directive specifying if content should be overwritten or just initially added. */
+    public static final String OVERWRITE_DIRECTIVE = "overwrite";
 
-    /** The uninstall flag specifying if content should be uninstalled. */
-    public static final String UNINSTALL_FLAG = "uninstall";
+    /** The uninstall directive specifying if content should be uninstalled. */
+    public static final String UNINSTALL_DIRECTIVE = "uninstall";
+    
+    /** The path directive specifying the target node where initial content will be loaded. */
+    public static final String PATH_DIRECTIVE = "path";
 
     /** The path for the initial content. */
     private final String path;
@@ -47,6 +50,9 @@ public class PathEntry {
 
     /** Should existing content be uninstalled? */
     private final boolean uninstall;
+    
+    /** Target path where initial content will be loaded. If it´s null then target node is the root node */
+    private final String target;
 
     public static Iterator<PathEntry> getContentPaths(final Bundle bundle) {
         final List<PathEntry> entries = new ArrayList<PathEntry>();
@@ -66,9 +72,10 @@ public class PathEntry {
     }
 
     public PathEntry(ManifestHeader.Entry entry) {
-        // check for overwrite and uninstall flag
-        final String overwriteValue = entry.getDirectiveValue(OVERWRITE_FLAG);
-        final String uninstallValue = entry.getDirectiveValue(UNINSTALL_FLAG);
+        // check for directives
+        final String overwriteValue = entry.getDirectiveValue(OVERWRITE_DIRECTIVE);
+        final String uninstallValue = entry.getDirectiveValue(UNINSTALL_DIRECTIVE);
+        final String pathValue = entry.getDirectiveValue(PATH_DIRECTIVE);
         boolean overwriteFlag = false;
         if ( overwriteValue != null ) {
             overwriteFlag = Boolean.valueOf(overwriteValue).booleanValue();
@@ -80,6 +87,11 @@ public class PathEntry {
         } else {
             this.uninstall = this.overwrite;
         }
+        if ( pathValue != null ) {
+        	this.target = pathValue;
+        } else {
+        	this.target = null;
+        }
     }
 
     public String getPath() {
@@ -93,4 +105,8 @@ public class PathEntry {
     public boolean isUninstall() {
         return this.uninstall;
     }
+
+	public String getTarget() {
+		return target;
+	}
 }

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-jcr-contentloader] 25/32: SLING-521: Restore more notice files.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit 5f28fb691af651c644dcb54422e399f644dffbbb
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Tue Jun 10 15:25:55 2008 +0000

    SLING-521: Restore more notice files.
    
    git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader@666152 13f79535-47bb-0310-9956-ffa450edef68
---
 NOTICE | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/NOTICE b/NOTICE
index 20ac2e3..15f72f3 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,11 +1,12 @@
-Apache Sling - Initial Content Loader
+Apache Sling Initial Content Loader
+Copyright 2007-2008 The Apache Software Foundation
 
-Apache Sling
-Copyright 2008 The Apache Software Foundation
+Apache Sling is based on source code originally developed 
+by Day Software (http://www.day.com/).
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).
+Licensed under the Apache License 2.0.
 
-Apache Sling is based on source code originally developed 
-by Day Software (http://www.day.com/).
-
+This product includes software from http://kxml.sourceforge.net.
+Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany.

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-jcr-contentloader] 02/32: SLING-400: Move content loading to own bundle.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit e7c3f36531d364510618407bd2ca8cf50d34d4a0
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Apr 30 07:05:59 2008 +0000

    SLING-400: Move content loading to own bundle.
    
    git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader@652308 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                            |  10 +-
 .../internal/ContentLoaderService.java             | 327 ++++++++
 .../jcr/contentloader/internal/ImportProvider.java |  27 +
 .../jcr/contentloader/internal/JsonReader.java     | 190 +++++
 .../sling/jcr/contentloader/internal/Loader.java   | 924 +++++++++++++++++++++
 .../contentloader/internal/NodeDescription.java    | 153 ++++
 .../jcr/contentloader/internal/NodeReader.java     |  31 +
 .../jcr/contentloader/internal/PathEntry.java      |  91 ++
 .../internal/PropertyDescription.java              | 119 +++
 .../jcr/contentloader/internal/XmlReader.java      | 169 ++++
 10 files changed, 2036 insertions(+), 5 deletions(-)

diff --git a/pom.xml b/pom.xml
index ef1f7e7..8b9958a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -60,7 +60,7 @@
                 <configuration>
                     <instructions>
                         <Private-Package>
-                            org.apache.sling.jcr.resource.internal.*,
+                            org.apache.sling.jcr.contentloader.internal.*,
                             org.kxml2.io, org.xmlpull.v1
                         </Private-Package>
 
@@ -83,12 +83,13 @@
             <artifactId>org.osgi.compendium</artifactId>
         </dependency>
         <dependency>
-            <groupId>javax.servlet</groupId>
-            <artifactId>servlet-api</artifactId>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.jcr.api</artifactId>
+            <version>2.0.0-incubator-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.api</artifactId>
+            <artifactId>org.apache.sling.commons.json</artifactId>
             <version>2.0.0-incubator-SNAPSHOT</version>
         </dependency>
         <dependency>
@@ -100,7 +101,6 @@
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
         </dependency>
-
         <dependency>
             <groupId>net.sf.kxml</groupId>
             <artifactId>kxml2</artifactId>
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java
new file mode 100644
index 0000000..57874f3
--- /dev/null
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java
@@ -0,0 +1,327 @@
+/*
+ * 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.contentloader.internal;
+
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.lock.LockException;
+
+import org.apache.sling.commons.mime.MimeTypeService;
+import org.apache.sling.jcr.api.SlingRepository;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.SynchronousBundleListener;
+import org.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The <code>ContentLoaderService</code> is the service
+ * providing the following functionality:
+ * <ul>
+ * <li>Bundle listener to load initial content.
+ * <li>Fires OSGi EventAdmin events on behalf of internal helper objects
+ * </ul>
+ *
+ * @scr.component metatype="false"
+ * @scr.property name="service.description" value="Sling
+ *               Content Loader Implementation"
+ * @scr.property name="service.vendor" value="The Apache Software Foundation"
+ */
+public class ContentLoaderService implements SynchronousBundleListener {
+
+    public static final String PROPERTY_CONTENT_LOADED = "content-loaded";
+
+    public static final String BUNDLE_CONTENT_NODE = "/var/sling/bundle-content";
+
+    /** default log */
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    /**
+     * The JCR Repository we access to resolve resources
+     *
+     * @scr.reference
+     */
+    private SlingRepository repository;
+
+    /**
+     * The MimeTypeService used by the initial content initialContentLoader to
+     * resolve MIME types for files to be installed.
+     *
+     * @scr.reference
+     */
+    private MimeTypeService mimeTypeService;
+
+    /**
+     * Administrative sessions used to check item existence.
+     */
+    private Session adminSession;
+
+    /**
+     * The initial content loader which is called to load initial content up
+     * into the repository when the providing bundle is installed.
+     */
+    private Loader initialContentLoader;
+
+    // ---------- BundleListener -----------------------------------------------
+
+    /**
+     * Loads and unloads any content provided by the bundle whose state
+     * changed. If the bundle has been started, the content is loaded. If
+     * the bundle is about to stop, the content are unloaded.
+     *
+     * @param event The <code>BundleEvent</code> representing the bundle state
+     *            change.
+     */
+    public void bundleChanged(BundleEvent event) {
+
+        //
+        // NOTE:
+        // This is synchronous - take care to not block the system !!
+        //
+
+        switch (event.getType()) {
+            case BundleEvent.STARTING:
+                // register content when the bundle content is available
+                // as node types are registered when the bundle is installed
+                // we can safely add the content at this point.
+                try {
+                    Session session = getAdminSession();
+                    initialContentLoader.registerBundle(session, event.getBundle(), false);
+                } catch (Throwable t) {
+                    log.error(
+                        "bundleChanged: Problem loading initial content of bundle "
+                            + event.getBundle().getSymbolicName() + " ("
+                            + event.getBundle().getBundleId() + ")", t);
+                }
+                break;
+            case BundleEvent.UPDATED:
+                try {
+                    Session session = getAdminSession();
+                    initialContentLoader.registerBundle(session, event.getBundle(), true);
+                } catch (Throwable t) {
+                    log.error(
+                        "bundleChanged: Problem updating initial content of bundle "
+                            + event.getBundle().getSymbolicName() + " ("
+                            + event.getBundle().getBundleId() + ")", t);
+                }
+                break;
+            case BundleEvent.STOPPED:
+                try {
+                    Session session = getAdminSession();
+                    initialContentLoader.unregisterBundle(session, event.getBundle());
+                } catch (Throwable t) {
+                    log.error(
+                        "bundleChanged: Problem unloading initial content of bundle "
+                            + event.getBundle().getSymbolicName() + " ("
+                            + event.getBundle().getBundleId() + ")", t);
+                }
+                break;
+        }
+    }
+
+    // ---------- Implementation helpers --------------------------------------
+
+    /** Returns the MIME type from the MimeTypeService for the given name */
+    public String getMimeType(String name) {
+        // local copy to not get NPE despite check for null due to concurrent
+        // unbind
+        MimeTypeService mts = mimeTypeService;
+        return (mts != null) ? mts.getMimeType(name) : null;
+    }
+
+    protected void createRepositoryPath(final Session writerSession, final String repositoryPath)
+    throws RepositoryException {
+        if ( !writerSession.itemExists(repositoryPath) ) {
+            Node node = writerSession.getRootNode();
+            String path = repositoryPath.substring(1);
+            int pos = path.lastIndexOf('/');
+            if ( pos != -1 ) {
+                final StringTokenizer st = new StringTokenizer(path.substring(0, pos), "/");
+                while ( st.hasMoreTokens() ) {
+                    final String token = st.nextToken();
+                    if ( !node.hasNode(token) ) {
+                        node.addNode(token, "sling:Folder");
+                        node.save();
+                    }
+                    node = node.getNode(token);
+                }
+                path = path.substring(pos + 1);
+            }
+            if ( !node.hasNode(path) ) {
+                node.addNode(path, "sling:Folder");
+                node.save();
+            }
+        }
+    }
+
+    // ---------- SCR Integration ---------------------------------------------
+
+    /** Activates this component, called by SCR before registering as a service */
+    protected void activate(ComponentContext componentContext) {
+        this.initialContentLoader = new Loader(this);
+
+        componentContext.getBundleContext().addBundleListener(this);
+
+        try {
+            final Session session = getAdminSession();
+            this.createRepositoryPath(session, ContentLoaderService.BUNDLE_CONTENT_NODE);
+            log.debug(
+                    "Activated - attempting to load content from all "
+                    + "bundles which are neither INSTALLED nor UNINSTALLED");
+
+            int ignored = 0;
+            Bundle[] bundles = componentContext.getBundleContext().getBundles();
+            for (Bundle bundle : bundles) {
+                if ((bundle.getState() & (Bundle.INSTALLED | Bundle.UNINSTALLED)) == 0) {
+                    // load content for bundles which are neither INSTALLED nor
+                    // UNINSTALLED
+                    initialContentLoader.registerBundle(session, bundle, false);
+                } else {
+                    ignored++;
+                }
+
+            }
+
+            log.debug(
+                    "Out of {} bundles, {} were not in a suitable state for initial content loading",
+                    bundles.length, ignored
+                    );
+
+        } catch (Throwable t) {
+            log.error("activate: Problem while loading initial content and"
+                + " registering mappings for existing bundles", t);
+        }
+    }
+
+    /** Deativates this component, called by SCR to take out of service */
+    protected void deactivate(ComponentContext componentContext) {
+        componentContext.getBundleContext().removeBundleListener(this);
+
+        if ( this.initialContentLoader != null ) {
+            this.initialContentLoader.dispose();
+            this.initialContentLoader = null;
+        }
+
+        if ( adminSession != null ) {
+            this.adminSession.logout();
+            this.adminSession = null;
+        }
+    }
+
+    // ---------- internal helper ----------------------------------------------
+
+    /** Returns the JCR repository used by this service. */
+    protected SlingRepository getRepository() {
+        return repository;
+    }
+
+    /**
+     * Returns an administrative session to the default workspace.
+     */
+    private synchronized Session getAdminSession()
+    throws RepositoryException {
+        if ( adminSession == null ) {
+            adminSession = getRepository().loginAdministrative(null);
+        }
+        return adminSession;
+    }
+
+    /**
+     * Return the bundle content info and make an exclusive lock.
+     * @param session
+     * @param bundle
+     * @return The map of bundle content info or null.
+     * @throws RepositoryException
+     */
+    public Map<String, Object> getBundleContentInfo(final Session session, final Bundle bundle)
+    throws RepositoryException {
+        final String nodeName = bundle.getSymbolicName();
+        final Node parentNode = (Node)session.getItem(BUNDLE_CONTENT_NODE);
+        if ( !parentNode.hasNode(nodeName) ) {
+            try {
+                final Node bcNode = parentNode.addNode(nodeName, "nt:unstructured");
+                bcNode.addMixin("mix:lockable");
+                parentNode.save();
+            } catch (RepositoryException re) {
+                // for concurrency issues (running in a cluster) we ignore exceptions
+                this.log.warn("Unable to create node " + nodeName, re);
+                session.refresh(true);
+            }
+        }
+        final Node bcNode = parentNode.getNode(nodeName);
+        if ( bcNode.isLocked() ) {
+            return null;
+        }
+        try {
+            bcNode.lock(false, true);
+        } catch (LockException le) {
+            return null;
+        }
+        final Map<String, Object> info = new HashMap<String, Object>();
+        if ( bcNode.hasProperty(ContentLoaderService.PROPERTY_CONTENT_LOADED) ) {
+            info.put(ContentLoaderService.PROPERTY_CONTENT_LOADED,
+                    bcNode.getProperty(ContentLoaderService.PROPERTY_CONTENT_LOADED).getBoolean());
+        } else {
+            info.put(ContentLoaderService.PROPERTY_CONTENT_LOADED, false);
+        }
+        return info;
+    }
+
+    public void unlockBundleContentInto(final Session session,
+                                        final Bundle  bundle,
+                                        final boolean contentLoaded)
+    throws RepositoryException {
+        final String nodeName = bundle.getSymbolicName();
+        final Node parentNode = (Node)session.getItem(BUNDLE_CONTENT_NODE);
+        final Node bcNode = parentNode.getNode(nodeName);
+        if ( contentLoaded ) {
+            bcNode.setProperty(ContentLoaderService.PROPERTY_CONTENT_LOADED, contentLoaded);
+            bcNode.setProperty("content-load-time", Calendar.getInstance());
+            bcNode.setProperty("content-loaded-by", bundle.getBundleContext().getProperty("sling.id"));
+            bcNode.setProperty("content-unload-time", (String)null);
+            bcNode.setProperty("content-unloaded-by", (String)null);
+            bcNode.save();
+        }
+        bcNode.unlock();
+    }
+
+    public void contentIsUninstalled(final Session session,
+                                     final Bundle  bundle) {
+        final String nodeName = bundle.getSymbolicName();
+        try {
+            final Node parentNode = (Node)session.getItem(BUNDLE_CONTENT_NODE);
+            if ( parentNode.hasNode(nodeName) ) {
+                final Node bcNode = parentNode.getNode(nodeName);
+                bcNode.setProperty(ContentLoaderService.PROPERTY_CONTENT_LOADED, false);
+                bcNode.setProperty("content-unload-time", Calendar.getInstance());
+                bcNode.setProperty("content-unloaded-by", bundle.getBundleContext().getProperty("sling.id"));
+                bcNode.save();
+            }
+        } catch (RepositoryException re) {
+            this.log.error("Unable to update bundle content info.", re);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/ImportProvider.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/ImportProvider.java
new file mode 100644
index 0000000..e28fd55
--- /dev/null
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/ImportProvider.java
@@ -0,0 +1,27 @@
+/*
+ * 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.contentloader.internal;
+
+import java.io.IOException;
+
+interface ImportProvider {
+
+    NodeReader getReader() throws IOException;
+    
+}
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/JsonReader.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/JsonReader.java
new file mode 100644
index 0000000..4b5a1e5
--- /dev/null
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/JsonReader.java
@@ -0,0 +1,190 @@
+/*
+ * 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.contentloader.internal;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.jcr.PropertyType;
+
+import org.apache.sling.commons.json.JSONArray;
+import org.apache.sling.commons.json.JSONException;
+import org.apache.sling.commons.json.JSONObject;
+
+
+/**
+ * The <code>JsonReader</code> TODO
+ */
+class JsonReader implements NodeReader {
+
+    private static final Set<String> ignoredNames = new HashSet<String>();
+    static {
+        ignoredNames.add("jcr:primaryType");
+        ignoredNames.add("jcr:mixinTypes");
+        ignoredNames.add("jcr:uuid");
+        ignoredNames.add("jcr:baseVersion");
+        ignoredNames.add("jcr:predecessors");
+        ignoredNames.add("jcr:successors");
+        ignoredNames.add("jcr:checkedOut");
+        ignoredNames.add("jcr:created");
+    }
+
+    static final ImportProvider PROVIDER = new ImportProvider() {
+        private JsonReader jsonReader;
+
+        public NodeReader getReader() {
+            if (jsonReader == null) {
+                jsonReader = new JsonReader();
+            }
+            return jsonReader;
+        }
+    };
+    
+    public NodeDescription parse(InputStream ins) throws IOException {
+        try {
+            String jsonString = toString(ins).trim();
+            if (!jsonString.startsWith("{")) {
+                jsonString = "{" + jsonString + "}";
+            }
+
+            JSONObject json = new JSONObject(jsonString);
+            String name = json.optString("name", null); // allow for no name !
+            return this.createNode(name, json);
+
+        } catch (JSONException je) {
+            throw (IOException) new IOException(je.getMessage()).initCause(je);
+        }
+    }
+
+    protected NodeDescription createNode(String name, JSONObject obj) throws JSONException {
+        NodeDescription node = new NodeDescription();
+        node.setName(name);
+
+        Object primaryType = obj.opt("jcr:primaryType");
+        if (primaryType != null) {
+            node.setPrimaryNodeType(String.valueOf(primaryType));
+        }
+
+        Object mixinsObject = obj.opt("jcr:mixinTypes");
+        if (mixinsObject instanceof JSONArray) {
+            JSONArray mixins = (JSONArray) mixinsObject;
+            for (int i = 0; i < mixins.length(); i++) {
+                node.addMixinNodeType(mixins.getString(i));
+            }
+        }
+
+        // add properties and nodes
+        JSONArray names = obj.names();
+        for (int i = 0; names != null && i < names.length(); i++) {
+            String n = names.getString(i);
+            // skip well known objects
+            if (!ignoredNames.contains(n)) {
+                Object o = obj.get(n);
+                if (o instanceof JSONObject) {
+                    NodeDescription child = this.createNode(n, (JSONObject) o);
+                    node.addChild(child);
+                } else if (o instanceof JSONArray) {
+                    PropertyDescription prop = createProperty(n, o);
+                    node.addProperty(prop);
+                } else {
+                    PropertyDescription prop = createProperty(n, o);
+                    node.addProperty(prop);
+                }
+            }
+        }
+        return node;
+    }
+
+    protected PropertyDescription createProperty(String name, Object value)
+            throws JSONException {
+        PropertyDescription property = new PropertyDescription();
+        property.setName(name);
+
+        // assume simple value
+        if (value instanceof JSONArray) {
+            // multivalue
+            JSONArray array = (JSONArray) value;
+            if (array.length() > 0) {
+                for (int i = 0; i < array.length(); i++) {
+                    property.addValue(array.get(i));
+                }
+                value = array.opt(0);
+            } else {
+                property.addValue(null);
+                value = null;
+            }
+
+        } else {
+            // single value
+            property.setValue(String.valueOf(value));
+        }
+        // set type
+        property.setType(getType(value));
+
+        return property;
+    }
+
+    protected String getType(Object object) {
+        if (object instanceof Double || object instanceof Float) {
+            return PropertyType.TYPENAME_DOUBLE;
+        } else if (object instanceof Number) {
+            return PropertyType.TYPENAME_LONG;
+        } else if (object instanceof Boolean) {
+            return PropertyType.TYPENAME_BOOLEAN;
+        }
+
+        // fall back to default
+        return PropertyType.TYPENAME_STRING;
+    }
+    
+    private String toString(InputStream ins) throws IOException {
+        if (!ins.markSupported()) {
+            ins = new BufferedInputStream(ins);
+        }
+        
+        String encoding;
+        ins.mark(5);
+        int c = ins.read();
+        if (c == '#') {
+            // character encoding following
+            StringBuffer buf = new StringBuffer();
+            for (c = ins.read(); !Character.isWhitespace((char) c); c = ins.read()) {
+                buf.append((char) c);
+            }
+            encoding = buf.toString();
+        } else {
+            ins.reset();
+            encoding = "UTF-8";
+        }
+
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        byte[] buf = new byte[1024];
+        int rd;
+        while ( (rd = ins.read(buf)) >= 0) {
+            bos.write(buf, 0, rd);
+        }
+        bos.close(); // just to comply with the contract
+        
+        return new String(bos.toByteArray(), encoding);
+    }
+}
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/Loader.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/Loader.java
new file mode 100644
index 0000000..300b2f8
--- /dev/null
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/Loader.java
@@ -0,0 +1,924 @@
+/*
+ * 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.contentloader.internal;
+
+import static javax.jcr.ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jcr.InvalidSerializedDataException;
+import javax.jcr.Item;
+import javax.jcr.Node;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.osgi.framework.Bundle;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The <code>Loader</code> loads initial content from the bundle.
+ */
+public class Loader {
+
+    public static final String EXT_XML = ".xml";
+
+    public static final String EXT_JCR_XML = ".jcr.xml";
+
+    public static final String EXT_JSON = ".json";
+
+    public static final String ROOT_DESCRIPTOR = "/ROOT";
+
+    // default content type for createFile()
+    private static final String DEFAULT_CONTENT_TYPE = "application/octet-stream";
+
+    /** default log */
+    private final Logger log = LoggerFactory.getLogger(Loader.class);
+
+    private ContentLoaderService jcrContentHelper;
+
+    private Map<String, ImportProvider> importProviders;
+
+    private Map<String, List<String>> delayedReferences;
+
+    // bundles whose registration failed and should be retried
+    private List<Bundle> delayedBundles;
+
+    public Loader(ContentLoaderService jcrContentHelper) {
+        this.jcrContentHelper = jcrContentHelper;
+        this.delayedReferences = new HashMap<String, List<String>>();
+        this.delayedBundles = new LinkedList<Bundle>();
+
+        importProviders = new LinkedHashMap<String, ImportProvider>();
+        importProviders.put(EXT_JCR_XML, null);
+        importProviders.put(EXT_JSON, JsonReader.PROVIDER);
+        importProviders.put(EXT_XML, XmlReader.PROVIDER);
+    }
+
+    public void dispose() {
+        this.delayedReferences = null;
+        if (this.delayedBundles != null) {
+            this.delayedBundles.clear();
+            this.delayedBundles = null;
+        }
+        this.jcrContentHelper = null;
+        this.importProviders.clear();
+    }
+
+    /**
+     * Register a bundle and install its content.
+     * @param session
+     * @param bundle
+     */
+    public void registerBundle(final Session session, final Bundle bundle, final boolean isUpdate) {
+        log.debug("Registering bundle {} for content loading.", bundle.getSymbolicName());
+        if (this.registerBundleInternal(session, bundle, false, isUpdate)) {
+            // handle delayed bundles, might help now
+            int currentSize = -1;
+            for (int i = this.delayedBundles.size(); i > 0
+                && currentSize != this.delayedBundles.size()
+                && !this.delayedBundles.isEmpty(); i--) {
+                for (Iterator<Bundle> di = this.delayedBundles.iterator(); di.hasNext();) {
+                    Bundle delayed = di.next();
+                    if (this.registerBundleInternal(session, delayed, true, false)) {
+                        di.remove();
+                    }
+                }
+                currentSize = this.delayedBundles.size();
+            }
+        } else {
+            // add to delayed bundles - if this is not an update!
+            if ( !isUpdate ) {
+                this.delayedBundles.add(bundle);
+            }
+        }
+    }
+
+    private boolean registerBundleInternal(final Session session,
+                                           final Bundle  bundle,
+                                           final boolean isRetry,
+                                           final boolean isUpdate) {
+        // check if bundle has initial content
+        final Iterator<PathEntry> pathIter = PathEntry.getContentPaths(bundle);
+        if (pathIter == null) {
+            log.debug("Bundle {} has no initial content",
+                bundle.getSymbolicName());
+            return true;
+        }
+
+        try {
+            // check if the content has already been loaded
+            final Map<String, Object> bundleContentInfo = this.jcrContentHelper.getBundleContentInfo(session, bundle);
+            // if we don't get an info, someone else is currently loading
+            if ( bundleContentInfo == null ) {
+                return false;
+            }
+
+            boolean success = false;
+            try {
+                final boolean contentAlreadyLoaded = ((Boolean)bundleContentInfo.get(ContentLoaderService.PROPERTY_CONTENT_LOADED)).booleanValue();
+                if ( !isUpdate && contentAlreadyLoaded ) {
+                    log.info("Content of bundle already loaded {}.", bundle.getSymbolicName());
+                } else {
+                    this.installContent(session, bundle, pathIter);
+                    if (isRetry) {
+                        // log success of retry
+                        log.info(
+                            "Retrytring to load initial content for bundle {} succeeded.",
+                            bundle.getSymbolicName());
+                    }
+                }
+                success = true;
+                return true;
+            } finally {
+                this.jcrContentHelper.unlockBundleContentInto(session, bundle, success);
+            }
+        } catch (RepositoryException re) {
+            // if we are retrying we already logged this message once, so we
+            // won't log it again
+            if (!isRetry) {
+                log.error("Cannot load initial content for bundle "
+                    + bundle.getSymbolicName() + " : " + re.getMessage(), re);
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Unregister a bundle.
+     * Remove installed content.
+     * @param bundle The bundle.
+     */
+    public void unregisterBundle(final Session session, final Bundle bundle) {
+        // check if bundle has initial content
+        final Iterator<PathEntry> pathIter = PathEntry.getContentPaths(bundle);
+        if (this.delayedBundles.contains(bundle)) {
+            this.delayedBundles.remove(bundle);
+        } else {
+            if ( pathIter != null ) {
+                this.uninstallContent(session, bundle, pathIter);
+                this.jcrContentHelper.contentIsUninstalled(session, bundle);
+            }
+        }
+    }
+
+    // ---------- internal -----------------------------------------------------
+
+    private void installContent(Session session, Bundle bundle, final Iterator<PathEntry> pathIter)
+    throws RepositoryException {
+        try {
+            log.debug("Installing initial content from bundle {}",
+                bundle.getSymbolicName());
+            while (pathIter.hasNext() ) {
+                final PathEntry entry = pathIter.next();
+                this.installFromPath(bundle, entry.getPath(), entry.isOverwrite(), session.getRootNode());
+            }
+
+            // persist modifications now
+            session.save();
+            log.debug("Done installing initial content from bundle {}",
+                bundle.getSymbolicName());
+        } finally {
+            try {
+                if (session.hasPendingChanges()) {
+                    session.refresh(false);
+                }
+            } catch (RepositoryException re) {
+                log.warn(
+                    "Failure to rollback partial initial content for bundle {}",
+                    bundle.getSymbolicName(), re);
+            }
+        }
+
+    }
+
+    /**
+     * Handle content installation for a single path.
+     * @param bundle The bundle containing the content.
+     * @param path   The path
+     * @param overwrite Should the content be overwritten.
+     * @param parent The parent node.
+     * @throws RepositoryException
+     */
+    private void installFromPath(final Bundle bundle,
+                                 final String path,
+                                 final boolean overwrite,
+                                 final Node parent)
+    throws RepositoryException {
+        @SuppressWarnings("unchecked")
+        Enumeration<String> entries = bundle.getEntryPaths(path);
+        if (entries == null) {
+            log.info("install: No initial content entries at {}", path);
+            return;
+        }
+
+        Set<URL> ignoreEntry = new HashSet<URL>();
+
+        // potential root node import/extension
+        URL rootNodeDescriptor = importRootNode(parent.getSession(), bundle, path);
+        if (rootNodeDescriptor != null) {
+            ignoreEntry.add(rootNodeDescriptor);
+        }
+
+        while (entries.hasMoreElements()) {
+            final String entry = entries.nextElement();
+            log.debug("Processing initial content entry {}", entry);
+            if (entry.endsWith("/")) {
+                // dir, check for node descriptor , else create dir
+                String base = entry.substring(0, entry.length() - 1);
+                String name = this.getName(base);
+
+                URL nodeDescriptor = null;
+                for (String ext : importProviders.keySet()) {
+                    nodeDescriptor = bundle.getEntry(base + ext);
+                    if (nodeDescriptor != null) {
+                        break;
+                    }
+                }
+
+                // if we have a descriptor, which has not been processed yet,
+                // otherwise call createFolder, which creates an nt:folder or
+                // returns an existing node (created by a descriptor)
+                Node node = null;
+                if (nodeDescriptor != null
+                    && !ignoreEntry.contains(nodeDescriptor)) {
+                    node = this.createNode(parent, name, nodeDescriptor, overwrite);
+                    ignoreEntry.add(nodeDescriptor);
+                } else {
+                    node = this.createFolder(parent, name, overwrite);
+                }
+
+                // walk down the line
+                if (node != null) {
+                    this.installFromPath(bundle, entry, overwrite, node);
+                }
+
+            } else {
+                // file => create file
+                URL file = bundle.getEntry(entry);
+                if (ignoreEntry.contains(file)) {
+                    // this is a consumed node descriptor
+                    continue;
+                }
+
+                // install if it is a descriptor
+                boolean foundProvider = false;
+                final Iterator<String> ipIter = this.importProviders.keySet().iterator();
+                while ( !foundProvider && ipIter.hasNext() ) {
+                    final String ext = ipIter.next();
+                    if ( entry.endsWith(ext) ) {
+                        foundProvider = true;
+                    }
+                }
+                if (foundProvider) {
+                    if (this.createNode(parent, this.getName(entry), file, overwrite) != null) {
+                        ignoreEntry.add(file);
+                        continue;
+                    }
+                }
+
+                // otherwise just place as file
+                try {
+                    this.createFile(parent, file);
+                } catch (IOException ioe) {
+                    log.warn("Cannot create file node for {}", file, ioe);
+                }
+            }
+        }
+    }
+
+    /**
+     * Create a folder
+     * @param parent The parent node.
+     * @param name   The name of the folder
+     * @param overwrite If set to true, an existing folder is removed first.
+     * @return The node pointing to the folder.
+     * @throws RepositoryException
+     */
+    private Node createFolder(Node parent, String name, final boolean overwrite)
+    throws RepositoryException {
+        if (parent.hasNode(name)) {
+            if ( overwrite ) {
+                parent.getNode(name).remove();
+            } else {
+                return parent.getNode(name);
+            }
+        }
+
+        return parent.addNode(name, "nt:folder");
+    }
+
+    private Node createNode(Node parent, String name, URL nodeXML, boolean overwrite)
+    throws RepositoryException {
+
+        InputStream ins = null;
+        try {
+            // special treatment for system view imports
+            if (nodeXML.getPath().toLowerCase().endsWith(EXT_JCR_XML)) {
+                return importSystemView(parent, name, nodeXML);
+            }
+
+            NodeReader nodeReader = null;
+            for (Map.Entry<String, ImportProvider> e: importProviders.entrySet()) {
+                if (nodeXML.getPath().toLowerCase().endsWith(e.getKey())) {
+                    nodeReader = e.getValue().getReader();
+                    break;
+                }
+            }
+
+            // cannot find out the type
+            if (nodeReader == null) {
+                return null;
+            }
+
+            ins = nodeXML.openStream();
+            NodeDescription clNode = nodeReader.parse(ins);
+
+            // nothing has been parsed
+            if (clNode == null) {
+                return null;
+            }
+
+            if (clNode.getName() == null) {
+                // set the name without the [last] extension (xml or json)
+                clNode.setName(toPlainName(name));
+            }
+
+            return this.createNode(parent, clNode, overwrite);
+        } catch (RepositoryException re) {
+            throw re;
+        } catch (Throwable t) {
+            throw new RepositoryException(t.getMessage(), t);
+        } finally {
+            if (ins != null) {
+                try {
+                    ins.close();
+                } catch (IOException ignore) {
+                }
+            }
+        }
+    }
+
+    /**
+     * Delete the node from the initial content.
+     * @param parent
+     * @param name
+     * @param nodeXML
+     * @throws RepositoryException
+     */
+    private void deleteNode(Node parent, String name)
+    throws RepositoryException {
+        if ( parent.hasNode(name) ) {
+            parent.getNode(name).remove();
+        }
+    }
+
+    private Node createNode(Node parentNode,
+                            NodeDescription clNode,
+                            final boolean overwrite)
+    throws RepositoryException {
+        // if node already exists but should be overwritten, delete it
+        if ( overwrite && parentNode.hasNode(clNode.getName()) ) {
+            parentNode.getNode(clNode.getName()).remove();
+        }
+
+        // ensure repository node
+        Node node;
+        if (parentNode.hasNode(clNode.getName())) {
+
+            // use existing node
+            node = parentNode.getNode(clNode.getName());
+
+        } else if (clNode.getPrimaryNodeType() == null) {
+
+            // node explicit node type, use repository default
+            node = parentNode.addNode(clNode.getName());
+
+        } else {
+
+            // explicit primary node type
+            node = parentNode.addNode(clNode.getName(),
+                clNode.getPrimaryNodeType());
+        }
+
+        return setupNode(node, clNode);
+    }
+
+    private Node setupNode(Node node,
+            NodeDescription clNode)
+            throws RepositoryException {
+
+        // ammend mixin node types
+        if (clNode.getMixinNodeTypes() != null) {
+            for (String mixin : clNode.getMixinNodeTypes()) {
+                if (!node.isNodeType(mixin)) {
+                    node.addMixin(mixin);
+                }
+            }
+        }
+
+        if (clNode.getProperties() != null) {
+            for (PropertyDescription prop : clNode.getProperties()) {
+                if (node.hasProperty(prop.getName())
+                    && !node.getProperty(prop.getName()).isNew()) {
+                    continue;
+                }
+
+                int type = PropertyType.valueFromName(prop.getType());
+                if (prop.isMultiValue()) {
+                    String[] values = prop.getValues().toArray(
+                        new String[prop.getValues().size()]);
+                    node.setProperty(prop.getName(), values, type);
+                } else if (type == PropertyType.REFERENCE) {
+                    // need to resolve the reference
+                    String propPath = node.getPath() + "/" + prop.getName();
+                    String uuid = this.getUUID(node.getSession(), propPath,
+                        prop.getValue());
+                    if (uuid != null) {
+                        node.setProperty(prop.getName(), uuid, type);
+                    }
+                } else {
+                    node.setProperty(prop.getName(), prop.getValue(), type);
+                }
+            }
+        }
+
+        if (clNode.getChildren() != null) {
+            for (NodeDescription child : clNode.getChildren()) {
+                this.createNode(node, child, false);
+            }
+        }
+
+        this.resolveReferences(node);
+
+        return node;
+    }
+
+    /**
+     * Create a file from the given url.
+     * @param parent
+     * @param source
+     * @throws IOException
+     * @throws RepositoryException
+     */
+    private void createFile(Node parent, URL source)
+    throws IOException, RepositoryException {
+        String name = this.getName(source.getPath());
+        if (parent.hasNode(name)) {
+            return;
+        }
+
+        URLConnection conn = source.openConnection();
+        long lastModified = conn.getLastModified();
+        String type = conn.getContentType();
+        InputStream data = conn.getInputStream();
+
+        // ensure content type
+        if (type == null) {
+            type = this.jcrContentHelper.getMimeType(name);
+            if (type == null) {
+                log.info(
+                    "createFile: Cannot find content type for {}, using {}",
+                    source.getPath(), DEFAULT_CONTENT_TYPE);
+                type = DEFAULT_CONTENT_TYPE;
+            }
+        }
+
+        // ensure sensible last modification date
+        if (lastModified <= 0) {
+            lastModified = System.currentTimeMillis();
+        }
+
+        Node file = parent.addNode(name, "nt:file");
+        Node content = file.addNode("jcr:content", "nt:resource");
+        content.setProperty("jcr:mimeType", type);
+        content.setProperty("jcr:lastModified", lastModified);
+        content.setProperty("jcr:data", data);
+    }
+
+    /**
+     * Delete the file from the given url.
+     * @param parent
+     * @param source
+     * @throws IOException
+     * @throws RepositoryException
+     */
+    private void deleteFile(Node parent, URL source)
+    throws IOException, RepositoryException {
+        String name = this.getName(source.getPath());
+        if (parent.hasNode(name)) {
+            parent.getNode(name).remove();
+        }
+    }
+
+    private String getUUID(Session session, String propPath,
+            String referencePath) throws RepositoryException {
+        if (session.itemExists(referencePath)) {
+            Item item = session.getItem(referencePath);
+            if (item.isNode()) {
+                Node refNode = (Node) item;
+                if (refNode.isNodeType("mix:referenceable")) {
+                    return refNode.getUUID();
+                }
+            }
+        } else {
+            // not existing yet, keep for delayed setting
+            List<String> current = this.delayedReferences.get(referencePath);
+            if (current == null) {
+                current = new ArrayList<String>();
+                this.delayedReferences.put(referencePath, current);
+            }
+            current.add(propPath);
+        }
+
+        // no UUID found
+        return null;
+    }
+
+    private void resolveReferences(Node node) throws RepositoryException {
+        List<String> props = this.delayedReferences.remove(node.getPath());
+        if (props == null || props.size() == 0) {
+            return;
+        }
+
+        // check whether we can set at all
+        if (!node.isNodeType("mix:referenceable")) {
+            return;
+        }
+
+        Session session = node.getSession();
+        String uuid = node.getUUID();
+
+        for (String property : props) {
+            String name = this.getName(property);
+            Node parentNode = this.getParentNode(session, property);
+            if (parentNode != null) {
+                parentNode.setProperty(name, uuid, PropertyType.REFERENCE);
+            }
+        }
+    }
+
+    /**
+     * Gets and decods the name part of the <code>path</code>. The name is
+     * the part of the path after the last slash (or the complete path if no
+     * slash is contained). To support names containing unsupported characters
+     * such as colon (<code>:</code>), names may be URL encoded (see
+     * <code>java.net.URLEncoder</code>) using the <i>UTF-8</i> character
+     * encoding. In this case, this method decodes the name using the
+     * <code>java.netURLDecoder</code> class with the <i>UTF-8</i> character
+     * encoding.
+     *
+     * @param path The path from which to extract the name part.
+     * @return The URL decoded name part.
+     */
+    private String getName(String path) {
+        int lastSlash = path.lastIndexOf('/');
+        String name = (lastSlash < 0) ? path : path.substring(lastSlash + 1);
+
+        // check for encoded characters (%xx)
+        // has encoded characters, need to decode
+        if (name.indexOf('%') >= 0) {
+            try {
+                return URLDecoder.decode(name, "UTF-8");
+            } catch (UnsupportedEncodingException uee) {
+                // actually unexpected because UTF-8 is required by the spec
+                log.error("Cannot decode "
+                    + name
+                    + " beause the platform has no support for UTF-8, using undecoded");
+            } catch (Exception e) {
+                // IllegalArgumentException or failure to decode
+                log.error("Cannot decode " + name + ", using undecoded", e);
+            }
+        }
+
+        // not encoded or problems decoding, return the name unmodified
+        return name;
+    }
+
+    private Node getParentNode(Session session, String path)
+            throws RepositoryException {
+        int lastSlash = path.lastIndexOf('/');
+
+        // not an absolute path, cannot find parent
+        if (lastSlash < 0) {
+            return null;
+        }
+
+        // node below root
+        if (lastSlash == 0) {
+            return session.getRootNode();
+        }
+
+        // item in the hierarchy
+        path = path.substring(0, lastSlash);
+        if (!session.itemExists(path)) {
+            return null;
+        }
+
+        Item item = session.getItem(path);
+        return (item.isNode()) ? (Node) item : null;
+    }
+
+    private void uninstallContent(final Session session, final Bundle bundle, final Iterator<PathEntry> pathIter) {
+        try {
+            log.debug("Uninstalling initial content from bundle {}",
+                bundle.getSymbolicName());
+            while (pathIter.hasNext() ) {
+                final PathEntry entry = pathIter.next();
+                if ( entry.isOverwrite() ) {
+                    this.uninstallFromPath(bundle, entry.getPath(), session.getRootNode());
+                } else {
+                    log.debug("Ignoring to uninstall content at {}, overwrite flag is not set.", entry.getPath());
+                }
+            }
+
+            // persist modifications now
+            session.save();
+            log.debug("Done uninstalling initial content from bundle {}",
+                bundle.getSymbolicName());
+        } catch (RepositoryException re) {
+            log.error("Unable to uninstall initial content from bundle " + bundle.getSymbolicName(), re);
+        } finally {
+            try {
+                if (session.hasPendingChanges()) {
+                    session.refresh(false);
+                }
+            } catch (RepositoryException re) {
+                log.warn(
+                    "Failure to rollback uninstaling initial content for bundle {}",
+                    bundle.getSymbolicName(), re);
+            }
+        }
+    }
+
+    /**
+     * Handle content uninstallation for a single path.
+     * @param bundle The bundle containing the content.
+     * @param path   The path
+     * @param parent The parent node.
+     * @throws RepositoryException
+     */
+    private void uninstallFromPath(final Bundle bundle,
+                                   final String path,
+                                   final Node parent)
+    throws RepositoryException {
+        @SuppressWarnings("unchecked")
+        Enumeration<String> entries = bundle.getEntryPaths(path);
+        if (entries == null) {
+            return;
+        }
+
+        Set<URL> ignoreEntry = new HashSet<URL>();
+
+        // potential root node import/extension
+        Descriptor rootNodeDescriptor = this.getRootNodeDescriptor(bundle, path);
+        if (rootNodeDescriptor != null) {
+            ignoreEntry.add(rootNodeDescriptor.rootNodeDescriptor);
+        }
+
+        while (entries.hasMoreElements()) {
+            final String entry = entries.nextElement();
+            log.debug("Processing initial content entry {}", entry);
+            if (entry.endsWith("/")) {
+                // dir, check for node descriptor , else create dir
+                String base = entry.substring(0, entry.length() - 1);
+                String name = this.getName(base);
+
+                URL nodeDescriptor = null;
+                for (String ext : importProviders.keySet()) {
+                    nodeDescriptor = bundle.getEntry(base + ext);
+                    if (nodeDescriptor != null) {
+                        break;
+                    }
+                }
+
+                final Node node;
+                boolean delete = false;
+                if (nodeDescriptor != null
+                    && !ignoreEntry.contains(nodeDescriptor)) {
+                    node = (parent.hasNode(toPlainName(name)) ? parent.getNode(toPlainName(name)) : null);
+                    delete = true;
+                } else {
+                    node = (parent.hasNode(name) ? parent.getNode(name) : null);
+                }
+
+                if ( node != null ) {
+                    // walk down the line
+                    this.uninstallFromPath(bundle, entry, node);
+                }
+
+                if (delete) {
+                    this.deleteNode(parent, toPlainName(name));
+                    ignoreEntry.add(nodeDescriptor);
+                }
+
+            } else {
+                // file => create file
+                URL file = bundle.getEntry(entry);
+                if (ignoreEntry.contains(file)) {
+                    // this is a consumed node descriptor
+                    continue;
+                }
+
+                // uninstall if it is a descriptor
+                boolean foundProvider = false;
+                final Iterator<String> ipIter = this.importProviders.keySet().iterator();
+                while ( !foundProvider && ipIter.hasNext() ) {
+                    final String ext = ipIter.next();
+                    if ( entry.endsWith(ext) ) {
+                        foundProvider = true;
+                    }
+                }
+                if (foundProvider) {
+                    this.deleteNode(parent, toPlainName(this.getName(entry)));
+                    ignoreEntry.add(file);
+                    continue;
+                }
+
+                // otherwise just delete the file
+                try {
+                    this.deleteFile(parent, file);
+                } catch (IOException ioe) {
+                    log.warn("Cannot delete file node for {}", file, ioe);
+                }
+            }
+        }
+    }
+
+    /**
+     * Import the XML file as JCR system or document view import. If the XML
+     * file is not a valid system or document view export/import file,
+     * <code>false</code> is returned.
+     *
+     * @param parent The parent node below which to import
+     * @param nodeXML The URL to the XML file to import
+     * @return <code>true</code> if the import succeeds, <code>false</code>
+     *         if the import fails due to XML format errors.
+     * @throws IOException If an IO error occurrs reading the XML file.
+     */
+    private Node importSystemView(Node parent, String name, URL nodeXML)
+            throws IOException {
+
+        InputStream ins = null;
+        try {
+
+            // check whether we have the content already, nothing to do then
+            name = toPlainName(name);
+            if (parent.hasNode(name)) {
+                log.debug(
+                    "importSystemView: Node {} for XML {} already exists, nothing to to",
+                    name, nodeXML);
+                return parent.getNode(name);
+            }
+
+            ins = nodeXML.openStream();
+            Session session = parent.getSession();
+            session.importXML(parent.getPath(), ins, IMPORT_UUID_CREATE_NEW);
+
+            // additionally check whether the expected child node exists
+            return (parent.hasNode(name)) ? parent.getNode(name) : null;
+
+        } catch (InvalidSerializedDataException isde) {
+
+            // the xml might not be System or Document View export, fall back
+            // to old-style XML reading
+            log.info(
+                "importSystemView: XML {} does not seem to be system view export, trying old style",
+                nodeXML);
+            return null;
+
+        } catch (RepositoryException re) {
+
+            // any other repository related issue...
+            log.info(
+                "importSystemView: Repository issue loading XML {}, trying old style",
+                nodeXML);
+            return null;
+
+        } finally {
+            if (ins != null) {
+                try {
+                    ins.close();
+                } catch (IOException ignore) {
+                    // ignore
+                }
+            }
+        }
+
+    }
+
+    protected static final class Descriptor {
+        public URL rootNodeDescriptor;
+        public NodeReader nodeReader;
+    }
+
+    /**
+     * Return the root node descriptor.
+     */
+    private Descriptor getRootNodeDescriptor(final Bundle bundle, final String path) {
+        URL rootNodeDescriptor = null;
+
+        for (Map.Entry<String, ImportProvider> e : importProviders.entrySet()) {
+            if (e.getValue() != null) {
+                rootNodeDescriptor = bundle.getEntry(path + ROOT_DESCRIPTOR + e.getKey());
+                if (rootNodeDescriptor != null) {
+                    try {
+                        final Descriptor d = new Descriptor();
+                        d.rootNodeDescriptor = rootNodeDescriptor;
+                        d.nodeReader = e.getValue().getReader();
+                        return d;
+                    } catch (IOException ioe) {
+                        this.log.error("Unable to setup node reader for " + e.getKey(), ioe);
+                        return null;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Imports mixin nodes and properties (and optionally child nodes) of the
+     * root node.
+     */
+    private URL importRootNode(Session session, Bundle bundle, String path)
+    throws RepositoryException {
+        final Descriptor descriptor = this.getRootNodeDescriptor(bundle, path);
+        // no root descriptor found
+        if (descriptor == null) {
+            return null;
+        }
+
+        InputStream ins = null;
+        try {
+
+            ins = descriptor.rootNodeDescriptor.openStream();
+            NodeDescription clNode = descriptor.nodeReader.parse(ins);
+
+            setupNode(session.getRootNode(), clNode);
+
+            return descriptor.rootNodeDescriptor;
+        } catch (RepositoryException re) {
+            throw re;
+        } catch (Throwable t) {
+            throw new RepositoryException(t.getMessage(), t);
+        } finally {
+            if (ins != null) {
+                try {
+                    ins.close();
+                } catch (IOException ignore) {
+                }
+            }
+        }
+
+    }
+
+    private String toPlainName(String name) {
+        String providerExt = null;
+        final Iterator<String> ipIter = this.importProviders.keySet().iterator();
+        while ( providerExt == null && ipIter.hasNext() ) {
+            final String ext = ipIter.next();
+            if ( name.endsWith(ext) ) {
+                providerExt = ext;
+            }
+        }
+        if (providerExt != null) {
+            return name.substring(0, name.length() - providerExt.length());
+        }
+        return name;
+
+    }
+}
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/NodeDescription.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/NodeDescription.java
new file mode 100644
index 0000000..043da37
--- /dev/null
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/NodeDescription.java
@@ -0,0 +1,153 @@
+/*
+ * 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.contentloader.internal;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+class NodeDescription {
+
+    private String name;
+    private String primaryNodeType;
+    private Set<String> mixinNodeTypes;
+    private List<PropertyDescription> properties;
+    private List<NodeDescription> children;
+
+    /**
+     * @return the children
+     */
+    List<NodeDescription> getChildren() {
+        return children;
+    }
+
+    /**
+     * @param children the children to set
+     */
+    void addChild(NodeDescription child) {
+        if (child != null) {
+            if (children == null) {
+                children = new ArrayList<NodeDescription>();
+            }
+
+            children.add(child);
+        }
+    }
+
+    /**
+     * @return the mixinNodeTypes
+     */
+    Set<String> getMixinNodeTypes() {
+        return mixinNodeTypes;
+    }
+
+    /**
+     * @param mixinNodeTypes the mixinNodeTypes to set
+     */
+    void addMixinNodeType(String mixinNodeType) {
+        if (mixinNodeType != null && mixinNodeType.length() > 0) {
+            if (mixinNodeTypes == null) {
+                mixinNodeTypes = new HashSet<String>();
+            }
+
+            mixinNodeTypes.add(mixinNodeType);
+        }
+    }
+
+    /**
+     * @return the name
+     */
+    String getName() {
+        return name;
+    }
+
+    /**
+     * @param name the name to set
+     */
+    void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * @return the primaryNodeType
+     */
+    String getPrimaryNodeType() {
+        return primaryNodeType;
+    }
+
+    /**
+     * @param primaryNodeType the primaryNodeType to set
+     */
+    void setPrimaryNodeType(String primaryNodeType) {
+        this.primaryNodeType = primaryNodeType;
+    }
+
+    /**
+     * @return the properties
+     */
+    List<PropertyDescription> getProperties() {
+        return properties;
+    }
+
+    /**
+     * @param properties the properties to set
+     */
+    void addProperty(PropertyDescription property) {
+        if (property != null) {
+            if (properties == null) {
+                properties = new ArrayList<PropertyDescription>();
+            }
+
+            properties.add(property);
+        }
+    }
+
+    public int hashCode() {
+        int code = getName().hashCode() * 17;
+        if (getPrimaryNodeType() != null) {
+            code += getPrimaryNodeType().hashCode();
+        }
+        return code;
+    }
+
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        } else if (!(obj instanceof NodeDescription)) {
+            return false;
+        }
+
+        NodeDescription other = (NodeDescription) obj;
+        return getName().equals(other.getName())
+            && equals(getPrimaryNodeType(), other.getPrimaryNodeType())
+            && equals(getMixinNodeTypes(), other.getMixinNodeTypes())
+            && equals(getProperties(), other.getProperties())
+            && equals(getChildren(), other.getChildren());
+    }
+
+    public String toString() {
+        return "Node " + getName() + ", primary=" + getPrimaryNodeType()
+            + ", mixins=" + getMixinNodeTypes();
+    }
+
+    private boolean equals(Object o1, Object o2) {
+        return (o1 == null) ? o2 == null : o1.equals(o2);
+    }
+}
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/NodeReader.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/NodeReader.java
new file mode 100644
index 0000000..2653114
--- /dev/null
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/NodeReader.java
@@ -0,0 +1,31 @@
+/*
+ * 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.contentloader.internal;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * The <code>NodeReader</code> TODO
+ */
+interface NodeReader {
+
+    NodeDescription parse(InputStream ins) throws IOException;
+
+}
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/PathEntry.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/PathEntry.java
new file mode 100644
index 0000000..b9a0633
--- /dev/null
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/PathEntry.java
@@ -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.contentloader.internal;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.osgi.framework.Bundle;
+
+/**
+ * A path entry from the manifest for initial content.
+ */
+public class PathEntry {
+
+    /** The manifest header to specify initial content to be loaded. */
+    public static final String CONTENT_HEADER = "Sling-Initial-Content";
+
+    /** The overwrite flag specifying if content should be overwritten or just initially added. */
+    public static final String OVERWRITE_FLAG = "overwrite";
+
+    /** The path for the initial content. */
+    private final String path;
+
+    /** Should existing content be overwritten? */
+    private final boolean overwrite;
+
+    public static Iterator<PathEntry> getContentPaths(final Bundle bundle) {
+        final List<PathEntry> entries = new ArrayList<PathEntry>();
+
+        final String root = (String) bundle.getHeaders().get(CONTENT_HEADER);
+        if (root != null) {
+            final StringTokenizer tokener = new StringTokenizer(root, ",");
+            while (tokener.hasMoreTokens()) {
+                final String path = tokener.nextToken().trim();
+                entries.add(new PathEntry(path));
+            }
+        }
+
+        if ( entries.size() == 0 ) {
+            return null;
+        }
+        return entries.iterator();
+    }
+
+    public PathEntry(String path) {
+        // check for overwrite flag
+        boolean overwrite = false;
+        int flagPos = path.indexOf(";");
+        if ( flagPos != -1 ) {
+            final StringTokenizer flagTokenizer = new StringTokenizer(path.substring(flagPos+1), ";");
+            while ( flagTokenizer.hasMoreTokens() ) {
+                final String token = flagTokenizer.nextToken();
+                int pos = token.indexOf(":=");
+                if ( pos != -1 ) {
+                    if ( token.substring(0, pos).equals(OVERWRITE_FLAG) ) {
+                        overwrite = Boolean.valueOf(token.substring(pos+2));
+                    }
+                }
+            }
+            path = path.substring(0, flagPos);
+        }
+        this.path = path;
+        this.overwrite = overwrite;
+    }
+
+    public String getPath() {
+        return this.path;
+    }
+
+    public boolean isOverwrite() {
+        return this.overwrite;
+    }
+}
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/PropertyDescription.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/PropertyDescription.java
new file mode 100644
index 0000000..4fd7823
--- /dev/null
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/PropertyDescription.java
@@ -0,0 +1,119 @@
+/*
+ * 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.contentloader.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jcr.PropertyType;
+
+class PropertyDescription {
+    private String name;
+    private String value;
+    private List<String> values;
+    private String type = PropertyType.TYPENAME_STRING; // default type to string
+
+    /**
+     * @return the name
+     */
+    String getName() {
+        return this.name;
+    }
+
+    /**
+     * @param name the name to set
+     */
+    void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * @return the type
+     */
+    String getType() {
+        return this.type;
+    }
+
+    /**
+     * @param type the type to set
+     */
+    void setType(String type) {
+        this.type = type;
+    }
+
+    /**
+     * @return the value
+     */
+    String getValue() {
+        return this.value;
+    }
+
+    /**
+     * @param value the value to set
+     */
+    void setValue(String value) {
+        this.value = value;
+    }
+
+    /**
+     * @return the values
+     */
+    List<String> getValues() {
+        return this.values;
+    }
+
+    /**
+     * @param values the values to set
+     */
+    void addValue(Object value) {
+        if (this.values == null) {
+            this.values = new ArrayList<String>();
+        }
+
+        if (value != null) {
+            this.values.add(value.toString());
+        }
+    }
+
+    boolean isMultiValue() {
+        return this.values != null;
+    }
+
+    public int hashCode() {
+        return this.getName().hashCode() * 17 + this.getType().hashCode();
+    }
+
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        } else if (!(obj instanceof PropertyDescription)) {
+            return false;
+        }
+
+        PropertyDescription other = (PropertyDescription) obj;
+        return this.getName().equals(other.getName())
+            && this.getType().equals(other.getType())
+            && this.equals(this.getValues(), other.getValues())
+            && this.equals(this.getValue(), other.getValue());
+    }
+
+    private boolean equals(Object o1, Object o2) {
+        return (o1 == null) ? o2 == null : o1.equals(o2);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/XmlReader.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/XmlReader.java
new file mode 100644
index 0000000..a96155e
--- /dev/null
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/XmlReader.java
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.jcr.contentloader.internal;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.LinkedList;
+
+import org.kxml2.io.KXmlParser;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+public class XmlReader implements NodeReader {
+
+    /*
+     * <node> <primaryNodeType>type</primaryNodeType> <mixinNodeTypes>
+     * <mixinNodeType>mixtype1</mixinNodeType> <mixinNodeType>mixtype2</mixinNodeType>
+     * </mixinNodeTypes> <properties> <property> <name>propName</name>
+     * <value>propValue</value> <type>propType</type> </property> <!-- more
+     * --> </properties> </node>
+     */
+
+    private static final String ELEM_NODE = "node";
+
+    private static final String ELEM_PRIMARY_NODE_TYPE = "primaryNodeType";
+
+    private static final String ELEM_MIXIN_NODE_TYPE = "mixinNodeType";
+
+    private static final String ELEM_PROPERTY = "property";
+
+    private static final String ELEM_NAME = "name";
+
+    private static final String ELEM_VALUE = "value";
+
+    private static final String ELEM_VALUES = "values";
+
+    private static final String ELEM_TYPE = "type";
+
+    static final ImportProvider PROVIDER = new ImportProvider() {
+        private XmlReader xmlReader;
+
+        public NodeReader getReader() throws IOException {
+            if (xmlReader == null) {
+                try {
+                    xmlReader = new XmlReader();
+                } catch (Throwable t) {
+                    throw (IOException) new IOException(t.getMessage()).initCause(t);
+                }
+            }
+            return xmlReader;
+        }
+    };
+
+    private KXmlParser xmlParser;
+
+    XmlReader() {
+        this.xmlParser = new KXmlParser();
+    }
+
+    // ---------- XML content access -------------------------------------------
+
+    public synchronized NodeDescription parse(InputStream ins) throws IOException {
+        try {
+            return this.parseInternal(ins);
+        } catch (XmlPullParserException xppe) {
+            throw (IOException) new IOException(xppe.getMessage()).initCause(xppe);
+        }
+    }
+
+    private NodeDescription parseInternal(InputStream ins) throws IOException,
+            XmlPullParserException {
+        String currentElement = "<root>";
+        LinkedList<String> elements = new LinkedList<String>();
+        NodeDescription currentNode = null;
+        LinkedList<NodeDescription> nodes = new LinkedList<NodeDescription>();
+        StringBuffer contentBuffer = new StringBuffer();
+        PropertyDescription currentProperty = null;
+
+        // set the parser input, use null encoding to force detection with
+        // <?xml?>
+        this.xmlParser.setInput(ins, null);
+
+        int eventType = this.xmlParser.getEventType();
+        while (eventType != XmlPullParser.END_DOCUMENT) {
+            if (eventType == XmlPullParser.START_TAG) {
+
+                elements.add(currentElement);
+                currentElement = this.xmlParser.getName();
+
+                if (ELEM_PROPERTY.equals(currentElement)) {
+                    currentProperty = new PropertyDescription();
+                } else if (ELEM_NODE.equals(currentElement)) {
+                    if (currentNode != null) nodes.add(currentNode);
+                    currentNode = new NodeDescription();
+                }
+
+            } else if (eventType == XmlPullParser.END_TAG) {
+
+                String qName = this.xmlParser.getName();
+                String content = contentBuffer.toString().trim();
+                contentBuffer.delete(0, contentBuffer.length());
+
+                if (ELEM_PROPERTY.equals(qName)) {
+                    currentNode.addProperty(currentProperty);
+                    currentProperty = null;
+
+                } else if (ELEM_NAME.equals(qName)) {
+                    if (currentProperty != null) {
+                        currentProperty.setName(content);
+                    } else if (currentNode != null) {
+                        currentNode.setName(content);
+                    }
+
+                } else if (ELEM_VALUE.equals(qName)) {
+                    if (currentProperty.isMultiValue()) {
+                        currentProperty.addValue(content);
+                    } else {
+                        currentProperty.setValue(content);
+                    }
+
+                } else if (ELEM_VALUES.equals(qName)) {
+                    currentProperty.addValue(null);
+                    currentProperty.setValue(null);
+
+                } else if (ELEM_TYPE.equals(qName)) {
+                    currentProperty.setType(content);
+
+                } else if (ELEM_NODE.equals(qName)) {
+                    if (!nodes.isEmpty()) {
+                        NodeDescription parent = nodes.removeLast();
+                        parent.addChild(currentNode);
+                        currentNode = parent;
+                    }
+
+                } else if (ELEM_PRIMARY_NODE_TYPE.equals(qName)) {
+                    currentNode.setPrimaryNodeType(content);
+
+                } else if (ELEM_MIXIN_NODE_TYPE.equals(qName)) {
+                    currentNode.addMixinNodeType(content);
+                }
+
+                currentElement = elements.removeLast();
+
+            } else if (eventType == XmlPullParser.TEXT) {
+                contentBuffer.append(this.xmlParser.getText());
+            }
+
+            eventType = this.xmlParser.next();
+        }
+
+        return currentNode;
+    }
+}

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-jcr-contentloader] 31/32: Move Sling to new TLP location

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit 769b49c65ca70e052893ec0369a07d20a0fd3029
Author: Felix Meschberger <fm...@apache.org>
AuthorDate: Thu Jun 18 09:21:02 2009 +0000

    Move Sling to new TLP location
    
    git-svn-id: https://svn.eu.apache.org/repos/asf/sling/tags/org.apache.sling.jcr.contentloader-2.0.2-incubator@785979 13f79535-47bb-0310-9956-ffa450edef68
---
 LICENSE                                            |  202 ++++
 NOTICE                                             |    8 +
 README.txt                                         |   38 +
 pom.xml                                            |  132 +++
 .../internal/ContentLoaderService.java             |  340 +++++++
 .../jcr/contentloader/internal/ImportProvider.java |   27 +
 .../jcr/contentloader/internal/JsonReader.java     |  189 ++++
 .../sling/jcr/contentloader/internal/Loader.java   | 1040 ++++++++++++++++++++
 .../contentloader/internal/NodeDescription.java    |  153 +++
 .../jcr/contentloader/internal/NodeReader.java     |   31 +
 .../jcr/contentloader/internal/PathEntry.java      |  140 +++
 .../internal/PropertyDescription.java              |  119 +++
 .../jcr/contentloader/internal/XmlReader.java      |  169 ++++
 src/main/resources/META-INF/DISCLAIMER             |    7 +
 src/main/resources/META-INF/LICENSE                |  232 +++++
 src/main/resources/META-INF/NOTICE                 |   11 +
 .../jcr/contentloader/internal/JsonReaderTest.java |  374 +++++++
 17 files changed, 3212 insertions(+)

diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..f31ecff
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,8 @@
+Apache Sling Initial Content Loader
+Copyright 2008 The Apache Software Foundation
+
+Apache Sling is based on source code originally developed 
+by Day Software (http://www.day.com/).
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..9c00331
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,38 @@
+Apache Sling Initial Content Loader
+
+This bundle provides initial content installation through bundles.
+
+
+Disclaimer
+==========
+Apache Sling is an effort undergoing incubation at The Apache Software Foundation (ASF),
+sponsored by the Apache Jackrabbit PMC. Incubation is required of all newly accepted
+projects until a further review indicates that the infrastructure, communications,
+and decision making process have stabilized in a manner consistent with other
+successful ASF projects. While incubation status is not necessarily a reflection of
+the completeness or stability of the code, it does indicate that the project has yet
+to be fully endorsed by the ASF.
+
+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/incubator/sling/trunk/jcr/contentloader
+
+See the Subversion documentation for other source control features.
+
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..55725f2
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,132 @@
+<?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>3-incubator</version>
+        <relativePath>../../parent/pom.xml</relativePath>
+    </parent>
+
+    <artifactId>org.apache.sling.jcr.contentloader</artifactId>
+    <version>2.0.2-incubator</version>
+    <packaging>bundle</packaging>
+
+    <name>Sling - Initial Content Loader</name>
+    <description>
+        This bundle provides initial content installation through bundles.
+    </description>
+
+    <scm>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/incubator/sling/tags/org.apache.sling.jcr.contentloader-2.0.2-incubator</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/incubator/sling/tags/org.apache.sling.jcr.contentloader-2.0.2-incubator</developerConnection>
+        <url>http://svn.apache.org/viewvc/incubator/sling/tags/org.apache.sling.jcr.contentloader-2.0.2-incubator</url>
+    </scm>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-scr-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Private-Package>
+                            org.apache.sling.jcr.contentloader.internal.*,
+                            org.kxml2.io, org.xmlpull.v1
+                        </Private-Package>
+
+                        <Embed-Dependency>
+                            kxml2
+                        </Embed-Dependency>
+
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <reporting>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <configuration>
+                    <excludePackageNames>
+                        org.apache.sling.jcr.contentloader.internal
+                    </excludePackageNames>
+                </configuration>
+            </plugin>
+        </plugins>
+    </reporting>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.osgi.core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.jcr.api</artifactId>
+            <version>2.0.2-incubator</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.json</artifactId>
+            <version>2.0.2-incubator</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.mime</artifactId>
+            <version>2.0.2-incubator</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.osgi</artifactId>
+            <version>2.0.2-incubator</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.engine</artifactId>
+            <version>2.0.2-incubator</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>net.sf.kxml</groupId>
+            <artifactId>kxml2</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java
new file mode 100644
index 0000000..347ce30
--- /dev/null
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java
@@ -0,0 +1,340 @@
+/*
+ * 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.contentloader.internal;
+
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.lock.LockException;
+
+import org.apache.sling.commons.mime.MimeTypeService;
+import org.apache.sling.engine.SlingSettingsService;
+import org.apache.sling.jcr.api.SlingRepository;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.SynchronousBundleListener;
+import org.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The <code>ContentLoaderService</code> is the service
+ * providing the following functionality:
+ * <ul>
+ * <li>Bundle listener to load initial content.
+ * <li>Fires OSGi EventAdmin events on behalf of internal helper objects
+ * </ul>
+ *
+ * @scr.component metatype="no"
+ * @scr.property name="service.description" value="Sling
+ *               Content Loader Implementation"
+ * @scr.property name="service.vendor" value="The Apache Software Foundation"
+ */
+public class ContentLoaderService implements SynchronousBundleListener {
+
+    public static final String PROPERTY_CONTENT_LOADED = "content-loaded";
+
+    public static final String BUNDLE_CONTENT_NODE = "/var/sling/bundle-content";
+
+    /** default log */
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    /**
+     * The JCR Repository we access to resolve resources
+     *
+     * @scr.reference
+     */
+    private SlingRepository repository;
+
+    /**
+     * The MimeTypeService used by the initial content initialContentLoader to
+     * resolve MIME types for files to be installed.
+     *
+     * @scr.reference
+     */
+    private MimeTypeService mimeTypeService;
+
+    /**
+     * Administrative sessions used to check item existence.
+     */
+    private Session adminSession;
+
+    /**
+     * The initial content loader which is called to load initial content up
+     * into the repository when the providing bundle is installed.
+     */
+    private Loader initialContentLoader;
+
+    /**
+     * The id of the current instance
+     */
+    private String slingId;
+
+    /**
+     * List of currently updated bundles.
+     */
+    private final Set<String> updatedBundles = new HashSet<String>();
+
+    /** @scr.reference
+     *  Sling settings service. */
+    protected SlingSettingsService settingsService;
+
+    // ---------- BundleListener -----------------------------------------------
+
+    /**
+     * Loads and unloads any content provided by the bundle whose state
+     * changed. If the bundle has been started, the content is loaded. If
+     * the bundle is about to stop, the content are unloaded.
+     *
+     * @param event The <code>BundleEvent</code> representing the bundle state
+     *            change.
+     */
+    public void bundleChanged(BundleEvent event) {
+
+        //
+        // NOTE:
+        // This is synchronous - take care to not block the system !!
+        //
+
+        switch (event.getType()) {
+            case BundleEvent.STARTING:
+                // register content when the bundle content is available
+                // as node types are registered when the bundle is installed
+                // we can safely add the content at this point.
+                try {
+                    Session session = getAdminSession();
+                    final boolean isUpdate = this.updatedBundles.remove(event.getBundle().getSymbolicName());
+                    initialContentLoader.registerBundle(session, event.getBundle(), isUpdate);
+                } catch (Throwable t) {
+                    log.error(
+                        "bundleChanged: Problem loading initial content of bundle "
+                            + event.getBundle().getSymbolicName() + " ("
+                            + event.getBundle().getBundleId() + ")", t);
+                }
+                break;
+            case BundleEvent.UPDATED:
+                // we just add the symbolic name to the list of updated bundles
+                // we will use this info when the new start event is triggered
+                this.updatedBundles.add(event.getBundle().getSymbolicName());
+                break;
+            case BundleEvent.STOPPED:
+                try {
+                    Session session = getAdminSession();
+                    initialContentLoader.unregisterBundle(session, event.getBundle());
+                } catch (Throwable t) {
+                    log.error(
+                        "bundleChanged: Problem unloading initial content of bundle "
+                            + event.getBundle().getSymbolicName() + " ("
+                            + event.getBundle().getBundleId() + ")", t);
+                }
+                break;
+        }
+    }
+
+    // ---------- Implementation helpers --------------------------------------
+
+    /** Returns the MIME type from the MimeTypeService for the given name */
+    public String getMimeType(String name) {
+        // local copy to not get NPE despite check for null due to concurrent
+        // unbind
+        MimeTypeService mts = mimeTypeService;
+        return (mts != null) ? mts.getMimeType(name) : null;
+    }
+
+    protected void createRepositoryPath(final Session writerSession, final String repositoryPath)
+    throws RepositoryException {
+        if ( !writerSession.itemExists(repositoryPath) ) {
+            Node node = writerSession.getRootNode();
+            String path = repositoryPath.substring(1);
+            int pos = path.lastIndexOf('/');
+            if ( pos != -1 ) {
+                final StringTokenizer st = new StringTokenizer(path.substring(0, pos), "/");
+                while ( st.hasMoreTokens() ) {
+                    final String token = st.nextToken();
+                    if ( !node.hasNode(token) ) {
+                        node.addNode(token, "sling:Folder");
+                        node.save();
+                    }
+                    node = node.getNode(token);
+                }
+                path = path.substring(pos + 1);
+            }
+            if ( !node.hasNode(path) ) {
+                node.addNode(path, "sling:Folder");
+                node.save();
+            }
+        }
+    }
+
+    // ---------- SCR Integration ---------------------------------------------
+
+    /** Activates this component, called by SCR before registering as a service */
+    protected void activate(ComponentContext componentContext) {
+        this.slingId = this.settingsService.getSlingId();
+        this.initialContentLoader = new Loader(this);
+
+        componentContext.getBundleContext().addBundleListener(this);
+
+        try {
+            final Session session = getAdminSession();
+            this.createRepositoryPath(session, ContentLoaderService.BUNDLE_CONTENT_NODE);
+            log.debug(
+                    "Activated - attempting to load content from all "
+                    + "bundles which are neither INSTALLED nor UNINSTALLED");
+
+            int ignored = 0;
+            Bundle[] bundles = componentContext.getBundleContext().getBundles();
+            for (Bundle bundle : bundles) {
+                if ((bundle.getState() & (Bundle.INSTALLED | Bundle.UNINSTALLED)) == 0) {
+                    // load content for bundles which are neither INSTALLED nor
+                    // UNINSTALLED
+                    initialContentLoader.registerBundle(session, bundle, false);
+                } else {
+                    ignored++;
+                }
+
+            }
+
+            log.debug(
+                    "Out of {} bundles, {} were not in a suitable state for initial content loading",
+                    bundles.length, ignored
+                    );
+
+        } catch (Throwable t) {
+            log.error("activate: Problem while loading initial content and"
+                + " registering mappings for existing bundles", t);
+        }
+    }
+
+    /** Deativates this component, called by SCR to take out of service */
+    protected void deactivate(ComponentContext componentContext) {
+        componentContext.getBundleContext().removeBundleListener(this);
+
+        if ( this.initialContentLoader != null ) {
+            this.initialContentLoader.dispose();
+            this.initialContentLoader = null;
+        }
+
+        if ( adminSession != null ) {
+            this.adminSession.logout();
+            this.adminSession = null;
+        }
+    }
+
+    // ---------- internal helper ----------------------------------------------
+
+    /** Returns the JCR repository used by this service. */
+    protected SlingRepository getRepository() {
+        return repository;
+    }
+
+    /**
+     * Returns an administrative session to the default workspace.
+     */
+    private synchronized Session getAdminSession()
+    throws RepositoryException {
+        if ( adminSession == null ) {
+            adminSession = getRepository().loginAdministrative(null);
+        }
+        return adminSession;
+    }
+
+    /**
+     * Return the bundle content info and make an exclusive lock.
+     * @param session
+     * @param bundle
+     * @return The map of bundle content info or null.
+     * @throws RepositoryException
+     */
+    public Map<String, Object> getBundleContentInfo(final Session session, final Bundle bundle)
+    throws RepositoryException {
+        final String nodeName = bundle.getSymbolicName();
+        final Node parentNode = (Node)session.getItem(BUNDLE_CONTENT_NODE);
+        if ( !parentNode.hasNode(nodeName) ) {
+            try {
+                final Node bcNode = parentNode.addNode(nodeName, "nt:unstructured");
+                bcNode.addMixin("mix:lockable");
+                parentNode.save();
+            } catch (RepositoryException re) {
+                // for concurrency issues (running in a cluster) we ignore exceptions
+                this.log.warn("Unable to create node " + nodeName, re);
+                session.refresh(true);
+            }
+        }
+        final Node bcNode = parentNode.getNode(nodeName);
+        if ( bcNode.isLocked() ) {
+            return null;
+        }
+        try {
+            bcNode.lock(false, true);
+        } catch (LockException le) {
+            return null;
+        }
+        final Map<String, Object> info = new HashMap<String, Object>();
+        if ( bcNode.hasProperty(ContentLoaderService.PROPERTY_CONTENT_LOADED) ) {
+            info.put(ContentLoaderService.PROPERTY_CONTENT_LOADED,
+                    bcNode.getProperty(ContentLoaderService.PROPERTY_CONTENT_LOADED).getBoolean());
+        } else {
+            info.put(ContentLoaderService.PROPERTY_CONTENT_LOADED, false);
+        }
+        return info;
+    }
+
+    public void unlockBundleContentInfo(final Session session,
+                                        final Bundle  bundle,
+                                        final boolean contentLoaded)
+    throws RepositoryException {
+        final String nodeName = bundle.getSymbolicName();
+        final Node parentNode = (Node)session.getItem(BUNDLE_CONTENT_NODE);
+        final Node bcNode = parentNode.getNode(nodeName);
+        if ( contentLoaded ) {
+            bcNode.setProperty(ContentLoaderService.PROPERTY_CONTENT_LOADED, contentLoaded);
+            bcNode.setProperty("content-load-time", Calendar.getInstance());
+            bcNode.setProperty("content-loaded-by", this.slingId);
+            bcNode.setProperty("content-unload-time", (String)null);
+            bcNode.setProperty("content-unloaded-by", (String)null);
+            bcNode.save();
+        }
+        bcNode.unlock();
+    }
+
+    public void contentIsUninstalled(final Session session,
+                                     final Bundle  bundle) {
+        final String nodeName = bundle.getSymbolicName();
+        try {
+            final Node parentNode = (Node)session.getItem(BUNDLE_CONTENT_NODE);
+            if ( parentNode.hasNode(nodeName) ) {
+                final Node bcNode = parentNode.getNode(nodeName);
+                bcNode.setProperty(ContentLoaderService.PROPERTY_CONTENT_LOADED, false);
+                bcNode.setProperty("content-unload-time", Calendar.getInstance());
+                bcNode.setProperty("content-unloaded-by", this.slingId);
+                bcNode.save();
+            }
+        } catch (RepositoryException re) {
+            this.log.error("Unable to update bundle content info.", re);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/ImportProvider.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/ImportProvider.java
new file mode 100644
index 0000000..e28fd55
--- /dev/null
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/ImportProvider.java
@@ -0,0 +1,27 @@
+/*
+ * 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.contentloader.internal;
+
+import java.io.IOException;
+
+interface ImportProvider {
+
+    NodeReader getReader() throws IOException;
+    
+}
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/JsonReader.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/JsonReader.java
new file mode 100644
index 0000000..ef5c4b4
--- /dev/null
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/JsonReader.java
@@ -0,0 +1,189 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.jcr.contentloader.internal;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.jcr.PropertyType;
+
+import org.apache.sling.commons.json.JSONArray;
+import org.apache.sling.commons.json.JSONException;
+import org.apache.sling.commons.json.JSONObject;
+
+
+/**
+ * The <code>JsonReader</code> TODO
+ */
+class JsonReader implements NodeReader {
+
+    private static final Set<String> ignoredNames = new HashSet<String>();
+    static {
+        ignoredNames.add("jcr:primaryType");
+        ignoredNames.add("jcr:mixinTypes");
+        ignoredNames.add("jcr:uuid");
+        ignoredNames.add("jcr:baseVersion");
+        ignoredNames.add("jcr:predecessors");
+        ignoredNames.add("jcr:successors");
+        ignoredNames.add("jcr:checkedOut");
+        ignoredNames.add("jcr:created");
+    }
+
+    static final ImportProvider PROVIDER = new ImportProvider() {
+        private JsonReader jsonReader;
+
+        public NodeReader getReader() {
+            if (jsonReader == null) {
+                jsonReader = new JsonReader();
+            }
+            return jsonReader;
+        }
+    };
+
+    public NodeDescription parse(InputStream ins) throws IOException {
+        try {
+            String jsonString = toString(ins).trim();
+            if (!jsonString.startsWith("{")) {
+                jsonString = "{" + jsonString + "}";
+            }
+
+            JSONObject json = new JSONObject(jsonString);
+            return this.createNode(null, json);
+
+        } catch (JSONException je) {
+            throw (IOException) new IOException(je.getMessage()).initCause(je);
+        }
+    }
+
+    protected NodeDescription createNode(String name, JSONObject obj) throws JSONException {
+        NodeDescription node = new NodeDescription();
+        node.setName(name);
+
+        Object primaryType = obj.opt("jcr:primaryType");
+        if (primaryType != null) {
+            node.setPrimaryNodeType(String.valueOf(primaryType));
+        }
+
+        Object mixinsObject = obj.opt("jcr:mixinTypes");
+        if (mixinsObject instanceof JSONArray) {
+            JSONArray mixins = (JSONArray) mixinsObject;
+            for (int i = 0; i < mixins.length(); i++) {
+                node.addMixinNodeType(mixins.getString(i));
+            }
+        }
+
+        // add properties and nodes
+        JSONArray names = obj.names();
+        for (int i = 0; names != null && i < names.length(); i++) {
+            String n = names.getString(i);
+            // skip well known objects
+            if (!ignoredNames.contains(n)) {
+                Object o = obj.get(n);
+                if (o instanceof JSONObject) {
+                    NodeDescription child = this.createNode(n, (JSONObject) o);
+                    node.addChild(child);
+                } else if (o instanceof JSONArray) {
+                    PropertyDescription prop = createProperty(n, o);
+                    node.addProperty(prop);
+                } else {
+                    PropertyDescription prop = createProperty(n, o);
+                    node.addProperty(prop);
+                }
+            }
+        }
+        return node;
+    }
+
+    protected PropertyDescription createProperty(String name, Object value)
+            throws JSONException {
+        PropertyDescription property = new PropertyDescription();
+        property.setName(name);
+
+        // assume simple value
+        if (value instanceof JSONArray) {
+            // multivalue
+            JSONArray array = (JSONArray) value;
+            if (array.length() > 0) {
+                for (int i = 0; i < array.length(); i++) {
+                    property.addValue(array.get(i));
+                }
+                value = array.opt(0);
+            } else {
+                property.addValue(null);
+                value = null;
+            }
+
+        } else {
+            // single value
+            property.setValue(String.valueOf(value));
+        }
+        // set type
+        property.setType(getType(value));
+
+        return property;
+    }
+
+    protected String getType(Object object) {
+        if (object instanceof Double || object instanceof Float) {
+            return PropertyType.TYPENAME_DOUBLE;
+        } else if (object instanceof Number) {
+            return PropertyType.TYPENAME_LONG;
+        } else if (object instanceof Boolean) {
+            return PropertyType.TYPENAME_BOOLEAN;
+        }
+
+        // fall back to default
+        return PropertyType.TYPENAME_STRING;
+    }
+
+    private String toString(InputStream ins) throws IOException {
+        if (!ins.markSupported()) {
+            ins = new BufferedInputStream(ins);
+        }
+
+        String encoding;
+        ins.mark(5);
+        int c = ins.read();
+        if (c == '#') {
+            // character encoding following
+            StringBuffer buf = new StringBuffer();
+            for (c = ins.read(); !Character.isWhitespace((char) c); c = ins.read()) {
+                buf.append((char) c);
+            }
+            encoding = buf.toString();
+        } else {
+            ins.reset();
+            encoding = "UTF-8";
+        }
+
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        byte[] buf = new byte[1024];
+        int rd;
+        while ( (rd = ins.read(buf)) >= 0) {
+            bos.write(buf, 0, rd);
+        }
+        bos.close(); // just to comply with the contract
+
+        return new String(bos.toByteArray(), encoding);
+    }
+}
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/Loader.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/Loader.java
new file mode 100644
index 0000000..ca6c28f
--- /dev/null
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/Loader.java
@@ -0,0 +1,1040 @@
+/*
+ * 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.contentloader.internal;
+
+import static javax.jcr.ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jcr.InvalidSerializedDataException;
+import javax.jcr.Item;
+import javax.jcr.Node;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.osgi.framework.Bundle;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The <code>Loader</code> loads initial content from the bundle.
+ */
+public class Loader {
+
+    public static final String EXT_XML = ".xml";
+
+    public static final String EXT_JCR_XML = ".jcr.xml";
+
+    public static final String EXT_JSON = ".json";
+
+    public static final String ROOT_DESCRIPTOR = "/ROOT";
+
+    // default content type for createFile()
+    private static final String DEFAULT_CONTENT_TYPE = "application/octet-stream";
+
+    /** default log */
+    private final Logger log = LoggerFactory.getLogger(Loader.class);
+
+    private ContentLoaderService jcrContentHelper;
+
+    private Map<String, ImportProvider> importProviders;
+
+    private Map<String, List<String>> delayedReferences;
+
+    // bundles whose registration failed and should be retried
+    private List<Bundle> delayedBundles;
+
+    public Loader(ContentLoaderService jcrContentHelper) {
+        this.jcrContentHelper = jcrContentHelper;
+        this.delayedReferences = new HashMap<String, List<String>>();
+        this.delayedBundles = new LinkedList<Bundle>();
+
+        importProviders = new LinkedHashMap<String, ImportProvider>();
+        importProviders.put(EXT_JCR_XML, null);
+        importProviders.put(EXT_JSON, JsonReader.PROVIDER);
+        importProviders.put(EXT_XML, XmlReader.PROVIDER);
+    }
+
+    public void dispose() {
+        delayedReferences = null;
+        if (delayedBundles != null) {
+            delayedBundles.clear();
+            delayedBundles = null;
+        }
+        jcrContentHelper = null;
+        importProviders.clear();
+    }
+
+    /**
+     * Register a bundle and install its content.
+     * 
+     * @param session
+     * @param bundle
+     */
+    public void registerBundle(final Session session, final Bundle bundle,
+            final boolean isUpdate) {
+
+        log.debug("Registering bundle {} for content loading.",
+            bundle.getSymbolicName());
+
+        if (registerBundleInternal(session, bundle, false, isUpdate)) {
+
+            // handle delayed bundles, might help now
+            int currentSize = -1;
+            for (int i = delayedBundles.size(); i > 0
+                && currentSize != delayedBundles.size()
+                && !delayedBundles.isEmpty(); i--) {
+
+                for (Iterator<Bundle> di = delayedBundles.iterator(); di.hasNext();) {
+
+                    Bundle delayed = di.next();
+                    if (registerBundleInternal(session, delayed, true, false)) {
+                        di.remove();
+                    }
+
+                }
+
+                currentSize = delayedBundles.size();
+            }
+
+        } else if (!isUpdate) {
+            // add to delayed bundles - if this is not an update!
+            delayedBundles.add(bundle);
+        }
+    }
+
+    private boolean registerBundleInternal(final Session session,
+            final Bundle bundle, final boolean isRetry, final boolean isUpdate) {
+
+        // check if bundle has initial content
+        final Iterator<PathEntry> pathIter = PathEntry.getContentPaths(bundle);
+        if (pathIter == null) {
+            log.debug("Bundle {} has no initial content",
+                bundle.getSymbolicName());
+            return true;
+        }
+
+        try {
+            
+            // check if the content has already been loaded
+            final Map<String, Object> bundleContentInfo = jcrContentHelper.getBundleContentInfo(
+                session, bundle);
+            
+            // if we don't get an info, someone else is currently loading
+            if (bundleContentInfo == null) {
+                return false;
+            }
+
+            boolean success = false;
+            try {
+                
+                final boolean contentAlreadyLoaded = ((Boolean) bundleContentInfo.get(ContentLoaderService.PROPERTY_CONTENT_LOADED)).booleanValue();
+                
+                if (!isUpdate && contentAlreadyLoaded) {
+                    
+                    log.info("Content of bundle already loaded {}.",
+                        bundle.getSymbolicName());
+                    
+                } else {
+                    
+                    installContent(session, bundle, pathIter,
+                        contentAlreadyLoaded);
+                    
+                    if (isRetry) {
+                        // log success of retry
+                        log.info(
+                            "Retrytring to load initial content for bundle {} succeeded.",
+                            bundle.getSymbolicName());
+                    }
+                    
+                }
+                
+                success = true;
+                return true;
+                
+            } finally {
+                jcrContentHelper.unlockBundleContentInfo(session, bundle,
+                    success);
+            }
+            
+        } catch (RepositoryException re) {
+            // if we are retrying we already logged this message once, so we
+            // won't log it again
+            if (!isRetry) {
+                log.error("Cannot load initial content for bundle "
+                    + bundle.getSymbolicName() + " : " + re.getMessage(), re);
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Unregister a bundle. Remove installed content.
+     * 
+     * @param bundle The bundle.
+     */
+    public void unregisterBundle(final Session session, final Bundle bundle) {
+        
+        // check if bundle has initial content
+        final Iterator<PathEntry> pathIter = PathEntry.getContentPaths(bundle);
+        if (delayedBundles.contains(bundle)) {
+            
+            delayedBundles.remove(bundle);
+            
+        } else {
+            
+            if (pathIter != null) {
+                uninstallContent(session, bundle, pathIter);
+                jcrContentHelper.contentIsUninstalled(session, bundle);
+            }
+            
+        }
+    }
+
+    // ---------- internal -----------------------------------------------------
+
+    private void installContent(final Session session, final Bundle bundle,
+            final Iterator<PathEntry> pathIter,
+            final boolean contentAlreadyLoaded) throws RepositoryException {
+        log.debug("Installing initial content from bundle {}",
+            bundle.getSymbolicName());
+        try {
+
+            // the nodes marked to be checked-in after import
+            List<Node> versionables = new ArrayList<Node>();
+
+            while (pathIter.hasNext()) {
+                final PathEntry entry = pathIter.next();
+                if (!contentAlreadyLoaded || entry.isOverwrite()) {
+                    
+                    Node targetNode = getTargetNode(session, entry.getTarget());
+
+                    if (targetNode != null) {
+                        installFromPath(bundle, entry.getPath(),
+                            entry.isOverwrite(), versionables,
+                            entry.isCheckin(), targetNode);
+                    }
+                }
+            }
+
+            // persist modifications now
+            session.save();
+
+            // finally checkin versionable nodes
+            for (Node versionable : versionables) {
+                versionable.checkin();
+            }
+
+        } finally {
+            try {
+                if (session.hasPendingChanges()) {
+                    session.refresh(false);
+                }
+            } catch (RepositoryException re) {
+                log.warn(
+                    "Failure to rollback partial initial content for bundle {}",
+                    bundle.getSymbolicName(), re);
+            }
+        }
+        log.debug("Done installing initial content from bundle {}",
+            bundle.getSymbolicName());
+
+    }
+
+    /**
+     * Handle content installation for a single path.
+     * 
+     * @param bundle The bundle containing the content.
+     * @param path The path
+     * @param overwrite Should the content be overwritten.
+     * @param parent The parent node.
+     * @throws RepositoryException
+     */
+    private void installFromPath(final Bundle bundle, final String path,
+            final boolean overwrite, List<Node> versionables,
+            final boolean checkin, final Node parent)
+            throws RepositoryException {
+        
+        @SuppressWarnings("unchecked")
+        Enumeration<String> entries = bundle.getEntryPaths(path);
+        if (entries == null) {
+            log.info("install: No initial content entries at {}", path);
+            return;
+        }
+
+        Set<URL> ignoreEntry = new HashSet<URL>();
+
+        // potential root node import/extension
+        URL rootNodeDescriptor = importRootNode(parent.getSession(), bundle,
+            path, versionables, checkin);
+        if (rootNodeDescriptor != null) {
+            ignoreEntry.add(rootNodeDescriptor);
+        }
+
+        while (entries.hasMoreElements()) {
+            final String entry = entries.nextElement();
+            log.debug("Processing initial content entry {}", entry);
+            if (entry.endsWith("/")) {
+                
+                // dir, check for node descriptor , else create dir
+                String base = entry.substring(0, entry.length() - 1);
+                String name = getName(base);
+
+                URL nodeDescriptor = null;
+                for (String ext : importProviders.keySet()) {
+                    nodeDescriptor = bundle.getEntry(base + ext);
+                    if (nodeDescriptor != null) {
+                        break;
+                    }
+                }
+
+                // if we have a descriptor, which has not been processed yet,
+                // otherwise call createFolder, which creates an nt:folder or
+                // returns an existing node (created by a descriptor)
+                Node node = null;
+                if (nodeDescriptor != null
+                    && !ignoreEntry.contains(nodeDescriptor)) {
+                    node = createNode(parent, name, nodeDescriptor, overwrite,
+                        versionables, checkin);
+                    ignoreEntry.add(nodeDescriptor);
+                } else {
+                    node = createFolder(parent, name, overwrite);
+                }
+
+                // walk down the line
+                if (node != null) {
+                    installFromPath(bundle, entry, overwrite, versionables,
+                        checkin, node);
+                }
+
+            } else {
+                
+                // file => create file
+                URL file = bundle.getEntry(entry);
+                if (ignoreEntry.contains(file)) {
+                    // this is a consumed node descriptor
+                    continue;
+                }
+
+                // install if it is a descriptor
+                boolean foundProvider = false;
+                final Iterator<String> ipIter = importProviders.keySet().iterator();
+                while (!foundProvider && ipIter.hasNext()) {
+                    final String ext = ipIter.next();
+                    if (entry.endsWith(ext)) {
+                        foundProvider = true;
+                    }
+                }
+                if (foundProvider) {
+                    if (createNode(parent, getName(entry), file, overwrite,
+                        versionables, checkin) != null) {
+                        ignoreEntry.add(file);
+                        continue;
+                    }
+                }
+
+                // otherwise just place as file
+                try {
+                    createFile(parent, file);
+                } catch (IOException ioe) {
+                    log.warn("Cannot create file node for {}", file, ioe);
+                }
+            }
+        }
+    }
+
+    private Node createNode(Node parent, String name, URL nodeXML,
+            boolean overwrite, List<Node> versionables, boolean checkin)
+            throws RepositoryException {
+
+        InputStream ins = null;
+        try {
+            // special treatment for system view imports
+            if (nodeXML.getPath().toLowerCase().endsWith(EXT_JCR_XML)) {
+                return importSystemView(parent, name, nodeXML);
+            }
+
+            NodeReader nodeReader = null;
+            for (Map.Entry<String, ImportProvider> e : importProviders.entrySet()) {
+                if (nodeXML.getPath().toLowerCase().endsWith(e.getKey())) {
+                    nodeReader = e.getValue().getReader();
+                    break;
+                }
+            }
+
+            // cannot find out the type
+            if (nodeReader == null) {
+                return null;
+            }
+
+            ins = nodeXML.openStream();
+            NodeDescription clNode = nodeReader.parse(ins);
+
+            // nothing has been parsed
+            if (clNode == null) {
+                return null;
+            }
+
+            if (clNode.getName() == null) {
+                // set the name without the [last] extension (xml or json)
+                clNode.setName(toPlainName(name));
+            }
+
+            return createNode(parent, clNode, overwrite, versionables, checkin);
+        } catch (RepositoryException re) {
+            throw re;
+        } catch (Throwable t) {
+            throw new RepositoryException(t.getMessage(), t);
+        } finally {
+            if (ins != null) {
+                try {
+                    ins.close();
+                } catch (IOException ignore) {
+                }
+            }
+        }
+    }
+
+    /**
+     * Delete the node from the initial content.
+     * 
+     * @param parent
+     * @param name
+     * @param nodeXML
+     * @throws RepositoryException
+     */
+    private void deleteNode(Node parent, String name)
+            throws RepositoryException {
+        if (parent.hasNode(name)) {
+            parent.getNode(name).remove();
+        }
+    }
+
+    private Node createNode(Node parentNode, NodeDescription clNode,
+            final boolean overwrite, List<Node> versionables, boolean checkin)
+            throws RepositoryException {
+        
+        // if node already exists but should be overwritten, delete it
+        if (overwrite && parentNode.hasNode(clNode.getName())) {
+            parentNode.getNode(clNode.getName()).remove();
+        }
+
+        // ensure repository node
+        Node node;
+        if (parentNode.hasNode(clNode.getName())) {
+
+            // use existing node
+            node = parentNode.getNode(clNode.getName());
+
+        } else if (clNode.getPrimaryNodeType() == null) {
+
+            // node explicit node type, use repository default
+            node = parentNode.addNode(clNode.getName());
+
+        } else {
+
+            // explicit primary node type
+            node = parentNode.addNode(clNode.getName(),
+                clNode.getPrimaryNodeType());
+        }
+
+        return setupNode(node, clNode, versionables, checkin);
+    }
+
+    private Node setupNode(Node node, NodeDescription clNode,
+            List<Node> versionables, boolean checkin)
+            throws RepositoryException {
+
+        // ammend mixin node types
+        if (clNode.getMixinNodeTypes() != null) {
+            for (String mixin : clNode.getMixinNodeTypes()) {
+                if (!node.isNodeType(mixin)) {
+                    node.addMixin(mixin);
+                }
+            }
+        }
+
+        // check if node is versionable
+        boolean addToVersionables = checkin
+            && node.isNodeType("mix:versionable");
+
+        if (clNode.getProperties() != null) {
+            for (PropertyDescription prop : clNode.getProperties()) {
+                if (node.hasProperty(prop.getName())
+                    && !node.getProperty(prop.getName()).isNew()) {
+                    continue;
+                }
+
+                int type = PropertyType.valueFromName(prop.getType());
+                if (prop.isMultiValue()) {
+
+                    String[] values = prop.getValues().toArray(
+                        new String[prop.getValues().size()]);
+                    node.setProperty(prop.getName(), values, type);
+
+                } else if (type == PropertyType.REFERENCE) {
+
+                    // need to resolve the reference
+                    String propPath = node.getPath() + "/" + prop.getName();
+                    String uuid = getUUID(node.getSession(), propPath,
+                        prop.getValue());
+                    if (uuid != null) {
+                        node.setProperty(prop.getName(), uuid, type);
+                    }
+
+                } else if ("jcr:isCheckedOut".equals(prop.getName())) {
+
+                    // don't try to write the property but record its state
+                    // for later checkin if set to false
+                    boolean checkedout = Boolean.valueOf(prop.getValue());
+                    if (!checkedout) {
+                        addToVersionables = true;
+                    }
+
+                } else {
+
+                    node.setProperty(prop.getName(), prop.getValue(), type);
+
+                }
+            }
+        }
+
+        // add the current node to the list of versionables to be checked
+        // in at the end. This is done if checkin is true and the node is
+        // versionable or if the jcr:isCheckedOut property is false
+        if (addToVersionables) {
+            versionables.add(node);
+        }
+
+        // create child nodes from the descriptor
+        if (clNode.getChildren() != null) {
+            for (NodeDescription child : clNode.getChildren()) {
+                createNode(node, child, false, versionables, checkin);
+            }
+        }
+
+        // resolve REFERENCE property values pointing to this node
+        resolveReferences(node);
+
+        return node;
+    }
+
+    /**
+     * Create a folder
+     * 
+     * @param parent The parent node.
+     * @param name The name of the folder
+     * @param overwrite If set to true, an existing folder is removed first.
+     * @return The node pointing to the folder.
+     * @throws RepositoryException
+     */
+    private Node createFolder(Node parent, String name, final boolean overwrite)
+            throws RepositoryException {
+        if (parent.hasNode(name)) {
+            if (overwrite) {
+                parent.getNode(name).remove();
+            } else {
+                return parent.getNode(name);
+            }
+        }
+
+        return parent.addNode(name, "nt:folder");
+    }
+
+    /**
+     * Create a file from the given url.
+     * 
+     * @param parent
+     * @param source
+     * @throws IOException
+     * @throws RepositoryException
+     */
+    private void createFile(Node parent, URL source) throws IOException,
+            RepositoryException {
+        String name = getName(source.getPath());
+        if (parent.hasNode(name)) {
+            return;
+        }
+
+        URLConnection conn = source.openConnection();
+        long lastModified = conn.getLastModified();
+        String type = conn.getContentType();
+        InputStream data = conn.getInputStream();
+
+        // ensure content type
+        if (type == null) {
+            type = jcrContentHelper.getMimeType(name);
+            if (type == null) {
+                log.info(
+                    "createFile: Cannot find content type for {}, using {}",
+                    source.getPath(), DEFAULT_CONTENT_TYPE);
+                type = DEFAULT_CONTENT_TYPE;
+            }
+        }
+
+        // ensure sensible last modification date
+        if (lastModified <= 0) {
+            lastModified = System.currentTimeMillis();
+        }
+
+        Node file = parent.addNode(name, "nt:file");
+        Node content = file.addNode("jcr:content", "nt:resource");
+        content.setProperty("jcr:mimeType", type);
+        content.setProperty("jcr:lastModified", lastModified);
+        content.setProperty("jcr:data", data);
+    }
+
+    /**
+     * Delete the file from the given url.
+     * 
+     * @param parent
+     * @param source
+     * @throws IOException
+     * @throws RepositoryException
+     */
+    private void deleteFile(Node parent, URL source) throws IOException,
+            RepositoryException {
+        String name = getName(source.getPath());
+        if (parent.hasNode(name)) {
+            parent.getNode(name).remove();
+        }
+    }
+
+    private String getUUID(Session session, String propPath,
+            String referencePath) throws RepositoryException {
+        if (session.itemExists(referencePath)) {
+            Item item = session.getItem(referencePath);
+            if (item.isNode()) {
+                Node refNode = (Node) item;
+                if (refNode.isNodeType("mix:referenceable")) {
+                    return refNode.getUUID();
+                }
+            }
+        } else {
+            // not existing yet, keep for delayed setting
+            List<String> current = delayedReferences.get(referencePath);
+            if (current == null) {
+                current = new ArrayList<String>();
+                delayedReferences.put(referencePath, current);
+            }
+            current.add(propPath);
+        }
+
+        // no UUID found
+        return null;
+    }
+
+    private void resolveReferences(Node node) throws RepositoryException {
+        List<String> props = delayedReferences.remove(node.getPath());
+        if (props == null || props.size() == 0) {
+            return;
+        }
+
+        // check whether we can set at all
+        if (!node.isNodeType("mix:referenceable")) {
+            return;
+        }
+
+        Session session = node.getSession();
+        String uuid = node.getUUID();
+
+        for (String property : props) {
+            String name = getName(property);
+            Node parentNode = getParentNode(session, property);
+            if (parentNode != null) {
+                parentNode.setProperty(name, uuid, PropertyType.REFERENCE);
+            }
+        }
+    }
+
+    /**
+     * Gets and decods the name part of the <code>path</code>. The name is
+     * the part of the path after the last slash (or the complete path if no
+     * slash is contained). To support names containing unsupported characters
+     * such as colon (<code>:</code>), names may be URL encoded (see
+     * <code>java.net.URLEncoder</code>) using the <i>UTF-8</i> character
+     * encoding. In this case, this method decodes the name using the
+     * <code>java.netURLDecoder</code> class with the <i>UTF-8</i> character
+     * encoding.
+     * 
+     * @param path The path from which to extract the name part.
+     * @return The URL decoded name part.
+     */
+    private String getName(String path) {
+        int lastSlash = path.lastIndexOf('/');
+        String name = (lastSlash < 0) ? path : path.substring(lastSlash + 1);
+
+        // check for encoded characters (%xx)
+        // has encoded characters, need to decode
+        if (name.indexOf('%') >= 0) {
+            try {
+                return URLDecoder.decode(name, "UTF-8");
+            } catch (UnsupportedEncodingException uee) {
+                // actually unexpected because UTF-8 is required by the spec
+                log.error("Cannot decode "
+                    + name
+                    + " beause the platform has no support for UTF-8, using undecoded");
+            } catch (Exception e) {
+                // IllegalArgumentException or failure to decode
+                log.error("Cannot decode " + name + ", using undecoded", e);
+            }
+        }
+
+        // not encoded or problems decoding, return the name unmodified
+        return name;
+    }
+
+    private Node getParentNode(Session session, String path)
+            throws RepositoryException {
+        int lastSlash = path.lastIndexOf('/');
+
+        // not an absolute path, cannot find parent
+        if (lastSlash < 0) {
+            return null;
+        }
+
+        // node below root
+        if (lastSlash == 0) {
+            return session.getRootNode();
+        }
+
+        // item in the hierarchy
+        path = path.substring(0, lastSlash);
+        if (!session.itemExists(path)) {
+            return null;
+        }
+
+        Item item = session.getItem(path);
+        return (item.isNode()) ? (Node) item : null;
+    }
+
+    private Node getTargetNode(Session session, String path)
+            throws RepositoryException {
+
+        // not specyfied path directive
+        if (path == null) return session.getRootNode();
+
+        int firstSlash = path.indexOf("/");
+
+        // it´s a relative path
+        if (firstSlash != 0) path = "/" + path;
+
+        Item item = session.getItem(path);
+        return (item.isNode()) ? (Node) item : null;
+    }
+
+    private void uninstallContent(final Session session, final Bundle bundle,
+            final Iterator<PathEntry> pathIter) {
+        try {
+            log.debug("Uninstalling initial content from bundle {}",
+                bundle.getSymbolicName());
+            while (pathIter.hasNext()) {
+                final PathEntry entry = pathIter.next();
+                if (entry.isUninstall()) {
+                    Node targetNode = getTargetNode(session, entry.getTarget());
+                    if (targetNode != null)
+                        uninstallFromPath(bundle, entry.getPath(), targetNode);
+                } else {
+                    log.debug(
+                        "Ignoring to uninstall content at {}, uninstall directive is not set.",
+                        entry.getPath());
+                }
+            }
+
+            // persist modifications now
+            session.save();
+            log.debug("Done uninstalling initial content from bundle {}",
+                bundle.getSymbolicName());
+        } catch (RepositoryException re) {
+            log.error("Unable to uninstall initial content from bundle "
+                + bundle.getSymbolicName(), re);
+        } finally {
+            try {
+                if (session.hasPendingChanges()) {
+                    session.refresh(false);
+                }
+            } catch (RepositoryException re) {
+                log.warn(
+                    "Failure to rollback uninstaling initial content for bundle {}",
+                    bundle.getSymbolicName(), re);
+            }
+        }
+    }
+
+    /**
+     * Handle content uninstallation for a single path.
+     * 
+     * @param bundle The bundle containing the content.
+     * @param path The path
+     * @param parent The parent node.
+     * @throws RepositoryException
+     */
+    private void uninstallFromPath(final Bundle bundle, final String path,
+            final Node parent) throws RepositoryException {
+        @SuppressWarnings("unchecked")
+        Enumeration<String> entries = bundle.getEntryPaths(path);
+        if (entries == null) {
+            return;
+        }
+
+        Set<URL> ignoreEntry = new HashSet<URL>();
+
+        // potential root node import/extension
+        Descriptor rootNodeDescriptor = getRootNodeDescriptor(bundle, path);
+        if (rootNodeDescriptor != null) {
+            ignoreEntry.add(rootNodeDescriptor.rootNodeDescriptor);
+        }
+
+        while (entries.hasMoreElements()) {
+            final String entry = entries.nextElement();
+            log.debug("Processing initial content entry {}", entry);
+            if (entry.endsWith("/")) {
+                // dir, check for node descriptor , else create dir
+                String base = entry.substring(0, entry.length() - 1);
+                String name = getName(base);
+
+                URL nodeDescriptor = null;
+                for (String ext : importProviders.keySet()) {
+                    nodeDescriptor = bundle.getEntry(base + ext);
+                    if (nodeDescriptor != null) {
+                        break;
+                    }
+                }
+
+                final Node node;
+                boolean delete = false;
+                if (nodeDescriptor != null
+                    && !ignoreEntry.contains(nodeDescriptor)) {
+                    node = (parent.hasNode(toPlainName(name))
+                            ? parent.getNode(toPlainName(name))
+                            : null);
+                    delete = true;
+                } else {
+                    node = (parent.hasNode(name) ? parent.getNode(name) : null);
+                }
+
+                if (node != null) {
+                    // walk down the line
+                    uninstallFromPath(bundle, entry, node);
+                }
+
+                if (delete) {
+                    deleteNode(parent, toPlainName(name));
+                    ignoreEntry.add(nodeDescriptor);
+                }
+
+            } else {
+                // file => create file
+                URL file = bundle.getEntry(entry);
+                if (ignoreEntry.contains(file)) {
+                    // this is a consumed node descriptor
+                    continue;
+                }
+
+                // uninstall if it is a descriptor
+                boolean foundProvider = false;
+                final Iterator<String> ipIter = importProviders.keySet().iterator();
+                while (!foundProvider && ipIter.hasNext()) {
+                    final String ext = ipIter.next();
+                    if (entry.endsWith(ext)) {
+                        foundProvider = true;
+                    }
+                }
+                if (foundProvider) {
+                    deleteNode(parent, toPlainName(getName(entry)));
+                    ignoreEntry.add(file);
+                    continue;
+                }
+
+                // otherwise just delete the file
+                try {
+                    deleteFile(parent, file);
+                } catch (IOException ioe) {
+                    log.warn("Cannot delete file node for {}", file, ioe);
+                }
+            }
+        }
+    }
+
+    /**
+     * Import the XML file as JCR system or document view import. If the XML
+     * file is not a valid system or document view export/import file,
+     * <code>false</code> is returned.
+     * 
+     * @param parent The parent node below which to import
+     * @param nodeXML The URL to the XML file to import
+     * @return <code>true</code> if the import succeeds, <code>false</code>
+     *         if the import fails due to XML format errors.
+     * @throws IOException If an IO error occurrs reading the XML file.
+     */
+    private Node importSystemView(Node parent, String name, URL nodeXML)
+            throws IOException {
+
+        InputStream ins = null;
+        try {
+
+            // check whether we have the content already, nothing to do then
+            name = toPlainName(name);
+            if (parent.hasNode(name)) {
+                log.debug(
+                    "importSystemView: Node {} for XML {} already exists, nothing to to",
+                    name, nodeXML);
+                return parent.getNode(name);
+            }
+
+            ins = nodeXML.openStream();
+            Session session = parent.getSession();
+            session.importXML(parent.getPath(), ins, IMPORT_UUID_CREATE_NEW);
+
+            // additionally check whether the expected child node exists
+            return (parent.hasNode(name)) ? parent.getNode(name) : null;
+
+        } catch (InvalidSerializedDataException isde) {
+
+            // the xml might not be System or Document View export, fall back
+            // to old-style XML reading
+            log.info(
+                "importSystemView: XML {} does not seem to be system view export, trying old style",
+                nodeXML);
+            return null;
+
+        } catch (RepositoryException re) {
+
+            // any other repository related issue...
+            log.info(
+                "importSystemView: Repository issue loading XML {}, trying old style",
+                nodeXML);
+            return null;
+
+        } finally {
+            if (ins != null) {
+                try {
+                    ins.close();
+                } catch (IOException ignore) {
+                    // ignore
+                }
+            }
+        }
+
+    }
+
+    protected static final class Descriptor {
+        public URL rootNodeDescriptor;
+
+        public NodeReader nodeReader;
+    }
+
+    /**
+     * Return the root node descriptor.
+     */
+    private Descriptor getRootNodeDescriptor(final Bundle bundle,
+            final String path) {
+        URL rootNodeDescriptor = null;
+
+        for (Map.Entry<String, ImportProvider> e : importProviders.entrySet()) {
+            if (e.getValue() != null) {
+                rootNodeDescriptor = bundle.getEntry(path + ROOT_DESCRIPTOR
+                    + e.getKey());
+                if (rootNodeDescriptor != null) {
+                    try {
+                        final Descriptor d = new Descriptor();
+                        d.rootNodeDescriptor = rootNodeDescriptor;
+                        d.nodeReader = e.getValue().getReader();
+                        return d;
+                    } catch (IOException ioe) {
+                        log.error("Unable to setup node reader for "
+                            + e.getKey(), ioe);
+                        return null;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Imports mixin nodes and properties (and optionally child nodes) of the
+     * root node.
+     */
+    private URL importRootNode(Session session, Bundle bundle, String path,
+            List<Node> versionables, boolean checkin)
+            throws RepositoryException {
+        final Descriptor descriptor = getRootNodeDescriptor(bundle, path);
+        // no root descriptor found
+        if (descriptor == null) {
+            return null;
+        }
+
+        InputStream ins = null;
+        try {
+
+            ins = descriptor.rootNodeDescriptor.openStream();
+            NodeDescription clNode = descriptor.nodeReader.parse(ins);
+
+            setupNode(session.getRootNode(), clNode, versionables, checkin);
+
+            return descriptor.rootNodeDescriptor;
+        } catch (RepositoryException re) {
+            throw re;
+        } catch (Throwable t) {
+            throw new RepositoryException(t.getMessage(), t);
+        } finally {
+            if (ins != null) {
+                try {
+                    ins.close();
+                } catch (IOException ignore) {
+                }
+            }
+        }
+
+    }
+
+    private String toPlainName(String name) {
+        String providerExt = null;
+        final Iterator<String> ipIter = importProviders.keySet().iterator();
+        while (providerExt == null && ipIter.hasNext()) {
+            final String ext = ipIter.next();
+            if (name.endsWith(ext)) {
+                providerExt = ext;
+            }
+        }
+        if (providerExt != null) {
+            return name.substring(0, name.length() - providerExt.length());
+        }
+        return name;
+
+    }
+}
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/NodeDescription.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/NodeDescription.java
new file mode 100644
index 0000000..043da37
--- /dev/null
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/NodeDescription.java
@@ -0,0 +1,153 @@
+/*
+ * 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.contentloader.internal;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+class NodeDescription {
+
+    private String name;
+    private String primaryNodeType;
+    private Set<String> mixinNodeTypes;
+    private List<PropertyDescription> properties;
+    private List<NodeDescription> children;
+
+    /**
+     * @return the children
+     */
+    List<NodeDescription> getChildren() {
+        return children;
+    }
+
+    /**
+     * @param children the children to set
+     */
+    void addChild(NodeDescription child) {
+        if (child != null) {
+            if (children == null) {
+                children = new ArrayList<NodeDescription>();
+            }
+
+            children.add(child);
+        }
+    }
+
+    /**
+     * @return the mixinNodeTypes
+     */
+    Set<String> getMixinNodeTypes() {
+        return mixinNodeTypes;
+    }
+
+    /**
+     * @param mixinNodeTypes the mixinNodeTypes to set
+     */
+    void addMixinNodeType(String mixinNodeType) {
+        if (mixinNodeType != null && mixinNodeType.length() > 0) {
+            if (mixinNodeTypes == null) {
+                mixinNodeTypes = new HashSet<String>();
+            }
+
+            mixinNodeTypes.add(mixinNodeType);
+        }
+    }
+
+    /**
+     * @return the name
+     */
+    String getName() {
+        return name;
+    }
+
+    /**
+     * @param name the name to set
+     */
+    void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * @return the primaryNodeType
+     */
+    String getPrimaryNodeType() {
+        return primaryNodeType;
+    }
+
+    /**
+     * @param primaryNodeType the primaryNodeType to set
+     */
+    void setPrimaryNodeType(String primaryNodeType) {
+        this.primaryNodeType = primaryNodeType;
+    }
+
+    /**
+     * @return the properties
+     */
+    List<PropertyDescription> getProperties() {
+        return properties;
+    }
+
+    /**
+     * @param properties the properties to set
+     */
+    void addProperty(PropertyDescription property) {
+        if (property != null) {
+            if (properties == null) {
+                properties = new ArrayList<PropertyDescription>();
+            }
+
+            properties.add(property);
+        }
+    }
+
+    public int hashCode() {
+        int code = getName().hashCode() * 17;
+        if (getPrimaryNodeType() != null) {
+            code += getPrimaryNodeType().hashCode();
+        }
+        return code;
+    }
+
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        } else if (!(obj instanceof NodeDescription)) {
+            return false;
+        }
+
+        NodeDescription other = (NodeDescription) obj;
+        return getName().equals(other.getName())
+            && equals(getPrimaryNodeType(), other.getPrimaryNodeType())
+            && equals(getMixinNodeTypes(), other.getMixinNodeTypes())
+            && equals(getProperties(), other.getProperties())
+            && equals(getChildren(), other.getChildren());
+    }
+
+    public String toString() {
+        return "Node " + getName() + ", primary=" + getPrimaryNodeType()
+            + ", mixins=" + getMixinNodeTypes();
+    }
+
+    private boolean equals(Object o1, Object o2) {
+        return (o1 == null) ? o2 == null : o1.equals(o2);
+    }
+}
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/NodeReader.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/NodeReader.java
new file mode 100644
index 0000000..2653114
--- /dev/null
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/NodeReader.java
@@ -0,0 +1,31 @@
+/*
+ * 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.contentloader.internal;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * The <code>NodeReader</code> TODO
+ */
+interface NodeReader {
+
+    NodeDescription parse(InputStream ins) throws IOException;
+
+}
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/PathEntry.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/PathEntry.java
new file mode 100644
index 0000000..cfb8c24
--- /dev/null
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/PathEntry.java
@@ -0,0 +1,140 @@
+/*
+ * 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.contentloader.internal;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.sling.commons.osgi.ManifestHeader;
+import org.osgi.framework.Bundle;
+
+/**
+ * A path entry from the manifest for initial content.
+ */
+public class PathEntry {
+
+    /** The manifest header to specify initial content to be loaded. */
+    public static final String CONTENT_HEADER = "Sling-Initial-Content";
+
+    /**
+     * The overwrite directive specifying if content should be overwritten or
+     * just initially added.
+     */
+    public static final String OVERWRITE_DIRECTIVE = "overwrite";
+
+    /** The uninstall directive specifying if content should be uninstalled. */
+    public static final String UNINSTALL_DIRECTIVE = "uninstall";
+
+    /**
+     * The path directive specifying the target node where initial content will
+     * be loaded.
+     */
+    public static final String PATH_DIRECTIVE = "path";
+
+    /**
+     * The checkin directive specifying whether versionable nodes should be
+     * checked in
+     */
+    public static final String CHECKIN_DIRECTIVE = "checkin";
+
+    /** The path for the initial content. */
+    private final String path;
+
+    /** Should existing content be overwritten? */
+    private final boolean overwrite;
+
+    /** Should existing content be uninstalled? */
+    private final boolean uninstall;
+    
+    /** Should versionable nodes be checked in? */
+    private final boolean checkin;
+
+    /**
+     * Target path where initial content will be loaded. If it´s null then
+     * target node is the root node
+     */
+    private final String target;
+
+    public static Iterator<PathEntry> getContentPaths(final Bundle bundle) {
+        final List<PathEntry> entries = new ArrayList<PathEntry>();
+
+        final String root = (String) bundle.getHeaders().get(CONTENT_HEADER);
+        if (root != null) {
+            final ManifestHeader header = ManifestHeader.parse(root);
+            for (final ManifestHeader.Entry entry : header.getEntries()) {
+                entries.add(new PathEntry(entry));
+            }
+        }
+
+        if (entries.size() == 0) {
+            return null;
+        }
+        return entries.iterator();
+    }
+
+    public PathEntry(ManifestHeader.Entry entry) {
+        // check for directives
+        final String overwriteValue = entry.getDirectiveValue(OVERWRITE_DIRECTIVE);
+        final String uninstallValue = entry.getDirectiveValue(UNINSTALL_DIRECTIVE);
+        final String pathValue = entry.getDirectiveValue(PATH_DIRECTIVE);
+        final String checkinValue = entry.getDirectiveValue(CHECKIN_DIRECTIVE);
+        boolean overwriteFlag = false;
+        if (overwriteValue != null) {
+            overwriteFlag = Boolean.valueOf(overwriteValue);
+        }
+        this.path = entry.getValue();
+        this.overwrite = overwriteFlag;
+        if (uninstallValue != null) {
+            this.uninstall = Boolean.valueOf(uninstallValue);
+        } else {
+            this.uninstall = this.overwrite;
+        }
+        if (pathValue != null) {
+            this.target = pathValue;
+        } else {
+            this.target = null;
+        }
+        if (checkinValue != null) {
+            this.checkin = Boolean.valueOf(checkinValue);
+        } else {
+            this.checkin = false;
+        }
+    }
+
+    public String getPath() {
+        return this.path;
+    }
+
+    public boolean isOverwrite() {
+        return this.overwrite;
+    }
+
+    public boolean isUninstall() {
+        return this.uninstall;
+    }
+
+    public boolean isCheckin() {
+        return this.checkin;
+    }
+    
+    public String getTarget() {
+        return target;
+    }
+}
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/PropertyDescription.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/PropertyDescription.java
new file mode 100644
index 0000000..4fd7823
--- /dev/null
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/PropertyDescription.java
@@ -0,0 +1,119 @@
+/*
+ * 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.contentloader.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jcr.PropertyType;
+
+class PropertyDescription {
+    private String name;
+    private String value;
+    private List<String> values;
+    private String type = PropertyType.TYPENAME_STRING; // default type to string
+
+    /**
+     * @return the name
+     */
+    String getName() {
+        return this.name;
+    }
+
+    /**
+     * @param name the name to set
+     */
+    void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * @return the type
+     */
+    String getType() {
+        return this.type;
+    }
+
+    /**
+     * @param type the type to set
+     */
+    void setType(String type) {
+        this.type = type;
+    }
+
+    /**
+     * @return the value
+     */
+    String getValue() {
+        return this.value;
+    }
+
+    /**
+     * @param value the value to set
+     */
+    void setValue(String value) {
+        this.value = value;
+    }
+
+    /**
+     * @return the values
+     */
+    List<String> getValues() {
+        return this.values;
+    }
+
+    /**
+     * @param values the values to set
+     */
+    void addValue(Object value) {
+        if (this.values == null) {
+            this.values = new ArrayList<String>();
+        }
+
+        if (value != null) {
+            this.values.add(value.toString());
+        }
+    }
+
+    boolean isMultiValue() {
+        return this.values != null;
+    }
+
+    public int hashCode() {
+        return this.getName().hashCode() * 17 + this.getType().hashCode();
+    }
+
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        } else if (!(obj instanceof PropertyDescription)) {
+            return false;
+        }
+
+        PropertyDescription other = (PropertyDescription) obj;
+        return this.getName().equals(other.getName())
+            && this.getType().equals(other.getType())
+            && this.equals(this.getValues(), other.getValues())
+            && this.equals(this.getValue(), other.getValue());
+    }
+
+    private boolean equals(Object o1, Object o2) {
+        return (o1 == null) ? o2 == null : o1.equals(o2);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/XmlReader.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/XmlReader.java
new file mode 100644
index 0000000..a96155e
--- /dev/null
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/XmlReader.java
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.jcr.contentloader.internal;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.LinkedList;
+
+import org.kxml2.io.KXmlParser;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+public class XmlReader implements NodeReader {
+
+    /*
+     * <node> <primaryNodeType>type</primaryNodeType> <mixinNodeTypes>
+     * <mixinNodeType>mixtype1</mixinNodeType> <mixinNodeType>mixtype2</mixinNodeType>
+     * </mixinNodeTypes> <properties> <property> <name>propName</name>
+     * <value>propValue</value> <type>propType</type> </property> <!-- more
+     * --> </properties> </node>
+     */
+
+    private static final String ELEM_NODE = "node";
+
+    private static final String ELEM_PRIMARY_NODE_TYPE = "primaryNodeType";
+
+    private static final String ELEM_MIXIN_NODE_TYPE = "mixinNodeType";
+
+    private static final String ELEM_PROPERTY = "property";
+
+    private static final String ELEM_NAME = "name";
+
+    private static final String ELEM_VALUE = "value";
+
+    private static final String ELEM_VALUES = "values";
+
+    private static final String ELEM_TYPE = "type";
+
+    static final ImportProvider PROVIDER = new ImportProvider() {
+        private XmlReader xmlReader;
+
+        public NodeReader getReader() throws IOException {
+            if (xmlReader == null) {
+                try {
+                    xmlReader = new XmlReader();
+                } catch (Throwable t) {
+                    throw (IOException) new IOException(t.getMessage()).initCause(t);
+                }
+            }
+            return xmlReader;
+        }
+    };
+
+    private KXmlParser xmlParser;
+
+    XmlReader() {
+        this.xmlParser = new KXmlParser();
+    }
+
+    // ---------- XML content access -------------------------------------------
+
+    public synchronized NodeDescription parse(InputStream ins) throws IOException {
+        try {
+            return this.parseInternal(ins);
+        } catch (XmlPullParserException xppe) {
+            throw (IOException) new IOException(xppe.getMessage()).initCause(xppe);
+        }
+    }
+
+    private NodeDescription parseInternal(InputStream ins) throws IOException,
+            XmlPullParserException {
+        String currentElement = "<root>";
+        LinkedList<String> elements = new LinkedList<String>();
+        NodeDescription currentNode = null;
+        LinkedList<NodeDescription> nodes = new LinkedList<NodeDescription>();
+        StringBuffer contentBuffer = new StringBuffer();
+        PropertyDescription currentProperty = null;
+
+        // set the parser input, use null encoding to force detection with
+        // <?xml?>
+        this.xmlParser.setInput(ins, null);
+
+        int eventType = this.xmlParser.getEventType();
+        while (eventType != XmlPullParser.END_DOCUMENT) {
+            if (eventType == XmlPullParser.START_TAG) {
+
+                elements.add(currentElement);
+                currentElement = this.xmlParser.getName();
+
+                if (ELEM_PROPERTY.equals(currentElement)) {
+                    currentProperty = new PropertyDescription();
+                } else if (ELEM_NODE.equals(currentElement)) {
+                    if (currentNode != null) nodes.add(currentNode);
+                    currentNode = new NodeDescription();
+                }
+
+            } else if (eventType == XmlPullParser.END_TAG) {
+
+                String qName = this.xmlParser.getName();
+                String content = contentBuffer.toString().trim();
+                contentBuffer.delete(0, contentBuffer.length());
+
+                if (ELEM_PROPERTY.equals(qName)) {
+                    currentNode.addProperty(currentProperty);
+                    currentProperty = null;
+
+                } else if (ELEM_NAME.equals(qName)) {
+                    if (currentProperty != null) {
+                        currentProperty.setName(content);
+                    } else if (currentNode != null) {
+                        currentNode.setName(content);
+                    }
+
+                } else if (ELEM_VALUE.equals(qName)) {
+                    if (currentProperty.isMultiValue()) {
+                        currentProperty.addValue(content);
+                    } else {
+                        currentProperty.setValue(content);
+                    }
+
+                } else if (ELEM_VALUES.equals(qName)) {
+                    currentProperty.addValue(null);
+                    currentProperty.setValue(null);
+
+                } else if (ELEM_TYPE.equals(qName)) {
+                    currentProperty.setType(content);
+
+                } else if (ELEM_NODE.equals(qName)) {
+                    if (!nodes.isEmpty()) {
+                        NodeDescription parent = nodes.removeLast();
+                        parent.addChild(currentNode);
+                        currentNode = parent;
+                    }
+
+                } else if (ELEM_PRIMARY_NODE_TYPE.equals(qName)) {
+                    currentNode.setPrimaryNodeType(content);
+
+                } else if (ELEM_MIXIN_NODE_TYPE.equals(qName)) {
+                    currentNode.addMixinNodeType(content);
+                }
+
+                currentElement = elements.removeLast();
+
+            } else if (eventType == XmlPullParser.TEXT) {
+                contentBuffer.append(this.xmlParser.getText());
+            }
+
+            eventType = this.xmlParser.next();
+        }
+
+        return currentNode;
+    }
+}
diff --git a/src/main/resources/META-INF/DISCLAIMER b/src/main/resources/META-INF/DISCLAIMER
new file mode 100644
index 0000000..90850c2
--- /dev/null
+++ b/src/main/resources/META-INF/DISCLAIMER
@@ -0,0 +1,7 @@
+Apache Sling is an effort undergoing incubation at The Apache Software Foundation (ASF),
+sponsored by the Apache Jackrabbit PMC. Incubation is required of all newly accepted
+projects until a further review indicates that the infrastructure, communications,
+and decision making process have stabilized in a manner consistent with other
+successful ASF projects. While incubation status is not necessarily a reflection of
+the completeness or stability of the code, it does indicate that the project has yet
+to be fully endorsed by the ASF.
\ No newline at end of file
diff --git a/src/main/resources/META-INF/LICENSE b/src/main/resources/META-INF/LICENSE
new file mode 100644
index 0000000..1a45730
--- /dev/null
+++ b/src/main/resources/META-INF/LICENSE
@@ -0,0 +1,232 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
+
+
+APACHE SLING SUBCOMPONENTS:
+
+Apache Sling includes subcomponents with separate copyright notices and
+license terms. Your use of these subcomponents is subject to the terms
+and conditions of the following licenses.
+
+kXML parser
+
+   Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   "Software"), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to permit
+   persons to whom the Software is furnished to do so, subject to the
+   following conditions:
+
+   The above copyright notice and this permission notice shall be included in
+   all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+   IN THE SOFTWARE. 
diff --git a/src/main/resources/META-INF/NOTICE b/src/main/resources/META-INF/NOTICE
new file mode 100644
index 0000000..fdc2970
--- /dev/null
+++ b/src/main/resources/META-INF/NOTICE
@@ -0,0 +1,11 @@
+Apache Sling Initial Content Loader
+Copyright 2008 The Apache Software Foundation
+
+Apache Sling is based on source code originally developed 
+by Day Software (http://www.day.com/).
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+This product includes software from http://kxml.sourceforge.net.
+Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany.
diff --git a/src/main/test/org/apache/sling/jcr/contentloader/internal/JsonReaderTest.java b/src/main/test/org/apache/sling/jcr/contentloader/internal/JsonReaderTest.java
new file mode 100644
index 0000000..a975d3e
--- /dev/null
+++ b/src/main/test/org/apache/sling/jcr/contentloader/internal/JsonReaderTest.java
@@ -0,0 +1,374 @@
+/*
+ * 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.contentloader.internal;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.jcr.PropertyType;
+
+import junit.framework.TestCase;
+
+import org.apache.sling.commons.json.JSONArray;
+import org.apache.sling.commons.json.JSONException;
+import org.apache.sling.commons.json.JSONObject;
+import org.apache.sling.jcr.contentloader.internal.JsonReader;
+import org.apache.sling.jcr.contentloader.internal.NodeDescription;
+import org.apache.sling.jcr.contentloader.internal.PropertyDescription;
+
+public class JsonReaderTest extends TestCase {
+
+    JsonReader jsonReader;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        this.jsonReader = new JsonReader();
+    }
+
+    protected void tearDown() throws Exception {
+        this.jsonReader = null;
+        super.tearDown();
+    }
+
+    public void testEmptyObject() {
+        try {
+            this.parse("");
+        } catch (IOException ioe) {
+            fail("Expected IOException from empty JSON");
+        }
+    }
+
+    public void testEmpty() throws IOException {
+        NodeDescription node = this.parse("{}");
+        assertNotNull("Expecting node", node);
+        assertNull("No name expected", node.getName());
+    }
+
+    public void testDefaultPrimaryNodeType() throws IOException {
+        String json = "{}";
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertNull(node.getPrimaryNodeType());
+        assertNull("No mixins expected", node.getMixinNodeTypes());
+        assertNull("No properties expected", node.getProperties());
+        assertNull("No children expected", node.getChildren());
+    }
+
+    public void testDefaultPrimaryNodeTypeWithSurroundWhitespace() throws IOException {
+        String json = "     {  }     ";
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertNull(node.getPrimaryNodeType());
+        assertNull("No mixins expected", node.getMixinNodeTypes());
+        assertNull("No properties expected", node.getProperties());
+        assertNull("No children expected", node.getChildren());
+    }
+
+    public void testDefaultPrimaryNodeTypeWithoutEnclosingBraces() throws IOException {
+        String json = "";
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertNull(node.getPrimaryNodeType());
+        assertNull("No mixins expected", node.getMixinNodeTypes());
+        assertNull("No properties expected", node.getProperties());
+        assertNull("No children expected", node.getChildren());
+    }
+
+    public void testDefaultPrimaryNodeTypeWithoutEnclosingBracesWithSurroundWhitespace() throws IOException {
+        String json = "             ";
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertNull(node.getPrimaryNodeType());
+        assertNull("No mixins expected", node.getMixinNodeTypes());
+        assertNull("No properties expected", node.getProperties());
+        assertNull("No children expected", node.getChildren());
+    }
+
+    public void testExplicitePrimaryNodeType() throws IOException {
+        String type = "xyz:testType";
+        String json = "{ \"jcr:primaryType\": \"" + type + "\" }";
+
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertEquals(type, node.getPrimaryNodeType());
+    }
+
+    public void testMixinNodeTypes1() throws JSONException, IOException {
+        Set<Object> mixins = this.toSet(new Object[]{ "xyz:mix1" });
+        String json = "{ \"jcr:mixinTypes\": " + this.toJsonArray(mixins) + "}";
+
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertEquals(mixins, node.getMixinNodeTypes());
+    }
+
+    public void testMixinNodeTypes2() throws JSONException, IOException {
+        Set<Object> mixins = this.toSet(new Object[]{ "xyz:mix1", "abc:mix2" });
+        String json = "{ \"jcr:mixinTypes\": " + this.toJsonArray(mixins) + "}";
+
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertEquals(mixins, node.getMixinNodeTypes());
+    }
+
+    public void testPropertiesNone() throws IOException, JSONException {
+        List<PropertyDescription> properties = null;
+        String json = "{ \"properties\": " + this.toJsonObject(properties) + "}";
+
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertEquals(properties, node.getProperties());
+    }
+
+    public void testPropertiesSingleValue() throws IOException, JSONException {
+        List<PropertyDescription> properties = new ArrayList<PropertyDescription>();
+        PropertyDescription prop = new PropertyDescription();
+        prop.setName("p1");
+        prop.setValue("v1");
+        properties.add(prop);
+        
+        String json = this.toJsonObject(properties).toString();
+        
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertEquals(new HashSet<PropertyDescription>(properties), new HashSet<PropertyDescription>(node.getProperties()));
+    }
+    
+    public void testPropertiesTwoSingleValue() throws IOException, JSONException {
+        List<PropertyDescription> properties = new ArrayList<PropertyDescription>();
+        PropertyDescription prop = new PropertyDescription();
+        prop.setName("p1");
+        prop.setValue("v1");
+        properties.add(prop);
+        prop = new PropertyDescription();
+        prop.setName("p2");
+        prop.setValue("v2");
+        properties.add(prop);
+
+        String json = this.toJsonObject(properties).toString();
+
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertEquals(new HashSet<PropertyDescription>(properties), new HashSet<PropertyDescription>(node.getProperties()));
+    }
+
+    public void testPropertiesMultiValue() throws IOException, JSONException {
+        List<PropertyDescription> properties = new ArrayList<PropertyDescription>();
+        PropertyDescription prop = new PropertyDescription();
+        prop.setName("p1");
+        prop.addValue("v1");
+        properties.add(prop);
+
+        String json = this.toJsonObject(properties).toString();
+
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertEquals(new HashSet<PropertyDescription>(properties), new HashSet<PropertyDescription>(node.getProperties()));
+    }
+
+    public void testPropertiesMultiValueEmpty() throws IOException, JSONException {
+        List<PropertyDescription> properties = new ArrayList<PropertyDescription>();
+        PropertyDescription prop = new PropertyDescription();
+        prop.setName("p1");
+        prop.addValue(null); // empty multivalue property
+        properties.add(prop);
+
+        String json = this.toJsonObject(properties).toString();
+
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertEquals(new HashSet<PropertyDescription>(properties), new HashSet<PropertyDescription>(node.getProperties()));
+    }
+
+    public void testChildrenNone() throws IOException, JSONException {
+        List<NodeDescription> nodes = null;
+        String json = this.toJsonObject(nodes).toString();
+
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertEquals(nodes, node.getChildren());
+    }
+
+    public void testChild() throws IOException, JSONException {
+        List<NodeDescription> nodes = new ArrayList<NodeDescription>();
+        NodeDescription child = new NodeDescription();
+        child.setName("p1");
+        nodes.add(child);
+
+        String json = this.toJsonObject(nodes).toString();
+
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertEquals(nodes, node.getChildren());
+    }
+
+    public void testChildWithMixin() throws IOException, JSONException {
+        List<NodeDescription> nodes = new ArrayList<NodeDescription>();
+        NodeDescription child = new NodeDescription();
+        child.setName("p1");
+        child.addMixinNodeType("p1:mix");
+        nodes.add(child);
+
+        String json = this.toJsonObject(nodes).toString();
+
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertEquals(nodes, node.getChildren());
+    }
+
+    public void testTwoChildren() throws IOException, JSONException {
+        List<NodeDescription> nodes = new ArrayList<NodeDescription>();
+        NodeDescription child = new NodeDescription();
+        child.setName("p1");
+        nodes.add(child);
+        child = new NodeDescription();
+        child.setName("p2");
+        nodes.add(child);
+
+        String json = this.toJsonObject(nodes).toString();
+
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertEquals(nodes, node.getChildren());
+    }
+
+    public void testChildWithProperty() throws IOException, JSONException {
+        List<NodeDescription> nodes = new ArrayList<NodeDescription>();
+        NodeDescription child = new NodeDescription();
+        child.setName("c1");
+        PropertyDescription prop = new PropertyDescription();
+        prop.setName("c1p1");
+        prop.setValue("c1v1");
+        child.addProperty(prop);
+        nodes.add(child);
+
+        String json = this.toJsonObject(nodes).toString();
+
+        NodeDescription node = this.parse(json);
+        assertNotNull("Expecting node", node);
+        assertEquals(nodes, node.getChildren());
+    }
+
+    //---------- internal helper ----------------------------------------------
+
+    private NodeDescription parse(String json) throws IOException {
+        String charSet = "ISO-8859-1";
+        json = "#" + charSet + "\r\n" + json;
+        InputStream ins = new ByteArrayInputStream(json.getBytes(charSet));
+        return this.jsonReader.parse(ins);
+    }
+
+    private Set<Object> toSet(Object[] content) {
+        Set<Object> set = new HashSet<Object>();
+        for (int i=0; content != null && i < content.length; i++) {
+            set.add(content[i]);
+        }
+
+        return set;
+    }
+
+    private JSONArray toJsonArray(Collection<?> set) throws JSONException {
+        List<Object> list = new ArrayList<Object>();
+        for (Object item : set) {
+            if (item instanceof NodeDescription) {
+                list.add(this.toJsonObject((NodeDescription) item));
+            } else {
+                list.add(item);
+            }
+        }
+        return new JSONArray(list);
+    }
+
+    private JSONObject toJsonObject(Collection<?> set) throws JSONException {
+        JSONObject obj = new JSONObject();
+        if (set != null) {
+            for (Object next: set) {
+                String name = this.getName(next);
+                obj.putOpt(name, this.toJsonObject(next));
+            }
+        }
+        return obj;
+    }
+
+    private Object toJsonObject(Object object) throws JSONException {
+        if (object instanceof NodeDescription) {
+            return this.toJsonObject((NodeDescription) object);
+        } else if (object instanceof PropertyDescription) {
+            return this.toJsonObject((PropertyDescription) object);
+        }
+
+        // fall back to string representation
+        return String.valueOf(object);
+    }
+
+    private JSONObject toJsonObject(NodeDescription node) throws JSONException {
+        JSONObject obj = new JSONObject();
+
+        if (node.getPrimaryNodeType() != null) {
+            obj.putOpt("jcr:primaryType", node.getPrimaryNodeType());
+        }
+
+        if (node.getMixinNodeTypes() != null) {
+            obj.putOpt("jcr:mixinTypes", this.toJsonArray(node.getMixinNodeTypes()));
+        }
+
+        if (node.getProperties() != null) {
+            for (PropertyDescription prop : node.getProperties()) {
+                obj.put(prop.getName(), toJsonObject(prop));
+            }
+        }
+
+        if (node.getChildren() != null) {
+            for (NodeDescription child : node.getChildren()) {
+                obj.put(child.getName(), toJsonObject(child));
+            }
+        }
+
+        return obj;
+    }
+
+    private Object toJsonObject(PropertyDescription property) throws JSONException {
+        if (!property.isMultiValue() && PropertyType.TYPENAME_STRING.equals(property.getType())) {
+            return this.toJsonObject(property.getValue());
+        }
+        Object obj;
+        if (property.isMultiValue()) {
+            obj = this.toJsonArray(property.getValues());
+        } else {
+            obj = this.toJsonObject(property.getValue());
+        }
+
+        return obj;
+    }
+
+    private String getName(Object object) {
+        if (object instanceof NodeDescription) {
+            return ((NodeDescription) object).getName();
+        } else if (object instanceof PropertyDescription) {
+            return ((PropertyDescription) object).getName();
+        }
+
+        // fall back to string representation
+        return String.valueOf(object);
+    }
+}

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-jcr-contentloader] 13/32: Add explicit dependency to JUnit library

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit 7a2d4b1e4a4579bcc8059d1ba3d3177439ebbf3b
Author: Felix Meschberger <fm...@apache.org>
AuthorDate: Tue May 27 08:58:45 2008 +0000

    Add explicit dependency to JUnit library
    
    git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader@660434 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/pom.xml b/pom.xml
index 7d0dd59..72cfce5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -116,5 +116,10 @@
             <artifactId>kxml2</artifactId>
             <scope>provided</scope>
         </dependency>
+        
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
     </dependencies>
 </project>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-jcr-contentloader] 32/32: Move Sling to new TLP location

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit 74ed6faf4f5ff7887c6d445edf147cfe6600eb7d
Merge: 769b49c d21d415
Author: Felix Meschberger <fm...@apache.org>
AuthorDate: Thu Jun 18 09:21:02 2009 +0000

    Move Sling to new TLP location
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/tags/org.apache.sling.jcr.contentloader-2.0.2-incubator@785979 13f79535-47bb-0310-9956-ffa450edef68


-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-jcr-contentloader] 15/32: SLING-483: Add excludes for javadocs (WiP)

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit 66b18601da9e96e0e613a7dab57d1a84b9880eb1
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Fri May 30 09:21:49 2008 +0000

    SLING-483: Add excludes for javadocs (WiP)
    
    git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader@661611 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/pom.xml b/pom.xml
index 72cfce5..7a6ebf7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -73,6 +73,19 @@
             </plugin>
         </plugins>
     </build>
+    <reporting>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <configuration>
+                    <excludePackageNames>
+                        org.apache.sling.jcr.contentloader.internal
+                    </excludePackageNames>
+                </configuration>
+            </plugin>
+        </plugins>
+    </reporting>
     <dependencies>
         <dependency>
             <groupId>org.apache.felix</groupId>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-jcr-contentloader] 01/32: Start new module for content loading.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit 089d630c5a8b44c2d9624fb4ee4806705ce04141
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Apr 30 06:29:30 2008 +0000

    Start new module for content loading.
    
    git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader@652299 13f79535-47bb-0310-9956-ffa450edef68
---
 DISCLAIMER    |   7 ++
 LICENSE       | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 LICENSE.kxml2 |  19 ++++++
 NOTICE        |  12 ++++
 pom.xml       | 110 ++++++++++++++++++++++++++++++++
 5 files changed, 350 insertions(+)

diff --git a/DISCLAIMER b/DISCLAIMER
new file mode 100644
index 0000000..90850c2
--- /dev/null
+++ b/DISCLAIMER
@@ -0,0 +1,7 @@
+Apache Sling is an effort undergoing incubation at The Apache Software Foundation (ASF),
+sponsored by the Apache Jackrabbit PMC. Incubation is required of all newly accepted
+projects until a further review indicates that the infrastructure, communications,
+and decision making process have stabilized in a manner consistent with other
+successful ASF projects. While incubation status is not necessarily a reflection of
+the completeness or stability of the code, it does indicate that the project has yet
+to be fully endorsed by the ASF.
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/LICENSE.kxml2 b/LICENSE.kxml2
new file mode 100644
index 0000000..1fe595b
--- /dev/null
+++ b/LICENSE.kxml2
@@ -0,0 +1,19 @@
+Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The  above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE. 
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..627ed1f
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,12 @@
+Apache Sling Initial Content Loader
+Copyright 2007-2008 The Apache Software Foundation
+
+Based on source code originally developed by
+Day Software (http://www.day.com/).
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+Licensed under the Apache License 2.0.
+
+This product includes software from http://kxml.sourceforge.net.
+Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany.
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..ef1f7e7
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,110 @@
+<?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>1-incubator-SNAPSHOT</version>
+        <relativePath>../../parent/pom.xml</relativePath>
+    </parent>
+
+    <artifactId>org.apache.sling.jcr.contentloader</artifactId>
+    <version>2.0.0-incubator-SNAPSHOT</version>
+    <packaging>bundle</packaging>
+
+    <name>Sling - Initial Content Loader</name>
+    <description>
+        This bundle provides initial content installation through bundles.
+    </description>
+
+    <scm>
+        <connection>
+            scm:svn:http://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader
+        </connection>
+        <developerConnection>
+            scm:svn:https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader
+        </developerConnection>
+        <url>
+            http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/contentloader
+        </url>
+    </scm>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-scr-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Private-Package>
+                            org.apache.sling.jcr.resource.internal.*,
+                            org.kxml2.io, org.xmlpull.v1
+                        </Private-Package>
+
+                        <Embed-Dependency>
+                            kxml2
+                        </Embed-Dependency>
+
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.osgi.core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.api</artifactId>
+            <version>2.0.0-incubator-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.mime</artifactId>
+            <version>2.0.0-incubator-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>net.sf.kxml</groupId>
+            <artifactId>kxml2</artifactId>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+</project>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-jcr-contentloader] 10/32: #SLING-414: Move generation and managing of the sling id to own service in the engine.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.jcr.contentloader-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentloader.git

commit 1a9cb5369399785d1108930b9dabedabb925b9d6
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Fri May 16 10:17:37 2008 +0000

    #SLING-414: Move generation and managing of the sling id to own service in the engine.
    
    git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk/jcr/contentloader@657002 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                                            | 5 +++++
 .../sling/jcr/contentloader/internal/ContentLoaderService.java     | 7 ++++++-
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index 21cc719..7d0dd59 100644
--- a/pom.xml
+++ b/pom.xml
@@ -103,6 +103,11 @@
             <version>2.0.0-incubator-SNAPSHOT</version>
         </dependency>
         <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.engine</artifactId>
+            <version>2.0.0-incubator-SNAPSHOT</version>
+        </dependency>
+        <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
         </dependency>
diff --git a/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java b/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java
index b3c05c6..af3c267 100644
--- a/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java
+++ b/src/main/java/org/apache/sling/jcr/contentloader/internal/ContentLoaderService.java
@@ -31,6 +31,7 @@ import javax.jcr.Session;
 import javax.jcr.lock.LockException;
 
 import org.apache.sling.commons.mime.MimeTypeService;
+import org.apache.sling.engine.SlingSettingsService;
 import org.apache.sling.jcr.api.SlingRepository;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleEvent;
@@ -97,6 +98,10 @@ public class ContentLoaderService implements SynchronousBundleListener {
      */
     private final Set<String> updatedBundles = new HashSet<String>();
 
+    /** @scr.reference
+     *  Sling settings service. */
+    protected SlingSettingsService settingsService;
+
     // ---------- BundleListener -----------------------------------------------
 
     /**
@@ -188,7 +193,7 @@ public class ContentLoaderService implements SynchronousBundleListener {
 
     /** Activates this component, called by SCR before registering as a service */
     protected void activate(ComponentContext componentContext) {
-        this.slingId = componentContext.getBundleContext().getProperty("sling.id");
+        this.slingId = this.settingsService.getSlingId();
         this.initialContentLoader = new Loader(this);
 
         componentContext.getBundleContext().addBundleListener(this);

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.