Introduce CRUD to GCR
[lgpl/argeo-commons.git] / org.argeo.api / src / org / argeo / api / gcr / spi / AbstractContent.java
index 2da186ef2538eb6d2d1f2da67be1d9dae6675d6a..79c59f2f66ad06c0b1cf2ca74b0b6917f1610b9a 100644 (file)
@@ -1,7 +1,11 @@
 package org.argeo.api.gcr.spi;
 
 import java.util.AbstractMap;
-import java.util.HashSet;
+import java.util.AbstractSet;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.argeo.api.gcr.Content;
@@ -10,39 +14,117 @@ public abstract class AbstractContent extends AbstractMap<String, Object> implem
 
        @Override
        public Set<Entry<String, Object>> entrySet() {
-               Set<Entry<String, Object>> result = new HashSet<>();
-               for (String key : keys()) {
-                       Entry<String, Object> entry = new Entry<String, Object>() {
+//             Set<Entry<String, Object>> result = new HashSet<>();
+//             for (String key : keys()) {
+//                     Entry<String, Object> entry = new Entry<String, Object>() {
+//
+//                             @Override
+//                             public String getKey() {
+//                                     return key;
+//                             }
+//
+//                             @Override
+//                             public Object getValue() {
+//                                     return get(key, Object.class);
+//                             }
+//
+//                             @Override
+//                             public Object setValue(Object value) {
+//                                     throw new UnsupportedOperationException();
+//                             }
+//
+//                     };
+//                     result.add(entry);
+//             }
+               Set<Entry<String, Object>> result = new AttrSet();
+               return result;
+       }
+
+       protected abstract Iterable<String> keys();
+
+       protected abstract void removeAttr(String key);
+
+       @Override
+       public String getPath() {
+               List<Content> ancestors = new ArrayList<>();
+               collectAncestors(ancestors, this);
+               StringBuilder path = new StringBuilder();
+               for (Content c : ancestors) {
+                       String name = c.getName();
+                       if (!"".equals(name))
+                               path.append('/').append(name);
+               }
+               return path.toString();
+       }
+
+       private void collectAncestors(List<Content> ancestors, Content content) {
+               if (content == null)
+                       return;
+               ancestors.add(0, content);
+               collectAncestors(ancestors, content.getParent());
+       }
+
+       /*
+        * UTILITIES
+        */
+       protected boolean isDefaultAttrTypeRequested(Class<?> clss) {
+               // check whether clss is Object.class
+               return clss.isAssignableFrom(Object.class);
+       }
+
+       @Override
+       public String toString() {
+               return "content "+getPath();
+       }
+
+       /*
+        * SUB CLASSES
+        */
+
+       class AttrSet extends AbstractSet<Entry<String, Object>> {
+
+               @Override
+               public Iterator<Entry<String, Object>> iterator() {
+                       final Iterator<String> keys = keys().iterator();
+                       Iterator<Entry<String, Object>> it = new Iterator<Map.Entry<String, Object>>() {
+
+                               String key = null;
 
                                @Override
-                               public String getKey() {
-                                       return key;
+                               public boolean hasNext() {
+                                       return keys.hasNext();
                                }
 
                                @Override
-                               public Object getValue() {
+                               public Entry<String, Object> next() {
+                                       key = keys.next();
                                        // TODO check type
-                                       return get(key, Object.class);
+                                       Object value = get(key, Object.class);
+                                       AbstractMap.SimpleEntry<String, Object> entry = new SimpleEntry<>(key, value);
+                                       return entry;
                                }
 
                                @Override
-                               public Object setValue(Object value) {
-                                       throw new UnsupportedOperationException();
+                               public void remove() {
+                                       if (key != null) {
+                                               AbstractContent.this.removeAttr(key);
+                                       } else {
+                                               throw new IllegalStateException("Iteration has not started");
+                                       }
                                }
 
                        };
-                       result.add(entry);
+                       return it;
+               }
+
+               @Override
+               public int size() {
+                       int count = 0;
+                       for (String key : keys()) {
+                               count++;
+                       }
+                       return count;
                }
-               return result;
-       }
 
-       protected abstract Iterable<String> keys();
-       
-       /*
-        * UTILITIES
-        */
-       protected boolean isDefaultAttrTypeRequested(Class<?> clss) {
-               // check whether clss is Object.class 
-               return clss.isAssignableFrom(Object.class);
        }
 }