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

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


The following commit(s) were added to refs/heads/master by this push:
     new 72aa20e  additional structure
72aa20e is described below

commit 72aa20e9cf7e0292161c6ffd0b1e6f31e73ae8f1
Author: JE Bailey <[email protected]>
AuthorDate: Fri Oct 19 14:59:49 2018 -0400

    additional structure
---
 .../apache/sling/mvresource/impl/MvResource.java   |  18 +--
 .../apache/sling/mvresource/impl/MvSession.java    |  23 ++++
 .../mvresource/impl/MvStoreResourceProvider.java   |  71 +++++------
 .../apache/sling/mvresource/impl/MvValueMap.java   | 136 +++++++++++++++++++++
 4 files changed, 206 insertions(+), 42 deletions(-)

diff --git 
a/mvresourceprovider/src/main/java/org/apache/sling/mvresource/impl/MvResource.java
 
b/mvresourceprovider/src/main/java/org/apache/sling/mvresource/impl/MvResource.java
index 5d031fc..009d040 100644
--- 
a/mvresourceprovider/src/main/java/org/apache/sling/mvresource/impl/MvResource.java
+++ 
b/mvresourceprovider/src/main/java/org/apache/sling/mvresource/impl/MvResource.java
@@ -19,6 +19,7 @@
 package org.apache.sling.mvresource.impl;
 
 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;
