]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.api.acr/src/org/argeo/api/acr/Content.java
Clarify system roles
[lgpl/argeo-commons.git] / org.argeo.api.acr / src / org / argeo / api / acr / Content.java
1 package org.argeo.api.acr;
2
3 import java.io.Closeable;
4 import java.io.IOException;
5 import java.util.List;
6 import java.util.Map;
7 import java.util.Optional;
8 import java.util.concurrent.CompletableFuture;
9
10 import javax.xml.XMLConstants;
11 import javax.xml.namespace.QName;
12
13 /**
14 * A semi-structured content, with attributes, within a hierarchical structure.
15 */
16 public interface Content extends Iterable<Content>, Map<QName, Object> {
17
18 QName getName();
19
20 String getPath();
21
22 Content getParent();
23
24 /*
25 * ATTRIBUTES OPERATIONS
26 */
27
28 <A> Optional<A> get(QName key, Class<A> clss);
29
30 default Object get(String key) {
31 if (key.indexOf(':') >= 0)
32 throw new IllegalArgumentException("Name " + key + " has a prefix");
33 return get(new QName(XMLConstants.NULL_NS_URI, key, XMLConstants.DEFAULT_NS_PREFIX));
34 }
35
36 default Object put(String key, Object value) {
37 if (key.indexOf(':') >= 0)
38 throw new IllegalArgumentException("Name " + key + " has a prefix");
39 return put(new QName(XMLConstants.NULL_NS_URI, key, XMLConstants.DEFAULT_NS_PREFIX), value);
40 }
41
42 default Object remove(String key) {
43 if (key.indexOf(':') >= 0)
44 throw new IllegalArgumentException("Name " + key + " has a prefix");
45 return remove(new QName(XMLConstants.NULL_NS_URI, key, XMLConstants.DEFAULT_NS_PREFIX));
46 }
47
48 Class<?> getType(QName key);
49
50 boolean isMultiple(QName key);
51
52 <A> Optional<List<A>> getMultiple(QName key, Class<A> clss);
53
54 @SuppressWarnings("unchecked")
55 default <A> List<A> getMultiple(QName key) {
56 Class<A> type;
57 try {
58 type = (Class<A>) getType(key);
59 } catch (ClassCastException e) {
60 throw new IllegalArgumentException("Requested type is not the default type");
61 }
62 Optional<List<A>> res = getMultiple(key, type);
63 if (res == null)
64 return null;
65 else {
66 if (res.isEmpty())
67 throw new IllegalStateException("Metadata " + key + " is not availabel as list of type " + type);
68 return res.get();
69 }
70 }
71
72 /*
73 * CONTENT OPERATIONS
74 */
75 // default CompletionStage<Content> edit(Consumer<Content> work) {
76 // return CompletableFuture.supplyAsync(() -> {
77 // work.accept(this);
78 // return this;
79 // }).minimalCompletionStage();
80 // }
81
82 Content add(QName name, QName... classes);
83
84 default Content add(String name, QName... classes) {
85 if (name.indexOf(':') >= 0)
86 throw new IllegalArgumentException("Name " + name + " has a prefix");
87 return add(new QName(XMLConstants.NULL_NS_URI, name, XMLConstants.DEFAULT_NS_PREFIX), classes);
88 }
89
90 void remove();
91
92 /*
93 * TYPING
94 */
95 List<QName> getContentClasses();
96
97 /** AND */
98 default boolean isContentClass(QName... contentClass) {
99 List<QName> contentClasses = getContentClasses();
100 for (QName cClass : contentClass) {
101 if (!contentClasses.contains(cClass))
102 return false;
103 }
104 return true;
105 }
106
107 /** OR */
108 default boolean hasContentClass(QName... contentClass) {
109 List<QName> contentClasses = getContentClasses();
110 for (QName cClass : contentClass) {
111 if (contentClasses.contains(cClass))
112 return true;
113 }
114 return false;
115 }
116
117 /*
118 * DEFAULT METHODS
119 */
120 default <A> A adapt(Class<A> clss) {
121 throw new UnsupportedOperationException("Cannot adapt content " + this + " to " + clss.getName());
122 }
123
124 default <C extends Closeable> C open(Class<C> clss) throws IOException {
125 throw new UnsupportedOperationException("Cannot open content " + this + " as " + clss.getName());
126 }
127
128 default <A> CompletableFuture<A> write(Class<A> clss) {
129 throw new UnsupportedOperationException("Cannot write content " + this + " as " + clss.getName());
130 }
131
132 /*
133 * CONVENIENCE METHODS
134 */
135 default String attr(String key) {
136 Object obj = get(key);
137 if (obj == null)
138 return null;
139 return obj.toString();
140
141 }
142
143 default String attr(QName key) {
144 Object obj = get(key);
145 if (obj == null)
146 return null;
147 return obj.toString();
148
149 }
150 //
151 // default String attr(Object key) {
152 // return key != null ? attr(key.toString()) : attr(null);
153 // }
154 //
155 // default <A> A get(Object key, Class<A> clss) {
156 // return key != null ? get(key.toString(), clss) : get(null, clss);
157 // }
158
159 /*
160 * EXPERIMENTAL UNSUPPORTED
161 */
162 default boolean hasText() {
163 return false;
164 }
165
166 default String getText() {
167 throw new UnsupportedOperationException();
168 }
169
170 }