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/10/20 14:41:11 UTC

[sling-org-apache-sling-jcr-contentparser] 12/38: SLING-6828 JCR Content Parser: Support XML Descriptor Files

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

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-contentparser.git

commit fd436431d5e9422d71e24081621cd0039bdb38a3
Author: Stefan Seifert <ss...@apache.org>
AuthorDate: Thu May 4 13:30:10 2017 +0000

    SLING-6828 JCR Content Parser: Support XML Descriptor Files
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1793800 13f79535-47bb-0310-9956-ffa450edef68
---
 .../jcr/contentparser/ContentParserFactory.java    |   3 +
 .../sling/jcr/contentparser/ContentType.java       |   6 +
 .../jcr/contentparser/impl/XmlContentParser.java   | 228 +++++++++++++++
 .../sling/jcr/contentparser/package-info.java      |   2 +-
 .../contentparser/impl/XmlContentParserTest.java   | 171 +++++++++++
 src/test/resources/content-test/content.xml        | 316 +++++++++++++++++++++
 6 files changed, 725 insertions(+), 1 deletion(-)

diff --git a/src/main/java/org/apache/sling/jcr/contentparser/ContentParserFactory.java b/src/main/java/org/apache/sling/jcr/contentparser/ContentParserFactory.java
index 33ca999..8894de6 100644
--- a/src/main/java/org/apache/sling/jcr/contentparser/ContentParserFactory.java
+++ b/src/main/java/org/apache/sling/jcr/contentparser/ContentParserFactory.java
@@ -20,6 +20,7 @@ package org.apache.sling.jcr.contentparser;
 
 import org.apache.sling.jcr.contentparser.impl.JcrXmlContentParser;
 import org.apache.sling.jcr.contentparser.impl.JsonContentParser;