@@ -28,11 +29,11 @@ import org.h2.mvstore.MVMap;
 
 public class MvResource extends AbstractResource {
 
-    private MVMap<String, Object> properties;
+    private MvValueMap properties;
     private String path;
     private ResourceResolver resolver;
 
-    public MvResource(ResourceResolver resolver, String path, MVMap<String, 
Object> properties) {
+    public MvResource(ResourceResolver resolver, String path, MvValueMap 
properties) {
         this.resolver = resolver;
         this.properties = properties;
         this.path = path;
@@ -45,13 +46,15 @@ public class MvResource extends AbstractResource {
 
     @Override
     public String getResourceType() {
-        if (properties.isEmpty()) {
-            return null;
-        }
         String type = (String) properties.get("sling:resourceType");
         if (type == null) {
             type = (String) properties.get("jcr:primaryType");
         }
+        if (type == null) {
+            if (properties.isEmpty()) {
+                return "sling:Folder";
+            }
+        }
         return type;
     }
 
@@ -64,6 +67,7 @@ public class MvResource extends AbstractResource {
     }
 
     private ResourceMetadata metaData  = new ResourceMetadata();
+    
     @Override
     public ResourceMetadata getResourceMetadata() {
         return metaData;
@@ -74,13 +78,13 @@ public class MvResource extends AbstractResource {
         return resolver;
     }
 
-    public MVMap<String, Object> getMVMap() {
+    public MvValueMap getMVMap() {
         return properties;
     }
 
     @Override
     public ValueMap getValueMap() {
-        return new DeepReadModifiableValueMapDecorator(this, new 
ValueMapDecorator(properties));
+        return this.properties;
     }
 
 }
diff --git 
a/mvresourceprovider/src/main/java/org/apache/sling/mvresource/impl/MvSession.java
 
b/mvresourceprovider/src/main/java/org/apache/sling/mvresource/impl/MvSession.java
new file mode 100644
index 0000000..be653dd
--- /dev/null
+++ 
b/mvresourceprovider/src/main/java/org/apache/sling/mvresource/impl/MvSession.java
@@ -0,0 +1,23 @@
+/*
+ * 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.mvresource.impl;
+
+public class MvSession {
+
+}
diff --git 
a/mvresourceprovider/src/main/java/org/apache/sling/mvresource/impl/MvStoreResourceProvider.java
 
b/mvresourceprovider/src/main/java/org/apache/sling/mvresource/impl/MvStoreResourceProvider.java
index e468365..614f44f 100644
--- 
a/mvresourceprovider/src/main/java/org/apache/sling/mvresource/impl/MvStoreResourceProvider.java
+++ 
b/mvresourceprovider/src/main/java/org/apache/sling/mvresource/impl/MvStoreResourceProvider.java
@@ -35,6 +35,7 @@ import org.apache.sling.spi.resource.provider.ResourceContext;
 import org.apache.sling.spi.resource.provider.ResourceProvider;
 import org.h2.mvstore.MVMap;
 import org.h2.mvstore.MVStore;
+import org.h2.mvstore.StreamStore;
 import org.osgi.framework.Constants;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.metatype.annotations.AttributeDefinition;
@@ -49,10 +50,12 @@ import org.slf4j.LoggerFactory;
         "adaptables=org.apache.sling.mvresource.impl.MvResource",
         "adapters=org.apache.sling.api.resource.ModifiableValueMap",
         ResourceProvider.PROPERTY_AUTHENTICATE + "=" + 
ResourceProvider.AUTHENTICATE_REQUIRED })
-public class MvStoreResourceProvider extends ResourceProvider<Object> 
implements AdapterFactory {
+public class MvStoreResourceProvider extends ResourceProvider<MvSession> 
implements AdapterFactory {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(MvStoreResourceProvider.class);
 
+    private static final String CHILDREN = "_children";
+
     @ObjectClassDefinition(name = "Apache Sling Resource Provider", 
description = "Configure an instance of the file system "
             + "resource provider in terms of provider root and file system 
location")
     public @interface Config {
@@ -77,12 +80,14 @@ public class MvStoreResourceProvider extends 
ResourceProvider<Object> implements
     }
 
     MVStore store;
+    private StreamStore binaryStore;
 
     @Override
     public void start(ProviderContext ctx) {
         LOG.info("mvprovider has started");
         super.start(ctx);
         store = MVStore.open("dataStore");
+        binaryStore = new StreamStore(store.openMap("_binaries"));
     }
 
     @Override
@@ -92,42 +97,37 @@ public class MvStoreResourceProvider extends 
ResourceProvider<Object> implements
     }
 
     @Override
-    public Resource getResource(ResolveContext<Object> context, String 
resourcePath, ResourceContext resourceContext,
+    public Resource getResource(ResolveContext<MvSession> context, String 
resourcePath, ResourceContext resourceContext,
             Resource parentResource) {
         LOG.info("GET {} ", resourcePath);
         MVMap<String, Object> properties = store.openMap(resourcePath);
+        if (resourcePath.equals("/content/apache/fake")) {
+            final ResourceProvider rp = context.getParentResourceProvider();
+            return rp.getResource(context.getParentResolveContext(), 
resourcePath, resourceContext, parentResource);
+        }
         if (properties.isEmpty()) {
-            if (resourcePath.equals("/content/apache/fake")) {
-                properties.put("jcr:primaryType", "sling:Site");
-                properties.put("jcr:title", "Fake Site");
-                properties.put("jcr:language", "en");
-                properties.put("sling:url", "https://sling.apache.org";);
-                store.commit();
-            }
             return null;
         }
-        return new MvResource(context.getResourceResolver(), resourcePath, 
properties);
+        return new MvResource(context.getResourceResolver(), resourcePath, new 
MvValueMap(properties, binaryStore));
     }
 
     @Override
-    public Resource create(ResolveContext<Object> ctx, String path, 
Map<String, Object> properties)
+    public Resource create(ResolveContext<MvSession> ctx, String path, 
Map<String, Object> properties)
             throws PersistenceException {
         LOG.info("CREATE  {} ", path);
-        try {
+        MVMap<String, Object> oldProps = store.openMap(path);
+        if (oldProps.isEmpty()) {
             String parent = parentPath(path);
-            MVMap<String, String[]> parentResource = 
store.openMap("_children");
+            MVMap<String, String[]> parentResource = store.openMap(CHILDREN);
             String[] children = parentResource.getOrDefault(parent, new 
String[] {});
             String[] newChildren = Arrays.copyOf(children, children.length + 
1);
             newChildren[children.length] = path;
             parentResource.put(parent, newChildren);
-            MVMap<String, Object> data = store.openMap(path);
-            data.putAll(properties);
-            return new MvResource(ctx.getResourceResolver(), path, data);
-        } catch (Exception e) {
-            LOG.error("Error occured in creation {}", e);
-            throw e;
         }
-
+        MvValueMap data = new MvValueMap(oldProps, binaryStore);
+        data.putAll(properties);
+        store.commit();
+        return new MvResource(ctx.getResourceResolver(), path, data);
     }
 
     public String currentName(String path) {
@@ -142,23 +142,23 @@ public class MvStoreResourceProvider extends 
ResourceProvider<Object> implements
     }
 
     @Override
-    public void commit(ResolveContext<Object> ctx) throws PersistenceException 
{
-       LOG.info("COMMIT  {} ", ctx.getProviderState());
-       store.commit();
+    public void commit(ResolveContext<MvSession> ctx) throws 
PersistenceException {
+        LOG.info("COMMIT  {} ", ctx.getProviderState());
+        store.commit();
     }
 
     @Override
-    public void delete(ResolveContext<Object> ctx, Resource resource) throws 
PersistenceException {
+    public void delete(ResolveContext<MvSession> ctx, Resource resource) 
throws PersistenceException {
         LOG.info("DELETE  {} ", resource.getName());
         if (!(resource instanceof MvResource)) {
             throw new PersistenceException("can not delete resource of type" + 
resource.getClass());
         }
-        MVMap<String, String[]> parentResource = store.openMap("_children");
+        MVMap<String, String[]> parentResource = store.openMap(CHILDREN);
         String parentPath = parentPath(resource.getPath());
         String[] childNames = parentResource.get(parentPath);
         String[] newChildren = new String[childNames.length - 1];
         int newIndex = 0;
-        for (int index = 0; index < childNames.length ; ++index) {
+        for (int index = 0; index < childNames.length; ++index) {
             if (!childNames[index].equals(resource.getName())) {
                 newChildren[newIndex++] = childNames[index];
             }
@@ -168,30 +168,31 @@ public class MvStoreResourceProvider extends 
ResourceProvider<Object> implements
         resourceToDelete.add(resource.getPath());
         deleteDescendents(parentResource, resourceToDelete);
     }
-    
-    private void deleteDescendents(MVMap<String, String[]> parentMap, 
Deque<String> pathsToDelete ) {
+
+    private void deleteDescendents(MVMap<String, String[]> parentMap, 
Deque<String> pathsToDelete) {
         if (pathsToDelete.isEmpty()) {
             return;
         }
         String currentPath = pathsToDelete.pop();
         String[] children = parentMap.getOrDefault(currentPath, new String[] 
{});
         store.removeMap(store.openMap(currentPath));
-        for (int i = 0; i < children.length ; ++i) {
+        for (int i = 0; i < children.length; ++i) {
             pathsToDelete.add(children[i]);
         }
-        deleteDescendents(parentMap,pathsToDelete);
+        deleteDescendents(parentMap, pathsToDelete);
     }
 
     @Override
-    public Iterator<Resource> listChildren(ResolveContext<Object> 
resolveContext, Resource resource) {
+    public Iterator<Resource> listChildren(ResolveContext<MvSession> 
resolveContext, Resource resource) {
         LOG.info("LIST CHILDREN");
-        MVMap<String, String[]> parentResource = store.openMap("_children");
+        MVMap<String, String[]> parentMap = store.openMap(CHILDREN);
         List<Resource> response = new ArrayList<>();
-        String[] childNames = parentResource.getOrDefault(resource.getPath(), 
new String[] {});
+        String[] childNames = parentMap.getOrDefault(resource.getPath(), new 
String[] {});
         for (int i = 0; i < childNames.length; ++i) {
-            String childPath = resource.getPath() + "/" + childNames[i];
+            String childPath = childNames[i];
             LOG.info("child found {}", childPath);
-            response.add(new MvResource(resolveContext.getResourceResolver(), 
childPath, store.openMap(childPath)));
+            response.add(new MvResource(resolveContext.getResourceResolver(), 
childPath,
+                    new MvValueMap(store.openMap(childPath), binaryStore)));
         }
         return response.iterator();
     }
diff --git 
a/mvresourceprovider/src/main/java/org/apache/sling/mvresource/impl/MvValueMap.java
 
b/mvresourceprovider/src/main/java/org/apache/sling/mvresource/impl/MvValueMap.java
new file mode 100644
index 0000000..aae9c48
--- /dev/null
+++ 
b/mvresourceprovider/src/main/java/org/apache/sling/mvresource/impl/MvValueMap.java
@@ -0,0 +1,136 @@
+/*
+ * 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.mvresource.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.sling.api.resource.ModifiableValueMap;
+import org.apache.sling.api.resource.ValueMap;
+import org.h2.mvstore.MVMap;
+import org.h2.mvstore.StreamStore;
+
+public class MvValueMap implements ValueMap, ModifiableValueMap {
+
+    private MVMap<String, Object> map;
+    private StreamStore store;
+
+    public MvValueMap(MVMap<String, Object> map, StreamStore binaryStore) {
+        this.map = map;
+        this.store = binaryStore;
+    }
+
+    @Override
+    public int size() {
+        return map.size();
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return map.isEmpty();
+    }
+
+    @Override
+    public boolean containsKey(Object key) {
+        return map.containsKey(key);
+    }
+
+    @Override
+    public boolean containsValue(Object value) {
+        return map.containsValue(value);
+    }
+
+    @Override
+    public Object get(Object key) {
+        Object value = map.get(key);
+        if (value instanceof String) {
+            String stringValue = value.toString();
+            if (stringValue.startsWith("{b}")) {
+                return store.get(stringValue.substring(3).getBytes());
+            }
+        }
+        return value;
+    }
+
+    @Override
+    public Object put(String key, Object value) {
+        if (value instanceof InputStream) {
+            try {
+                value = "{b}"+ new String(store.put((InputStream)value));
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return map.put(key, value);
+    }
+
+    @Override
+    public Object remove(Object key) {
+        return map.remove(key);
+    }
+
+    @Override
+    public void putAll(Map<? extends String, ? extends Object> m) {
+        map.putAll(map);
+    }
+
+    @Override
+    public void clear() {
+        map.clear();
+    }
+
+    @Override
+    public Set<String> keySet() {
+        return map.keySet();
+    }
+
+    @Override
+    public Collection<Object> values() {
+        return map.values();
+    }
+
+    @Override
+    public Set<Entry<String, Object>> entrySet() {
+        return map.entrySet();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T> T get(String name, Class<T> type) {
+        Object response = get(name);
+        if (response == null) {
+            return null;
+        }
+        if (!response.getClass().isAssignableFrom(type)) {
+            return null;
+        }
+        return (T)response;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T> T get(String name, T defaultValue) {
+        return (T) map.getOrDefault(name, defaultValue);
+    }
+    
+
+}

Reply via email to