Added: 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNode.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNode.java?rev=1783888&view=auto
==============================================================================
--- 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNode.java
 (added)
+++ 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNode.java
 Tue Feb 21 13:54:37 2017
@@ -0,0 +1,481 @@
+/*
+ * 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.fsprovider.internal.mapper.jcr;
+
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.util.Calendar;
+
+import javax.jcr.AccessDeniedException;
+import javax.jcr.Binary;
+import javax.jcr.InvalidItemStateException;
+import javax.jcr.InvalidLifecycleTransitionException;
+import javax.jcr.Item;
+import javax.jcr.ItemExistsException;
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.MergeException;
+import javax.jcr.NoSuchWorkspaceException;
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
+import javax.jcr.RepositoryException;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.Value;
+import javax.jcr.ValueFormatException;
+import javax.jcr.lock.Lock;
+import javax.jcr.lock.LockException;
+import javax.jcr.nodetype.ConstraintViolationException;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
+import javax.jcr.nodetype.NodeDefinition;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.version.ActivityViolationException;
+import javax.jcr.version.Version;
+import javax.jcr.version.VersionException;
+import javax.jcr.version.VersionHistory;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.sling.api.resource.Resource;
+
+/**
+ * Simplified implementation of read-only content access via the JCR API.
+ */
+public final class FsNode extends FsItem implements Node {
+    
+    public FsNode(Resource resource) {
+        super(resource);
+    }
+    
+    @Override
+    public Node getNode(String relPath) throws PathNotFoundException, 
RepositoryException {
+        Resource child = resource.getChild(relPath);
+        if (child != null) {
+            return new FsNode(child);
+        }
+        throw new PathNotFoundException(relPath);
+    }
+
+    @Override
+    public NodeIterator getNodes() throws RepositoryException {
+        return new FsNodeIterator(resource.listChildren());
+    }
+
+    @Override
+    public Property getProperty(String relPath) throws PathNotFoundException, 
RepositoryException {
+        if (props.containsKey(relPath)) {
+            return new FsProperty(resource, relPath, this);
+        }
+        throw new PathNotFoundException(relPath);
+    }
+
+    @Override
+    public PropertyIterator getProperties() throws RepositoryException {
+        return new FsPropertyIterator(props.keySet().iterator(), resource, 
this);
+    }
+
+    @Override
+    public String getUUID() throws UnsupportedRepositoryOperationException, 
RepositoryException {
+        String uuid = props.get("jcr:uuid", String.class);
+        if (uuid != null) {
+            return uuid;
+        }
+        else {
+            throw new UnsupportedRepositoryOperationException();
+        }
+    }
+
+    @Override
+    public boolean hasNode(String relPath) throws RepositoryException {
+        return resource.getChild(relPath) != null;
+    }
+
+    @Override
+    public boolean hasProperty(String relPath) throws RepositoryException {
+        return props.containsKey(relPath);
+    }
+
+    @Override
+    public boolean hasNodes() throws RepositoryException {
+        return resource.listChildren().hasNext();
+    }
+
+    @Override
+    public boolean hasProperties() throws RepositoryException {
+        return !props.isEmpty();
+    }
+
+    @Override
+    public boolean isNodeType(String nodeTypeName) throws RepositoryException {
+        return StringUtils.equals(nodeTypeName, props.get("jcr:primaryType", 
String.class));
+    }
+
+    @Override
+    public boolean canAddMixin(String mixinName) throws 
NoSuchNodeTypeException, RepositoryException {
+        return false;
+    }
+
+    @Override
+    public boolean isCheckedOut() throws RepositoryException {
+        return false;
+    }
+
+    @Override
+    public boolean holdsLock() throws RepositoryException {
+        return false;
+    }
+
+    @Override
+    public boolean isLocked() throws RepositoryException {
+        return false;
+    }
+
+
+    // --- unsupported methods ---
+    
+    @Override
+    public Node addNode(String relPath) throws ItemExistsException, 
PathNotFoundException, VersionException,
+            ConstraintViolationException, LockException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Node addNode(String relPath, String primaryNodeTypeName)
+            throws ItemExistsException, PathNotFoundException, 
NoSuchNodeTypeException, LockException, VersionException,
+            ConstraintViolationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void orderBefore(String srcChildRelPath, String destChildRelPath)
+            throws UnsupportedRepositoryOperationException, VersionException, 
ConstraintViolationException,
+            ItemNotFoundException, LockException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Property setProperty(String name, Value value) throws 
ValueFormatException, VersionException, LockException,
+            ConstraintViolationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Property setProperty(String name, Value value, int type) throws 
ValueFormatException, VersionException,
+            LockException, ConstraintViolationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Property setProperty(String name, Value[] values) throws 
ValueFormatException, VersionException,
+            LockException, ConstraintViolationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Property setProperty(String name, Value[] values, int type) throws 
ValueFormatException, VersionException,
+            LockException, ConstraintViolationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Property setProperty(String name, String[] values) throws 
ValueFormatException, VersionException,
+            LockException, ConstraintViolationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Property setProperty(String name, String[] values, int type) throws 
ValueFormatException, VersionException,
+            LockException, ConstraintViolationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Property setProperty(String name, String value) throws 
ValueFormatException, VersionException, LockException,
+            ConstraintViolationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Property setProperty(String name, String value, int type) throws 
ValueFormatException, VersionException,
+            LockException, ConstraintViolationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Property setProperty(String name, InputStream value) throws 
ValueFormatException, VersionException,
+            LockException, ConstraintViolationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Property setProperty(String name, Binary value) throws 
ValueFormatException, VersionException, LockException,
+            ConstraintViolationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Property setProperty(String name, boolean value) throws 
ValueFormatException, VersionException,
+            LockException, ConstraintViolationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Property setProperty(String name, double value) throws 
ValueFormatException, VersionException, LockException,
+            ConstraintViolationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Property setProperty(String name, BigDecimal value) throws 
ValueFormatException, VersionException,
+            LockException, ConstraintViolationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Property setProperty(String name, long value) throws 
ValueFormatException, VersionException, LockException,
+            ConstraintViolationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Property setProperty(String name, Calendar value) throws 
ValueFormatException, VersionException,
+            LockException, ConstraintViolationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Property setProperty(String name, Node value) throws 
ValueFormatException, VersionException, LockException,
+            ConstraintViolationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public PropertyIterator getReferences() throws RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public PropertyIterator getReferences(String name) throws 
RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public PropertyIterator getWeakReferences() throws RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public PropertyIterator getWeakReferences(String name) throws 
RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setPrimaryType(String nodeTypeName) throws 
NoSuchNodeTypeException, VersionException,
+            ConstraintViolationException, LockException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void addMixin(String mixinName) throws NoSuchNodeTypeException, 
VersionException,
+            ConstraintViolationException, LockException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void removeMixin(String mixinName) throws NoSuchNodeTypeException, 
VersionException,
+            ConstraintViolationException, LockException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public NodeDefinition getDefinition() throws RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Version checkin() throws VersionException, 
UnsupportedRepositoryOperationException,
+            InvalidItemStateException, LockException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void checkout() throws UnsupportedRepositoryOperationException, 
LockException, ActivityViolationException,
+            RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void doneMerge(Version version) throws VersionException, 
InvalidItemStateException,
+            UnsupportedRepositoryOperationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void cancelMerge(Version version) throws VersionException, 
InvalidItemStateException,
+            UnsupportedRepositoryOperationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void update(String srcWorkspace) throws NoSuchWorkspaceException, 
AccessDeniedException, LockException,
+            InvalidItemStateException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public NodeIterator merge(String srcWorkspace, boolean bestEffort) throws 
NoSuchWorkspaceException,
+            AccessDeniedException, MergeException, LockException, 
InvalidItemStateException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getCorrespondingNodePath(String workspaceName)
+            throws ItemNotFoundException, NoSuchWorkspaceException, 
AccessDeniedException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public NodeIterator getSharedSet() throws RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void removeSharedSet()
+            throws VersionException, LockException, 
ConstraintViolationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void removeShare()
+            throws VersionException, LockException, 
ConstraintViolationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void restore(String versionName, boolean removeExisting) throws 
VersionException, ItemExistsException,
+            UnsupportedRepositoryOperationException, LockException, 
InvalidItemStateException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void restore(Version version, boolean removeExisting) throws 
VersionException, ItemExistsException,
+            InvalidItemStateException, 
UnsupportedRepositoryOperationException, LockException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void restore(Version version, String relPath, boolean 
removeExisting)
+            throws PathNotFoundException, ItemExistsException, 
VersionException, ConstraintViolationException,
+            UnsupportedRepositoryOperationException, LockException, 
InvalidItemStateException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void restoreByLabel(String versionLabel, boolean removeExisting)
+            throws VersionException, ItemExistsException, 
UnsupportedRepositoryOperationException, LockException,
+            InvalidItemStateException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public VersionHistory getVersionHistory() throws 
UnsupportedRepositoryOperationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Version getBaseVersion() throws 
UnsupportedRepositoryOperationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Lock lock(boolean isDeep, boolean isSessionScoped) throws 
UnsupportedRepositoryOperationException,
+            LockException, AccessDeniedException, InvalidItemStateException, 
RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Lock getLock()
+            throws UnsupportedRepositoryOperationException, LockException, 
AccessDeniedException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void unlock() throws UnsupportedRepositoryOperationException, 
LockException, AccessDeniedException,
+            InvalidItemStateException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void followLifecycleTransition(String transition)
+            throws UnsupportedRepositoryOperationException, 
InvalidLifecycleTransitionException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String[] getAllowedLifecycleTransistions()
+            throws UnsupportedRepositoryOperationException, 
RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public NodeIterator getNodes(String namePattern) throws 
RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public NodeIterator getNodes(String[] nameGlobs) throws 
RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public NodeType getPrimaryNodeType() throws RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getIdentifier() throws RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int getIndex() throws RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public NodeType[] getMixinNodeTypes() throws RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Item getPrimaryItem() throws ItemNotFoundException, 
RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public PropertyIterator getProperties(String namePattern) throws 
RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public PropertyIterator getProperties(String[] nameGlobs) throws 
RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+}

