You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ss...@apache.org on 2017/02/28 15:40:57 UTC

svn commit: r1784765 [2/5] - in /sling/branches/fsresource-1.1.x: ./ src/main/java/org/apache/sling/fsprovider/internal/ src/main/java/org/apache/sling/fsprovider/internal/mapper/ src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/ src/main/...

Added: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/FileResource.java
URL: http://svn.apache.org/viewvc/sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/FileResource.java?rev=1784765&view=auto
==============================================================================
--- sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/FileResource.java (added)
+++ sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/FileResource.java Tue Feb 28 15:40:56 2017
@@ -0,0 +1,206 @@
+/*
+ * 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 java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import org.apache.sling.adapter.annotations.Adaptable;
+import org.apache.sling.adapter.annotations.Adapter;
+import org.apache.sling.api.resource.AbstractResource;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceMetadata;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.api.wrappers.ValueMapDecorator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The <code>FsResource</code> represents a file system file or folder as
+ * a Sling Resource.
+ */
+@Adaptable(adaptableClass=Resource.class, adapters={
+    @Adapter({File.class, URL.class}),
+    @Adapter(condition="If the resource is an FsResource and is a readable file.", value=InputStream.class)
+})
+public final class FileResource extends AbstractResource {
+
+    /**
+     * The resource type for file system files mapped into the resource tree by
+     * the {@link FsResourceProvider} (value is "nt:file").
+     */
+    public static final String RESOURCE_TYPE_FILE = "nt:file";
+
+    /**
+     * The resource type for file system folders mapped into the resource tree
+     * by the {@link FsResourceProvider} (value is "nt:folder").
+     */
+    public static final String RESOURCE_TYPE_FOLDER = "nt:folder";
+
+    // the owning resource resolver
+    private final ResourceResolver resolver;
+
+    // the path of this resource in the resource tree
+    private final String resourcePath;
+
+    // the file wrapped by this instance
+    private final File file;
+
+    // the resource type, assigned on demand
+    private String resourceType;
+
+    // the resource metadata, assigned on demand
+    private ResourceMetadata metaData;
+
+    private static final Logger log = LoggerFactory.getLogger(FileResource.class);
+    
+    /**
+     * Creates an instance of this Filesystem resource.
+     *
+     * @param resolver The owning resource resolver
+     * @param resourcePath The resource path in the resource tree
+     * @param file The wrapped file
+     */
+    FileResource(ResourceResolver resolver, String resourcePath, File file) {
+        this.resolver = resolver;
+        this.resourcePath = resourcePath;
+        this.file = file;
+    }
+
+    /**
+     * Returns the path of this resource
+     */
+    public String getPath() {
+        return resourcePath;
+    }
+
+    /**
+     * Returns the resource meta data for this resource containing the file
+     * length, last modification time and the resource path (same as
+     * {@link #getPath()}).
+     */
+    public ResourceMetadata getResourceMetadata() {
+        if (metaData == null) {
+            metaData = new ResourceMetadata();
+            metaData.setContentLength(file.length());
+            metaData.setModificationTime(file.lastModified());
+            metaData.setResolutionPath(resourcePath);
+            if ( this.file.isDirectory() ) {
+                metaData.put(ResourceMetadata.INTERNAL_CONTINUE_RESOLVING, Boolean.TRUE);
+            }
+        }
+        return metaData;
+    }
+
+    /**
+     * Returns the resource resolver which cause this resource object to be
+     * created.
+     */
+    public ResourceResolver getResourceResolver() {
+        return resolver;
+    }
+
+    /**
+     * Returns <code>null</code>}
+     */
+    public String getResourceSuperType() {
+        return null;
+    }
+
+    /**
+     * Returns {@link #RESOURCE_TYPE_FILE} if this resource
+     * wraps a file. Otherwise {@link #RESOURCE_TYPE_FOLDER}
+     * is returned.
+     */
+    public String getResourceType() {
+        if (resourceType == null) {
+            resourceType = file.isFile() ? RESOURCE_TYPE_FILE : RESOURCE_TYPE_FOLDER;
+        }
+        return resourceType;
+    }
+
+    /**
+     * Returns an adapter for this resource. This implementation supports
+     * <code>File</code>, <code>InputStream</code> and <code>URL</code>
+     * plus those supported by the adapter manager.
+     */
+    @Override
+    @SuppressWarnings("unchecked")
+    public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
+        if (type == File.class) {
+            return (AdapterType) file;
+        }
+        else if (type == InputStream.class) {
+            if (!file.isDirectory() && file.canRead()) {
+                try {
+                    return (AdapterType) new FileInputStream(file);
+                }
+                catch (IOException ioe) {
+                    log.info("adaptTo: Cannot open a stream on the file " + file, ioe);
+                }
+            }
+            else {
+                log.debug("adaptTo: File {} is not a readable file", file);
+            }
+        }
+        else if (type == URL.class) {
+            try {
+                return (AdapterType) file.toURI().toURL();
+            }
+            catch (MalformedURLException mue) {
+                log.info("adaptTo: Cannot convert the file path " + file + " to an URL", mue);
+            }
+
+        }
+        else if (type == ValueMap.class) {
+            // this resource simulates nt:file/nt:folder behavior by returning it as resource type
+            // we should simulate the corresponding JCR properties in a value map as well
+            if (file.exists() && file.canRead()) {
+                Map<String,Object> props = new HashMap<String, Object>();
+                props.put("jcr:primaryType", getResourceType());
+                props.put("jcr:createdBy", "system");
+                Calendar lastModifed = Calendar.getInstance();
+                lastModifed.setTimeInMillis(file.lastModified());
+                props.put("jcr:created", lastModifed);
+                return (AdapterType) new ValueMapDecorator(props);
+            }
+        }
+        return super.adaptTo(type);
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
+                .append("path", resourcePath)
+                .append("file", file.getPath())
+                .append("resourceType", getResourceType())
+                .build();
+    }
+
+}

