package org.argeo.api.acr; import java.io.Closeable; import java.io.IOException; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.concurrent.CompletableFuture; import javax.xml.XMLConstants; import javax.xml.namespace.QName; /** * A semi-structured content, with attributes, within a hierarchical structure. */ public interface Content extends Iterable, Map { QName getName(); String getPath(); Content getParent(); /* * ATTRIBUTES OPERATIONS */ Optional get(QName key, Class 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); Optional> getMultiple(QName key, Class clss); @SuppressWarnings("unchecked") default List getMultiple(QName key) { Class type; try { type = (Class) getType(key); } catch (ClassCastException e) { throw new IllegalArgumentException("Requested type is not the default type"); } Optional> 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(); } } /* * CONTENT OPERATIONS */ // default CompletionStage edit(Consumer work) { // return CompletableFuture.supplyAsync(() -> { // work.accept(this); // return this; // }).minimalCompletionStage(); // } 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); } void remove(); /* * TYPING */ List getTypes(); /* * DEFAULT METHODS */ default A adapt(Class clss) { throw new UnsupportedOperationException("Cannot adapt content " + this + " to " + clss.getName()); } default C open(Class clss) throws IOException { throw new UnsupportedOperationException("Cannot open content " + this + " as " + clss.getName()); } default CompletableFuture write(Class clss) { throw new UnsupportedOperationException("Cannot write 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 get(Object key, Class clss) { // return key != null ? get(key.toString(), clss) : get(null, clss); // } /* * EXPERIMENTAL UNSUPPORTED */ default boolean hasText() { return false; } default String getText() { throw new UnsupportedOperationException(); } }