Propchange: 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNode.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNode.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Tue Feb 21 13:54:37 2017
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNode.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNodeIterator.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNodeIterator.java?rev=1783888&view=auto
==============================================================================
--- 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNodeIterator.java
 (added)
+++ 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNodeIterator.java
 Tue Feb 21 13:54:37 2017
@@ -0,0 +1,74 @@
+/*
+ * 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.fsprovider.internal.mapper.jcr;
+
+import java.util.Iterator;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+
+import org.apache.sling.api.resource.Resource;
+
+/**
+ * Simplified implementation of read-only content access via the JCR API.
+ */
+class FsNodeIterator implements NodeIterator {
+    
+    private final Iterator<Resource> resources;
+
+    public FsNodeIterator(Iterator<Resource> resources) {
+        this.resources = resources;
+    }
+
+    public boolean hasNext() {
+        return resources.hasNext();
+    }
+
+    public Object next() {
+        return nextNode();
+    }
+
+    @Override
+    public Node nextNode() {
+        return resources.next().adaptTo(Node.class);
+    }
+
+    
+    // --- unsupported methods ---
+        
+    public void remove() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void skip(long skipNum) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public long getSize() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public long getPosition() {
+        throw new UnsupportedOperationException();
+    }
+
+}

Propchange: 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNodeIterator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNodeIterator.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Tue Feb 21 13:54:37 2017
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNodeIterator.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsProperty.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsProperty.java?rev=1783888&view=auto
==============================================================================
--- 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsProperty.java
 (added)
+++ 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsProperty.java
 Tue Feb 21 13:54:37 2017