Propchange: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/FileResource.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/FileResource.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Tue Feb 28 15:40:56 2017
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/FileResource.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/FileResourceMapper.java
URL: http://svn.apache.org/viewvc/sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/FileResourceMapper.java?rev=1784765&view=auto
==============================================================================
--- sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/FileResourceMapper.java (added)
+++ sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/FileResourceMapper.java Tue Feb 28 15:40:56 2017
@@ -0,0 +1,145 @@
+/*
+ * 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 java.io.File;
+import java.util.Iterator;
+
+import org.apache.commons.collections.IteratorUtils;
+import org.apache.commons.collections.Predicate;
+import org.apache.commons.collections.Transformer;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.fsprovider.internal.ContentFileExtensions;
+import org.apache.sling.fsprovider.internal.FsResourceMapper;
+
+public final class FileResourceMapper implements FsResourceMapper {
+
+    // The location in the resource tree where the resources are mapped
+    private final String providerRoot;
+
+    // providerRoot + "/" to be used for prefix matching of paths
+    private final String providerRootPrefix;
+
+    // The "root" file or folder in the file system
+    private final File providerFile;
+    
+    private final ContentFileExtensions contentFileExtensions;
+    
+    public FileResourceMapper(String providerRoot, File providerFile, ContentFileExtensions contentFileExtensions) {
+        this.providerRoot = providerRoot;
+        this.providerRootPrefix = providerRoot.concat("/");
+        this.providerFile = providerFile;
+        this.contentFileExtensions = contentFileExtensions;
+    }
+    
+    @Override
+    public Resource getResource(final ResourceResolver resolver, final String resourcePath) {
+        File file = getFile(resourcePath);
+        if (file != null) {
+            return new FileResource(resolver, resourcePath, file);
+        }
+        else {
+            return null;
+        }
+    }
+    
+    @SuppressWarnings("unchecked")
+    @Override
+    public Iterator<Resource> getChildren(final ResourceResolver resolver, final Resource parent) {
+        final String parentPath = parent.getPath();
+        File parentFile = parent.adaptTo(File.class);
+
+        // not a FsResource, try to create one from the resource
+        if (parentFile == null) {
+            // if the parent path is at or below the provider root, get
+            // the respective file
+            parentFile = getFile(parentPath);
+
+            // if the parent path is actually the parent of the provider
+            // root, return a single element iterator just containing the
+            // provider file, unless the provider file is a directory and
+            // a repository item with the same path actually exists
+            if (parentFile == null) {
+
+                if (providerFile.exists() && !StringUtils.startsWith(parentPath, providerRoot)) {
+                    String parentPathPrefix = parentPath.concat("/");
+                    if (providerRoot.startsWith(parentPathPrefix)) {
+                        String relPath = providerRoot.substring(parentPathPrefix.length());
+                        if (relPath.indexOf('/') < 0) {
+                            Resource res = new FileResource(resolver, providerRoot, providerFile);
+                            return IteratorUtils.singletonIterator(res);
+                        }
+                    }
+                }
+
+                // no children here
+                return null;
+            }
+        }
+        
+        // ensure parent is a directory
+        if (!parentFile.isDirectory()) {
+            return null;
+        }
+
+        Iterator<File> children = IteratorUtils.filteredIterator(IteratorUtils.arrayIterator(parentFile.listFiles()), new Predicate() {
+            @Override
+            public boolean evaluate(Object object) {
+                File file = (File)object;
+                return !contentFileExtensions.matchesSuffix(file);
+            }
+        });
+        if (!children.hasNext()) {
+            return null;
+        }
+        return IteratorUtils.transformedIterator(children, new Transformer() {
+            @Override
+            public Object transform(Object input) {
+                File file = (File)input;
+                String path = parentPath + "/" + file.getName();
+                return new FileResource(resolver, path, file);
+            }
+        });
+    }
+
+    /**
+     * Returns a file corresponding to the given absolute resource tree path. If
+     * the path equals the configured provider root, the provider root file is
+     * returned. If the path starts with the configured provider root, a file is
+     * returned relative to the provider root file whose relative path is the
+     * remains of the resource tree path without the provider root path.
+     * Otherwise <code>null</code> is returned.
+     */
+    private File getFile(String path) {
+        if (path.equals(providerRoot)) {
+            return providerFile;
+        }
+        if (path.startsWith(providerRootPrefix)) {
+            String relPath = path.substring(providerRootPrefix.length());
+            File file = new File(providerFile, relPath);
+            if (file.exists() && !contentFileExtensions.matchesSuffix(file)) {
+                return file;
+            }
+        }
+        return null;
+    }
+    
+}

