]>
git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.api.acr/src/org/argeo/api/acr/Content.java
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 isContentClass(QNamed
... contentClass
) {
133 List
<QName
> lst
= new ArrayList
<>();
134 for (QNamed qNamed
: contentClass
)
135 lst
.add(qNamed
.qName());
136 return isContentClass(lst
.toArray(new QName
[lst
.size()]));
140 default boolean hasContentClass(QName
... contentClass
) {
141 List
<QName
> contentClasses
= getContentClasses();
142 for (QName cClass
: contentClass
) {
143 if (contentClasses
.contains(cClass
))
150 default boolean hasContentClass(QNamed
... contentClass
) {
151 List
<QName
> lst
= new ArrayList
<>();
152 for (QNamed qNamed
: contentClass
)
153 lst
.add(qNamed
.qName());
154 return hasContentClass(lst
.toArray(new QName
[lst
.size()]));
161 default int getSiblingIndex() {
168 default <A
> A
adapt(Class
<A
> clss
) {
169 throw new UnsupportedOperationException("Cannot adapt content " + this + " to " + clss
.getName());
172 default <C
extends Closeable
> C
open(Class
<C
> clss
) throws IOException
{
173 throw new UnsupportedOperationException("Cannot open content " + this + " as " + clss
.getName());
176 default <A
> CompletableFuture
<A
> write(Class
<A
> clss
) {
177 throw new UnsupportedOperationException("Cannot write content " + this + " as " + clss
.getName());
184 default boolean hasChild(QName name
) {
185 for (Content child
: this) {
186 if (child
.getName().equals(name
))
192 default boolean hasChild(QNamed name
) {
193 return hasChild(name
.qName());
196 default Content
anyOrAddChild(QName name
, QName
... classes
) {
197 Content child
= anyChild(name
);
200 return this.add(name
, classes
);
203 default Content
anyOrAddChild(String name
, QName
... classes
) {
204 return anyOrAddChild(unqualified(name
), classes
);
207 /** Any child with this name, or null if there is none */
208 default Content
anyChild(QName name
) {
209 for (Content child
: this) {
210 if (child
.getName().equals(name
))
216 default List
<Content
> children(QName name
) {
217 List
<Content
> res
= new ArrayList
<>();
218 for (Content child
: this) {
219 if (child
.getName().equals(name
))
225 default Optional
<Content
> soleChild(QName name
) {
226 List
<Content
> res
= children(name
);
228 return Optional
.empty();
230 throw new IllegalStateException(this + " has multiple children with name " + name
);
231 return Optional
.of(res
.get(0));
234 default Content
child(QName name
) {
235 return soleChild(name
).orElseThrow();
238 default Content
child(QNamed name
) {
239 return child(name
.qName());
245 default String
attr(QName key
) {
246 // TODO check String type?
247 Object obj
= get(key
);
250 return obj
.toString();
253 default String
attr(QNamed key
) {
254 return attr(key
.qName());
257 default String
attr(String key
) {
258 return attr(unqualified(key
));
261 // default String attr(Object key) {
262 // return key != null ? attr(key.toString()) : attr(null);
265 // default <A> A get(Object key, Class<A> clss) {
266 // return key != null ? get(key.toString(), clss) : get(null, clss);
270 * EXPERIMENTAL UNSUPPORTED
272 default boolean hasText() {
276 default String
getText() {
277 throw new UnsupportedOperationException();