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