Propchange: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/FileResourceMapper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/FileResourceMapper.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Tue Feb 28 15:40:56 2017
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/FileResourceMapper.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/ValueMapUtil.java
URL: http://svn.apache.org/viewvc/sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/ValueMapUtil.java?rev=1784765&view=auto
==============================================================================
--- sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/ValueMapUtil.java (added)
+++ sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/ValueMapUtil.java Tue Feb 28 15:40:56 2017
@@ -0,0 +1,66 @@
+/*
+ * 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 java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jcr.nodetype.NodeType;
+
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.api.wrappers.ValueMapDecorator;
+
+final class ValueMapUtil {
+    
+    private ValueMapUtil() {
+        // static methods only
+    }
+    
+    /**
+     * Convert map to value map.
+     * @param content Content map.
+     * @return Value map.
+     */
+    public static ValueMap toValueMap(Map<String,Object> content) {
+        Map<String,Object> props = new HashMap<>();
+        
+        for (Map.Entry<String, Object> entry : ((Map<String,Object>)content).entrySet()) {
+            if (entry.getValue() instanceof Map) {
+                // skip child resources
+                continue;
+            }
+            else if (entry.getValue() instanceof Collection) {
+                // convert lists to arrays
+                props.put(entry.getKey(), ((Collection)entry.getValue()).toArray());
+            }
+            else {
+                props.put(entry.getKey(), entry.getValue());
+            }
+        }
+        
+        // fallback to default jcr:primaryType is none is set
+        if (!props.containsKey("jcr:primaryType")) {
+            props.put("jcr:primaryType", NodeType.NT_UNSTRUCTURED);
+        }
+        
+        return new ValueMapDecorator(props);
+    }
+
+}

