Work on typing
[lgpl/argeo-commons.git] / org.argeo.api / src / org / argeo / api / gcr / Content.java
index 34f11758aa08f2e45d9536875fe6638ddd72098c..fa4d5071330d87f08b3eca2c984a9ee0e229c3b4 100644 (file)
 package org.argeo.api.gcr;
 
+import java.util.List;
 import java.util.Map;
+import java.util.Optional;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
 
 /**
  * A semi-structured content, with attributes, within a hierarchical structure.
  */
-public interface Content extends Iterable<Content>, Map<String, Object> {
-
-       String getName();
+public interface Content extends Iterable<Content>, Map<QName, Object> {
 
-//     Iterable<String> keys();
+       QName getName();
 
-       <A> A get(String key, Class<A> clss);
+       String getPath();
 
-       ContentSession getSession();
+       Content getParent();
 
        /*
-        * DEFAULT METHODS
+        * ATTRIBUTES OPERATIONS
         */
-       default <A> A adapt(Class<A> clss) {
-               return null;
+
+       <A> Optional<A> get(QName key, Class<A> clss);
+
+       default Object get(String key) {
+               if (key.indexOf(':') >= 0)
+                       throw new IllegalArgumentException("Name " + key + " has a prefix");
+               return get(new QName(XMLConstants.NULL_NS_URI, key, XMLConstants.DEFAULT_NS_PREFIX));
+       }
+
+       default Object put(String key, Object value) {
+               if (key.indexOf(':') >= 0)
+                       throw new IllegalArgumentException("Name " + key + " has a prefix");
+               return put(new QName(XMLConstants.NULL_NS_URI, key, XMLConstants.DEFAULT_NS_PREFIX), value);
+       }
+
+       default Object remove(String key) {
+               if (key.indexOf(':') >= 0)
+                       throw new IllegalArgumentException("Name " + key + " has a prefix");
+               return remove(new QName(XMLConstants.NULL_NS_URI, key, XMLConstants.DEFAULT_NS_PREFIX));
+       }
+
+       Class<?> getType(QName key);
+
+       boolean isMultiple(QName key);
+
+       <A> Optional<List<A>> getMultiple(QName key, Class<A> clss);
+
+       default <A> List<A> getMultiple(QName key) {
+               Class<A> type;
+               try {
+                       type = (Class<A>) getType(key);
+               } catch (ClassCastException e) {
+                       throw new IllegalArgumentException("Requested type is not the default type");
+               }
+               Optional<List<A>> res = getMultiple(key, type);
+               if (res == null)
+                       return null;
+               else {
+                       if (res.isEmpty())
+                               throw new IllegalStateException("Metadata " + key + " is not availabel as list of type " + type);
+                       return res.get();
+               }
        }
 
        /*
-        * CONVENIENCE METHODS
+        * CONTENT OPERATIONS
         */
-       default String attr(String key) {
-               return get(key, String.class);
+       Content add(QName name, QName... classes);
+
+       default Content add(String name, QName... classes) {
+               if (name.indexOf(':') >= 0)
+                       throw new IllegalArgumentException("Name " + name + " has a prefix");
+               return add(new QName(XMLConstants.NULL_NS_URI, name, XMLConstants.DEFAULT_NS_PREFIX), classes);
        }
 
-       default String attr(Enum<?> key) {
-               return attr(key.name());
+       void remove();
+
+       /*
+        * DEFAULT METHODS
+        */
+       default <A> A adapt(Class<A> clss) throws IllegalArgumentException {
+               throw new IllegalArgumentException("Cannot adapt content " + this + " to " + clss.getName());
        }
 
-       default <A> A get(Enum<?> key, Class<A> clss) {
-               return get(key.name(), clss);
+       default <C extends AutoCloseable> C open(Class<C> clss) throws Exception, IllegalArgumentException {
+               throw new IllegalArgumentException("Cannot open content " + this + " as " + clss.getName());
        }
 
+       /*
+        * CONVENIENCE METHODS
+        */
+//     default String attr(String key) {
+//             return get(key, String.class);
+//     }
+//
+//     default String attr(Object key) {
+//             return key != null ? attr(key.toString()) : attr(null);
+//     }
+//
+//     default <A> A get(Object key, Class<A> clss) {
+//             return key != null ? get(key.toString(), clss) : get(null, clss);
+//     }
+
        /*
         * EXPERIMENTAL UNSUPPORTED
         */