+import org.apache.sling.jcr.contentparser.impl.XmlContentParser;
 import org.osgi.annotation.versioning.ProviderType;
 
 /**
@@ -51,6 +52,8 @@ public final class ContentParserFactory {
         switch (type) {
             case JSON:
                 return new JsonContentParser(options);
+            case XML:
+                return new XmlContentParser(options);
             case JCR_XML:
                 return new JcrXmlContentParser(options);
             default:
diff --git a/src/main/java/org/apache/sling/jcr/contentparser/ContentType.java b/src/main/java/org/apache/sling/jcr/contentparser/ContentType.java
index 21d7e14..a4d99c5 100644
--- a/src/main/java/org/apache/sling/jcr/contentparser/ContentType.java
+++ b/src/main/java/org/apache/sling/jcr/contentparser/ContentType.java
@@ -33,6 +33,12 @@ public enum ContentType {
     JSON("json"),
 
     /**
+     * XML content descriptor file.
+     * @see https://sling.apache.org/documentation/bundles/content-loading-jcr-contentloader.html#xml-descriptor-files
+     */
+    XML("xml"),
+
+    /**
      * JCR XML content (FileVault XML). Also known as extended document view XML.
      * Extends the regular document view as specified by JCR 2.0 by specifics like
      * multivalue and typing information. Is used by Jackrabbit FileVault.
diff --git a/src/main/java/org/apache/sling/jcr/contentparser/impl/XmlContentParser.java b/src/main/java/org/apache/sling/jcr/contentparser/impl/XmlContentParser.java
new file mode 100644
index 0000000..4685a8c
--- /dev/null
+++ b/src/main/java/org/apache/sling/jcr/contentparser/impl/XmlContentParser.java
@@ -0,0 +1,228 @@
+/*
+ * 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.contentparser.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.PropertyType;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.sling.jcr.contentparser.ContentHandler;
+import org.apache.sling.jcr.contentparser.ContentParser;
+import org.apache.sling.jcr.contentparser.ParseException;
+import org.apache.sling.jcr.contentparser.ParserOptions;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+/**
+ * Parses XML files that contains content fragments.
+ * Instance of this class is thread-safe.
+ */
+public final class XmlContentParser implements ContentParser {
+    
+    private final ParserHelper helper;    
+    private final DocumentBuilderFactory documentBuilderFactory;
+    
+    public XmlContentParser(ParserOptions options) {
+        this.helper = new ParserHelper(options);
+        documentBuilderFactory = DocumentBuilderFactory.newInstance();
+    }
+    
+    @Override
+    public void parse(ContentHandler handler, InputStream is) throws IOException, ParseException {
+        try {
+            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
+            Document doc = documentBuilder.parse(is);
+            parse(handler, doc.getDocumentElement(), null);
+        }
+        catch (ParserConfigurationException | SAXException ex) {
+            throw new ParseException("Error parsing JCR XML content.", ex);
+        }
+    }
+    
+    private void parse(ContentHandler handler, Element element, String parentPath) {
+        
+        // build node path
+        String path;
+        if (parentPath == null) {
+            path = "/";
+        }
+        else {
+            String name = getChildText(element, "name");
+            if (StringUtils.isEmpty(name)) {
+                throw new ParseException("Child node without name detected below path " + parentPath);
+            }
+            path = helper.concatenatePath(parentPath, name);
+            if (helper.ignoreResource(name)) {
+                return;
+            }
+        }
+
+        Map<String,Object> properties = new HashMap<>();
+        
+        // primary node type and mixins
+        String primaryType = getChildText(element, "primaryNodeType");
+        if (StringUtils.isNotBlank(primaryType) && !helper.ignoreProperty("jcr:primaryType")) {
+            properties.put("jcr:primaryType", primaryType);
+        }
+        String[] mixins = getChildTextArray(element, "mixinNodeType");
+        if (mixins.length > 0 && !helper.ignoreProperty("jcr:mixinTypes")) {
+            properties.put("jcr:mixinTypes", mixins);
+        }
+        
+        // properties
+        List<Element> propertyElements = getChildren(element, "property");
+        for (Element propertyElement : propertyElements) {
+            
+            // property name
+            String name = getChildText(propertyElement, "name");
+            if (StringUtils.isBlank(name)) {
+                throw new ParseException("Property without name detected at path " + path);
+            }
+            if (helper.ignoreProperty(name)) {
+                continue;
+            }
+            
+            // property type
+            String typeString = getChildText(propertyElement, "type");
+            if (StringUtils.isBlank(typeString)) {
+                throw new ParseException("Property '" + name + "' has no type at path " + path);
+            }
+            int type;
+            try {
+                type = PropertyType.valueFromName(typeString);
+            }
+            catch (IllegalArgumentException ex) {
+                throw new ParseException("Property '" + name + "' has illegal type '" + typeString + "' at path " + path);
+            }
+            
+            // property value
+            Object value;
+            List<Element> valuesElements = getChildren(propertyElement, "values");
+            if (!valuesElements.isEmpty()) {
+                Element valuesElement = valuesElements.get(0);
+                List<Element> valueElements = getChildren(valuesElement, "value");
+                String[] stringValues = new String[valueElements.size()];
+                for (int i=0; i<valueElements.size(); i++) {
+                    stringValues[i] = valueElements.get(i).getTextContent();
+                }
+                value = convertMultiValue(stringValues, type);
+            }
+            else {
+                String stringValue = getChildText(propertyElement, "value");
+                value = convertValue(stringValue, type);
+            }
+            properties.put(name, value);
+        }
+        
+        // report current JSON object
+        helper.ensureDefaultPrimaryType(properties);
+        handler.resource(path, properties);
+        
+        // child nodes
+        List<Element> nodeElements = getChildren(element, "node");
+        for (Element node : nodeElements) {
+            parse(handler, node, path);
+        }
+        
+    }
+    
+    private List<Element> getChildren(Element element, String childName) {
+        List<Element> result = new ArrayList<>();
+        NodeList children = element.getChildNodes();
+        int len = children.getLength();
+        for (int i=0; i<len; i++) {
+            Node child = children.item(i);
+            if (child instanceof Element) {
+                Element childElement = (Element)child;
+                if (StringUtils.equals(childElement.getNodeName(), childName)) {
+                    result.add(childElement);
+                }
+            }
+        }
+        return result;
+    }
+    
+    private String getChildText(Element element, String childName) {
+        List<Element> children = getChildren(element, childName);
+        if (children.isEmpty()) {
+            return null;
+        }
+        else if (children.size() == 1) {
+            return children.get(0).getTextContent();
+        }
+        else {
+            throw new ParseException("Found multiple elements with name '" + childName + "': " + children.size());
+        }
+    }
+    
+    private String[] getChildTextArray(Element element, String childName) {
+        List<Element> children = getChildren(element, childName);
+        String[] result = new String[children.size()];
+        for (int i=0; i<children.size(); i++) {
+            result[i] = children.get(i).getTextContent();
+        }
+        return result;
+    }
+    
+    private Object convertValue(String value, int type) {
+        switch (type) {
+            case PropertyType.STRING:
+            case PropertyType.NAME:
+            case PropertyType.PATH:
+            case PropertyType.REFERENCE:
+            case PropertyType.WEAKREFERENCE:
+            case PropertyType.URI:
+                return value;
+            case PropertyType.LONG:
+                return Long.valueOf(value);
+            case PropertyType.DOUBLE:
+                return Double.valueOf(value);
+            case PropertyType.DATE:
+                return helper.tryParseCalendar(value);
+            case PropertyType.BOOLEAN:
+                return Boolean.valueOf(value);
+            case PropertyType.DECIMAL:
+                return new BigDecimal(value);
+            default:
+                throw new ParseException("Unsupported property type: " + PropertyType.nameFromValue(type));
+        }
+    }
+
+    private Object convertMultiValue(String[] values, int type) {
+        Object[] result = new Object[values.length];
+        for (int i=0; i<values.length; i++) {
+            result[i] = convertValue(values[i], type);
+        }
+        return helper.convertSingleTypeArray(result);
+    }
+    
+}
diff --git a/src/main/java/org/apache/sling/jcr/contentparser/package-info.java b/src/main/java/org/apache/sling/jcr/contentparser/package-info.java
index 1b6b2a8..771f212 100644
--- a/src/main/java/org/apache/sling/jcr/contentparser/package-info.java
+++ b/src/main/java/org/apache/sling/jcr/contentparser/package-info.java
@@ -19,5 +19,5 @@
 /**
  * Parser for repository content serialized e.g. as JSON or JCR XML.
  */
