X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=org.argeo.api.acr%2Fsrc%2Forg%2Fargeo%2Fapi%2Facr%2FContent.java;h=7ec29594713e885d8f39a2efa00c0a24b186f7f3;hb=9e6715d360fb29bb817ecaf6d49f0c8a3cc014f5;hp=f52ab31b8f25223e109b4781707502f924cd5ebd;hpb=f3cb3bed85cb528d919193ce6abb2bb8d05faf03;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.api.acr/src/org/argeo/api/acr/Content.java b/org.argeo.api.acr/src/org/argeo/api/acr/Content.java index f52ab31b8..7ec295947 100644 --- a/org.argeo.api.acr/src/org/argeo/api/acr/Content.java +++ b/org.argeo.api.acr/src/org/argeo/api/acr/Content.java @@ -16,6 +16,8 @@ import javax.xml.namespace.QName; * A semi-structured content, with attributes, within a hierarchical structure. */ public interface Content extends Iterable, Map { + /** The base of a repository path. */ + String ROOT_PATH = "/"; QName getName(); @@ -82,31 +84,38 @@ public interface Content extends Iterable, Map { } List res = getMultiple(key, type); return res; -// 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(); -// } + /** Adds a new empty {@link Content} to this {@link Content}. */ + Content add(QName name, QName... contentClass); - Content add(QName name, QName... classes); + default Content add(QName name, QNamed... contentClass) { + return add(name, toQNames(contentClass)); + } + + /** + * Adds a new {@link Content} to this {@link Content}, setting the provided + * attributes. The provided attributes can be used as hints by the + * implementation. In particular, setting {@link DName#getcontenttype} will + * imply that this content has a file semantic. + */ + default Content add(QName name, Map attrs, QName... classes) { + Content child = add(name, classes); + putAll(attrs); + return child; + } default Content add(String name, QName... classes) { return add(unqualified(name), classes); } + default Content add(String name, Map attrs, QName... classes) { + return add(unqualified(name), attrs, classes); + } + void remove(); /* @@ -130,10 +139,7 @@ public interface Content extends Iterable, Map { /** AND */ default boolean isContentClass(QNamed... contentClass) { - List lst = new ArrayList<>(); - for (QNamed qNamed : contentClass) - lst.add(qNamed.qName()); - return isContentClass(lst.toArray(new QName[lst.size()])); + return isContentClass(toQNames(contentClass)); } /** OR */ @@ -148,10 +154,14 @@ public interface Content extends Iterable, Map { /** OR */ default boolean hasContentClass(QNamed... contentClass) { - List lst = new ArrayList<>(); - for (QNamed qNamed : contentClass) - lst.add(qNamed.qName()); - return hasContentClass(lst.toArray(new QName[lst.size()])); + return hasContentClass(toQNames(contentClass)); + } + + static QName[] toQNames(QNamed... names) { + QName[] res = new QName[names.length]; + for (int i = 0; i < names.length; i++) + res[i] = names[i].qName(); + return res; } /* @@ -222,6 +232,14 @@ public interface Content extends Iterable, Map { return res; } + default List children(QNamed name) { + return children(name.qName()); + } + + default Optional soleChild(QNamed name) { + return soleChild(name.qName()); + } + default Optional soleChild(QName name) { List res = children(name); if (res.isEmpty()) @@ -231,6 +249,10 @@ public interface Content extends Iterable, Map { return Optional.of(res.get(0)); } + default Content soleOrAddChild(QName name, QName... classes) { + return soleChild(name).orElseGet(() -> this.add(name, classes)); + } + default Content child(QName name) { return soleChild(name).orElseThrow(); } @@ -242,29 +264,51 @@ public interface Content extends Iterable, Map { /* * ATTR AS STRING */ + /** + * Convenience method returning an attribute as a {@link String}. + * + * @param key the attribute name + * @return the attribute value as a {@link String} or null. + * + * @see Object#toString() + */ default String attr(QName key) { - // TODO check String type? - Object obj = get(key); - if (obj == null) - return null; - return obj.toString(); + return get(key, String.class).orElse(null); } + /** + * Convenience method returning an attribute as a {@link String}. + * + * @param key the attribute name + * @return the attribute value as a {@link String} or null. + * + * @see Object#toString() + */ default String attr(QNamed key) { return attr(key.qName()); } + /** + * Convenience method returning an attribute as a {@link String}. + * + * @param key the attribute name + * @return the attribute value as a {@link String} or null. + * + * @see Object#toString() + */ default String attr(String key) { return attr(unqualified(key)); } -// -// 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); -// } + + /* + * CONTEXT + */ + /** + * A content within this repository + * + * @param path either an absolute path or a path relative to this content + */ + Optional getContent(String path); /* * EXPERIMENTAL UNSUPPORTED