]> git.argeo.org Git - lgpl/argeo-commons.git/blob - AbstractContent.java
b614a14cbb0702ef2723bd11e12ee0943adcb2d1
[lgpl/argeo-commons.git] / AbstractContent.java
1 package org.argeo.cms.acr;
2
3 import java.util.AbstractMap;
4 import java.util.AbstractSet;
5 import java.util.ArrayList;
6 import java.util.Collections;
7 import java.util.Iterator;
8 import java.util.List;
9 import java.util.Map;
10 import java.util.Optional;
11 import java.util.Set;
12
13 import javax.xml.namespace.QName;
14
15 import org.argeo.api.acr.Content;
16 import org.argeo.api.acr.CrName;
17 import org.argeo.api.acr.spi.ProvidedContent;
18
19 /** Partial reference implementation of a {@link ProvidedContent}. */
20 public abstract class AbstractContent extends AbstractMap<QName, Object> implements ProvidedContent {
21
22 /*
23 * ATTRIBUTES OPERATIONS
24 */
25 protected abstract Iterable<QName> keys();
26
27 protected abstract void removeAttr(QName key);
28
29 @Override
30 public Set<Entry<QName, Object>> entrySet() {
31 Set<Entry<QName, Object>> result = new AttrSet();
32 return result;
33 }
34
35 @Override
36 public Class<?> getType(QName key) {
37 return String.class;
38 }
39
40 @Override
41 public boolean isMultiple(QName key) {
42 return false;
43 }
44
45 @SuppressWarnings("unchecked")
46 @Override
47 public <A> Optional<List<A>> getMultiple(QName key, Class<A> clss) {
48 Object value = get(key);
49 if (value == null)
50 return null;
51 if (value instanceof List) {
52 try {
53 List<A> res = (List<A>) value;
54 return Optional.of(res);
55 } catch (ClassCastException e) {
56 List<A> res = new ArrayList<>();
57 List<?> lst = (List<?>) value;
58 try {
59 for (Object o : lst) {
60 A item = (A) o;
61 res.add(item);
62 }
63 return Optional.of(res);
64 } catch (ClassCastException e1) {
65 return Optional.empty();
66 }
67 }
68 } else {// singleton
69 try {
70 A res = (A) value;
71 return Optional.of(Collections.singletonList(res));
72 } catch (ClassCastException e) {
73 return Optional.empty();
74 }
75 }
76 }
77
78 /*
79 * CONTENT OPERATIONS
80 */
81
82 @Override
83 public String getPath() {
84 List<Content> ancestors = new ArrayList<>();
85 collectAncestors(ancestors, this);
86 StringBuilder path = new StringBuilder();
87 for (Content c : ancestors) {
88 QName name = c.getName();
89 // FIXME
90 if (!CrName.ROOT.get().equals(name))
91 path.append('/').append(name);
92 }
93 return path.toString();
94 }
95
96 private void collectAncestors(List<Content> ancestors, Content content) {
97 if (content == null)
98 return;
99 ancestors.add(0, content);
100 collectAncestors(ancestors, content.getParent());
101 }
102
103 /*
104 * UTILITIES
105 */
106 protected boolean isDefaultAttrTypeRequested(Class<?> clss) {
107 // check whether clss is Object.class
108 return clss.isAssignableFrom(Object.class);
109 }
110
111 // @Override
112 // public String toString() {
113 // return "content " + getPath();
114 // }
115
116 /*
117 * SUB CLASSES
118 */
119
120 class AttrSet extends AbstractSet<Entry<QName, Object>> {
121
122 @Override
123 public Iterator<Entry<QName, Object>> iterator() {
124 final Iterator<QName> keys = keys().iterator();
125 Iterator<Entry<QName, Object>> it = new Iterator<Map.Entry<QName, Object>>() {
126
127 QName key = null;
128
129 @Override
130 public boolean hasNext() {
131 return keys.hasNext();
132 }
133
134 @Override
135 public Entry<QName, Object> next() {
136 key = keys.next();
137 // TODO check type
138 Optional<?> value = get(key, Object.class);
139 assert !value.isEmpty();
140 AbstractMap.SimpleEntry<QName, Object> entry = new SimpleEntry<>(key, value.get());
141 return entry;
142 }
143
144 @Override
145 public void remove() {
146 if (key != null) {
147 AbstractContent.this.removeAttr(key);
148 } else {
149 throw new IllegalStateException("Iteration has not started");
150 }
151 }
152
153 };
154 return it;
155 }
156
157 @Override
158 public int size() {
159
160 int count = 0;
161 for (Iterator<QName> it = keys().iterator(); it.hasNext();) {
162 count++;
163 }
164 return count;
165 }
166
167 }
168 }