X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.api.acr%2Fsrc%2Forg%2Fargeo%2Fapi%2Facr%2Fspi%2FAbstractContent.java;fp=org.argeo.api.acr%2Fsrc%2Forg%2Fargeo%2Fapi%2Facr%2Fspi%2FAbstractContent.java;h=6bfc7cd5f06e74c183835ead822aaf292f4f241e;hb=7d2a002f5dcfe8a8c7b29803b70d4b1aff265ed1;hp=0000000000000000000000000000000000000000;hpb=865fc51900459b888938cc0d6943673ee6f20d09;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.api.acr/src/org/argeo/api/acr/spi/AbstractContent.java b/org.argeo.api.acr/src/org/argeo/api/acr/spi/AbstractContent.java new file mode 100644 index 000000000..6bfc7cd5f --- /dev/null +++ b/org.argeo.api.acr/src/org/argeo/api/acr/spi/AbstractContent.java @@ -0,0 +1,164 @@ +package org.argeo.api.acr.spi; + +import java.util.AbstractMap; +import java.util.AbstractSet; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +import javax.xml.namespace.QName; + +import org.argeo.api.acr.Content; +import org.argeo.api.acr.CrName; + +public abstract class AbstractContent extends AbstractMap implements Content { + + /* + * ATTRIBUTES OPERATIONS + */ + protected abstract Iterable keys(); + + protected abstract void removeAttr(QName key); + + @Override + public Set> entrySet() { + Set> result = new AttrSet(); + return result; + } + + @Override + public Class getType(QName key) { + return String.class; + } + + @Override + public boolean isMultiple(QName key) { + return false; + } + + @Override + public Optional> getMultiple(QName key, Class clss) { + Object value = get(key); + if (value == null) + return null; + if (value instanceof List) { + try { + List res = (List) value; + return Optional.of(res); + } catch (ClassCastException e) { + List res = new ArrayList<>(); + List lst = (List) value; + try { + for (Object o : lst) { + A item = (A) o; + res.add(item); + } + return Optional.of(res); + } catch (ClassCastException e1) { + return Optional.empty(); + } + } + } else {// singleton + try { + A res = (A) value; + return Optional.of(Collections.singletonList(res)); + } catch (ClassCastException e) { + return Optional.empty(); + } + } + } + + /* + * CONTENT OPERATIONS + */ + + @Override + public String getPath() { + List ancestors = new ArrayList<>(); + collectAncestors(ancestors, this); + StringBuilder path = new StringBuilder(); + for (Content c : ancestors) { + QName name = c.getName(); + // FIXME + if (!CrName.ROOT.get().equals(name)) + path.append('/').append(name); + } + return path.toString(); + } + + private void collectAncestors(List ancestors, Content content) { + if (content == null) + return; + ancestors.add(0, content); + collectAncestors(ancestors, content.getParent()); + } + + /* + * UTILITIES + */ + protected boolean isDefaultAttrTypeRequested(Class clss) { + // check whether clss is Object.class + return clss.isAssignableFrom(Object.class); + } + + @Override + public String toString() { + return "content " + getPath(); + } + + /* + * SUB CLASSES + */ + + class AttrSet extends AbstractSet> { + + @Override + public Iterator> iterator() { + final Iterator keys = keys().iterator(); + Iterator> it = new Iterator>() { + + QName key = null; + + @Override + public boolean hasNext() { + return keys.hasNext(); + } + + @Override + public Entry next() { + key = keys.next(); + // TODO check type + Optional value = get(key, Object.class); + assert !value.isEmpty(); + AbstractMap.SimpleEntry entry = new SimpleEntry<>(key, value.get()); + return entry; + } + + @Override + public void remove() { + if (key != null) { + AbstractContent.this.removeAttr(key); + } else { + throw new IllegalStateException("Iteration has not started"); + } + } + + }; + return it; + } + + @Override + public int size() { + int count = 0; + for (QName key : keys()) { + count++; + } + return count; + } + + } +}