@@ -0,0 +1,241 @@
+/*
+ * 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.fsprovider.internal.mapper.jcr;
+
+import java.io.InputStream;
+import java.lang.reflect.Array;
+import java.math.BigDecimal;
+import java.util.Calendar;
+
+import javax.jcr.AccessDeniedException;
+import javax.jcr.Binary;
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.ValueFormatException;
+import javax.jcr.lock.LockException;
+import javax.jcr.nodetype.ConstraintViolationException;
+import javax.jcr.nodetype.PropertyDefinition;
+import javax.jcr.version.VersionException;
+
+import org.apache.sling.api.resource.Resource;
+
+/**
+ * Simplified implementation of read-only content access via the JCR API.
+ */
+class FsProperty extends FsItem implements Property {
+    
+    private final String propertyName;
+    private final Node node;
+    
+    public FsProperty(Resource resource, String propertyName, Node node) {
+        super(resource);
+        this.propertyName = propertyName;
+        this.node = node;
+    }
+    
+    @Override
+    public String getName() throws RepositoryException {
+        return propertyName;
+    }
+
+    @Override
+    public Node getParent() throws ItemNotFoundException, 
AccessDeniedException, RepositoryException {
+        return getNode();
+    }
+
+    @Override
+    public Node getNode() throws ItemNotFoundException, ValueFormatException, 
RepositoryException {
+        return node;
+    }
+    
+    @Override
+    public String getPath() throws RepositoryException {
+        return resource.getPath() + "/" + propertyName;
+    }
+
+    @Override
+    public Value getValue() throws ValueFormatException, RepositoryException {
+        return new FsValue(props, propertyName);
+    }
+
+    @Override
+    public String getString() throws ValueFormatException, RepositoryException 
{
+        return getValue().getString();
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    public InputStream getStream() throws ValueFormatException, 
RepositoryException {
+        return getValue().getStream();
+    }
+
+    @Override
+    public Binary getBinary() throws ValueFormatException, RepositoryException 
{
+        return getValue().getBinary();
+    }
+
+    @Override
+    public long getLong() throws ValueFormatException, RepositoryException {
+        return getValue().getLong();
+    }
+
+    @Override
+    public double getDouble() throws ValueFormatException, RepositoryException 
{
+        return getValue().getDouble();
+    }
+
+    @Override
+    public BigDecimal getDecimal() throws ValueFormatException, 
RepositoryException {
+        return getValue().getDecimal();
+    }
+
+    @Override
+    public Calendar getDate() throws ValueFormatException, RepositoryException 
{
+        return getValue().getDate();
+    }
+
+    @Override
+    public boolean getBoolean() throws ValueFormatException, 
RepositoryException {
+        return getValue().getBoolean();
+    }
+
+    @Override
+    public Value[] getValues() throws ValueFormatException, 
RepositoryException {
+        if (!isMultiple()) {
+            throw new ValueFormatException();
+        }
+        Object value = props.get(propertyName);
+        int size = Array.getLength(value);
+        Value[] result = new Value[size];
+        for (int i=0; i<size; i++) {
+            result[i] = new FsValue(props, propertyName, i);
+        }
+        return result;
+    }
+
+    @Override
+    public boolean isMultiple() throws RepositoryException {
+        Object value = props.get(propertyName);
+        return value != null && value.getClass().isArray();
+    }
+
+    @Override
+    public int getType() throws RepositoryException {
+        return getValue().getType();
+    }
+    
+
+    // --- unsupported methods ---
+    
+    @Override
+    public void setValue(Value value) throws ValueFormatException, 
VersionException, LockException,
+            ConstraintViolationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setValue(Value[] values) throws ValueFormatException, 
VersionException, LockException,
+            ConstraintViolationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setValue(String value) throws ValueFormatException, 
VersionException, LockException,
+            ConstraintViolationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setValue(String[] values) throws ValueFormatException, 
VersionException, LockException,
+            ConstraintViolationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setValue(InputStream value) throws ValueFormatException, 
VersionException, LockException,
+            ConstraintViolationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setValue(Binary value) throws ValueFormatException, 
VersionException, LockException,
+            ConstraintViolationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setValue(long value) throws ValueFormatException, 
VersionException, LockException,
+            ConstraintViolationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setValue(double value) throws ValueFormatException, 
VersionException, LockException,
+            ConstraintViolationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setValue(BigDecimal value) throws ValueFormatException, 
VersionException, LockException,
+            ConstraintViolationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setValue(Calendar value) throws ValueFormatException, 
VersionException, LockException,
+            ConstraintViolationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setValue(boolean value) throws ValueFormatException, 
VersionException, LockException,
+            ConstraintViolationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setValue(Node value) throws ValueFormatException, 
VersionException, LockException,
+            ConstraintViolationException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public PropertyDefinition getDefinition() throws RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Property getProperty() throws ItemNotFoundException, 
ValueFormatException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public long getLength() throws ValueFormatException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public long[] getLengths() throws ValueFormatException, 
RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+}

Propchange: 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsProperty.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsProperty.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Tue Feb 21 13:54:37 2017
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsProperty.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsPropertyIterator.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsPropertyIterator.java?rev=1783888&view=auto
==============================================================================
--- 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsPropertyIterator.java
 (added)
+++ 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsPropertyIterator.java
 Tue Feb 21 13:54:37 2017
@@ -0,0 +1,79 @@
+/*
+ * 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.fsprovider.internal.mapper.jcr;
+
+import java.util.Iterator;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
+
+import org.apache.sling.api.resource.Resource;
+
+/**
+ * Simplified implementation of read-only content access via the JCR API.
+ */
+class FsPropertyIterator implements PropertyIterator {
+    
+    private final Iterator<String> propertyNames;
+    private final Resource resource;
+    private final Node node;
+    
+    public FsPropertyIterator(Iterator<String> propertyNames, Resource 
resource, Node node) {
+        this.propertyNames = propertyNames;
+        this.resource = resource;
+        this.node = node;
+    }
+
+    public boolean hasNext() {
+        return propertyNames.hasNext();
+    }
+
+    public Object next() {
+        return nextProperty();
+    }
+
+    @Override
+    public Property nextProperty() {
+        return new FsProperty(resource, propertyNames.next(), node);
+    }
+
+    
+    // --- unsupported methods ---
+        
+    public void remove() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void skip(long skipNum) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public long getSize() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public long getPosition() {
+        throw new UnsupportedOperationException();
+    }
+
+}

Propchange: 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsPropertyIterator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsPropertyIterator.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Tue Feb 21 13:54:37 2017
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsPropertyIterator.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsValue.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsValue.java?rev=1783888&view=auto
==============================================================================
--- 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsValue.java
 (added)
+++ 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsValue.java
 Tue Feb 21 13:54:37 2017
@@ -0,0 +1,162 @@
+/*
+ * 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.fsprovider.internal.mapper.jcr;
+
+import java.io.InputStream;
+import java.lang.reflect.Array;
+import java.math.BigDecimal;
+import java.util.Calendar;
+
+import javax.jcr.Binary;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.ValueFormatException;
+
+import org.apache.sling.api.resource.ValueMap;
+
+/**
+ * Simplified implementation of read-only content access via the JCR API.
+ */
+class FsValue implements Value {
+    
+    private final ValueMap props;
+    private final String propertyName;
+    private final int arrayIndex;
+    
+    public FsValue(ValueMap props, String propertyName) {
+        this.props = props;
+        this.propertyName = propertyName;
+        this.arrayIndex = -1;
+    }
+
+    public FsValue(ValueMap props, String propertyName, int arrayIndex) {
+        this.props = props;
+        this.propertyName = propertyName;
+        this.arrayIndex = arrayIndex;
+    }
+
+    @Override
+    public String getString() throws ValueFormatException, 
IllegalStateException, RepositoryException {
+        if (arrayIndex >= 0) {
+            return props.get(propertyName, String[].class)[arrayIndex];
+        }
+        else {
+            return props.get(propertyName, String.class);
+        }
+    }
+
+    @Override
+    public long getLong() throws ValueFormatException, RepositoryException {
+        if (arrayIndex >= 0) {
+            return props.get(propertyName, Long[].class)[arrayIndex];
+        }
+        else {
+            return props.get(propertyName, 0L);
+        }
+    }
+
+    @Override
+    public double getDouble() throws ValueFormatException, RepositoryException 
{
+        if (arrayIndex >= 0) {
+            return props.get(propertyName, Double[].class)[arrayIndex];
+        }
+        else {
+            return props.get(propertyName, 0d);
+        }
+    }
+
+    @Override
+    public BigDecimal getDecimal() throws ValueFormatException, 
RepositoryException {
+        if (arrayIndex >= 0) {
+            return props.get(propertyName, BigDecimal[].class)[arrayIndex];
+        }
+        else {
+            return props.get(propertyName, BigDecimal.ZERO);
+        }
+    }
+
+    @Override
+    public Calendar getDate() throws ValueFormatException, RepositoryException 
{
+        if (arrayIndex >= 0) {
+            return props.get(propertyName, Calendar[].class)[arrayIndex];
+        }
+        else {
+            return props.get(propertyName, Calendar.class);
+        }
+    }
+
+    @Override
+    public boolean getBoolean() throws ValueFormatException, 
RepositoryException {
+        if (arrayIndex >= 0) {
+            return props.get(propertyName, Boolean[].class)[arrayIndex];
+        }
+        else {
+            return props.get(propertyName, false);
+        }
+    }
+
+    @Override
+    public int getType() {
+        Object value = props.get(propertyName);
+        if (value == null) {
+            return PropertyType.UNDEFINED;
+        }
+        Class type = value.getClass();
+        if (type.isArray() && Array.getLength(value) > 0) {
+            Object firstItem = Array.get(value, 0);
+            if (firstItem != null) {
+                type = firstItem.getClass();
+            }
+        }
+        if (type == String.class) {
+            return PropertyType.STRING;
+        }
+        if (type == Boolean.class || type == boolean.class) {
+            return PropertyType.BOOLEAN;
+        }
+        if (type == BigDecimal.class) {
+            return PropertyType.DECIMAL;
+        }
+        if (type == Double.class || type == double.class || type == 
Float.class || type == float.class) {
+            return PropertyType.DOUBLE;
+        }
+        if (Number.class.isAssignableFrom(type)) {
+            return PropertyType.LONG;
+        }
+        if (type == Calendar.class) {
+            return PropertyType.DATE;
+        }
+        return PropertyType.UNDEFINED;
+    }
+
+
+    // --- unsupported methods ---
+    
+    @Override
+    public InputStream getStream() throws RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Binary getBinary() throws RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+}

Propchange: 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsValue.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsValue.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Tue Feb 21 13:54:37 2017
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsValue.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/parser/ContentFileParser.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/parser/ContentFileParser.java?rev=1783888&view=auto
==============================================================================
--- 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/parser/ContentFileParser.java
 (added)
+++ 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/parser/ContentFileParser.java
 Tue Feb 21 13:54:37 2017
@@ -0,0 +1,52 @@
+/*
+ * 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.fsprovider.internal.parser;
+
+import java.io.File;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * Parses file that contains content fragments (e.g. JSON, JCR XML).
+ */
+public final class ContentFileParser {
+    
+    /**
+     * JSON content files.
+     */
+    public static final String JSON_SUFFIX = ".json";
+    
+    private ContentFileParser() {
+        // static methods only
+    }
+    
+    /**
+     * Parse content from file.
+     * @param file File. Type is detected automatically.
+     * @return Content or null if content could not be parsed.
+     */
+    public static Map<String,Object> parse(File file) {
+        if (StringUtils.endsWith(file.getName(), JSON_SUFFIX)) {
+            return JsonFileParser.parse(file);
+        }
+        return null;
+    }
+
+}

Propchange: 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/parser/ContentFileParser.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/parser/ContentFileParser.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Tue Feb 21 13:54:37 2017
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/parser/ContentFileParser.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/parser/JsonFileParser.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/parser/JsonFileParser.java?rev=1783888&view=auto
==============================================================================
--- 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/parser/JsonFileParser.java
 (added)
+++ 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/parser/JsonFileParser.java
 Tue Feb 21 13:54:37 2017
@@ -0,0 +1,126 @@
+/*
+ * 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.fsprovider.internal.parser;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonNumber;
+import javax.json.JsonObject;
+import javax.json.JsonReader;
+import javax.json.JsonReaderFactory;
+import javax.json.JsonString;
+import javax.json.JsonValue;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Parses JSON file that contains content fragments.
+ */
+class JsonFileParser {
+    
+    private static final Logger log = 
LoggerFactory.getLogger(JsonFileParser.class);
+    
+    private static final JsonReaderFactory JSON_READER_FACTORY;
+    static {
+        // allow comments in JSON files
+        Map<String,Object> jsonReaderFactoryConfig = new HashMap<>();
+        jsonReaderFactoryConfig.put("org.apache.johnzon.supports-comments", 
true);
+        // workaround for JsonProvider classloader issue until 
https://issues.apache.org/jira/browse/GERONIMO-6560 is fixed
+        ClassLoader oldClassLoader = 
Thread.currentThread().getContextClassLoader();
+        try {
+            
Thread.currentThread().setContextClassLoader(JsonFileParser.class.getClassLoader());
+            JSON_READER_FACTORY = 
Json.createReaderFactory(jsonReaderFactoryConfig);
+        }
+        finally {
+            Thread.currentThread().setContextClassLoader(oldClassLoader);
+        }
+    }
+    
+    private JsonFileParser() {
+        // static methods only
+    }
+    
+    /**
+     * Parse JSON file.
+     * @param file File
+     * @return Content
+     */
+    public static Map<String,Object> parse(File file) {
+        log.debug("Parse JSON content from {}", file.getPath());
+        try {
+            try (FileInputStream fis = new FileInputStream(file);
+                    JsonReader reader = JSON_READER_FACTORY.createReader(fis)) 
{
+                return toMap(reader.readObject());
+            }
+        }
+        catch (IOException ex) {
+            log.warn("Error parsing JSON content from " + file.getPath(), ex);
+            return null;
+        }
+    }
+    
+    private static Map<String,Object> toMap(JsonObject object) {
+        Map<String,Object> map = new LinkedHashMap<>();
+        for (Map.Entry<String, JsonValue> entry : object.entrySet()) {
+            map.put(entry.getKey(), convertValue(entry.getValue()));
+        }
+        return map;
+    }
+    
+    private static Object convertValue(JsonValue value) {
+        switch (value.getValueType()) {
+            case STRING:
+                return ((JsonString)value).getString();
+            case NUMBER:
+                JsonNumber numberValue = (JsonNumber)value;
+                if (numberValue.isIntegral()) {
+                    return numberValue.longValue();
+                }
+                else {
+                    return numberValue.doubleValue();
+                }
+            case TRUE:
+                return true;
+            case FALSE:
+                return false;
+            case NULL:
+                return null;
+            case ARRAY:
+                JsonArray arrayValue = (JsonArray)value;
+                Object[] values = new Object[arrayValue.size()];
+                for (int i=0; i<values.length; i++) {
+                    values[i] = convertValue(arrayValue.get(i));
+                }
+                return values;
+            case OBJECT:
+                return toMap((JsonObject)value);
+            default:
+                throw new IllegalArgumentException("Unexpected JSON value 
type: " + value.getValueType());
+        }
+    }
+    
+}

Propchange: 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/parser/JsonFileParser.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/parser/JsonFileParser.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Tue Feb 21 13:54:37 2017
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: 
sling/trunk/bundles/extensions/fsresource/src/main/java/org/apache/sling/fsprovider/internal/parser/JsonFileParser.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/FileMonitorTest.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/FileMonitorTest.java?rev=1783888&r1=1783887&r2=1783888&view=diff
==============================================================================
--- 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/FileMonitorTest.java
 (original)
+++ 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/FileMonitorTest.java
 Tue Feb 21 13:54:37 2017
@@ -63,7 +63,8 @@ public class FileMonitorTest {
                 context.registerInjectActivateService(new FsResourceProvider(),
                         "provider.file", tempDir.getPath(),
                         "provider.root", "/fs-test",
-                        "provider.checkinterval", 120);
+                        "provider.checkinterval", 120,
+                        "provider.json.content", true);
                 
                 // register resource change listener
                 context.registerService(ResourceChangeListener.class, 
resourceListener,
@@ -85,7 +86,7 @@ public class FileMonitorTest {
         assertTrue(changes.isEmpty());
         
         File file1a = new File(tempDir, "folder1/file1a.txt");
-        FileUtils.write(file1a, "newcontent");
+        FileUtils.touch(file1a);
         
         Thread.sleep(250);
 
@@ -153,6 +154,50 @@ public class FileMonitorTest {
         assertChange(changes, 1, "/fs-test/folder1", ChangeType.REMOVED);
     }
 
+    @Test
+    public void testUpdateJsonContent() throws Exception {
+        List<ResourceChange> changes = resourceListener.getChanges();
+        assertTrue(changes.isEmpty());
+        
+        File file1a = new File(tempDir, "folder2/content.json");
+        FileUtils.touch(file1a);
+        
+        Thread.sleep(250);
+
+        assertEquals(1, changes.size());
+        assertChange(changes, 0, "/fs-test/folder2/content", 
ChangeType.CHANGED);
+    }
+    
+    @Test
+    public void testAddJsonContent() throws Exception {
+        List<ResourceChange> changes = resourceListener.getChanges();
+        assertTrue(changes.isEmpty());
+        
+        File file1c = new File(tempDir, "folder1/file1c.json");
+        FileUtils.write(file1c, "{'prop1':'value1'}");
+        
+        Thread.sleep(250);
+
+        assertEquals(2, changes.size());
+        assertChange(changes, 0, "/fs-test/folder1", ChangeType.CHANGED);
+        assertChange(changes, 1, "/fs-test/folder1/file1c", ChangeType.ADDED);
+    }
+    
+    @Test
+    public void testRemoveJsonContent() throws Exception {
+        List<ResourceChange> changes = resourceListener.getChanges();
+        assertTrue(changes.isEmpty());
+        
+        File file1a = new File(tempDir, "folder2/content.json");
+        file1a.delete();
+        
+        Thread.sleep(250);
+
+        assertEquals(2, changes.size());
+        assertChange(changes, 0, "/fs-test/folder2", ChangeType.CHANGED);
+        assertChange(changes, 1, "/fs-test/folder2/content", 
ChangeType.REMOVED);
+    }
+    
     
     private void assertChange(List<ResourceChange> changes, int index, String 
path, ChangeType changeType) {
         ResourceChange change = changes.get(index);

Modified: 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/FilesFolderTest.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/FilesFolderTest.java?rev=1783888&r1=1783887&r2=1783888&view=diff
==============================================================================
--- 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/FilesFolderTest.java
 (original)
+++ 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/FilesFolderTest.java
 Tue Feb 21 13:54:37 2017
@@ -18,12 +18,13 @@
  */
 package org.apache.sling.fsprovider.internal;
 
-import static 
org.apache.sling.fsprovider.internal.TestUtils.REGISTER_FSRESOURCE_PLUGIN;
 import static org.apache.sling.fsprovider.internal.TestUtils.assertFile;
 import static org.apache.sling.fsprovider.internal.TestUtils.assertFolder;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertThat;
 
 import org.apache.sling.api.resource.Resource;
+import org.apache.sling.fsprovider.internal.TestUtils.RegisterFsResourcePlugin;
 import org.apache.sling.hamcrest.ResourceMatchers;
 import org.apache.sling.testing.mock.sling.ResourceResolverType;
 import org.apache.sling.testing.mock.sling.junit.SlingContext;
@@ -42,7 +43,7 @@ public class FilesFolderTest {
 
     @Rule
     public SlingContext context = new 
SlingContextBuilder(ResourceResolverType.JCR_MOCK)
-        .plugin(REGISTER_FSRESOURCE_PLUGIN)
+        .plugin(new RegisterFsResourcePlugin())
         .build();
 
     @Before
@@ -63,14 +64,16 @@ public class FilesFolderTest {
         assertFile(fsroot, "folder1/file1a.txt", "file1a");
         assertFile(fsroot, "folder1/file1b.txt", "file1b");
         assertFile(fsroot, "folder1/folder11/file11a.txt", "file11a");
-        assertFile(fsroot, "folder2/file2a.txt", "file2a");
+        assertFile(fsroot, "folder2/content.json", null);
     }
 
     @Test
     public void testListChildren() {
         assertThat(root, ResourceMatchers.containsChildren("fs-test"));
         assertThat(fsroot, ResourceMatchers.hasChildren("folder1", "folder2"));
-        assertThat(fsroot.getChild("folder1"), 
ResourceMatchers.hasChildren("file1a.txt", "file1b.txt"));
+        assertThat(fsroot.getChild("folder1"), 
ResourceMatchers.hasChildren("folder11", "file1a.txt", "file1b.txt"));
+        assertThat(fsroot.getChild("folder2"), 
ResourceMatchers.hasChildren("folder21", "content.json"));
+        
assertFalse(fsroot.getChild("folder1/file1a.txt").listChildren().hasNext());
     }
 
 }

Added: 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/InvalidRootFolderTest.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/InvalidRootFolderTest.java?rev=1783888&view=auto
==============================================================================
--- 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/InvalidRootFolderTest.java
 (added)
+++ 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/InvalidRootFolderTest.java
 Tue Feb 21 13:54:37 2017
@@ -0,0 +1,65 @@
+/*
+ * 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.fsprovider.internal;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.fsprovider.internal.TestUtils.RegisterFsResourcePlugin;
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.apache.sling.testing.mock.sling.junit.SlingContextBuilder;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Test with invalid fs folder.
+ */
+public class InvalidRootFolderTest {
+
+    private Resource fsroot;
+
+    @Rule
+    public SlingContext context = new 
SlingContextBuilder(ResourceResolverType.JCR_MOCK)
+        .plugin(new RegisterFsResourcePlugin("provider.file", 
"/invalid-folder"))
+        .build();
+
+    @Before
+    public void setUp() {
+        fsroot = context.resourceResolver().getResource("/fs-test");
+    }
+
+    @Test
+    public void testFolders() {
+        assertNull(fsroot.getChild("folder1"));
+    }
+
+    @Test
+    public void testFiles() {
+        assertNull(fsroot.getChild("folder1/file1a.txt"));
+    }
+
+    @Test
+    public void testListChildren() {
+        assertFalse(fsroot.listChildren().hasNext());
+    }
+
+}

Propchange: 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/InvalidRootFolderTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/InvalidRootFolderTest.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Tue Feb 21 13:54:37 2017
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/InvalidRootFolderTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/JcrMixedTest.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/JcrMixedTest.java?rev=1783888&r1=1783887&r2=1783888&view=diff
==============================================================================
--- 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/JcrMixedTest.java
 (original)
+++ 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/JcrMixedTest.java
 Tue Feb 21 13:54:37 2017
@@ -18,7 +18,6 @@
  */
 package org.apache.sling.fsprovider.internal;
 
-import static 
org.apache.sling.fsprovider.internal.TestUtils.REGISTER_FSRESOURCE_PLUGIN;
 import static org.apache.sling.fsprovider.internal.TestUtils.assertFile;
 import static org.hamcrest.Matchers.not;
 import static org.junit.Assert.assertThat;
@@ -27,6 +26,7 @@ import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 
 import org.apache.sling.api.resource.Resource;
+import org.apache.sling.fsprovider.internal.TestUtils.RegisterFsResourcePlugin;
 import org.apache.sling.hamcrest.ResourceMatchers;
 import org.apache.sling.testing.mock.sling.ResourceResolverType;
 import org.apache.sling.testing.mock.sling.junit.SlingContext;
@@ -45,7 +45,7 @@ public class JcrMixedTest {
 
     @Rule
     public SlingContext context = new 
SlingContextBuilder(ResourceResolverType.JCR_MOCK)
-        .plugin(REGISTER_FSRESOURCE_PLUGIN)
+        .plugin(new RegisterFsResourcePlugin())
         .build();
 
     @Before
@@ -84,7 +84,7 @@ public class JcrMixedTest {
         assertFile(fsroot, "folder1/file1a.txt", "file1a");
         assertFile(fsroot, "folder1/file1b.txt", "file1b");
         assertFile(fsroot, "folder1/folder11/file11a.txt", "file11a");
-        assertFile(fsroot, "folder2/file2a.txt", "file2a");
+        assertFile(fsroot, "folder2/content.json", null);
 
         // do not expected properties from JCR for files
         Resource file1a = fsroot.getChild("folder1/file1a.txt");

Added: 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/JsonContentTest.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/JsonContentTest.java?rev=1783888&view=auto
==============================================================================
--- 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/JsonContentTest.java
 (added)
+++ 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/JsonContentTest.java
 Tue Feb 21 13:54:37 2017
@@ -0,0 +1,234 @@
+/*
+ * 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.fsprovider.internal;
+
+import static org.apache.sling.fsprovider.internal.TestUtils.assertFile;
+import static org.apache.sling.fsprovider.internal.TestUtils.assertFolder;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.PropertyIterator;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.fsprovider.internal.TestUtils.RegisterFsResourcePlugin;
+import org.apache.sling.hamcrest.ResourceMatchers;
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.apache.sling.testing.mock.sling.junit.SlingContextBuilder;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Test access to files and folders from filesystem.
+ */
+public class JsonContentTest {
+
+    private Resource root;
+    private Resource fsroot;
+
+    @Rule
+    public SlingContext context = new 
SlingContextBuilder(ResourceResolverType.JCR_MOCK)
+        .plugin(new RegisterFsResourcePlugin("provider.json.content", true))
+        .build();
+
+    @Before
+    public void setUp() {
+        root = context.resourceResolver().getResource("/");
+        fsroot = context.resourceResolver().getResource("/fs-test");
+    }
+
+    @Test
+    public void testFolders() {
+        assertFolder(fsroot, "folder1");
+        assertFolder(fsroot, "folder1/folder11");
+        assertFolder(fsroot, "folder2");
+    }
+
+    @Test
+    public void testFiles() {
+        assertFile(fsroot, "folder1/file1a.txt", "file1a");
+        assertFile(fsroot, "folder1/file1b.txt", "file1b");
+        assertFile(fsroot, "folder1/folder11/file11a.txt", "file11a");
+        assertNull(fsroot.getChild("folder2/content.json"));
+    }
+
+    @Test
+    public void testListChildren() {
+        assertThat(root, ResourceMatchers.containsChildren("fs-test"));
+        assertThat(fsroot, ResourceMatchers.hasChildren("folder1", "folder2"));
+        assertThat(fsroot.getChild("folder1"), 
ResourceMatchers.hasChildren("folder11", "file1a.txt", "file1b.txt"));
+        assertThat(fsroot.getChild("folder2"), 
ResourceMatchers.hasChildren("folder21", "content"));
+    }
+
+    @Test
+    public void testJsonContent_Root() {
+        Resource underTest = fsroot.getChild("folder2/content");
+        assertNotNull(underTest);
+        assertEquals("app:Page", 
underTest.getValueMap().get("jcr:primaryType", String.class));
+        assertEquals("app:Page", underTest.getResourceType());
+        assertThat(underTest, ResourceMatchers.hasChildren("jcr:content"));
+    }
+
+    @Test
+    public void testJsonContent_Level1() {
+        Resource underTest = fsroot.getChild("folder2/content/jcr:content");
+        assertNotNull(underTest);
+        assertEquals("app:PageContent", 
underTest.getValueMap().get("jcr:primaryType", String.class));
+        assertEquals("sample/components/homepage", 
underTest.getResourceType());
+        assertEquals("sample/components/supertype", 
underTest.getResourceSuperType());
+        assertThat(underTest, ResourceMatchers.hasChildren("par", "header", 
"newslist", "lead", "image", "carousel", "rightpar"));
+    }
+
+    @Test
+    public void testJsonContent_Level5() {
+        Resource underTest = 
fsroot.getChild("folder2/content/jcr:content/par/image/file/jcr:content");
+        assertNotNull(underTest);
+        assertEquals("nt:resource", 
underTest.getValueMap().get("jcr:primaryType", String.class));
+        assertFalse(underTest.listChildren().hasNext());
+    }
+
+    @Test
+    public void testJsonContent_Datatypes() {
+        Resource underTest = 
fsroot.getChild("folder2/content/toolbar/profiles/jcr:content");
+        ValueMap props = underTest.getValueMap();
+        
+        assertEquals("Profiles", props.get("jcr:title", String.class));
+        assertEquals(true, props.get("booleanProp", false));
+        assertEquals((Long)1234567890123L, props.get("longProp", Long.class));
+        assertEquals((Double)1.2345d, props.get("decimalProp", Double.class), 
0.00001d);
+        
+        assertArrayEquals(new String[] { "aa", "bb", "cc" }, 
props.get("stringPropMulti", String[].class));
+        assertArrayEquals(new Long[] { 1234567890123L, 55L }, 
props.get("longPropMulti", Long[].class));
+    }
+
+    @Test
+    public void testJsonContent_Datatypes_JCR() throws RepositoryException {
+        Resource underTest = 
fsroot.getChild("folder2/content/toolbar/profiles/jcr:content");
+        ValueMap props = underTest.getValueMap();
+        Node node = underTest.adaptTo(Node.class);
+        
+        assertEquals("/fs-test/folder2/content/toolbar/profiles/jcr:content", 
node.getPath());
+        assertEquals(6, node.getDepth());
+        assertTrue(node.isNodeType("app:PageContent"));
+        
+        assertTrue(node.hasProperty("jcr:title"));
+        assertEquals(PropertyType.STRING, 
node.getProperty("jcr:title").getType());
+        assertFalse(node.getProperty("jcr:title").isMultiple());
+        
assertEquals("/fs-test/folder2/content/toolbar/profiles/jcr:content/jcr:title", 
node.getProperty("jcr:title").getPath());
+        assertEquals("Profiles", node.getProperty("jcr:title").getString());
+        assertEquals(PropertyType.BOOLEAN, 
node.getProperty("booleanProp").getType());
+        assertEquals(true, node.getProperty("booleanProp").getBoolean());
+        assertEquals(PropertyType.LONG, 
node.getProperty("longProp").getType());
+        assertEquals(1234567890123L, node.getProperty("longProp").getLong());
+        assertEquals(PropertyType.DOUBLE, 
node.getProperty("decimalProp").getType());
+        assertEquals(1.2345d, node.getProperty("decimalProp").getDouble(), 
0.00001d);
+        
+        assertEquals(PropertyType.STRING, 
node.getProperty("stringPropMulti").getType());
+        assertTrue(node.getProperty("stringPropMulti").isMultiple());
+        Value[] stringPropMultiValues = 
node.getProperty("stringPropMulti").getValues();
+        assertEquals(3, stringPropMultiValues.length);
+        assertEquals("aa", stringPropMultiValues[0].getString());
+        assertEquals("bb", stringPropMultiValues[1].getString());
+        assertEquals("cc", stringPropMultiValues[2].getString());
+
+        assertEquals(PropertyType.LONG, 
node.getProperty("longPropMulti").getType());
+        assertTrue(node.getProperty("longPropMulti").isMultiple());
+        Value[] longPropMultiValues = 
node.getProperty("longPropMulti").getValues();
+        assertEquals(2, longPropMultiValues.length);
+        assertEquals(1234567890123L, longPropMultiValues[0].getLong());
+        assertEquals(55L, longPropMultiValues[1].getLong());
+        
+        // assert property iterator
+        Set<String> propertyNames = new HashSet<>();
+        PropertyIterator propertyIterator = node.getProperties();
+        while (propertyIterator.hasNext()) {
+            propertyNames.add(propertyIterator.nextProperty().getName());
+        }
+        assertTrue(props.keySet().containsAll(propertyNames));
+
+        // assert node iterator
+        Set<String> nodeNames = new HashSet<>();
+        NodeIterator nodeIterator = node.getNodes();
+        while (nodeIterator.hasNext()) {
+            nodeNames.add(nodeIterator.nextNode().getName());
+        }
+        assertEquals(ImmutableSet.of("par", "rightpar"), nodeNames);
+        
+        // node hierarchy
+        assertTrue(node.hasNode("rightpar"));
+        Node rightpar = node.getNode("rightpar");
+        assertEquals(7, rightpar.getDepth());
+        Node parent = rightpar.getParent();
+        assertTrue(node.isSame(parent));
+        Node ancestor = (Node)rightpar.getAncestor(4);
+        assertEquals(underTest.getParent().getPath(), ancestor.getPath());     
   
+    }
+
+    @Test
+    public void testJsonContent_InvalidPath() {
+        Resource underTest = 
fsroot.getChild("folder2/content/jcr:content/xyz");
+        assertNull(underTest);
+    }
+
+    @Test
+    public void testJcrMixedContent() throws RepositoryException {
+        // prepare mixed JCR content
+        Node node = root.adaptTo(Node.class);
+        Node fstest = node.addNode("fs-test", "nt:folder");
+        fstest.addNode("folder3", "nt:folder");
+
+        assertNull(fsroot.getChild("folder3"));
+    }
+
+    @Test
+    public void testFolder2ChildNodes() throws RepositoryException {
+        Resource folder2 = fsroot.getChild("folder2");
+        List<Resource> children = ImmutableList.copyOf(folder2.listChildren());
+        
+        assertEquals(2, children.size());
+        Resource child1 = children.get(0);
+        assertEquals("content", child1.getName());
+        assertEquals("app:Page", child1.getResourceType());
+        assertEquals("app:Page", child1.getValueMap().get("jcr:primaryType", 
String.class));
+
+        Resource child2 = children.get(1);
+        assertEquals("folder21", child2.getName());
+        assertEquals("nt:folder", child2.getValueMap().get("jcr:primaryType", 
String.class));
+    }
+
+}

Propchange: 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/JsonContentTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/JsonContentTest.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Tue Feb 21 13:54:37 2017
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/JsonContentTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/TestUtils.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/TestUtils.java?rev=1783888&r1=1783887&r2=1783888&view=diff
==============================================================================
--- 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/TestUtils.java
 (original)
+++ 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/TestUtils.java
 Tue Feb 21 13:54:37 2017
@@ -28,25 +28,33 @@ import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.CharEncoding;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.hamcrest.ResourceMatchers;
+import org.apache.sling.testing.mock.osgi.MapUtil;
 import org.apache.sling.testing.mock.osgi.context.AbstractContextPlugin;
-import org.apache.sling.testing.mock.osgi.context.ContextPlugin;
 import org.apache.sling.testing.mock.sling.context.SlingContextImpl;
 
 class TestUtils {
 
-    public static ContextPlugin<SlingContextImpl> REGISTER_FSRESOURCE_PLUGIN = 
new AbstractContextPlugin<SlingContextImpl>() {
+    public static class RegisterFsResourcePlugin extends 
AbstractContextPlugin<SlingContextImpl> {
+        private final Map<String,Object> props;
+        public RegisterFsResourcePlugin(Object... props) {
+            this.props = MapUtil.toMap(props); 
+        }
         @Override
         public void beforeSetUp(SlingContextImpl context) throws Exception {
-            context.registerInjectActivateService(new FsResourceProvider(),
-                    "provider.file", "src/test/resources/fs-test",
-                    "provider.root", "/fs-test",
-                    "provider.checkinterval", 0);
+            Map<String,Object> config = new HashMap<>();
+            config.put("provider.file", "src/test/resources/fs-test");
+            config.put("provider.root", "/fs-test");
+            config.put("provider.checkinterval", 0);
+            config.putAll(props);
+            context.registerInjectActivateService(new FsResourceProvider(), 
config);
         }
     };
 
@@ -69,19 +77,21 @@ class TestUtils {
         assertThat(file, ResourceMatchers.props("jcr:primaryType", "nt:file"));
         assertEquals("nt:file", file.getResourceType());
         
-        try {
-            try (InputStream is = file.adaptTo(InputStream.class)) {
-                String data = IOUtils.toString(is, CharEncoding.UTF_8);
-                assertEquals(content, data);
-            }
-        }
-        catch (IOException ex) {
-            throw new RuntimeException(ex);
-        }
-
         assertNull(file.getResourceSuperType());
         assertEquals(file.getName(), file.adaptTo(File.class).getName());
         assertTrue(StringUtils.contains(file.adaptTo(URL.class).toString(), 
file.getName()));
+        
+        if (content != null) {
+            try {
+                try (InputStream is = file.adaptTo(InputStream.class)) {
+                    String data = IOUtils.toString(is, CharEncoding.UTF_8);
+                    assertEquals(content, data);
+                }
+            }
+            catch (IOException ex) {
+                throw new RuntimeException(ex);
+            }
+        }
     }    
 
 }

Added: 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/ContentFileTest.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/ContentFileTest.java?rev=1783888&view=auto
==============================================================================
--- 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/ContentFileTest.java
 (added)
+++ 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/ContentFileTest.java
 Tue Feb 21 13:54:37 2017
@@ -0,0 +1,112 @@
+/*
+ * 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.fsprovider.internal.mapper;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.util.Map;
+
+import org.apache.sling.api.resource.ValueMap;
+import org.junit.Test;
+
+public class ContentFileTest {
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testRootContent() {
+        File file = new 
File("src/test/resources/fs-test/folder2/content.json");
+        
+        ContentFile underTest = new ContentFile(file, null);
+        assertEquals(file, underTest.getFile());
+        assertNull(underTest.getSubPath());
+        
+        assertTrue(underTest.hasContent());
+
+        Map<String,Object> content = 
(Map<String,Object>)underTest.getContent();
+        assertEquals("app:Page", content.get("jcr:primaryType"));
+        assertEquals("app:PageContent", 
((Map<String,Object>)content.get("jcr:content")).get("jcr:primaryType"));
+
+        ValueMap props = underTest.getValueMap();
+        assertEquals("app:Page", props.get("jcr:primaryType"));
+        assertNull(props.get("jcr:content"));
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testContentLevel1() {
+        File file = new 
File("src/test/resources/fs-test/folder2/content.json");
+        
+        ContentFile underTest = new ContentFile(file, "jcr:content");
+        assertEquals(file, underTest.getFile());
+        assertEquals("jcr:content", underTest.getSubPath());
+        
+        assertTrue(underTest.hasContent());
+
+        Map<String,Object> content = 
(Map<String,Object>)underTest.getContent();
+        assertEquals("app:PageContent", content.get("jcr:primaryType"));
+
+        ValueMap props = underTest.getValueMap();
+        assertEquals("app:PageContent", props.get("jcr:primaryType"));
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testContentLevel5() {
+        File file = new 
File("src/test/resources/fs-test/folder2/content.json");
+        
+        ContentFile underTest = new ContentFile(file, 
"jcr:content/par/image/file/jcr:content");
+        assertEquals(file, underTest.getFile());
+        assertEquals("jcr:content/par/image/file/jcr:content", 
underTest.getSubPath());
+        
+        assertTrue(underTest.hasContent());
+
+        Map<String,Object> content = 
(Map<String,Object>)underTest.getContent();
+        assertEquals("nt:resource", content.get("jcr:primaryType"));
+
+        ValueMap props = underTest.getValueMap();
+        assertEquals("nt:resource", props.get("jcr:primaryType"));
+    }
+
+    @Test
+    public void testContentProperty() {
+        File file = new 
File("src/test/resources/fs-test/folder2/content.json");
+        
+        ContentFile underTest = new ContentFile(file, "jcr:content/jcr:title");
+        assertEquals(file, underTest.getFile());
+        assertEquals("jcr:content/jcr:title", underTest.getSubPath());
+        
+        assertTrue(underTest.hasContent());
+
+        assertEquals("English", underTest.getContent());
+
+        assertTrue(underTest.getValueMap().isEmpty());
+    }
+
+    @Test
+    public void testInvalidFile() {
+        File file = new File("src/test/resources/fs-test/folder1/file1a.txt");
+        ContentFile underTest = new ContentFile(file, null);
+        assertFalse(underTest.hasContent());
+    }
+
+}

Propchange: 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/ContentFileTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/ContentFileTest.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Tue Feb 21 13:54:37 2017
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/ContentFileTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/ValueMapUtilTest.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/ValueMapUtilTest.java?rev=1783888&view=auto
==============================================================================
--- 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/ValueMapUtilTest.java
 (added)
+++ 
sling/trunk/bundles/extensions/fsresource/src/test/java/org/apache/sling/fsprovider/internal/mapper/ValueMapUtilTest.java
 Tue Feb 21 13:54:37 2017
@@ -0,0 +1,55 @@
+/*
+ * 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.fsprovider.internal.mapper;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.sling.api.resource.ValueMap;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+public class ValueMapUtilTest {
+
+    @Test
+    public void testToValueMap() {
+        Map<String,Object> content = new HashMap<>();
+        content.put("stringProp", "abc");
+        content.put("intProp", 123);
+        content.put("childNode", ImmutableMap.<String,Object>of());
+        content.put("stringArray", new String[] { "a", "b", "c" });
+        content.put("stringList", ImmutableList.of("ab", "cd"));
+        content.put("intList", ImmutableList.of(12, 34));
+        
+        ValueMap props = ValueMapUtil.toValueMap(content);
+        assertEquals("abc", props.get("stringProp", String.class));
+        assertEquals((Integer)123, props.get("intProp", 0));
+        assertNull(props.get("childNode"));
+        assertArrayEquals(new String[] { "a", "b", "c" }, 
props.get("stringArray", String[].class));
+        assertArrayEquals(new String[] { "ab", "cd" }, props.get("stringList", 
String[].class));
+        assertArrayEquals(new Integer[] { 12, 34 }, props.get("intList", 
Integer[].class));
+    }
+
+}


Reply via email to