Propchange: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/ValueMapUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/ValueMapUtil.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Tue Feb 28 15:40:56 2017
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/ValueMapUtil.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsItem.java
URL: http://svn.apache.org/viewvc/sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsItem.java?rev=1784765&view=auto
==============================================================================
--- sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsItem.java (added)
+++ sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsItem.java Tue Feb 28 15:40:56 2017
@@ -0,0 +1,161 @@
+/*
+ * 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 javax.jcr.AccessDeniedException;
+import javax.jcr.InvalidItemStateException;
+import javax.jcr.Item;
+import javax.jcr.ItemExistsException;
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.ItemVisitor;
+import javax.jcr.Node;
+import javax.jcr.ReferentialIntegrityException;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.lock.LockException;
+import javax.jcr.nodetype.ConstraintViolationException;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
+import javax.jcr.version.VersionException;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.fsprovider.internal.mapper.ContentFile;
+
+/**
+ * Simplified implementation of read-only content access via the JCR API.
+ */
+abstract class FsItem implements Item {
+    
+    protected final ContentFile contentFile;
+    protected final ResourceResolver resolver;
+    protected final ValueMap props;
+    
+    public FsItem(ContentFile contentFile, ResourceResolver resolver) {
+        this.contentFile = contentFile;
+        this.resolver = resolver;
+        this.props = contentFile.getValueMap();
+    }
+
+    @Override
+    public String getPath() throws RepositoryException {
+        if (contentFile.getSubPath() == null) {
+            return contentFile.getPath();
+        }
+        else {
+            return contentFile.getPath() + "/" + contentFile.getSubPath();
+        }
+    }
+
+    @Override
+    public Item getAncestor(int depth) throws ItemNotFoundException, AccessDeniedException, RepositoryException {
+        String path;
+        if (depth == 0) {
+            path = "/";
+        }
+        else {
+            String[] pathParts = StringUtils.splitPreserveAllTokens(getPath(), "/");
+            path = StringUtils.join(pathParts, "/", 0, depth + 1);
+        }
+        Resource resource = resolver.getResource(path);
+        if (resource != null) {
+            Node refNode = resource.adaptTo(Node.class);
+            if (refNode != null) {
+                return refNode;
+            }
+        }
+        throw new ItemNotFoundException();
+    }
+
+    @Override
+    public int getDepth() throws RepositoryException {
+        if (StringUtils.equals("/", getPath())) {
+            return 0;
+        } else {
+            return StringUtils.countMatches(getPath(), "/");
+        }
+    }
+
+    @Override
+    public Session getSession() throws RepositoryException {
+        return resolver.adaptTo(Session.class);
+    }
+
+    @Override
+    public boolean isNode() {
+        return (this instanceof Node);
+    }
+
+    @Override
+    public boolean isNew() {
+        return false;
+    }
+
+    @Override
+    public boolean isModified() {
+        return false;
+    }
+
+    @Override
+    public boolean isSame(Item otherItem) throws RepositoryException {
+        return StringUtils.equals(getPath(), otherItem.getPath());
+    }
+
+    @Override
+    public void accept(ItemVisitor visitor) throws RepositoryException {
+        // do nothing
+    }
+    
+    @Override
+    public String toString() {
+        try {
+            return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
+                    .append("path", getPath())
+                    .build();
+        }
+        catch (RepositoryException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+    
+    
+    // --- unsupported methods ---
+
+    @Override
+    public void save() throws AccessDeniedException, ItemExistsException, ConstraintViolationException,
+            InvalidItemStateException, ReferentialIntegrityException, VersionException, LockException,
+            NoSuchNodeTypeException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void refresh(boolean keepChanges) throws InvalidItemStateException, RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void remove() throws VersionException, LockException, ConstraintViolationException, AccessDeniedException,
+            RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+}

Propchange: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsItem.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsItem.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Tue Feb 28 15:40:56 2017
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsItem.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNode.java
URL: http://svn.apache.org/viewvc/sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNode.java?rev=1784765&view=auto
==============================================================================
--- sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNode.java (added)
+++ sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNode.java Tue Feb 28 15:40:56 2017
@@ -0,0 +1,549 @@
+/*
+ * 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;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceUtil;
+import org.apache.sling.fsprovider.internal.mapper.ContentFile;
+
+/**
+ * Simplified implementation of read-only content access via the JCR API.
+ */
+public final class FsNode extends FsItem implements Node {
+    
+    public FsNode(ContentFile contentFile, ResourceResolver resolver) {
+        super(contentFile, resolver);
+    }
+    
+    private String getPrimaryTypeName() {
+        return props.get("jcr:primaryType", String.class);
+    }
+    
+    private String[] getMixinTypeNames() {
+        return props.get("jcr:mixinTypes", new String[0]);
+    }
+    
+    @Override
+    public String getName() throws RepositoryException {
+        if (contentFile.getSubPath() == null) {
+            return ResourceUtil.getName(contentFile.getPath());
+        }
+        else {
+            return ResourceUtil.getName(contentFile.getSubPath());
+        }
+    }
+
+    @Override
+    public Node getParent() throws ItemNotFoundException, AccessDeniedException, RepositoryException {
+        return getNode(ResourceUtil.getParent(getPath()));
+    }
+    
+    @Override
+    public Node getNode(String relPath) throws PathNotFoundException, RepositoryException {
+        if (relPath == null) {
+            throw new PathNotFoundException();
+        }
+        
+        // get absolute node path
+        String path = relPath;
+        if (!StringUtils.startsWith(path,  "/")) {
+            path = ResourceUtil.normalize(getPath() + "/" + relPath);
+        }
+
+        if (StringUtils.equals(path, contentFile.getPath()) || StringUtils.startsWith(path, contentFile.getPath() + "/")) {
+            // node is contained in content file
+            String subPath;
+            if (StringUtils.equals(path, contentFile.getPath())) {
+                subPath = null;
+            }
+            else {
+                subPath = path.substring(contentFile.getPath().length() + 1);
+            }
+            ContentFile referencedFile = contentFile.navigateTo(subPath);
+            if (referencedFile.hasContent()) {
+                return new FsNode(referencedFile, resolver);
+            }
+        }
+        else {
+            // node is outside content file
+            Node refNode = null;
+            Resource resource = resolver.getResource(path);
+            if (resource != null) {
+                refNode = resource.adaptTo(Node.class);
+                if (refNode != null) {
+                    return refNode;
+                }
+            }
+        }
+        throw new PathNotFoundException(relPath);
+    }
+
+    @Override
+    public NodeIterator getNodes() throws RepositoryException {
+        return new FsNodeIterator(contentFile, resolver);
+    }
+
+    @Override
+    public Property getProperty(String relPath) throws PathNotFoundException, RepositoryException {
+        if (props.containsKey(relPath)) {
+            return new FsProperty(contentFile, resolver, relPath, this);
+        }
+        throw new PathNotFoundException(relPath);
+    }
+
+    @Override
+    public PropertyIterator getProperties() throws RepositoryException {
+        return new FsPropertyIterator(props.keySet().iterator(), contentFile, resolver, 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 {
+        try {
+            getNode(relPath);
+            return true;
+        }
+        catch (RepositoryException ex) {
+            return false;
+        }
+    }
+
+    @Override
+    public boolean hasProperty(String relPath) throws RepositoryException {
+        return props.containsKey(relPath);
+    }
+
+    @Override
+    public boolean hasNodes() throws RepositoryException {
+        return getNodes().hasNext();
+    }
+
+    @Override
+    public boolean hasProperties() throws RepositoryException {
+        return !props.isEmpty();
+    }
+
+    @Override
+    public boolean isNodeType(String nodeTypeName) throws RepositoryException {
+        return StringUtils.equals(nodeTypeName, getPrimaryTypeName());
+    }
+
+    @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;
+    }
+
+    @Override
+    public NodeType getPrimaryNodeType() throws RepositoryException {
+        return new FsNodeType(getPrimaryTypeName(), false);
+    }
+
+    @Override
+    public NodeType[] getMixinNodeTypes() throws RepositoryException {
+        String[] mixinTypeNames = getMixinTypeNames();
+        NodeType[] mixinTypes = new NodeType[mixinTypeNames.length];
+        for (int i=0; i<mixinTypeNames.length; i++) {
+            mixinTypes[i] = new FsNodeType(mixinTypeNames[i], true);
+        }
+        return mixinTypes;
+    }
+    
+
+    // --- 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 String getIdentifier() throws RepositoryException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int getIndex() 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/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNode.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNode.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Tue Feb 28 15:40:56 2017
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNode.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNodeIterator.java
URL: http://svn.apache.org/viewvc/sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNodeIterator.java?rev=1784765&view=auto
==============================================================================
--- sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNodeIterator.java (added)
+++ sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNodeIterator.java Tue Feb 28 15:40:56 2017
@@ -0,0 +1,98 @@
+/*
+ * 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 java.util.Map;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+
+import org.apache.commons.collections.IteratorUtils;
+import org.apache.commons.collections.Predicate;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.fsprovider.internal.mapper.ContentFile;
+
+/**
+ * Simplified implementation of read-only content access via the JCR API.
+ */
+class FsNodeIterator implements NodeIterator {
+    
+    private final ContentFile contentFile;
+    private final ResourceResolver resolver;
+    private final Iterator<Map.Entry<String,Map<String,Object>>> children;
+
+    @SuppressWarnings("unchecked")
+    public FsNodeIterator(ContentFile contentFile, ResourceResolver resolver) {
+        this.contentFile = contentFile;
+        this.resolver = resolver;
+        Map<String,Object> content = (Map<String,Object>)contentFile.getContent();
+        this.children = IteratorUtils.filteredIterator(content.entrySet().iterator(), new Predicate() {
+            @Override
+            public boolean evaluate(Object object) {
+                Map.Entry<String,Object> entry = (Map.Entry<String,Object>)object;
+                return (entry.getValue() instanceof Map);
+            }
+        });
+    }
+
+    public boolean hasNext() {
+        return children.hasNext();
+    }
+
+    public Object next() {
+        return nextNode();
+    }
+
+    @Override
+    public Node nextNode() {
+        Map.Entry<String,Map<String,Object>> nextEntry = children.next();
+        String subPath;
+        if (contentFile.getSubPath() == null) {
+            subPath = nextEntry.getKey();
+        }
+        else {
+            subPath = contentFile.getSubPath() + "/" + nextEntry.getKey();
+        }
+        return new FsNode(contentFile.navigateTo(subPath), resolver);
+    }
+
+    
+    // --- 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/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNodeIterator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNodeIterator.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Tue Feb 28 15:40:56 2017
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNodeIterator.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNodeType.java
URL: http://svn.apache.org/viewvc/sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNodeType.java?rev=1784765&view=auto
==============================================================================
--- sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNodeType.java (added)
+++ sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNodeType.java Tue Feb 28 15:40:56 2017
@@ -0,0 +1,157 @@
+/*
+ * 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 javax.jcr.Value;
+import javax.jcr.nodetype.NodeDefinition;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.nodetype.NodeTypeIterator;
+import javax.jcr.nodetype.PropertyDefinition;
+
+import org.apache.commons.lang3.StringUtils;
+
+class FsNodeType implements NodeType {
+    
+    private final String name;
+    private final boolean mixin;
+    
+    public FsNodeType(String name, boolean mixin) {
+        this.name = name;
+        this.mixin = mixin;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String[] getDeclaredSupertypeNames() {
+        return new String[0];
+    }
+
+    @Override
+    public boolean isAbstract() {
+        return false;
+    }
+
+    @Override
+    public boolean isMixin() {
+        return mixin;
+    }
+
+    @Override
+    public boolean hasOrderableChildNodes() {
+        return false;
+    }
+
+    @Override
+    public boolean isQueryable() {
+        return false;
+    }
+
+    @Override
+    public String getPrimaryItemName() {
+        return null;
+    }
+
+    @Override
+    public NodeType[] getSupertypes() {
+        return new NodeType[0];
+    }
+
+    @Override
+    public NodeType[] getDeclaredSupertypes() {
+        return new NodeType[0];
+    }
+
+    @Override
+    public boolean isNodeType(String nodeTypeName) {
+        return StringUtils.equals(name, nodeTypeName);
+    }
+
+
+    // --- unsupported methods ---    
+    
+    @Override
+    public PropertyDefinition[] getDeclaredPropertyDefinitions() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public NodeDefinition[] getDeclaredChildNodeDefinitions() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public NodeTypeIterator getSubtypes() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public NodeTypeIterator getDeclaredSubtypes() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public PropertyDefinition[] getPropertyDefinitions() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public NodeDefinition[] getChildNodeDefinitions() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean canSetProperty(String propertyName, Value value) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean canSetProperty(String propertyName, Value[] values) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean canAddChildNode(String childNodeName) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean canAddChildNode(String childNodeName, String nodeTypeName) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean canRemoveItem(String itemName) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean canRemoveNode(String nodeName) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean canRemoveProperty(String propertyName) {
+        throw new UnsupportedOperationException();
+    }
+
+}

Propchange: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNodeType.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNodeType.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Tue Feb 28 15:40:56 2017
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsNodeType.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsProperty.java
URL: http://svn.apache.org/viewvc/sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsProperty.java?rev=1784765&view=auto
==============================================================================
--- sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsProperty.java (added)
+++ sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsProperty.java Tue Feb 28 15:40:56 2017
@@ -0,0 +1,242 @@
+/*
+ * 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.ResourceResolver;
+import org.apache.sling.fsprovider.internal.mapper.ContentFile;
+
+/**
+ * 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(ContentFile contentFile, ResourceResolver resolver, String propertyName, Node node) {
+        super(contentFile, resolver);
+        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 super.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();
+    }
+    
+    @Override
+    public PropertyDefinition getDefinition() throws RepositoryException {
+        return new FsPropertyDefinition(propertyName);
+    }
+
+    
+    // --- 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 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/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsProperty.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsProperty.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Tue Feb 28 15:40:56 2017
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsProperty.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsPropertyDefinition.java
URL: http://svn.apache.org/viewvc/sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsPropertyDefinition.java?rev=1784765&view=auto
==============================================================================
--- sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsPropertyDefinition.java (added)
+++ sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsPropertyDefinition.java Tue Feb 28 15:40:56 2017
@@ -0,0 +1,100 @@
+/*
+ * 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 javax.jcr.PropertyType;
+import javax.jcr.Value;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.nodetype.PropertyDefinition;
+import javax.jcr.version.OnParentVersionAction;
+
+class FsPropertyDefinition implements PropertyDefinition {
+    
+    private final String name;
+    
+    public FsPropertyDefinition(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public NodeType getDeclaringNodeType() {
+        return null;
+    }
+
+    @Override
+    public boolean isAutoCreated() {
+        return false;
+    }
+
+    @Override
+    public boolean isMandatory() {
+        return false;
+    }
+
+    @Override
+    public int getOnParentVersion() {
+        return OnParentVersionAction.COPY;
+    }
+
+    @Override
+    public boolean isProtected() {
+        return false;
+    }
+
+    @Override
+    public int getRequiredType() {
+        return PropertyType.UNDEFINED;
+    }
+
+    @Override
+    public String[] getValueConstraints() {
+        return new String[0];
+    }
+
+    @Override
+    public Value[] getDefaultValues() {
+        return new Value[0];
+    }
+
+    @Override
+    public boolean isMultiple() {
+        return false;
+    }
+
+    @Override
+    public String[] getAvailableQueryOperators() {
+        return new String[0];
+    }
+
+    @Override
+    public boolean isFullTextSearchable() {
+        return false;
+    }
+
+    @Override
+    public boolean isQueryOrderable() {
+        return false;
+    }    
+
+}

Propchange: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsPropertyDefinition.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsPropertyDefinition.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Tue Feb 28 15:40:56 2017
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsPropertyDefinition.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsPropertyIterator.java
URL: http://svn.apache.org/viewvc/sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsPropertyIterator.java?rev=1784765&view=auto
==============================================================================
--- sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsPropertyIterator.java (added)
+++ sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsPropertyIterator.java Tue Feb 28 15:40:56 2017
@@ -0,0 +1,82 @@
+/*
+ * 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.ResourceResolver;
+import org.apache.sling.fsprovider.internal.mapper.ContentFile;
+
+/**
+ * Simplified implementation of read-only content access via the JCR API.
+ */
+class FsPropertyIterator implements PropertyIterator {
+    
+    private final Iterator<String> propertyNames;
+    private final ContentFile contentFile;
+    private final ResourceResolver resolver;
+    private final Node node;
+    
+    public FsPropertyIterator(Iterator<String> propertyNames, ContentFile contentFile, ResourceResolver resolver, Node node) {
+        this.propertyNames = propertyNames;
+        this.contentFile = contentFile;
+        this.resolver = resolver;
+        this.node = node;
+    }
+
+    public boolean hasNext() {
+        return propertyNames.hasNext();
+    }
+
+    public Object next() {
+        return nextProperty();
+    }
+
+    @Override
+    public Property nextProperty() {
+        return new FsProperty(contentFile, resolver, 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/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsPropertyIterator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsPropertyIterator.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Tue Feb 28 15:40:56 2017
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsPropertyIterator.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsValue.java
URL: http://svn.apache.org/viewvc/sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsValue.java?rev=1784765&view=auto
==============================================================================
--- sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsValue.java (added)
+++ sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsValue.java Tue Feb 28 15:40:56 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/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsValue.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsValue.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Tue Feb 28 15:40:56 2017
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/mapper/jcr/FsValue.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/parser/ContentFileCache.java
URL: http://svn.apache.org/viewvc/sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/parser/ContentFileCache.java?rev=1784765&view=auto
==============================================================================
--- sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/parser/ContentFileCache.java (added)
+++ sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/parser/ContentFileCache.java Tue Feb 28 15:40:56 2017
@@ -0,0 +1,107 @@
+/*
+ * 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.Collections;
+import java.util.Map;
+
+import org.apache.commons.collections.map.LRUMap;
+
+/**
+ * Cache for parsed content from content files (e.g. JSON, JCR XML).
+ */
+public final class ContentFileCache {
+
+    private final Map<String,Map<String,Object>> contentCache;
+    private final Map<String,Object> NULL_MAP = Collections.emptyMap();
+    
+    /**
+     * @param maxSize Cache size. 0 = caching disabled.
+     */
+    @SuppressWarnings("unchecked")
+    public ContentFileCache(int maxSize) {
+        if (maxSize > 0) {
+            this.contentCache = Collections.synchronizedMap(new LRUMap(maxSize));
+        }
+        else {
+            this.contentCache = null;
+        }
+    }
+    
+    /**
+     * Get content.
+     * @param path Path (used as cache key).
+     * @param file File
+     * @return Content or null
+     */
+    public Map<String,Object> get(String path, File file) {
+        Map<String,Object> content = null;
+        if (contentCache != null) {
+            content = contentCache.get(path);
+        }
+        if (content == null) {
+            content = ContentFileParser.parse(file);
+            if (content == null) {
+                content = NULL_MAP;
+            }
+            if (contentCache != null) {
+                contentCache.put(path, content);
+            }
+        }
+        if (content == NULL_MAP) {
+            return null;
+        }
+        else {
+            return content;
+        }
+    }
+    
+    /**
+     * Remove content from cache.
+     * @param path Path (used as cache key)
+     */
+    public void remove(String path) {
+        if (contentCache != null) {
+            contentCache.remove(path);
+        }
+    }
+
+    /**
+     * Clear whole cache
+     */
+    public void clear() {
+        if (contentCache != null) {
+            contentCache.clear();
+        }
+    }
+    
+    /**
+     * @return Current cache size
+     */
+    public int size() {
+        if (contentCache != null) {
+            return contentCache.size();
+        }
+        else {
+            return 0;
+        }
+    }
+
+}

Propchange: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/parser/ContentFileCache.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/parser/ContentFileCache.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Tue Feb 28 15:40:56 2017
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: sling/branches/fsresource-1.1.x/src/main/java/org/apache/sling/fsprovider/internal/parser/ContentFileCache.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain