]>
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
> {
19 /** The base of a repository path. */
20 String ROOT_PATH
= "/";
29 * ATTRIBUTES OPERATIONS
32 <A
> Optional
<A
> get(QName key
, Class
<A
> clss
);
34 Class
<?
> getType(QName key
);
36 boolean isMultiple(QName key
);
38 <A
> List
<A
> getMultiple(QName key
, Class
<A
> clss
);
41 * ATTRIBUTES OPERATION HELPERS
43 default boolean containsKey(QNamed key
) {
44 return containsKey(key
.qName());
47 default <A
> Optional
<A
> get(QNamed key
, Class
<A
> clss
) {
48 return get(key
.qName(), clss
);
51 default Object
get(QNamed key
) {
52 return get(key
.qName());
55 default Object
put(QNamed key
, Object value
) {
56 return put(key
.qName(), value
);
59 default Object
remove(QNamed key
) {
60 return remove(key
.qName());
63 // TODO do we really need the helpers below?
65 default Object
get(String key
) {
66 return get(unqualified(key
));
69 default Object
put(String key
, Object value
) {
70 return put(unqualified(key
), value
);
73 default Object
remove(String key
) {
74 return remove(unqualified(key
));
77 @SuppressWarnings("unchecked")
78 default <A
> List
<A
> getMultiple(QName key
) {
81 type
= (Class
<A
>) getType(key
);
82 } catch (ClassCastException e
) {
83 throw new IllegalArgumentException("Requested type is not the default type");
85 List
<A
> res
= getMultiple(key
, type
);
92 Content
add(QName name
, QName
... classes
);
94 default Content
add(String name
, QName
... classes
) {
95 return add(unqualified(name
), classes
);
103 List
<QName
> getContentClasses();
105 default void addContentClasses(QName
... contentClass
) {
106 throw new UnsupportedOperationException("Adding content classes to " + getPath() + " is not supported");
110 default boolean isContentClass(QName
... contentClass
) {
111 List
<QName
> contentClasses
= getContentClasses();
112 for (QName cClass
: contentClass
) {
113 if (!contentClasses
.contains(cClass
))
120 default boolean isContentClass(QNamed
... contentClass
) {
121 List
<QName
> lst
= new ArrayList
<>();
122 for (QNamed qNamed
: contentClass
)
123 lst
.add(qNamed
.qName());
124 return isContentClass(lst
.toArray(new QName
[lst
.size()]));
128 default boolean hasContentClass(QName
... contentClass
) {
129 List
<QName
> contentClasses
= getContentClasses();
130 for (QName cClass
: contentClass
) {
131 if (contentClasses
.contains(cClass
))
138 default boolean hasContentClass(QNamed
... contentClass
) {
139 List
<QName
> lst
= new ArrayList
<>();
140 for (QNamed qNamed
: contentClass
)
141 lst
.add(qNamed
.qName());
142 return hasContentClass(lst
.toArray(new QName
[lst
.size()]));
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 List
<Content
> children(QNamed name
) {
214 return children(name
.qName());
217 default Optional
<Content
> soleChild(QNamed name
) {
218 return soleChild(name
.qName());
221 default Optional
<Content
> soleChild(QName name
) {
222 List
<Content
> res
= children(name
);
224 return Optional
.empty();
226 throw new IllegalStateException(this + " has multiple children with name " + name
);
227 return Optional
.of(res
.get(0));
230 default Content
child(QName name
) {
231 return soleChild(name
).orElseThrow();
234 default Content
child(QNamed name
) {
235 return child(name
.qName());
242 * Convenience method returning an attribute as a {@link String}.
244 * @param key the attribute name
245 * @return the attribute value as a {@link String} or <code>null</code>.
247 * @see Object#toString()
249 default String
attr(QName key
) {
250 return get(key
, String
.class).orElse(null);
254 * Convenience method returning an attribute as a {@link String}.
256 * @param key the attribute name
257 * @return the attribute value as a {@link String} or <code>null</code>.
259 * @see Object#toString()
261 default String
attr(QNamed key
) {
262 return attr(key
.qName());
266 * Convenience method returning an attribute as a {@link String}.
268 * @param key the attribute name
269 * @return the attribute value as a {@link String} or <code>null</code>.
271 * @see Object#toString()
273 default String
attr(String key
) {
274 return attr(unqualified(key
));
281 * A content within this repository
283 * @param path either an absolute path or a path relative to this content
285 Optional
<Content
> getContent(String path
);
288 * EXPERIMENTAL UNSUPPORTED
290 default boolean hasText() {
294 default String
getText() {
295 throw new UnsupportedOperationException();