-@org.osgi.annotation.versioning.Version("1.0.0")
+@org.osgi.annotation.versioning.Version("1.1.0")
 package org.apache.sling.jcr.contentparser;
diff --git a/src/test/java/org/apache/sling/jcr/contentparser/impl/XmlContentParserTest.java b/src/test/java/org/apache/sling/jcr/contentparser/impl/XmlContentParserTest.java
new file mode 100644
index 0000000..d51c5d6
--- /dev/null
+++ b/src/test/java/org/apache/sling/jcr/contentparser/impl/XmlContentParserTest.java
@@ -0,0 +1,171 @@
+/*
+ * 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.contentparser.impl;
+
+import static org.apache.sling.jcr.contentparser.impl.TestUtils.parse;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.io.File;
+import java.math.BigDecimal;
+import java.util.Calendar;
+import java.util.Map;
+import java.util.TimeZone;
+
+import org.apache.sling.jcr.contentparser.ContentParser;
+import org.apache.sling.jcr.contentparser.ContentParserFactory;
+import org.apache.sling.jcr.contentparser.ContentType;
+import org.apache.sling.jcr.contentparser.ParseException;
+import org.apache.sling.jcr.contentparser.ParserOptions;
+import org.apache.sling.jcr.contentparser.impl.mapsupport.ContentElement;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableSet;
+
+public class XmlContentParserTest {
+
+    private File file;
+
+    @Before
+    public void setUp() throws Exception {
+        file = new File("src/test/resources/content-test/content.xml");
+    }
+
+    @Test
+    public void testPageJcrPrimaryType() throws Exception {
+        ContentParser underTest = ContentParserFactory.create(ContentType.XML);
+        ContentElement content = parse(underTest, file);
+
+        assertEquals("app:Page", content.getProperties().get("jcr:primaryType"));
+    }
+
+    @Test
+    public void testDataTypes() throws Exception {
+        ContentParser underTest = ContentParserFactory.create(ContentType.XML);
+        ContentElement content = parse(underTest, file);
+
+        Map<String, Object> props = content.getChild("toolbar/profiles/jcr:content").getProperties();
+        assertEquals(true, props.get("hideInNav"));
+
+        assertEquals(1234567890123L, props.get("longProp"));
+        assertEquals(new BigDecimal("1.2345"), props.get("decimalProp"));
+        assertEquals(true, props.get("booleanProp"));
+
+        assertArrayEquals(new Long[] { 1234567890123L, 55L }, (Long[]) props.get("longPropMulti"));
+        assertArrayEquals(new BigDecimal[] { new BigDecimal("1.2345"), new BigDecimal("1.1") }, (BigDecimal[]) props.get("decimalPropMulti"));
+        assertArrayEquals(new Boolean[] { true, false }, (Boolean[]) props.get("booleanPropMulti"));
+    }
+
+    @Test
+    public void testContentProperties() throws Exception {
+        ContentParser underTest = ContentParserFactory.create(ContentType.XML);
+        ContentElement content = parse(underTest, file);
+
+        Map<String, Object> props = content.getChild("jcr:content/header").getProperties();
+        assertEquals("/content/dam/sample/header.png", props.get("imageReference"));
+    }
+
+    @Test
+    public void testCalendar() throws Exception {
+        ContentParser underTest = ContentParserFactory.create(ContentType.XML,
+                new ParserOptions().detectCalendarValues(true));
+        ContentElement content = parse(underTest, file);
+
+        Map<String, Object> props = content.getChild("jcr:content").getProperties();
+
+        Calendar calendar = (Calendar) props.get("app:lastModified");
+        assertNotNull(calendar);
+
+        calendar.setTimeZone(TimeZone.getTimeZone("GMT+2"));
+
+        assertEquals(2014, calendar.get(Calendar.YEAR));
+        assertEquals(4, calendar.get(Calendar.MONTH) + 1);
+        assertEquals(22, calendar.get(Calendar.DAY_OF_MONTH));
+
+        assertEquals(15, calendar.get(Calendar.HOUR_OF_DAY));
+        assertEquals(11, calendar.get(Calendar.MINUTE));
+        assertEquals(24, calendar.get(Calendar.SECOND));
+    }
+
+    @Test
+    public void testUTF8Chars() throws Exception {
+        ContentParser underTest = ContentParserFactory.create(ContentType.XML);
+        ContentElement content = parse(underTest, file);
+
+        Map<String, Object> props = content.getChild("jcr:content").getProperties();
+
+        assertEquals("äöü߀", props.get("utf8Property"));
+    }
+
+    @Test(expected = ParseException.class)
+    public void testParseInvalidJson() throws Exception {
+        file = new File("src/test/resources/invalid-test/invalid.json");
+        ContentParser underTest = ContentParserFactory.create(ContentType.XML);
+        ContentElement content = parse(underTest, file);
+        assertNull(content);
+    }
+
+    @Test(expected = ParseException.class)
+    public void testParseInvalidJsonWithObjectList() throws Exception {
+        file = new File("src/test/resources/invalid-test/contentWithObjectList.json");
+        ContentParser underTest = ContentParserFactory.create(ContentType.XML);
+        ContentElement content = parse(underTest, file);
+        assertNull(content);
+    }
+
+    @Test
+    public void testIgnoreResourcesProperties() throws Exception {
+        ContentParser underTest = ContentParserFactory.create(ContentType.XML,
+                new ParserOptions().ignoreResourceNames(ImmutableSet.of("header", "newslist"))
+                        .ignorePropertyNames(ImmutableSet.of("jcr:title")));
+        ContentElement content = parse(underTest, file);
+        ContentElement child = content.getChild("jcr:content");
+
+        assertEquals("Sample Homepage", child.getProperties().get("pageTitle"));
+        assertNull(child.getProperties().get("jcr:title"));
+
+        assertNull(child.getChildren().get("header"));
+        assertNull(child.getChildren().get("newslist"));
+        assertNotNull(child.getChildren().get("lead"));
+
+        assertEquals("abc", child.getProperties().get("refpro1"));
+        assertEquals("def", child.getProperties().get("pathprop1"));
+    }
+
+    @Test
+    public void testGetChild() throws Exception {
+        ContentParser underTest = ContentParserFactory.create(ContentType.XML);
+        ContentElement content = parse(underTest, file);
+        assertNull(content.getName());
+        
+        ContentElement deepChild = content.getChild("jcr:content/par/image/file/jcr:content");
+        assertEquals("jcr:content", deepChild.getName());
+        assertEquals("nt:resource", deepChild.getProperties().get("jcr:primaryType"));
+
+        ContentElement invalidChild = content.getChild("non/existing/path");
+        assertNull(invalidChild);
+
+        invalidChild = content.getChild("/jcr:content");
+        assertNull(invalidChild);
+    }
+
+}
diff --git a/src/test/resources/content-test/content.xml b/src/test/resources/content-test/content.xml
new file mode 100644
index 0000000..88be464
--- /dev/null
+++ b/src/test/resources/content-test/content.xml
@@ -0,0 +1,316 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<node>
+  <primaryNodeType>app:Page</primaryNodeType>
+  <property><name>jcr:createdBy</name><value>admin</value><type>String</type></property>
+  <property><name>jcr:created</name><value>Thu Aug 07 2014 16:32:59 GMT+0200</value><type>Date</type></property>
+  
+  <node>
+    <name>jcr:content</name>
+    <primaryNodeType>app:PageContent</primaryNodeType>
+    <property><name>jcr:createdBy</name><value>admin</value><type>String</type></property>
+    <property><name>jcr:title</name><value>English</value><type>String</type></property>
+    <property><name>app:template</name><value>sample/templates/homepage</value><type>String</type></property>
+    <property><name>jcr:created</name><value>Thu Aug 07 2014 16:32:59 GMT+0200</value><type>Date</type></property>
+    <property><name>app:lastModified</name><value>Tue Apr 22 2014 15:11:24 GMT+0200</value><type>Date</type></property>
+    <property><name>dateISO8601String</name><value>2014-04-22T15:11:24.000+02:00</value><type>Date</type></property>
+    <property><name>pageTitle</name><value>Sample Homepage</value><type>String</type></property>
+    <property><name>sling:resourceType</name><value>sample/components/homepage</value><type>String</type></property>
+    <property><name>sling:resourceSuperType</name><value>sample/components/supertype</value><type>String</type></property>
+    <property><name>app:designPath</name><value>/etc/designs/sample</value><type>String</type></property>
+    <property><name>app:lastModifiedBy</name><value>admin</value><type>String</type></property>
+    <property><name>utf8Property</name><value>äöü߀</value><type>String</type></property>
+    <property><name>refpro1</name><value>abc</value><type>Reference</type></property>
+    <property><name>pathprop1</name><value>def</value><type>Path</type></property>
+    
+    <node>
+      <name>par</name>
+      <primaryNodeType>nt:unstructured</primaryNodeType>
+      <property><name>sling:resourceType</name><value>foundation/components/parsys</value><type>String</type></property>
+      <node>
+        <name>colctrl</name>
+        <primaryNodeType>nt:unstructured</primaryNodeType>
+        <property><name>jcr:createdBy</name><value>admin</value><type>String</type></property>
+        <property><name>jcr:lastModifiedBy</name><value>admin</value><type>String</type></property>
+        <property><name>layout</name><value>2;colctrl-lt0</value><type>String</type></property>
+        <property><name>jcr:created</name><value>Mon Aug 23 2010 22:02:24 GMT+0200</value><type>Date</type></property>
+        <property><name>jcr:lastModified</name><value>Mon Aug 23 2010 22:02:35 GMT+0200</value><type>Date</type></property>
+        <property><name>sling:resourceType</name><value>foundation/components/parsys/colctrl</value><type>String</type></property>
+      </node>
+      <node>
+        <name>image</name>
+        <primaryNodeType>nt:unstructured</primaryNodeType>
+        <property><name>jcr:createdBy</name><value>admin</value><type>String</type></property>
+        <property><name>fileReference</name><value>/content/dam/sample/portraits/jane_doe.jpg</value><type>String</type></property>
+        <property><name>jcr:lastModifiedBy</name><value>admin</value><type>String</type></property>
+        <property><name>jcr:created</name><value>Mon Aug 23 2010 22:03:39 GMT+0200</value><type>Date</type></property>
+        <property><name>width</name><value>340</value><type>String</type></property>
+        <property><name>jcr:lastModified</name><value>Sun Oct 31 2010 21:39:50 GMT+0100</value><type>Date</type></property>
+        <property><name>sling:resourceTyp</name><value>foundation/components/image</value><type>String</type></property>
+        <node>
+          <name>file</name>
+          <primaryNodeType>nt:file</primaryNodeType>
+          <property><name>jcr:createdB</name><value>admin</value><type>String</type></property>
+          <property><name>jcr:created</name><value>Thu Aug 07 2014 16:32:59 GMT+0200</value><type>Date</type></property>
+          <node>
+            <name>jcr:content</name>
+            <primaryNodeType>nt:resource</primaryNodeType>
+            <property><name>jcr:lastModifiedBy</name><value>anonymous</value><type>String</type></property>
+            <property><name>jcr:mimeType</name><value>image/jpeg</value><type>String</type></property>
+            <property><name>jcr:lastModified</name><value>Thu Aug 07 2014 16:32:59 GMT+0200</value><type>Date</type></property>
+            <property><name>jcr:uuid</name><value>eda76d00-b2cd-4b59-878f-c33f71ceaddc</value><type>String</type></property>
+          </node>
+        </node>
+      </node>
+      <node>
+        <name>title_1</name>
+        <primaryNodeType>nt:unstructured</primaryNodeType>
+        <property><name>jcr:createdBy</name><value>admin</value><type>String</type></property>
+        <property><name>jcr:title</name><value>Strategic Consulting</value><type>String</type></property>
+        <property><name>jcr:lastModifiedBy</name><value>admin</value><type>String</type></property>
+        <property><name>jcr:created</name><value>Mon Aug 23 2010 22:12:08 GMT+0200</value><type>Date</type></property>
+        <property><name>jcr:lastModified</name><value>Wed Oct 27 2010 21:33:24 GMT+0200</value><type>Date</type></property>
+        <property><name>sling:resourceType</name><value>sample/components/title</value><type>String</type></property>
+      </node>
+      <node>
+        <name>text_1</name>
+        <primaryNodeType>nt:unstructured</primaryNodeType>
+        <property><name>jcr:createdBy</name><value>admin</value><type>String</type></property>
+        <property><name>jcr:lastModifiedBy</name><value>admin</value><type>String</type></property>
+        <property><name>jcr:created</name><value>Sun Oct 31 2010 21:48:04 GMT+0100</value><type>Date</type></property>
+        <property><name>text</name><value><![CDATA[<p><span class="Apple-style-span" style="font-size: 12px;">In&nbsp;today's competitive market, organizations can face several key geometric challenges:</span></p>
+<ul>
+<li><span class="Apple-style-span" style="font-size: 12px;">Polyhedral Sectioning</span></li>
+<li><span class="Apple-style-span" style="font-size: 12px;">Triangulation&nbsp;</span></li>
+<li><span class="Apple-style-span" style="font-size: 12px;">Trigonometric Calculation</span></li>
+<li><span class="Apple-style-span" style="font-size: 12px;">Ruler and Compass Construction</span></li>
+</ul>
+<p><span class="Apple-style-span" style="font-size: 12px;"><br>
+Sample is ready to help your organization deal effectively with all these challenges through our award winning geometric consulting services.</span></p>
+<p style="font-family: tahoma, arial, helvetica, sans-serif; font-size: 12px;\"><\/p>
+]]></value><type>String</type></property>
+        <property><name>jcr:lastModified</name><value>Sun Oct 31 2010 21:49:06 GMT+0100</value><type>Date</type></property>
+        <property><name>sling:resourceType</name><value>foundation/components/text</value><type>String</type></property>
+        <property><name>textIsRich</name><value>true</value><type>String</type></property>
+      </node>
+      <node>
+        <name>col_break12825937554040</name>
+        <primaryNodeType>nt:unstructured</primaryNodeType>
+        <property><name>controlType</name><value>break</value><type>String</type></property>
+        <property><name>sling:resourceType</name><value>foundation/components/parsys/colctrl</value><type>String</type></property>
+      </node>
+      <node>
+        <name>image_0</name>
+        <primaryNodeType>nt:unstructured</primaryNodeType>
+        <property><name>jcr:createdBy</name><value>admin</value><type>String</type></property>
+        <property><name>fileReference</name><value>/content/dam/sample/offices/clean_room.jpg</value><type>String</type></property>
+        <property><name>height</name><value>226</value><type>String</type></property>
+        <property><name>jcr:lastModifiedBy</name><value>admin</value><type>String</type></property>
+        <property><name>jcr:created</name><value>Mon Aug 23 2010 22:04:46 GMT+0200</value><type>Date</type></property>
+        <property><name>jcr:lastModified</name><value>Fri Nov 05 2010 10:38:15 GMT+0100</value><type>Date</type></property>
+        <property><name>sling:resourceType</name><value>foundation/components/image</value><type>String</type></property>
+        <property><name>imageRotate</name><value>0</value><type>String</type></property>
+        <node>
+          <name>file</name>
+          <primaryNodeType>nt:file</primaryNodeType>
+          <property><name>jcr:createdBy</name><value>admin</value><type>String</type></property>
+          <property><name>jcr:created</name><value>Thu Aug 07 2014 16:32:59 GMT+0200</value><type>Date</type></property>
+          <node>
+            <name>jcr:content</name>
+            <primaryNodeType>nt:resource</primaryNodeType>
+            <property><name>jcr:lastModifiedBy</name><value>anonymous</value><type>String</type></property>
+            <property><name>jcr:mimeType</name><value>image/jpeg</value><type>String</type></property>
+            <property><name>jcr:lastModified</name><value>Thu Aug 07 2014 16:32:59 GMT+0200</value><type>String</type></property>
+            <property><name>jcr:uuid</name><value>6139077f-191f-4337-aaef-55456ebe6784</value><type>String</type></property>
+          </node>
+        </node>
+      </node>
+      <node>
+        <name>title_2</name>
+        <primaryNodeType>nt:unstructured</primaryNodeType>
+        <property><name>jcr:createdBy</name><value>admin</value><type>String</type></property>
+        <property><name>jcr:title</name><value>Shape Technology</value><type>String</type></property>
+        <property><name>jcr:lastModifiedBy</name><value>admin</value><type>String</type></property>
+        <property><name>jcr:created</name><value>Mon Aug 23 2010 22:12:13 GMT+0200</value><type>Date</type></property>
+        <property><name>jcr:lastModified</name><value>Tue Oct 26 2010 21:16:29 GMT+0200</value><type>Date</type></property>
+        <property><name>sling:resourceType</name><value>sample/components/title</value><type>String</type></property>
+      </node>
+      <node>
+        <name>text_0</name>
+        <primaryNodeType>nt:unstructured</primaryNodeType>
+        <property><name>jcr:createdBy</name><value>admin</value><type>String</type></property>
+        <property><name>jcr:lastModifiedBy</name><value>admin</value><type>String</type></property>
+        <property><name>jcr:created</name><value>Mon Aug 23 2010 22:16:30 GMT+0200</value><type>Date</type></property>
+        <property><name>text</name><value><![CDATA[<p>The Sample investment in R&amp;D has done more than solidify our industry leadership role, we have now outpaced our competitors to such an extent that we are in an altogether new space.</p>
+<p>This is why our high quality polygons and polyhedra provide the only turnkey solutions across the whole range of euclidean geometry. And our mathematicians are working on the next generation of fractal curves to bring you shapes that are unthinkable today.</p>
+<p></p>
+<p></p>
+]]></value><type>String</type></property>
+        <property><name>jcr:lastModified</name><value>Mon Nov 08 2010 20:39:00 GMT+0100</value><type>Date</type></property>
+        <property><name>sling:resourceType</name><value>foundation/components/text</value><type>String</type></property>
+        <property><name>textIsRich</name><value>true</value><type>String</type></property>
+      </node>
+      <node>
+        <name>col_end12825937444810</name>
+        <primaryNodeType>nt:unstructured</primaryNodeType>
+        <property><name>controlType</name><value>end</value><type>String</type></property>
+        <property><name>sling:resourceType</name><value>foundation/components/parsys/colctrl</value><type>String</type></property>
+      </node>
+    </node>
+    <node>
+      <name>header</name>
+      <primaryNodeType>nt:unstructured</primaryNodeType>
+      <property><name>jcr:title</name><value>trust our experience
+to manage your business</value><type>String</type></property>
+      <property><name>imageReference</name><value>/content/dam/sample/header.png</value><type>String</type></property>
+      <property><name>text</name><value>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc eget neque. Nunc condimentum ipsum et orci. Aenean est. Cras eget diam. read more</value><type>String</type></property>
+      <property><name>sling:resourceType</name><value>sample/components/header</value><type>String</type></property>
+    </node>
+    <node>
+      <name>newslist</name>
+      <primaryNodeType>nt:unstructured</primaryNodeType>
+      <property><name>headline</name><value>trust our experience
+to manage your business</value><type>String</type></property>
+      <property><name>text</name><value>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc eget neque. Nunc condimentum ipsum et orci. Aenean est. Cras eget diam. read more</value><type>String</type></property>
+      <property><name>sling:resourceType</name><value>sample/components/listchildren</value><type>String</type></property>
+      <property><name>listroot</name><value>/content/sample/en/about/news</value><type>String</type></property>
+    </node>
+    <node>
+      <name>lead</name>
+      <primaryNodeType>nt:unstructured</primaryNodeType>
+      <property><name>jcr:title</name><value>World Leader in Applied Geometry </value><type>String</type></property>
+      <property><name>jcr:lastModifiedBy</name><value>admin</value><type>String</type></property>
+      <property><name>text</name><value>Lead Text</value><type>String</type></property>
+      <property><name>title</name><value>Lead Title</value><type>String</type></property>
+      <property><name>jcr:description</name><value>ample has been selling and servicing shapes for over 2000 years. From our beginnings as a small vendor of squares and rectangles we have grown our business into a leading global provider of platonic solids and fractals. Join us as we lead geometry into the future.</value><type>String</type></property>
+      <property><name>jcr:lastModified</name><value>Wed Jan 19 2011 14:35:29 GMT+0100</value><type>Date</type></property>
+      <property><name>sling:resourceType</name><value>sample/components/lead</value><type>String</type></property>
+      <node>
+        <name>app:annotations</name>
+        <primaryNodeType>nt:unstructured</primaryNodeType>
+      </node>
+    </node>
+    <node>
+      <name>image</name>
+      <primaryNodeType>nt:unstructured</primaryNodeType>
+      <property><name>jcr:lastModifiedBy</name><value>admin</value><type>String</type></property>
+      <property><name>jcr:lastModified</name><value>Wed Oct 27 2010 21:30:59 GMT+0200</value><type>Date</type></property>
+      <property><name>imageRotate</name><value>0</value><type>String</type></property>
+    </node>
+    <node>
+      <name>carousel</name>
+      <primaryNodeType>nt:unstructured</primaryNodeType>
+      <property><name>playSpeed</name><value>6000</value><type>String</type></property>
+      <property><name>jcr:lastModifiedBy</name><value>admin</value><type>String</type></property>
+      <property><name>pages</name><values><value>/content/sample/en/events/techsummit</value><value>/content/sample/en/events/userconf</value><value>/content/sample/en/events/shapecon</value><value>/content/sample/en/events/dsc</value></values><type>String</type></property>
+      <property><name>jcr:lastModified</name><value>Tue Oct 05 2010 14:14:27 GMT+0200</value><type>Date</type></property>
+      <property><name>transTime</name><value>1000</value><type>String</type></property>
+      <property><name>sling:resourceType</name><value>foundation/components/carousel</value><type>String</type></property>
+      <property><name>listFrom</name><value>static</value><type>String</type></property>
+    </node>
+    <node>
+      <name>rightpar</name>
+      <primaryNodeType>nt:unstructured</primaryNodeType>
+      <property><name>sling:resourceType</name><value>foundation/components/parsys</value><type>String</type></property>
+      <node>
+        <name>teaser</name>
+        <primaryNodeType>nt:unstructured</primaryNodeType>
+        <property><name>jcr:createdBy</name><value>admin</value><type>String</type></property>
+        <property><name>jcr:lastModifiedBy</name><value>admin</value><type>String</type></property>
+        <property><name>jcr:created</name><value>Tue Jan 25 2011 11:30:09 GMT+0100</value><type>Date</type></property>
+        <property><name>campaignpath</name><value>/content/campaigns/sample</value><type>String</type></property>
+        <property><name>jcr:lastModified</name><value>Wed Feb 02 2011 08:40:30 GMT+0100</value><type>Date</type></property>
+        <property><name>sling:resourceTyp</name><value>personalization/components/teaser</value><type>String</type></property>
+      </node>
+    </node>
+  </node>
+  <node>
+    <name>toolbar</name>
+    <primaryNodeType>app:Page</primaryNodeType>
+    <property><name>jcr:createdBy</name><value>admin</value><type>String</type></property>
+    <property><name>jcr:created</name><value>Thu Aug 07 2014 16:33:00 GMT+0200</value><type>String</type></property>
+    <node>
+      <name>jcr:content</name>
+      <primaryNodeType>app:PageContent</primaryNodeType>
+      <property><name>subtitle</name><value>Contains the toolbar</value><type>String</type></property>
+      <property><name>jcr:createdBy</name><value>admin</value><type>String</type></property>
+      <property><name>jcr:title</name><value>Toolbar</value><type>String</type></property>
+      <property><name>app:template</name><value>sample/templates/contentpage</value><type>String</type></property>
+      <property><name>jcr:created</name><value>Thu Aug 07 2014 16:33:00 GMT+0200</value><type>String</type></property>
+      <property><name>app:lastModified</name><value>Wed Aug 25 2010 22:51:02 GMT+0200</value><type>Date</type></property>
+      <property><name>hideInNav</name><value>true</value><type>Date</type></property>
+      <property><name>sling:resourceType</name><value>sample/components/contentpage</value><type>String</type></property>
+      <property><name>app:lastModifiedBy</name><value>admin</value><type>String</type></property>
+      <node>
+        <name>par</name>
+        <primaryNodeType>nt:unstructured</primaryNodeType>
+        <property><name>sling:resourceType</name><value>foundation/components/parsys</value><type>String</type></property>
+      </node>
+      <node>
+        <name>rightpar</name>
+        <primaryNodeType>nt:unstructured</primaryNodeType>
+        <property><name>sling:resourceType</name><value>foundation/components/iparsys</value><type>String</type></property>
+        <node>
+          <name>iparsys_fake_par</name>
+          <primaryNodeType>nt:unstructured</primaryNodeType>
+          <property><name>sling:resourceType</name><value>foundation/components/iparsys/par</value><type>String</type></property>
+        </node>
+      </node>
+    </node>
+    <node>
+      <name>profiles</name>
+      <primaryNodeType>app:Page</primaryNodeType>
+      <property><name>jcr:createdBy</name><value>admin</value><type>String</type></property>
+      <property><name>jcr:created</name><value>Thu Aug 07 2014 16:33:00 GMT+0200</value><type>Date</type></property>
+      <node>
+        <name>jcr:content</name>
+        <primaryNodeType>app:PageContent</primaryNodeType>
+        <mixinNodeType>type1</mixinNodeType>
+        <mixinNodeType>type2</mixinNodeType>
+        <property><name>jcr:createdBy</name><value>admin</value><type>String</type></property>
+        <property><name>jcr:title</name><value>Profiles</value><type>String</type></property>
+        <property><name>app:template</name><value>sample/templates/contentpage</value><type>String</type></property>
+        <property><name>jcr:created</name><value>Thu Aug 07 2014 16:33:00 GMT+0200</value><type>Date</type></property>
+        <property><name>app:lastModified</name><value>Thu Nov 05 2009 20:27:13 GMT+0100</value><type>Date</type></property>
+        <property><name>hideInNav</name><value>true</value><type>Boolean</type></property>
+        <property><name>sling:resourceType</name><value>sample/components/contentpage</value><type>String</type></property>
+        <property><name>app:lastModifiedBy</name><value>admin</value><type>String</type></property>
+        <property><name>longProp</name><value>1234567890123</value><type>Long</type></property>
+        <property><name>decimalProp</name><value>1.2345</value><type>Decimal</type></property>
+        <property><name>booleanProp</name><value>true</value><type>Boolean</type></property>
+        <property><name>longPropMulti</name><values><value>1234567890123</value><value>55</value></values><type>Long</type></property>
+        <property><name>decimalPropMulti</name><values><value>1.2345</value><value>1.1</value></values><type>Decimal</type></property>
+        <property><name>booleanPropMulti</name><values><value>true</value><value>false</value></values><type>Boolean</type></property>
+        <property><name>stringPropMulti</name><values><value>aa</value><value>bb</value><value>cc</value></values><type>String</type></property>
+        <node>
+          <name>par</name>
+          <primaryNodeType>nt:unstructured</primaryNodeType>
+          <property><name>sling:resourceType</name><value>foundation/components/parsys</value><type>String</type></property>
+          <node>
+            <name>textimage</name>
+            <primaryNodeType>nt:unstructured</primaryNodeType>
+            <property><name>sling:resourceType</name><value>foundation/components/textimage</value><type>String</type></property>
+          </node>
+          <node>
+            <name>mygadgets</name>
+            <primaryNodeType>nt:unstructured</primaryNodeType>
+            <property><name>gadgets</name><value>http://customer.meteogroup.de/meteogroup/gadgets/wetter24.xml
+http://germanweatherradar.googlecode.com/svn/trunk/german-weather-radar.xml
+http://www.digitalpowered.info/gadget/ski.pictures.xml
+http://www.canbuffi.de/gadgets/clock/clock.xml</value><type>String</type></property>
+            <property><name>sling:resourceType</name><value>personalization/components/mygadgets</value><type>String</type></property>
+          </node>
+        </node>
+        <node>
+          <name>rightpar</name>
+          <primaryNodeType>nt:unstructured</primaryNodeType>
+          <property><name>sling:resourceType</name><value>foundation/components/iparsys</value><type>String</type></property>
+          <node>
+            <name>iparsys_fake_par</name>
+            <primaryNodeType>nt:unstructured</primaryNodeType>
+            <property><name>sling:resourceType</name><value>foundation/components/iparsys/par</value><type>String</type></property>
+          </node>
+        </node>
+      </node>
+    </node>
+  </node>
+</node>

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