]>
git.argeo.org Git - lgpl/argeo-commons.git/blob - Content.java
b605fa1e0062140b18fd5b1784fe8ea0fd6171bc
1 package org
.argeo
.api
.acr
;
3 import static org
.argeo
.api
.acr
.NamespaceUtils
.unqualified
;
5 import java
.io
.Closeable
;
6 import java
.io
.IOException
;
7 import java
.util
.ArrayList
;
10 import java
.util
.Optional
;
11 import java
.util
.concurrent
.CompletableFuture
;
13 import javax
.xml
.namespace
.QName
;
16 * A semi-structured content, with attributes, within a hierarchical structure.
18 public interface Content
extends Iterable
<Content
>, Map
<QName
, Object
> {
27 * ATTRIBUTES OPERATIONS
30 <A
> Optional
<A
> get(QName key
, Class
<A
> clss
);
32 Class
<?
> getType(QName key
);
34 boolean isMultiple(QName key
);
36 <A
> List
<A
> getMultiple(QName key
, Class
<A
> clss
);
39 * ATTRIBUTES OPERATION HELPERS
41 default boolean containsKey(QNamed key
) {
42 return containsKey(key
.qName());
45 default <A
> Optional
<A
> get(QNamed key
, Class
<A
> clss
) {
46 return get(key
.qName(), clss
);
49 default Object
get(QNamed key
) {
50 return get(key
.qName());
53 default Object
put(QNamed key
, Object value
) {
54 return put(key
.qName(), value
);
57 default Object
remove(QNamed key
) {
58 return remove(key
.qName());
61 // TODO do we really need the helpers below?
63 default Object
get(String key
) {
64 return get(unqualified(key
));
67 default Object
put(String key
, Object value
) {
68 return put(unqualified(key
), value
);
71 default Object
remove(String key
) {
72 return remove(unqualified(key
));
75 @SuppressWarnings("unchecked")
76 default <A
> List
<A
> getMultiple(QName key
) {
79 type
= (Class
<A
>) getType(key
);
80 } catch (ClassCastException e
) {
81 throw new IllegalArgumentException("Requested type is not the default type");
83 List
<A
> res
= getMultiple(key
, type
);
89 // throw new IllegalStateException("Metadata " + key + " is not availabel as list of type " + type);
97 // default CompletionStage<Content> edit(Consumer<Content> work) {
98 // return CompletableFuture.supplyAsync(() -> {
101 // }).minimalCompletionStage();
104 Content
add(QName name
, QName
... classes
);
106 default Content
add(String name
, QName
... classes
) {
107 return add(unqualified(name
), classes
);
115 List
<QName
> getContentClasses();
117 default void addContentClasses(QName
... contentClass
) {
118 throw new UnsupportedOperationException("Adding content classes to " + getPath() + " is not supported");
122 default boolean isContentClass(QName
... contentClass
) {
123 List
<QName
> contentClasses
= getContentClasses();
124 for (QName cClass
: contentClass
) {
125 if (!contentClasses
.contains(cClass
))
132 default boolean hasContentClass(QName
... contentClass
) {
133 List
<QName
> contentClasses
= getContentClasses();
134 for (QName cClass
: contentClass
) {
135 if (contentClasses
.contains(cClass
))
141 default boolean hasContentClass(QNamed contentClass
) {
142 return hasContentClass(contentClass
.qName());
149 default int getSiblingIndex() {
156 default <A
> A
adapt(Class
<A
> clss
) {
157 throw new UnsupportedOperationException("Cannot adapt content " + this + " to " + clss
.getName());
160 default <C
extends Closeable
> C
open(Class
<C
> clss
) throws IOException
{
161 throw new UnsupportedOperationException("Cannot open content " + this + " as " + clss
.getName());
164 default <A
> CompletableFuture
<A
> write(Class
<A
> clss
) {
165 throw new UnsupportedOperationException("Cannot write content " + this + " as " + clss
.getName());
172 default boolean hasChild(QName name
) {
173 for (Content child
: this) {
174 if (child
.getName().equals(name
))
180 default boolean hasChild(QNamed name
) {
181 return hasChild(name
.qName());
184 default Content
anyOrAddChild(QName name
, QName
... classes
) {
185 Content child
= anyChild(name
);
188 return this.add(name
, classes
);
191 default Content
anyOrAddChild(String name
, QName
... classes
) {
192 return anyOrAddChild(unqualified(name
), classes
);
195 /** Any child with this name, or null if there is none */
196 default Content
anyChild(QName name
) {
197 for (Content child
: this) {
198 if (child
.getName().equals(name
))
204 default List
<Content
> children(QName name
) {
205 List
<Content
> res
= new ArrayList
<>();
206 for (Content child
: this) {
207 if (child
.getName().equals(name
))
213 default Optional
<Content
> soleChild(QName name
) {
214 List
<Content
> res
= children(name
);
216 return Optional
.empty();
218 throw new IllegalStateException(this + " has multiple children with name " + name
);
219 return Optional
.of(res
.get(0));
222 default Content
child(QName name
) {
223 return soleChild(name
).orElseThrow();
226 default Content
child(QNamed name
) {
227 return child(name
.qName());
233 default String
attr(QName key
) {
234 // TODO check String type?
235 Object obj
= get(key
);
238 return obj
.toString();
241 default String
attr(QNamed key
) {
242 return attr(key
.qName());
245 default String
attr(String key
) {
246 return attr(unqualified(key
));
249 // default String attr(Object key) {
250 // return key != null ? attr(key.toString()) : attr(null);
253 // default <A> A get(Object key, Class<A> clss) {
254 // return key != null ? get(key.toString(), clss) : get(null, clss);
258 * EXPERIMENTAL UNSUPPORTED
260 default boolean hasText() {
264 default String
getText() {
265 throw new UnsupportedOperationException();