A2_CATEGORY = org.argeo.suite
BUNDLES = \
-org.argeo.app.api \
+org.argeo.api.app \
org.argeo.app.core \
org.argeo.app.jcr \
org.argeo.app.geo \
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
--- /dev/null
+/bin/
+/target/
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.argeo.api.app</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
--- /dev/null
+/MANIFEST.MF
--- /dev/null
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
--- /dev/null
+package org.argeo.api.app;
+
+import org.argeo.api.acr.Content;
+import org.argeo.api.cms.CmsSession;
+
+/** Access to content which is specific to a user and their state. */
+public interface AppUserState {
+ Content getOrCreateSessionDir(CmsSession session);
+}
--- /dev/null
+package org.argeo.api.app;
+
+/** Constant related to entities, typically used in an OSGi context. */
+public interface EntityConstants {
+ final static String TYPE = "entity.type";
+// final static String DEFAULT_EDITOR_ID = "entity.defaultEditorId";
+
+}
--- /dev/null
+package org.argeo.api.app;
+
+/** The definition of an entity, a composite configurable data structure. */
+public interface EntityDefinition {
+// String getEditorId(Node entity);
+
+ String getType();
+}
--- /dev/null
+package org.argeo.api.app;
+
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+
+/** Supported mime types. */
+public enum EntityMimeType {
+ XML("text/xml", "xml"), CSV("text/csv", "csv");
+
+ private final String mimeType;
+ private final String[] extensions;
+
+ EntityMimeType(String mimeType, String... extensions) {
+ this.mimeType = mimeType;
+ this.extensions = extensions;
+ }
+
+ public String getMimeType() {
+ return mimeType;
+ }
+
+ public String[] getExtensions() {
+ return extensions;
+ }
+
+ public String getDefaultExtension() {
+ if (extensions.length > 0)
+ return extensions[0];
+ else
+ return null;
+ }
+
+ public String toHttpContentType(Charset charset) {
+ if (charset == null)
+ return mimeType;
+ return mimeType + "; charset=" + charset.name();
+ }
+
+ public String toHttpContentType() {
+ if (mimeType.startsWith("text/")) {
+ return toHttpContentType(StandardCharsets.UTF_8);
+ } else {
+ return mimeType;
+ }
+ }
+
+ public static EntityMimeType find(String mimeType) {
+ for (EntityMimeType entityMimeType : values()) {
+ if (entityMimeType.mimeType.equals(mimeType))
+ return entityMimeType;
+ }
+ return null;
+ }
+
+ @Override
+ public String toString() {
+ return mimeType;
+ }
+
+}
--- /dev/null
+package org.argeo.api.app;
+
+import org.argeo.api.acr.QNamed;
+
+/** Names used in the entity namespace http://www.argeo.org/ns/entity. */
+public enum EntityName implements QNamed {
+ type, relatedTo, //
+ // time,
+ date,
+ // geography
+ minLat, minLon, maxLat, maxLon,
+ // geo entities
+ place,
+ //
+ ;
+
+ @Override
+ public String getDefaultPrefix() {
+ return "entity";
+ }
+
+ public String basePath() {
+ return '/' + name();
+ }
+
+ @Override
+ public String getNamespace() {
+ return "http://www.argeo.org/ns/entity";
+ }
+
+}
--- /dev/null
+package org.argeo.api.app;
+
+import org.argeo.api.acr.ldap.LdapAttr;
+
+/** Constants used to name entity structures. */
+public interface EntityNames {
+ @Deprecated
+ final String FORM_BASE = "form";
+ final String SUBMISSIONS_BASE = "submissions";
+ @Deprecated
+ final String TERM = "term";
+ final String NAME = "name";
+
+// final String ENTITY_DEFINITIONS_PATH = "/entity";
+ @Deprecated
+ final String TYPOLOGIES_PATH = "/" + TERM;
+ /** Administrative units. */
+ final String ADM = "adm";
+
+ @Deprecated
+ final String ENTITY_TYPE = EntityName.type.get();
+
+ // GENERIC CONCEPTS
+// /** The language which is relevant. */
+// final String XML_LANG = "xml:lang";
+ /** The date which is relevant. */
+ @Deprecated
+ final String ENTITY_DATE = EntityName.date.get();
+ @Deprecated
+ final String ENTITY_RELATED_TO = EntityName.relatedTo.get();
+
+ // DEFAULT FOLDER NAMES
+ final String MEDIA = "media";
+ final String FILES = "files";
+
+ // LDAP-LIKE ENTITIES
+ @Deprecated
+ final String DISPLAY_NAME = LdapAttr.displayName.get();
+ // Persons
+ @Deprecated
+ final String GIVEN_NAME = LdapAttr.givenName.get();
+ @Deprecated
+ final String SURNAME = LdapAttr.sn.get();
+ @Deprecated
+ final String EMAIL = LdapAttr.mail.get();
+ @Deprecated
+ final String OU = LdapAttr.ou.get();
+
+ // WGS84
+ @Deprecated
+ final String GEO_LAT = WGS84PosName.lat.get();
+ @Deprecated
+ final String GEO_LONG = WGS84PosName.lon.get();
+ @Deprecated
+ final String GEO_ALT = WGS84PosName.alt.get();
+
+ // SVG
+ @Deprecated
+ final String SVG_WIDTH = "svg:width";
+ @Deprecated
+ final String SVG_HEIGHT = "svg:height";
+ @Deprecated
+ final String SVG_LENGTH = "svg:length";
+ @Deprecated
+ final String SVG_UNIT = "svg:unit";
+ @Deprecated
+ final String SVG_DUR = "svg:dur";
+ @Deprecated
+ final String SVG_DIRECTION = "svg:direction";
+}
--- /dev/null
+package org.argeo.api.app;
+
+import org.argeo.api.acr.QNamed;
+
+/** Types used in the entity namespace http://www.argeo.org/ns/entity. */
+public enum EntityType implements QNamed {
+ // entity
+ entity, local, relatedTo,
+ // structure
+ space, document,
+ // typology
+ typologies, terms, term,
+ // form
+ form, formSet, formSubmission,
+ // graphics
+ box,
+ // geography
+ geopoint, bearing, geobounded,
+ // ldap
+ person, user;
+
+ public final static String ENTITY_NAMESPACE_URI = "http://www.argeo.org/ns/entity";
+ public final static String ENTITY_DEFAULT_PREFIX = "entity";
+
+ @Override
+ public String getDefaultPrefix() {
+ return ENTITY_DEFAULT_PREFIX;
+ }
+
+ public String basePath() {
+ return '/' + name();
+ }
+
+ @Override
+ public String getNamespace() {
+ return ENTITY_NAMESPACE_URI;
+ }
+}
--- /dev/null
+package org.argeo.api.app;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.ThreadLocalRandom;
+
+/** A range of numerical IDs (typically numerical uid or gid). */
+public class IdRange {
+ // see https://systemd.io/UIDS-GIDS/#special-distribution-uid-ranges
+ final static long MIN_INCLUDED = Long.parseUnsignedLong("66000");
+ final static long MAX_EXCLUDED = Long.parseUnsignedLong("4294967294");
+
+ // We use long as a de facto unsigned int
+
+ /** included */
+ private final long min;
+ /** included */
+ private final long max;
+
+ public IdRange(long min, long max) {
+ this.min = min;
+ this.max = max;
+ }
+
+ public IdRange(long minPow10) {
+ this(minPow10, maxFromMinPow10(minPow10));
+ }
+
+ public long getMin() {
+ return min;
+ }
+
+ public long getMax() {
+ return max;
+ }
+
+ @Override
+ public int hashCode() {
+ return (int) min;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof IdRange idRange) {
+ return min == idRange.min && max == idRange.max;
+ } else
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return "[" + Long.toUnsignedString(min) + "," + Long.toUnsignedString(max) + "]";
+ }
+
+ /*
+ * RANGE GENERATION
+ */
+ public static synchronized Set<IdRange> randomRanges10000(int count, Set<IdRange> forbiddenRanges) {
+ Set<IdRange> res = new HashSet<>();
+
+ for (int i = 0; i < count; i++) {
+ IdRange newRange = null;
+ do {
+ newRange = randomRange10000();
+ } while (overlap(newRange, res) || overlap(newRange, forbiddenRanges));
+ res.add(newRange);
+ }
+ return res;
+ }
+
+ public static synchronized IdRange randomRange10000() {
+ // TODO make it more generic
+ long minPred = 7l;
+ long maxPred = 429496l;
+
+ long rand = ThreadLocalRandom.current().nextLong(minPred, maxPred);
+ long min = rand * 10000l;
+ return new IdRange(min);
+ }
+
+ public static boolean overlap(IdRange idRange, Set<IdRange> idRanges) {
+ for (IdRange other : idRanges) {
+ if (overlap(idRange, other))
+ return true;
+ }
+ return false;
+ }
+
+ public static boolean overlap(IdRange idRange, IdRange other) {
+ // see
+ // https://stackoverflow.com/questions/3269434/whats-the-most-efficient-way-to-test-if-two-ranges-overlap
+ return idRange.min <= other.max && other.min <= idRange.max;
+ }
+
+ /*
+ * UTILITIES
+ */
+
+ private static long maxFromMinPow10(long minPow10) {
+ if ((minPow10 % 100) != 0) {
+ throw new IllegalArgumentException(minPow10 + " must at least ends with two zeroes");
+ }
+ int exp = 2;
+ exp: for (int i = exp + 1; i < 10; i++) {
+ if ((minPow10 % pow10(i)) != 0)
+ break exp;
+ exp++;
+ }
+// System.out.println(exp);
+
+ long max = minPow10 + pow10(exp) - 1;
+ return max;
+ }
+
+ /** Power of 10. */
+ private static long pow10(int exp) {
+ if (exp == 0)
+ return 1;
+ else
+ return 10 * pow10(exp - 1);
+ }
+
+ public static void main(String... args) {
+ System.out.println(maxFromMinPow10(100));
+ System.out.println(maxFromMinPow10(78500));
+ System.out.println(maxFromMinPow10(716850000));
+
+// System.out.println(pow10(6));
+// System.out.println(maxFromMinPow10(12));
+// System.out.println(maxFromMinPow10(124));
+// System.out.println(maxFromMinPow10(99814565));
+ }
+}
--- /dev/null
+package org.argeo.api.app;
+
+import java.util.Map;
+
+import org.argeo.api.cms.CmsLog;
+
+/**
+ * A container for an object whose relevance can be ranked. Typically used in an
+ * OSGi context with the service.ranking property.
+ */
+public class RankedObject<T> {
+ private final static CmsLog log = CmsLog.getLog(RankedObject.class);
+
+ private final static String SERVICE_RANKING = "service.ranking";
+// private final static String SERVICE_ID = "service.id";
+
+ private T object;
+ private Map<String, Object> properties;
+ private final int rank;
+
+ public RankedObject(T object, Map<String, Object> properties) {
+ this(object, properties, extractRanking(properties));
+ }
+
+ public RankedObject(T object, Map<String, Object> properties, int rank) {
+ super();
+ this.object = object;
+ this.properties = properties;
+ this.rank = rank;
+ }
+
+ private static int extractRanking(Map<String, Object> properties) {
+ if (properties == null)
+ return 0;
+ if (properties.containsKey(SERVICE_RANKING))
+ return (Integer) properties.get(SERVICE_RANKING);
+// else if (properties.containsKey(SERVICE_ID))
+// return (Long) properties.get(SERVICE_ID);
+ else
+ return 0;
+ }
+
+ public T get() {
+ return object;
+ }
+
+ public Map<String, Object> getProperties() {
+ return properties;
+ }
+
+ public int getRank() {
+ return rank;
+ }
+
+ @Override
+ public int hashCode() {
+ return object.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof RankedObject))
+ return false;
+ RankedObject<?> other = (RankedObject<?>) obj;
+ return rank == other.rank && object.equals(other.object);
+ }
+
+ @Override
+ public String toString() {
+ return object.getClass().getName() + " with rank " + rank;
+ }
+
+ public static <K, T> boolean hasHigherRank(Map<K, RankedObject<T>> map, K key, Map<String, Object> properties) {
+ if (!map.containsKey(key))
+ return true;
+ RankedObject<T> rankedObject = new RankedObject<>(null, properties);
+ RankedObject<T> current = map.get(key);
+ return current.getRank() < rankedObject.getRank();
+ }
+
+ /**
+ * @return the {@link RankedObject}, or <code>null</code> if the current one was
+ * kept
+ */
+ public static <K, T> RankedObject<T> putIfHigherRank(Map<K, RankedObject<T>> map, K key, T object,
+ Map<String, Object> properties) {
+ RankedObject<T> rankedObject = new RankedObject<>(object, properties);
+ if (!map.containsKey(key)) {
+ map.put(key, rankedObject);
+ if (log.isTraceEnabled())
+ log.trace(
+ "Added " + key + " as " + object.getClass().getName() + " with rank " + rankedObject.getRank());
+ return rankedObject;
+ } else {
+ RankedObject<T> current = map.get(key);
+ if (current.getRank() < rankedObject.getRank()) {
+ map.put(key, rankedObject);
+ if (log.isDebugEnabled())
+ log.debug("Replaced " + key + " by " + object.getClass().getName() + " with rank "
+ + rankedObject.getRank());
+ return rankedObject;
+ } else if (current.getRank() == rankedObject.getRank()) {
+ log.error("Already " + key + " by " + current.get().getClass().getName() + " with rank "
+ + rankedObject.getRank() + ", ignoring " + rankedObject.get().getClass().getName());
+ return null;
+ } else {
+ return null;
+ }
+ }
+
+ }
+
+}
--- /dev/null
+package org.argeo.api.app;
+
+import javax.xml.namespace.QName;
+
+import org.argeo.api.acr.ArgeoNamespace;
+import org.argeo.api.acr.ContentName;
+import org.argeo.api.acr.ldap.LdapAttr;
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.api.cms.auth.SystemRole;
+
+/** Standard suite system roles. */
+public enum SuiteRole implements SystemRole {
+ /** An external person who has read access to part of the information. */
+ observer,
+ /** An active coworker. */
+ coworker,
+ /** Someone who is allowed validate and publish information. */
+ publisher,
+ /** Someone with manager status within an organisation. Does not necessarily give more rights. */
+ manager,
+ //
+ ;
+
+ private final static String QUALIFIER = "app.";
+
+ private final ContentName name;
+
+ SuiteRole() {
+ name = new ContentName(ArgeoNamespace.ROLE_NAMESPACE_URI, QUALIFIER + name());
+ }
+
+ @Override
+ public QName qName() {
+ return name;
+ }
+
+ @Deprecated
+ private String getRolePrefix() {
+ return "org.argeo.suite";
+ }
+
+ @Deprecated
+ public String dn() {
+ return new StringBuilder(LdapAttr.cn.name()).append("=").append(getRolePrefix()).append(".").append(name())
+ .append(",").append(CmsConstants.SYSTEM_ROLES_BASEDN).toString();
+ }
+}
--- /dev/null
+package org.argeo.api.app;
+
+import java.util.List;
+
+/**
+ * A name within a {@link Typology}, used to qualify an entity (categories,
+ * keywords, etc.).
+ */
+public interface Term {
+ String getId();
+
+ String getName();
+
+// String getRelativePath();
+
+ Typology getTypology();
+
+ List<? extends Term> getSubTerms();
+
+ Term getParentTerm();
+
+}
--- /dev/null
+package org.argeo.api.app;
+
+import java.util.List;
+import java.util.Set;
+
+/** Provides optimised access and utilities around terms typologies. */
+public interface TermsManager {
+ Typology getTypology(String typology);
+
+ Set<Typology> getTypologies();
+
+ Term getTerm(String id);
+
+ List<Term> listAllTerms(String typology);
+
+}
--- /dev/null
+package org.argeo.api.app;
+
+import java.util.List;
+
+/** A structured and exhaustive set of {@link Term}s. */
+public interface Typology {
+
+ String getId();
+
+ boolean isFlat();
+
+ List<? extends Term> getSubTerms();
+
+ Term findTermByName(String name);
+}
--- /dev/null
+package org.argeo.api.app;
+
+import org.argeo.api.acr.QNamed;
+
+/**
+ * Geographical coordinate in WGS84 reference datum.
+ *
+ * @see https://www.w3.org/2003/01/geo/
+ */
+public enum WGS84PosName implements QNamed {
+ lat, lon("long"), alt;
+
+ private final String localName;
+
+ private WGS84PosName() {
+ localName = null;
+ }
+
+ private WGS84PosName(String localName) {
+ this.localName = localName;
+ }
+
+ @Override
+ public String getNamespace() {
+ return "http://www.w3.org/2003/01/geo/wgs84_pos#";
+ }
+
+ @Override
+ public String getDefaultPrefix() {
+ return "geo";
+ }
+
+ @Override
+ public String localName() {
+ if (localName != null)
+ return localName;
+ return QNamed.super.localName();
+ }
+
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified" attributeFormDefault="unqualified"
+ targetNamespace="http://www.argeo.org/ns/entity"
+ xmlns:entity="http://www.argeo.org/ns/entity">
+
+ <xs:attribute name="date" type="xs:date" />
+
+ <xs:element name="local">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:any minOccurs="0" maxOccurs="unbounded"
+ namespace="##local" processContents="lax" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="##any"
+ processContents="lax" />
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="terms">
+ <xs:complexType>
+ <xs:sequence minOccurs="0" maxOccurs="unbounded">
+ <xs:element ref="entity:term"></xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="term">
+ <xs:complexType>
+ <xs:sequence minOccurs="0" maxOccurs="unbounded">
+ <xs:element ref="entity:term"></xs:element>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##any"
+ processContents="lax" />
+ </xs:complexType>
+ </xs:element>
+</xs:schema>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns="http://apaf.on.netiket.eu/ns/apaf"
+ targetNamespace="http://apaf.on.netiket.eu/ns/apaf"
+ xmlns:entity="http://www.argeo.org/ns/entity" xmlns:dav="DAV:"
+ xmlns:gml="http://www.opengis.net/gml">
+<!-- <xs:import -->
+<!-- schemaLocation="entity.xsd" -->
+<!-- namespace="http://www.argeo.org/ns/entity"></xs:import> -->
+ <!-- <xs:import -->
+ <!-- schemaLocation="https://schemas.opengis.net/gml/3.2.1/gml.xsd" -->
+ <!-- namespace="http://www.opengis.net/gml/3.2"></xs:import> -->
+ <xs:import namespace="http://www.opengis.net/gml"
+ schemaLocation="http://schemas.opengis.net/gml/3.1.1/base/gml.xsd" />
+
+ <xs:complexType name="entityFeatureType">
+ <xs:complexContent>
+ <xs:extension base="gml:AbstractFeatureType">
+ <xs:sequence>
+ <xs:element name="area" type="gml:PolygonPropertyType" />
+ <xs:element name="geopoint" type="gml:PointPropertyType" />
+ <xs:element name="path" type="xs:string" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="entityFeature" type="entityFeatureType"
+ substitutionGroup="gml:_Feature" />
+
+ <!-- <xs:complexType name="TestFeatureCollectionType"> <xs:complexContent>
+ <xs:extension base="gml:AbstractFeatureCollectionType" /> </xs:complexContent>
+ </xs:complexType> <xs:element name="TestFeatureCollection" type="TestFeatureCollectionType"
+ /> -->
+
+</xs:schema>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17"/>
- <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
- <classpathentry kind="src" path="src"/>
- <classpathentry kind="output" path="bin"/>
-</classpath>
+++ /dev/null
-/bin/
-/target/
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>org.argeo.app.api</name>
- <comment></comment>
- <projects>
- </projects>
- <buildSpec>
- <buildCommand>
- <name>org.eclipse.jdt.core.javabuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.ManifestBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.SchemaBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>org.eclipse.pde.PluginNature</nature>
- <nature>org.eclipse.jdt.core.javanature</nature>
- </natures>
-</projectDescription>
+++ /dev/null
-/MANIFEST.MF
+++ /dev/null
-source.. = src/
-output.. = bin/
-bin.includes = META-INF/,\
- .
+++ /dev/null
-package org.argeo.app.api;
-
-import org.argeo.api.acr.Content;
-import org.argeo.api.cms.CmsSession;
-
-/** Access to content which is specific to a user and their state. */
-public interface AppUserState {
- Content getOrCreateSessionDir(CmsSession session);
-}
+++ /dev/null
-package org.argeo.app.api;
-
-/** Constant related to entities, typically used in an OSGi context. */
-public interface EntityConstants {
- final static String TYPE = "entity.type";
-// final static String DEFAULT_EDITOR_ID = "entity.defaultEditorId";
-
-}
+++ /dev/null
-package org.argeo.app.api;
-
-/** The definition of an entity, a composite configurable data structure. */
-public interface EntityDefinition {
-// String getEditorId(Node entity);
-
- String getType();
-}
+++ /dev/null
-package org.argeo.app.api;
-
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-
-/** Supported mime types. */
-public enum EntityMimeType {
- XML("text/xml", "xml"), CSV("text/csv", "csv");
-
- private final String mimeType;
- private final String[] extensions;
-
- EntityMimeType(String mimeType, String... extensions) {
- this.mimeType = mimeType;
- this.extensions = extensions;
- }
-
- public String getMimeType() {
- return mimeType;
- }
-
- public String[] getExtensions() {
- return extensions;
- }
-
- public String getDefaultExtension() {
- if (extensions.length > 0)
- return extensions[0];
- else
- return null;
- }
-
- public String toHttpContentType(Charset charset) {
- if (charset == null)
- return mimeType;
- return mimeType + "; charset=" + charset.name();
- }
-
- public String toHttpContentType() {
- if (mimeType.startsWith("text/")) {
- return toHttpContentType(StandardCharsets.UTF_8);
- } else {
- return mimeType;
- }
- }
-
- public static EntityMimeType find(String mimeType) {
- for (EntityMimeType entityMimeType : values()) {
- if (entityMimeType.mimeType.equals(mimeType))
- return entityMimeType;
- }
- return null;
- }
-
- @Override
- public String toString() {
- return mimeType;
- }
-
-}
+++ /dev/null
-package org.argeo.app.api;
-
-import org.argeo.api.acr.QNamed;
-
-/** Names used in the entity namespace http://www.argeo.org/ns/entity. */
-public enum EntityName implements QNamed {
- type, relatedTo, //
- // time,
- date,
- // geography
- minLat, minLon, maxLat, maxLon,
- // geo entities
- place,
- //
- ;
-
- @Override
- public String getDefaultPrefix() {
- return "entity";
- }
-
- public String basePath() {
- return '/' + name();
- }
-
- @Override
- public String getNamespace() {
- return "http://www.argeo.org/ns/entity";
- }
-
-}
+++ /dev/null
-package org.argeo.app.api;
-
-import org.argeo.api.acr.ldap.LdapAttr;
-
-/** Constants used to name entity structures. */
-public interface EntityNames {
- @Deprecated
- final String FORM_BASE = "form";
- final String SUBMISSIONS_BASE = "submissions";
- @Deprecated
- final String TERM = "term";
- final String NAME = "name";
-
-// final String ENTITY_DEFINITIONS_PATH = "/entity";
- @Deprecated
- final String TYPOLOGIES_PATH = "/" + TERM;
- /** Administrative units. */
- final String ADM = "adm";
-
- @Deprecated
- final String ENTITY_TYPE = EntityName.type.get();
-
- // GENERIC CONCEPTS
-// /** The language which is relevant. */
-// final String XML_LANG = "xml:lang";
- /** The date which is relevant. */
- @Deprecated
- final String ENTITY_DATE = EntityName.date.get();
- @Deprecated
- final String ENTITY_RELATED_TO = EntityName.relatedTo.get();
-
- // DEFAULT FOLDER NAMES
- final String MEDIA = "media";
- final String FILES = "files";
-
- // LDAP-LIKE ENTITIES
- @Deprecated
- final String DISPLAY_NAME = LdapAttr.displayName.get();
- // Persons
- @Deprecated
- final String GIVEN_NAME = LdapAttr.givenName.get();
- @Deprecated
- final String SURNAME = LdapAttr.sn.get();
- @Deprecated
- final String EMAIL = LdapAttr.mail.get();
- @Deprecated
- final String OU = LdapAttr.ou.get();
-
- // WGS84
- @Deprecated
- final String GEO_LAT = WGS84PosName.lat.get();
- @Deprecated
- final String GEO_LONG = WGS84PosName.lon.get();
- @Deprecated
- final String GEO_ALT = WGS84PosName.alt.get();
-
- // SVG
- @Deprecated
- final String SVG_WIDTH = "svg:width";
- @Deprecated
- final String SVG_HEIGHT = "svg:height";
- @Deprecated
- final String SVG_LENGTH = "svg:length";
- @Deprecated
- final String SVG_UNIT = "svg:unit";
- @Deprecated
- final String SVG_DUR = "svg:dur";
- @Deprecated
- final String SVG_DIRECTION = "svg:direction";
-}
+++ /dev/null
-package org.argeo.app.api;
-
-import org.argeo.api.acr.QNamed;
-
-/** Types used in the entity namespace http://www.argeo.org/ns/entity. */
-public enum EntityType implements QNamed {
- // entity
- entity, local, relatedTo,
- // structure
- space, document,
- // typology
- typologies, terms, term,
- // form
- form, formSet, formSubmission,
- // graphics
- box,
- // geography
- geopoint, bearing, geobounded,
- // ldap
- person, user;
-
- public final static String ENTITY_NAMESPACE_URI = "http://www.argeo.org/ns/entity";
- public final static String ENTITY_DEFAULT_PREFIX = "entity";
-
- @Override
- public String getDefaultPrefix() {
- return ENTITY_DEFAULT_PREFIX;
- }
-
- public String basePath() {
- return '/' + name();
- }
-
- @Override
- public String getNamespace() {
- return ENTITY_NAMESPACE_URI;
- }
-}
+++ /dev/null
-package org.argeo.app.api;
-
-import java.util.HashSet;
-import java.util.Set;
-import java.util.concurrent.ThreadLocalRandom;
-
-/** A range of numerical IDs (typically numerical uid or gid). */
-public class IdRange {
- // see https://systemd.io/UIDS-GIDS/#special-distribution-uid-ranges
- final static long MIN_INCLUDED = Long.parseUnsignedLong("66000");
- final static long MAX_EXCLUDED = Long.parseUnsignedLong("4294967294");
-
- // We use long as a de facto unsigned int
-
- /** included */
- private final long min;
- /** included */
- private final long max;
-
- public IdRange(long min, long max) {
- this.min = min;
- this.max = max;
- }
-
- public IdRange(long minPow10) {
- this(minPow10, maxFromMinPow10(minPow10));
- }
-
- public long getMin() {
- return min;
- }
-
- public long getMax() {
- return max;
- }
-
- @Override
- public int hashCode() {
- return (int) min;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof IdRange idRange) {
- return min == idRange.min && max == idRange.max;
- } else
- return false;
- }
-
- @Override
- public String toString() {
- return "[" + Long.toUnsignedString(min) + "," + Long.toUnsignedString(max) + "]";
- }
-
- /*
- * RANGE GENERATION
- */
- public static synchronized Set<IdRange> randomRanges10000(int count, Set<IdRange> forbiddenRanges) {
- Set<IdRange> res = new HashSet<>();
-
- for (int i = 0; i < count; i++) {
- IdRange newRange = null;
- do {
- newRange = randomRange10000();
- } while (overlap(newRange, res) || overlap(newRange, forbiddenRanges));
- res.add(newRange);
- }
- return res;
- }
-
- public static synchronized IdRange randomRange10000() {
- // TODO make it more generic
- long minPred = 7l;
- long maxPred = 429496l;
-
- long rand = ThreadLocalRandom.current().nextLong(minPred, maxPred);
- long min = rand * 10000l;
- return new IdRange(min);
- }
-
- public static boolean overlap(IdRange idRange, Set<IdRange> idRanges) {
- for (IdRange other : idRanges) {
- if (overlap(idRange, other))
- return true;
- }
- return false;
- }
-
- public static boolean overlap(IdRange idRange, IdRange other) {
- // see
- // https://stackoverflow.com/questions/3269434/whats-the-most-efficient-way-to-test-if-two-ranges-overlap
- return idRange.min <= other.max && other.min <= idRange.max;
- }
-
- /*
- * UTILITIES
- */
-
- private static long maxFromMinPow10(long minPow10) {
- if ((minPow10 % 100) != 0) {
- throw new IllegalArgumentException(minPow10 + " must at least ends with two zeroes");
- }
- int exp = 2;
- exp: for (int i = exp + 1; i < 10; i++) {
- if ((minPow10 % pow10(i)) != 0)
- break exp;
- exp++;
- }
-// System.out.println(exp);
-
- long max = minPow10 + pow10(exp) - 1;
- return max;
- }
-
- /** Power of 10. */
- private static long pow10(int exp) {
- if (exp == 0)
- return 1;
- else
- return 10 * pow10(exp - 1);
- }
-
- public static void main(String... args) {
- System.out.println(maxFromMinPow10(100));
- System.out.println(maxFromMinPow10(78500));
- System.out.println(maxFromMinPow10(716850000));
-
-// System.out.println(pow10(6));
-// System.out.println(maxFromMinPow10(12));
-// System.out.println(maxFromMinPow10(124));
-// System.out.println(maxFromMinPow10(99814565));
- }
-}
+++ /dev/null
-package org.argeo.app.api;
-
-import java.util.Map;
-
-import org.argeo.api.cms.CmsLog;
-
-/**
- * A container for an object whose relevance can be ranked. Typically used in an
- * OSGi context with the service.ranking property.
- */
-public class RankedObject<T> {
- private final static CmsLog log = CmsLog.getLog(RankedObject.class);
-
- private final static String SERVICE_RANKING = "service.ranking";
-// private final static String SERVICE_ID = "service.id";
-
- private T object;
- private Map<String, Object> properties;
- private final int rank;
-
- public RankedObject(T object, Map<String, Object> properties) {
- this(object, properties, extractRanking(properties));
- }
-
- public RankedObject(T object, Map<String, Object> properties, int rank) {
- super();
- this.object = object;
- this.properties = properties;
- this.rank = rank;
- }
-
- private static int extractRanking(Map<String, Object> properties) {
- if (properties == null)
- return 0;
- if (properties.containsKey(SERVICE_RANKING))
- return (Integer) properties.get(SERVICE_RANKING);
-// else if (properties.containsKey(SERVICE_ID))
-// return (Long) properties.get(SERVICE_ID);
- else
- return 0;
- }
-
- public T get() {
- return object;
- }
-
- public Map<String, Object> getProperties() {
- return properties;
- }
-
- public int getRank() {
- return rank;
- }
-
- @Override
- public int hashCode() {
- return object.hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (!(obj instanceof RankedObject))
- return false;
- RankedObject<?> other = (RankedObject<?>) obj;
- return rank == other.rank && object.equals(other.object);
- }
-
- @Override
- public String toString() {
- return object.getClass().getName() + " with rank " + rank;
- }
-
- public static <K, T> boolean hasHigherRank(Map<K, RankedObject<T>> map, K key, Map<String, Object> properties) {
- if (!map.containsKey(key))
- return true;
- RankedObject<T> rankedObject = new RankedObject<>(null, properties);
- RankedObject<T> current = map.get(key);
- return current.getRank() < rankedObject.getRank();
- }
-
- /**
- * @return the {@link RankedObject}, or <code>null</code> if the current one was
- * kept
- */
- public static <K, T> RankedObject<T> putIfHigherRank(Map<K, RankedObject<T>> map, K key, T object,
- Map<String, Object> properties) {
- RankedObject<T> rankedObject = new RankedObject<>(object, properties);
- if (!map.containsKey(key)) {
- map.put(key, rankedObject);
- if (log.isTraceEnabled())
- log.trace(
- "Added " + key + " as " + object.getClass().getName() + " with rank " + rankedObject.getRank());
- return rankedObject;
- } else {
- RankedObject<T> current = map.get(key);
- if (current.getRank() < rankedObject.getRank()) {
- map.put(key, rankedObject);
- if (log.isDebugEnabled())
- log.debug("Replaced " + key + " by " + object.getClass().getName() + " with rank "
- + rankedObject.getRank());
- return rankedObject;
- } else if (current.getRank() == rankedObject.getRank()) {
- log.error("Already " + key + " by " + current.get().getClass().getName() + " with rank "
- + rankedObject.getRank() + ", ignoring " + rankedObject.get().getClass().getName());
- return null;
- } else {
- return null;
- }
- }
-
- }
-
-}
+++ /dev/null
-package org.argeo.app.api;
-
-import javax.xml.namespace.QName;
-
-import org.argeo.api.acr.ArgeoNamespace;
-import org.argeo.api.acr.ContentName;
-import org.argeo.api.acr.ldap.LdapAttr;
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.cms.SystemRole;
-
-/** Standard suite system roles. */
-public enum SuiteRole implements SystemRole {
- /** An external person who has read access to part of the information. */
- observer,
- /** An active coworker. */
- coworker,
- /** Someone who is allowed validate and publish information. */
- publisher,
- /** Someone with manager status within an organisation. Does not necessarily give more rights. */
- manager,
- //
- ;
-
- private final static String QUALIFIER = "app.";
-
- private final ContentName name;
-
- SuiteRole() {
- name = new ContentName(ArgeoNamespace.ROLE_NAMESPACE_URI, QUALIFIER + name());
- }
-
- @Override
- public QName qName() {
- return name;
- }
-
- @Deprecated
- private String getRolePrefix() {
- return "org.argeo.suite";
- }
-
- @Deprecated
- public String dn() {
- return new StringBuilder(LdapAttr.cn.name()).append("=").append(getRolePrefix()).append(".").append(name())
- .append(",").append(CmsConstants.SYSTEM_ROLES_BASEDN).toString();
- }
-}
+++ /dev/null
-package org.argeo.app.api;
-
-import java.util.List;
-
-/**
- * A name within a {@link Typology}, used to qualify an entity (categories,
- * keywords, etc.).
- */
-public interface Term {
- String getId();
-
- String getName();
-
-// String getRelativePath();
-
- Typology getTypology();
-
- List<? extends Term> getSubTerms();
-
- Term getParentTerm();
-
-}
+++ /dev/null
-package org.argeo.app.api;
-
-import java.util.List;
-import java.util.Set;
-
-/** Provides optimised access and utilities around terms typologies. */
-public interface TermsManager {
- Typology getTypology(String typology);
-
- Set<Typology> getTypologies();
-
- Term getTerm(String id);
-
- List<Term> listAllTerms(String typology);
-
-}
+++ /dev/null
-package org.argeo.app.api;
-
-import java.util.List;
-
-/** A structured and exhaustive set of {@link Term}s. */
-public interface Typology {
-
- String getId();
-
- boolean isFlat();
-
- List<? extends Term> getSubTerms();
-
- Term findTermByName(String name);
-}
+++ /dev/null
-package org.argeo.app.api;
-
-import org.argeo.api.acr.QNamed;
-
-/**
- * Geographical coordinate in WGS84 reference datum.
- *
- * @see https://www.w3.org/2003/01/geo/
- */
-public enum WGS84PosName implements QNamed {
- lat, lon("long"), alt;
-
- private final String localName;
-
- private WGS84PosName() {
- localName = null;
- }
-
- private WGS84PosName(String localName) {
- this.localName = localName;
- }
-
- @Override
- public String getNamespace() {
- return "http://www.w3.org/2003/01/geo/wgs84_pos#";
- }
-
- @Override
- public String getDefaultPrefix() {
- return "geo";
- }
-
- @Override
- public String localName() {
- if (localName != null)
- return localName;
- return QNamed.super.localName();
- }
-
-}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
- elementFormDefault="qualified" attributeFormDefault="unqualified"
- targetNamespace="http://www.argeo.org/ns/entity"
- xmlns:entity="http://www.argeo.org/ns/entity">
-
- <xs:attribute name="date" type="xs:date" />
-
- <xs:element name="local">
- <xs:complexType>
- <xs:sequence>
- <xs:any minOccurs="0" maxOccurs="unbounded"
- namespace="##local" processContents="lax" />
- </xs:sequence>
- <xs:anyAttribute namespace="##any"
- processContents="lax" />
- </xs:complexType>
- </xs:element>
-
- <xs:element name="terms">
- <xs:complexType>
- <xs:sequence minOccurs="0" maxOccurs="unbounded">
- <xs:element ref="entity:term"></xs:element>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
-
- <xs:element name="term">
- <xs:complexType>
- <xs:sequence minOccurs="0" maxOccurs="unbounded">
- <xs:element ref="entity:term"></xs:element>
- </xs:sequence>
- <xs:anyAttribute namespace="##any"
- processContents="lax" />
- </xs:complexType>
- </xs:element>
-</xs:schema>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
- xmlns="http://apaf.on.netiket.eu/ns/apaf"
- targetNamespace="http://apaf.on.netiket.eu/ns/apaf"
- xmlns:entity="http://www.argeo.org/ns/entity" xmlns:dav="DAV:"
- xmlns:gml="http://www.opengis.net/gml">
-<!-- <xs:import -->
-<!-- schemaLocation="entity.xsd" -->
-<!-- namespace="http://www.argeo.org/ns/entity"></xs:import> -->
- <!-- <xs:import -->
- <!-- schemaLocation="https://schemas.opengis.net/gml/3.2.1/gml.xsd" -->
- <!-- namespace="http://www.opengis.net/gml/3.2"></xs:import> -->
- <xs:import namespace="http://www.opengis.net/gml"
- schemaLocation="http://schemas.opengis.net/gml/3.1.1/base/gml.xsd" />
-
- <xs:complexType name="entityFeatureType">
- <xs:complexContent>
- <xs:extension base="gml:AbstractFeatureType">
- <xs:sequence>
- <xs:element name="area" type="gml:PolygonPropertyType" />
- <xs:element name="geopoint" type="gml:PointPropertyType" />
- <xs:element name="path" type="xs:string" />
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>
-
- <xs:element name="entityFeature" type="entityFeatureType"
- substitutionGroup="gml:_Feature" />
-
- <!-- <xs:complexType name="TestFeatureCollectionType"> <xs:complexContent>
- <xs:extension base="gml:AbstractFeatureCollectionType" /> </xs:complexContent>
- </xs:complexType> <xs:element name="TestFeatureCollection" type="TestFeatureCollectionType"
- /> -->
-
-</xs:schema>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="start" name="org.argeo.app.termsContentProvider">
<implementation class="org.argeo.app.acr.terms.TermsContentProvider"/>
- <reference bind="setService" cardinality="1..1" interface="org.argeo.app.api.TermsManager" name="TermsManager" policy="static"/>
+ <reference bind="setService" cardinality="1..1" interface="org.argeo.api.app.TermsManager" name="TermsManager" policy="static"/>
<service>
<provide interface="org.argeo.api.acr.spi.ContentProvider"/>
</service>
import org.argeo.api.acr.NamespaceUtils;
import org.argeo.api.acr.spi.ContentProvider;
import org.argeo.api.acr.spi.ProvidedSession;
-import org.argeo.app.api.Term;
+import org.argeo.api.app.Term;
import org.argeo.cms.acr.AbstractContent;
public class TermContent extends AbstractContent {
import org.argeo.api.acr.ContentNotFoundException;
import org.argeo.api.acr.spi.ProvidedContent;
import org.argeo.api.acr.spi.ProvidedSession;
-import org.argeo.app.api.EntityType;
-import org.argeo.app.api.Term;
-import org.argeo.app.api.TermsManager;
-import org.argeo.app.api.Typology;
+import org.argeo.api.app.EntityType;
+import org.argeo.api.app.Term;
+import org.argeo.api.app.TermsManager;
+import org.argeo.api.app.Typology;
import org.argeo.cms.acr.AbstractSimpleContentProvider;
import org.argeo.cms.acr.ContentUtils;
import org.argeo.api.acr.NamespaceUtils;
import org.argeo.api.acr.spi.ContentProvider;
import org.argeo.api.acr.spi.ProvidedSession;
-import org.argeo.app.api.Typology;
+import org.argeo.api.app.Typology;
import org.argeo.cms.acr.AbstractContent;
public class TypologyContent extends AbstractContent {
package org.argeo.app.core;
-import org.argeo.app.api.EntityDefinition;
+import org.argeo.api.app.EntityDefinition;
public abstract class AbstractEntityDefinition implements EntityDefinition {
package org.argeo.app.core;
+import static java.lang.System.Logger.Level.ERROR;
+
import java.net.MalformedURLException;
+import java.net.URI;
import java.net.URL;
import java.util.Objects;
import org.argeo.api.acr.spi.ContentNamespace;
+import org.argeo.cms.acr.CmsContentNamespace;
public enum SuiteContentNamespace implements ContentNamespace {
//
// ARGEO
//
- ENTITY("entity", "http://www.argeo.org/ns/entity", "/org/argeo/app/api/entity.xsd", null),
+ ENTITY("entity", "http://www.argeo.org/ns/entity",
+ "platform:/plugin/org.argeo.app.api/org/argeo/api/app/entity.xsd", null),
//
ARGEO_DBK("argeodbk", "http://www.argeo.org/ns/argeodbk", null, null),
//
ODK("odk", "http://www.opendatakit.org/xforms", null, null),
//
WGS84("geo", "http://www.w3.org/2003/01/geo/wgs84_pos#", null, null),
+ // Re-add XML in order to solve import issue with xlink
+ XML("xml", "http://www.w3.org/XML/1998/namespace", "xml.xsd", "http://www.w3.org/2001/xml.xsd"),
//
+
;
private final static String RESOURCE_BASE = "/org/argeo/app/core/schemas/";
Objects.requireNonNull(namespace);
this.namespace = namespace;
if (resourceFileName != null) {
- if (!resourceFileName.startsWith("/"))
- resource = getClass().getResource(RESOURCE_BASE + resourceFileName);
- else
- resource = getClass().getResource(resourceFileName);
- Objects.requireNonNull(resource);
+ try {
+ // FIXME workaround when in nested OSGi frameworks
+ // we should use class path, as before
+ if (!resourceFileName.startsWith("platform:")) {
+ resource = URI.create("platform:/plugin/org.argeo.app.core" + RESOURCE_BASE + resourceFileName)
+ .toURL();
+ } else {
+ resource = URI.create(resourceFileName).toURL();
+ }
+ } catch (MalformedURLException e) {
+ resource = null;
+ System.getLogger(CmsContentNamespace.class.getName()).log(ERROR,
+ "Cannot load " + resourceFileName + ": " + e.getMessage());
+ // throw new IllegalArgumentException("Cannot convert " + resourceFileName + "
+ // to URL");
+ }
+ // Objects.requireNonNull(resource);
}
if (publicUrl != null)
try {
import org.argeo.api.acr.Content;
import org.argeo.api.acr.ldap.LdapAttr;
import org.argeo.api.acr.ldap.LdapObj;
-import org.argeo.app.api.EntityType;
-import org.argeo.cms.RoleNameUtils;
+import org.argeo.api.app.EntityType;
+import org.argeo.api.cms.auth.RoleNameUtils;
/** Utilities around the Argeo Suite APIs. */
public class SuiteUtils {
package org.argeo.app.docbook;
import org.argeo.api.acr.Content;
-import org.argeo.app.api.EntityType;
+import org.argeo.api.app.EntityType;
/** Utilities when using ACR to access DocBook. */
public class DbkAcrUtils {
</service>
<property name="context.path" type="String" value="/api/wfs/" />
<reference bind="setContentRepository" cardinality="1..1" interface="org.argeo.api.acr.spi.ProvidedRepository" name="ProvidedRepository" policy="static"/>
- <reference bind="addFeatureAdapter" cardinality="0..n" interface="org.argeo.app.api.geo.FeatureAdapter" name="FeatureAdapter" policy="dynamic" unbind="removeFeatureAdapter"/>
+ <reference bind="addFeatureAdapter" cardinality="0..n" interface="org.argeo.api.app.geo.FeatureAdapter" name="FeatureAdapter" policy="dynamic" unbind="removeFeatureAdapter"/>
</scr:component>
--- /dev/null
+package org.argeo.api.app.geo;
+
+import javax.xml.namespace.QName;
+
+import org.argeo.api.acr.Content;
+import org.argeo.api.acr.search.AndFilter;
+import org.locationtech.jts.geom.Geometry;
+
+import jakarta.json.stream.JsonGenerator;
+
+/** Transform a {@link Content} to an OGC feature. */
+public interface FeatureAdapter {
+ Geometry getDefaultGeometry(Content c, QName targetFeature);
+
+ void writeProperties(JsonGenerator g, Content content, QName targetFeature);
+
+ void addConstraintsForFeature(AndFilter filter, QName targetFeature);
+}
--- /dev/null
+package org.argeo.api.app.geo;
+
+/** Keys used for WFS KVP (key-value pair) encoding. */
+public enum WfsKvp {
+ CQL_FILTER("cql_filter"), //
+ OUTPUT_FORMAT("outputFormat"), //
+ TYPE_NAMES("typeNames"), //
+ BBOX("bbox"), //
+ FORMAT_OPTIONS("format_options"), //
+ ;
+
+ public final static String FILENAME_ = "filename:";
+
+ private final String key;
+
+ private WfsKvp(String key) {
+ this.key = key;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+}
+++ /dev/null
-package org.argeo.app.api.geo;
-
-import javax.xml.namespace.QName;
-
-import org.argeo.api.acr.Content;
-import org.argeo.api.acr.search.AndFilter;
-import org.argeo.app.api.EntityType;
-import org.argeo.app.geo.acr.GeoEntityUtils;
-import org.locationtech.jts.geom.Geometry;
-
-import jakarta.json.stream.JsonGenerator;
-
-public interface FeatureAdapter {
- default Geometry getDefaultGeometry(Content c, QName targetFeature) {
- // TODO deal with more defaults
- // TODO deal with target feature
- if (c.hasContentClass(EntityType.geopoint)) {
- return getGeoPointGeometry(c);
- }
- return null;
- }
-
- void writeProperties(JsonGenerator g, Content content, QName targetFeature);
-
- void addConstraintsForFeature(AndFilter filter, QName targetFeature);
-
- static Geometry getGeoPointGeometry(Content c) {
- if (c.hasContentClass(EntityType.geopoint)) {
- return GeoEntityUtils.toPoint(c);
-// double latitude = c.get(WGS84PosName.lat, Double.class).get();
-// double longitude = c.get(WGS84PosName.lon, Double.class).get();
-//
-// Coordinate coordinate = new Coordinate(longitude, latitude);
-// Point the_geom = JTS.GEOMETRY_FACTORY.createPoint(coordinate);
-// return the_geom;
- }
- return null;
- }
-}
+++ /dev/null
-package org.argeo.app.api.geo;
-
-/** Keys used for WFS KVP (key-value pair) encoding. */
-public enum WfsKvp {
- CQL_FILTER("cql_filter"), //
- OUTPUT_FORMAT("outputFormat"), //
- TYPE_NAMES("typeNames"), //
- BBOX("bbox"), //
- FORMAT_OPTIONS("format_options"), //
- ;
-
- public final static String FILENAME_ = "filename:";
-
- private final String key;
-
- private WfsKvp(String key) {
- this.key = key;
- }
-
- public String getKey() {
- return key;
- }
-
-}
--- /dev/null
+package org.argeo.app.geo.acr;
+
+import javax.xml.namespace.QName;
+
+import org.argeo.api.acr.Content;
+import org.argeo.api.app.EntityType;
+import org.argeo.api.app.geo.FeatureAdapter;
+import org.locationtech.jts.geom.Geometry;
+
+public abstract class AbstractFeatureAdapter implements FeatureAdapter {
+ @Override
+ public Geometry getDefaultGeometry(Content c, QName targetFeature) {
+ // TODO deal with more defaults
+ // TODO deal with target feature
+ if (c.hasContentClass(EntityType.geopoint)) {
+ return getGeoPointGeometry(c);
+ }
+ return null;
+ }
+
+ protected Geometry getGeoPointGeometry(Content c) {
+ if (c.hasContentClass(EntityType.geopoint)) {
+ return GeoEntityUtils.toPoint(c);
+// double latitude = c.get(WGS84PosName.lat, Double.class).get();
+// double longitude = c.get(WGS84PosName.lon, Double.class).get();
+//
+// Coordinate coordinate = new Coordinate(longitude, latitude);
+// Point the_geom = JTS.GEOMETRY_FACTORY.createPoint(coordinate);
+// return the_geom;
+ }
+ return null;
+ }
+
+}
import org.argeo.api.acr.ContentName;
import org.argeo.api.acr.DName;
import org.argeo.api.acr.QNamed;
+import org.argeo.api.app.EntityName;
+import org.argeo.api.app.EntityType;
+import org.argeo.api.app.WGS84PosName;
import org.argeo.api.cms.CmsLog;
-import org.argeo.app.api.EntityName;
-import org.argeo.app.api.EntityType;
-import org.argeo.app.api.WGS84PosName;
import org.argeo.app.geo.GeoJson;
import org.argeo.app.geo.JTS;
import org.locationtech.jts.geom.Coordinate;
import org.argeo.api.acr.ldap.LdapAttr;
import org.argeo.api.acr.search.AndFilter;
import org.argeo.api.acr.spi.ProvidedRepository;
+import org.argeo.api.app.EntityName;
+import org.argeo.api.app.EntityType;
+import org.argeo.api.app.WGS84PosName;
+import org.argeo.api.app.geo.FeatureAdapter;
+import org.argeo.api.app.geo.WfsKvp;
import org.argeo.api.cms.CmsLog;
-import org.argeo.app.api.EntityName;
-import org.argeo.app.api.EntityType;
-import org.argeo.app.api.WGS84PosName;
-import org.argeo.app.api.geo.FeatureAdapter;
-import org.argeo.app.api.geo.WfsKvp;
import org.argeo.app.geo.CqlUtils;
import org.argeo.app.geo.GeoJson;
import org.argeo.app.geo.GeoUtils;
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.argeo.internal.app.jcr.appUserState">
<implementation class="org.argeo.internal.app.jcr.AppUserStateImpl"/>
<service>
- <provide interface="org.argeo.app.api.AppUserState"/>
+ <provide interface="org.argeo.api.app.AppUserState"/>
</service>
<reference bind="setJcrContentProvider" cardinality="1..1" interface="org.argeo.cms.jcr.acr.JcrContentProvider" name="JcrContentProvider" policy="static"/>
<reference bind="setContentRepository" cardinality="1..1" interface="org.argeo.api.acr.ContentRepository" name="ContentRepository" policy="static"/>
<implementation class="org.argeo.app.jcr.terms.SuiteTermsManager"/>
<reference bind="setRepository" cardinality="1..1" interface="javax.jcr.Repository" name="Repository" policy="static" target="(cn=ego)"/>
<service>
- <provide interface="org.argeo.app.api.TermsManager"/>
+ <provide interface="org.argeo.api.app.TermsManager"/>
</service>
</scr:component>
import javax.jcr.Node;
import javax.jcr.RepositoryException;
+import org.argeo.api.app.EntityType;
import org.argeo.api.cms.CmsLog;
-import org.argeo.app.api.EntityType;
import org.argeo.jcr.JcrUtils;
import org.argeo.maintenance.AbstractMaintenanceService;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
-import org.argeo.app.api.EntityConstants;
-import org.argeo.app.api.EntityDefinition;
+import org.argeo.api.app.EntityConstants;
+import org.argeo.api.app.EntityDefinition;
import org.argeo.cms.jcr.CmsJcrUtils;
import org.argeo.jcr.Jcr;
import org.osgi.framework.BundleContext;
import javax.security.auth.x500.X500Principal;
import org.argeo.api.acr.ldap.LdapAttr;
+import org.argeo.api.app.AppUserState;
+import org.argeo.api.app.EntityType;
import org.argeo.api.cms.CmsConstants;
import org.argeo.api.cms.CmsSession;
-import org.argeo.app.api.AppUserState;
-import org.argeo.app.api.EntityType;
+import org.argeo.api.cms.auth.RoleNameUtils;
import org.argeo.app.core.SuiteUtils;
-import org.argeo.cms.RoleNameUtils;
import org.argeo.jcr.JcrException;
import org.argeo.jcr.JcrUtils;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
+import org.argeo.api.app.EntityType;
import org.argeo.api.cms.CmsLog;
-import org.argeo.app.api.EntityType;
import org.argeo.app.docbook.DbkAttr;
import org.argeo.app.docbook.DbkType;
import org.argeo.jcr.Jcr;
import javax.jcr.Session;
import javax.jcr.nodetype.NodeType;
+import org.argeo.api.app.EntityMimeType;
+import org.argeo.api.app.EntityType;
import org.argeo.api.cms.CmsLog;
-import org.argeo.app.api.EntityMimeType;
-import org.argeo.app.api.EntityType;
import org.argeo.app.odk.OdkNames;
import org.argeo.app.odk.OrxListName;
import org.argeo.app.odk.OrxManifestName;
import java.util.ArrayList;
import java.util.List;
-import org.argeo.app.api.Term;
+import org.argeo.api.app.Term;
/**
* A single term. Helper to optimise {@link SuiteTermsManager} implementation.
import javax.jcr.RepositoryException;
import javax.jcr.Session;
+import org.argeo.api.app.EntityNames;
+import org.argeo.api.app.EntityType;
+import org.argeo.api.app.Term;
+import org.argeo.api.app.TermsManager;
+import org.argeo.api.app.Typology;
import org.argeo.api.cms.CmsConstants;
-import org.argeo.app.api.EntityNames;
-import org.argeo.app.api.EntityType;
-import org.argeo.app.api.Term;
-import org.argeo.app.api.TermsManager;
-import org.argeo.app.api.Typology;
import org.argeo.cms.jcr.CmsJcrUtils;
import org.argeo.jcr.Jcr;
import org.argeo.jcr.JcrException;
import javax.jcr.Node;
-import org.argeo.app.api.Term;
-import org.argeo.app.api.Typology;
+import org.argeo.api.app.Term;
+import org.argeo.api.app.Typology;
import org.argeo.jcr.Jcr;
/** A typology. Helper to optimise {@link SuiteTermsManager} implementation. */
import org.argeo.api.acr.Content;
import org.argeo.api.acr.ContentRepository;
import org.argeo.api.acr.ContentSession;
+import org.argeo.api.app.AppUserState;
import org.argeo.api.cms.CmsConstants;
import org.argeo.api.cms.CmsSession;
-import org.argeo.app.api.AppUserState;
import org.argeo.app.jcr.SuiteJcrUtils;
import org.argeo.cms.acr.ContentUtils;
import org.argeo.cms.jcr.acr.JcrContentProvider;
import javax.jcr.nodetype.NodeType;
import javax.jcr.security.Privilege;
+import org.argeo.api.app.EntityType;
import org.argeo.api.cms.CmsConstants;
-import org.argeo.app.api.EntityType;
import org.argeo.jcr.JcrUtils;
import org.argeo.maintenance.AbstractMaintenanceService;
<property name="osgi.http.whiteboard.context.select" type="String" value="(osgi.http.whiteboard.context.name=odkServletContext)"/>
<property name="osgi.http.whiteboard.servlet.multipart.enabled" type="String" value="true"/>
<reference bind="addSubmissionListener" cardinality="0..n" interface="org.argeo.app.xforms.FormSubmissionListener" name="FormSubmissionListener" policy="dynamic" unbind="removeSubmissionListener"/>
- <reference bind="setAppUserState" cardinality="1..1" interface="org.argeo.app.api.AppUserState" name="AppUserState" policy="static"/>
+ <reference bind="setAppUserState" cardinality="1..1" interface="org.argeo.api.app.AppUserState" name="AppUserState" policy="static"/>
</scr:component>
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.argeo.api.app.EntityType;
import org.argeo.api.cms.CmsConstants;
import org.argeo.api.cms.CmsLog;
-import org.argeo.app.api.EntityType;
import org.argeo.app.odk.OrxListName;
import org.argeo.app.odk.OrxManifestName;
import org.argeo.cms.auth.RemoteAuthUtils;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.output.NullOutputStream;
-import org.argeo.app.api.EntityMimeType;
-import org.argeo.app.api.EntityType;
-import org.argeo.app.api.WGS84PosName;
+import org.argeo.api.app.EntityMimeType;
+import org.argeo.api.app.EntityType;
+import org.argeo.api.app.WGS84PosName;
import org.argeo.app.geo.GeoShapeUtils;
import org.argeo.app.odk.OrxManifestName;
import org.argeo.cms.auth.RemoteAuthUtils;
import javax.servlet.http.Part;
import org.argeo.api.acr.Content;
+import org.argeo.api.app.AppUserState;
import org.argeo.api.cms.CmsLog;
import org.argeo.api.cms.CmsSession;
-import org.argeo.app.api.AppUserState;
import org.argeo.app.image.ImageProcessor;
import org.argeo.app.odk.OrxType;
import org.argeo.app.xforms.FormSubmissionListener;
org.osgi.service.http.context,\
javax.jcr.nodetype,\
org.osgi.framework,\
-org.argeo.app.api,\
+org.argeo.api.app,\
org.argeo.cms.acr.xml,\
javax.servlet.*;version="[3,5)",\
*
<reference bind="addLayer" cardinality="1..n" interface="org.argeo.app.swt.ux.SwtAppLayer" name="SuiteLayer" policy="dynamic" unbind="removeLayer"/>
<reference bind="setCmsContext" cardinality="1..1" interface="org.argeo.api.cms.CmsContext" name="CmsContext" policy="static"/>
<reference bind="setContentRepository" cardinality="1..1" interface="org.argeo.api.acr.ContentRepository" name="ContentRepository" policy="static"/>
- <reference bind="setAppUserState" cardinality="1..1" interface="org.argeo.app.api.AppUserState" name="AppUserState" policy="static"/>
+ <reference bind="setAppUserState" cardinality="1..1" interface="org.argeo.api.app.AppUserState" name="AppUserState" policy="static"/>
</scr:component>
</service>
<property name="service.ranking" type="Integer" value="-1000"/>
<properties entry="config/termsEntryArea.properties"/>
- <reference bind="setTermsManager" cardinality="1..1" interface="org.argeo.app.api.TermsManager" name="TermsManager" policy="static"/>
+ <reference bind="setTermsManager" cardinality="1..1" interface="org.argeo.api.app.TermsManager" name="TermsManager" policy="static"/>
</scr:component>
OSGI-INF/termsLayer.xml,\
Import-Package:\
-org.argeo.app.api,\
+org.argeo.api.app,\
org.argeo.cms.swt.acr;resolution:=optional,\
org.argeo.app.swt.ux;resolution:=optional,\
org.argeo.app.swt.terms;resolution:=optional,\
-Subproject commit cabcc3462226b71849ca42301c21e05b63f150c2
+Subproject commit 979b11e352bda7d783c921a62e8cb5ed950a7564
argeo.osgi.start.5=\
org.argeo.app.profile.acr.fs,\
org.argeo.app.core,\
+org.argeo.app.geo,\
org.argeo.app.jcr,\
org.argeo.app.ui,\
org.argeo.app.theme.default,\
-org.argeo.app.geo,\
+org.argeo.app.servlet.publish,\
+org.argeo.app.servlet.odk
# Local
major=2
minor=3
-micro=23
-qualifier=.next
+micro=24
+qualifier=
Bundle-Copyright= \
Copyright 2014-2023 Argeo GmbH, \
argeo.osgi.start.5=\
org.argeo.app.profile.acr.fs,\
org.argeo.app.core,\
+org.argeo.app.geo,\
+org.argeo.app.jcr,\
org.argeo.app.ui,\
org.argeo.app.theme.default,\
org.argeo.app.servlet.publish,\
org.eclipse.swt,\
org.argeo.api.cms.ux,\
org.argeo.cms.ux.acr,\
-org.argeo.app.api,\
+org.argeo.api.app,\
org.argeo.cms.osgi,\
*
\ No newline at end of file
import org.argeo.api.acr.Content;
import org.argeo.api.acr.DName;
import org.argeo.api.acr.spi.ProvidedContent;
+import org.argeo.api.app.EntityNames;
+import org.argeo.api.app.EntityType;
import org.argeo.api.cms.ux.Cms2DSize;
import org.argeo.api.cms.ux.CmsImageManager;
-import org.argeo.app.api.EntityNames;
-import org.argeo.app.api.EntityType;
import org.argeo.app.docbook.DbkAttr;
import org.argeo.app.docbook.DbkType;
import org.argeo.cms.acr.SvgAttrs;
package org.argeo.app.swt.osgi;
+import static java.lang.System.Logger.Level.TRACE;
+
import java.awt.Color;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.System.Logger;
-import java.lang.System.Logger.Level;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
try (InputStream imageIn = new ByteArrayInputStream(out.toByteArray())) {
imageData = new ImageData(imageIn);
}
- logger.log(Level.DEBUG, () -> "Generated " + size + "x" + size + " PNG icon from " + path);
+ logger.log(TRACE, () -> "Generated " + size + "x" + size + " PNG icon from " + path);
} catch (IOException | TranscoderException e) {
throw new RuntimeException("Cannot transcode SVG " + path, e);
}
import org.argeo.api.acr.Content;
import org.argeo.api.acr.NamespaceUtils;
import org.argeo.api.acr.spi.ProvidedContent;
+import org.argeo.api.app.EntityType;
import org.argeo.api.cms.ux.CmsView;
-import org.argeo.app.api.EntityType;
import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.swt.acr.SwtUiProvider;
import org.argeo.cms.swt.widgets.SwtTreeView;
package org.argeo.app.swt.terms;
import org.argeo.api.acr.Content;
+import org.argeo.api.app.Term;
+import org.argeo.api.app.TermsManager;
+import org.argeo.api.app.Typology;
import org.argeo.api.cms.ux.CmsIcon;
-import org.argeo.app.api.Term;
-import org.argeo.app.api.TermsManager;
-import org.argeo.app.api.Typology;
import org.argeo.cms.Localized;
import org.argeo.cms.swt.CmsSwtTheme;
import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.api.acr.Content;
import org.argeo.api.acr.NamespaceUtils;
+import org.argeo.api.app.Term;
+import org.argeo.api.app.TermsManager;
import org.argeo.api.cms.CmsLog;
-import org.argeo.app.api.Term;
-import org.argeo.app.api.TermsManager;
import org.argeo.app.ux.SuiteStyle;
import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.swt.MouseDoubleClick;
import java.util.List;
import org.argeo.api.acr.Content;
-import org.argeo.app.api.Term;
-import org.argeo.app.api.TermsManager;
+import org.argeo.api.app.Term;
+import org.argeo.api.app.TermsManager;
import org.argeo.app.ux.SuiteStyle;
import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.swt.MouseDoubleClick;
import org.argeo.api.acr.Content;
import org.argeo.api.acr.NamespaceUtils;
import org.argeo.api.acr.spi.ProvidedContent;
+import org.argeo.api.app.EntityType;
+import org.argeo.api.app.TermsManager;
import org.argeo.api.cms.ux.CmsView;
-import org.argeo.app.api.EntityType;
-import org.argeo.app.api.TermsManager;
import org.argeo.app.ux.SuiteUxEvent;
import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.swt.acr.SwtUiProvider;
import java.util.TreeMap;
import org.argeo.api.acr.Content;
+import org.argeo.api.app.RankedObject;
import org.argeo.api.cms.CmsLog;
import org.argeo.api.cms.ux.CmsIcon;
import org.argeo.api.cms.ux.CmsView;
-import org.argeo.app.api.RankedObject;
import org.argeo.app.core.SuiteUtils;
import org.argeo.app.ux.SuiteIcon;
import org.argeo.app.ux.SuiteStyle;
import static org.argeo.api.cms.ux.CmsView.CMS_VIEW_UID_PROPERTY;
import java.lang.ref.WeakReference;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Timer;
import java.util.TimerTask;
import java.util.TreeMap;
-import java.util.TreeSet;
import javax.xml.namespace.QName;
import org.argeo.api.acr.Content;
import org.argeo.api.acr.ContentRepository;
import org.argeo.api.acr.spi.ProvidedSession;
+import org.argeo.api.app.AppUserState;
+import org.argeo.api.app.EntityConstants;
+import org.argeo.api.app.EntityName;
+import org.argeo.api.app.EntityType;
+import org.argeo.api.app.RankedObject;
import org.argeo.api.cms.CmsConstants;
import org.argeo.api.cms.CmsEvent;
import org.argeo.api.cms.CmsEventSubscriber;
import org.argeo.api.cms.ux.CmsTheme;
import org.argeo.api.cms.ux.CmsUi;
import org.argeo.api.cms.ux.CmsView;
-import org.argeo.app.api.AppUserState;
-import org.argeo.app.api.EntityConstants;
-import org.argeo.app.api.EntityName;
-import org.argeo.app.api.EntityType;
-import org.argeo.app.api.RankedObject;
import org.argeo.app.ux.AbstractArgeoApp;
import org.argeo.app.ux.AppUi;
import org.argeo.app.ux.SuiteUxEvent;
return layersByPid.get(pid).get();
}
- private <T> T findByType(Map<String, RankedObject<T>> byType, Content content) {
+ private List<String> listTypes(Map<String, ? extends Object> byType, Content content) {
if (content == null)
- throw new IllegalArgumentException("A node should be provided");
-
-// boolean checkJcr = false;
-// if (checkJcr && content instanceof JcrContent) {
-// Node context = ((JcrContent) content).getJcrNode();
-// try {
-// // mixins
-// Set<String> types = new TreeSet<>();
-// for (NodeType mixinType : context.getMixinNodeTypes()) {
-// String mixinTypeName = mixinType.getName();
-// if (byType.containsKey(mixinTypeName)) {
-// types.add(mixinTypeName);
-// }
-// for (NodeType superType : mixinType.getDeclaredSupertypes()) {
-// if (byType.containsKey(superType.getName())) {
-// types.add(superType.getName());
-// }
-// }
-// }
-// // primary node type
-// NodeType primaryType = context.getPrimaryNodeType();
-// String primaryTypeName = primaryType.getName();
-// if (byType.containsKey(primaryTypeName)) {
-// types.add(primaryTypeName);
-// }
-// for (NodeType superType : primaryType.getDeclaredSupertypes()) {
-// if (byType.containsKey(superType.getName())) {
-// types.add(superType.getName());
-// }
-// }
-// // entity type
-// if (context.isNodeType(EntityType.entity.get())) {
-// if (context.hasProperty(EntityNames.ENTITY_TYPE)) {
-// String entityTypeName = context.getProperty(EntityNames.ENTITY_TYPE).getString();
-// if (byType.containsKey(entityTypeName)) {
-// types.add(entityTypeName);
-// }
-// }
-// }
-//
-// if (CmsJcrUtils.isUserHome(context) && byType.containsKey("nt:folder")) {// home node
-// types.add("nt:folder");
-// }
-//
-// if (types.size() == 0)
-// throw new IllegalArgumentException(
-// "No type found for " + context + " (" + listTypes(context) + ")");
-// String type = types.iterator().next();
-// if (!byType.containsKey(type))
-// throw new IllegalArgumentException("No component found for " + context + " with type " + type);
-// return byType.get(type).get();
-// } catch (RepositoryException e) {
-// throw new IllegalStateException(e);
-// }
-//
-// } else {
- Set<String> types = new TreeSet<>();
+ throw new IllegalArgumentException("A content should be provided");
+ List<String> types = new ArrayList<>();
if (content.hasContentClass(EntityType.entity.qName())) {
String type = content.attr(EntityName.type.qName());
if (type != null && byType.containsKey(type))
if (byType.containsKey(type))
types.add(type);
}
- if (types.size() == 0) {
+ if (types.isEmpty())
throw new IllegalArgumentException("No type found for " + content + " (" + objectClasses + ")");
+ return types;
+ }
+
+ private RankedObject<SwtAppLayer> findLayerByType(Content content) {
+ List<String> types = listTypes(layersByType, content);
+ // we assume the types will be ordered by priority
+ // (no possible for LDAP at this stage)
+ for (String type : types) {
+ if (layersByType.containsKey(type))
+ return layersByType.get(type);
+ }
+ throw new IllegalArgumentException("No layer found for " + content + " with type " + types);
+ }
+
+ private RankedObject<SwtUiProvider> findUiProviderByType(Content content) {
+ RankedObject<SwtAppLayer> layerRO = findLayerByType(content);
+ List<String> layerTypes = LangUtils.toStringList(layerRO.getProperties().get(EntityConstants.TYPE));
+ List<String> types = listTypes(uiProvidersByType, content);
+ // layer types are ordered by priority
+ for (String type : layerTypes) {
+ if (types.contains(type) && uiProvidersByType.containsKey(type))
+ return uiProvidersByType.get(type);
}
- String type = types.iterator().next();
- if (!byType.containsKey(type))
- throw new IllegalArgumentException("No component found for " + content + " with type " + type);
- return byType.get(type).get();
-// }
+ throw new IllegalArgumentException("No UI provider found for " + content + " with types " + types);
}
@Override
appTitle = ui.getTitle().lead();
if (isTopic(topic, SuiteUxEvent.refreshPart)) {
- Content node = getContentFromEvent(ui, event);
- if (node == null)
+ Content content = getContentFromEvent(ui, event);
+ if (content == null)
return;
- SwtUiProvider uiProvider = findByType(uiProvidersByType, node);
- SwtAppLayer layer = findByType(layersByType, node);
- ui.switchToLayer(layer, node);
- layer.view(uiProvider, ui.getCurrentWorkArea(), node);
- ui.getCmsView().stateChanged(nodeToState(node), stateTitle(appTitle, CmsUxUtils.getTitle(node)));
+ SwtUiProvider uiProvider = findUiProviderByType(content).get();
+ SwtAppLayer layer = findLayerByType(content).get();
+ ui.switchToLayer(layer, content);
+ layer.view(uiProvider, ui.getCurrentWorkArea(), content);
+ ui.getCmsView().stateChanged(nodeToState(content),
+ stateTitle(appTitle, CmsUxUtils.getTitle(content)));
} else if (isTopic(topic, SuiteUxEvent.openNewPart)) {
- Content node = getContentFromEvent(ui, event);
- if (node == null)
+ Content content = getContentFromEvent(ui, event);
+ if (content == null)
return;
- SwtUiProvider uiProvider = findByType(uiProvidersByType, node);
- SwtAppLayer layer = findByType(layersByType, node);
- ui.switchToLayer(layer, node);
- layer.open(uiProvider, ui.getCurrentWorkArea(), node);
- ui.getCmsView().stateChanged(nodeToState(node), stateTitle(appTitle, CmsUxUtils.getTitle(node)));
+ SwtUiProvider uiProvider = findUiProviderByType(content).get();
+ SwtAppLayer layer = findLayerByType(content).get();
+ ui.switchToLayer(layer, content);
+ layer.open(uiProvider, ui.getCurrentWorkArea(), content);
+ ui.getCmsView().stateChanged(nodeToState(content),
+ stateTitle(appTitle, CmsUxUtils.getTitle(content)));
} else if (isTopic(topic, SuiteUxEvent.switchLayer)) {
String layerId = get(event, SuiteUxEvent.LAYER);
if (layerId != null && !"".equals(layerId.trim())) {
}
}
} else {
- Content node = getContentFromEvent(ui, event);
- if (node != null) {
- SwtAppLayer layer = findByType(layersByType, node);
- ui.switchToLayer(layer, node);
+ Content content = getContentFromEvent(ui, event);
+ if (content != null) {
+ SwtAppLayer layer = findLayerByType(content).get();
+ ui.switchToLayer(layer, content);
}
}
}
Content node;
if (path == null) {
return null;
-// // look for a user
-// String username = get(event, SuiteUxEvent.USERNAME);
-// if (username == null)
-// return null;
-// User user = cmsUserManager.getUser(username);
-// if (user == null)
-// return null;
-// node = ContentUtils.roleToContent(cmsUserManager, contentSession, user);
} else {
node = contentSession.get(path);
}
RankedObject.putIfHigherRank(layersByPid, pid, layer, properties);
}
if (properties.containsKey(EntityConstants.TYPE)) {
+ // TODO check consistency of entity types with overridden ?
List<String> types = LangUtils.toStringList(properties.get(EntityConstants.TYPE));
for (String type : types)
RankedObject.putIfHigherRank(layersByType, type, layer, properties);
<reference bind="addLayer" cardinality="1..n" interface="org.argeo.app.swt.ux.SwtAppLayer" name="SuiteLayer" policy="dynamic" unbind="removeLayer"/>
<reference bind="setCmsContext" cardinality="1..1" interface="org.argeo.api.cms.CmsContext" name="CmsContext" policy="static"/>
<reference bind="setContentRepository" cardinality="1..1" interface="org.argeo.api.acr.ContentRepository" name="ContentRepository" policy="static"/>
- <reference bind="setAppUserState" cardinality="1..1" interface="org.argeo.app.api.AppUserState" name="AppUserState" policy="static"/>
+ <reference bind="setAppUserState" cardinality="1..1" interface="org.argeo.api.app.AppUserState" name="AppUserState" policy="static"/>
</scr:component>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0">
- <implementation class="org.argeo.app.ui.openlayers.OverviewMap"/>
- <properties entry="config/overviewMap.properties"/>
- <service>
- <provide interface="org.argeo.cms.swt.acr.SwtUiProvider"/>
- </service>
- <property name="service.ranking" type="Integer" value="-1000"/>
- <reference bind="setJcrContentProvider" cardinality="1..1" interface="org.argeo.cms.jcr.acr.JcrContentProvider" name="JcrContentProvider" policy="static"/>
-</scr:component>
OSGI-INF/documentsFolder.xml,\
OSGI-INF/fsEntryArea.xml,\
OSGI-INF/mapLayer.xml,\
-OSGI-INF/overviewMap.xml,\
OSGI-INF/defaultMap.xml,\
OSGI-INF/wwwLayer.xml,\
OSGI-INF/documentUiProvider.xml,\
--- /dev/null
+package org.argeo.app.jface;
+
+import org.eclipse.jface.viewers.AbstractTableViewer;
+import org.eclipse.jface.viewers.ColumnViewer;
+import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
+import org.eclipse.jface.viewers.Viewer;
+
+/** Utilities around JFace. */
+public class JFaceUtils {
+ /**
+ * TootlTip support is supported only for {@link AbstractTableViewer} in RAP
+ */
+ public static void enableToolTipSupport(Viewer viewer) {
+ if (viewer instanceof ColumnViewer)
+ ColumnViewerToolTipSupport.enableFor((ColumnViewer) viewer);
+ }
+
+ /** singleton */
+ private JFaceUtils() {
+
+ }
+}
import javax.jcr.query.Query;
import javax.jcr.query.QueryResult;
-import org.argeo.app.api.EntityType;
+import org.argeo.api.app.EntityType;
import org.argeo.app.jcr.XPathUtils;
import org.argeo.app.ui.widgets.DelayedText;
import org.argeo.app.ux.SuiteIcon;
import javax.jcr.Session;
import org.apache.commons.io.IOUtils;
+import org.argeo.api.app.EntityNames;
+import org.argeo.api.app.EntityType;
import org.argeo.api.cms.ux.CmsEditable;
import org.argeo.api.cms.ux.CmsStyle;
-import org.argeo.app.api.EntityNames;
-import org.argeo.app.api.EntityType;
import org.argeo.app.swt.ux.SuiteSwtUtils;
import org.argeo.app.ux.SuiteUxEvent;
import org.argeo.cms.acr.ContentUtils;
import javax.jcr.RepositoryException;
import javax.jcr.nodetype.NodeType;
+import org.argeo.api.app.EntityNames;
+import org.argeo.api.app.EntityType;
import org.argeo.api.cms.ux.Cms2DSize;
import org.argeo.api.cms.ux.CmsImageManager;
-import org.argeo.app.api.EntityNames;
-import org.argeo.app.api.EntityType;
import org.argeo.app.docbook.DbkAttr;
import org.argeo.app.docbook.DbkType;
import org.argeo.app.jcr.docbook.DbkJcrUtils;
import javax.jcr.Item;
+import org.argeo.api.app.Term;
+import org.argeo.api.app.TermsManager;
+import org.argeo.api.app.Typology;
import org.argeo.api.cms.ux.CmsIcon;
-import org.argeo.app.api.Term;
-import org.argeo.app.api.TermsManager;
-import org.argeo.app.api.Typology;
import org.argeo.cms.Localized;
import org.argeo.cms.swt.CmsSwtTheme;
import org.argeo.cms.swt.CmsSwtUtils;
import javax.jcr.Item;
+import org.argeo.api.app.Term;
+import org.argeo.api.app.TermsManager;
import org.argeo.api.cms.CmsLog;
-import org.argeo.app.api.Term;
-import org.argeo.app.api.TermsManager;
import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.swt.SwtEditablePart;
import org.argeo.cms.swt.MouseDoubleClick;
import javax.jcr.Item;
-import org.argeo.app.api.Term;
-import org.argeo.app.api.TermsManager;
+import org.argeo.api.app.Term;
+import org.argeo.api.app.TermsManager;
import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.swt.SwtEditablePart;
import org.argeo.cms.swt.MouseDoubleClick;
import org.argeo.api.acr.Content;
import org.argeo.api.acr.NamespaceUtils;
import org.argeo.api.acr.spi.ProvidedContent;
+import org.argeo.api.app.EntityType;
import org.argeo.api.cms.CmsLog;
import org.argeo.api.cms.ux.CmsView;
-import org.argeo.app.api.EntityType;
import org.argeo.app.ux.SuiteUxEvent;
import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.swt.acr.SwtUiProvider;
import javax.jcr.query.Query;
import org.argeo.api.acr.Content;
+import org.argeo.api.app.EntityType;
import org.argeo.api.cms.CmsConstants;
-import org.argeo.app.api.EntityType;
import org.argeo.app.ui.SuiteUiUtils;
import org.argeo.app.ui.widgets.TreeOrSearchArea;
import org.argeo.app.ux.SuiteIcon;
import javax.jcr.RepositoryException;
import org.apache.commons.io.IOUtils;
-import org.argeo.app.api.EntityNames;
-import org.argeo.app.api.EntityType;
import org.argeo.app.ux.SuiteUxEvent;
import org.argeo.api.cms.CmsLog;
import org.argeo.api.cms.ux.CmsView;
+import org.argeo.api.app.EntityNames;
+import org.argeo.api.app.EntityType;
import org.argeo.api.cms.CmsConstants;
import org.argeo.cms.swt.CmsSwtUtils;
import org.eclipse.swt.SWT;
import javax.jcr.query.Query;
import org.argeo.api.acr.Content;
+import org.argeo.api.app.EntityType;
import org.argeo.api.cms.CmsConstants;
-import org.argeo.app.api.EntityType;
import org.argeo.cms.jcr.acr.JcrContentProvider;
import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.ui.CmsUiProvider;
package org.argeo.app.ui.people;
+import java.util.ArrayList;
+import java.util.List;
+
import org.argeo.api.acr.Content;
import org.argeo.api.acr.ContentSession;
import org.argeo.api.acr.ldap.LdapAcrUtils;
import org.argeo.api.acr.ldap.LdapObj;
import org.argeo.api.acr.spi.ProvidedContent;
import org.argeo.api.cms.directory.CmsGroup;
+import org.argeo.api.cms.directory.CmsRole;
import org.argeo.api.cms.directory.CmsUser;
import org.argeo.api.cms.directory.CmsUserManager;
import org.argeo.api.cms.directory.HierarchyUnit;
import org.argeo.app.ux.SuiteMsg;
import org.argeo.cms.CurrentUser;
import org.argeo.cms.acr.ContentUtils;
-import org.argeo.cms.auth.CmsRole;
import org.argeo.cms.swt.CmsSwtTheme;
import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.swt.Selected;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
-import org.osgi.service.useradmin.Role;
public class GroupUiProvider implements SwtUiProvider {
private CmsUserManager cmsUserManager;
ContentSession contentSession = ((ProvidedContent) context).getSession();
TabularPart<Content, Content> membersPart = new AbstractTabularPart<Content, Content>() {
- Role[] roles;
+ List<CmsRole> roles;
@Override
public int getItemCount() {
- roles = context.adapt(CmsGroup.class).getMembers();
- return roles.length;
+ roles = new ArrayList<CmsRole>(context.adapt(CmsGroup.class).getDirectMembers());
+ return roles.size();
}
@Override
public Content getData(int row) {
- Role role = roles[row];
+ CmsRole role = roles.get(row);
Content content = ContentUtils.roleToContent(cmsUserManager, contentSession, role);
return content;
}
ToolItem addItem = new ToolItem(toolBar, SWT.FLAT);
addItem.setImage(theme.getSmallIcon(SuiteIcon.add));
- addItem.setEnabled(CurrentUser.implies(CmsRole.groupAdmin, hierarchyUnit.getBase()));
+ addItem.setEnabled(CurrentUser.implies(org.argeo.cms.auth.CmsSystemRole.groupAdmin, hierarchyUnit.getBase()));
// members view
SwtTableView<Content, Content> membersView = new SwtTableView<>(area, SWT.BORDER, membersPart);
// CONTROLLER
membersPart.onSelected((model) -> {
- deleteItem.setEnabled(CurrentUser.implies(CmsRole.groupAdmin, hierarchyUnit.getBase()));
+ deleteItem.setEnabled(CurrentUser.implies(org.argeo.cms.auth.CmsSystemRole.groupAdmin, hierarchyUnit.getBase()));
deleteItem.setData(model);
});
import org.argeo.app.ux.SuiteIcon;
import org.argeo.cms.CurrentUser;
import org.argeo.cms.acr.ContentUtils;
-import org.argeo.cms.auth.CmsRole;
+import org.argeo.cms.auth.CmsSystemRole;
import org.argeo.cms.ux.widgets.AbstractHierarchicalPart;
import org.argeo.cms.ux.widgets.Column;
}
} else {
for (UserDirectory directory : cmsUserManager.getUserDirectories()) {
- if (CurrentUser.implies(CmsRole.userAdmin, directory.getBase())) {
+ if (CurrentUser.implies(CmsSystemRole.userAdmin, directory.getBase())) {
visible.add(directory);
}
for (HierarchyUnit hu : directory.getDirectHierarchyUnits(true)) {
- if (CurrentUser.implies(CmsRole.userAdmin, hu.getBase())) {
+ if (CurrentUser.implies(CmsSystemRole.userAdmin, hu.getBase())) {
visible.add(hu);
}
}
import org.argeo.app.ux.SuiteUxEvent;
import org.argeo.cms.CurrentUser;
import org.argeo.cms.acr.ContentUtils;
-import org.argeo.cms.auth.CmsRole;
+import org.argeo.cms.auth.CmsSystemRole;
import org.argeo.cms.jcr.acr.JcrContent;
import org.argeo.cms.swt.CmsSwtTheme;
import org.argeo.cms.swt.CmsSwtUtils;
addItem.setEnabled(true);
addOrgItem.setEnabled(usersPart.getInput() != null
- && CurrentUser.implies(CmsRole.groupAdmin, usersPart.getInput().getBase()));
+ && CurrentUser.implies(CmsSystemRole.groupAdmin, usersPart.getInput().getBase()));
// cmsView.sendEvent(SuiteUxEvent.refreshPart.topic(), SuiteUxEvent
// .eventProperties(ContentUtils.hierarchyUnitToContent(contentSession, hierarchyUnit)));
}
import org.argeo.api.acr.QNamed;
import org.argeo.api.acr.ldap.LdapAttr;
import org.argeo.api.acr.ldap.LdapObj;
+import org.argeo.api.app.SuiteRole;
+import org.argeo.api.cms.auth.RoleNameUtils;
+import org.argeo.api.cms.auth.SystemRole;
import org.argeo.api.cms.directory.CmsGroup;
import org.argeo.api.cms.directory.CmsUser;
import org.argeo.api.cms.directory.CmsUserManager;
import org.argeo.api.cms.directory.HierarchyUnit;
import org.argeo.api.cms.directory.HierarchyUnit.Type;
-import org.argeo.app.api.SuiteRole;
import org.argeo.app.swt.ux.SuiteSwtUtils;
import org.argeo.app.ux.SuiteMsg;
import org.argeo.app.ux.SuiteStyle;
import org.argeo.cms.CmsMsg;
import org.argeo.cms.CurrentUser;
import org.argeo.cms.Localized;
-import org.argeo.cms.RoleNameUtils;
-import org.argeo.cms.SystemRole;
-import org.argeo.cms.auth.CmsRole;
+import org.argeo.cms.auth.CmsSystemRole;
import org.argeo.cms.swt.CmsSwtUtils;
import org.argeo.cms.swt.Selected;
import org.argeo.cms.swt.acr.SwtSection;
roleContext, roles);
addRoleCheckBox(rolesSection, hierarchyUnit, user, SuiteMsg.publisherRole, SuiteRole.publisher,
roleContext, roles);
- addRoleCheckBox(rolesSection, hierarchyUnit, user, SuiteMsg.userAdminRole, CmsRole.userAdmin,
+ addRoleCheckBox(rolesSection, hierarchyUnit, user, SuiteMsg.userAdminRole, CmsSystemRole.userAdmin,
roleContext, roles);
}
// Composite facetsSection = new Composite(main, SWT.NONE);
// new Label(facetsSection, SWT.NONE).setText(member);
// }
// }
- if (CurrentUser.implies(CmsRole.userAdmin, roleContext)) {
+ if (CurrentUser.implies(CmsSystemRole.userAdmin, roleContext)) {
SwtSection changePasswordSection = new SwtSection(main, SWT.BORDER);
changePasswordSection.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
changePasswordSection.setLayout(new GridLayout(2, false));
}
}
- if (systemRole.equals(CmsRole.userAdmin)) {
- if (!CurrentUser.isUserContext(roleContext) && CurrentUser.implies(CmsRole.userAdmin, roleContext)) {
+ if (systemRole.equals(CmsSystemRole.userAdmin)) {
+ if (!CurrentUser.isUserContext(roleContext) && CurrentUser.implies(CmsSystemRole.userAdmin, roleContext)) {
// a user admin cannot modify the user admins of their own context
radio.setEnabled(true);
} else {
radio.setEnabled(false);
}
} else {
- radio.setEnabled(CurrentUser.implies(CmsRole.userAdmin, roleContext));
+ radio.setEnabled(CurrentUser.implies(CmsSystemRole.userAdmin, roleContext));
}
radio.addSelectionListener((Selected) (e) -> {
import org.argeo.api.acr.ldap.LdapAcrUtils;
import org.argeo.api.acr.ldap.LdapAttr;
import org.argeo.api.acr.ldap.LdapObj;
+import org.argeo.api.cms.directory.CmsUser;
import org.argeo.api.cms.ux.CmsIcon;
import org.argeo.app.ux.SuiteIcon;
import org.argeo.cms.CurrentUser;
-import org.argeo.cms.auth.UserAdminUtils;
import org.argeo.cms.ux.widgets.Column;
-import org.osgi.service.useradmin.User;
public class UserColumn implements Column<Content> {
@Override
public String getText(Content role) {
if (role.hasContentClass(LdapObj.inetOrgPerson))
- return UserAdminUtils.getUserDisplayName(role.adapt(User.class));
+ return role.adapt(CmsUser.class).getDisplayName();
else if (role.hasContentClass(LdapObj.organization))
return role.attr(LdapAttr.o);
else if (role.hasContentClass(LdapObj.groupOfNames)) {
import org.argeo.api.acr.Content;
import org.argeo.api.acr.ContentSession;
import org.argeo.api.acr.ldap.LdapObj;
+import org.argeo.api.cms.directory.CmsRole;
import org.argeo.api.cms.directory.CmsUserManager;
import org.argeo.api.cms.directory.HierarchyUnit;
import org.argeo.api.cms.directory.UserDirectory;
import org.argeo.cms.acr.ContentUtils;
import org.argeo.cms.ux.widgets.DefaultTabularPart;
-import org.osgi.service.useradmin.Role;
public class UsersPart extends DefaultTabularPart<HierarchyUnit, Content> {
private ContentSession contentSession;
List<Content> roles = new ArrayList<>();
UserDirectory ud = (UserDirectory) hu.getDirectory();
if (ud.getRealm().isPresent()) {
- for (Role r : ud.getHierarchyUnitRoles(ud, null, true)) {
+ for (CmsRole r : ud.getHierarchyUnitRoles(ud, null, true)) {
Content content = ContentUtils.roleToContent(cmsUserManager, contentSession, r);
if (content.hasContentClass(LdapObj.inetOrgPerson, LdapObj.organization))
roles.add(content);
for (HierarchyUnit directChild : hu.getDirectHierarchyUnits(false)) {
if (!(directChild.isType(HierarchyUnit.Type.FUNCTIONAL)
|| directChild.isType(HierarchyUnit.Type.ROLES))) {
- for (Role r : ud.getHierarchyUnitRoles(directChild, null, false)) {
+ for (CmsRole r : ud.getHierarchyUnitRoles(directChild, null, false)) {
Content content = ContentUtils.roleToContent(cmsUserManager, contentSession, r);
if (content.hasContentClass(LdapObj.inetOrgPerson, LdapObj.organization, LdapObj.groupOfNames))
roles.add(content);