From: Mathieu Baudier Date: Mon, 22 Nov 2021 09:09:29 +0000 (+0100) Subject: Simplify project structure X-Git-Tag: v2.3.2~7 X-Git-Url: https://git.argeo.org/?p=gpl%2Fargeo-suite.git;a=commitdiff_plain;h=3440f51df3e4c015972c7b6a0efb3ce16188b89b Simplify project structure --- diff --git a/core/.gitignore b/core/.gitignore deleted file mode 100644 index b83d222..0000000 --- a/core/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target/ diff --git a/core/cnf/maven.bnd b/core/cnf/maven.bnd deleted file mode 100644 index 4bd5c0c..0000000 --- a/core/cnf/maven.bnd +++ /dev/null @@ -1 +0,0 @@ --include: ../../cnf/maven.bnd \ No newline at end of file diff --git a/core/org.argeo.entity.api/.classpath b/core/org.argeo.entity.api/.classpath deleted file mode 100644 index e801ebf..0000000 --- a/core/org.argeo.entity.api/.classpath +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/core/org.argeo.entity.api/.gitignore b/core/org.argeo.entity.api/.gitignore deleted file mode 100644 index 09e3bc9..0000000 --- a/core/org.argeo.entity.api/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/bin/ -/target/ diff --git a/core/org.argeo.entity.api/.project b/core/org.argeo.entity.api/.project deleted file mode 100644 index 1269cce..0000000 --- a/core/org.argeo.entity.api/.project +++ /dev/null @@ -1,28 +0,0 @@ - - - org.argeo.entity.api - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - diff --git a/core/org.argeo.entity.api/META-INF/.gitignore b/core/org.argeo.entity.api/META-INF/.gitignore deleted file mode 100644 index 4854a41..0000000 --- a/core/org.argeo.entity.api/META-INF/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/MANIFEST.MF diff --git a/core/org.argeo.entity.api/bnd.bnd b/core/org.argeo.entity.api/bnd.bnd deleted file mode 100644 index ab46172..0000000 --- a/core/org.argeo.entity.api/bnd.bnd +++ /dev/null @@ -1,5 +0,0 @@ -Require-Capability:\ -cms.datamodel;filter:="(name=jcrx)" - -Provide-Capability:\ -cms.datamodel; name=entity; cnd=/org/argeo/entity/entity.cnd diff --git a/core/org.argeo.entity.api/build.properties b/core/org.argeo.entity.api/build.properties deleted file mode 100644 index 34d2e4d..0000000 --- a/core/org.argeo.entity.api/build.properties +++ /dev/null @@ -1,4 +0,0 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . diff --git a/core/org.argeo.entity.api/pom.xml b/core/org.argeo.entity.api/pom.xml deleted file mode 100644 index c13a40d..0000000 --- a/core/org.argeo.entity.api/pom.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - 4.0.0 - - org.argeo.suite - core - 2.3-SNAPSHOT - .. - - org.argeo.entity.api - Entity API - jar - - - - org.argeo.commons - org.argeo.enterprise - ${version.argeo-commons} - - - diff --git a/core/org.argeo.entity.api/src/org/argeo/entity/EntityConstants.java b/core/org.argeo.entity.api/src/org/argeo/entity/EntityConstants.java deleted file mode 100644 index 93021e0..0000000 --- a/core/org.argeo.entity.api/src/org/argeo/entity/EntityConstants.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.argeo.entity; - -/** 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"; - -} diff --git a/core/org.argeo.entity.api/src/org/argeo/entity/EntityDefinition.java b/core/org.argeo.entity.api/src/org/argeo/entity/EntityDefinition.java deleted file mode 100644 index 08aff61..0000000 --- a/core/org.argeo.entity.api/src/org/argeo/entity/EntityDefinition.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.argeo.entity; - -import javax.jcr.Node; - -/** The definition of an entity, a composite configurable data structure. */ -public interface EntityDefinition { - String getEditorId(Node entity); - - String getType(); -} diff --git a/core/org.argeo.entity.api/src/org/argeo/entity/EntityMimeType.java b/core/org.argeo.entity.api/src/org/argeo/entity/EntityMimeType.java deleted file mode 100644 index 997f1be..0000000 --- a/core/org.argeo.entity.api/src/org/argeo/entity/EntityMimeType.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.argeo.entity; - -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; - } - -} diff --git a/core/org.argeo.entity.api/src/org/argeo/entity/EntityNames.java b/core/org.argeo.entity.api/src/org/argeo/entity/EntityNames.java deleted file mode 100644 index ede7447..0000000 --- a/core/org.argeo.entity.api/src/org/argeo/entity/EntityNames.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.argeo.entity; - -import org.argeo.naming.LdapAttrs; - -/** 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"; - - final String ENTITY_TYPE = "entity:type"; - // final String ENTITY_UID = "entity:uid"; - // final String ENTITY_NAME = "entity:name"; - - // GENERIC CONCEPTS - /** The language which is relevant. */ - final String XML_LANG = "xml:lang"; - /** The date which is relevant. */ - final String ENTITY_DATE = "entity:date"; - @Deprecated - final String ENTITY_RELATED_TO = "entity:relatedTo"; - - // DEFAULT FOLDER NAMES - final String MEDIA = "media"; - final String FILES = "files"; - - // LDAP-LIKE ENTITIES - @Deprecated - final String DISPLAY_NAME = LdapAttrs.displayName.property(); - // Persons - @Deprecated - final String GIVEN_NAME = LdapAttrs.givenName.property(); - @Deprecated - final String SURNAME = LdapAttrs.sn.property(); - @Deprecated - final String EMAIL = LdapAttrs.mail.property(); - @Deprecated - final String OU = LdapAttrs.ou.property(); - - // WGS84 - final String GEO_LAT = "geo:lat"; - final String GEO_LONG = "geo:long"; - final String GEO_ALT = "geo:alt"; - - // SVG - final String SVG_WIDTH = "svg:width"; - final String SVG_HEIGHT = "svg:height"; - final String SVG_LENGTH = "svg:length"; - final String SVG_UNIT = "svg:unit"; - final String SVG_DUR = "svg:dur"; - final String SVG_DIRECTION = "svg:direction"; -} diff --git a/core/org.argeo.entity.api/src/org/argeo/entity/EntityType.java b/core/org.argeo.entity.api/src/org/argeo/entity/EntityType.java deleted file mode 100644 index 089cdcf..0000000 --- a/core/org.argeo.entity.api/src/org/argeo/entity/EntityType.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.argeo.entity; - -/** Types related to entities. */ -public enum EntityType implements JcrName { - // entity - entity, local, relatedTo, - // structure - space, document, - // typology - typologies, terms, term, - // form - form, formSet, formSubmission, - // graphics - box, - // geography - geopoint, bearing, - // ldap - person, user; - - @Override - public String getPrefix() { - return prefix(); - } - - public static String prefix() { - return "entity"; - } - - public String basePath() { - return '/' + name(); - } - - @Override - public String getNamespace() { - return namespace(); - } - - public static String namespace() { - return "http://www.argeo.org/ns/entity"; - } - -} diff --git a/core/org.argeo.entity.api/src/org/argeo/entity/EntityTypes.java b/core/org.argeo.entity.api/src/org/argeo/entity/EntityTypes.java deleted file mode 100644 index ef35147..0000000 --- a/core/org.argeo.entity.api/src/org/argeo/entity/EntityTypes.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.argeo.entity; - -/** Types related to entities. */ -@Deprecated -public interface EntityTypes { - final static String ENTITY_ENTITY = "entity:entity"; - final static String ENTITY_DEFINITION = "entity:definition"; - - final static String ENTITY_PERSON = "entity:person"; -} diff --git a/core/org.argeo.entity.api/src/org/argeo/entity/JcrName.java b/core/org.argeo.entity.api/src/org/argeo/entity/JcrName.java deleted file mode 100644 index 322c42e..0000000 --- a/core/org.argeo.entity.api/src/org/argeo/entity/JcrName.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.argeo.entity; - -import java.util.function.Supplier; - -/** Can be applied to {@link Enum}s in order to generate prefixed names. */ -@FunctionalInterface -public interface JcrName extends Supplier { - String name(); - - default String getPrefix() { - return null; - } - - default String getNamespace() { - return null; - } - - @Override - default String get() { - String prefix = getPrefix(); - return prefix != null ? prefix + ":" + name() : name(); - } - - default String withNamespace() { - String namespace = getNamespace(); - if (namespace == null) - throw new UnsupportedOperationException("No namespace is specified for " + getClass()); - return "{" + namespace + "}" + name(); - } -} diff --git a/core/org.argeo.entity.api/src/org/argeo/entity/Term.java b/core/org.argeo.entity.api/src/org/argeo/entity/Term.java deleted file mode 100644 index 3bf075a..0000000 --- a/core/org.argeo.entity.api/src/org/argeo/entity/Term.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.argeo.entity; - -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 getSubTerms(); - - Term getParentTerm(); - -} diff --git a/core/org.argeo.entity.api/src/org/argeo/entity/TermsManager.java b/core/org.argeo.entity.api/src/org/argeo/entity/TermsManager.java deleted file mode 100644 index 7564ff9..0000000 --- a/core/org.argeo.entity.api/src/org/argeo/entity/TermsManager.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.argeo.entity; - -import java.util.List; - -/** Provides optimised access and utilities around terms typologies. */ -public interface TermsManager { - Typology getTypology(String typology); - - Term getTerm(String id); - - List listAllTerms(String typology); - -} diff --git a/core/org.argeo.entity.api/src/org/argeo/entity/Typology.java b/core/org.argeo.entity.api/src/org/argeo/entity/Typology.java deleted file mode 100644 index 5be27e3..0000000 --- a/core/org.argeo.entity.api/src/org/argeo/entity/Typology.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.argeo.entity; - -import java.util.List; - -/** A structured and exhaustive set of {@link Term}s. */ -public interface Typology { - - String getId(); - - boolean isFlat(); - - List getSubTerms(); - - Term findTermByName(String name); -} diff --git a/core/org.argeo.entity.api/src/org/argeo/entity/entity.cnd b/core/org.argeo.entity.api/src/org/argeo/entity/entity.cnd deleted file mode 100644 index 2ea89f9..0000000 --- a/core/org.argeo.entity.api/src/org/argeo/entity/entity.cnd +++ /dev/null @@ -1,114 +0,0 @@ -// Standard namespaces - - -// see https://www.w3.org/2003/01/geo/ - - - - - - -[entity:entity] > mix:created, mix:referenceable -mixin - -[entity:local] > entity:entity -mixin -- entity:type (String) m - -[entity:relatedTo] -mixin -+ entity:relatedTo (nt:address) * - -// -// ENTITY DEFINITION -// -//[entity:definition] > entity:composite, mix:created, mix:lastModified, mix:referenceable -//- entity:type (String) multiple - -//[entity:part] - -//[entity:reference] - -//[entity:composite] -//orderable -//+ * (entity:part) -//+ * (entity:reference) -//+ * (entity:composite) - -[entity:query] > nt:query, mix:referenceable - -[entity:querySet] -+ * (entity:query) = entity:query * - -// -// STRUCTURE -// -[entity:space] -mixin - -[entity:document] -mixin - -// -// TYPOLOGY -// -[entity:typologies] -+ * (entity:terms) = entity:terms - -[entity:term] -orderable -- name (NAME) -- * (*) -+ term (entity:term) = entity:term * - -[entity:terms] > mix:referenceable -orderable -+ term (entity:term) = entity:term * - -// -// FORM -// -[entity:form] -mixin -+ queries (entity:querySet) = entity:querySet - -[entity:formSubmission] -mixin - -[entity:formSet] > mix:title -mixin - -// -// GRAPHICS -// -[entity:box] -mixin -- svg:width (DOUBLE) -- svg:height (DOUBLE) -- svg:length (DOUBLE) -- svg:unit (STRING) -- svg:dur (DOUBLE) - -// LDAP-LIKE ENTITIES -// A real person -[entity:person] > entity:entity -mixin -- ldap:sn (String) -- ldap:givenName (String) -- ldap:mail (String) * - -[entity:user] > entity:person -mixin -- ldap:distinguishedName (String) -- ldap:uid (String) - -// GEOGRAPHY -[entity:geopoint] -mixin -- geo:long (DOUBLE) -- geo:lat (DOUBLE) -- geo:alt (DOUBLE) - -[entity:bearing] -mixin -- svg:direction (DOUBLE) diff --git a/core/org.argeo.entity.core/.classpath b/core/org.argeo.entity.core/.classpath deleted file mode 100644 index e801ebf..0000000 --- a/core/org.argeo.entity.core/.classpath +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/core/org.argeo.entity.core/.gitignore b/core/org.argeo.entity.core/.gitignore deleted file mode 100644 index 09e3bc9..0000000 --- a/core/org.argeo.entity.core/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/bin/ -/target/ diff --git a/core/org.argeo.entity.core/.project b/core/org.argeo.entity.core/.project deleted file mode 100644 index 1acff84..0000000 --- a/core/org.argeo.entity.core/.project +++ /dev/null @@ -1,28 +0,0 @@ - - - org.argeo.entity.core - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - diff --git a/core/org.argeo.entity.core/META-INF/.gitignore b/core/org.argeo.entity.core/META-INF/.gitignore deleted file mode 100644 index 4854a41..0000000 --- a/core/org.argeo.entity.core/META-INF/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/MANIFEST.MF diff --git a/core/org.argeo.entity.core/bnd.bnd b/core/org.argeo.entity.core/bnd.bnd deleted file mode 100644 index e69de29..0000000 diff --git a/core/org.argeo.entity.core/build.properties b/core/org.argeo.entity.core/build.properties deleted file mode 100644 index 34d2e4d..0000000 --- a/core/org.argeo.entity.core/build.properties +++ /dev/null @@ -1,4 +0,0 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . diff --git a/core/org.argeo.entity.core/pom.xml b/core/org.argeo.entity.core/pom.xml deleted file mode 100644 index e3a5b76..0000000 --- a/core/org.argeo.entity.core/pom.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - 4.0.0 - - org.argeo.suite - core - 2.3-SNAPSHOT - .. - - org.argeo.entity.core - Entity Reference Implementation - jar - - - org.argeo.suite - org.argeo.entity.api - 2.3-SNAPSHOT - - - - - org.argeo.commons - org.argeo.cms - ${version.argeo-commons} - - - diff --git a/core/org.argeo.entity.core/src/org/argeo/entity/core/JcrEntityDefinition.java b/core/org.argeo.entity.core/src/org/argeo/entity/core/JcrEntityDefinition.java deleted file mode 100644 index 6eb086d..0000000 --- a/core/org.argeo.entity.core/src/org/argeo/entity/core/JcrEntityDefinition.java +++ /dev/null @@ -1,73 +0,0 @@ -package org.argeo.entity.core; - -import java.util.Map; - -import javax.jcr.Node; -import javax.jcr.Repository; -import javax.jcr.RepositoryException; -import javax.jcr.Session; - -import org.argeo.api.NodeUtils; -import org.argeo.entity.EntityConstants; -import org.argeo.entity.EntityDefinition; -import org.argeo.jcr.Jcr; -import org.osgi.framework.BundleContext; - -/** An entity definition based on a JCR data structure. */ -public class JcrEntityDefinition implements EntityDefinition { - private Repository repository; - - private String type; - private String defaultEditorId; - - public void init(BundleContext bundleContext, Map properties) throws RepositoryException { - Session adminSession = NodeUtils.openDataAdminSession(repository, null); - try { - type = properties.get(EntityConstants.TYPE); - if (type == null) - throw new IllegalArgumentException("Entity type property " + EntityConstants.TYPE + " must be set."); - defaultEditorId = properties.get(EntityConstants.DEFAULT_EDITOR_ID); -// String definitionPath = EntityNames.ENTITY_DEFINITIONS_PATH + '/' + type; -// if (!adminSession.itemExists(definitionPath)) { -// Node entityDefinition = JcrUtils.mkdirs(adminSession, definitionPath, EntityTypes.ENTITY_DEFINITION); -//// entityDefinition.addMixin(EntityTypes.ENTITY_DEFINITION); -// adminSession.save(); -// } - initJcr(adminSession); - } finally { - Jcr.logout(adminSession); - } - } - - /** To be overridden in order to perform additional initialisations. */ - protected void initJcr(Session adminSession) throws RepositoryException { - - } - - public void destroy(BundleContext bundleContext, Map properties) throws RepositoryException { - - } - - @Override - public String getEditorId(Node entity) { - return defaultEditorId; - } - - @Override - public String getType() { - return type; - } - - protected Repository getRepository() { - return repository; - } - - public void setRepository(Repository repository) { - this.repository = repository; - } - - public String toString() { - return "Entity Definition " + getType(); - } - -} diff --git a/core/org.argeo.entity.ui/.classpath b/core/org.argeo.entity.ui/.classpath deleted file mode 100644 index e801ebf..0000000 --- a/core/org.argeo.entity.ui/.classpath +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/core/org.argeo.entity.ui/.gitignore b/core/org.argeo.entity.ui/.gitignore deleted file mode 100644 index 09e3bc9..0000000 --- a/core/org.argeo.entity.ui/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/bin/ -/target/ diff --git a/core/org.argeo.entity.ui/.project b/core/org.argeo.entity.ui/.project deleted file mode 100644 index a1f7177..0000000 --- a/core/org.argeo.entity.ui/.project +++ /dev/null @@ -1,28 +0,0 @@ - - - org.argeo.entity.ui - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - diff --git a/core/org.argeo.entity.ui/META-INF/.gitignore b/core/org.argeo.entity.ui/META-INF/.gitignore deleted file mode 100644 index 4854a41..0000000 --- a/core/org.argeo.entity.ui/META-INF/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/MANIFEST.MF diff --git a/core/org.argeo.entity.ui/bnd.bnd b/core/org.argeo.entity.ui/bnd.bnd deleted file mode 100644 index e7cd4cb..0000000 --- a/core/org.argeo.entity.ui/bnd.bnd +++ /dev/null @@ -1,3 +0,0 @@ -Import-Package:\ -org.eclipse.swt,\ -* \ No newline at end of file diff --git a/core/org.argeo.entity.ui/build.properties b/core/org.argeo.entity.ui/build.properties deleted file mode 100644 index 34d2e4d..0000000 --- a/core/org.argeo.entity.ui/build.properties +++ /dev/null @@ -1,4 +0,0 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . diff --git a/core/org.argeo.entity.ui/pom.xml b/core/org.argeo.entity.ui/pom.xml deleted file mode 100644 index 0ac2270..0000000 --- a/core/org.argeo.entity.ui/pom.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - 4.0.0 - - org.argeo.suite - core - 2.3-SNAPSHOT - .. - - org.argeo.entity.ui - Entity UI - jar - - - org.argeo.suite - org.argeo.entity.core - 2.3-SNAPSHOT - - - - - org.argeo.commons - org.argeo.cms.ui - ${version.argeo-commons} - - - - - org.argeo.commons - org.argeo.eclipse.ui.rap - ${version.argeo-commons} - - - - - org.argeo.tp - argeo-tp-rap-e4 - ${version.argeo-tp} - pom - provided - - - diff --git a/core/org.argeo.entity.ui/src/org/argeo/entity/ui/forms/AbstractTermsPart.java b/core/org.argeo.entity.ui/src/org/argeo/entity/ui/forms/AbstractTermsPart.java deleted file mode 100644 index 36ae274..0000000 --- a/core/org.argeo.entity.ui/src/org/argeo/entity/ui/forms/AbstractTermsPart.java +++ /dev/null @@ -1,131 +0,0 @@ -package org.argeo.entity.ui.forms; - -import javax.jcr.Item; - -import org.argeo.cms.Localized; -import org.argeo.cms.ui.CmsTheme; -import org.argeo.cms.ui.util.CmsIcon; -import org.argeo.cms.ui.util.CmsUiUtils; -import org.argeo.cms.ui.viewers.EditablePart; -import org.argeo.cms.ui.widgets.ContextOverlay; -import org.argeo.cms.ui.widgets.StyledControl; -import org.argeo.entity.Term; -import org.argeo.entity.TermsManager; -import org.argeo.entity.Typology; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Text; -import org.eclipse.swt.widgets.ToolItem; - -/** Common logic between single and mutliple terms editable part. */ -public abstract class AbstractTermsPart extends StyledControl implements EditablePart { - private static final long serialVersionUID = -5497097995341927710L; - protected final TermsManager termsManager; - protected final Typology typology; - - private final boolean editable; - - private CmsIcon deleteIcon; - private CmsIcon addIcon; - private CmsIcon cancelIcon; - - private Color highlightColor; - private Composite highlight; - - protected final CmsTheme theme; - - public AbstractTermsPart(Composite parent, int style, Item item, TermsManager termsManager, String typology) { - super(parent, style, item); - if (item == null) - throw new IllegalArgumentException("Item cannot be null"); - this.termsManager = termsManager; - this.typology = termsManager.getTypology(typology); - this.theme = CmsTheme.getCmsTheme(parent); - editable = !(SWT.READ_ONLY == (style & SWT.READ_ONLY)); - highlightColor = parent.getDisplay().getSystemColor(SWT.COLOR_GRAY); - } - - public boolean isEditable() { - return editable; - } - - protected void createHighlight(Composite block) { - highlight = new Composite(block, SWT.NONE); - highlight.setBackground(highlightColor); - GridData highlightGd = new GridData(SWT.FILL, SWT.FILL, false, false); - highlightGd.widthHint = 5; - highlightGd.heightHint = 3; - highlight.setLayoutData(highlightGd); - - } - - protected String getTermLabel(Term term) { - if (term instanceof Localized) - return ((Localized) term).lead(); - else - return term.getName(); - - } - - protected abstract void refresh(ContextOverlay contextArea, String filter, Text txt); - - protected boolean isTermSelectable(Term term) { - return true; - } - - protected void processTermListLabel(Term term, Label label) { - - } - - protected void setControlLayoutData(Control control) { - control.setLayoutData(CmsUiUtils.fillAll()); - } - - protected void setContainerLayoutData(Composite composite) { - composite.setLayoutData(CmsUiUtils.fillAll()); - } - - // - // STYLING - // - public void setDeleteIcon(CmsIcon deleteIcon) { - this.deleteIcon = deleteIcon; - } - - public void setAddIcon(CmsIcon addIcon) { - this.addIcon = addIcon; - } - - public void setCancelIcon(CmsIcon cancelIcon) { - this.cancelIcon = cancelIcon; - } - - protected TermsManager getTermsManager() { - return termsManager; - } - - protected void styleDelete(ToolItem deleteItem) { - if (deleteIcon != null) - deleteItem.setImage(deleteIcon.getSmallIcon(theme)); - else - deleteItem.setText("-"); - } - - protected void styleCancel(ToolItem cancelItem) { - if (cancelIcon != null) - cancelItem.setImage(cancelIcon.getSmallIcon(theme)); - else - cancelItem.setText("X"); - } - - protected void styleAdd(ToolItem addItem) { - if (addIcon != null) - addItem.setImage(addIcon.getSmallIcon(theme)); - else - addItem.setText("+"); - } -} diff --git a/core/org.argeo.entity.ui/src/org/argeo/entity/ui/forms/MultiTermsPart.java b/core/org.argeo.entity.ui/src/org/argeo/entity/ui/forms/MultiTermsPart.java deleted file mode 100644 index 8d40763..0000000 --- a/core/org.argeo.entity.ui/src/org/argeo/entity/ui/forms/MultiTermsPart.java +++ /dev/null @@ -1,207 +0,0 @@ -package org.argeo.entity.ui.forms; - -import java.util.ArrayList; -import java.util.List; - -import javax.jcr.Item; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.cms.ui.forms.FormStyle; -import org.argeo.cms.ui.util.CmsUiUtils; -import org.argeo.cms.ui.viewers.EditablePart; -import org.argeo.cms.ui.widgets.ContextOverlay; -import org.argeo.eclipse.ui.MouseDoubleClick; -import org.argeo.eclipse.ui.MouseDown; -import org.argeo.eclipse.ui.Selected; -import org.argeo.entity.Term; -import org.argeo.entity.TermsManager; -import org.argeo.jcr.Jcr; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.layout.RowLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Text; -import org.eclipse.swt.widgets.ToolBar; -import org.eclipse.swt.widgets.ToolItem; - -/** {@link EditablePart} for multiple terms. */ -public class MultiTermsPart extends AbstractTermsPart { - private static final long serialVersionUID = -4961135649177920808L; - private final static Log log = LogFactory.getLog(MultiTermsPart.class); - - public MultiTermsPart(Composite parent, int style, Item item, TermsManager termsManager, String typology) { - super(parent, style, item, termsManager, typology); - } - - @Override - protected Control createControl(Composite box, String style) { - Composite placeholder = new Composite(box, SWT.NONE); - - boolean vertical = SWT.VERTICAL == (getStyle() & SWT.VERTICAL); - RowLayout rl = new RowLayout(vertical ? SWT.VERTICAL : SWT.HORIZONTAL); - rl = CmsUiUtils.noMarginsRowLayout(rl); -// rl.wrap = true; -// rl.justify = true; - placeholder.setLayout(rl); - List currentValue = getValue(); - if (currentValue != null && !currentValue.isEmpty()) { - for (Term value : currentValue) { - Composite block = new Composite(placeholder, SWT.NONE); - block.setLayout(CmsUiUtils.noSpaceGridLayout(3)); - Label lbl = new Label(block, SWT.NONE); - String display = getTermLabel(value); - lbl.setText(display); - CmsUiUtils.style(lbl, style == null ? FormStyle.propertyText.style() : style); - processTermListLabel(value, lbl); - if (isEditable()) - lbl.addMouseListener((MouseDoubleClick) (e) -> { - startEditing(); - }); - if (isEditing()) { - ToolBar toolBar = new ToolBar(block, SWT.HORIZONTAL); - ToolItem deleteItem = new ToolItem(toolBar, SWT.FLAT); - styleDelete(deleteItem); - deleteItem.addSelectionListener((Selected) (e) -> { - // we retrieve them again here because they may have changed - List curr = getValue(); - List newValue = new ArrayList<>(); - for (Term v : curr) { - if (!v.equals(value)) - newValue.add(v); - } - setValue(newValue); - block.dispose(); - layout(true, true); - }); - - } - } - } else {// empty - if (isEditable() && !isEditing()) { - ToolBar toolBar = new ToolBar(placeholder, SWT.HORIZONTAL); - ToolItem addItem = new ToolItem(toolBar, SWT.FLAT); - styleAdd(addItem); - addItem.addSelectionListener((Selected) (e) -> { - startEditing(); - }); - } - } - - if (isEditing()) { - Composite block = new Composite(placeholder, SWT.NONE); - block.setLayout(CmsUiUtils.noSpaceGridLayout(3)); - - createHighlight(block); - - Text txt = new Text(block, SWT.SINGLE | SWT.BORDER); - txt.setLayoutData(CmsUiUtils.fillWidth()); -// txt.setMessage("[new]"); - - CmsUiUtils.style(txt, style == null ? FormStyle.propertyText.style() : style); - - ToolBar toolBar = new ToolBar(block, SWT.HORIZONTAL); - ToolItem cancelItem = new ToolItem(toolBar, SWT.FLAT); - styleCancel(cancelItem); - cancelItem.addSelectionListener((Selected) (e) -> { - stopEditing(); - }); - - ContextOverlay contextOverlay = new ContextOverlay(txt, SWT.NONE) { - private static final long serialVersionUID = -7980078594405384874L; - - @Override - protected void onHide() { - stopEditing(); - } - }; - contextOverlay.setLayout(new GridLayout()); - // filter - txt.addModifyListener((e) -> { - String filter = txt.getText().toLowerCase(); - if ("".equals(filter.trim())) - filter = null; - refresh(contextOverlay, filter, txt); - }); - txt.addFocusListener(new FocusListener() { - private static final long serialVersionUID = -6024501573409619949L; - - @Override - public void focusLost(FocusEvent event) { -// if (!contextOverlay.isDisposed() && contextOverlay.isShellVisible()) -// getDisplay().asyncExec(() -> stopEditing()); - } - - @Override - public void focusGained(FocusEvent event) { - // txt.setText(""); - if (!contextOverlay.isDisposed() && !contextOverlay.isShellVisible()) - refresh(contextOverlay, null, txt); - } - }); - layout(new Control[] { txt }); - // getDisplay().asyncExec(() -> txt.setFocus()); - } - return placeholder; - } - - @Override - protected void refresh(ContextOverlay contextArea, String filter, Text txt) { - CmsUiUtils.clear(contextArea); - List terms = termsManager.listAllTerms(typology.getId()); - List currentValue = getValue(); - terms: for (Term term : terms) { - if (currentValue != null && currentValue.contains(term)) - continue terms; - String display = getTermLabel(term); - if (filter != null && !display.toLowerCase().contains(filter)) - continue terms; - Label termL = new Label(contextArea, SWT.WRAP); - termL.setText(display); - processTermListLabel(term, termL); - if (isTermSelectable(term)) - termL.addMouseListener((MouseDown) (e) -> { - List newValue = new ArrayList<>(); - List curr = getValue(); - if (currentValue != null) - newValue.addAll(curr); - newValue.add(term); - setValue(newValue); - contextArea.hide(); - stopEditing(); - }); - } - contextArea.show(); - } - - protected List getValue() { - String property = typology.getId(); - List curr = Jcr.getMultiple(getNode(), property); - List res = new ArrayList<>(); - if (curr != null) - terms: for (String str : curr) { - Term term = termsManager.getTerm(str); - if (term == null) { - log.warn("Ignoring term " + str + " for " + getNode() + ", as it was not found."); - continue terms; - } - res.add(term); - } - return res; - } - - protected void setValue(List value) { - String property = typology.getId(); - List ids = new ArrayList<>(); - for (Term term : value) { - ids.add(term.getId()); - } - Jcr.set(getNode(), property, ids); - Jcr.save(getNode()); - } - -} diff --git a/core/org.argeo.entity.ui/src/org/argeo/entity/ui/forms/SingleTermPart.java b/core/org.argeo.entity.ui/src/org/argeo/entity/ui/forms/SingleTermPart.java deleted file mode 100644 index 0b5948a..0000000 --- a/core/org.argeo.entity.ui/src/org/argeo/entity/ui/forms/SingleTermPart.java +++ /dev/null @@ -1,159 +0,0 @@ -package org.argeo.entity.ui.forms; - -import java.util.List; - -import javax.jcr.Item; - -import org.argeo.cms.ui.forms.FormStyle; -import org.argeo.cms.ui.util.CmsUiUtils; -import org.argeo.cms.ui.viewers.EditablePart; -import org.argeo.cms.ui.widgets.ContextOverlay; -import org.argeo.eclipse.ui.MouseDoubleClick; -import org.argeo.eclipse.ui.MouseDown; -import org.argeo.eclipse.ui.Selected; -import org.argeo.entity.Term; -import org.argeo.entity.TermsManager; -import org.argeo.jcr.Jcr; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Text; -import org.eclipse.swt.widgets.ToolBar; -import org.eclipse.swt.widgets.ToolItem; - -/** {@link EditablePart} for terms. */ -public class SingleTermPart extends AbstractTermsPart { - private static final long serialVersionUID = -4961135649177920808L; - - public SingleTermPart(Composite parent, int style, Item item, TermsManager termsManager, String typology) { - super(parent, style, item, termsManager, typology); - } - - @Override - protected Control createControl(Composite box, String style) { - if (isEditing()) { - Composite block = new Composite(box, SWT.NONE); - block.setLayout(CmsUiUtils.noSpaceGridLayout(3)); - - createHighlight(block); - - Text txt = new Text(block, SWT.SINGLE | SWT.BORDER); - CmsUiUtils.style(txt, style == null ? FormStyle.propertyText.style() : style); - - ToolBar toolBar = new ToolBar(block, SWT.HORIZONTAL); - ToolItem deleteItem = new ToolItem(toolBar, SWT.PUSH); - styleDelete(deleteItem); - deleteItem.addSelectionListener((Selected) (e) -> { - setValue(null); - stopEditing(); - }); - ToolItem cancelItem = new ToolItem(toolBar, SWT.PUSH); - styleCancel(cancelItem); - cancelItem.addSelectionListener((Selected) (e) -> { - stopEditing(); - }); - - ContextOverlay contextOverlay = new ContextOverlay(txt, SWT.NONE) { - private static final long serialVersionUID = -7980078594405384874L; - - @Override - protected void onHide() { - stopEditing(); - } - }; - contextOverlay.setLayout(new GridLayout()); - // filter - txt.addModifyListener((e) -> { - String filter = txt.getText().toLowerCase(); - if ("".equals(filter.trim())) - filter = null; - refresh(contextOverlay, filter, txt); - }); - txt.addFocusListener(new FocusListener() { - private static final long serialVersionUID = -6024501573409619949L; - - @Override - public void focusLost(FocusEvent event) { -// if (!contextOverlay.isDisposed() && contextOverlay.isShellVisible()) -// getDisplay().asyncExec(() -> stopEditing()); - } - - @Override - public void focusGained(FocusEvent event) { - // txt.setText(""); - if (!contextOverlay.isDisposed() && !contextOverlay.isShellVisible()) - refresh(contextOverlay, null, txt); - } - }); - layout(new Control[] { block }); - getDisplay().asyncExec(() -> txt.setFocus()); - return block; - } else { - Composite block = new Composite(box, SWT.NONE); - block.setLayout(CmsUiUtils.noSpaceGridLayout(2)); - Term currentValue = getValue(); - if (currentValue != null) { - Label lbl = new Label(block, SWT.SINGLE); - String display = getTermLabel(currentValue); - lbl.setText(display); - CmsUiUtils.style(lbl, style == null ? FormStyle.propertyText.style() : style); - processTermListLabel(currentValue, lbl); - if (isEditable()) { - lbl.addMouseListener((MouseDoubleClick) (e) -> { - startEditing(); - }); - } - } else { - if (isEditable()) { - ToolBar toolBar = new ToolBar(block, SWT.HORIZONTAL); - ToolItem addItem = new ToolItem(toolBar, SWT.FLAT); - styleAdd(addItem); - addItem.addSelectionListener((Selected) (e) -> { - startEditing(); - }); - } - } - return block; - } - } - - @Override - protected void refresh(ContextOverlay contextArea, String filter, Text txt) { - CmsUiUtils.clear(contextArea); - List terms = termsManager.listAllTerms(typology.getId()); - terms: for (Term term : terms) { - String display = getTermLabel(term); - if (filter != null && !display.toLowerCase().contains(filter)) - continue terms; - Label termL = new Label(contextArea, SWT.WRAP); - termL.setText(display); - processTermListLabel(term, termL); - if (isTermSelectable(term)) - termL.addMouseListener((MouseDown) (e) -> { - setValue(term); - contextArea.hide(); - stopEditing(); - }); - } - contextArea.show(); - // txt.setFocus(); - } - - protected Term getValue() { - String property = typology.getId(); - String id = Jcr.get(getNode(), property); - Term term = termsManager.getTerm(id); - - return term; - } - - protected void setValue(Term value) { - String property = typology.getId(); - Jcr.set(getNode(), property, value != null ? value.getId() : null); - Jcr.save(getNode()); - } -} diff --git a/core/org.argeo.suite.core/.classpath b/core/org.argeo.suite.core/.classpath deleted file mode 100644 index e801ebf..0000000 --- a/core/org.argeo.suite.core/.classpath +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/core/org.argeo.suite.core/.gitignore b/core/org.argeo.suite.core/.gitignore deleted file mode 100644 index 09e3bc9..0000000 --- a/core/org.argeo.suite.core/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/bin/ -/target/ diff --git a/core/org.argeo.suite.core/.project b/core/org.argeo.suite.core/.project deleted file mode 100644 index ab084af..0000000 --- a/core/org.argeo.suite.core/.project +++ /dev/null @@ -1,33 +0,0 @@ - - - org.argeo.suite.core - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - org.eclipse.pde.ds.core.builder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - diff --git a/core/org.argeo.suite.core/META-INF/.gitignore b/core/org.argeo.suite.core/META-INF/.gitignore deleted file mode 100644 index 4854a41..0000000 --- a/core/org.argeo.suite.core/META-INF/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/MANIFEST.MF diff --git a/core/org.argeo.suite.core/OSGI-INF/maintenanceService.xml b/core/org.argeo.suite.core/OSGI-INF/maintenanceService.xml deleted file mode 100644 index 2d495c8..0000000 --- a/core/org.argeo.suite.core/OSGI-INF/maintenanceService.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/core/org.argeo.suite.core/OSGI-INF/termsManager.xml b/core/org.argeo.suite.core/OSGI-INF/termsManager.xml deleted file mode 100644 index 3e6d4c6..0000000 --- a/core/org.argeo.suite.core/OSGI-INF/termsManager.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/core/org.argeo.suite.core/bnd.bnd b/core/org.argeo.suite.core/bnd.bnd deleted file mode 100644 index 1b9efff..0000000 --- a/core/org.argeo.suite.core/bnd.bnd +++ /dev/null @@ -1,14 +0,0 @@ -Bundle-ActivationPolicy: lazy - -Service-Component:\ -OSGI-INF/termsManager.xml,\ -OSGI-INF/maintenanceService.xml - -Import-Package:\ -javax.transaction,\ -org.osgi.service.useradmin,\ -javax.jcr.nodetype,\ -javax.jcr.security,\ -org.argeo.api,\ -org.argeo.entity,\ -* \ No newline at end of file diff --git a/core/org.argeo.suite.core/build.properties b/core/org.argeo.suite.core/build.properties deleted file mode 100644 index 6210e84..0000000 --- a/core/org.argeo.suite.core/build.properties +++ /dev/null @@ -1,5 +0,0 @@ -output.. = bin/ -bin.includes = META-INF/,\ - .,\ - OSGI-INF/ -source.. = src/ diff --git a/core/org.argeo.suite.core/pom.xml b/core/org.argeo.suite.core/pom.xml deleted file mode 100644 index 283dba0..0000000 --- a/core/org.argeo.suite.core/pom.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - 4.0.0 - - org.argeo.suite - core - 2.3-SNAPSHOT - .. - - org.argeo.suite.core - Suite Core - jar - - - org.argeo.suite - org.argeo.entity.core - 2.3-SNAPSHOT - - - - - org.argeo.commons - org.argeo.cms - ${version.argeo-commons} - - - org.argeo.commons - org.argeo.maintenance - ${version.argeo-commons} - - - diff --git a/core/org.argeo.suite.core/src/org/argeo/suite/RankedObject.java b/core/org.argeo.suite.core/src/org/argeo/suite/RankedObject.java deleted file mode 100644 index bfba46e..0000000 --- a/core/org.argeo.suite.core/src/org/argeo/suite/RankedObject.java +++ /dev/null @@ -1,98 +0,0 @@ -package org.argeo.suite; - -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * A container for an object whose relevance can be ranked. Typically used in an - * OSGi context with the service.ranking property. - */ -public class RankedObject { - private final static Log log = LogFactory.getLog(RankedObject.class); - - private final static String SERVICE_RANKING = "service.ranking"; -// private final static String SERVICE_ID = "service.id"; - - private T object; - private Map properties; - private final Long rank; - - public RankedObject(T object, Map properties) { - this(object, properties, extractRanking(properties)); - } - - public RankedObject(T object, Map properties, Long rank) { - super(); - this.object = object; - this.properties = properties; - this.rank = rank; - } - - private static Long extractRanking(Map properties) { - if (properties == null) - return 0l; - if (properties.containsKey(SERVICE_RANKING)) - return Long.valueOf(properties.get(SERVICE_RANKING).toString()); -// else if (properties.containsKey(SERVICE_ID)) -// return (Long) properties.get(SERVICE_ID); - else - return 0l; - } - - public T get() { - return object; - } - - public Map getProperties() { - return properties; - } - - public Long 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.equals(other.rank) && object.equals(other.object); - } - - @Override - public String toString() { - return object.getClass().getName() + " with rank " + rank; - } - - public static RankedObject putIfHigherRank(Map> map, K key, T object, - Map properties) { - RankedObject 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 current = map.get(key); - if (current.getRank() <= rankedObject.getRank()) { - map.put(key, rankedObject); - if (log.isTraceEnabled()) - log.trace("Replaced " + key + " by " + object.getClass().getName() + " with rank " - + rankedObject.getRank()); - return rankedObject; - } else { - return current; - } - } - - } - -} diff --git a/core/org.argeo.suite.core/src/org/argeo/suite/RankingKey.java b/core/org.argeo.suite.core/src/org/argeo/suite/RankingKey.java deleted file mode 100644 index e099195..0000000 --- a/core/org.argeo.suite.core/src/org/argeo/suite/RankingKey.java +++ /dev/null @@ -1,160 +0,0 @@ -package org.argeo.suite; - -import java.util.Map; - -/** - * Key used to classify and filter available components (typically provided by - * OSGi services). - */ -@Deprecated -public class RankingKey implements Comparable { - public final static String SERVICE_PID = "service.pid"; - public final static String SERVICE_ID = "service.id"; - public final static String SERVICE_RANKING = "service.ranking"; - public final static String DATA_TYPE = "data.type"; - - private String pid; - private Integer ranking = 0; - private Long id = 0l; - private String dataType; - private String dataPath; - - public RankingKey(String pid, Integer ranking, Long id, String dataType, String dataPath) { - super(); - this.pid = pid; - this.ranking = ranking; - this.id = id; - this.dataType = dataType; - this.dataPath = dataPath; - } - - public RankingKey(Map properties) { - this.pid = properties.containsKey(SERVICE_PID) ? properties.get(SERVICE_PID).toString() : null; - this.ranking = properties.containsKey(SERVICE_RANKING) - ? Integer.parseInt(properties.get(SERVICE_RANKING).toString()) - : 0; - this.id = properties.containsKey(SERVICE_ID) ? (Long) properties.get(SERVICE_ID) : null; - - // Argeo specific - this.dataType = properties.containsKey(DATA_TYPE) ? properties.get(DATA_TYPE).toString() : null; - } - - @Override - public int hashCode() { - Integer result = 0; - if (pid != null) - result = +pid.hashCode(); - if (ranking != null) - result = +ranking; - if (dataType != null) - result = +dataType.hashCode(); - return result; - } - - @Override - protected Object clone() throws CloneNotSupportedException { - return new RankingKey(pid, ranking, id, dataType, dataPath); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(""); - if (pid != null) - sb.append(pid); - if (ranking != null && ranking != 0) - sb.append(' ').append(ranking); - if (dataType != null) - sb.append(' ').append(dataType); - return sb.toString(); - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof RankingKey)) - return false; - RankingKey other = (RankingKey) obj; - return equalsOrBothNull(pid, other.pid) && equalsOrBothNull(ranking, other.ranking) - && equalsOrBothNull(id, other.id) && equalsOrBothNull(dataType, other.dataType) - && equalsOrBothNull(dataPath, other.dataPath); - } - - @Override - public int compareTo(RankingKey o) { - if (pid != null && o.pid != null) { - if (pid.equals(o.pid)) { - if (ranking.equals(o.ranking)) - if (id != null && o.id != null) - return id.compareTo(o.id); - else - return 0; - else - return ranking.compareTo(o.ranking); - } else { - return pid.compareTo(o.pid); - } - - } else { - if (dataType != null && o.dataType != null) { - if (dataType.equals(o.dataType)) { - // TODO factorise - if (ranking.equals(o.ranking)) - if (id != null && o.id != null) - return id.compareTo(o.id); - else - return 0; - else - return ranking.compareTo(o.ranking); - } else { - return dataPath.compareTo(o.dataType); - } - } - } - return -1; - } - - public String getPid() { - return pid; - } - - public Integer getRanking() { - return ranking; - } - - public Long getId() { - return id; - } - - public String getDataType() { - return dataType; - } - - public String getDataPath() { - return dataPath; - } - - public static RankingKey minPid(String pid) { - return new RankingKey(pid, Integer.MIN_VALUE, null, null, null); - } - - public static RankingKey maxPid(String pid) { - return new RankingKey(pid, Integer.MAX_VALUE, null, null, null); - } - - public static RankingKey minDataType(String dataType) { - return new RankingKey(null, Integer.MIN_VALUE, null, dataType, null); - } - - public static RankingKey maxDataType(String dataType) { - return new RankingKey(null, Integer.MAX_VALUE, null, dataType, null); - } - - private static boolean equalsOrBothNull(Object o1, Object o2) { - if (o1 == null && o2 == null) - return true; - if (o1 == null && o2 != null) - return false; - if (o1 != null && o2 == null) - return false; - return o2.equals(o1); - } -} diff --git a/core/org.argeo.suite.core/src/org/argeo/suite/SuiteRole.java b/core/org.argeo.suite.core/src/org/argeo/suite/SuiteRole.java deleted file mode 100644 index 382f50c..0000000 --- a/core/org.argeo.suite.core/src/org/argeo/suite/SuiteRole.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.argeo.suite; - -import org.argeo.api.NodeConstants; -import org.argeo.naming.Distinguished; -import org.argeo.naming.LdapAttrs; - -/** Office specific roles used in the code */ -public enum SuiteRole implements Distinguished { - coworker, manager; - - public String getRolePrefix() { - return "org.argeo.suite"; - } - - public String dn() { - return new StringBuilder(LdapAttrs.cn.name()).append("=").append(getRolePrefix()).append(".").append(name()) - .append(",").append(NodeConstants.ROLES_BASEDN).toString(); - } -} diff --git a/core/org.argeo.suite.core/src/org/argeo/suite/SuiteUtils.java b/core/org.argeo.suite.core/src/org/argeo/suite/SuiteUtils.java deleted file mode 100644 index 93f3b14..0000000 --- a/core/org.argeo.suite.core/src/org/argeo/suite/SuiteUtils.java +++ /dev/null @@ -1,122 +0,0 @@ -package org.argeo.suite; - -import java.util.HashSet; -import java.util.Set; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; -import javax.jcr.Session; -import javax.jcr.nodetype.NodeType; -import javax.jcr.security.Privilege; -import javax.naming.ldap.LdapName; -import javax.security.auth.x500.X500Principal; - -import org.argeo.api.NodeConstants; -import org.argeo.cms.auth.CmsSession; -import org.argeo.entity.EntityType; -import org.argeo.jackrabbit.security.JackrabbitSecurityUtils; -import org.argeo.jcr.JcrException; -import org.argeo.jcr.JcrUtils; -import org.argeo.naming.LdapAttrs; - -/** Utilities around the Argeo Suite APIs. */ -public class SuiteUtils { - - public static String getUserNodePath(LdapName userDn) { - String uid = userDn.getRdn(userDn.size() - 1).getValue().toString(); - return EntityType.user.basePath() + '/' + uid; - } - - public static Node getOrCreateUserNode(Session adminSession, LdapName userDn) { - try { - Node usersBase = adminSession.getNode(EntityType.user.basePath()); - String uid = userDn.getRdn(userDn.size() - 1).getValue().toString(); - Node userNode; - if (!usersBase.hasNode(uid)) { - userNode = usersBase.addNode(uid, NodeType.NT_UNSTRUCTURED); - userNode.addMixin(EntityType.user.get()); - userNode.addMixin(NodeType.MIX_CREATED); - userNode.setProperty(LdapAttrs.distinguishedName.property(), userDn.toString()); - userNode.setProperty(LdapAttrs.uid.property(), uid); - adminSession.save(); - JackrabbitSecurityUtils.denyPrivilege(adminSession, userNode.getPath(), SuiteRole.coworker.dn(), - Privilege.JCR_READ); - JcrUtils.addPrivilege(adminSession, userNode.getPath(), new X500Principal(userDn.toString()).getName(), - Privilege.JCR_READ); - JcrUtils.addPrivilege(adminSession, userNode.getPath(), NodeConstants.ROLE_USER_ADMIN, - Privilege.JCR_ALL); - } else { - userNode = usersBase.getNode(uid); - } - return userNode; - } catch (RepositoryException e) { - throw new JcrException("Cannot create user node for " + userDn, e); - } - } - - public static Node getCmsSessionNode(Session session, CmsSession cmsSession) { - try { - return session.getNode(getUserNodePath(cmsSession.getUserDn()) + '/' + cmsSession.getUuid().toString()); - } catch (RepositoryException e) { - throw new JcrException("Cannot get session dir for " + cmsSession, e); - } - } - - public static Node getOrCreateCmsSessionNode(Session adminSession, CmsSession cmsSession) { - try { - LdapName userDn = cmsSession.getUserDn(); -// String uid = userDn.get(userDn.size() - 1); - Node userNode = getOrCreateUserNode(adminSession, userDn); -// if (!usersBase.hasNode(uid)) { -// userNode = usersBase.addNode(uid, NodeType.NT_UNSTRUCTURED); -// userNode.addMixin(EntityType.user.get()); -// userNode.addMixin(NodeType.MIX_CREATED); -// usersBase.setProperty(LdapAttrs.uid.property(), uid); -// usersBase.setProperty(LdapAttrs.distinguishedName.property(), userDn.toString()); -// adminSession.save(); -// } else { -// userNode = usersBase.getNode(uid); -// } - String cmsSessionUuid = cmsSession.getUuid().toString(); - Node cmsSessionNode; - if (!userNode.hasNode(cmsSessionUuid)) { - cmsSessionNode = userNode.addNode(cmsSessionUuid, NodeType.NT_UNSTRUCTURED); - cmsSessionNode.addMixin(NodeType.MIX_CREATED); - adminSession.save(); - JcrUtils.addPrivilege(adminSession, cmsSessionNode.getPath(), cmsSession.getUserRole(), - Privilege.JCR_ALL); - } else { - cmsSessionNode = userNode.getNode(cmsSessionUuid); - } - return cmsSessionNode; - } catch (RepositoryException e) { - throw new JcrException("Cannot create session dir for " + cmsSession, e); - } - } - - /** Singleton. */ - private SuiteUtils() { - - } - - public static Set extractRoles(String[] semiColArr) { - Set res = new HashSet<>(); - // TODO factorize and make it more robust - final String rolesPrefix = "roles:=\""; - // first one is layer id - for (int i = 1; i < semiColArr.length; i++) { - if (semiColArr[i].startsWith(rolesPrefix)) { - String rolesStr = semiColArr[i].substring(rolesPrefix.length()); - // remove last " - rolesStr = rolesStr.substring(0, rolesStr.lastIndexOf('\"')); - // TODO support AND (&) as well - String[] roles = rolesStr.split("\\|");// OR (|) - for (String role : roles) { - res.add(role.trim()); - } - } - } - return res; - } - -} diff --git a/core/org.argeo.suite.core/src/org/argeo/suite/core/CustomMaintenanceService.java b/core/org.argeo.suite.core/src/org/argeo/suite/core/CustomMaintenanceService.java deleted file mode 100644 index 5d76eb1..0000000 --- a/core/org.argeo.suite.core/src/org/argeo/suite/core/CustomMaintenanceService.java +++ /dev/null @@ -1,74 +0,0 @@ -package org.argeo.suite.core; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; - -import javax.jcr.ImportUUIDBehavior; -import javax.jcr.ItemExistsException; -import javax.jcr.Node; -import javax.jcr.RepositoryException; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.entity.EntityType; -import org.argeo.jcr.JcrUtils; -import org.argeo.maintenance.AbstractMaintenanceService; - -/** Base for custom initialisations. */ -public abstract class CustomMaintenanceService extends AbstractMaintenanceService { - private final static Log log = LogFactory.getLog(AbstractMaintenanceService.class); - - protected List getTypologies() { - return new ArrayList<>(); - } - - protected String getTypologiesLoadBase() { - return "/sys/terms"; - } - - protected void loadTypologies(Node customBaseNode) throws RepositoryException, IOException { - List typologies = getTypologies(); - if (!typologies.isEmpty()) { - Node termsBase = JcrUtils.getOrAdd(customBaseNode, EntityType.terms.name(), EntityType.typologies.get()); - for (String terms : typologies) { - loadTerms(termsBase, terms); - } - // TODO do not save here, so that upper layers can decide when to save - termsBase.getSession().save(); - } - } - - protected void loadTerms(Node termsBase, String name) throws IOException, RepositoryException { - try { -// if (termsBase.hasNode(name)) -// return; - - String termsLoadPath = getTypologiesLoadBase() + '/' + name + ".xml"; - URL termsUrl = getClass().getClassLoader().getResource(termsLoadPath); - if (termsUrl == null) - throw new IllegalArgumentException("Terms '" + name + "' not found."); - try (InputStream in = termsUrl.openStream()) { - termsBase.getSession().importXML(termsBase.getPath(), in, - ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING); - } catch (ItemExistsException e) { - log.warn("Terms " + name + " exists with another UUID, removing it..."); - termsBase.getNode(name).remove(); - try (InputStream in = termsUrl.openStream()) { - termsBase.getSession().importXML(termsBase.getPath(), in, - ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING); - } - } - if (log.isDebugEnabled()) - log.debug("Terms '" + name + "' loaded."); - // TODO do not save here, so that upper layers can decide when to save - termsBase.getSession().save(); - } catch (RepositoryException | IOException e) { - log.error("Cannot load terms '" + name + "': " + e.getMessage()); - throw e; - } - } - -} diff --git a/core/org.argeo.suite.core/src/org/argeo/suite/core/SuiteMaintenanceService.java b/core/org.argeo.suite.core/src/org/argeo/suite/core/SuiteMaintenanceService.java deleted file mode 100644 index b217373..0000000 --- a/core/org.argeo.suite.core/src/org/argeo/suite/core/SuiteMaintenanceService.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.argeo.suite.core; - -import java.io.IOException; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; -import javax.jcr.Session; -import javax.jcr.nodetype.NodeType; -import javax.jcr.security.Privilege; - -import org.argeo.api.NodeConstants; -import org.argeo.entity.EntityType; -import org.argeo.jcr.JcrUtils; -import org.argeo.maintenance.AbstractMaintenanceService; - -/** Initialises an Argeo Suite backend. */ -public class SuiteMaintenanceService extends AbstractMaintenanceService { - - @Override - public boolean prepareJcrTree(Session adminSession) throws RepositoryException, IOException { - boolean modified = false; - Node rootNode = adminSession.getRootNode(); - if (!rootNode.hasNode(EntityType.user.name())) { - rootNode.addNode(EntityType.user.name(), NodeType.NT_UNSTRUCTURED); - modified = true; - } - if (modified) - adminSession.save(); - return modified; - } - - @Override - public void configurePrivileges(Session adminSession) throws RepositoryException { - JcrUtils.addPrivilege(adminSession, EntityType.user.basePath(), NodeConstants.ROLE_USER_ADMIN, - Privilege.JCR_ALL); - //JcrUtils.addPrivilege(adminSession, "/", SuiteRole.coworker.dn(), Privilege.JCR_READ); - } - -} diff --git a/core/org.argeo.suite.core/src/org/argeo/suite/core/SuiteTerm.java b/core/org.argeo.suite.core/src/org/argeo/suite/core/SuiteTerm.java deleted file mode 100644 index 227b567..0000000 --- a/core/org.argeo.suite.core/src/org/argeo/suite/core/SuiteTerm.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.argeo.suite.core; - -import java.util.ArrayList; -import java.util.List; - -import org.argeo.entity.Term; - -/** - * A single term. Helper to optimise {@link SuiteTermsManager} implementation. - */ -class SuiteTerm implements Term { - private final String name; - private final String relativePath; - private final SuiteTypology typology; - private final String id; - - private final SuiteTerm parentTerm; - private final List subTerms = new ArrayList<>(); - - SuiteTerm(SuiteTypology typology, String relativePath, SuiteTerm parentTerm) { - this.typology = typology; - this.parentTerm = parentTerm; - this.relativePath = relativePath; - int index = relativePath.lastIndexOf('/'); - if (index > 0) { - this.name = relativePath.substring(index + 1); - } else { - this.name = relativePath; - } - id = typology.getName() + '/' + relativePath; - } - - @Override - public String getId() { - return id; - } - - @Override - public String getName() { - return name; - } - - public String getRelativePath() { - return relativePath; - } - - @Override - public SuiteTypology getTypology() { - return typology; - } - - @Override - public List getSubTerms() { - return subTerms; - } - - @Override - public SuiteTerm getParentTerm() { - return parentTerm; - } - -} diff --git a/core/org.argeo.suite.core/src/org/argeo/suite/core/SuiteTermsManager.java b/core/org.argeo.suite.core/src/org/argeo/suite/core/SuiteTermsManager.java deleted file mode 100644 index f8822f7..0000000 --- a/core/org.argeo.suite.core/src/org/argeo/suite/core/SuiteTermsManager.java +++ /dev/null @@ -1,103 +0,0 @@ -package org.argeo.suite.core; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.jcr.Node; -import javax.jcr.Repository; -import javax.jcr.RepositoryException; -import javax.jcr.Session; - -import org.argeo.api.NodeConstants; -import org.argeo.api.NodeUtils; -import org.argeo.entity.EntityNames; -import org.argeo.entity.EntityType; -import org.argeo.entity.Term; -import org.argeo.entity.TermsManager; -import org.argeo.jcr.Jcr; -import org.argeo.jcr.JcrException; - -/** Argeo Suite implementation of terms manager. */ -public class SuiteTermsManager implements TermsManager { - private final Map terms = new HashMap<>(); - private final Map typologies = new HashMap<>(); - - // JCR - private Repository repository; - private Session adminSession; - - public void init() { - adminSession = NodeUtils.openDataAdminSession(repository, NodeConstants.SYS_WORKSPACE); - } - - @Override - public List listAllTerms(String typology) { - List res = new ArrayList<>(); - SuiteTypology t = getTypology(typology); - for (SuiteTerm term : t.getAllTerms()) { - res.add(term); - } - return res; - } - - @Override - public SuiteTerm getTerm(String termId) { - return terms.get(termId); - } - - @Override - public SuiteTypology getTypology(String typology) { - SuiteTypology t = typologies.get(typology); - if (t == null) { - Node termsNode = Jcr.getNode(adminSession, "SELECT * FROM [{0}] WHERE NAME()=\"{1}\"", - EntityType.terms.get(), typology); - if (termsNode == null) - throw new IllegalArgumentException("Typology " + typology + " not found."); - t = loadTypology(termsNode); - } - return t; - } - - SuiteTypology loadTypology(Node termsNode) { - try { - SuiteTypology typology = new SuiteTypology(termsNode); - for (Node termNode : Jcr.iterate(termsNode.getNodes())) { - if (termNode.isNodeType(EntityType.term.get())) { - SuiteTerm term = loadTerm(typology, termNode, null); - if (!term.getSubTerms().isEmpty()) - typology.markNotFlat(); - typology.getSubTerms().add(term); - } - } - typologies.put(typology.getName(), typology); - return typology; - } catch (RepositoryException e) { - throw new JcrException("Cannot load typology from " + termsNode, e); - } - } - - SuiteTerm loadTerm(SuiteTypology typology, Node termNode, SuiteTerm parentTerm) throws RepositoryException { - String name = termNode.getProperty(EntityNames.NAME).getString(); - String relativePath = parentTerm == null ? name : parentTerm.getRelativePath() + '/' + name; - SuiteTerm term = new SuiteTerm(typology, relativePath, parentTerm); - terms.put(term.getId(), term); - for (Node subTermNode : Jcr.iterate(termNode.getNodes())) { - if (termNode.isNodeType(EntityType.term.get())) { - SuiteTerm subTerm = loadTerm(typology, subTermNode, term); - term.getSubTerms().add(subTerm); - } - } - return term; - } - - public void destroy() { - Jcr.logout(adminSession); - } - - public void setRepository(Repository repository) { - this.repository = repository; - } - -} diff --git a/core/org.argeo.suite.core/src/org/argeo/suite/core/SuiteTypology.java b/core/org.argeo.suite.core/src/org/argeo/suite/core/SuiteTypology.java deleted file mode 100644 index d9d6673..0000000 --- a/core/org.argeo.suite.core/src/org/argeo/suite/core/SuiteTypology.java +++ /dev/null @@ -1,95 +0,0 @@ -package org.argeo.suite.core; - -import java.util.ArrayList; -import java.util.List; - -import javax.jcr.Node; - -import org.argeo.entity.Term; -import org.argeo.entity.Typology; -import org.argeo.jcr.Jcr; - -/** A typology. Helper to optimise {@link SuiteTermsManager} implementation. */ -class SuiteTypology implements Typology { - private final String name; - private final Node node; - private boolean isFlat = true; - - private final List subTerms = new ArrayList<>(); - - public SuiteTypology(Node node) { - this.node = node; - this.name = Jcr.getName(this.node); - } - - @Override - public String getId() { - return name; - } - - public String getName() { - return name; - } - - public Node getNode() { - return node; - } - - void markNotFlat() { - if (isFlat) - isFlat = false; - } - - @Override - public boolean isFlat() { - return isFlat; - } - - @Override - public List getSubTerms() { - return subTerms; - } - - public List getAllTerms() { - if (isFlat) - return subTerms; - else { - List terms = new ArrayList<>(); - for (SuiteTerm subTerm : subTerms) { - terms.add(subTerm); - collectSubTerms(terms, subTerm); - } - return terms; - } - } - - public Term findTermByName(String name) { - List collected = new ArrayList<>(); - for (SuiteTerm subTerm : subTerms) { - collectTermsByName(subTerm, name, collected); - } - if (collected.isEmpty()) - return null; - if (collected.size() == 1) - return collected.get(0); - throw new IllegalArgumentException( - "There are " + collected.size() + " terms with name " + name + " in typology " + getId()); - } - - private void collectTermsByName(SuiteTerm term, String name, List collected) { - if (term.getName().equals(name)) { - collected.add(term); - } - for (SuiteTerm subTerm : term.getSubTerms()) { - collectTermsByName(subTerm, name, collected); - } - } - - private void collectSubTerms(List terms, SuiteTerm term) { - for (SuiteTerm subTerm : term.getSubTerms()) { - terms.add(subTerm); - collectSubTerms(terms, subTerm); - } - } - -} diff --git a/core/org.argeo.suite.core/src/org/argeo/suite/library/DocxExtractor.java b/core/org.argeo.suite.core/src/org/argeo/suite/library/DocxExtractor.java deleted file mode 100644 index 53e73f3..0000000 --- a/core/org.argeo.suite.core/src/org/argeo/suite/library/DocxExtractor.java +++ /dev/null @@ -1,355 +0,0 @@ -package org.argeo.suite.library; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - -import org.argeo.util.DigestUtils; -import org.xml.sax.Attributes; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.XMLReader; -import org.xml.sax.helpers.DefaultHandler; - -/** Parses a .docx document, trying its best to extract text and table data. */ -public class DocxExtractor { - final static String T = "t"; - final static String TC = "tc"; - final static String TR = "tr"; - final static String TBL = "tbl"; - final static String P = "p"; - static boolean debug = false; - - final static String PROOF_ERR = "proofErr"; - final static String TYPE = "type"; - final static String SPELL_START = "spellStart"; - final static String SPELL_END = "spellEnd"; - - protected List tables = new ArrayList<>(); - protected List text = new ArrayList<>(); - protected Map media = new TreeMap<>(); - private Set mediaDigests = new HashSet<>(); - - protected void processTextItem(List lines, String str) { - lines.add(str); - } - - protected boolean skipMedia(String digest) { - return false; - } - - class DocxHandler extends DefaultHandler { - - private StringBuilder buffer = new StringBuilder(); - private Tbl currentTbl = null; - - boolean inSpellErr = false; - boolean inParagraph = false; - - @Override - public void startElement(String uri, String name, String qName, Attributes attributes) throws SAXException { - // System.out.println(localName + " " + qName + " " + uri.hashCode()); - if (P.equals(name)) { - if (debug && currentTbl == null) - System.out.println("# START PARA"); - inParagraph = true; - } else if (PROOF_ERR.equals(name)) { - String type = attributes.getValue(uri, TYPE); - if (SPELL_START.equals(type)) - inSpellErr = true; - else if (SPELL_END.equals(type)) - inSpellErr = false; - - } else if (TBL.equals(name)) { - if (currentTbl != null) { - Tbl childTbl = new Tbl(); - childTbl.parentTbl = currentTbl; - currentTbl = childTbl; - // throw new IllegalStateException("Already an active table"); - } else { - currentTbl = new Tbl(); - } - } - } - - @Override - public void endElement(String uri, String name, String qName) throws SAXException { - if (name.equals(T)) { -// if (inSpellErr) { -// // do not reset the buffer -// return; -// } - - if (currentTbl != null) { - currentTbl.appendText(buffer.toString()); - } else { - String str = buffer.toString(); - // replace NO-BREAK SPACE by regular space. - str = str.replace('\u00A0', ' '); - str = str.strip(); - if (!"".equals(str)) { - processTextItem(text, str); - } - } - } else if (name.equals(P)) { - if (debug && currentTbl == null) - System.out.println("# END PARA"); - if (currentTbl != null) { - currentTbl.currentRow.current.text.append('\n'); - } else { - - } - inParagraph = false; - } else if (name.equals(TC)) { - if (currentTbl != null) - currentTbl.closeColumn(); - } else if (name.equals(TR)) { - if (currentTbl != null) - currentTbl.closeRow(); - } else if (name.equals(TBL)) { - if (currentTbl != null) { - tables.add(currentTbl); - if (currentTbl.parentTbl != null) - currentTbl = currentTbl.parentTbl; - else - currentTbl = null; - } else { - throw new IllegalStateException("Closing a table while none was open."); - } - } - // reset the buffer - buffer.setLength(0); - } - - @Override - public void characters(char[] ch, int start, int length) throws SAXException { - buffer.append(ch, start, length); - } - - } - - public static class Tbl { - Tbl parentTbl = null; - Tr currentRow = new Tr(); - List
rows = new ArrayList<>(); - - void appendText(String str) { - currentRow.current.text.append(str); - } - - void closeColumn() { - currentRow.columns.add(currentRow.current); - currentRow.current = new Tc(); - } - - void closeRow() { - rows.add(currentRow); - currentRow = new Tr(); - } - - public List
getRows() { - return rows; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - for (Tr tr : rows) { - String txt = tr.toString(); - sb.append(txt).append('\n'); - } - return sb.toString(); - } - } - - public static class Tr { - Tc current = new Tc(); - List columns = new ArrayList<>(); - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - for (Tc tc : columns) { - sb.append("\"").append(tc.toString()).append("\"").append(','); - } - return sb.toString(); - } - - public List getColumns() { - return columns; - } - - } - - public static class Tc { - StringBuilder text = new StringBuilder(); - - @Override - public String toString() { - return text.toString().trim(); - } - - } - - protected void parse(Reader in) { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - SAXParser saxParser = spf.newSAXParser(); - XMLReader xmlReader = saxParser.getXMLReader(); - xmlReader.setContentHandler(new DocxHandler()); - xmlReader.parse(new InputSource(in)); - } catch (ParserConfigurationException | SAXException | IOException e) { - throw new RuntimeException("Cannot parse document", e); - } - } - - public List getText() { - return text; - } - - public List getTables() { - return tables; - } - - public Map getMedia() { - return media; - } - - public void load(ZipInputStream zIn) { - try { - ZipEntry entry = null; - while ((entry = zIn.getNextEntry()) != null) { - if ("word/document.xml".equals(entry.getName())) { - try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { - byte[] buffer = new byte[2048]; - int len = 0; - while ((len = zIn.read(buffer)) > 0) { - out.write(buffer, 0, len); - } - try (Reader reader = new InputStreamReader(new ByteArrayInputStream(out.toByteArray()), - StandardCharsets.UTF_8)) { - parse(reader); - } - } - } else if (entry.getName().startsWith("word/media")) { - String fileName = entry.getName().substring(entry.getName().lastIndexOf('/') + 1); - int dotIndex = fileName.lastIndexOf('.'); - String ext = fileName.substring(dotIndex + 1).toLowerCase(); - // we ignore .jfif - if ("jpeg".equals(ext)) - ext = "jpg"; - fileName = fileName.substring(0, dotIndex) + "." + ext; - switch (ext) { - case "png": - case "jpg": - case "gif": - case "bmp": - case "tiff": - try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { - byte[] buffer = new byte[2048]; - int len = 0; - while ((len = zIn.read(buffer)) > 0) { - out.write(buffer, 0, len); - } - byte[] bytes = out.toByteArray(); - String digest = DigestUtils.digest(DigestUtils.MD5, bytes); - if (skipMedia(digest)) - break; - if (!mediaDigests.contains(digest)) { - media.put(fileName, bytes); - mediaDigests.add(digest); - } - } - break; - default: - break; - } - } else { - // System.out.println(entry.getName()); - } - } - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - // throw new IllegalArgumentException("No document.xml found"); - - } - -// public static Reader extractDocumentXml(ZipInputStream zIn) throws IOException { -// ZipEntry entry = null; -// while ((entry = zIn.getNextEntry()) != null) { -// if ("word/document.xml".equals(entry.getName())) { -// try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { -// byte[] buffer = new byte[2048]; -// int len = 0; -// while ((len = zIn.read(buffer)) > 0) { -// out.write(buffer, 0, len); -// } -// return new InputStreamReader(new ByteArrayInputStream(out.toByteArray()), StandardCharsets.UTF_8); -// } -// } else { -// System.out.println(entry.getName()); -// } -// } -// throw new IllegalArgumentException("No document.xml found"); -// } - -// protected static ZipInputStream openAsZip(String file) throws IOException { -// ZipInputStream zIn; -// Path path = Paths.get(file); -// zIn = new ZipInputStream(Files.newInputStream(path)); -// return zIn; -// } - - public static void main(String[] args) throws IOException { - if (args.length == 0) - throw new IllegalArgumentException("Provide a file path"); - Path p = Paths.get(args[0]); - - DocxExtractor importer = new DocxExtractor(); - try (ZipInputStream zIn = new ZipInputStream(Files.newInputStream(p))) { - importer.load(zIn); - } - // display - System.out.println("## TEXT"); - for (int i = 0; i < importer.text.size(); i++) { - String str = importer.text.get(i); - System.out.println(str); - } - - System.out.println("\n"); - - for (int i = 0; i < importer.tables.size(); i++) { - Tbl tbl = importer.tables.get(i); - System.out.println("## TABLE " + i); - System.out.println(tbl); - } - - System.out.println("## MEDIA"); - for (String fileName : importer.media.keySet()) { - int sizeKb = importer.media.get(fileName).length / 1024; - System.out.println(fileName + " " + sizeKb + " kB"); - } - } - -} diff --git a/core/org.argeo.suite.core/src/org/argeo/suite/util/XPathUtils.java b/core/org.argeo.suite.core/src/org/argeo/suite/util/XPathUtils.java deleted file mode 100644 index 66d9aa0..0000000 --- a/core/org.argeo.suite.core/src/org/argeo/suite/util/XPathUtils.java +++ /dev/null @@ -1,177 +0,0 @@ -package org.argeo.suite.util; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Calendar; - -import javax.jcr.RepositoryException; -import javax.jcr.Session; -import javax.jcr.query.Query; -import javax.jcr.query.QueryManager; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.jackrabbit.util.ISO9075; - -/** Ease XPath generation for JCR requests */ -public class XPathUtils { - private final static Log log = LogFactory.getLog(XPathUtils.class); - - private final static String QUERY_XPATH = "xpath"; - - public static String descendantFrom(String parentPath) { - if (notEmpty(parentPath)) { - if ("/".equals(parentPath)) - parentPath = ""; - // Hardcoded dependency to Jackrabbit. Remove - String result = "/jcr:root" + ISO9075.encodePath(parentPath); - if (log.isTraceEnabled()) { - String result2 = "/jcr:root" + parentPath; - if (!result2.equals(result)) - log.warn("Encoded Path " + result2 + " --> " + result); - } - return result; - } else - return ""; - } - - public static String localAnd(String... conditions) { - StringBuilder builder = new StringBuilder(); - for (String condition : conditions) { - if (notEmpty(condition)) { - builder.append(" ").append(condition).append(" and "); - } - } - if (builder.length() > 3) - return builder.substring(0, builder.length() - 4); - else - return ""; - } - - public static String xPathNot(String condition) { - if (notEmpty(condition)) - return "not(" + condition + ")"; - else - return ""; - } - - public static String getFreeTextConstraint(String filter) throws RepositoryException { - StringBuilder builder = new StringBuilder(); - if (notEmpty(filter)) { - String[] strs = filter.trim().split(" "); - for (String token : strs) { - builder.append("jcr:contains(.,'*" + encodeXPathStringValue(token) + "*') and "); - } - return builder.substring(0, builder.length() - 4); - } - return ""; - } - - public static String getPropertyContains(String propertyName, String filter) throws RepositoryException { - if (notEmpty(filter)) - return "jcr:contains(@" + propertyName + ",'*" + encodeXPathStringValue(filter) + "*')"; - return ""; - } - - private final static DateFormat jcrRefFormatter = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSS'+02:00'"); - - /** - * @param propertyName - * @param calendar the reference date - * @param lowerOrGreater "<", ">" TODO validate ">=" - * @return - * @throws RepositoryException - */ - public static String getPropertyDateComparaison(String propertyName, Calendar cal, String lowerOrGreater) - throws RepositoryException { - if (cal != null) { - String jcrDateStr = jcrRefFormatter.format(cal.getTime()); - - // jcrDateStr = "2015-08-03T05:00:03:000Z"; - String result = "@" + propertyName + " " + lowerOrGreater + " xs:dateTime('" + jcrDateStr + "')"; - return result; - } - return ""; - } - - public static String getPropertyEquals(String propertyName, String value) { - if (notEmpty(value)) - return "@" + propertyName + "='" + encodeXPathStringValue(value) + "'"; - return ""; - } - - public static String encodeXPathStringValue(String propertyValue) { - // TODO implement safer mechanism to escape invalid characters - // Also check why we have used this regex in ResourceSerrviceImpl l 474 - // String cleanedKey = key.replaceAll("(?:')", "''"); - String result = propertyValue.replaceAll("'", "''"); - return result; - } - - public static void andAppend(StringBuilder builder, String condition) { - if (notEmpty(condition)) { - builder.append(condition); - builder.append(" and "); - } - } - - public static void appendOrderByProperties(StringBuilder builder, boolean ascending, String... propertyNames) { - if (propertyNames.length > 0) { - builder.append(" order by "); - for (String propName : propertyNames) - builder.append("@").append(propName).append(", "); - builder = builder.delete(builder.length() - 2, builder.length()); - if (ascending) - builder.append(" ascending "); - else - builder.append(" descending "); - } - } - - public static void appendAndPropStringCondition(StringBuilder builder, String propertyName, String filter) - throws RepositoryException { - if (notEmpty(filter)) { - andAppend(builder, getPropertyContains(propertyName, filter)); - } - } - - public static void appendAndNotPropStringCondition(StringBuilder builder, String propertyName, String filter) - throws RepositoryException { - if (notEmpty(filter)) { - String cond = getPropertyContains(propertyName, filter); - builder.append(xPathNot(cond)); - builder.append(" and "); - } - } - - public static Query createQuery(Session session, String queryString) throws RepositoryException { - QueryManager queryManager = session.getWorkspace().getQueryManager(); - // Localise JCR properties for XPATH - queryString = localiseJcrItemNames(queryString); - return queryManager.createQuery(queryString, QUERY_XPATH); - } - - private final static String NS_JCR = "\\{http://www.jcp.org/jcr/1.0\\}"; - private final static String NS_NT = "\\{http://www.jcp.org/jcr/nt/1.0\\}"; - private final static String NS_MIX = "\\{http://www.jcp.org/jcr/mix/1.0\\}"; - - /** - * Replace the generic namespace with the local "jcr:", "nt:", "mix:" values. It - * is a workaround that must be later cleaned - */ - public static String localiseJcrItemNames(String name) { - name = name.replaceAll(NS_JCR, "jcr:"); - name = name.replaceAll(NS_NT, "nt:"); - name = name.replaceAll(NS_MIX, "mix:"); - return name; - } - - private static boolean notEmpty(String stringToTest) { - return !(stringToTest == null || "".equals(stringToTest.trim())); - } - - /** Singleton. */ - private XPathUtils() { - - } -} diff --git a/core/org.argeo.suite.theme.default/.gitignore b/core/org.argeo.suite.theme.default/.gitignore deleted file mode 100644 index 09e3bc9..0000000 --- a/core/org.argeo.suite.theme.default/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/bin/ -/target/ diff --git a/core/org.argeo.suite.theme.default/.project b/core/org.argeo.suite.theme.default/.project deleted file mode 100644 index d157155..0000000 --- a/core/org.argeo.suite.theme.default/.project +++ /dev/null @@ -1,27 +0,0 @@ - - - org.argeo.suite.theme.default - - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - org.eclipse.pde.ds.core.builder - - - - - - org.eclipse.pde.PluginNature - - diff --git a/core/org.argeo.suite.theme.default/META-INF/.gitignore b/core/org.argeo.suite.theme.default/META-INF/.gitignore deleted file mode 100644 index 4854a41..0000000 --- a/core/org.argeo.suite.theme.default/META-INF/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/MANIFEST.MF diff --git a/core/org.argeo.suite.theme.default/OSGI-INF/cmsTheme.xml b/core/org.argeo.suite.theme.default/OSGI-INF/cmsTheme.xml deleted file mode 100644 index 66b8c44..0000000 --- a/core/org.argeo.suite.theme.default/OSGI-INF/cmsTheme.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/core/org.argeo.suite.theme.default/bnd.bnd b/core/org.argeo.suite.theme.default/bnd.bnd deleted file mode 100644 index 6c4a97c..0000000 --- a/core/org.argeo.suite.theme.default/bnd.bnd +++ /dev/null @@ -1,6 +0,0 @@ -Service-Component:\ -OSGI-INF/cmsTheme.xml - -Import-Package:\ -org.argeo.cms.ui.util,\ -* \ No newline at end of file diff --git a/core/org.argeo.suite.theme.default/build.properties b/core/org.argeo.suite.theme.default/build.properties deleted file mode 100644 index 7f8c707..0000000 --- a/core/org.argeo.suite.theme.default/build.properties +++ /dev/null @@ -1,2 +0,0 @@ -bin.includes = META-INF/,\ - OSGI-INF/ diff --git a/core/org.argeo.suite.theme.default/pom.xml b/core/org.argeo.suite.theme.default/pom.xml deleted file mode 100644 index 1f5398a..0000000 --- a/core/org.argeo.suite.theme.default/pom.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - 4.0.0 - - org.argeo.suite - core - 2.3-SNAPSHOT - .. - - org.argeo.suite.theme.default - Suite Default Theme - jar - - - diff --git a/core/org.argeo.suite.theme.default/rap/work.css b/core/org.argeo.suite.theme.default/rap/work.css deleted file mode 100644 index c0aaeb1..0000000 --- a/core/org.argeo.suite.theme.default/rap/work.css +++ /dev/null @@ -1,181 +0,0 @@ -.argeo-suite-header { - color: white; - background-color: #00294b; -} - -.argeo-suite-headerTitle { - font: bold 18px sans-serif; - color: white; - background-color: #00294b; -} - -.argeo-suite-leadPane { - background-color: #eee; -} - -Label.argeo-suite-leadPane { - font: 14px sans-serif; - color: #888; - background-color: #eee; -} - -Button.argeo-suite-leadPane:hover { - cursor:pointer; -} - -.argeo-suite-recentItems { - font: bold 14px sans-serif; - color: white; - background-color: #00294b; - padding: 8px 16px; -} - -.argeo-suite-titleContainer { - background-color: #00294b; - padding: 6px 8px 4px 8px; -} - -.argeo-suite-titleLabel { - font: bold 14px sans-serif; - color: white; - background-color: #00294b; -} - -.argeo-suite-subTitleLabel { - font: italic 14px sans-serif; - color: #777; - padding: 4px 8px; -} - -.argeo-suite-simpleLabel { - font: bold 14px sans-serif; - padding: 0px; -} - -.argeo-suite-simpleText { - font: 14px sans-serif; - padding: 0px; -} - -.argeo-suite-titleCell { - font: bold 14px sans-serif; - background-color: #ddd; -} - -.argeo-suite-inlineButton { - padding: 0px 4px; - font: 12px sans-serif; - border: 1px solid white; - color: white; - background-image: none; - background-color: #00294b; -} - -.argeo-suite-inlineButton:hover { - color: #00294b; - background-color: white; -} - -Composite.argeo-suite-mainTabBody { - background-color: #eee; - border: 1px solid #bbb; -} - -.argeo-suite-mainTab { - background-color: #eee; - border: 1px solid #888; -} - -ToolItem.argeo-suite-mainTab { - border: none; - background-color: #eee; -} - -ToolItem.argeo-suite-mainTab:hover { - background-color: #eee; -} - - -Button.argeo-suite-mainTab { - border: 1px solid #eee; - background-color: #eee; -} - -.argeo-suite-mainTab:hover { - background-color: #eee; -} - -Button.argeo-suite-mainTab:hover { - cursor: pointer; - background-color: #eee; -} - -.argeo-suite-mainTabSelected { - font: bold 14px sans-serif; - color: white; - /*background-color: #00294b;*/ - background-color: #5882b5; - border:1px solid #888; -} - -ToolItem.argeo-suite-mainTabSelected { - border: none; -} - -ToolItem.argeo-suite-mainTabSelected:hover { - background-color: #5882b5; -} - -Button.argeo-suite-mainTabSelected { - border: none; -} - -Sash { - border: 1px solid white; - background-image: none; - background-color: white; -} - -Sash:hover { - border: 1px solid #5882b5; - background-color: #5882b5; -} - -TreeItem{ - background-color:#fff; -} - -Tree-RowOverlay:selected { - color:#fff; - background-color:#5882b5; -} - -TableItem{ - background-color:#fff; -} - -Table-RowOverlay:selected { - color:#fff; - background-color:#5882b5; -} - -.argeo-suite-navigationBar{ - background-color:#ddd; -} - -.argeo-suite-navigationTitle{ - background-color:#ddd; - font:bold 14px sans-serif; -} - -.argeo-suite-navigationButton{ - color:#777; - background-color:#ddd; - font:bold 14px sans-serif; -} - -.argeo-suite-navigationButton:hover{ - cursor:pointer; - color:#ddd; - background-color:#777; -} diff --git a/core/org.argeo.suite.theme.default/swt/app.css b/core/org.argeo.suite.theme.default/swt/app.css deleted file mode 100644 index 4ac745d..0000000 --- a/core/org.argeo.suite.theme.default/swt/app.css +++ /dev/null @@ -1,129 +0,0 @@ -.argeo-suite-header { - color: white; - background-color: #00294b; -} - -.argeo-suite-headerTitle { - font: bold 14px sans-serif; - color: white; - background-color: #00294b; -} - -.argeo-suite-leadPane { - background-color: #eee; -} - -Label.argeo-suite-leadPane { - font: 11px sans-serif; - color: #888; - background-color: #eee; -} - -Button.argeo-suite-leadPane:hover { - cursor: pointer; -} - -.argeo-suite-recentItems { - font: bold 13px sans-serif; - color: white; - background-color: #00294b; - padding: 8px 16px; -} - -.argeo-suite-titleContainer { - background-color: #00294b; -} - -.argeo-suite-titleLabel { - font: bold 13px sans-serif; - margin: 6px 8px 4px 8px; - color: white; - background-color: #00294b; -} - -.argeo-suite-subTitleLabel { - font: italic 14px sans-serif; - color: #777; - margin: 4px 8px; -} - -.argeo-suite-formLine { - padding: 4px 8px 4px 16px; -} - -.argeo-suite-simpleLabel { - font: normal 11px sans-serif; - border: 8px solid #eee; -} - -.argeo-suite-simpleText { - -} - -.argeo-suite-simpleInput { - padding: 4px 8px 4px 8px; -} - -.argeo-suite-titleCell { - font: bold 11px sans-serif; - background-color: #ddd; -} - -.argeo-suite-inlineButton { - padding: 0px 4px; - font: 12px sans-serif; - border: 1px solid white; - color: white; - background-image: none; - background-color: #00294b; -} - -.argeo-suite-inlineButton:hover { - color: #00294b; - background-color: white; -} - -Composite.argeo-suite-mainTabBody { - background-color: #eee; - border: 1px solid #bbb; -} - -.argeo-suite-mainTab { - background-color: #eee; - border: 1px solid #bbb; -} - -ToolItem.argeo-suite-mainTab { - border: none; - background-color: #eee; -} - -Button.argeo-suite-mainTab { - border: none; - background-color: #eee; -} - -.argeo-suite-mainTab:hover { - background-color: #eee; -} - -Button.argeo-suite-mainTab:hover { - cursor: pointer; - background-color: #eee; -} - -.argeo-suite-mainTabSelected { - font: bold 14px sans-serif; - color: white; - /*background-color: #00294b;*/ - background-color: #5882b5; - border: 1px solid #00294b; -} - -ToolItem.argeo-suite-mainTabSelected { - border: none; -} - -Button.argeo-suite-mainTabSelected { - border: none; -} \ No newline at end of file diff --git a/core/org.argeo.suite.ui.rap/.gitignore b/core/org.argeo.suite.ui.rap/.gitignore deleted file mode 100644 index 09e3bc9..0000000 --- a/core/org.argeo.suite.ui.rap/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/bin/ -/target/ diff --git a/core/org.argeo.suite.ui.rap/.project b/core/org.argeo.suite.ui.rap/.project deleted file mode 100644 index eff6bb0..0000000 --- a/core/org.argeo.suite.ui.rap/.project +++ /dev/null @@ -1,27 +0,0 @@ - - - org.argeo.suite.ui.rap - - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - org.eclipse.pde.ds.core.builder - - - - - - org.eclipse.pde.PluginNature - - diff --git a/core/org.argeo.suite.ui.rap/META-INF/.gitignore b/core/org.argeo.suite.ui.rap/META-INF/.gitignore deleted file mode 100644 index 4854a41..0000000 --- a/core/org.argeo.suite.ui.rap/META-INF/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/MANIFEST.MF diff --git a/core/org.argeo.suite.ui.rap/OSGI-INF/cmsWebApp.xml b/core/org.argeo.suite.ui.rap/OSGI-INF/cmsWebApp.xml deleted file mode 100644 index 4dfdcff..0000000 --- a/core/org.argeo.suite.ui.rap/OSGI-INF/cmsWebApp.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/core/org.argeo.suite.ui.rap/bnd.bnd b/core/org.argeo.suite.ui.rap/bnd.bnd deleted file mode 100644 index 35b671b..0000000 --- a/core/org.argeo.suite.ui.rap/bnd.bnd +++ /dev/null @@ -1,6 +0,0 @@ -Service-Component: OSGI-INF/cmsWebApp.xml - -Import-Package:\ -org.argeo.cms.web,\ -org.eclipse.rap.rwt.application,\ -* diff --git a/core/org.argeo.suite.ui.rap/build.properties b/core/org.argeo.suite.ui.rap/build.properties deleted file mode 100644 index 6210e84..0000000 --- a/core/org.argeo.suite.ui.rap/build.properties +++ /dev/null @@ -1,5 +0,0 @@ -output.. = bin/ -bin.includes = META-INF/,\ - .,\ - OSGI-INF/ -source.. = src/ diff --git a/core/org.argeo.suite.ui.rap/pom.xml b/core/org.argeo.suite.ui.rap/pom.xml deleted file mode 100644 index c82e7ce..0000000 --- a/core/org.argeo.suite.ui.rap/pom.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - 4.0.0 - - org.argeo.suite - core - 2.3-SNAPSHOT - .. - - org.argeo.suite.ui.rap - Suite UI RAP - jar - - - org.argeo.suite - org.argeo.suite.ui - 2.3-SNAPSHOT - - - - - org.argeo.tp - argeo-tp-rap-e4 - ${version.argeo-tp} - pom - provided - - - diff --git a/core/org.argeo.suite.ui/.classpath b/core/org.argeo.suite.ui/.classpath deleted file mode 100644 index e801ebf..0000000 --- a/core/org.argeo.suite.ui/.classpath +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/core/org.argeo.suite.ui/.gitignore b/core/org.argeo.suite.ui/.gitignore deleted file mode 100644 index 09e3bc9..0000000 --- a/core/org.argeo.suite.ui/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/bin/ -/target/ diff --git a/core/org.argeo.suite.ui/.project b/core/org.argeo.suite.ui/.project deleted file mode 100644 index 7146bab..0000000 --- a/core/org.argeo.suite.ui/.project +++ /dev/null @@ -1,33 +0,0 @@ - - - org.argeo.suite.ui - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - org.eclipse.pde.ds.core.builder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - diff --git a/core/org.argeo.suite.ui/META-INF/.gitignore b/core/org.argeo.suite.ui/META-INF/.gitignore deleted file mode 100644 index 4854a41..0000000 --- a/core/org.argeo.suite.ui/META-INF/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/MANIFEST.MF diff --git a/core/org.argeo.suite.ui/OSGI-INF/adminLeadPane.xml b/core/org.argeo.suite.ui/OSGI-INF/adminLeadPane.xml deleted file mode 100644 index 0d060fb..0000000 --- a/core/org.argeo.suite.ui/OSGI-INF/adminLeadPane.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - argeo.suite.ui.termsLayer - - - diff --git a/core/org.argeo.suite.ui/OSGI-INF/cmsApp.xml b/core/org.argeo.suite.ui/OSGI-INF/cmsApp.xml deleted file mode 100644 index e42eeeb..0000000 --- a/core/org.argeo.suite.ui/OSGI-INF/cmsApp.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/core/org.argeo.suite.ui/OSGI-INF/dashboard.xml b/core/org.argeo.suite.ui/OSGI-INF/dashboard.xml deleted file mode 100644 index f678b5b..0000000 --- a/core/org.argeo.suite.ui/OSGI-INF/dashboard.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/core/org.argeo.suite.ui/OSGI-INF/dashboardLayer.xml b/core/org.argeo.suite.ui/OSGI-INF/dashboardLayer.xml deleted file mode 100644 index b60eafc..0000000 --- a/core/org.argeo.suite.ui/OSGI-INF/dashboardLayer.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/core/org.argeo.suite.ui/OSGI-INF/eventRecorder.xml b/core/org.argeo.suite.ui/OSGI-INF/eventRecorder.xml deleted file mode 100644 index 49badfd..0000000 --- a/core/org.argeo.suite.ui/OSGI-INF/eventRecorder.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/core/org.argeo.suite.ui/OSGI-INF/footer.xml b/core/org.argeo.suite.ui/OSGI-INF/footer.xml deleted file mode 100644 index 3499b4f..0000000 --- a/core/org.argeo.suite.ui/OSGI-INF/footer.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/core/org.argeo.suite.ui/OSGI-INF/header.xml b/core/org.argeo.suite.ui/OSGI-INF/header.xml deleted file mode 100644 index 526d9f9..0000000 --- a/core/org.argeo.suite.ui/OSGI-INF/header.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/core/org.argeo.suite.ui/OSGI-INF/l10n/bundle.properties b/core/org.argeo.suite.ui/OSGI-INF/l10n/bundle.properties deleted file mode 100644 index 5716780..0000000 --- a/core/org.argeo.suite.ui/OSGI-INF/l10n/bundle.properties +++ /dev/null @@ -1,98 +0,0 @@ -dashboard=dashboard -#people=contacts -documents=documents -locations=locations -recentItems=recent items - -appTitle=Argeo Suite - -# -# PEOPLE -# org.argeo.people.ui.PeopleMsg -# -person=Person -organisation=Organisation - -# NewPersonWizard -firstName=First Name -lastName=Last Name -salutation=Salutation -email=Email -personWizardWindowTitle=New person -personWizardPageTitle=Create a contact - -# NewOrgWizard -legalName=Legal name -legalForm=Legal form -vatId=VAT ID -orgWizardWindowTitle=New organisation -orgWizardPageTitle=Create an organisation - - -# ContextAddressComposite -chooseAnOrganisation=Choose an organisation -street=Street -streetComplement=Street complement -zipCode=Zip code -city=City -state=State -country=Country -geopoint=Geopoint - -# FilteredOrderableEntityTable -filterHelp=Type filter criterion separated by a space - -# BankAccountComposite -accountHolder=Account holder -bankName=Bank name -currency=Currency -accountNumber=Account number -bankNumber=Bank number -BIC=BIC -IBAN=IBAN - -# EditJobDialog -position=Role -chosenItem=Chose item -department=Department -isPrimary=Is primary -searchAndChooseEntity=Search and choose a corresponding entity - -# ContactListCTab (e4) -notes=Notes -addAContact=Add a contact -contactValue=Contact value -linkedCompany=Linked company - -# OrgAdminInfoCTab (e4) -paymentAccount=Payment account - -# OrgEditor (e4) -orgDetails=Details -orgActivityLog=Activity log -team=Team -orgAdmin=Admin. - -# PersonEditor (e4) -personDetails=Contact details -personActivityLog=Activity log -personOrgs=Organisations -personSecurity=Security - -# PersonSecurityCTab (e4) -resetPassword=Reset password - -# Generic -label=Label -aCustomLabel=A custom label -description=Description -value=Value -name=Name -primary=Primary -add=Add -save=Save -pickUp=Pick up - -# Tags -confirmNewTag=Tag #{0} is not yet registered. Are you sure you want to create it? -cannotCreateTag=Tag #{0} is not yet registered and you don't have enough rights to create it. diff --git a/core/org.argeo.suite.ui/OSGI-INF/l10n/bundle_de.properties b/core/org.argeo.suite.ui/OSGI-INF/l10n/bundle_de.properties deleted file mode 100644 index 0af19c2..0000000 --- a/core/org.argeo.suite.ui/OSGI-INF/l10n/bundle_de.properties +++ /dev/null @@ -1,98 +0,0 @@ -dashboard=dashboard -people=Kontakte -documents=Dokumente -locations=Orte -recentItems=neulich - -appTitle=Argeo Suite - -# -# PEOPLE -# org.argeo.people.ui.PeopleMsg -# -person=Person -organisation=Organisation - -# NewPersonWizard -firstName=Vorname -lastName=Nachname -salutation=Salutation -email=E-Mail -personWizardWindowTitle=Neue Person -personWizardPageTitle=Kontakt erstellen - -# NewOrgWizard -legalName=Name -legalForm=Geschäftsform -vatId=Ust ID -orgWizardWindowTitle=Neue Organisation -orgWizardPageTitle=Organisation erstellen - - -# ContextAddressComposite -chooseAnOrganisation=Organisation wählen -street=Strasse -streetComplement=Strasse Zusatz -zipCode=PLZ -city=Stadt -state=Bundesland -country=Land -geopoint=Geopoint - -# FilteredOrderableEntityTable -filterHelp=Type filter criterion separated by a space - -# BankAccountComposite -accountHolder=Kontoinhaber -bankName=Name der Bank -currency=Währung -accountNumber=Kontonummer -bankNumber=BLZ -BIC=BIC -IBAN=IBAN - -# EditJobDialog -position=Rolle -chosenItem=Auswahl -department=Abteilung -isPrimary=Ist Primär -searchAndChooseEntity=Suche und wähle ein zugehöriges Objekt - -# ContactListCTab (e4) -notes=Bemerkungen -addAContact=Kontakt hinzufügen -contactValue=Kontakt value -linkedCompany=zugehörige Firma - -# OrgAdminInfoCTab (e4) -paymentAccount=Geschäftskonto - -# OrgEditor (e4) -orgDetails=Details -orgActivityLog=Aktivitäten Log -team=Team -orgAdmin=Admin. - -# PersonEditor (e4) -personDetails=Kontakt Daten -personActivityLog=Aktivitäten Log -personOrgs=Organisationen -personSecurity=Sicherheit - -# PersonSecurityCTab (e4) -resetPassword=Passwort zurücksetzen - -# Generic -label=Beschriftung -aCustomLabel=Eine spezifische Beschriftung -description=Beschreibung -value=Wert -name=Name -primary=Haupt- -add=Hinzufügen -save=Speichern -pickUp=Aussuchen - -# Tags -confirmNewTag=Das Hashtag '{0}' existiert noch nicht. WollenSie es hinzufügen? -cannotCreateTag=Das Hashtag '{0}' existiert nicht uns Sie haben nicht die Rechte, um es hinzufügen. diff --git a/core/org.argeo.suite.ui/OSGI-INF/l10n/bundle_fr.properties b/core/org.argeo.suite.ui/OSGI-INF/l10n/bundle_fr.properties deleted file mode 100644 index 225e5fd..0000000 --- a/core/org.argeo.suite.ui/OSGI-INF/l10n/bundle_fr.properties +++ /dev/null @@ -1,102 +0,0 @@ -dashboard=dashboard -people=contacts -documents=documents -locations=lieux -recentItems=récent - -appTitle=Argeo Suite - -# -# GENERIC -# - -# -# PEOPLE -# org.argeo.people.ui.PeopleMsg -# -person=Personne -organisation=Organisation - -# NewPersonWizard -firstName=Prénom -lastName=Nom -salutation=Salutation -email=Email -personWizardWindowTitle=Nouvelle personne -personWizardPageTitle=Créer un contact - -# NewOrgWizard -legalName=Nom -legalForm=Forme légale -vatId=ID TVA -orgWizardWindowTitle=Nouvelle organisation -orgWizardPageTitle=Créer une organisation - - -# ContextAddressComposite -chooseAnOrganisation=Choisir une organisation -street=Rue -streetComplement=Complément rue -zipCode=Code postal -city=Ville -state=État -country=Pays -geopoint=Géocoordonnées - -# FilteredOrderableEntityTable -filterHelp=Sasir les critères de filtrage séparés par des espaces - -# BankAccountComposite -accountHolder=Propriétaire du compte -bankName=Nom de la banque -currency=Devise -accountNumber=Numéro de compte -bankNumber=Numéro de banque -BIC=BIC -IBAN=IBAN - -# EditJobDialog -position=Rôle -chosenItem=Choisir une élément -department=Service -isPrimary=Principal -searchAndChooseEntity=Cherhcer et choisir l'entitée correspondante - -# ContactListCTab (e4) -notes=Notes -addAContact=Ajouter un contact -contactValue=Valeur -linkedCompany=Entreprise liée - -# OrgAdminInfoCTab (e4) -paymentAccount=Compte de paiement - -# OrgEditor (e4) -orgDetails=Détails -orgActivityLog=Activités -team=Équipe -orgAdmin=Admin. - -# PersonEditor (e4) -personDetails=Détails du contact -personActivityLog=Activités -personOrgs=Organisations -personSecurity=Accès - -# PersonSecurityCTab (e4) -resetPassword=Force le mot de passe - -# Generic -label=Étiquette -aCustomLabel=Une étiquette spécifique -description=Description -value=Valeur -name=Nom -primary=Principal -add=Ajouter -save=Sauver -pickUp=Choisir - -# Tags -confirmNewTag=Le tag #{0} n'existe pas encore. Voulez-vous le créer? -cannotCreateTag=Le tag #{0} n'existe pas encore et vous n'avez pas les droits pour le créer. diff --git a/core/org.argeo.suite.ui/OSGI-INF/leadPane.xml b/core/org.argeo.suite.ui/OSGI-INF/leadPane.xml deleted file mode 100644 index c43d933..0000000 --- a/core/org.argeo.suite.ui/OSGI-INF/leadPane.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - argeo.suite.ui.dashboardLayer -argeo.library.ui.contentLayer -argeo.people.ui.peopleLayer -argeo.geo.ui.mapLayer - - - diff --git a/core/org.argeo.suite.ui/OSGI-INF/loginScreen.xml b/core/org.argeo.suite.ui/OSGI-INF/loginScreen.xml deleted file mode 100644 index 0c5377a..0000000 --- a/core/org.argeo.suite.ui/OSGI-INF/loginScreen.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/core/org.argeo.suite.ui/OSGI-INF/recentItems.xml b/core/org.argeo.suite.ui/OSGI-INF/recentItems.xml deleted file mode 100644 index 8aaee16..0000000 --- a/core/org.argeo.suite.ui/OSGI-INF/recentItems.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/core/org.argeo.suite.ui/OSGI-INF/termsEntryArea.xml b/core/org.argeo.suite.ui/OSGI-INF/termsEntryArea.xml deleted file mode 100644 index cfcae11..0000000 --- a/core/org.argeo.suite.ui/OSGI-INF/termsEntryArea.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/core/org.argeo.suite.ui/OSGI-INF/termsLayer.xml b/core/org.argeo.suite.ui/OSGI-INF/termsLayer.xml deleted file mode 100644 index f320dd9..0000000 --- a/core/org.argeo.suite.ui/OSGI-INF/termsLayer.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/core/org.argeo.suite.ui/bnd.bnd b/core/org.argeo.suite.ui/bnd.bnd deleted file mode 100644 index 7785626..0000000 --- a/core/org.argeo.suite.ui/bnd.bnd +++ /dev/null @@ -1,24 +0,0 @@ -Service-Component:\ -OSGI-INF/cmsApp.xml,\ -OSGI-INF/eventRecorder.xml,\ -OSGI-INF/header.xml,\ -OSGI-INF/footer.xml,\ -OSGI-INF/leadPane.xml,\ -OSGI-INF/loginScreen.xml,\ -OSGI-INF/recentItems.xml,\ -OSGI-INF/adminLeadPane.xml,\ -OSGI-INF/termsEntryArea.xml,\ -OSGI-INF/termsLayer.xml,\ -OSGI-INF/dashboard.xml,\ -OSGI-INF/dashboardLayer.xml - -Import-Package:\ -org.argeo.api,\ -org.argeo.cms.ui.widgets,\ -org.eclipse.swt,\ -org.osgi.framework,\ -org.argeo.entity,\ -org.eclipse.core.commands.common,\ -org.eclipse.jface.window,\ -org.eclipse.jface.dialogs,\ -* diff --git a/core/org.argeo.suite.ui/build.properties b/core/org.argeo.suite.ui/build.properties deleted file mode 100644 index d829967..0000000 --- a/core/org.argeo.suite.ui/build.properties +++ /dev/null @@ -1,10 +0,0 @@ -output.. = bin/ -bin.includes = META-INF/,\ - .,\ - OSGI-INF/,\ - config/,\ - OSGI-INF/loginScreen.xml,\ - OSGI-INF/dashboard.xml,\ - OSGI-INF/recentItems.xml,\ - OSGI-INF/dashboardLayer.xml -source.. = src/ diff --git a/core/org.argeo.suite.ui/config/adminLeadPane.properties b/core/org.argeo.suite.ui/config/adminLeadPane.properties deleted file mode 100644 index 90b9b04..0000000 --- a/core/org.argeo.suite.ui/config/adminLeadPane.properties +++ /dev/null @@ -1 +0,0 @@ -service.pid=argeo.suite.ui.adminLeadPane diff --git a/core/org.argeo.suite.ui/config/cmsApp.properties b/core/org.argeo.suite.ui/config/cmsApp.properties deleted file mode 100644 index 1dec00e..0000000 --- a/core/org.argeo.suite.ui/config/cmsApp.properties +++ /dev/null @@ -1,3 +0,0 @@ -service.pid=argeo.suite.ui.app - -event.topics=argeo/suite/* \ No newline at end of file diff --git a/core/org.argeo.suite.ui/config/dashboard.properties b/core/org.argeo.suite.ui/config/dashboard.properties deleted file mode 100644 index 1832543..0000000 --- a/core/org.argeo.suite.ui/config/dashboard.properties +++ /dev/null @@ -1 +0,0 @@ -service.pid=argeo.suite.ui.dashboard diff --git a/core/org.argeo.suite.ui/config/dashboardLayer.properties b/core/org.argeo.suite.ui/config/dashboardLayer.properties deleted file mode 100644 index 79abe4c..0000000 --- a/core/org.argeo.suite.ui/config/dashboardLayer.properties +++ /dev/null @@ -1,4 +0,0 @@ -service.pid=argeo.suite.ui.dashboardLayer - -title=Dashboard -icon=dashboard \ No newline at end of file diff --git a/core/org.argeo.suite.ui/config/eventRecorder.properties b/core/org.argeo.suite.ui/config/eventRecorder.properties deleted file mode 100644 index 6503863..0000000 --- a/core/org.argeo.suite.ui/config/eventRecorder.properties +++ /dev/null @@ -1,3 +0,0 @@ -service.pid=argeo.suite.ui.eventRecorder - -event.topics=argeo/suite/* \ No newline at end of file diff --git a/core/org.argeo.suite.ui/config/footer.properties b/core/org.argeo.suite.ui/config/footer.properties deleted file mode 100644 index 12aca56..0000000 --- a/core/org.argeo.suite.ui/config/footer.properties +++ /dev/null @@ -1 +0,0 @@ -service.pid=argeo.suite.ui.footer diff --git a/core/org.argeo.suite.ui/config/header.properties b/core/org.argeo.suite.ui/config/header.properties deleted file mode 100644 index 034d5f5..0000000 --- a/core/org.argeo.suite.ui/config/header.properties +++ /dev/null @@ -1,4 +0,0 @@ -service.pid=argeo.suite.ui.header -argeo.suite.ui=true - -argeo.suite.ui.header.title=%appTitle \ No newline at end of file diff --git a/core/org.argeo.suite.ui/config/leadPane.properties b/core/org.argeo.suite.ui/config/leadPane.properties deleted file mode 100644 index 0d7b193..0000000 --- a/core/org.argeo.suite.ui/config/leadPane.properties +++ /dev/null @@ -1 +0,0 @@ -service.pid=argeo.suite.ui.leadPane diff --git a/core/org.argeo.suite.ui/config/loginScreen.properties b/core/org.argeo.suite.ui/config/loginScreen.properties deleted file mode 100644 index 332614d..0000000 --- a/core/org.argeo.suite.ui/config/loginScreen.properties +++ /dev/null @@ -1 +0,0 @@ -service.pid=argeo.suite.ui.loginScreen diff --git a/core/org.argeo.suite.ui/config/recentItems.properties b/core/org.argeo.suite.ui/config/recentItems.properties deleted file mode 100644 index 7321c55..0000000 --- a/core/org.argeo.suite.ui/config/recentItems.properties +++ /dev/null @@ -1 +0,0 @@ -service.pid=argeo.suite.ui.recentItems diff --git a/core/org.argeo.suite.ui/config/termsEntryArea.properties b/core/org.argeo.suite.ui/config/termsEntryArea.properties deleted file mode 100644 index cd31517..0000000 --- a/core/org.argeo.suite.ui/config/termsEntryArea.properties +++ /dev/null @@ -1 +0,0 @@ -service.pid=argeo.suite.ui.termsEntryArea diff --git a/core/org.argeo.suite.ui/config/termsLayer.properties b/core/org.argeo.suite.ui/config/termsLayer.properties deleted file mode 100644 index 2c0532e..0000000 --- a/core/org.argeo.suite.ui/config/termsLayer.properties +++ /dev/null @@ -1,5 +0,0 @@ -service.pid=argeo.suite.ui.termsLayer -title=Terms -icon=dashboard - -entity.type=entity:terms,entity:term \ No newline at end of file diff --git a/core/org.argeo.suite.ui/pom.xml b/core/org.argeo.suite.ui/pom.xml deleted file mode 100644 index c0cc002..0000000 --- a/core/org.argeo.suite.ui/pom.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - 4.0.0 - - org.argeo.suite - core - 2.3-SNAPSHOT - .. - - org.argeo.suite.ui - Suite UI - jar - - - org.argeo.suite - org.argeo.suite.core - 2.3-SNAPSHOT - - - org.argeo.suite - org.argeo.entity.ui - 2.3-SNAPSHOT - - - - - org.argeo.commons - org.argeo.eclipse.ui - ${version.argeo-commons} - - - org.argeo.commons - org.argeo.eclipse.ui.rap - ${version.argeo-commons} - provided - - - - - org.argeo.tp - argeo-tp-rap-e4 - ${version.argeo-tp} - pom - provided - - - diff --git a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/DefaultDashboard.java b/core/org.argeo.suite.ui/src/org/argeo/suite/ui/DefaultDashboard.java deleted file mode 100644 index 9835b67..0000000 --- a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/DefaultDashboard.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.argeo.suite.ui; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; - -import org.argeo.cms.auth.CurrentUser; -import org.argeo.cms.ui.CmsUiProvider; -import org.argeo.cms.ui.CmsView; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; - -/** Provides a dashboard. */ -public class DefaultDashboard implements CmsUiProvider { - - @Override - public Control createUi(Composite parent, Node context) throws RepositoryException { - parent.setLayout(new GridLayout()); - CmsView cmsView = CmsView.getCmsView(parent); - if (cmsView.isAnonymous()) - throw new IllegalStateException("No user is not logged in"); - - Label lbl = new Label(parent, SWT.NONE); - lbl.setText("Welcome " + CurrentUser.getDisplayName() + "!"); - - return lbl; - } - -} diff --git a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/DefaultEditionLayer.java b/core/org.argeo.suite.ui/src/org/argeo/suite/ui/DefaultEditionLayer.java deleted file mode 100644 index 8945855..0000000 --- a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/DefaultEditionLayer.java +++ /dev/null @@ -1,286 +0,0 @@ -package org.argeo.suite.ui; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; - -import org.argeo.cms.Localized; -import org.argeo.cms.ui.CmsTheme; -import org.argeo.cms.ui.CmsUiProvider; -import org.argeo.cms.ui.util.CmsUiUtils; -import org.argeo.jcr.JcrException; -import org.argeo.suite.ui.widgets.TabbedArea; -import org.argeo.util.LangUtils; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.SashForm; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.osgi.framework.BundleContext; -import org.osgi.framework.wiring.BundleWiring; - -/** An app layer based on an entry area and an editor area. */ -public class DefaultEditionLayer implements SuiteLayer { - private CmsUiProvider entryArea; - private CmsUiProvider defaultView; - private CmsUiProvider workArea; - private List weights = new ArrayList<>(); - private boolean startMaximized = false; - private boolean fixedEntryArea = false; - private boolean singleTab = false; - private Localized title = null; - - @Override - public Control createUi(Composite parent, Node context) throws RepositoryException { - // TODO Factorize more, or split into more specialised classes? - if (entryArea != null) { - if (fixedEntryArea) { - FixedEditionArea editionArea = new FixedEditionArea(parent, parent.getStyle()); - Control entryAreaC = entryArea.createUi(editionArea.getEntryArea(), context); - CmsUiUtils.style(entryAreaC, SuiteStyle.entryArea); - if (this.defaultView != null) { - editionArea.getTabbedArea().view(defaultView, context); - } - return editionArea; - } else { - SashFormEditionArea editionArea = new SashFormEditionArea(parent, parent.getStyle()); - entryArea.createUi(editionArea.getEntryArea(), context); - if (this.defaultView != null) { - editionArea.getTabbedArea().view(defaultView, context); - } - return editionArea; - } - } else { - if (this.workArea != null) { - Composite area = new Composite(parent, SWT.NONE); - this.workArea.createUi(area, context); - return area; - } - CmsTheme theme = CmsTheme.getCmsTheme(parent); - TabbedArea tabbedArea = createTabbedArea(parent, theme); - return tabbedArea; - } - } - - @Override - public void view(CmsUiProvider uiProvider, Composite workAreaC, Node context) { - if (workArea != null) { - try { - CmsUiUtils.clear(workAreaC); - workArea.createUi(workAreaC, context); - workAreaC.layout(true, true); - return; - } catch (RepositoryException e) { - throw new JcrException("Cannot rebuild work area", e); - } - } - - // tabbed area - TabbedArea tabbedArea = findTabbedArea(workAreaC); - if (tabbedArea == null) - throw new IllegalArgumentException("Unsupported work area " + workAreaC.getClass().getName()); - if (uiProvider == null) { - // reset - tabbedArea.closeAllTabs(); - if (this.defaultView != null) { - tabbedArea.view(defaultView, context); - } - } else { - tabbedArea.view(uiProvider, context); - } - } - - @Override - public Node getCurrentContext(Composite workArea) { - TabbedArea tabbedArea = findTabbedArea(workArea); - if (tabbedArea == null) - return null; - return tabbedArea.getCurrentContext(); - } - - private TabbedArea findTabbedArea(Composite workArea) { - TabbedArea tabbedArea = null; - if (workArea instanceof SashFormEditionArea) { - tabbedArea = ((SashFormEditionArea) workArea).getTabbedArea(); - } else if (workArea instanceof FixedEditionArea) { - tabbedArea = ((FixedEditionArea) workArea).getTabbedArea(); - } else if (workArea instanceof TabbedArea) { - tabbedArea = (TabbedArea) workArea; - } - return tabbedArea; - } - - @Override - public void open(CmsUiProvider uiProvider, Composite workArea, Node context) { - TabbedArea tabbedArea = ((SashFormEditionArea) workArea).getTabbedArea(); - tabbedArea.open(uiProvider, context); - } - - @Override - public Localized getTitle() { - return title; - } - - public void init(BundleContext bundleContext, Map properties) { - weights = LangUtils.toStringList(properties.get(Property.weights.name())); - startMaximized = properties.containsKey(Property.startMaximized.name()) - && "true".equals(properties.get(Property.startMaximized.name())); - fixedEntryArea = properties.containsKey(Property.fixedEntryArea.name()) - && "true".equals(properties.get(Property.fixedEntryArea.name())); - if (fixedEntryArea && weights.size() != 0) { - throw new IllegalArgumentException("Property " + Property.weights.name() + " should not be set if property " - + Property.fixedEntryArea.name() + " is set."); - } - singleTab = properties.containsKey(Property.singleTab.name()) - && "true".equals(properties.get(Property.singleTab.name())); - - String titleStr = (String) properties.get(SuiteLayer.Property.title.name()); - if (titleStr != null) { - if (titleStr.startsWith("%")) { - title = new Localized() { - - @Override - public String name() { - return titleStr; - } - - @Override - public ClassLoader getL10nClassLoader() { - return bundleContext != null - ? bundleContext.getBundle().adapt(BundleWiring.class).getClassLoader() - : getClass().getClassLoader(); - } - }; - } else { - title = new Localized.Untranslated(titleStr); - } - } - } - - public void destroy(BundleContext bundleContext, Map properties) { - - } - - public void setEntryArea(CmsUiProvider entryArea) { - this.entryArea = entryArea; - } - - public void setWorkArea(CmsUiProvider workArea) { - this.workArea = workArea; - } - - public void setDefaultView(CmsUiProvider defaultView) { - this.defaultView = defaultView; - } - - TabbedArea createTabbedArea(Composite parent, CmsTheme theme) { - TabbedArea tabbedArea = new TabbedArea(parent, SWT.NONE); - tabbedArea.setSingleTab(singleTab); - tabbedArea.setBodyStyle(SuiteStyle.mainTabBody.style()); - tabbedArea.setTabStyle(SuiteStyle.mainTab.style()); - tabbedArea.setTabSelectedStyle(SuiteStyle.mainTabSelected.style()); - tabbedArea.setCloseIcon(SuiteIcon.close.getSmallIcon(theme)); - tabbedArea.setLayoutData(CmsUiUtils.fillAll()); - return tabbedArea; - } - -// /** A work area based on an entry area and and a tabbed area. */ - class SashFormEditionArea extends SashForm { - private static final long serialVersionUID = 2219125778722702618L; - private TabbedArea tabbedArea; - private Composite entryC; - - SashFormEditionArea(Composite parent, int style) { - super(parent, SWT.HORIZONTAL); - CmsTheme theme = CmsTheme.getCmsTheme(parent); - - Composite editorC; - if (SWT.RIGHT_TO_LEFT == (style & SWT.RIGHT_TO_LEFT)) {// arabic, hebrew, etc. - editorC = new Composite(this, SWT.BORDER); - entryC = new Composite(this, SWT.BORDER); - } else { - entryC = new Composite(this, SWT.NONE); - editorC = new Composite(this, SWT.NONE); - } - - // sash form specific - if (weights.size() != 0) { - int[] actualWeight = new int[weights.size()]; - for (int i = 0; i < weights.size(); i++) { - actualWeight[i] = Integer.parseInt(weights.get(i)); - } - setWeights(actualWeight); - } else { - int[] actualWeights = new int[] { 3000, 7000 }; - setWeights(actualWeights); - } - if (startMaximized) - setMaximizedControl(editorC); - - GridLayout editorAreaLayout = CmsUiUtils.noSpaceGridLayout(); -// editorAreaLayout.verticalSpacing = 0; -// editorAreaLayout.marginBottom = 0; -// editorAreaLayout.marginHeight = 0; -// editorAreaLayout.marginLeft = 0; -// editorAreaLayout.marginRight = 0; - editorC.setLayout(editorAreaLayout); - - tabbedArea = createTabbedArea(editorC, theme); - } - - TabbedArea getTabbedArea() { - return tabbedArea; - } - - Composite getEntryArea() { - return entryC; - } - - } - - class FixedEditionArea extends Composite { - private static final long serialVersionUID = -5525672639277322465L; - private TabbedArea tabbedArea; - private Composite entryC; - - public FixedEditionArea(Composite parent, int style) { - super(parent, style); - CmsTheme theme = CmsTheme.getCmsTheme(parent); - - setLayout(CmsUiUtils.noSpaceGridLayout(2)); - - Composite editorC; - if (SWT.RIGHT_TO_LEFT == (style & SWT.RIGHT_TO_LEFT)) {// arabic, hebrew, etc. - editorC = new Composite(this, SWT.NONE); - entryC = new Composite(this, SWT.NONE); - } else { - entryC = new Composite(this, SWT.NONE); - editorC = new Composite(this, SWT.NONE); - } - entryC.setLayoutData(CmsUiUtils.fillHeight()); - - GridLayout editorAreaLayout = CmsUiUtils.noSpaceGridLayout(); -// editorAreaLayout.verticalSpacing = 0; -// editorAreaLayout.marginBottom = 0; -// editorAreaLayout.marginHeight = 0; -// editorAreaLayout.marginLeft = 0; -// editorAreaLayout.marginRight = 0; - editorC.setLayout(editorAreaLayout); - editorC.setLayoutData(CmsUiUtils.fillAll()); - - tabbedArea = createTabbedArea(editorC, theme); - } - - TabbedArea getTabbedArea() { - return tabbedArea; - } - - Composite getEntryArea() { - return entryC; - } - } - -} \ No newline at end of file diff --git a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/DefaultFooter.java b/core/org.argeo.suite.ui/src/org/argeo/suite/ui/DefaultFooter.java deleted file mode 100644 index 4ab5474..0000000 --- a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/DefaultFooter.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.argeo.suite.ui; - -import java.util.Map; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; - -import org.argeo.cms.ui.CmsUiProvider; -import org.argeo.cms.ui.util.CmsUiUtils; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.osgi.framework.BundleContext; - -/** Footer of a standard Argeo Suite application. */ -public class DefaultFooter implements CmsUiProvider { - @Override - public Control createUi(Composite parent, Node context) throws RepositoryException { - parent.setLayout(CmsUiUtils.noSpaceGridLayout()); - Composite content = new Composite(parent, SWT.NONE); - content.setLayoutData(new GridData(0, 0)); - Control contentControl = createContent(content, context); - - // TODO support and guarantee - - return contentControl; - } - - protected Control createContent(Composite parent, Node context) throws RepositoryException { - return parent; - } - - public void init(BundleContext bundleContext, Map properties) { - } - - public void destroy(BundleContext bundleContext, Map properties) { - - } -} diff --git a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/DefaultHeader.java b/core/org.argeo.suite.ui/src/org/argeo/suite/ui/DefaultHeader.java deleted file mode 100644 index 91154c3..0000000 --- a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/DefaultHeader.java +++ /dev/null @@ -1,119 +0,0 @@ -package org.argeo.suite.ui; - -import java.util.Map; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; - -import org.argeo.cms.Localized; -import org.argeo.cms.auth.CurrentUser; -import org.argeo.cms.ui.CmsTheme; -import org.argeo.cms.ui.CmsUiProvider; -import org.argeo.cms.ui.CmsView; -import org.argeo.cms.ui.util.CmsUiUtils; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.osgi.framework.BundleContext; -import org.osgi.framework.wiring.BundleWiring; - -/** Header of a standard Argeo Suite application. */ -public class DefaultHeader implements CmsUiProvider { - public final static String TITLE_PROPERTY = "argeo.suite.ui.header.title"; - private Localized title = null; - - @Override - public Control createUi(Composite parent, Node context) throws RepositoryException { - CmsView cmsView = CmsView.getCmsView(parent); - CmsTheme theme = CmsTheme.getCmsTheme(parent); - - parent.setLayout(CmsUiUtils.noSpaceGridLayout(new GridLayout(3, true))); - - // TODO right to left - Composite lead = new Composite(parent, SWT.NONE); - CmsUiUtils.style(lead, SuiteStyle.header); - lead.setLayoutData(new GridData(SWT.LEAD, SWT.CENTER, true, false)); - lead.setLayout(new GridLayout()); - Label lbl = new Label(lead, SWT.NONE); -// String title = properties.get(TITLE_PROPERTY); -// // TODO expose the localized -// lbl.setText(LocaleUtils.isLocaleKey(title) ? LocaleUtils.local(title, getClass().getClassLoader()).toString() -// : title); - lbl.setText(title.lead()); - CmsUiUtils.style(lbl, SuiteStyle.headerTitle); - lbl.setLayoutData(CmsUiUtils.fillWidth()); - - Composite middle = new Composite(parent, SWT.NONE); - CmsUiUtils.style(middle, SuiteStyle.header); - middle.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false)); - middle.setLayout(new GridLayout()); - - Composite end = new Composite(parent, SWT.NONE); - CmsUiUtils.style(end, SuiteStyle.header); - end.setLayoutData(new GridData(SWT.END, SWT.CENTER, true, false)); - - if (!cmsView.isAnonymous()) { - end.setLayout(new GridLayout(2, false)); - Label userL = new Label(end, SWT.NONE); - CmsUiUtils.style(userL, SuiteStyle.header); - userL.setText(CurrentUser.getDisplayName()); - Button logoutB = new Button(end, SWT.FLAT); -// CmsUiUtils.style(logoutB, SuiteStyle.header); - logoutB.setImage(SuiteIcon.logout.getSmallIcon(theme)); - logoutB.addSelectionListener(new SelectionAdapter() { - private static final long serialVersionUID = 7116760083964201233L; - - @Override - public void widgetSelected(SelectionEvent e) { - cmsView.logout(); - } - - }); - } else { - end.setLayout(new GridLayout(1, false)); - // required in order to avoid wrong height after logout - new Label(end, SWT.NONE).setText(""); - - } - return lbl; - } - - public void init(BundleContext bundleContext, Map properties) { - String titleStr = (String) properties.get(TITLE_PROPERTY); - if (titleStr != null) { - if (titleStr.startsWith("%")) { - title = new Localized() { - - @Override - public String name() { - return titleStr; - } - - @Override - public ClassLoader getL10nClassLoader() { - return bundleContext != null - ? bundleContext.getBundle().adapt(BundleWiring.class).getClassLoader() - : getClass().getClassLoader(); - } - }; - } else { - title = new Localized.Untranslated(titleStr); - } - } - } - - public void destroy(BundleContext bundleContext, Map properties) { - - } - - public Localized getTitle() { - return title; - } - -} diff --git a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/DefaultLeadPane.java b/core/org.argeo.suite.ui/src/org/argeo/suite/ui/DefaultLeadPane.java deleted file mode 100644 index 46de177..0000000 --- a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/DefaultLeadPane.java +++ /dev/null @@ -1,188 +0,0 @@ -package org.argeo.suite.ui; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.cms.Localized; -import org.argeo.cms.auth.CurrentUser; -import org.argeo.cms.ui.CmsUiProvider; -import org.argeo.cms.ui.CmsView; -import org.argeo.cms.ui.util.CmsUiUtils; -import org.argeo.suite.RankedObject; -import org.argeo.suite.SuiteUtils; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.osgi.framework.BundleContext; -import org.osgi.framework.Constants; -import org.osgi.framework.wiring.BundleWiring; - -/** Side pane listing various perspectives. */ -public class DefaultLeadPane implements CmsUiProvider { - private final static Log log = LogFactory.getLog(DefaultLeadPane.class); - - public static enum Property { - defaultLayers, adminLayers; - } - - private Map> layers = Collections.synchronizedSortedMap(new TreeMap<>()); - private List defaultLayers; - private List adminLayers = new ArrayList<>(); - - private ClassLoader l10nClassLoader; - - @Override - public Control createUi(Composite parent, Node node) throws RepositoryException { - CmsView cmsView = CmsView.getCmsView(parent); - parent.setLayout(CmsUiUtils.noSpaceGridLayout()); - Composite appLayersC = new Composite(parent, SWT.NONE); - CmsUiUtils.style(appLayersC, SuiteStyle.leadPane); - GridLayout layout = new GridLayout(); - layout.verticalSpacing = 10; - layout.marginTop = 10; - layout.marginLeft = 10; - layout.marginRight = 10; - appLayersC.setLayout(layout); - appLayersC.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false)); - - Composite adminLayersC; - if (!adminLayers.isEmpty()) { - adminLayersC = new Composite(parent, SWT.NONE); - CmsUiUtils.style(adminLayersC, SuiteStyle.leadPane); - GridLayout adminLayout = new GridLayout(); - adminLayout.verticalSpacing = 10; - adminLayout.marginBottom = 10; - adminLayout.marginLeft = 10; - adminLayout.marginRight = 10; - adminLayersC.setLayout(adminLayout); - adminLayersC.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, false, true)); - } else { - adminLayersC = null; - } - -// boolean isAdmin = cmsView.doAs(() -> CurrentUser.isInRole(NodeConstants.ROLE_USER_ADMIN)); - Set userRoles = cmsView.doAs(() -> CurrentUser.roles()); - Button first = null; - layers: for (String layerDef : defaultLayers) { - layerDef = layerDef.trim(); - if ("".equals(layerDef)) - continue layers;// skip empty lines - String[] semiColArr = layerDef.split(";"); - String layerId = semiColArr[0]; - Set layerRoles = SuiteUtils.extractRoles(semiColArr); - if (layers.containsKey(layerId)) { - if (!layerRoles.isEmpty()) { - Set intersection = new HashSet(layerRoles); - intersection.retainAll(userRoles); - if (intersection.isEmpty()) - continue layers;// skip unauthorized layer - } - RankedObject layerObj = layers.get(layerId); - - Localized title = null; - if (!adminLayers.contains(layerId)) { - String titleStr = (String) layerObj.getProperties().get(SuiteLayer.Property.title.name()); - if (titleStr != null) { - if (titleStr.startsWith("%")) { - // LocaleUtils.local(titleStr, getClass().getClassLoader()); - title = () -> titleStr; - } else { - title = new Localized.Untranslated(titleStr); - } - } - } - - String iconName = (String) layerObj.getProperties().get(SuiteLayer.Property.icon.name()); - SuiteIcon icon = null; - if (iconName != null) - icon = SuiteIcon.valueOf(iconName); - - Composite buttonParent; - if (adminLayers.contains(layerId)) - buttonParent = adminLayersC; - else - buttonParent = appLayersC; - Button b = SuiteUiUtils.createLayerButton(buttonParent, layerId, title, icon, l10nClassLoader); - if (first == null) - first = b; - } - } - return first; - } - - public void init(BundleContext bundleContext, Map properties) { - l10nClassLoader = bundleContext != null ? bundleContext.getBundle().adapt(BundleWiring.class).getClassLoader() - : getClass().getClassLoader(); - - String[] defaultLayers = (String[]) properties.get(Property.defaultLayers.toString()); - if (defaultLayers == null) - throw new IllegalArgumentException("Default layers must be set."); - this.defaultLayers = Arrays.asList(defaultLayers); - if (log.isDebugEnabled()) - log.debug("Default layers: " + Arrays.asList(defaultLayers)); - String[] adminLayers = (String[]) properties.get(Property.adminLayers.toString()); - if (adminLayers != null) { - this.adminLayers = Arrays.asList(adminLayers); - if (log.isDebugEnabled()) - log.debug("Admin layers: " + Arrays.asList(adminLayers)); - } - } - - public void destroy(BundleContext bundleContext, Map properties) { - - } - - public void addLayer(SuiteLayer layer, Map properties) { - if (properties.containsKey(Constants.SERVICE_PID)) { - String pid = (String) properties.get(Constants.SERVICE_PID); - RankedObject.putIfHigherRank(layers, pid, layer, properties); - } - } - - public void removeLayer(SuiteLayer layer, Map properties) { - if (properties.containsKey(Constants.SERVICE_PID)) { - String pid = (String) properties.get(Constants.SERVICE_PID); - if (layers.containsKey(pid)) { - if (layers.get(pid).equals(new RankedObject(layer, properties))) { - layers.remove(pid); - } - } - } - } - -// protected Button createLayerButton(Composite parent, String layer, Localized msg, CmsIcon icon) { -// CmsTheme theme = CmsTheme.getCmsTheme(parent); -// Button button = new Button(parent, SWT.PUSH); -// CmsUiUtils.style(button, SuiteStyle.leadPane); -// if (icon != null) -// button.setImage(icon.getBigIcon(theme)); -// button.setLayoutData(new GridData(SWT.CENTER, SWT.BOTTOM, true, false)); -// // button.setToolTipText(msg.lead()); -// if (msg != null) { -// Label lbl = new Label(parent, SWT.CENTER); -// CmsUiUtils.style(lbl, SuiteStyle.leadPane); -// // CmsUiUtils.markup(lbl); -// ClassLoader l10nClassLoader = getClass().getClassLoader(); -// String txt = LocaleUtils.lead(msg, l10nClassLoader); -//// String txt = msg.lead(); -// lbl.setText(txt); -// lbl.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, true, false)); -// } -// CmsUiUtils.sendEventOnSelect(button, SuiteEvent.switchLayer.topic(), SuiteEvent.LAYER, layer); -// return button; -// } -} diff --git a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/DefaultLoginScreen.java b/core/org.argeo.suite.ui/src/org/argeo/suite/ui/DefaultLoginScreen.java deleted file mode 100644 index 3757a19..0000000 --- a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/DefaultLoginScreen.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.argeo.suite.ui; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; - -import org.argeo.cms.auth.CurrentUser; -import org.argeo.cms.ui.CmsUiProvider; -import org.argeo.cms.ui.CmsView; -import org.argeo.cms.ui.widgets.auth.CmsLogin; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; - -/** Provides a login screen. */ -public class DefaultLoginScreen implements CmsUiProvider { - - @Override - public Control createUi(Composite parent, Node context) throws RepositoryException { - CmsView cmsView = CmsView.getCmsView(parent); - if (!cmsView.isAnonymous()) - throw new IllegalStateException(CurrentUser.getUsername() + " is already logged in"); - - parent.setLayout(new GridLayout()); - Composite loginArea = new Composite(parent, SWT.NONE); - loginArea.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true)); - - CmsLogin cmsLogin = new CmsLogin(cmsView); - cmsLogin.createUi(loginArea); - return cmsLogin.getCredentialsBlock(); - } - -} diff --git a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/EventRecorder.java b/core/org.argeo.suite.ui/src/org/argeo/suite/ui/EventRecorder.java deleted file mode 100644 index 4c928a9..0000000 --- a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/EventRecorder.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.argeo.suite.ui; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.osgi.service.event.Event; -import org.osgi.service.event.EventHandler; - -/** Record UI events. */ -public class EventRecorder implements EventHandler { - private final static Log log = LogFactory.getLog(EventRecorder.class); - - public void init() { - - } - - public void destroy() { - - } - - @Override - public void handleEvent(Event event) { - if (log.isTraceEnabled()) - log.trace(event); - - } - -} diff --git a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/RecentItems.java b/core/org.argeo.suite.ui/src/org/argeo/suite/ui/RecentItems.java deleted file mode 100644 index b9aa5b7..0000000 --- a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/RecentItems.java +++ /dev/null @@ -1,366 +0,0 @@ -package org.argeo.suite.ui; - -import static org.argeo.eclipse.ui.EclipseUiUtils.notEmpty; - -import java.util.List; -import java.util.Map; - -import javax.jcr.Node; -import javax.jcr.NodeIterator; -import javax.jcr.RepositoryException; -import javax.jcr.Session; -import javax.jcr.observation.Event; -import javax.jcr.observation.EventIterator; -import javax.jcr.observation.EventListener; -import javax.jcr.query.Query; -import javax.jcr.query.QueryResult; - -import org.argeo.cms.ui.CmsTheme; -import org.argeo.cms.ui.CmsUiProvider; -import org.argeo.cms.ui.CmsView; -import org.argeo.cms.ui.util.CmsUiUtils; -import org.argeo.eclipse.ui.EclipseUiUtils; -import org.argeo.entity.EntityType; -import org.argeo.jcr.Jcr; -import org.argeo.jcr.JcrUtils; -import org.argeo.suite.ui.widgets.DelayedText; -import org.argeo.suite.util.XPathUtils; -import org.eclipse.jface.layout.TableColumnLayout; -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.jface.viewers.ColumnWeightData; -import org.eclipse.jface.viewers.DoubleClickEvent; -import org.eclipse.jface.viewers.IDoubleClickListener; -import org.eclipse.jface.viewers.ILabelProvider; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.KeyListener; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.TableColumn; -import org.eclipse.swt.widgets.Text; -import org.eclipse.swt.widgets.ToolBar; -import org.eclipse.swt.widgets.ToolItem; - -/** List recent items. */ -public class RecentItems implements CmsUiProvider { - private final static int SEARCH_TEXT_DELAY = 800; - private final static int SEARCH_DEFAULT_LIMIT = 100; - - private CmsTheme theme; - - private String entityType; - - static enum Property { - entityTypes; - } - - @Override - public Control createUi(Composite parent, Node context) throws RepositoryException { - theme = CmsTheme.getCmsTheme(parent); - parent.setLayout(new GridLayout()); -// parent.setLayout(CmsUiUtils.noSpaceGridLayout()); - parent.setLayout(new GridLayout()); - -// Composite top = new Composite(parent, SWT.BORDER); -// CmsUiUtils.style(top, SuiteStyle.recentItems); -// top.setLayoutData(CmsUiUtils.fillWidth()); -// top.setLayout(CmsUiUtils.noSpaceGridLayout(2)); -// Label lbl = new Label(top, SWT.FLAT); -// lbl.setLayoutData(CmsUiUtils.fillWidth()); -// lbl.setText(SuiteMsg.recentItems.lead()); -// CmsUiUtils.style(lbl, SuiteStyle.recentItems); -// -// ToolBar topToolBar = new ToolBar(top, SWT.NONE); -// ToolItem addItem = new ToolItem(topToolBar, SWT.FLAT); -//// CmsUiUtils.style(addItem, SuiteStyle.recentItems); -// addItem.setImage(SuiteIcon.add.getSmallIcon(theme)); - - if (context == null) - return null; - SingleEntityViewer entityViewer = new SingleEntityViewer(parent, SWT.NONE, context.getSession()); - entityViewer.createUi(); - entityViewer.getViewer().getTable().setLayoutData(CmsUiUtils.fillAll()); - - Composite bottom = new Composite(parent, SWT.NONE); - bottom.setLayoutData(CmsUiUtils.fillWidth()); - bottom.setLayout(CmsUiUtils.noSpaceGridLayout()); - ToolBar bottomToolBar = new ToolBar(bottom, SWT.NONE); - bottomToolBar.setLayoutData(new GridData(SWT.END, SWT.FILL, true, false)); - ToolItem deleteItem = new ToolItem(bottomToolBar, SWT.FLAT); - deleteItem.setEnabled(false); -// CmsUiUtils.style(deleteItem, SuiteStyle.recentItems); - deleteItem.setImage(SuiteIcon.delete.getSmallIcon(theme)); - ToolItem addItem = new ToolItem(bottomToolBar, SWT.FLAT); - addItem.setImage(SuiteIcon.add.getSmallIcon(theme)); - entityViewer.getViewer().addDoubleClickListener(new IDoubleClickListener() { - - @Override - public void doubleClick(DoubleClickEvent event) { - Node node = (Node) entityViewer.getViewer().getStructuredSelection().getFirstElement(); - if (node != null) - CmsView.getCmsView(parent).sendEvent(SuiteEvent.openNewPart.topic(), - SuiteEvent.eventProperties(node)); - - } - }); - entityViewer.getViewer().addSelectionChangedListener(new ISelectionChangedListener() { - public void selectionChanged(SelectionChangedEvent event) { - Node node = (Node) entityViewer.getViewer().getStructuredSelection().getFirstElement(); - if (node != null) { - CmsView.getCmsView(parent).sendEvent(SuiteEvent.refreshPart.topic(), - SuiteEvent.eventProperties(node)); - deleteItem.setEnabled(true); - } else { - deleteItem.setEnabled(false); - } - } - }); - - return entityViewer.filterTxt; - - } - - public void init(Map properties) { - // TODO manage multiple entities - entityType = properties.get(Property.entityTypes.name()); - } - - class SingleEntityViewer { - Composite parent; - Text filterTxt; - TableViewer viewer; - Session session; - - public SingleEntityViewer(Composite parent, int style, Session session) { - this.parent = parent; - this.session = session; - } - - public void createUi() { - // MainLayout - addFilterPanel(parent); - viewer = createListPart(parent, new SingleEntityLabelProvider()); - refreshFilteredList(); - - try { - String[] nodeTypes = entityType != null && entityType.contains(":") ? new String[] { entityType } - : null; - session.getWorkspace().getObservationManager().addEventListener(new EventListener() { - - @Override - public void onEvent(EventIterator events) { - parent.getDisplay().asyncExec(() -> refreshFilteredList()); - } - }, Event.PROPERTY_CHANGED | Event.NODE_ADDED | Event.NODE_REMOVED | Event.PROPERTY_ADDED, "/", true, - null, nodeTypes, false); - } catch (RepositoryException e) { - throw new IllegalStateException("Cannot add JCR observer", e); - } - - } - - private void addFilterPanel(Composite parent) { - // Use a delayed text: the query won't be done until the user stop - // typing for 800ms - int style = SWT.BORDER | SWT.SEARCH | SWT.ICON_CANCEL; - DelayedText delayedText = new DelayedText(parent, style, SEARCH_TEXT_DELAY); - filterTxt = delayedText.getText(); - filterTxt.setLayoutData(EclipseUiUtils.fillWidth()); - - // final ServerPushSession pushSession = new ServerPushSession(); - delayedText.addDelayedModifyListener(null, new ModifyListener() { - private static final long serialVersionUID = 5003010530960334977L; - - public void modifyText(ModifyEvent event) { - delayedText.getText().getDisplay().asyncExec(new Runnable() { - @Override - public void run() { - refreshFilteredList(); - } - }); - // pushSession.stop(); - } - }); - - // Jump to the first item of the list using the down arrow - filterTxt.addKeyListener(new KeyListener() { - private static final long serialVersionUID = -4523394262771183968L; - - @Override - public void keyReleased(KeyEvent e) { - } - - @Override - public void keyPressed(KeyEvent e) { - // boolean shiftPressed = (e.stateMask & SWT.SHIFT) != 0; - // boolean altPressed = (e.stateMask & SWT.ALT) != 0; - if (e.keyCode == SWT.ARROW_DOWN || e.keyCode == SWT.TAB) { -// Object first = entityViewer.getElementAt(0); -// if (first != null) { -// entityViewer.getTable().setFocus(); -// entityViewer.setSelection(new StructuredSelection(first), true); -// } - e.doit = false; - } - } - }); - - parent.addDisposeListener((e) -> { - delayedText.close(); - }); - } - - protected TableViewer createListPart(Composite parent, ILabelProvider labelProvider) { -// parent.setLayout(new GridLayout()); -// parent.setLayout(CmsUiUtils.noSpaceGridLayout()); - - Composite tableComposite = new Composite(parent, SWT.NONE); - GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_VERTICAL - | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL); - tableComposite.setLayoutData(gd); - - TableViewer viewer = new TableViewer(tableComposite, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER); - viewer.setLabelProvider(labelProvider); - - TableColumn singleColumn = new TableColumn(viewer.getTable(), SWT.V_SCROLL); - TableColumnLayout tableColumnLayout = new TableColumnLayout(); - tableColumnLayout.setColumnData(singleColumn, new ColumnWeightData(85)); - tableComposite.setLayout(tableColumnLayout); - - // Corresponding table & style - Table table = viewer.getTable(); -// Listener[] mouseDownListeners = table.getListeners(SWT.MouseDown); -// for (Listener listener : table.getListeners(SWT.MouseDown)) -// table.removeListener(SWT.MouseDown, listener); -// for (Listener listener : table.getListeners(SWT.MouseUp)) -// table.removeListener(SWT.MouseUp, listener); -// for (Listener listener : table.getListeners(SWT.MouseDoubleClick)) -// table.removeListener(SWT.MouseDoubleClick, listener); -// -// table.addMouseListener(new MouseListener() { -// -// @Override -// public void mouseUp(MouseEvent e) { -// System.out.println("Mouse up: "+e); -// } -// -// @Override -// public void mouseDown(MouseEvent e) { -// System.out.println("Mouse down: "+e); -// } -// -// @Override -// public void mouseDoubleClick(MouseEvent e) { -// System.out.println("Mouse double: "+e); -// -// } -// }); - table.setLinesVisible(true); - table.setHeaderVisible(false); - // CmsUiUtils.markup(table); - // CmsUiUtils.setItemHeight(table, 26); - - viewer.setContentProvider(new BasicNodeListContentProvider()); - return viewer; - } - -// public boolean setFocus() { -// refreshFilteredList(); -// return parent.setFocus(); -// } - - public void forceRefresh(Object object) { - refreshFilteredList(); - } - - protected void refreshFilteredList() { - try { - String filter = filterTxt.getText(); - // Prevents the query on the full repository - // if (isEmpty(filter)) { - // entityViewer.setInput(null); - // return; - // } - - // XPATH Query - String xpathQueryStr; - if (entityType != null) { - int indexColumn = entityType.indexOf(':'); - if (indexColumn > 0) {// JCR node type - xpathQueryStr = "//element(*, " + entityType + ") order by @jcr:created descending"; - } else { - xpathQueryStr = entityType.contains(":") ? "//element(*, " + entityType + ")" - : "//element(*, " + EntityType.entity.get() + ")[@entity:type='" + entityType + "']"; - } - } else { - xpathQueryStr = "//element(*, " + EntityType.entity.get() + ")"; - } -// String xpathQueryStr = "//element(*, " + ConnectTypes.CONNECT_ENTITY + ")"; - String xpathFilter = XPathUtils.getFreeTextConstraint(filter); - if (notEmpty(xpathFilter)) - xpathQueryStr += "[" + xpathFilter + "]"; - -// long begin = System.currentTimeMillis(); - // session.refresh(false); - Query xpathQuery = XPathUtils.createQuery(session, xpathQueryStr); - - xpathQuery.setLimit(SEARCH_DEFAULT_LIMIT); - QueryResult result = xpathQuery.execute(); - - NodeIterator nit = result.getNodes(); - viewer.setInput(JcrUtils.nodeIteratorToList(nit)); -// if (log.isTraceEnabled()) { -// long end = System.currentTimeMillis(); -// log.trace("Quick Search - Found: " + nit.getSize() + " in " + (end - begin) -// + " ms by executing XPath query (" + xpathQueryStr + ")."); -// } - } catch (RepositoryException e) { - throw new IllegalStateException("Unable to list entities", e); - } - } - - public TableViewer getViewer() { - return viewer; - } - - class SingleEntityLabelProvider extends ColumnLabelProvider { - private static final long serialVersionUID = -2209337675781795677L; - - @Override - public String getText(Object element) { - return Jcr.getTitle((Node) element); - } - - } - - class BasicNodeListContentProvider implements IStructuredContentProvider { - private static final long serialVersionUID = 1L; - // keep a cache of the Nodes in the content provider to be able to - // manage long request - private List nodes; - - public void dispose() { - } - - /** Expects a list of nodes as a new input */ - @SuppressWarnings("unchecked") - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - nodes = (List) newInput; - } - - public Object[] getElements(Object arg0) { - return nodes.toArray(); - } - } - } -} diff --git a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteApp.java b/core/org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteApp.java deleted file mode 100644 index e499463..0000000 --- a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteApp.java +++ /dev/null @@ -1,623 +0,0 @@ -package org.argeo.suite.ui; - -import static org.argeo.cms.ui.CmsView.CMS_VIEW_UID_PROPERTY; - -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.TreeMap; -import java.util.TreeSet; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; -import javax.jcr.Session; -import javax.jcr.nodetype.NodeType; -import javax.naming.InvalidNameException; -import javax.naming.ldap.LdapName; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.api.NodeUtils; -import org.argeo.cms.CmsUserManager; -import org.argeo.cms.LocaleUtils; -import org.argeo.cms.Localized; -import org.argeo.cms.auth.CmsSession; -import org.argeo.cms.ui.AbstractCmsApp; -import org.argeo.cms.ui.CmsTheme; -import org.argeo.cms.ui.CmsUiProvider; -import org.argeo.cms.ui.CmsView; -import org.argeo.cms.ui.dialogs.CmsFeedback; -import org.argeo.cms.ui.util.CmsUiUtils; -import org.argeo.eclipse.ui.specific.UiContext; -import org.argeo.entity.EntityConstants; -import org.argeo.entity.EntityNames; -import org.argeo.entity.EntityType; -import org.argeo.jcr.Jcr; -import org.argeo.jcr.JcrException; -import org.argeo.suite.RankedObject; -import org.argeo.suite.SuiteUtils; -import org.argeo.util.LangUtils; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Composite; -import org.osgi.framework.Constants; -import org.osgi.service.event.Event; -import org.osgi.service.event.EventHandler; -import org.osgi.service.useradmin.User; - -/** The Argeo Suite App. */ -public class SuiteApp extends AbstractCmsApp implements EventHandler { - private final static Log log = LogFactory.getLog(SuiteApp.class); - - public final static String PUBLIC_BASE_PATH_PROPERTY = "publicBasePath"; - public final static String DEFAULT_UI_NAME_PROPERTY = "defaultUiName"; - public final static String DEFAULT_THEME_ID_PROPERTY = "defaultThemeId"; - public final static String DEFAULT_LAYER_PROPERTY = "defaultLayer"; - private final static String LOGIN = "login"; - private final static String HOME_STATE = "~"; - - private String publicBasePath = null; - - private String pidPrefix; - private String headerPid; - private String footerPid; - private String leadPanePid; - private String adminLeadPanePid; - private String loginScreenPid; - - private String defaultLayerPid = "argeo.suite.ui.dashboardLayer"; - - private String defaultUiName = "app"; - private String adminUiName = "admin"; - private String defaultThemeId = "org.argeo.suite.theme.default"; - - private Map> uiProvidersByPid = Collections.synchronizedMap(new HashMap<>()); - private Map> uiProvidersByType = Collections.synchronizedMap(new HashMap<>()); - private Map> layersByPid = Collections.synchronizedSortedMap(new TreeMap<>()); - private Map> layersByType = Collections.synchronizedSortedMap(new TreeMap<>()); - - private CmsUserManager cmsUserManager; - - // TODO make more optimal or via CmsSession/CmsView - private Map managedUis = new HashMap<>(); - - public void init(Map properties) { - if (log.isDebugEnabled()) - log.info("Argeo Suite App started"); - - if (properties.containsKey(DEFAULT_UI_NAME_PROPERTY)) - defaultUiName = LangUtils.get(properties, DEFAULT_UI_NAME_PROPERTY); - if (properties.containsKey(DEFAULT_THEME_ID_PROPERTY)) - defaultThemeId = LangUtils.get(properties, DEFAULT_THEME_ID_PROPERTY); - if (properties.containsKey(DEFAULT_LAYER_PROPERTY)) - defaultLayerPid = LangUtils.get(properties, DEFAULT_LAYER_PROPERTY); - publicBasePath = LangUtils.get(properties, PUBLIC_BASE_PATH_PROPERTY); - - if (properties.containsKey(Constants.SERVICE_PID)) { - String servicePid = properties.get(Constants.SERVICE_PID).toString(); - if (servicePid.endsWith(".app")) { - pidPrefix = servicePid.substring(0, servicePid.length() - "app".length()); - } - } - - if (pidPrefix == null) - throw new IllegalArgumentException("PID prefix must be set."); - - headerPid = pidPrefix + "header"; - footerPid = pidPrefix + "footer"; - leadPanePid = pidPrefix + "leadPane"; - adminLeadPanePid = pidPrefix + "adminLeadPane"; - loginScreenPid = pidPrefix + "loginScreen"; - } - - public void destroy(Map properties) { - for (SuiteUi ui : managedUis.values()) - if (!ui.isDisposed()) - ui.dispose(); - if (log.isDebugEnabled()) - log.info("Argeo Suite App stopped"); - - } - - @Override - public Set getUiNames() { - HashSet uiNames = new HashSet<>(); - uiNames.add(defaultUiName); - uiNames.add(adminUiName); - return uiNames; - } - - @Override - public Composite initUi(Composite parent) { - String uiName = parent.getData(UI_NAME_PROPERTY) != null ? parent.getData(UI_NAME_PROPERTY).toString() : null; - CmsView cmsView = CmsView.getCmsView(parent); - if (cmsView == null) - throw new IllegalStateException("No CMS view is registered."); - CmsTheme theme = getTheme(uiName); - if (theme != null) - CmsTheme.registerCmsTheme(parent.getShell(), theme); - SuiteUi argeoSuiteUi = new SuiteUi(parent, SWT.INHERIT_DEFAULT); - String uid = cmsView.getUid(); - managedUis.put(uid, argeoSuiteUi); - argeoSuiteUi.addDisposeListener((e) -> { - managedUis.remove(uid); - if (log.isDebugEnabled()) - log.debug("Suite UI " + uid + " has been disposed."); - }); - return argeoSuiteUi; - } - - @Override - public String getThemeId(String uiName) { - return defaultThemeId; - } - - @Override - public void refreshUi(Composite parent, String state) { - try { - Node context = null; - SuiteUi ui = (SuiteUi) parent; - - String uiName = Objects.toString(ui.getParent().getData(UI_NAME_PROPERTY), null); - if (uiName == null) - throw new IllegalStateException("UI name should not be null"); - CmsView cmsView = CmsView.getCmsView(parent); - CmsUiProvider headerUiProvider = findUiProvider(headerPid); - CmsUiProvider footerUiProvider = findUiProvider(footerPid); - CmsUiProvider leadPaneUiProvider; - if (adminUiName.equals(uiName)) { - leadPaneUiProvider = findUiProvider(adminLeadPanePid); - } else { - leadPaneUiProvider = findUiProvider(leadPanePid); - } - - Localized appTitle = null; - if (headerUiProvider instanceof DefaultHeader) { - appTitle = ((DefaultHeader) headerUiProvider).getTitle(); - } - ui.setTitle(appTitle); - - if (cmsView.isAnonymous() && publicBasePath == null) {// internal app, must login - ui.logout(); - if (headerUiProvider != null) - refreshPart(headerUiProvider, ui.getHeader(), context); - ui.refreshBelowHeader(false); - refreshPart(findUiProvider(loginScreenPid), ui.getBelowHeader(), context); - if (footerUiProvider != null) - refreshPart(footerUiProvider, ui.getFooter(), context); - ui.layout(true, true); - setState(ui, LOGIN); - } else { - if (LOGIN.equals(state)) - state = null; - CmsSession cmsSession = cmsView.getCmsSession(); - if (ui.getUserDir() == null) { - // FIXME NPE on CMSSession when logging in from anonymous - if (cmsSession == null || cmsView.isAnonymous()) { - assert publicBasePath != null; - ui.initSessions(getRepository(), publicBasePath); - } else { - Session adminSession = null; - try { - adminSession = NodeUtils.openDataAdminSession(getRepository(), null); - Node userDir = SuiteUtils.getOrCreateCmsSessionNode(adminSession, cmsSession); - ui.initSessions(getRepository(), userDir.getPath()); - } finally { - Jcr.logout(adminSession); - } - } - } - initLocale(cmsSession); - context = stateToNode(ui, state); - if (context == null) - context = ui.getUserDir(); - - if (headerUiProvider != null) - refreshPart(headerUiProvider, ui.getHeader(), context); - ui.refreshBelowHeader(true); - for (String key : layersByPid.keySet()) { - SuiteLayer layer = layersByPid.get(key).get(); - ui.addLayer(key, layer); - } - - if (leadPaneUiProvider != null) - refreshPart(leadPaneUiProvider, ui.getLeadPane(), context); - if (footerUiProvider != null) - refreshPart(footerUiProvider, ui.getFooter(), context); - ui.layout(true, true); - setState(parent, state != null ? state : defaultLayerPid); - } - } catch (Exception e) { - CmsFeedback.show("Unexpected exception", e); - } - } - - private void initLocale(CmsSession cmsSession) { - if (cmsSession == null) - return; - Locale locale = cmsSession.getLocale(); - UiContext.setLocale(locale); - LocaleUtils.setThreadLocale(locale); - - } - - private void refreshPart(CmsUiProvider uiProvider, Composite part, Node context) { - CmsUiUtils.clear(part); - uiProvider.createUiPart(part, context); - } - - private CmsUiProvider findUiProvider(String pid) { - if (!uiProvidersByPid.containsKey(pid)) - return null; - return uiProvidersByPid.get(pid).get(); - } - - private SuiteLayer findLayer(String pid) { - if (!layersByPid.containsKey(pid)) - return null; - return layersByPid.get(pid).get(); - } - - private T findByType(Map> byType, Node context) { - if (context == null) - throw new IllegalArgumentException("A node should be provided"); - try { - // mixins - Set 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 (context.getPath().equals("/")) {// root node -// types.add("nt:folder"); -// } - if (NodeUtils.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); - } - } - - private static String listTypes(Node context) { - try { - StringBuilder sb = new StringBuilder(); - sb.append(context.getPrimaryNodeType().getName()); - for (NodeType superType : context.getPrimaryNodeType().getDeclaredSupertypes()) { - sb.append(' '); - sb.append(superType.getName()); - } - - for (NodeType nodeType : context.getMixinNodeTypes()) { - sb.append(' '); - sb.append(nodeType.getName()); - if (nodeType.getName().equals(EntityType.local.get())) - sb.append('/').append(context.getProperty(EntityNames.ENTITY_TYPE).getString()); - for (NodeType superType : nodeType.getDeclaredSupertypes()) { - sb.append(' '); - sb.append(superType.getName()); - } - } - return sb.toString(); - } catch (RepositoryException e) { - throw new JcrException(e); - } - } - - @Override - public void setState(Composite parent, String state) { - if (state == null) - return; - if (!state.startsWith("/")) { - if (parent instanceof SuiteUi) { - SuiteUi ui = (SuiteUi) parent; - if (LOGIN.equals(state)) { - String appTitle = ""; - if (ui.getTitle() != null) - appTitle = ui.getTitle().lead(); - ui.getCmsView().stateChanged(state, appTitle); - return; - } - Map properties = new HashMap<>(); - String layerId = HOME_STATE.equals(state) ? defaultLayerPid : state; - properties.put(SuiteEvent.LAYER, layerId); - properties.put(SuiteEvent.NODE_PATH, HOME_STATE); - ui.getCmsView().sendEvent(SuiteEvent.switchLayer.topic(), properties); - } - return; - } - SuiteUi suiteUi = (SuiteUi) parent; - Node node = stateToNode(suiteUi, state); - if (node == null) { - suiteUi.getCmsView().navigateTo(HOME_STATE); - } else { - suiteUi.getCmsView().sendEvent(SuiteEvent.switchLayer.topic(), SuiteEvent.eventProperties(node)); - suiteUi.getCmsView().sendEvent(SuiteEvent.refreshPart.topic(), SuiteEvent.eventProperties(node)); - } - } - - // TODO move it to an internal package? - static String nodeToState(Node node) { - return '/' + Jcr.getWorkspaceName(node) + Jcr.getPath(node); - } - - private Node stateToNode(SuiteUi suiteUi, String state) { - if (suiteUi == null) - return null; - if (state == null || !state.startsWith("/")) - return null; - - String path = state.substring(1); - String workspace; - if (path.equals("")) { - workspace = null; - path = "/"; - } else { - int index = path.indexOf('/'); - if (index == 0) { - log.error("Cannot interpret " + state); -// cmsView.navigateTo("~"); - return null; - } else if (index > 0) { - workspace = path.substring(0, index); - path = path.substring(index); - } else {// index<0, assuming root node - workspace = path; - path = "/"; - } - } - Session session = suiteUi.getSession(workspace); - if (session == null) - return null; - Node node = Jcr.getNode(session, path); - return node; - } - - /* - * Events management - */ - - @Override - public void handleEvent(Event event) { - - // Specific UI related events - SuiteUi ui = getRelatedUi(event); - if (ui == null) - return; - try { - String appTitle = ""; - if (ui.getTitle() != null) - appTitle = ui.getTitle().lead() + " - "; - -// String currentLayerId = ui.getCurrentLayerId(); -// SuiteLayer currentLayer = currentLayerId != null ? layersByPid.get(currentLayerId).get() : null; - if (SuiteUiUtils.isTopic(event, SuiteEvent.refreshPart)) { - Node node = getNode(ui, event); - if (node == null) - return; - CmsUiProvider uiProvider = findByType(uiProvidersByType, node); - SuiteLayer layer = findByType(layersByType, node); - ui.switchToLayer(layer, node); - ui.getCmsView().runAs(() -> layer.view(uiProvider, ui.getCurrentWorkArea(), node)); - ui.getCmsView().stateChanged(nodeToState(node), appTitle + Jcr.getTitle(node)); - } else if (SuiteUiUtils.isTopic(event, SuiteEvent.openNewPart)) { - Node node = getNode(ui, event); - if (node == null) - return; - CmsUiProvider uiProvider = findByType(uiProvidersByType, node); - SuiteLayer layer = findByType(layersByType, node); - ui.switchToLayer(layer, node); - ui.getCmsView().runAs(() -> layer.open(uiProvider, ui.getCurrentWorkArea(), node)); - ui.getCmsView().stateChanged(nodeToState(node), appTitle + Jcr.getTitle(node)); - } else if (SuiteUiUtils.isTopic(event, SuiteEvent.switchLayer)) { - String layerId = get(event, SuiteEvent.LAYER); - if (layerId != null) { -// ui.switchToLayer(layerId, ui.getUserDir()); - SuiteLayer suiteLayer = findLayer(layerId); - if (suiteLayer == null) - throw new IllegalArgumentException("No layer '" + layerId + "' available."); - Localized layerTitle = suiteLayer.getTitle(); - // FIXME make sure we don't rebuild the work area twice - Composite workArea = ui.getCmsView().doAs(() -> ui.switchToLayer(layerId, ui.getUserDir())); - String title = null; - if (layerTitle != null) - title = layerTitle.lead(); - Node nodeFromState = getNode(ui, event); - if (nodeFromState != null && nodeFromState.getPath().equals(ui.getUserDir().getPath())) { - // default layer view is forced - String state = defaultLayerPid.equals(layerId) ? "~" : layerId; - ui.getCmsView().stateChanged(state, appTitle + title); - suiteLayer.view(null, workArea, nodeFromState); - } else { - Node layerCurrentContext = suiteLayer.getCurrentContext(workArea); - if (layerCurrentContext != null) { - // layer was already showing a context so we set the state to it - ui.getCmsView().stateChanged(nodeToState(layerCurrentContext), - appTitle + Jcr.getTitle(layerCurrentContext)); - } else { - // no context was shown - ui.getCmsView().stateChanged(layerId, appTitle + title); - } - } - } else { - Node node = getNode(ui, event); - if (node != null) { - SuiteLayer layer = findByType(layersByType, node); - ui.getCmsView().runAs(() -> ui.switchToLayer(layer, node)); - } - } - } - } catch (Exception e) { - log.error("Cannot handle event " + event, e); -// CmsView.getCmsView(ui).exception(e); - } - - } - - private Node getNode(SuiteUi ui, Event event) { - String nodePath = get(event, SuiteEvent.NODE_PATH); - if (nodePath != null && nodePath.equals(HOME_STATE)) - return ui.getUserDir(); - String workspaceName = get(event, SuiteEvent.WORKSPACE); - Session session = ui.getSession(workspaceName); - Node node; - if (nodePath == null) { - // look for a user - String username = get(event, SuiteEvent.USERNAME); - if (username == null) - return null; - User user = cmsUserManager.getUser(username); - if (user == null) - return null; - LdapName userDn; - try { - userDn = new LdapName(user.getName()); - } catch (InvalidNameException e) { - throw new IllegalArgumentException("Badly formatted username", e); - } - String userNodePath = SuiteUtils.getUserNodePath(userDn); - if (Jcr.itemExists(session, userNodePath)) - node = Jcr.getNode(session, userNodePath); - else { - Session adminSession = null; - try { - adminSession = NodeUtils.openDataAdminSession(getRepository(), workspaceName); - SuiteUtils.getOrCreateUserNode(adminSession, userDn); - } finally { - Jcr.logout(adminSession); - } - node = Jcr.getNode(session, userNodePath); - } - } else { - node = Jcr.getNode(session, nodePath); - } - return node; - } - - private SuiteUi getRelatedUi(Event event) { - return managedUis.get(get(event, CMS_VIEW_UID_PROPERTY)); - } - - public static String get(Event event, String key) { - Object value = event.getProperty(key); - if (value == null) - return null; -// throw new IllegalArgumentException("Property " + key + " must be set"); - return value.toString(); - - } - - /* - * Dependency injection. - */ - - public void addUiProvider(CmsUiProvider uiProvider, Map properties) { - if (properties.containsKey(Constants.SERVICE_PID)) { - String pid = (String) properties.get(Constants.SERVICE_PID); - RankedObject.putIfHigherRank(uiProvidersByPid, pid, uiProvider, properties); - } - if (properties.containsKey(EntityConstants.TYPE)) { - List types = LangUtils.toStringList(properties.get(EntityConstants.TYPE)); - for (String type : types) - RankedObject.putIfHigherRank(uiProvidersByType, type, uiProvider, properties); - } - } - - public void removeUiProvider(CmsUiProvider uiProvider, Map properties) { - if (properties.containsKey(Constants.SERVICE_PID)) { - String pid = (String) properties.get(Constants.SERVICE_PID); - if (uiProvidersByPid.containsKey(pid)) { - if (uiProvidersByPid.get(pid).equals(new RankedObject(uiProvider, properties))) { - uiProvidersByPid.remove(pid); - } - } - } - if (properties.containsKey(EntityConstants.TYPE)) { - List types = LangUtils.toStringList(properties.get(EntityConstants.TYPE)); - for (String type : types) { - if (uiProvidersByType.containsKey(type)) { - if (uiProvidersByType.get(type).equals(new RankedObject(uiProvider, properties))) { - uiProvidersByType.remove(type); - } - } - } - } - } - - public void addLayer(SuiteLayer layer, Map properties) { - if (properties.containsKey(Constants.SERVICE_PID)) { - String pid = (String) properties.get(Constants.SERVICE_PID); - RankedObject.putIfHigherRank(layersByPid, pid, layer, properties); - } - if (properties.containsKey(EntityConstants.TYPE)) { - List types = LangUtils.toStringList(properties.get(EntityConstants.TYPE)); - for (String type : types) - RankedObject.putIfHigherRank(layersByType, type, layer, properties); - } - } - - public void removeLayer(SuiteLayer layer, Map properties) { - if (properties.containsKey(Constants.SERVICE_PID)) { - String pid = (String) properties.get(Constants.SERVICE_PID); - if (layersByPid.containsKey(pid)) { - if (layersByPid.get(pid).equals(new RankedObject(layer, properties))) { - layersByPid.remove(pid); - } - } - } - if (properties.containsKey(EntityConstants.TYPE)) { - List types = LangUtils.toStringList(properties.get(EntityConstants.TYPE)); - for (String type : types) { - if (layersByType.containsKey(type)) { - if (layersByType.get(type).equals(new RankedObject(layer, properties))) { - layersByType.remove(type); - } - } - } - } - } - - public void setCmsUserManager(CmsUserManager cmsUserManager) { - this.cmsUserManager = cmsUserManager; - } - -} diff --git a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteEvent.java b/core/org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteEvent.java deleted file mode 100644 index 563cd21..0000000 --- a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteEvent.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.argeo.suite.ui; - -import java.util.HashMap; -import java.util.Map; - -import javax.jcr.Node; - -import org.argeo.cms.ui.util.CmsEvent; -import org.argeo.jcr.Jcr; -import org.osgi.service.useradmin.User; - -/** Events specific to Argeo Suite. */ -public enum SuiteEvent implements CmsEvent { - openNewPart, refreshPart, switchLayer; - - public final static String LAYER = "layer"; -// public final static String NODE_ID = "nodeId"; - public final static String NODE_PATH = "path"; - public final static String USERNAME = "username"; - public final static String WORKSPACE = "workspace"; - - public String getTopicBase() { - return "argeo/suite/ui"; - } - - public static Map eventProperties(Node node) { - Map properties = new HashMap<>(); - properties.put(NODE_PATH, Jcr.getPath(node)); - properties.put(WORKSPACE, Jcr.getWorkspaceName(node)); - return properties; - } - - public static Map eventProperties(User user) { - Map properties = new HashMap<>(); - properties.put(USERNAME, user.getName()); - return properties; - } -} diff --git a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteIcon.java b/core/org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteIcon.java deleted file mode 100644 index 2c9561d..0000000 --- a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteIcon.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.argeo.suite.ui; - -import org.argeo.cms.ui.util.CmsIcon; - -/** Icon names used by Argeo Suite. */ -public enum SuiteIcon implements CmsIcon { - add, save, close, closeAll, search, delete, logout, dashboard, - // people - people, person, organisation, - // library - documents, document, folder, - // admin and settings - settings, user, - // misc - task, tag, location, inbox, map; -} diff --git a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteLayer.java b/core/org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteLayer.java deleted file mode 100644 index d18192f..0000000 --- a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteLayer.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.argeo.suite.ui; - -import javax.jcr.Node; - -import org.argeo.cms.Localized; -import org.argeo.cms.ui.CmsUiProvider; -import org.eclipse.swt.widgets.Composite; - -/** An UI layer for the main work area. */ -public interface SuiteLayer extends CmsUiProvider { - static enum Property { - title, icon, weights, startMaximized, singleTab, fixedEntryArea; - } - - void view(CmsUiProvider uiProvider, Composite workArea, Node context); - - Node getCurrentContext(Composite workArea); - - default void open(CmsUiProvider uiProvider, Composite workArea, Node context) { - view(uiProvider, workArea, context); - } - - default Localized getTitle() { - return null; - } -} diff --git a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteMsg.java b/core/org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteMsg.java deleted file mode 100644 index 3b376db..0000000 --- a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteMsg.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.argeo.suite.ui; - -import org.argeo.cms.Localized; - -/** Localized messages. */ -public enum SuiteMsg implements Localized { - dashboard, people, documents, locations, recentItems, - // NewPersonWizard - firstName, lastName, salutation, email, personWizardWindowTitle, personWizardPageTitle, - // NewOrgWizard - orgWizardWindowTitle, orgWizardPageTitle, legalName, legalForm, vatId, - // ContextAddressComposite - chooseAnOrganisation, street, streetComplement, zipCode, city, state, country, geopoint, - // FilteredOrderableEntityTable - filterHelp, - // BankAccountComposite - accountHolder, bankName, currency, accountNumber, bankNumber, BIC, IBAN, - // EditJobDialog - position, chosenItem, department, isPrimary, searchAndChooseEntity, - // ContactListCTab (e4) - notes, addAContact, contactValue, linkedCompany, - // OrgAdminInfoCTab (e4) - paymentAccount, - // OrgEditor (e4) - orgDetails, orgActivityLog, team, orgAdmin, - // PersonEditor (e4) - personDetails, personActivityLog, personOrgs, personSecurity, - // PersonSecurityCTab (e4) - resetPassword, - // Generic - label, aCustomLabel, description, value, name, primary, add, save, pickup, - // Tag - confirmNewTag, cannotCreateTag; -} diff --git a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteStyle.java b/core/org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteStyle.java deleted file mode 100644 index 0b26852..0000000 --- a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteStyle.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.argeo.suite.ui; - -import org.argeo.cms.ui.util.CmsStyle; - -/** Styles used by Argeo Suite work UI. */ -public enum SuiteStyle implements CmsStyle { - // header - header, headerTitle, headerMenu, headerMenuItem, - // footer - footer, - // recent items - recentItems, - // lead pane - leadPane, leadPaneItem, leadPaneSectionTitle, leadPaneSubSectionTitle, - // entry area - entryArea, - // group composite - titleContainer, titleLabel, subTitleLabel, formLine, formColumn, navigationBar, navigationTitle, navigationButton, - // forms elements - simpleLabel, simpleText, simpleInput, - // table - titleCell, - // layers - workArea, - // tabbed area - mainTabBody, mainTabSelected, mainTab, - // buttons - inlineButton; - - @Override - public String getClassPrefix() { - return "argeo-suite"; - } - -} diff --git a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteUi.java b/core/org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteUi.java deleted file mode 100644 index 469e36f..0000000 --- a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteUi.java +++ /dev/null @@ -1,258 +0,0 @@ -package org.argeo.suite.ui; - -import java.util.HashMap; -import java.util.Map; - -import javax.jcr.Node; -import javax.jcr.Repository; -import javax.jcr.RepositoryException; -import javax.jcr.Session; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.api.NodeConstants; -import org.argeo.cms.Localized; -import org.argeo.cms.ui.CmsView; -import org.argeo.cms.ui.util.CmsUiUtils; -import org.argeo.jcr.Jcr; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.FormLayout; -import org.eclipse.swt.widgets.Composite; - -/** The view for the default ergonomics of Argeo Suite. */ -class SuiteUi extends Composite { - private static final long serialVersionUID = 6207018859086689108L; - private final static Log log = LogFactory.getLog(SuiteUi.class); - - private Localized title; - private Composite header; - private Composite footer; - private Composite belowHeader; - private Composite leadPane; - private Composite sidePane; - private Composite dynamicArea; - - private Session sysSession; - private Session homeSession; - private Node userDir; - - private Map layers = new HashMap<>(); - private Map workAreas = new HashMap<>(); - private String currentLayerId = null; - - private CmsView cmsView; - - public SuiteUi(Composite parent, int style) { - super(parent, style); - cmsView = CmsView.getCmsView(parent); - this.setLayout(CmsUiUtils.noSpaceGridLayout()); - - header = new Composite(this, SWT.NONE); - header.setLayout(CmsUiUtils.noSpaceGridLayout()); - CmsUiUtils.style(header, SuiteStyle.header); - header.setLayoutData(CmsUiUtils.fillWidth()); - - belowHeader = new Composite(this, SWT.NONE); - belowHeader.setLayoutData(CmsUiUtils.fillAll()); - - footer = new Composite(this, SWT.NONE); - footer.setLayout(CmsUiUtils.noSpaceGridLayout()); - CmsUiUtils.style(footer, SuiteStyle.footer); - footer.setLayoutData(CmsUiUtils.fillWidth()); - } - - public void refreshBelowHeader(boolean initApp) { - CmsUiUtils.clear(belowHeader); - int style = getStyle(); - if (initApp) { - belowHeader.setLayout(CmsUiUtils.noSpaceGridLayout(3)); - - if (SWT.RIGHT_TO_LEFT == (style & SWT.RIGHT_TO_LEFT)) {// arabic, hebrew, etc. - sidePane = new Composite(belowHeader, SWT.NONE); - sidePane.setLayout(CmsUiUtils.noSpaceGridLayout()); - sidePane.setLayoutData(CmsUiUtils.fillHeight()); - dynamicArea = new Composite(belowHeader, SWT.NONE); - leadPane = new Composite(belowHeader, SWT.NONE); - } else { - leadPane = new Composite(belowHeader, SWT.NONE); - dynamicArea = new Composite(belowHeader, SWT.NONE); - sidePane = new Composite(belowHeader, SWT.NONE); - sidePane.setLayout(CmsUiUtils.noSpaceGridLayout()); - sidePane.setLayoutData(CmsUiUtils.fillHeight()); - } - leadPane.setLayoutData(CmsUiUtils.fillHeight()); - leadPane.setLayout(CmsUiUtils.noSpaceGridLayout()); - CmsUiUtils.style(leadPane, SuiteStyle.leadPane); - - dynamicArea.setLayoutData(CmsUiUtils.fillAll()); - dynamicArea.setLayout(new FormLayout()); - - } else { - belowHeader.setLayout(CmsUiUtils.noSpaceGridLayout()); - } - } - - /* - * LAYERS - */ - - Composite getCurrentWorkArea() { - if (currentLayerId == null) - throw new IllegalStateException("No current layer"); - return workAreas.get(currentLayerId); - } - - String getCurrentLayerId() { - return currentLayerId; - } - - private Composite getLayer(String id, Node context) { - if (!layers.containsKey(id)) - return null; - if (!workAreas.containsKey(id)) - initLayer(id, layers.get(id), context); - return workAreas.get(id); - } - - Composite switchToLayer(String layerId, Node context) { - Composite current = null; - if (currentLayerId != null) { - current = getCurrentWorkArea(); - if (currentLayerId.equals(layerId)) - return current; - } - if (context == null) { - if (!cmsView.isAnonymous()) - context = userDir; - } - Composite toShow = getLayer(layerId, context); - if (toShow != null) { - currentLayerId = layerId; - if (!isDisposed()) { -// getDisplay().syncExec(() -> { - if (!toShow.isDisposed()) { - toShow.moveAbove(null); - } else { - log.warn("Cannot show work area because it is disposed."); - toShow = initLayer(layerId, layers.get(layerId), context); - toShow.moveAbove(null); - } - dynamicArea.layout(true, true); -// }); - } - return toShow; - } else { - return current; - } - } - - Composite switchToLayer(SuiteLayer layer, Node context) { - // TODO make it more robust - for (String layerId : layers.keySet()) { - SuiteLayer l = layers.get(layerId); - if (layer == l) { - return switchToLayer(layerId, context); - } - } - throw new IllegalArgumentException("Layer is not registered."); - } - - void addLayer(String id, SuiteLayer layer) { - layers.put(id, layer); - } - - void removeLayer(String id) { - layers.remove(id); - if (workAreas.containsKey(id)) { - Composite workArea = workAreas.remove(id); - if (!workArea.isDisposed()) - workArea.dispose(); - } - } - - protected Composite initLayer(String id, SuiteLayer layer, Node context) { - Composite workArea = cmsView.doAs(() -> (Composite) layer.createUiPart(dynamicArea, context)); - CmsUiUtils.style(workArea, SuiteStyle.workArea); - workArea.setLayoutData(CmsUiUtils.coverAll()); - workAreas.put(id, workArea); - return workArea; - } - - synchronized void logout() { - userDir = null; - Jcr.logout(sysSession); - Jcr.logout(homeSession); - currentLayerId = null; - workAreas.clear(); - } - - /* - * GETTERS / SETTERS - */ - - Composite getHeader() { - return header; - } - - Composite getFooter() { - return footer; - } - - Composite getLeadPane() { - return leadPane; - } - - Composite getSidePane() { - return sidePane; - } - - Composite getBelowHeader() { - return belowHeader; - } - -// Session getSysSession() { -// return sysSession; -// } -// - synchronized void initSessions(Repository repository, String userDirPath) throws RepositoryException { - this.sysSession = repository.login(); - this.homeSession = repository.login(NodeConstants.HOME_WORKSPACE); - userDir = sysSession.getNode(userDirPath); - addDisposeListener((e) -> { - Jcr.logout(sysSession); - Jcr.logout(homeSession); - }); - } - - Node getUserDir() { - return userDir; - } - - Session getSysSession() { - return sysSession; - } - - Session getSession(String workspaceName) { - if (workspaceName == null) - return sysSession; - if (NodeConstants.SYS_WORKSPACE.equals(workspaceName)) - return sysSession; - else if (NodeConstants.HOME_WORKSPACE.equals(workspaceName)) - return homeSession; - else - throw new IllegalArgumentException("Unknown workspace " + workspaceName); - } - - public CmsView getCmsView() { - return cmsView; - } - - public Localized getTitle() { - return title; - } - - public void setTitle(Localized title) { - this.title = title; - } - -} diff --git a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteUiUtils.java b/core/org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteUiUtils.java deleted file mode 100644 index 048b946..0000000 --- a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteUiUtils.java +++ /dev/null @@ -1,435 +0,0 @@ -package org.argeo.suite.ui; - -import java.io.IOException; -import java.io.InputStream; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; -import javax.jcr.Session; - -import org.argeo.cms.LocaleUtils; -import org.argeo.cms.Localized; -import org.argeo.cms.auth.CurrentUser; -import org.argeo.cms.ui.CmsEditable; -import org.argeo.cms.ui.CmsTheme; -import org.argeo.cms.ui.CmsView; -import org.argeo.cms.ui.dialogs.LightweightDialog; -import org.argeo.cms.ui.util.CmsEvent; -import org.argeo.cms.ui.util.CmsIcon; -import org.argeo.cms.ui.util.CmsLink; -import org.argeo.cms.ui.util.CmsStyle; -import org.argeo.cms.ui.util.CmsUiUtils; -import org.argeo.eclipse.ui.EclipseUiUtils; -import org.argeo.entity.EntityNames; -import org.argeo.entity.EntityType; -import org.argeo.jcr.Jcr; -import org.argeo.jcr.JcrException; -import org.argeo.jcr.JcrUtils; -import org.argeo.suite.SuiteRole; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.ScrolledComposite; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseListener; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Text; -import org.osgi.service.event.Event; - -/** UI utilities related to the APAF project. */ -public class SuiteUiUtils { - - /** Singleton. */ - private SuiteUiUtils() { - } - - /** creates a title bar composite with label and optional button */ - public static void addTitleBar(Composite parent, String title, Boolean isEditable) { - Composite titleBar = new Composite(parent, SWT.NONE); - titleBar.setLayoutData(CmsUiUtils.fillWidth()); - CmsUiUtils.style(titleBar, SuiteStyle.titleContainer); - - titleBar.setLayout(CmsUiUtils.noSpaceGridLayout(new GridLayout(2, false))); - Label titleLbl = new Label(titleBar, SWT.NONE); - titleLbl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true)); - CmsUiUtils.style(titleLbl, SuiteStyle.titleLabel); - titleLbl.setText(title); - - if (isEditable) { - Button editBtn = new Button(titleBar, SWT.PUSH); - editBtn.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false)); - CmsUiUtils.style(editBtn, SuiteStyle.inlineButton); - editBtn.setText("Edit"); - } - } - - public static Label addFormLabel(Composite parent, String label) { - Label lbl = new Label(parent, SWT.WRAP); - lbl.setText(label); - // lbl.setLayoutData(new GridData(SWT.LEAD, SWT.CENTER, true, true)); - CmsUiUtils.style(lbl, SuiteStyle.simpleLabel); - return lbl; - } - - public static Text addFormTextField(Composite parent, String text, String message) { - return addFormTextField(parent, text, message, SWT.NONE); - } - - public static Text addFormTextField(Composite parent, String text, String message, int style) { - Text txt = new Text(parent, style); - if (text != null) - txt.setText(text); - if (message != null) - txt.setMessage(message); - txt.setLayoutData(new GridData(SWT.LEAD, SWT.CENTER, true, true)); - CmsUiUtils.style(txt, SuiteStyle.simpleText); - return txt; - } - - public static Text addFormInputField(Composite parent, String placeholder) { - Text txt = new Text(parent, SWT.BORDER); - - GridData gridData = CmsUiUtils.fillWidth(); - txt.setLayoutData(gridData); - - if (placeholder != null) - txt.setText(placeholder); - - CmsUiUtils.style(txt, SuiteStyle.simpleInput); - return txt; - } - - /** creates a single horizontal-block composite for key:value display */ - public static Text addFormLine(Composite parent, String label, String text) { - Composite lineComposite = new Composite(parent, SWT.NONE); - lineComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - lineComposite.setLayout(new GridLayout(2, false)); - CmsUiUtils.style(lineComposite, SuiteStyle.formLine); - addFormLabel(lineComposite, label); - Text txt = addFormTextField(lineComposite, text, null); - txt.setEditable(false); - txt.setLayoutData(CmsUiUtils.fillWidth()); - return txt; - } - - public static Text addFormLine(Composite parent, String label, Node node, String property, - CmsEditable cmsEditable) { - Composite lineComposite = new Composite(parent, SWT.NONE); - lineComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - lineComposite.setLayout(new GridLayout(2, false)); - CmsUiUtils.style(lineComposite, SuiteStyle.formLine); - addFormLabel(lineComposite, label); - String text = Jcr.get(node, property); -// int style = cmsEditable.isEditing() ? SWT.WRAP : SWT.WRAP; - Text txt = addFormTextField(lineComposite, text, null, SWT.WRAP); - if (cmsEditable != null && cmsEditable.isEditing()) { - txt.addModifyListener((e) -> { - Jcr.set(node, property, txt.getText()); - Jcr.save(node); - }); - } else { - txt.setEditable(false); - } - txt.setLayoutData(CmsUiUtils.fillWidth()); - return txt; - } - - public static Text addFormInput(Composite parent, String label, String placeholder) { - Composite lineComposite = new Composite(parent, SWT.NONE); - lineComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - lineComposite.setLayout(new GridLayout(2, false)); - CmsUiUtils.style(lineComposite, SuiteStyle.formLine); - addFormLabel(lineComposite, label); - Text txt = addFormInputField(lineComposite, placeholder); - txt.setLayoutData(CmsUiUtils.fillWidth()); - return txt; - } - - /** - * creates a single horizontal-block composite for key:value display, with - * offset value - */ - public static Text addFormLine(Composite parent, String label, String text, Integer offset) { - Composite lineComposite = new Composite(parent, SWT.NONE); - lineComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - lineComposite.setLayout(new GridLayout(3, false)); - CmsUiUtils.style(lineComposite, SuiteStyle.formLine); - Label offsetLbl = new Label(lineComposite, SWT.NONE); - GridData gridData = new GridData(); - gridData.widthHint = offset; - offsetLbl.setLayoutData(gridData); - addFormLabel(lineComposite, label); - Text txt = addFormTextField(lineComposite, text, null); - txt.setLayoutData(CmsUiUtils.fillWidth()); - return txt; - } - - /** creates a single vertical-block composite for key:value display */ - public static Text addFormColumn(Composite parent, String label, String text) { -// Composite columnComposite = new Composite(parent, SWT.NONE); -// columnComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); -// columnComposite.setLayout(new GridLayout(1, false)); - addFormLabel(parent, label); - Text txt = addFormTextField(parent, text, null); - txt.setEditable(false); - txt.setLayoutData(CmsUiUtils.fillWidth()); - return txt; - } - - public static Text addFormColumn(Composite parent, String label, Node node, String property, - CmsEditable cmsEditable) { -// Composite columnComposite = new Composite(parent, SWT.NONE); -// columnComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); -// columnComposite.setLayout(new GridLayout(1, false)); - addFormLabel(parent, label); - String text = Jcr.get(node, property); -// int style = cmsEditable.isEditing() ? SWT.WRAP : SWT.WRAP; - Text txt = addFormTextField(parent, text, null, SWT.WRAP); - if (cmsEditable != null && cmsEditable.isEditing()) { - txt.addModifyListener((e) -> { - Jcr.set(node, property, txt.getText()); - Jcr.save(node); - }); - } else { - txt.setEditable(false); - } - txt.setLayoutData(CmsUiUtils.fillWidth()); - return txt; - } - - public static Label createBoldLabel(Composite parent, Localized localized) { - Label label = new Label(parent, SWT.LEAD); - label.setText(localized.lead()); - label.setFont(EclipseUiUtils.getBoldFont(parent)); - label.setLayoutData(new GridData(SWT.LEAD, SWT.CENTER, false, false)); - return label; - } - - public static Label addFormPicture(Composite parent, String label, Node fileNode) throws RepositoryException { - Composite lineComposite = new Composite(parent, SWT.NONE); - lineComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - lineComposite.setLayout(new GridLayout(2, true)); - CmsUiUtils.style(lineComposite, SuiteStyle.formLine); - addFormLabel(lineComposite, label); - - return addPicture(lineComposite, fileNode); - } - - public static Label addPicture(Composite parent, Node fileNode) throws RepositoryException { - return addPicture(parent, fileNode, null); - } - - public static Label addPicture(Composite parent, Node fileNode, Integer maxWidth) throws RepositoryException { - return addPicture(parent, fileNode, maxWidth, null); - } - - public static Label addPicture(Composite parent, Node fileNode, Integer maxWidth, Node link) - throws RepositoryException { - Node content = fileNode.getNode(Node.JCR_CONTENT); - // TODO move it deeper in the middleware. - if (!content.isNodeType(EntityType.box.get())) { - if (content.getSession().hasPermission(content.getPath(), Session.ACTION_SET_PROPERTY)) { - try (InputStream in = JcrUtils.getFileAsStream(fileNode)) { - ImageData imageData = new ImageData(in); - content.addMixin(EntityType.box.get()); - content.setProperty(EntityNames.SVG_WIDTH, imageData.width); - content.setProperty(EntityNames.SVG_HEIGHT, imageData.height); - content.getSession().save(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - } - - // TODO optimise - Long width; - Long height; - if (content.isNodeType(EntityType.box.get())) { - width = content.getProperty(EntityNames.SVG_WIDTH).getLong(); - height = content.getProperty(EntityNames.SVG_HEIGHT).getLong(); - } else { - try (InputStream in = JcrUtils.getFileAsStream(fileNode)) { - ImageData imageData = new ImageData(in); - width = Long.valueOf(imageData.width); - height = Long.valueOf(imageData.height); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - if (maxWidth != null && width > maxWidth) { - Double ratio = maxWidth.doubleValue() / width.doubleValue(); - width = maxWidth.longValue(); - height = Math.round(ratio * height); - } - Label img = new Label(parent, SWT.NONE); - CmsUiUtils.markup(img); - StringBuffer txt = new StringBuffer(); - String target = toLink(link); - if (target != null) - txt.append(""); - txt.append(CmsUiUtils.img(fileNode, width.toString(), height.toString())); - if (target != null) - txt.append(""); - img.setText(txt.toString()); - if (parent.getLayout() instanceof GridLayout) { - GridData gd = new GridData(SWT.CENTER, SWT.CENTER, false, false); - gd.widthHint = width.intValue(); - gd.heightHint = height.intValue(); - img.setLayoutData(gd); - } - - if (target == null) - img.addMouseListener(new MouseListener() { - private static final long serialVersionUID = -1362242049325206168L; - - @Override - public void mouseUp(MouseEvent e) { - } - - @Override - public void mouseDown(MouseEvent e) { - } - - @Override - public void mouseDoubleClick(MouseEvent e) { - LightweightDialog dialog = new LightweightDialog(img.getShell()) { - - @Override - protected Control createDialogArea(Composite parent) { - parent.setLayout(new GridLayout()); - ScrolledComposite scroll = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL); - scroll.setLayoutData(CmsUiUtils.fillAll()); - scroll.setLayout(CmsUiUtils.noSpaceGridLayout()); - scroll.setExpandHorizontal(true); - scroll.setExpandVertical(true); - // scroll.setAlwaysShowScrollBars(true); - - Composite c = new Composite(scroll, SWT.NONE); - scroll.setContent(c); - c.setLayout(new GridLayout()); - c.setLayoutData(CmsUiUtils.fillAll()); - Label bigImg = new Label(c, SWT.NONE); - CmsUiUtils.markup(bigImg); - bigImg.setText(CmsUiUtils.img(fileNode, Jcr.get(content, EntityNames.SVG_WIDTH), - Jcr.get(content, EntityNames.SVG_HEIGHT))); - bigImg.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true)); - return bigImg; - } - - @Override - protected Point getInitialSize() { - Point shellSize = img.getShell().getSize(); - return new Point(shellSize.x - 100, shellSize.y - 100); - } - - }; - dialog.open(); - } - }); - return img; - } - - public static String toLink(Node node) { - try { - return node != null ? "#" + CmsUiUtils.cleanPathForUrl(SuiteApp.nodeToState(node)) : null; - } catch (RepositoryException e) { - throw new JcrException("Cannot get link from " + node, e); - } - } - - public static Control addLink(Composite parent, String label, Node node, CmsStyle style) - throws RepositoryException { - String target = toLink(node); - CmsLink link = new CmsLink(label, target, style); - return link.createUi(parent, node); - } - - public static Control addExternalLink(Composite parent, String label, String url, String plainCssAnchorClass, - boolean newWindow) throws RepositoryException { - Label lbl = new Label(parent, SWT.NONE); - CmsUiUtils.markup(lbl); - StringBuilder txt = new StringBuilder(); - txt.append(""); - txt.append(label); - txt.append(""); - lbl.setText(txt.toString()); - return lbl; - } - - public static boolean isCoworker(CmsView cmsView) { - boolean coworker = cmsView.doAs(() -> CurrentUser.isInRole(SuiteRole.coworker.dn())); - return coworker; - } - - public static boolean isTopic(Event event, CmsEvent cmsEvent) { - return event.getTopic().equals(cmsEvent.topic()); - } - - public static Button createLayerButton(Composite parent, String layer, Localized msg, CmsIcon icon, - ClassLoader l10nClassLoader) { - CmsTheme theme = CmsTheme.getCmsTheme(parent); - Button button = new Button(parent, SWT.PUSH); - CmsUiUtils.style(button, SuiteStyle.leadPane); - if (icon != null) - button.setImage(icon.getBigIcon(theme)); - button.setLayoutData(new GridData(SWT.CENTER, SWT.BOTTOM, true, false)); - // button.setToolTipText(msg.lead()); - if (msg != null) { - Label lbl = new Label(parent, SWT.CENTER); - CmsUiUtils.style(lbl, SuiteStyle.leadPane); - String txt = LocaleUtils.lead(msg, l10nClassLoader); -// String txt = msg.lead(); - lbl.setText(txt); - lbl.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, true, false)); - } - CmsUiUtils.sendEventOnSelect(button, SuiteEvent.switchLayer.topic(), SuiteEvent.LAYER, layer); - return button; - } - -// public static String createAndConfigureEntity(Shell shell, Session referenceSession, String mainMixin, -// String... additionnalProps) { -// -// Session tmpSession = null; -// Session mainSession = null; -// try { -// // FIXME would not work if home is another physical workspace -// tmpSession = referenceSession.getRepository().login(NodeConstants.HOME_WORKSPACE); -// Node draftNode = null; -// for (int i = 0; i < additionnalProps.length - 1; i += 2) { -// draftNode.setProperty(additionnalProps[i], additionnalProps[i + 1]); -// } -// Wizard wizard = null; -// CmsWizardDialog dialog = new CmsWizardDialog(shell, wizard); -// // WizardDialog dialog = new WizardDialog(shell, wizard); -// if (dialog.open() == Window.OK) { -// String parentPath = null;// "/" + appService.getBaseRelPath(mainMixin); -// // FIXME it should be possible to specify the workspace -// mainSession = referenceSession.getRepository().login(); -// Node parent = mainSession.getNode(parentPath); -// Node task = null;// appService.publishEntity(parent, mainMixin, draftNode); -//// task = appService.saveEntity(task, false); -// referenceSession.refresh(true); -// return task.getPath(); -// } -// return null; -// } catch (RepositoryException e1) { -// throw new JcrException( -// "Unable to create " + mainMixin + " entity with session " + referenceSession.toString(), e1); -// } finally { -// JcrUtils.logoutQuietly(tmpSession); -// JcrUtils.logoutQuietly(mainSession); -// } -// } - -} diff --git a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/TermsEntryArea.java b/core/org.argeo.suite.ui/src/org/argeo/suite/ui/TermsEntryArea.java deleted file mode 100644 index 0f7e927..0000000 --- a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/TermsEntryArea.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.argeo.suite.ui; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; - -import org.argeo.cms.ui.CmsUiProvider; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; - -/** Entry area for managing th etypologies. */ -public class TermsEntryArea implements CmsUiProvider { - - @Override - public Control createUi(Composite parent, Node context) throws RepositoryException { - parent.setLayout(new GridLayout()); - Label lbl = new Label(parent, SWT.NONE); - lbl.setText("Typologies"); - return lbl; - } - -} diff --git a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/dialogs/NewPersonPage.java b/core/org.argeo.suite.ui/src/org/argeo/suite/ui/dialogs/NewPersonPage.java deleted file mode 100644 index ddd4488..0000000 --- a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/dialogs/NewPersonPage.java +++ /dev/null @@ -1,72 +0,0 @@ -package org.argeo.suite.ui.dialogs; - -import org.argeo.suite.ui.SuiteMsg; -import org.argeo.suite.ui.SuiteUiUtils; -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Text; - -public class NewPersonPage extends WizardPage { - private static final long serialVersionUID = -944349994177526468L; - protected Text lastNameTxt; - protected Text firstNameTxt; - protected Text emailTxt; - - protected NewPersonPage(String pageName) { - super(pageName); - setTitle(SuiteMsg.personWizardPageTitle.lead()); - } - - @Override - public void createControl(Composite parent) { - parent.setLayout(new GridLayout(2, false)); - - // FirstName - SuiteUiUtils.createBoldLabel(parent, SuiteMsg.firstName); - firstNameTxt = new Text(parent, SWT.BORDER); - firstNameTxt.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - - // LastName - SuiteUiUtils.createBoldLabel(parent, SuiteMsg.lastName); - lastNameTxt = new Text(parent, SWT.BORDER); - lastNameTxt.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - - SuiteUiUtils.createBoldLabel(parent, SuiteMsg.email); - emailTxt = new Text(parent, SWT.BORDER); - emailTxt.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - - ModifyListener ml = new ModifyListener() { - private static final long serialVersionUID = -1628130380128946886L; - - @Override - public void modifyText(ModifyEvent event) { - getContainer().updateButtons(); - } - }; - - firstNameTxt.addModifyListener(ml); - lastNameTxt.addModifyListener(ml); - emailTxt.addModifyListener(ml); - - // Don't forget this. - setControl(firstNameTxt); - firstNameTxt.setFocus(); - - } - -// public void updateNode(Node node, PeopleService peopleService, ResourcesService resourcesService) { -// ConnectJcrUtils.setJcrProperty(node, PeopleNames.PEOPLE_LAST_NAME, PropertyType.STRING, lastNameTxt.getText()); -// ConnectJcrUtils.setJcrProperty(node, PeopleNames.PEOPLE_FIRST_NAME, PropertyType.STRING, -// firstNameTxt.getText()); -// ConnectJcrUtils.setJcrProperty(node, PeopleNames.PEOPLE_DISPLAY_NAME, PropertyType.STRING, -// firstNameTxt.getText() + " " + lastNameTxt.getText()); -// String email = emailTxt.getText(); -// ConnectJcrUtils.setJcrProperty(node, PeopleNames.PEOPLE_PRIMARY_EMAIL, PropertyType.STRING, email); -// PeopleJcrUtils.createEmail(resourcesService, peopleService, node, email, true, null, null); -// } -} diff --git a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/dialogs/NewPersonWizard.java b/core/org.argeo.suite.ui/src/org/argeo/suite/ui/dialogs/NewPersonWizard.java deleted file mode 100644 index 9db5e04..0000000 --- a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/dialogs/NewPersonWizard.java +++ /dev/null @@ -1,151 +0,0 @@ -package org.argeo.suite.ui.dialogs; - -import static org.argeo.eclipse.ui.EclipseUiUtils.isEmpty; - -import javax.jcr.Node; - -import org.argeo.eclipse.ui.EclipseUiUtils; -import org.argeo.suite.ui.SuiteMsg; -import org.argeo.suite.ui.SuiteUiUtils; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.wizard.Wizard; -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Text; - -/** Ask first & last name. Update the passed node on finish */ -public class NewPersonWizard extends Wizard { - // private final static Log log = LogFactory.getLog(NewPersonWizard.class); - - // Context - private Node person; - - // This page widgets - protected Text lastNameTxt; - protected Text firstNameTxt; - // private Button useDistinctDisplayNameBtn; - // private Text displayNameTxt; - - public NewPersonWizard(Node person) { - this.person = person; - } - - @Override - public void addPages() { - try { - MainInfoPage page = new MainInfoPage("Main page"); - addPage(page); - } catch (Exception e) { - throw new RuntimeException("Cannot add page to wizard", e); - } - setWindowTitle(SuiteMsg.personWizardWindowTitle.lead()); - } - - /** - * Called when the user click on 'Finish' in the wizard. The task is then - * created and the corresponding session saved. - */ - @Override - public boolean performFinish() { - String lastName = lastNameTxt.getText(); - String firstName = firstNameTxt.getText(); - // String displayName = displayNameTxt.getText(); - // boolean useDistinct = useDistinctDisplayNameBtn.getSelection(); - if (EclipseUiUtils.isEmpty(lastName) && EclipseUiUtils.isEmpty(firstName)) { - MessageDialog.openError(getShell(), "Non-valid information", - "Please enter at least a name that is not empty."); - return false; - } else { -// ConnectJcrUtils.setJcrProperty(person, PEOPLE_LAST_NAME, PropertyType.STRING, lastName); -// ConnectJcrUtils.setJcrProperty(person, PEOPLE_FIRST_NAME, PropertyType.STRING, firstName); -// String fullName = firstName + " " + lastName; -// ConnectJcrUtils.setJcrProperty(person, PEOPLE_DISPLAY_NAME, PropertyType.STRING, fullName); - return true; - } - } - - @Override - public boolean performCancel() { - return true; - } - - @Override - public boolean canFinish() { - String lastName = lastNameTxt.getText(); - String firstName = firstNameTxt.getText(); - if (isEmpty(lastName) && isEmpty(firstName)) { - return false; - } else - return true; - } - - protected class MainInfoPage extends WizardPage { - private static final long serialVersionUID = 1L; - - public MainInfoPage(String pageName) { - super(pageName); - setTitle(SuiteMsg.personWizardPageTitle.lead()); - // setMessage("Please enter a last name and/or a first name."); - } - - public void createControl(Composite parent) { - parent.setLayout(new GridLayout(2, false)); - - // FirstName - SuiteUiUtils.createBoldLabel(parent, SuiteMsg.firstName); - firstNameTxt = new Text(parent, SWT.BORDER); - // firstNameTxt.setMessage("a first name"); - firstNameTxt.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - - // LastName - SuiteUiUtils.createBoldLabel(parent, SuiteMsg.lastName); - lastNameTxt = new Text(parent, SWT.BORDER); - // lastNameTxt.setMessage("a last name"); - lastNameTxt.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - - // Display Name - // useDistinctDisplayNameBtn = new Button(parent, SWT.CHECK); - // useDistinctDisplayNameBtn.setText("Define a disting display name"); - // useDistinctDisplayNameBtn.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, - // true, false, 2, 1)); - // - // ConnectWorkbenchUtils.createBoldLabel(parent, "Display Name"); - // displayNameTxt = new Text(parent, SWT.BORDER); - // displayNameTxt.setMessage("an optional display name"); - // displayNameTxt.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, - // false)); - // displayNameTxt.setEnabled(false); - // - // useDistinctDisplayNameBtn.addSelectionListener(new SelectionAdapter() { - // private static final long serialVersionUID = 1L; - // - // @Override - // public void widgetSelected(SelectionEvent e) { - // displayNameTxt.setEnabled(useDistinctDisplayNameBtn.getSelection()); - // } - // }); - - ModifyListener ml = new ModifyListener() { - private static final long serialVersionUID = -1628130380128946886L; - - @Override - public void modifyText(ModifyEvent event) { - getContainer().updateButtons(); - } - }; - - firstNameTxt.addModifyListener(ml); - lastNameTxt.addModifyListener(ml); - // displayNameTxt.addModifyListener(ml); - - // Don't forget this. - setControl(firstNameTxt); - firstNameTxt.setFocus(); - } - } -} diff --git a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/dialogs/NewUserWizard.java b/core/org.argeo.suite.ui/src/org/argeo/suite/ui/dialogs/NewUserWizard.java deleted file mode 100644 index 5b4575d..0000000 --- a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/dialogs/NewUserWizard.java +++ /dev/null @@ -1,151 +0,0 @@ -package org.argeo.suite.ui.dialogs; - -import static org.argeo.eclipse.ui.EclipseUiUtils.isEmpty; - -import javax.jcr.Node; - -import org.argeo.eclipse.ui.EclipseUiUtils; -import org.argeo.suite.ui.SuiteMsg; -import org.argeo.suite.ui.SuiteUiUtils; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.wizard.Wizard; -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Text; - -/** Ask first & last name. Update the passed node on finish */ -public class NewUserWizard extends Wizard { - // private final static Log log = LogFactory.getLog(NewPersonWizard.class); - - // Context - private Node person; - - // This page widgets - protected Text lastNameTxt; - protected Text firstNameTxt; - // private Button useDistinctDisplayNameBtn; - // private Text displayNameTxt; - - public NewUserWizard(Node person) { - this.person = person; - } - - @Override - public void addPages() { - try { - MainInfoPage page = new MainInfoPage("Main page"); - addPage(page); - } catch (Exception e) { - throw new RuntimeException("Cannot add page to wizard", e); - } - setWindowTitle(SuiteMsg.personWizardWindowTitle.lead()); - } - - /** - * Called when the user click on 'Finish' in the wizard. The task is then - * created and the corresponding session saved. - */ - @Override - public boolean performFinish() { - String lastName = lastNameTxt.getText(); - String firstName = firstNameTxt.getText(); - // String displayName = displayNameTxt.getText(); - // boolean useDistinct = useDistinctDisplayNameBtn.getSelection(); - if (EclipseUiUtils.isEmpty(lastName) && EclipseUiUtils.isEmpty(firstName)) { - MessageDialog.openError(getShell(), "Non-valid information", - "Please enter at least a name that is not empty."); - return false; - } else { -// ConnectJcrUtils.setJcrProperty(person, PEOPLE_LAST_NAME, PropertyType.STRING, lastName); -// ConnectJcrUtils.setJcrProperty(person, PEOPLE_FIRST_NAME, PropertyType.STRING, firstName); -// String fullName = firstName + " " + lastName; -// ConnectJcrUtils.setJcrProperty(person, PEOPLE_DISPLAY_NAME, PropertyType.STRING, fullName); - return true; - } - } - - @Override - public boolean performCancel() { - return true; - } - - @Override - public boolean canFinish() { - String lastName = lastNameTxt.getText(); - String firstName = firstNameTxt.getText(); - if (isEmpty(lastName) && isEmpty(firstName)) { - return false; - } else - return true; - } - - protected class MainInfoPage extends WizardPage { - private static final long serialVersionUID = 1L; - - public MainInfoPage(String pageName) { - super(pageName); - setTitle(SuiteMsg.personWizardPageTitle.lead()); - // setMessage("Please enter a last name and/or a first name."); - } - - public void createControl(Composite parent) { - parent.setLayout(new GridLayout(2, false)); - - // FirstName - SuiteUiUtils.createBoldLabel(parent, SuiteMsg.firstName); - firstNameTxt = new Text(parent, SWT.BORDER); - // firstNameTxt.setMessage("a first name"); - firstNameTxt.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - - // LastName - SuiteUiUtils.createBoldLabel(parent, SuiteMsg.lastName); - lastNameTxt = new Text(parent, SWT.BORDER); - // lastNameTxt.setMessage("a last name"); - lastNameTxt.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - - // Display Name - // useDistinctDisplayNameBtn = new Button(parent, SWT.CHECK); - // useDistinctDisplayNameBtn.setText("Define a disting display name"); - // useDistinctDisplayNameBtn.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, - // true, false, 2, 1)); - // - // ConnectWorkbenchUtils.createBoldLabel(parent, "Display Name"); - // displayNameTxt = new Text(parent, SWT.BORDER); - // displayNameTxt.setMessage("an optional display name"); - // displayNameTxt.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, - // false)); - // displayNameTxt.setEnabled(false); - // - // useDistinctDisplayNameBtn.addSelectionListener(new SelectionAdapter() { - // private static final long serialVersionUID = 1L; - // - // @Override - // public void widgetSelected(SelectionEvent e) { - // displayNameTxt.setEnabled(useDistinctDisplayNameBtn.getSelection()); - // } - // }); - - ModifyListener ml = new ModifyListener() { - private static final long serialVersionUID = -1628130380128946886L; - - @Override - public void modifyText(ModifyEvent event) { - getContainer().updateButtons(); - } - }; - - firstNameTxt.addModifyListener(ml); - lastNameTxt.addModifyListener(ml); - // displayNameTxt.addModifyListener(ml); - - // Don't forget this. - setControl(firstNameTxt); - firstNameTxt.setFocus(); - } - } -} diff --git a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/widgets/AbstractConnectContextMenu.java b/core/org.argeo.suite.ui/src/org/argeo/suite/ui/widgets/AbstractConnectContextMenu.java deleted file mode 100644 index 07f9cee..0000000 --- a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/widgets/AbstractConnectContextMenu.java +++ /dev/null @@ -1,133 +0,0 @@ -package org.argeo.suite.ui.widgets; - -import java.util.HashMap; -import java.util.Map; - -import org.argeo.cms.ui.util.CmsUiUtils; -import org.argeo.eclipse.ui.EclipseUiUtils; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.ShellEvent; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; - -/** - * Generic popup context menu for TableViewer to enable single sourcing between - * CMS and Workbench - */ -public abstract class AbstractConnectContextMenu { - - private Shell parentShell; - private Shell shell; - // Local context - - private final static String KEY_ACTION_ID = "actionId"; - private final String[] defaultActions; - private Map actionButtons = new HashMap(); - - public AbstractConnectContextMenu(Display display, String[] defaultActions) { - parentShell = display.getActiveShell(); - shell = new Shell(parentShell, SWT.NO_TRIM | SWT.BORDER | SWT.ON_TOP); - this.defaultActions = defaultActions; - } - - protected void createControl() { - shell.setLayout(EclipseUiUtils.noSpaceGridLayout()); - Composite boxCmp = new Composite(shell, SWT.NO_FOCUS | SWT.BORDER); - boxCmp.setLayout(EclipseUiUtils.noSpaceGridLayout()); -// CmsUiUtils.style(boxCmp, ConnectUiStyles.CONTEXT_MENU_BOX); - createContextMenu(boxCmp); - shell.addShellListener(new ActionsShellListener()); - } - - protected void createContextMenu(Composite boxCmp) { - ActionsSelListener asl = new ActionsSelListener(); - for (String actionId : defaultActions) { - Button btn = new Button(boxCmp, SWT.FLAT | SWT.LEAD); - btn.setText(getLabel(actionId)); - btn.setLayoutData(EclipseUiUtils.fillWidth()); - CmsUiUtils.markup(btn); -// CmsUiUtils.style(btn, actionId + ConnectUiStyles.BUTTON_SUFFIX); - btn.setData(KEY_ACTION_ID, actionId); - btn.addSelectionListener(asl); - actionButtons.put(actionId, btn); - } - } - - protected void setVisible(boolean visible, String... buttonIds) { - for (String id : buttonIds) { - Button button = actionButtons.get(id); - button.setVisible(visible); - GridData gd = (GridData) button.getLayoutData(); - gd.heightHint = visible ? SWT.DEFAULT : 0; - } - } - - public void show(Control source, Point location, IStructuredSelection selection) { - if (shell.isDisposed()) { - shell = new Shell(Display.getCurrent(), SWT.NO_TRIM | SWT.BORDER | SWT.ON_TOP); - createControl(); - } - if (shell.isVisible()) - shell.setVisible(false); - - if (aboutToShow(source, location, selection)) { - shell.pack(); - shell.layout(); - if (source instanceof Control) - shell.setLocation(((Control) source).toDisplay(location.x, location.y)); - shell.open(); - } - } - - protected Shell getParentShell() { - return parentShell; - } - - class StyleButton extends Label { - private static final long serialVersionUID = 7731102609123946115L; - - public StyleButton(Composite parent, int swtStyle) { - super(parent, swtStyle); - } - } - - class ActionsSelListener extends SelectionAdapter { - private static final long serialVersionUID = -1041871937815812149L; - - @Override - public void widgetSelected(SelectionEvent e) { - Object eventSource = e.getSource(); - if (eventSource instanceof Button) { - Button pressedBtn = (Button) eventSource; - performAction((String) pressedBtn.getData(KEY_ACTION_ID)); - shell.close(); - } - } - } - - class ActionsShellListener extends org.eclipse.swt.events.ShellAdapter { - private static final long serialVersionUID = -5092341449523150827L; - - @Override - public void shellDeactivated(ShellEvent e) { - setVisible(false); - shell.setVisible(false); - //shell.close(); - } - } - - protected abstract boolean performAction(String actionId); - - protected abstract boolean aboutToShow(Control source, Point location, IStructuredSelection selection); - - protected abstract String getLabel(String actionId); -} diff --git a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/widgets/ConnectAbstractDropDown.java b/core/org.argeo.suite.ui/src/org/argeo/suite/ui/widgets/ConnectAbstractDropDown.java deleted file mode 100644 index ffe733e..0000000 --- a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/widgets/ConnectAbstractDropDown.java +++ /dev/null @@ -1,194 +0,0 @@ -package org.argeo.suite.ui.widgets; - -import java.util.Arrays; -import java.util.List; - -import org.argeo.cms.ui.util.CmsUiUtils; -import org.argeo.eclipse.ui.EclipseUiUtils; -import org.eclipse.rap.rwt.widgets.DropDown; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.FocusEvent; -import org.eclipse.swt.events.FocusListener; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Text; -import org.eclipse.swt.widgets.Widget; - -/** - * Enable easy addition of a {@code DropDown} widget to a text with listeners - * configured - */ -public abstract class ConnectAbstractDropDown { - - private final Text text; - private final DropDown dropDown; - private boolean modifyFromList = false; - - // Current displayed text - private String userText = ""; - // Current displayed list items - private String[] values; - - // Fine tuning - boolean readOnly; - boolean refreshOnFocus; - - /** Implementing classes should call refreshValues() after initialisation */ - public ConnectAbstractDropDown(Text text) { - this(text, SWT.NONE, false); - } - - /** - * Implementing classes should call refreshValues() after initialisation - * - * @param text - * @param style - * only SWT.READ_ONLY is understood, check if the entered text is - * part of the legal choices. - */ - public ConnectAbstractDropDown(Text text, int style) { - this(text, style, false); - } - - /** - * Implementers should call refreshValues() once init has been done. - * - * @param text - * @param style - * only SWT.READ_ONLY is understood, check if the entered text is - * part of the legal choices. - * @param refreshOnFocus - * if true, the possible values are computed each time the focus is - * gained. It enables, among other to fine tune the getFilteredValues - * method depending on the current context - */ - public ConnectAbstractDropDown(Text text, int style, boolean refreshOnFocus) { - this.text = text; - dropDown = new DropDown(text); - Object obj = dropDown; - if (obj instanceof Widget) - CmsUiUtils.markup((Widget) obj); - readOnly = (style & SWT.READ_ONLY) != 0; - this.refreshOnFocus = refreshOnFocus; - addListeners(); - } - - /** - * Overwrite to force the refresh of the possible values on focus gained event - */ - protected boolean refreshOnFocus() { - return refreshOnFocus; - } - - public String getText() { - return text.getText(); - } - - public void init() { - refreshValues(); - } - - public void reset(String value) { - modifyFromList = true; - if (EclipseUiUtils.notEmpty(value)) - text.setText(value); - else - text.setText(""); - refreshValues(); - modifyFromList = false; - } - - /** Overwrite to provide specific filtering */ - protected abstract List getFilteredValues(String filter); - - protected void refreshValues() { - List filteredValues = getFilteredValues(text.getText()); - values = filteredValues.toArray(new String[filteredValues.size()]); - dropDown.setItems(values); - } - - protected void addListeners() { - addModifyListener(); - addSelectionListener(); - addDefaultSelectionListener(); - addFocusListener(); - } - - protected void addFocusListener() { - text.addFocusListener(new FocusListener() { - private static final long serialVersionUID = -7179112097626535946L; - - public void focusGained(FocusEvent event) { - if (refreshOnFocus) { - modifyFromList = true; - refreshValues(); - modifyFromList = false; - } - dropDown.setVisible(true); - } - - public void focusLost(FocusEvent event) { - dropDown.setVisible(false); - if (readOnly && values != null && !Arrays.asList(values).contains(userText)) { - modifyFromList = true; - text.setText(""); - refreshValues(); - modifyFromList = false; - } - } - }); - } - - private void addSelectionListener() { - Object obj = dropDown; - if (obj instanceof Widget) - ((Widget) obj).addListener(SWT.Selection, new Listener() { - private static final long serialVersionUID = -2357157809365135142L; - - public void handleEvent(Event event) { - if (event.index != -1) { - modifyFromList = true; - text.setText(values[event.index]); - modifyFromList = false; - text.selectAll(); - } else { - text.setText(userText); - text.setSelection(userText.length(), userText.length()); - text.setFocus(); - } - } - }); - } - - private void addDefaultSelectionListener() { - Object obj = dropDown; - if (obj instanceof Widget) - ((Widget) obj).addListener(SWT.DefaultSelection, new Listener() { - private static final long serialVersionUID = -5958008322630466068L; - - public void handleEvent(Event event) { - if (event.index != -1) { - text.setText(values[event.index]); - text.setSelection(event.text.length()); - dropDown.setVisible(false); - } - } - }); - } - - private void addModifyListener() { - text.addListener(SWT.Modify, new Listener() { - private static final long serialVersionUID = -4373972835244263346L; - - public void handleEvent(Event event) { - if (!modifyFromList) { - userText = text.getText(); - refreshValues(); - if (values.length == 1) - dropDown.setSelectionIndex(0); - dropDown.setVisible(true); - } - } - }); - } -} diff --git a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/widgets/DelayedText.java b/core/org.argeo.suite.ui/src/org/argeo/suite/ui/widgets/DelayedText.java deleted file mode 100644 index a03c250..0000000 --- a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/widgets/DelayedText.java +++ /dev/null @@ -1,127 +0,0 @@ -package org.argeo.suite.ui.widgets; - -import java.util.Timer; -import java.util.TimerTask; - -import org.eclipse.rap.rwt.service.ServerPushSession; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Text; - -/** - * Text that introduce a timer in the attached ModifyListener. - * - * Note that corresponding ModifyEvent will *NOT* be sent in the UI thread. - * Calling ModifierInstance must be implemented in consequence. Note also that - * this delayed text only manages one listener at a time. - * - */ -public class DelayedText { - final int delay; - private Object lock = new Object(); - private MyTimer timer = new MyTimer(DelayedText.this.toString()); - private ModifyListener delayedModifyListener; - private ServerPushSession pushSession; - - private Text text; - - private ModifyListener modifyListener = new ModifyListener() { - private static final long serialVersionUID = 1117506414462641980L; - - public void modifyText(ModifyEvent e) { - ModifyEvent delayedEvent = null; - synchronized (lock) { - if (delayedModifyListener != null) { - Event tmpEvent = new Event(); - tmpEvent.widget = text; - tmpEvent.display = e.display; - tmpEvent.data = e.data; - tmpEvent.time = e.time; - delayedEvent = new ModifyEvent(tmpEvent); - } - } - final ModifyEvent timerModifyEvent = delayedEvent; - - synchronized (timer) { - if (timer.timerTask != null) { - timer.timerTask.cancel(); - timer.timerTask = null; - } - - if (delayedEvent != null) { - timer.timerTask = new TimerTask() { - public void run() { - synchronized (lock) { - delayedModifyListener.modifyText(timerModifyEvent); - // Bad approach: it is not a good idea to put a - // display.asyncExec in a lock... - // DelayedText.this.getDisplay().asyncExec(new - // Runnable() { - // @Override - // public void run() { - // delayedModifyListener.modifyText(timerModifyEvent); - // } - // } - // ); - } - synchronized (timer) { - timer.timerTask = null; - } - } - }; - timer.schedule(timer.timerTask, delay); - if (pushSession != null) - pushSession.start(); - } - } - }; - }; - - public DelayedText(Composite parent, int style, int delayInMs) { - // super(parent, style); - text = new Text(parent, style); - this.delay = delayInMs; - text.addModifyListener(modifyListener); - } - - /** - * Adds a modify text listener that will be delayed. If another Modify event - * happens during the waiting delay, the older event will be canceled an a new - * one will be scheduled after another new delay. - */ - public void addDelayedModifyListener(ServerPushSession pushSession, ModifyListener listener) { - synchronized (lock) { - delayedModifyListener = listener; - this.pushSession = pushSession; - } - } - - public void removeDelayedModifyListener(ModifyListener listener) { - synchronized (lock) { - delayedModifyListener = null; - pushSession = null; - } - } - - private class MyTimer extends Timer { - private TimerTask timerTask = null; - - public MyTimer(String name) { - super(name); - } - } - - public Text getText() { - return text; - } - - public void close() { - if (pushSession != null) - pushSession.stop(); - if (timer != null) - timer.cancel(); - }; - -} diff --git a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/widgets/TabbedArea.java b/core/org.argeo.suite.ui/src/org/argeo/suite/ui/widgets/TabbedArea.java deleted file mode 100644 index c281904..0000000 --- a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/widgets/TabbedArea.java +++ /dev/null @@ -1,256 +0,0 @@ -package org.argeo.suite.ui.widgets; - -import java.util.ArrayList; -import java.util.List; - -import javax.jcr.Node; - -import org.argeo.cms.ui.CmsUiProvider; -import org.argeo.cms.ui.util.CmsUiUtils; -import org.argeo.cms.ui.viewers.Section; -import org.argeo.eclipse.ui.Selected; -import org.argeo.jcr.Jcr; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.StackLayout; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.ToolBar; -import org.eclipse.swt.widgets.ToolItem; - -/** Manages {@link Section} in a tab-like structure. */ -public class TabbedArea extends Composite { - private static final long serialVersionUID = 8659669229482033444L; - - private Composite headers; - private Composite body; - - private List
sections = new ArrayList<>(); - - private Node previousNode; - private CmsUiProvider previousUiProvider; - private CmsUiProvider currentUiProvider; - - private String tabStyle; - private String tabSelectedStyle; - private String bodyStyle; - private Image closeIcon; - - private StackLayout stackLayout; - - private boolean singleTab = false; - - public TabbedArea(Composite parent, int style) { - super(parent, SWT.NONE); - CmsUiUtils.style(parent, bodyStyle); - - setLayout(CmsUiUtils.noSpaceGridLayout()); - - // TODO manage tabs at bottom or sides - headers = new Composite(this, SWT.NONE); - headers.setLayoutData(CmsUiUtils.fillWidth()); - body = new Composite(this, SWT.NONE); - body.setLayoutData(CmsUiUtils.fillAll()); - // body.setLayout(new FormLayout()); - stackLayout = new StackLayout(); - body.setLayout(stackLayout); - emptyState(); - } - - protected void refreshTabHeaders() { - int tabCount = sections.size() > 0 ? sections.size() : 1; - for (Control tab : headers.getChildren()) - tab.dispose(); - - headers.setLayout(CmsUiUtils.noSpaceGridLayout(new GridLayout(tabCount, true))); - - if (sections.size() == 0) { - Composite emptyHeader = new Composite(headers, SWT.NONE); - emptyHeader.setLayoutData(CmsUiUtils.fillAll()); - emptyHeader.setLayout(new GridLayout()); - Label lbl = new Label(emptyHeader, SWT.NONE); - lbl.setText(""); - lbl.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false)); - - } - - Section currentSection = getCurrentSection(); - for (Section section : sections) { - boolean selected = section == currentSection; - Composite sectionHeader = section.createHeader(headers); - CmsUiUtils.style(sectionHeader, selected ? tabSelectedStyle : tabStyle); - int headerColumns = singleTab ? 1 : 2; - sectionHeader.setLayout(new GridLayout(headerColumns, false)); - sectionHeader.setLayout(CmsUiUtils.noSpaceGridLayout(headerColumns)); - Button title = new Button(sectionHeader, SWT.FLAT); - CmsUiUtils.style(title, selected ? tabSelectedStyle : tabStyle); - title.setLayoutData(CmsUiUtils.fillWidth()); - title.addSelectionListener((Selected) (e) -> showTab(tabIndex(section.getNode()))); - Node node = section.getNode(); - String titleStr = Jcr.getTitle(node); - // TODO internationalize - title.setText(titleStr); - if (!singleTab) { - ToolBar toolBar = new ToolBar(sectionHeader, SWT.NONE); - ToolItem closeItem = new ToolItem(toolBar, SWT.FLAT); - if (closeIcon != null) - closeItem.setImage(closeIcon); - else - closeItem.setText("X"); - CmsUiUtils.style(closeItem, selected ? tabSelectedStyle : tabStyle); - closeItem.addSelectionListener((Selected) (e) -> closeTab(section)); - } - } - - } - - public void view(CmsUiProvider uiProvider, Node context) { - if (body.isDisposed()) - return; - int index = tabIndex(context); - if (index >= 0) { - showTab(index); - previousNode = context; - previousUiProvider = uiProvider; - return; - } - Section section = (Section) body.getChildren()[0]; - previousNode = section.getNode(); - if (previousNode == null) {// empty state - previousNode = context; - previousUiProvider = uiProvider; - } else { - previousUiProvider = currentUiProvider; - } - currentUiProvider = uiProvider; - section.setNode(context); - // section.setLayoutData(CmsUiUtils.coverAll()); - build(section, uiProvider, context); - if (sections.size() == 0) - sections.add(section); - refreshTabHeaders(); - index = tabIndex(context); - showTab(index); - layout(true, true); - } - - public void open(CmsUiProvider uiProvider, Node context) { - if (singleTab) - throw new UnsupportedOperationException("Open is not supported in single tab mode."); - - if (previousNode != null && Jcr.getIdentifier(previousNode).equals(Jcr.getIdentifier(context))) { - // does nothing - return; - } - if (sections.size() == 0) - CmsUiUtils.clear(body); - Section currentSection = getCurrentSection(); - int currentIndex = sections.indexOf(currentSection); - Section previousSection = new Section(body, SWT.NONE, context); - build(previousSection, previousUiProvider, previousNode); - // previousSection.setLayoutData(CmsUiUtils.coverAll()); - int index = currentIndex + 1; - sections.add(index, previousSection); - showTab(index); - refreshTabHeaders(); - layout(true, true); - } - - public void showTab(int index) { - Section sectionToShow = sections.get(index); - // sectionToShow.moveAbove(null); - stackLayout.topControl = sectionToShow; - refreshTabHeaders(); - layout(true, true); - } - - protected void build(Section section, CmsUiProvider uiProvider, Node context) { - for (Control child : section.getChildren()) - child.dispose(); - CmsUiUtils.style(section, bodyStyle); - section.setNode(context); - uiProvider.createUiPart(section, context); - - } - - private int tabIndex(Node node) { - for (int i = 0; i < sections.size(); i++) { - Section section = sections.get(i); - if (Jcr.getIdentifier(section.getNode()).equals(Jcr.getIdentifier(node))) - return i; - } - return -1; - } - - public void closeTab(Section section) { - int currentIndex = sections.indexOf(section); - int nextIndex = currentIndex == 0 ? 0 : currentIndex - 1; - sections.remove(section); - section.dispose(); - if (sections.size() == 0) { - emptyState(); - refreshTabHeaders(); - layout(true, true); - return; - } - refreshTabHeaders(); - showTab(nextIndex); - } - - public void closeAllTabs() { - for(Section section:sections) { - section.dispose(); - } - sections.clear(); - emptyState(); - refreshTabHeaders(); - layout(true, true); - } - - protected void emptyState() { - new Section(body, SWT.NONE, null); - refreshTabHeaders(); - } - - public Composite getCurrent() { - return getCurrentSection(); - } - - protected Section getCurrentSection() { - return (Section) stackLayout.topControl; - } - - public Node getCurrentContext() { - Section section = getCurrentSection(); - if (section != null) { - return section.getNode(); - } else { - return null; - } - } - - public void setTabStyle(String tabStyle) { - this.tabStyle = tabStyle; - } - - public void setTabSelectedStyle(String tabSelectedStyle) { - this.tabSelectedStyle = tabSelectedStyle; - } - - public void setBodyStyle(String bodyStyle) { - this.bodyStyle = bodyStyle; - } - - public void setCloseIcon(Image closeIcon) { - this.closeIcon = closeIcon; - } - - public void setSingleTab(boolean singleTab) { - this.singleTab = singleTab; - } - -} diff --git a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/widgets/TreeOrSearchArea.java b/core/org.argeo.suite.ui/src/org/argeo/suite/ui/widgets/TreeOrSearchArea.java deleted file mode 100644 index 3434ed5..0000000 --- a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/widgets/TreeOrSearchArea.java +++ /dev/null @@ -1,74 +0,0 @@ -package org.argeo.suite.ui.widgets; - -import org.argeo.cms.ui.util.CmsUiUtils; -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.StackLayout; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Text; - -/** - * Displays a tree by default, which becomes a list if the search text field is - * used. - */ -public class TreeOrSearchArea extends Composite { - private static final long serialVersionUID = -1302546480076719532L; - - private Text searchT; - private StackLayout bodyLayout; - - private TreeViewer treeViewer; - private TreeViewer searchResultsViewer; - - public TreeOrSearchArea(Composite parent, int style) { - super(parent, style); - createUi(this); - } - - protected void createUi(Composite parent) { - parent.setLayout(new GridLayout()); - Composite searchC = new Composite(parent, SWT.NONE); - searchC.setLayout(new GridLayout()); - searchC.setLayoutData(CmsUiUtils.fillWidth()); - createSearchUi(searchC); - - Composite bodyC = new Composite(parent, SWT.NONE); - bodyC.setLayoutData(CmsUiUtils.fillAll()); - bodyLayout = new StackLayout(); - bodyC.setLayout(bodyLayout); - Composite treeC = new Composite(bodyC, SWT.NONE); - createTreeUi(treeC); - Composite searchResultsC = new Composite(bodyC, SWT.NONE); - createSearchResultsUi(searchResultsC); - - bodyLayout.topControl = treeC; - } - - protected void createSearchUi(Composite parent) { - parent.setLayout(CmsUiUtils.noSpaceGridLayout()); - searchT = new Text(parent, SWT.MULTI | SWT.BORDER); - searchT.setLayoutData(CmsUiUtils.fillWidth()); - } - - protected void createTreeUi(Composite parent) { - parent.setLayout(CmsUiUtils.noSpaceGridLayout()); - treeViewer = new TreeViewer(parent); - treeViewer.getTree().setLayoutData(CmsUiUtils.fillAll()); - } - - protected void createSearchResultsUi(Composite parent) { - parent.setLayout(CmsUiUtils.noSpaceGridLayout()); - searchResultsViewer = new TreeViewer(parent); - searchResultsViewer.getTree().setLayoutData(CmsUiUtils.fillAll()); - } - - public TreeViewer getTreeViewer() { - return treeViewer; - } - - public TreeViewer getSearchResultsViewer() { - return searchResultsViewer; - } - -} diff --git a/core/pom.xml b/core/pom.xml deleted file mode 100644 index 1ddbfc5..0000000 --- a/core/pom.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - 4.0.0 - - org.argeo.suite - argeo-suite - 2.3-SNAPSHOT - .. - - core - Argeo Core Components - pom - - - org.argeo.entity.api - org.argeo.entity.core - org.argeo.entity.ui - - - org.argeo.suite.core - org.argeo.suite.ui - org.argeo.suite.ui.rap - org.argeo.suite.theme.default - - diff --git a/environment/.gitignore b/environment/.gitignore deleted file mode 100644 index b83d222..0000000 --- a/environment/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target/ diff --git a/environment/cnf/maven.bnd b/environment/cnf/maven.bnd deleted file mode 100644 index 4bd5c0c..0000000 --- a/environment/cnf/maven.bnd +++ /dev/null @@ -1 +0,0 @@ --include: ../../cnf/maven.bnd \ No newline at end of file diff --git a/environment/org.argeo.geo.ui/.classpath b/environment/org.argeo.geo.ui/.classpath deleted file mode 100644 index e801ebf..0000000 --- a/environment/org.argeo.geo.ui/.classpath +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/environment/org.argeo.geo.ui/.gitignore b/environment/org.argeo.geo.ui/.gitignore deleted file mode 100644 index 09e3bc9..0000000 --- a/environment/org.argeo.geo.ui/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/bin/ -/target/ diff --git a/environment/org.argeo.geo.ui/.project b/environment/org.argeo.geo.ui/.project deleted file mode 100644 index a25e06f..0000000 --- a/environment/org.argeo.geo.ui/.project +++ /dev/null @@ -1,33 +0,0 @@ - - - org.argeo.geo.ui - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - org.eclipse.pde.ds.core.builder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - diff --git a/environment/org.argeo.geo.ui/META-INF/.gitignore b/environment/org.argeo.geo.ui/META-INF/.gitignore deleted file mode 100644 index 4854a41..0000000 --- a/environment/org.argeo.geo.ui/META-INF/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/MANIFEST.MF diff --git a/environment/org.argeo.geo.ui/OSGI-INF/l10n/bundle.properties b/environment/org.argeo.geo.ui/OSGI-INF/l10n/bundle.properties deleted file mode 100644 index 3ded5eb..0000000 --- a/environment/org.argeo.geo.ui/OSGI-INF/l10n/bundle.properties +++ /dev/null @@ -1 +0,0 @@ -map=map diff --git a/environment/org.argeo.geo.ui/OSGI-INF/mapLayer.xml b/environment/org.argeo.geo.ui/OSGI-INF/mapLayer.xml deleted file mode 100644 index 7cf8487..0000000 --- a/environment/org.argeo.geo.ui/OSGI-INF/mapLayer.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/environment/org.argeo.geo.ui/OSGI-INF/overviewMap.xml b/environment/org.argeo.geo.ui/OSGI-INF/overviewMap.xml deleted file mode 100644 index c75200a..0000000 --- a/environment/org.argeo.geo.ui/OSGI-INF/overviewMap.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/environment/org.argeo.geo.ui/bnd.bnd b/environment/org.argeo.geo.ui/bnd.bnd deleted file mode 100644 index 4fdb49b..0000000 --- a/environment/org.argeo.geo.ui/bnd.bnd +++ /dev/null @@ -1,17 +0,0 @@ -Import-Package:\ -javax.jcr.nodetype,\ -org.osgi.service.event,\ -com.fasterxml.jackson.core,\ -org.argeo.suite.ui,\ -org.argeo.api,\ -org.eclipse.swt,\ -org.eclipse.jface.viewers,\ -org.osgi.framework,\ -* - -Service-Component:\ -OSGI-INF/mapLayer.xml,\ -OSGI-INF/overviewMap.xml - -Provide-Capability:\ -cms.publish;pkg=org.djapps.on.openheritage.ui,file="*.png,*.js,*.html" \ No newline at end of file diff --git a/environment/org.argeo.geo.ui/build.properties b/environment/org.argeo.geo.ui/build.properties deleted file mode 100644 index 34d2e4d..0000000 --- a/environment/org.argeo.geo.ui/build.properties +++ /dev/null @@ -1,4 +0,0 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . diff --git a/environment/org.argeo.geo.ui/config/mapLayer.properties b/environment/org.argeo.geo.ui/config/mapLayer.properties deleted file mode 100644 index 37bf3c7..0000000 --- a/environment/org.argeo.geo.ui/config/mapLayer.properties +++ /dev/null @@ -1,6 +0,0 @@ -service.pid=argeo.geo.ui.mapLayer - -title=%map -icon=map - -entity.type=entity:geopoint diff --git a/environment/org.argeo.geo.ui/config/overviewMap.properties b/environment/org.argeo.geo.ui/config/overviewMap.properties deleted file mode 100644 index d842c98..0000000 --- a/environment/org.argeo.geo.ui/config/overviewMap.properties +++ /dev/null @@ -1 +0,0 @@ -service.pid=argeo.geo.ui.overviewMap diff --git a/environment/org.argeo.geo.ui/pom.xml b/environment/org.argeo.geo.ui/pom.xml deleted file mode 100644 index f820ca1..0000000 --- a/environment/org.argeo.geo.ui/pom.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - 4.0.0 - - org.argeo.suite - environment - 2.3-SNAPSHOT - .. - - org.argeo.geo.ui - Geography UI - jar - - - org.argeo.suite - org.argeo.suite.ui - 2.3-SNAPSHOT - - - - - org.argeo.tp - argeo-tp-rap-e4 - ${version.argeo-tp} - pom - provided - - - - org.argeo.commons - org.argeo.eclipse.ui.rap - ${version.argeo-commons} - provided - - - - diff --git a/environment/org.argeo.geo.ui/src/org/argeo/geo/GeoJsonUtils.java b/environment/org.argeo.geo.ui/src/org/argeo/geo/GeoJsonUtils.java deleted file mode 100644 index 0d58480..0000000 --- a/environment/org.argeo.geo.ui/src/org/argeo/geo/GeoJsonUtils.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.argeo.geo; - -import java.util.Map; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ObjectNode; - -/** Geo data utilities. */ -public class GeoJsonUtils { - - /** Add these properties to all features. */ - public static void addProperties(JsonNode tree, Map map) { - for (JsonNode feature : tree.get("features")) { - ObjectNode properties = (ObjectNode) feature.get("properties"); - for (String key : map.keySet()) { - properties.put(key, map.get(key)); - } - } - } - - /** Singleton. */ - private GeoJsonUtils() { - } -} diff --git a/environment/org.argeo.geo.ui/src/org/argeo/geo/GeoToSvg.java b/environment/org.argeo.geo.ui/src/org/argeo/geo/GeoToSvg.java deleted file mode 100644 index 4d593f2..0000000 --- a/environment/org.argeo.geo.ui/src/org/argeo/geo/GeoToSvg.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.argeo.geo; - -import java.io.IOException; -import java.io.InputStream; -import java.io.Writer; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; - -/** Converts a geographical feature to an SVG. */ -public class GeoToSvg { - public void convertGeoJsonToSvg(Path source, Path target) { - ObjectMapper objectMapper = new ObjectMapper(); - try (InputStream in = Files.newInputStream(source); - Writer out = Files.newBufferedWriter(target, StandardCharsets.UTF_8)) { - JsonNode tree = objectMapper.readTree(in); - JsonNode coord = tree.get("features").get(0).get("geometry").get("coordinates"); - double ratio = 100; - double minX = Double.POSITIVE_INFINITY; - double maxX = Double.NEGATIVE_INFINITY; - double minY = Double.POSITIVE_INFINITY; - double maxY = Double.NEGATIVE_INFINITY; - List shapes = new ArrayList<>(); - for (JsonNode shape : coord) { - StringBuffer sb = new StringBuffer(); - sb.append(" maxY) - maxY = y; - double lng = latlng.get(1).asDouble(); - double x = lng * ratio; - if (x < minX) - minX = x; - if (x > maxX) - maxX = x; - sb.append(y + "," + x + " "); - } - sb.append("\">"); - sb.append("\n"); - shapes.add(sb.toString()); - } - - double width = maxX - minX; - double height = maxY - minY; - out.write("\n"); - for (String shape : shapes) { - out.write(shape); - out.write("\n"); - } - out.write(""); - } catch (IOException e) { - throw new RuntimeException("Cannot convert " + source + " to " + target, e); - } - } - -} diff --git a/environment/org.argeo.geo.ui/src/org/argeo/support/openlayers/OLMap.java b/environment/org.argeo.geo.ui/src/org/argeo/support/openlayers/OLMap.java deleted file mode 100644 index ac104c6..0000000 --- a/environment/org.argeo.geo.ui/src/org/argeo/support/openlayers/OLMap.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.argeo.support.openlayers; - -import org.argeo.cms.ui.util.CmsUiUtils; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; - -public class OLMap extends Composite { - private Label div; - - public OLMap(Composite parent, int style) { - super(parent, style); - setLayout(CmsUiUtils.noSpaceGridLayout()); - div = new Label(this, SWT.NONE); - CmsUiUtils.markup(div); - CmsUiUtils.disableMarkupValidation(div); - div.setText("
"); - div.setLayoutData(CmsUiUtils.fillAll()); - } - -} diff --git a/environment/org.argeo.geo.ui/src/org/argeo/support/openlayers/OpenLayersMap.java b/environment/org.argeo.geo.ui/src/org/argeo/support/openlayers/OpenLayersMap.java deleted file mode 100644 index 5357149..0000000 --- a/environment/org.argeo.geo.ui/src/org/argeo/support/openlayers/OpenLayersMap.java +++ /dev/null @@ -1,301 +0,0 @@ -package org.argeo.support.openlayers; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; - -import org.apache.commons.io.IOUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.api.NodeConstants; -import org.argeo.cms.ui.CmsView; -import org.argeo.cms.ui.util.CmsUiUtils; -import org.argeo.entity.EntityNames; -import org.argeo.entity.EntityType; -import org.argeo.suite.ui.SuiteEvent; -import org.eclipse.swt.SWT; -import org.eclipse.swt.browser.Browser; -import org.eclipse.swt.browser.BrowserFunction; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; - -/** Display a map. */ -public class OpenLayersMap extends Composite { - private static final long serialVersionUID = 1055893020490283622L; - - private final static Log log = LogFactory.getLog(OpenLayersMap.class); - - private Browser browser; - private boolean renderCompleted = false; - - private Double centerLng = null, centerLat = null; - private Integer zoom = null; - private String vectorSource = null; - private String gpxSource = null; - - private String vectorSourceStyle; - - private List geoJsonSources = new ArrayList<>(); - private Map vectorSources = new HashMap<>(); - private Map layerStyles = new HashMap<>(); - - private CmsView cmsView; - - public OpenLayersMap(Composite parent, int style, URL mapHtml) { - super(parent, style); - cmsView = CmsView.getCmsView(parent); - setLayout(new GridLayout()); - - browser = new Browser(this, SWT.BORDER); - browser.setLayoutData(CmsUiUtils.fillAll()); - String html; - try (InputStream in = mapHtml.openStream()) { - html = IOUtils.toString(in, StandardCharsets.UTF_8); - } catch (IOException e) { - throw new RuntimeException(e); - } - new RenderCompleted(browser, "renderCompleted"); - new OnFeatureSelect(browser, "onFeatureSelect"); - new OnFeatureUnselect(browser, "onFeatureUnselect"); - new OnFeatureClick(browser, "onFeatureClick"); - browser.setText(html); - } - - public void setCenter(Double lng, Double lat) { - if (isRenderCompleted()) - browser.evaluate("map.getView().setCenter(ol.proj.fromLonLat([" + lng + ", " + lat + "]))"); - this.centerLat = lat; - this.centerLng = lng; - } - - public synchronized void setRenderCompleted(boolean renderCompleted) { - this.renderCompleted = renderCompleted; - notifyAll(); - } - - public synchronized boolean isRenderCompleted() { - return renderCompleted; - } - - @Override - public synchronized void dispose() { - long timeout = 500; - long begin = System.currentTimeMillis(); - while (!isRenderCompleted() && ((System.currentTimeMillis() - begin) < timeout)) { - try { - wait(50); - } catch (InterruptedException e) { - // silent - } - } - super.dispose(); - } - - public void setZoom(int zoom) { - if (isRenderCompleted()) - browser.evaluate("map.getView().setZoom(" + zoom + ")"); - this.zoom = zoom; - } - - protected String asVectorSource(List geoPoints) throws RepositoryException { - boolean first = true; - StringBuffer sb = new StringBuffer("new ol.source.Vector({ features: ["); - for (int i = 0; i < geoPoints.size(); i++) { - Node node = geoPoints.get(i); - if (node.isNodeType(EntityType.geopoint.get())) { - if (first) - first = false; - else - sb.append(","); - Double lng = node.getProperty(EntityNames.GEO_LONG).getDouble(); - Double lat = node.getProperty(EntityNames.GEO_LAT).getDouble(); - sb.append("new ol.Feature({ geometry:"); - sb.append("new ol.geom.Point(ol.proj.fromLonLat(["); - sb.append(lng).append(',').append(lat); - sb.append("]))"); - sb.append(",path:\"").append(node.getPath()).append("\""); - sb.append(",name:\"").append(node.getName()).append("\""); - String entityType = null; - if (node.isNodeType(EntityType.local.get())) { - entityType = node.getProperty(EntityNames.ENTITY_TYPE).getString(); - sb.append(", type:'").append(entityType).append("'"); - } - sb.append("})"); - } - } - sb.append("]"); - sb.append(" })"); - return sb.toString(); - } - - public void addPoints(List geoPoints) throws RepositoryException { - this.vectorSource = asVectorSource(geoPoints); - if (log.isTraceEnabled()) - log.trace("Vector source: " + vectorSource); - renderVectorSource(); - } - - public void addPoints(String layerName, List geoPoints, String style) throws RepositoryException { - this.vectorSources.put(layerName, asVectorSource(geoPoints)); - if (style != null) { - layerStyles.put(layerName, style); - } - renderVectorSources(); - } - - protected void renderVectorSource() { - if (vectorSource == null) - return; - if (isRenderCompleted()) { -// String style = ", style: new ol.style.Style({ image: new ol.style.Icon({ src: '/pkg/org.djapps.on.openheritage.ui/map_oc.png' }) })"; - String style = vectorSourceStyle != null ? ", style: " + vectorSourceStyle : ""; -// String style = ""; - String toEvaluate = "map.addLayer(new ol.layer.Vector({ source: " + vectorSource + style + "}));"; -// System.out.println(toEvaluate); - browser.execute(toEvaluate); - } - } - - protected void renderVectorSources() { - if (vectorSources.isEmpty()) - return; - if (isRenderCompleted()) { - StringBuilder toExecute = new StringBuilder(); - for (String name : vectorSources.keySet()) { - String style = layerStyles.containsKey(name) ? ", style: " + layerStyles.get(name) : ""; - String toEvaluate = "map.addLayer(new ol.layer.Vector({ source: " + vectorSources.get(name) + style - + ",name: '" + name + "'}));"; - toExecute.append(toEvaluate); - } - System.out.println(toExecute); - browser.execute(toExecute.toString()); - } - } - - public void addPoint(Double lng, Double lat) { - this.vectorSource = "new ol.source.Vector({ features: [ new ol.Feature({ geometry:" - + " new ol.geom.Point(ol.proj.fromLonLat([" + lng + ", " + lat + "])) }) ] })"; -// if (renderCompleted) { -// browser.evaluate( -// "map.addLayer(new ol.layer.Vector({ source: new ol.source.Vector({ features: [ new ol.Feature({ geometry:" -// + " new ol.geom.Point(ol.proj.fromLonLat([" + lng + ", " + lat + "])) }) ] }) }));"); -// } - renderVectorSource(); - } - - public void addGpx(String path) { - this.gpxSource = "new ol.source.Vector({ url: '" + path + "', format: new ol.format.GPX() })"; - renderGpxSource(); - } - - protected void renderGpxSource() { - if (gpxSource == null) - return; - if (isRenderCompleted()) - browser.evaluate("map.addLayer(new ol.layer.Vector({ source: " + gpxSource + "}));"); - } - - public void addGeoJson(String path) { - String geoJsonSource = "new ol.source.Vector({ url: '" + path + "', format: new ol.format.GeoJSON() })"; - geoJsonSources.add(geoJsonSource); - renderGeoJsonSources(); - } - - protected void renderGeoJsonSources() { - if (geoJsonSources.isEmpty()) - return; - if (isRenderCompleted()) { - for (String geoJson : geoJsonSources) { - browser.evaluate("map.addLayer(new ol.layer.Vector({ source: " + geoJson + "}));"); - } - } - } - - public void setVectorSourceStyle(String vectorSourceStyle) { - this.vectorSourceStyle = vectorSourceStyle; - } - - private class RenderCompleted extends BrowserFunction { - - RenderCompleted(Browser browser, String name) { - super(browser, name); - } - - @Override - public Object function(Object[] arguments) { - try { - if (!isRenderCompleted()) { - setRenderCompleted(true); - if (zoom != null) - setZoom(zoom); - if (centerLat != null && centerLng != null) { - setCenter(centerLng, centerLat); - } - if (!geoJsonSources.isEmpty()) - renderGeoJsonSources(); - if (gpxSource != null) - renderGpxSource(); - if (vectorSource != null) - renderVectorSource(); - if (!vectorSources.isEmpty()) - renderVectorSources(); - } - return null; - } catch (Exception e) { - log.error("Cannot render map", e); - return null; - } - } - } - - private class OnFeatureSelect extends BrowserFunction { - - OnFeatureSelect(Browser browser, String name) { - super(browser, name); - } - - @Override - public Object function(Object[] arguments) { - if (arguments.length == 0) - return null; - String path = arguments[0].toString(); - Map properties = new HashMap<>(); - properties.put(SuiteEvent.NODE_PATH, path); - properties.put(SuiteEvent.WORKSPACE, NodeConstants.SYS_WORKSPACE); - cmsView.sendEvent(SuiteEvent.refreshPart.topic(), properties); - return null; - } - } - - private class OnFeatureUnselect extends BrowserFunction { - - OnFeatureUnselect(Browser browser, String name) { - super(browser, name); - } - - @Override - public Object function(Object[] arguments) { - return null; - } - } - - private class OnFeatureClick extends BrowserFunction { - - OnFeatureClick(Browser browser, String name) { - super(browser, name); - } - - @Override - public Object function(Object[] arguments) { - return null; - } - } -} diff --git a/environment/org.argeo.geo.ui/src/org/argeo/support/openlayers/OverviewMap.java b/environment/org.argeo.geo.ui/src/org/argeo/support/openlayers/OverviewMap.java deleted file mode 100644 index b2fd01e..0000000 --- a/environment/org.argeo.geo.ui/src/org/argeo/support/openlayers/OverviewMap.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.argeo.support.openlayers; - -import java.util.List; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; -import javax.jcr.observation.Event; -import javax.jcr.observation.EventIterator; -import javax.jcr.observation.EventListener; -import javax.jcr.query.Query; - -import org.argeo.cms.ui.CmsUiProvider; -import org.argeo.cms.ui.util.CmsUiUtils; -import org.argeo.entity.EntityType; -import org.argeo.jcr.JcrException; -import org.argeo.jcr.JcrUtils; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; - -/** Displays an overview map. */ -public class OverviewMap implements CmsUiProvider { - - @Override - public Control createUi(Composite parent, Node context) throws RepositoryException { - parent.setLayout(new GridLayout()); - refreshUi(parent, context); - - try { - String[] nodeTypes = { EntityType.geopoint.get() }; - context.getSession().getWorkspace().getObservationManager().addEventListener(new EventListener() { - - @Override - public void onEvent(EventIterator events) { - if (!parent.isDisposed()) - parent.getDisplay().asyncExec(() -> { - try { - refreshUi(parent, context); - } catch (RepositoryException e) { - throw new JcrException(e); - } - }); - } - }, Event.PROPERTY_CHANGED | Event.NODE_ADDED | Event.NODE_REMOVED | Event.PROPERTY_ADDED, "/", true, null, - nodeTypes, false); - } catch (RepositoryException e) { - throw new IllegalStateException("Cannot add JCR observer", e); - } - - return parent; - } - - protected void refreshUi(Composite parent, Node context) throws RepositoryException { - CmsUiUtils.clear(parent); - Query query = context.getSession().getWorkspace().getQueryManager() - .createQuery("SELECT * FROM [" + EntityType.geopoint.get() + "]", Query.JCR_SQL2); - List geoPoints = JcrUtils.nodeIteratorToList(query.execute().getNodes()); - OpenLayersMap map = new OpenLayersMap(parent, SWT.NONE, getClass().getResource("map-osm.html")); - map.setLayoutData(CmsUiUtils.fillAll()); - - // apafMap.setZoom(7); - // apafMap.setCenter(-2.472, 8.010); - map.addPoints(geoPoints); - } -} diff --git a/environment/org.argeo.geo.ui/src/org/argeo/support/openlayers/map-osm.html b/environment/org.argeo.geo.ui/src/org/argeo/support/openlayers/map-osm.html deleted file mode 100644 index 157d708..0000000 --- a/environment/org.argeo.geo.ui/src/org/argeo/support/openlayers/map-osm.html +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - -
- - - \ No newline at end of file diff --git a/environment/org.argeo.geo.ui/src/org/argeo/support/openlayers/map.js b/environment/org.argeo.geo.ui/src/org/argeo/support/openlayers/map.js deleted file mode 100644 index 68489fb..0000000 --- a/environment/org.argeo.geo.ui/src/org/argeo/support/openlayers/map.js +++ /dev/null @@ -1,11 +0,0 @@ -var map = new ol.Map({ - target : 'map', - layers : [ new ol.layer.Tile({ - source : new ol.source.OSM() - }) ], - view : new ol.View({ - center : ol.proj.fromLonLat([ 34, 34 ]), - zoom : 4 - }) -}); - \ No newline at end of file diff --git a/environment/pom.xml b/environment/pom.xml deleted file mode 100644 index e972862..0000000 --- a/environment/pom.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - 4.0.0 - - org.argeo.suite - argeo-suite - 2.3-SNAPSHOT - .. - - environment - Argeo Environment Components - pom - - org.argeo.geo.ui - - diff --git a/knowledge/.gitignore b/knowledge/.gitignore deleted file mode 100644 index b83d222..0000000 --- a/knowledge/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target/ diff --git a/knowledge/cnf/maven.bnd b/knowledge/cnf/maven.bnd deleted file mode 100644 index 4bd5c0c..0000000 --- a/knowledge/cnf/maven.bnd +++ /dev/null @@ -1 +0,0 @@ --include: ../../cnf/maven.bnd \ No newline at end of file diff --git a/knowledge/org.argeo.support.geonames/.classpath b/knowledge/org.argeo.support.geonames/.classpath deleted file mode 100644 index e801ebf..0000000 --- a/knowledge/org.argeo.support.geonames/.classpath +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/knowledge/org.argeo.support.geonames/.gitignore b/knowledge/org.argeo.support.geonames/.gitignore deleted file mode 100644 index 09e3bc9..0000000 --- a/knowledge/org.argeo.support.geonames/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/bin/ -/target/ diff --git a/knowledge/org.argeo.support.geonames/.project b/knowledge/org.argeo.support.geonames/.project deleted file mode 100644 index 3c8181f..0000000 --- a/knowledge/org.argeo.support.geonames/.project +++ /dev/null @@ -1,28 +0,0 @@ - - - org.argeo.support.geonames - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - diff --git a/knowledge/org.argeo.support.geonames/META-INF/.gitignore b/knowledge/org.argeo.support.geonames/META-INF/.gitignore deleted file mode 100644 index 4854a41..0000000 --- a/knowledge/org.argeo.support.geonames/META-INF/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/MANIFEST.MF diff --git a/knowledge/org.argeo.support.geonames/bnd.bnd b/knowledge/org.argeo.support.geonames/bnd.bnd deleted file mode 100644 index e69de29..0000000 diff --git a/knowledge/org.argeo.support.geonames/build.properties b/knowledge/org.argeo.support.geonames/build.properties deleted file mode 100644 index 34d2e4d..0000000 --- a/knowledge/org.argeo.support.geonames/build.properties +++ /dev/null @@ -1,4 +0,0 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . diff --git a/knowledge/org.argeo.support.geonames/pom.xml b/knowledge/org.argeo.support.geonames/pom.xml deleted file mode 100644 index 4352219..0000000 --- a/knowledge/org.argeo.support.geonames/pom.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - 4.0.0 - - org.argeo.suite - knowledge - 2.3-SNAPSHOT - .. - - org.argeo.support.geonames - Geonames support - jar - - - org.argeo.commons - org.argeo.cms - ${version.argeo-commons} - - - diff --git a/knowledge/org.argeo.support.geonames/src/org/argeo/support/geonames/GeonamesAdm.java b/knowledge/org.argeo.support.geonames/src/org/argeo/support/geonames/GeonamesAdm.java deleted file mode 100644 index d578272..0000000 --- a/knowledge/org.argeo.support.geonames/src/org/argeo/support/geonames/GeonamesAdm.java +++ /dev/null @@ -1,157 +0,0 @@ -package org.argeo.support.geonames; - -import java.time.LocalDate; -import java.time.ZoneId; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.function.Function; - -/** A Geonames administrative subdivision. */ -public class GeonamesAdm { - private final Long geonameId; - private final String countryCode; - private final String adminCode1; - private final String admLevel; - private final Integer level; - private final String name; - private final String asciiName; - private final List alternateNames; - private final Double lat; - private final Double lng; - private final LocalDate lastUpdated; - private final ZoneId timeZone; - - private final Long[] upperLevelIds = new Long[5]; - private final List upperLevels = new ArrayList<>(); - - private List row; - - /** Initialise from a row in the main Geonames table. */ - public GeonamesAdm(List row) { - geonameId = Long.parseLong(row.get(0)); - admLevel = row.get(7); - countryCode = row.get(8); - adminCode1 = row.get(10); - if (admLevel.startsWith("ADM")) { - if (admLevel.endsWith("H")) - level = Integer.parseInt(admLevel.substring(3, admLevel.length() - 1)); - else - level = Integer.parseInt(admLevel.substring(3)); - } else if (admLevel.equals("PCLI")) { - level = 0; - } else { - throw new IllegalArgumentException("Unsupported admin level " + admLevel); - } - name = row.get(1); - asciiName = row.get(2); - alternateNames = Arrays.asList(row.get(3).split(",")); - lat = Double.parseDouble(row.get(4)); - lng = Double.parseDouble(row.get(5)); - lastUpdated = LocalDate.parse(row.get(18)); - timeZone = ZoneId.of(row.get(17)); - // upper levels - if (row.get(11) != null && !row.get(11).trim().equals("")) - upperLevelIds[2] = Long.parseLong(row.get(11)); - if (row.get(12) != null && !row.get(12).trim().equals("")) - upperLevelIds[3] = Long.parseLong(row.get(12)); - if (row.get(13) != null && !row.get(13).trim().equals("")) - upperLevelIds[4] = Long.parseLong(row.get(13)); - this.row = row; - } - - public void mapUpperLevels(Map index) { - for (int i = 0; i < level; i++) { - Long geonameId = upperLevelIds[i]; - upperLevels.add(i, index.get(geonameId)); - } - } - - public Long getGeonameId() { - return geonameId; - } - - public Integer getLevel() { - return level; - } - - public String getName() { - return name; - } - - public String getName(Function transform) { - if (transform != null) - return transform.apply(name); - else - return name; - - } - - public String getAsciiName() { - return asciiName; - } - - public List getAlternateNames() { - return alternateNames; - } - - public Double getLat() { - return lat; - } - - public Double getLng() { - return lng; - } - - public String getCountryCode() { - return countryCode; - } - - public String getAdmLevel() { - return admLevel; - } - - public List getRow() { - return row; - } - - public LocalDate getLastUpdated() { - return lastUpdated; - } - - public ZoneId getTimeZone() { - return timeZone; - } - - public String getAdminCode1() { - return adminCode1; - } - - public Long[] getUpperLevelIds() { - return upperLevelIds; - } - - public List getUpperLevels() { - return upperLevels; - } - - @Override - public int hashCode() { - return geonameId.intValue(); - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof GeonamesAdm)) - return false; - GeonamesAdm other = (GeonamesAdm) obj; - return geonameId.equals(other.geonameId); - } - - @Override - public String toString() { - return name + " (ADM" + level + " " + geonameId + ")"; - } - -} diff --git a/knowledge/org.argeo.support.geonames/src/org/argeo/support/geonames/ImportGeonamesAdmin.java b/knowledge/org.argeo.support.geonames/src/org/argeo/support/geonames/ImportGeonamesAdmin.java deleted file mode 100644 index 9af5987..0000000 --- a/knowledge/org.argeo.support.geonames/src/org/argeo/support/geonames/ImportGeonamesAdmin.java +++ /dev/null @@ -1,93 +0,0 @@ -package org.argeo.support.geonames; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.argeo.util.CsvParser; -import org.argeo.util.CsvWriter; - -/** Import GeoNames administrative division from the main table. */ -public class ImportGeonamesAdmin { - // private Log log = LogFactory.getLog(ImportGeonamesAdmin.class); - private Map geonamesAdms = new HashMap<>(); - - /** Loads the data. */ - public void parse(InputStream in) { - Map countryGeonameIds = new HashMap<>(); - Map admin1GeonameIds = new HashMap<>(); - CsvParser csvParser = new CsvParser() { - - @Override - protected void processLine(Integer lineNumber, List header, List tokens) { - if (!"A".equals(tokens.get(6))) - return; - GeonamesAdm geonamesAdm = new GeonamesAdm(tokens); - geonamesAdms.put(geonamesAdm.getGeonameId(), geonamesAdm); - if (geonamesAdm.getAdmLevel().equals("PCLI")) - countryGeonameIds.put(geonamesAdm.getCountryCode(), geonamesAdm.getGeonameId()); - if (geonamesAdm.getAdmLevel().equals("ADM1")) - admin1GeonameIds.put(geonamesAdm.getAdminCode1(), geonamesAdm.getGeonameId()); - } - }; - csvParser.setSeparator('\t'); - csvParser.setNoHeader(true); - csvParser.parse(in, StandardCharsets.UTF_8); - - // fill upper levels - for (GeonamesAdm adm : geonamesAdms.values()) { - adm.getUpperLevelIds()[0] = countryGeonameIds.get(adm.getCountryCode()); - if (adm.getLevel() > 0) - adm.getUpperLevelIds()[1] = admin1GeonameIds.get(adm.getAdminCode1()); - adm.mapUpperLevels(geonamesAdms); - } - - } - - public Map getGeonamesAdms() { - return geonamesAdms; - } - - /** - * Copies only the Geonames of feature class 'A' (administrative subdivisions). - */ - public static void filterGeonamesAdm(InputStream in, OutputStream out) { - CsvWriter csvWriter = new CsvWriter(out, StandardCharsets.UTF_8); - csvWriter.setSeparator('\t'); - CsvParser csvParser = new CsvParser() { - - @Override - protected void processLine(Integer lineNumber, List header, List tokens) { - if (tokens.size() < 7 || !"A".equals(tokens.get(6))) - return; - csvWriter.writeLine(tokens); - } - }; - csvParser.setSeparator('\t'); - csvParser.setNoHeader(true); - csvParser.parse(in, StandardCharsets.UTF_8); - } - - public static void main(String[] args) throws IOException { -// String country = "allCountries"; - String country = "CI"; -// try (InputStream in = Files -// .newInputStream(Paths.get(System.getProperty("user.home") + "/gis/data/geonames/" + country + ".txt")); -// OutputStream out = Files.newOutputStream( -// Paths.get(System.getProperty("user.home") + "/gis/data/geonames/" + country + "-adm.txt"))) { -// ImportGeonamesAdmin.filterGeonamesAdm(in, out); -// } - try (InputStream in = Files.newInputStream( - Paths.get(System.getProperty("user.home") + "/gis/data/geonames/" + country + "-adm.txt"))) { - ImportGeonamesAdmin importGeonamesAdmin = new ImportGeonamesAdmin(); - importGeonamesAdmin.parse(in); - } - } - -} diff --git a/knowledge/org.argeo.support.odk/.classpath b/knowledge/org.argeo.support.odk/.classpath deleted file mode 100644 index e801ebf..0000000 --- a/knowledge/org.argeo.support.odk/.classpath +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/knowledge/org.argeo.support.odk/.gitignore b/knowledge/org.argeo.support.odk/.gitignore deleted file mode 100644 index 09e3bc9..0000000 --- a/knowledge/org.argeo.support.odk/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/bin/ -/target/ diff --git a/knowledge/org.argeo.support.odk/.project b/knowledge/org.argeo.support.odk/.project deleted file mode 100644 index ac46107..0000000 --- a/knowledge/org.argeo.support.odk/.project +++ /dev/null @@ -1,33 +0,0 @@ - - - org.argeo.support.odk - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - org.eclipse.pde.ds.core.builder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - diff --git a/knowledge/org.argeo.support.odk/META-INF/.gitignore b/knowledge/org.argeo.support.odk/META-INF/.gitignore deleted file mode 100644 index 4854a41..0000000 --- a/knowledge/org.argeo.support.odk/META-INF/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/MANIFEST.MF diff --git a/knowledge/org.argeo.support.odk/OSGI-INF/odkFormListServlet.xml b/knowledge/org.argeo.support.odk/OSGI-INF/odkFormListServlet.xml deleted file mode 100644 index 937b474..0000000 --- a/knowledge/org.argeo.support.odk/OSGI-INF/odkFormListServlet.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/knowledge/org.argeo.support.odk/OSGI-INF/odkFormServlet.xml b/knowledge/org.argeo.support.odk/OSGI-INF/odkFormServlet.xml deleted file mode 100644 index 7f7e4db..0000000 --- a/knowledge/org.argeo.support.odk/OSGI-INF/odkFormServlet.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/knowledge/org.argeo.support.odk/OSGI-INF/odkManifestServlet.xml b/knowledge/org.argeo.support.odk/OSGI-INF/odkManifestServlet.xml deleted file mode 100644 index cfc56ef..0000000 --- a/knowledge/org.argeo.support.odk/OSGI-INF/odkManifestServlet.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/knowledge/org.argeo.support.odk/OSGI-INF/odkServletContext.xml b/knowledge/org.argeo.support.odk/OSGI-INF/odkServletContext.xml deleted file mode 100644 index 78b5b66..0000000 --- a/knowledge/org.argeo.support.odk/OSGI-INF/odkServletContext.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/knowledge/org.argeo.support.odk/OSGI-INF/odkSubmissionServlet.xml b/knowledge/org.argeo.support.odk/OSGI-INF/odkSubmissionServlet.xml deleted file mode 100644 index bce66c4..0000000 --- a/knowledge/org.argeo.support.odk/OSGI-INF/odkSubmissionServlet.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/knowledge/org.argeo.support.odk/bnd.bnd b/knowledge/org.argeo.support.odk/bnd.bnd deleted file mode 100644 index fa581ce..0000000 --- a/knowledge/org.argeo.support.odk/bnd.bnd +++ /dev/null @@ -1,19 +0,0 @@ -Require-Capability:\ -cms.datamodel;filter:="(name=entity)",\ -cms.datamodel;filter:="(name=xforms)" - -Provide-Capability:\ -cms.datamodel; name=odk; cnd=/org/argeo/support/odk/odk.cnd - -Service-Component:\ -OSGI-INF/odkServletContext.xml,\ -OSGI-INF/odkFormListServlet.xml,\ -OSGI-INF/odkFormServlet.xml,\ -OSGI-INF/odkSubmissionServlet.xml,\ -OSGI-INF/odkManifestServlet.xml - -Import-Package:\ -org.osgi.service.http.context,\ -org.argeo.api,\ -javax.jcr.nodetype,\ -* diff --git a/knowledge/org.argeo.support.odk/build.properties b/knowledge/org.argeo.support.odk/build.properties deleted file mode 100644 index 1cdf3dd..0000000 --- a/knowledge/org.argeo.support.odk/build.properties +++ /dev/null @@ -1,6 +0,0 @@ -output.. = bin/ -bin.includes = META-INF/,\ - .,\ - OSGI-INF/,\ - OSGI-INF/odkServletContext.xml -source.. = src/ diff --git a/knowledge/org.argeo.support.odk/pom.xml b/knowledge/org.argeo.support.odk/pom.xml deleted file mode 100644 index 98dfe25..0000000 --- a/knowledge/org.argeo.support.odk/pom.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - 4.0.0 - - org.argeo.suite - knowledge - 2.3-SNAPSHOT - .. - - org.argeo.support.odk - ODK support - jar - - - org.argeo.suite - org.argeo.suite.core - 2.3-SNAPSHOT - - - org.argeo.suite - org.argeo.support.xforms - 2.3-SNAPSHOT - - - diff --git a/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/BundleResourceOdkForm.java b/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/BundleResourceOdkForm.java deleted file mode 100644 index fc55f35..0000000 --- a/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/BundleResourceOdkForm.java +++ /dev/null @@ -1,101 +0,0 @@ -package org.argeo.support.odk; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.Map; - -import org.apache.commons.io.FilenameUtils; -import org.apache.commons.io.IOUtils; -import org.argeo.util.DigestUtils; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; - -/** {@link OdkForm} implementation based on an OSGi {@link Bundle} resource. */ -public class BundleResourceOdkForm implements OdkForm { - private String formId; - private String name; - private String version; - private String description; - private String hash; - private String fileName; - - private byte[] data; - - public void init(Map properties, BundleContext bundleContext) throws IOException { - String location = properties.get("location"); - fileName = FilenameUtils.getName(location); - URL url = bundleContext.getBundle().getResource(location); - data = IOUtils.toByteArray(url.openStream()); - hash = "md5:" + DigestUtils.digest(DigestUtils.MD5, data); - - // TODO get it from the XML - formId = properties.get("formId"); - version = properties.get("version"); - - name = properties.get("name"); - description = properties.get("description"); - } - - @Override - public String getFormId() { - return formId; - } - - @Override - public String getName() { - return name; - } - - @Override - public String getVersion() { - return version; - } - - @Override - public String getDescription() { - return description; - } - - @Override - public String getHash(String hashType) { - return hash; - } - - @Override - public String getFileName() { - return fileName; - } - - @Override - public InputStream openStream() { - return new ByteArrayInputStream(data); - } - - @Override - public int hashCode() { - assert formId != null; - assert version != null; - return formId.hashCode() + version.hashCode(); - } - - @Override - public boolean equals(Object obj) { - assert formId != null; - assert version != null; - if (!(obj instanceof OdkForm)) - return false; - OdkForm other = (OdkForm) obj; - assert other.getFormId() != null; - assert other.getVersion() != null; - - return other.getFormId().equals(formId) && other.getVersion().equals(version); - } - - @Override - public String toString() { - return "ODK Form " + formId + ", v" + version; - } - -} diff --git a/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/OdkForm.java b/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/OdkForm.java deleted file mode 100644 index 7b79a13..0000000 --- a/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/OdkForm.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.argeo.support.odk; - -import java.io.InputStream; - -/** Abstraction of a single ODK form. */ -public interface OdkForm { - String getFormId(); - - String getName(); - - String getVersion(); - - String getDescription(); - - String getHash(String hashType); - - String getFileName(); - - InputStream openStream(); -} diff --git a/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/OdkNames.java b/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/OdkNames.java deleted file mode 100644 index fbb2087..0000000 --- a/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/OdkNames.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.argeo.support.odk; - -/** Names related to ODK. */ -public interface OdkNames { - - public final static String H_HTML = "h:html"; -} diff --git a/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/OdkUtils.java b/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/OdkUtils.java deleted file mode 100644 index f4bb936..0000000 --- a/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/OdkUtils.java +++ /dev/null @@ -1,199 +0,0 @@ -package org.argeo.support.odk; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.charset.StandardCharsets; - -import javax.jcr.ImportUUIDBehavior; -import javax.jcr.Node; -import javax.jcr.NodeIterator; -import javax.jcr.Property; -import javax.jcr.RepositoryException; -import javax.jcr.Session; -import javax.jcr.Value; -import javax.jcr.nodetype.NodeType; -import javax.jcr.query.Query; -import javax.jcr.query.QueryResult; -import javax.jcr.query.Row; -import javax.jcr.query.RowIterator; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.entity.EntityMimeType; -import org.argeo.entity.EntityType; -import org.argeo.jcr.Jcr; -import org.argeo.jcr.JcrUtils; -import org.argeo.jcr.JcrxApi; -import org.argeo.util.DigestUtils; - -/** Utilities around ODK. */ -public class OdkUtils { - private final static Log log = LogFactory.getLog(OdkUtils.class); - - public static Node loadOdkForm(Node formBase, String name, InputStream in, InputStream... additionalNodes) - throws RepositoryException, IOException { - if (!formBase.isNodeType(EntityType.formSet.get())) - throw new IllegalArgumentException( - "Parent path " + formBase + " must be of type " + EntityType.formSet.get()); - Node form = JcrUtils.getOrAdd(formBase, name, OrxListName.xform.get(), NodeType.MIX_VERSIONABLE); - - String previousCsum = JcrxApi.getChecksum(form, JcrxApi.MD5); - String previousFormId = Jcr.get(form, OrxListName.formID.get()); - String previousFormVersion = Jcr.get(form, OrxListName.version.get()); - - Session s = formBase.getSession(); - s.importXML(form.getPath(), in, ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING); - - for (InputStream additionalIn : additionalNodes) { - s.importXML(form.getPath(), additionalIn, ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING); - } - s.save(); - - // manage instances - // NodeIterator instances = - // form.getNodes("h:html/h:head/xforms:model/xforms:instance"); - NodeIterator instances = form.getNode("h:html/h:head/xforms:model").getNodes("xforms:instance"); - Node primaryInstance = null; - while (instances.hasNext()) { - Node instance = instances.nextNode(); - if (primaryInstance == null) { - primaryInstance = instance; - } else {// secondary instances - String instanceId = instance.getProperty("id").getString(); - URI instanceUri = null; - if (instance.hasProperty("src")) - try { - instanceUri = new URI(instance.getProperty("src").getString()); - } catch (URISyntaxException e) { - throw new IllegalArgumentException("Instance " + instanceId + " has a badly formatted URI", e); - } - if (instanceUri != null) { - if ("jr".equals(instanceUri.getScheme())) { - String uuid; - String mimeType; - String encoding = StandardCharsets.UTF_8.name(); - String type = instanceUri.getHost(); - String path = instanceUri.getPath(); - if ("file".equals(type)) { - if (!path.endsWith(".xml")) - throw new IllegalArgumentException("File uri " + instanceUri + " must end with .xml"); - // Work around bug in ODK Collect not supporting paths - // path = path.substring(0, path.length() - ".xml".length()); - // Node target = file.getSession().getNode(path); - uuid = path.substring(1, path.length() - ".xml".length()); - mimeType = EntityMimeType.XML.getMimeType(); - } else if ("file-csv".equals(type)) { - if (!path.endsWith(".csv")) - throw new IllegalArgumentException("File uri " + instanceUri + " must end with .csv"); - // Work around bug in ODK Collect not supporting paths - // path = path.substring(0, path.length() - ".csv".length()); - // Node target = file.getSession().getNode(path); - uuid = path.substring(1, path.length() - ".csv".length()); - mimeType = EntityMimeType.CSV.getMimeType(); - } else { - throw new IllegalArgumentException("Unsupported instance type " + type); - } - Node manifest = JcrUtils.getOrAdd(form, OrxManifestName.manifest.name(), - OrxManifestName.manifest.get()); - Node file = JcrUtils.getOrAdd(manifest, instanceId); - file.addMixin(NodeType.MIX_MIMETYPE); - file.setProperty(Property.JCR_MIMETYPE, mimeType); - file.setProperty(Property.JCR_ENCODING, encoding); - Node target = file.getSession().getNodeByIdentifier(uuid); - - if (target.isNodeType(NodeType.NT_QUERY)) { - Query query = target.getSession().getWorkspace().getQueryManager().getQuery(target); - query.setLimit(10); - QueryResult queryResult = query.execute(); - RowIterator rit = queryResult.getRows(); - while (rit.hasNext()) { - Row row = rit.nextRow(); - for (Value value : row.getValues()) { - System.out.print(value.getString()); - System.out.print(','); - } - System.out.print('\n'); - } - - } - - if (target.isNodeType(NodeType.MIX_REFERENCEABLE)) { - file.setProperty(Property.JCR_ID, target); - if (file.hasProperty(Property.JCR_PATH)) - file.getProperty(Property.JCR_PATH).remove(); - } else { - file.setProperty(Property.JCR_PATH, target.getPath()); - if (file.hasProperty(Property.JCR_ID)) - file.getProperty(Property.JCR_ID).remove(); - } - } - } - } - } - - if (primaryInstance == null) - throw new IllegalArgumentException("No primary instance found in " + form); - if (!primaryInstance.hasNodes()) - throw new IllegalArgumentException("No data found in primary instance of " + form); - NodeIterator primaryInstanceChildren = primaryInstance.getNodes(); - Node data = primaryInstanceChildren.nextNode(); - if (primaryInstanceChildren.hasNext()) - throw new IllegalArgumentException("More than one data found in primary instance of " + form); - String formId = data.getProperty("id").getString(); - if (previousFormId != null && !formId.equals(previousFormId)) - log.warn("Form id of " + form + " changed from " + previousFormId + " to " + formId); - form.setProperty(OrxListName.formID.get(), formId); - String formVersion = data.getProperty("version").getString(); - - if (previousCsum == null)// save before checksuming - s.save(); - String newCsum; - try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { - s.exportDocumentView(form.getPath() + "/" + OdkNames.H_HTML, out, true, false); - newCsum = DigestUtils.digest(DigestUtils.MD5, out.toByteArray()); - } - if (previousCsum == null) { - JcrxApi.addChecksum(form, newCsum); - JcrUtils.updateLastModified(form); - form.setProperty(OrxListName.version.get(), formVersion); - s.save(); - s.getWorkspace().getVersionManager().checkpoint(form.getPath()); - if (log.isDebugEnabled()) - log.debug("New form " + form); - } else { - if (newCsum.equals(previousCsum)) { - // discard - s.refresh(false); - if (log.isDebugEnabled()) - log.debug("Unmodified form " + form); - return form; - } else { - if (formVersion.equals(previousFormVersion)) { - s.refresh(false); - throw new IllegalArgumentException("Form " + form + " has been changed but version " + formVersion - + " has not been changed, discarding changes..."); - } - form.setProperty(OrxListName.version.get(), formVersion); - JcrxApi.addChecksum(form, newCsum); - JcrUtils.updateLastModified(form); - s.save(); - s.getWorkspace().getVersionManager().checkpoint(form.getPath()); - if (log.isDebugEnabled()) { - log.debug("Updated form " + form); - log.debug("Previous csum " + previousCsum); - log.debug("New csum " + newCsum); - } - } - } - return form; - } - - /** Singleton. */ - private OdkUtils() { - - } - -} diff --git a/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/OrxListName.java b/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/OrxListName.java deleted file mode 100644 index 0404c90..0000000 --- a/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/OrxListName.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.argeo.support.odk; - -import org.argeo.entity.JcrName; - -/** Types related to the http://openrosa.org/xforms/xformsList namespace. */ -public enum OrxListName implements JcrName { - xform, - // names - formID, version; - - @Override - public String getPrefix() { - return prefix(); - } - - public static String prefix() { - return "orxList"; - } - - @Override - public String getNamespace() { - return namespace(); - } - - public static String namespace() { - return "http://openrosa.org/xforms/xformsList"; - } - -} diff --git a/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/OrxManifestName.java b/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/OrxManifestName.java deleted file mode 100644 index c9fcc5d..0000000 --- a/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/OrxManifestName.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.argeo.support.odk; - -import org.argeo.entity.JcrName; - -/** Types related to the http://openrosa.org/xforms/xformsList namespace. */ -public enum OrxManifestName implements JcrName { - manifest, mediaFile; - - @Override - public String getPrefix() { - return prefix(); - } - - public static String prefix() { - return "orxManifest"; - } - - @Override - public String getNamespace() { - return namespace(); - } - - public static String namespace() { - return "http://openrosa.org/xforms/xformsManifest"; - } - -} diff --git a/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/OrxType.java b/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/OrxType.java deleted file mode 100644 index 3b5d601..0000000 --- a/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/OrxType.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.argeo.support.odk; - -import org.argeo.entity.JcrName; - -/** Types related to the http://openrosa.org/xforms/xformsList namespace. */ -public enum OrxType implements JcrName { - submission, xml_submission_file; - - @Override - public String getPrefix() { - return prefix(); - } - - public static String prefix() { - return "orx"; - } - - @Override - public String getNamespace() { - return namespace(); - } - - public static String namespace() { - return "http://openrosa.org/xforms"; - } - -} diff --git a/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/odk.cnd b/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/odk.cnd deleted file mode 100644 index d80096d..0000000 --- a/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/odk.cnd +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - -[odk:head] -+ h:title (jcrx:xmlvalue) = jcrx:xmlvalue -+ xforms:model (odk:model) = odk:model - -[odk:body] > xforms:ui - - -[odk:html] > mix:referenceable -+ h:head (odk:head) = odk:head -+ h:body (odk:body) = odk:body - -[odk:model] > xforms:model -+ odk:setgeopoint (odk:setgeopoint) = odk:setgeopoint -+ xforms:itext (odk:itext) = odk:itext - -[odk:itext] -+ xforms:translation (odk:translation) = odk:translation * - -[odk:translation] -- lang (STRING) m -- default (STRING) -+ xforms:text (odk:text) = odk:text * - -[odk:text] -- id (STRING) m -+ xforms:value (jcrx:xmlvalue) = jcrx:xmlvalue - -[odk:setgeopoint] -- event (STRING) -- ref (STRING) - -// OpenRosa web API - -[orxList:xform] > mix:created, mix:lastModified, jcrx:csum, entity:form -- orxList:formID (STRING) -- orxList:version (STRING) -+ h:html (odk:html) = odk:html -+ manifest (orxManifest:manifest) = orxManifest:manifest - -[orxManifest:manifest] -+ * (orxManifest:mediaFile) = orxManifest:mediaFile - -[orxManifest:mediaFile] > nt:address, jcrx:csum - -[orx:submission] > mix:created, entity:formSubmission -+ xml_submission_file (nt:unstructured) = nt:unstructured -+ * (nt:file) * - - diff --git a/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/servlet/OdkFormListServlet.java b/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/servlet/OdkFormListServlet.java deleted file mode 100644 index 36bdaae..0000000 --- a/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/servlet/OdkFormListServlet.java +++ /dev/null @@ -1,168 +0,0 @@ -package org.argeo.support.odk.servlet; - -import java.io.IOException; -import java.io.Writer; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -import javax.jcr.Node; -import javax.jcr.NodeIterator; -import javax.jcr.Property; -import javax.jcr.Repository; -import javax.jcr.RepositoryException; -import javax.jcr.Session; -import javax.jcr.query.Query; -import javax.jcr.query.QueryResult; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.api.NodeConstants; -import org.argeo.cms.servlet.ServletAuthUtils; -import org.argeo.entity.EntityType; -import org.argeo.jcr.Jcr; -import org.argeo.jcr.JcrxApi; -import org.argeo.support.odk.OdkForm; -import org.argeo.support.odk.OrxListName; -import org.argeo.support.odk.OrxManifestName; - -/** Lists available forms. */ -public class OdkFormListServlet extends HttpServlet { - private static final long serialVersionUID = 2706191315048423321L; - private final static Log log = LogFactory.getLog(OdkFormListServlet.class); - - private Set odkForms = Collections.synchronizedSet(new HashSet<>()); - -// private DateTimeFormatter versionFormatter = DateTimeFormatter.ofPattern("YYYY-MM-dd-HHmm") -// .withZone(ZoneId.from(ZoneOffset.UTC)); - - private Repository repository; - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - resp.setContentType("text/xml; charset=utf-8"); - resp.setHeader("X-OpenRosa-Version", "1.0"); - resp.setDateHeader("Date", System.currentTimeMillis()); - - String serverName = req.getServerName(); - int serverPort = req.getServerPort(); - String protocol = serverPort == 443 || req.isSecure() ? "https" : "http"; - - String pathInfo = req.getPathInfo(); - - Session session = ServletAuthUtils.doAs(() -> Jcr.login(repository, NodeConstants.SYS_WORKSPACE), req); -// session = NodeUtils.openDataAdminSession(repository, NodeConstants.SYS_WORKSPACE); - Writer writer = resp.getWriter(); - writer.append(""); - writer.append(""); - boolean oldApproach = false; - if (!oldApproach) { - try { - - Query query; - if (pathInfo == null) { -// query = session.getWorkspace().getQueryManager() -// .createQuery("SELECT * FROM [nt:unstructured]", Query.JCR_SQL2); - query = session.getWorkspace().getQueryManager() - .createQuery("SELECT * FROM [" + OrxListName.xform.get() + "]", Query.JCR_SQL2); - } else { - query = session.getWorkspace().getQueryManager() - .createQuery( - "SELECT node FROM [" + OrxListName.xform.get() - + "] AS node WHERE ISDESCENDANTNODE (node, '" + pathInfo + "')", - Query.JCR_SQL2); - } - QueryResult queryResult = query.execute(); - - NodeIterator nit = queryResult.getNodes(); -// log.debug(session.getUserID()); -// log.debug(session.getWorkspace().getName()); -// NodeIterator nit = session.getRootNode().getNodes(); -// while (nit.hasNext()) { -// log.debug(nit.nextNode()); -// } - while (nit.hasNext()) { - StringBuilder sb = new StringBuilder(); - Node node = nit.nextNode(); - if (node.isNodeType(OrxListName.xform.get())) { - sb.append(""); - sb.append("" + node.getProperty(OrxListName.formID.get()).getString() + ""); - sb.append("" + Jcr.getTitle(node) + ""); - sb.append("" + node.getProperty(OrxListName.version.get()).getString() + ""); - sb.append("md5:" + JcrxApi.getChecksum(node, JcrxApi.MD5) + ""); - if (node.hasProperty(Property.JCR_DESCRIPTION)) - sb.append("" + node.getProperty(Property.JCR_DESCRIPTION).getString() + ""); - sb.append("" + protocol + "://" + serverName - + (serverPort == 80 || serverPort == 443 ? "" : ":" + serverPort) + "/api/odk/form" - + node.getPath() + ""); - if (node.hasNode(OrxManifestName.manifest.name())) { - sb.append("" + protocol + "://" + serverName - + (serverPort == 80 || serverPort == 443 ? "" : ":" + serverPort) - + "/api/odk/formManifest" + node.getNode(OrxManifestName.manifest.name()).getPath() - + ""); - } - sb.append(""); - } else if (node.isNodeType(EntityType.formSet.get())) { - sb.append(""); - sb.append("" + node.getPath() + ""); - sb.append("" + node.getProperty(Property.JCR_TITLE).getString() + ""); - sb.append("" + protocol + "://" + serverName - + (serverPort == 80 || serverPort == 443 ? "" : ":" + serverPort) + "/api/odk/formList" - + node.getPath() + ""); - sb.append(""); - } - String str = sb.toString(); - if (!str.equals("")) { - if (log.isDebugEnabled()) - log.debug(str); - writer.append(str); - } - } - } catch (RepositoryException e) { - e.printStackTrace(); - // TODO error message - // resp.sendError(500); - resp.sendError(503); - } finally { - Jcr.logout(session); - } - - } else { - for (OdkForm form : odkForms) { - StringBuilder sb = new StringBuilder(); - sb.append(""); - sb.append("" + form.getFormId() + ""); - sb.append("" + form.getName() + ""); - sb.append("" + form.getVersion() + ""); - sb.append("" + form.getHash(null) + ""); - sb.append("" + form.getDescription() + ""); - sb.append("" + protocol + "://" + serverName - + (serverPort == 80 || serverPort == 443 ? "" : ":" + serverPort) + "/api/odk/form/" - + form.getFileName() + ""); - sb.append(""); - String str = sb.toString(); - if (log.isDebugEnabled()) - log.debug(str); - writer.append(str); - } - } - writer.append(""); - } - - public void addForm(OdkForm odkForm) { - odkForms.add(odkForm); - } - - public void removeForm(OdkForm odkForm) { - odkForms.remove(odkForm); - } - - public void setRepository(Repository repository) { - this.repository = repository; - } - -} diff --git a/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/servlet/OdkFormServlet.java b/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/servlet/OdkFormServlet.java deleted file mode 100644 index cab562c..0000000 --- a/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/servlet/OdkFormServlet.java +++ /dev/null @@ -1,83 +0,0 @@ -package org.argeo.support.odk.servlet; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import javax.jcr.Repository; -import javax.jcr.RepositoryException; -import javax.jcr.Session; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.io.FilenameUtils; -import org.argeo.cms.servlet.ServletAuthUtils; -import org.argeo.jcr.Jcr; -import org.argeo.support.odk.OdkForm; -import org.argeo.support.odk.OdkNames; - -/** Retrieves a single form. */ -public class OdkFormServlet extends HttpServlet { - private static final long serialVersionUID = 7838305967987687370L; - - private Repository repository; - private Map odkForms = Collections.synchronizedMap(new HashMap<>()); - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - resp.setContentType("text/xml; charset=utf-8"); - - Session session = ServletAuthUtils.doAs(() -> Jcr.login(repository, null), req); - - String pathInfo = req.getPathInfo(); - if (pathInfo.startsWith("//")) - pathInfo = pathInfo.substring(1); - - boolean oldApproach = false; - try { - if (!oldApproach) { - String path = URLDecoder.decode(pathInfo, StandardCharsets.UTF_8); - session.exportDocumentView(path + "/" + OdkNames.H_HTML, resp.getOutputStream(), true, false); - } else { - - String fileName = FilenameUtils.getName(pathInfo); - OdkForm form = odkForms.get(fileName); - if (form == null) - throw new IllegalArgumentException("No form named " + fileName + " was found"); - - byte[] buffer = new byte[1024]; - try (InputStream in = form.openStream(); OutputStream out = resp.getOutputStream();) { - int bytesRead; - while ((bytesRead = in.read(buffer)) != -1) - out.write(buffer, 0, bytesRead); - } - } - } catch (RepositoryException e) { - e.printStackTrace(); - // TODO error message - resp.sendError(500); - } finally { - Jcr.logout(session); - } - } - - public void addForm(OdkForm odkForm) { - odkForms.put(odkForm.getFileName(), odkForm); - } - - public void removeForm(OdkForm odkForm) { - odkForms.remove(odkForm.getFileName()); - } - - public void setRepository(Repository repository) { - this.repository = repository; - } - -} diff --git a/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/servlet/OdkManifestServlet.java b/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/servlet/OdkManifestServlet.java deleted file mode 100644 index 3510e06..0000000 --- a/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/servlet/OdkManifestServlet.java +++ /dev/null @@ -1,189 +0,0 @@ -package org.argeo.support.odk.servlet; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.Writer; -import java.nio.charset.Charset; -import java.security.DigestOutputStream; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; -import java.util.List; - -import javax.jcr.ItemNotFoundException; -import javax.jcr.Node; -import javax.jcr.NodeIterator; -import javax.jcr.Property; -import javax.jcr.Repository; -import javax.jcr.RepositoryException; -import javax.jcr.Session; -import javax.jcr.Value; -import javax.jcr.nodetype.NodeType; -import javax.jcr.query.Query; -import javax.jcr.query.QueryResult; -import javax.jcr.query.Row; -import javax.jcr.query.RowIterator; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.io.output.NullOutputStream; -import org.argeo.cms.servlet.ServletAuthUtils; -import org.argeo.entity.EntityMimeType; -import org.argeo.jcr.Jcr; -import org.argeo.jcr.JcrException; -import org.argeo.support.odk.OrxManifestName; -import org.argeo.util.CsvWriter; -import org.argeo.util.DigestUtils; - -/** Describe additional files. */ -public class OdkManifestServlet extends HttpServlet { - private static final long serialVersionUID = 138030510865877478L; - - private Repository repository; - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - resp.setHeader("X-OpenRosa-Version", "1.0"); - resp.setDateHeader("Date", System.currentTimeMillis()); - - String pathInfo = req.getPathInfo(); - if (pathInfo.startsWith("//")) - pathInfo = pathInfo.substring(1); - - String serverName = req.getServerName(); - int serverPort = req.getServerPort(); - String protocol = serverPort == 443 || req.isSecure() ? "https" : "http"; - - Session session = ServletAuthUtils.doAs(() -> Jcr.login(repository, null), req); - - try { - Node node = session.getNode(pathInfo); - if (node.isNodeType(OrxManifestName.manifest.get())) { - resp.setContentType(EntityMimeType.XML.toHttpContentType()); - Writer writer = resp.getWriter(); - writer.append(""); - writer.append(""); - NodeIterator nit = node.getNodes(); - children: while (nit.hasNext()) { - Node file = nit.nextNode(); - if (file.isNodeType(OrxManifestName.mediaFile.get())) { - EntityMimeType mimeType = EntityMimeType - .find(file.getProperty(Property.JCR_MIMETYPE).getString()); - Charset charset = Charset.forName(file.getProperty(Property.JCR_ENCODING).getString()); - - if (file.isNodeType(NodeType.NT_ADDRESS)) { - Node target; - try { - target = file.getProperty(Property.JCR_ID).getNode(); - } catch (ItemNotFoundException e) { - // TODO remove old manifests - continue children; - } - writer.append(""); - writer.append(""); - // Work around bug in ODK Collect not supporting paths - // writer.append(target.getPath().substring(1) + ".xml"); - writer.append(target.getIdentifier() + "." + mimeType.getDefaultExtension()); - writer.append(""); - - MessageDigest messageDigest = MessageDigest.getInstance(DigestUtils.MD5); - // TODO cache a temp file ? - try (DigestOutputStream out = new DigestOutputStream(new NullOutputStream(), - messageDigest)) { - writeMediaFile(out, target, mimeType, charset); - writer.append(""); - writer.append("md5sum:" + DigestUtils.encodeHexString(out.getMessageDigest().digest())); - writer.append(""); - } - -// try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { -// session.exportDocumentView(target.getPath(), out, true, false); -// String fileCsum = DigestUtils.digest(DigestUtils.MD5, out.toByteArray()); -// writer.append(""); -// writer.append("md5sum:" + fileCsum); -// writer.append(""); -// } - writer.append("" + protocol + "://" + serverName - + (serverPort == 80 || serverPort == 443 ? "" : ":" + serverPort) - + "/api/odk/formManifest" + file.getPath() + ""); - } - writer.append(""); - } - } - - writer.append(""); - } else if (node.isNodeType(OrxManifestName.mediaFile.get())) { - EntityMimeType mimeType = EntityMimeType.find(node.getProperty(Property.JCR_MIMETYPE).getString()); - Charset charset = Charset.forName(node.getProperty(Property.JCR_ENCODING).getString()); - resp.setContentType(mimeType.toHttpContentType(charset)); - if (node.isNodeType(NodeType.NT_ADDRESS)) { - Node target = node.getProperty(Property.JCR_ID).getNode(); - - writeMediaFile(resp.getOutputStream(), target, mimeType, charset); -// try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { -// session.exportDocumentView(target.getPath(), out, true, false); -// System.out.println(new String(out.toByteArray(), StandardCharsets.UTF_8)); -// resp.getOutputStream().write(out.toByteArray()); -// } - } else { - throw new IllegalArgumentException("Unsupported node " + node); - } - } else { - throw new IllegalArgumentException("Unsupported node " + node); - } - } catch (RepositoryException e) { - throw new JcrException(e); - } catch (NoSuchAlgorithmException e) { - throw new ServletException(e); - } finally { - Jcr.logout(session); - } - - } - - protected void writeMediaFile(OutputStream out, Node target, EntityMimeType mimeType, Charset charset) - throws RepositoryException, IOException { - if (target.isNodeType(NodeType.NT_QUERY)) { - Query query = target.getSession().getWorkspace().getQueryManager().getQuery(target); - QueryResult queryResult = query.execute(); - String[] columnNames = queryResult.getColumnNames(); - if (EntityMimeType.XML.equals(mimeType)) { - } else if (EntityMimeType.CSV.equals(mimeType)) { - CsvWriter csvWriter = new CsvWriter(out, charset); - csvWriter.writeLine(columnNames); - RowIterator rit = queryResult.getRows(); - while (rit.hasNext()) { - Row row = rit.nextRow(); - Value[] values = row.getValues(); - List lst = new ArrayList<>(); - for (Value value : values) { - lst.add(value.getString()); - } - csvWriter.writeLine(lst); - } - } - } else { - if (EntityMimeType.XML.equals(mimeType)) { - target.getSession().exportDocumentView(target.getPath(), out, true, false); - } else if (EntityMimeType.CSV.equals(mimeType)) { - CsvWriter csvWriter = new CsvWriter(out, charset); - csvWriter.writeLine(new String[] { "name", "label" }); - NodeIterator children = target.getNodes(); - while (children.hasNext()) { - Node child = children.nextNode(); - String label = Jcr.getTitle(child); - csvWriter.writeLine(new String[] { child.getIdentifier(), label }); - } - } - - } - - } - - public void setRepository(Repository repository) { - this.repository = repository; - } - -} diff --git a/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/servlet/OdkServletContext.java b/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/servlet/OdkServletContext.java deleted file mode 100644 index f06965d..0000000 --- a/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/servlet/OdkServletContext.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.argeo.support.odk.servlet; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.argeo.cms.servlet.PrivateWwwAuthServletContext; - -/** ODK specific authentication (with additional headers).*/ -public class OdkServletContext extends PrivateWwwAuthServletContext { - - @Override - protected void askForWwwAuth(HttpServletRequest request, HttpServletResponse response) { - super.askForWwwAuth(request, response); - response.setHeader("X-OpenRosa-Version", "1.0"); - response.setDateHeader("Date", System.currentTimeMillis()); - - } - -} diff --git a/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/servlet/OdkSubmissionServlet.java b/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/servlet/OdkSubmissionServlet.java deleted file mode 100644 index 70a80c0..0000000 --- a/knowledge/org.argeo.support.odk/src/org/argeo/support/odk/servlet/OdkSubmissionServlet.java +++ /dev/null @@ -1,129 +0,0 @@ -package org.argeo.support.odk.servlet; - -import java.io.IOException; -import java.time.Instant; -import java.time.ZoneId; -import java.time.ZoneOffset; -import java.time.format.DateTimeFormatter; -import java.util.HashSet; -import java.util.Set; - -import javax.jcr.ImportUUIDBehavior; -import javax.jcr.Node; -import javax.jcr.Property; -import javax.jcr.Repository; -import javax.jcr.RepositoryException; -import javax.jcr.Session; -import javax.jcr.nodetype.NodeType; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.Part; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.api.NodeUtils; -import org.argeo.cms.auth.CmsSession; -import org.argeo.cms.servlet.ServletAuthUtils; -import org.argeo.jcr.Jcr; -import org.argeo.jcr.JcrUtils; -import org.argeo.suite.SuiteUtils; -import org.argeo.support.odk.OrxType; -import org.argeo.support.xforms.FormSubmissionListener; - -/** Receives a form submission. */ -public class OdkSubmissionServlet extends HttpServlet { - private static final long serialVersionUID = 7834401404691302385L; - private final static Log log = LogFactory.getLog(OdkSubmissionServlet.class); - - private final static String XML_SUBMISSION_FILE = "xml_submission_file"; - - private DateTimeFormatter submissionNameFormatter = DateTimeFormatter.ofPattern("YYYY-MM-dd-HHmmssSSS") - .withZone(ZoneId.from(ZoneOffset.UTC)); - - private Repository repository; - - private Set submissionListeners = new HashSet<>(); - - @Override - protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - resp.setContentType("text/xml; charset=utf-8"); - resp.setHeader("X-OpenRosa-Version", "1.0"); - resp.setDateHeader("Date", System.currentTimeMillis()); - resp.setIntHeader("X-OpenRosa-Accept-Content-Length", 1024 * 1024); - - Session session = ServletAuthUtils.doAs(() -> Jcr.login(repository, null), req); - - try { -// Node submissions = JcrUtils.mkdirs(session, -// "/" + EntityType.form.get() + "/" + EntityNames.SUBMISSIONS_BASE); - CmsSession cmsSession = ServletAuthUtils.getCmsSession(req); - - ClassLoader currentContextCl = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(ServletAuthUtils.class.getClassLoader()); - Session adminSession = null; - try { - // TODO centralise at a deeper level - adminSession = NodeUtils.openDataAdminSession(repository, null); - SuiteUtils.getOrCreateCmsSessionNode(adminSession, cmsSession); - } finally { - Jcr.logout(adminSession); - Thread.currentThread().setContextClassLoader(currentContextCl); - } - - Node cmsSessionNode = SuiteUtils.getCmsSessionNode(session, cmsSession); - Node submission = cmsSessionNode.addNode(submissionNameFormatter.format(Instant.now()), - OrxType.submission.get()); - for (Part part : req.getParts()) { - if (log.isDebugEnabled()) - log.debug("Part: " + part.getName() + ", " + part.getContentType()); - - if (part.getName().equals(XML_SUBMISSION_FILE)) { - Node xml = submission.addNode(XML_SUBMISSION_FILE, NodeType.NT_UNSTRUCTURED); - session.importXML(xml.getPath(), part.getInputStream(), - ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING); - - } else { - Node fileNode = JcrUtils.copyStreamAsFile(submission, part.getName(), part.getInputStream()); - String contentType = part.getContentType(); - if (contentType != null) { - fileNode.addMixin(NodeType.MIX_MIMETYPE); - fileNode.setProperty(Property.JCR_MIMETYPE, contentType); - - } - if (part.getName().endsWith(".jpg") || part.getName().endsWith(".png")) { - // TODO meta data and thumbnails - } - } - } - session.save(); - for (FormSubmissionListener submissionListener : submissionListeners) { - submissionListener.formSubmissionReceived(submission); - } - } catch (RepositoryException e) { - e.printStackTrace(); - resp.setStatus(503); - return; - } finally { - Jcr.logout(session); - } - - resp.setStatus(201); - resp.getWriter().write("" - + "Form Received!" + ""); - - } - - public void setRepository(Repository repository) { - this.repository = repository; - } - - public synchronized void addSubmissionListener(FormSubmissionListener listener) { - submissionListeners.add(listener); - } - - public synchronized void removeSubmissionListener(FormSubmissionListener listener) { - submissionListeners.remove(listener); - } -} diff --git a/knowledge/org.argeo.support.xforms/.classpath b/knowledge/org.argeo.support.xforms/.classpath deleted file mode 100644 index e801ebf..0000000 --- a/knowledge/org.argeo.support.xforms/.classpath +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/knowledge/org.argeo.support.xforms/.gitignore b/knowledge/org.argeo.support.xforms/.gitignore deleted file mode 100644 index 09e3bc9..0000000 --- a/knowledge/org.argeo.support.xforms/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/bin/ -/target/ diff --git a/knowledge/org.argeo.support.xforms/.project b/knowledge/org.argeo.support.xforms/.project deleted file mode 100644 index 3c50bfa..0000000 --- a/knowledge/org.argeo.support.xforms/.project +++ /dev/null @@ -1,28 +0,0 @@ - - - org.argeo.support.xforms - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - diff --git a/knowledge/org.argeo.support.xforms/META-INF/.gitignore b/knowledge/org.argeo.support.xforms/META-INF/.gitignore deleted file mode 100644 index 4854a41..0000000 --- a/knowledge/org.argeo.support.xforms/META-INF/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/MANIFEST.MF diff --git a/knowledge/org.argeo.support.xforms/bnd.bnd b/knowledge/org.argeo.support.xforms/bnd.bnd deleted file mode 100644 index 23c86a9..0000000 --- a/knowledge/org.argeo.support.xforms/bnd.bnd +++ /dev/null @@ -1,5 +0,0 @@ -Require-Capability:\ -cms.datamodel;filter:="(name=entity)" - -Provide-Capability:\ -cms.datamodel; name=xforms; cnd=/org/argeo/support/xforms/xforms.cnd diff --git a/knowledge/org.argeo.support.xforms/build.properties b/knowledge/org.argeo.support.xforms/build.properties deleted file mode 100644 index 34d2e4d..0000000 --- a/knowledge/org.argeo.support.xforms/build.properties +++ /dev/null @@ -1,4 +0,0 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . diff --git a/knowledge/org.argeo.support.xforms/pom.xml b/knowledge/org.argeo.support.xforms/pom.xml deleted file mode 100644 index 44815ad..0000000 --- a/knowledge/org.argeo.support.xforms/pom.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - 4.0.0 - - org.argeo.suite - knowledge - 2.3-SNAPSHOT - .. - - org.argeo.support.xforms - XForms support - jar - - - org.argeo.suite - org.argeo.suite.core - 2.3-SNAPSHOT - - - diff --git a/knowledge/org.argeo.support.xforms/src/org/argeo/support/xforms/FormSubmissionListener.java b/knowledge/org.argeo.support.xforms/src/org/argeo/support/xforms/FormSubmissionListener.java deleted file mode 100644 index e23ef36..0000000 --- a/knowledge/org.argeo.support.xforms/src/org/argeo/support/xforms/FormSubmissionListener.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.argeo.support.xforms; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; - -/** Called when a user has received a new form submission. */ -public interface FormSubmissionListener { - /** Called after a form submission has been stored in the user area. */ - void formSubmissionReceived(Node node) throws RepositoryException; -} diff --git a/knowledge/org.argeo.support.xforms/src/org/argeo/support/xforms/xforms.cnd b/knowledge/org.argeo.support.xforms/src/org/argeo/support/xforms/xforms.cnd deleted file mode 100644 index c24dbae..0000000 --- a/knowledge/org.argeo.support.xforms/src/org/argeo/support/xforms/xforms.cnd +++ /dev/null @@ -1,39 +0,0 @@ - - -[xforms:model] -+ xforms:instance (xforms:instance) = xforms:instance * -+ xforms:bind (xforms:bind) = xforms:bind * -+ xforms:setvalue (xforms:setvalue) = xforms:setvalue * - -[xforms:instance] > nt:unstructured - -[xforms:bind] -- * (STRING) - -[xforms:setvalue] -- * (STRING) - -[xforms:select] > xforms:input -+ xforms:itemset (xforms:itemset) = xforms:itemset - -[xforms:itemset] -- nodeset (STRING) -+ xforms:label (jcrx:xmlvalue) = jcrx:xmlvalue -+ xforms:value (jcrx:xmlvalue) = jcrx:xmlvalue - -[xforms:ui] -- * (STRING) -+ xforms:label (jcrx:xmlvalue) = jcrx:xmlvalue * -+ xforms:hint (jcrx:xmlvalue) = jcrx:xmlvalue * -+ xforms:input (xforms:input) = xforms:input * -+ xforms:select (xforms:select) = xforms:select * -+ xforms:select1 (xforms:select) = xforms:select * -+ xforms:trigger (xforms:input) = xforms:input * -+ xforms:upload (xforms:input) = xforms:input * -+ xforms:group (xforms:ui) = xforms:ui * -+ xforms:repeat (xforms:ui) = xforms:ui * - -[xforms:input] -- * (STRING) -+ xforms:label (jcrx:xmlvalue) = jcrx:xmlvalue -+ xforms:hint (jcrx:xmlvalue) = jcrx:xmlvalue * diff --git a/knowledge/org.argeo.support.xforms/xsd/XForms-Schema.xsd b/knowledge/org.argeo.support.xforms/xsd/XForms-Schema.xsd deleted file mode 100644 index 6383f86..0000000 --- a/knowledge/org.argeo.support.xforms/xsd/XForms-Schema.xsd +++ /dev/null @@ -1,858 +0,0 @@ - - - - - - - - Attributes for _every_ element in XForms - - - - - - - - - - - - - - - - - - - - - - - - - instance container. - - - - - - - - - - - - submit info container. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Definition of bind container. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/knowledge/pom.xml b/knowledge/pom.xml deleted file mode 100644 index 02d2d14..0000000 --- a/knowledge/pom.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - 4.0.0 - - org.argeo.suite - argeo-suite - 2.3-SNAPSHOT - .. - - knowledge - Argeo Knowledge Components - pom - - org.argeo.support.xforms - org.argeo.support.odk - org.argeo.support.geonames - - diff --git a/lib/pom.xml b/lib/pom.xml index abb3383..737c561 100644 --- a/lib/pom.xml +++ b/lib/pom.xml @@ -15,7 +15,7 @@ 2.1.27 2.3-SNAPSHOT - 2.1.1 + 2.3-SNAPSHOT diff --git a/library/.gitignore b/library/.gitignore deleted file mode 100644 index b83d222..0000000 --- a/library/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target/ diff --git a/library/cnf/maven.bnd b/library/cnf/maven.bnd deleted file mode 100644 index 4bd5c0c..0000000 --- a/library/cnf/maven.bnd +++ /dev/null @@ -1 +0,0 @@ --include: ../../cnf/maven.bnd \ No newline at end of file diff --git a/library/org.argeo.library.ui/.classpath b/library/org.argeo.library.ui/.classpath deleted file mode 100644 index e801ebf..0000000 --- a/library/org.argeo.library.ui/.classpath +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/library/org.argeo.library.ui/.gitignore b/library/org.argeo.library.ui/.gitignore deleted file mode 100644 index 09e3bc9..0000000 --- a/library/org.argeo.library.ui/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/bin/ -/target/ diff --git a/library/org.argeo.library.ui/.project b/library/org.argeo.library.ui/.project deleted file mode 100644 index 6aa2010..0000000 --- a/library/org.argeo.library.ui/.project +++ /dev/null @@ -1,33 +0,0 @@ - - - org.argeo.library.ui - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - org.eclipse.pde.ds.core.builder - - - - - - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - - diff --git a/library/org.argeo.library.ui/META-INF/.gitignore b/library/org.argeo.library.ui/META-INF/.gitignore deleted file mode 100644 index 4854a41..0000000 --- a/library/org.argeo.library.ui/META-INF/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/MANIFEST.MF diff --git a/library/org.argeo.library.ui/OSGI-INF/contentEntryArea.xml b/library/org.argeo.library.ui/OSGI-INF/contentEntryArea.xml deleted file mode 100644 index 0b5646e..0000000 --- a/library/org.argeo.library.ui/OSGI-INF/contentEntryArea.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/library/org.argeo.library.ui/OSGI-INF/contentLayer.xml b/library/org.argeo.library.ui/OSGI-INF/contentLayer.xml deleted file mode 100644 index 0dae1af..0000000 --- a/library/org.argeo.library.ui/OSGI-INF/contentLayer.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/library/org.argeo.library.ui/OSGI-INF/documentsFolder.xml b/library/org.argeo.library.ui/OSGI-INF/documentsFolder.xml deleted file mode 100644 index d7d71f0..0000000 --- a/library/org.argeo.library.ui/OSGI-INF/documentsFolder.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/library/org.argeo.library.ui/OSGI-INF/fsEntryArea.xml b/library/org.argeo.library.ui/OSGI-INF/fsEntryArea.xml deleted file mode 100644 index 540f4ff..0000000 --- a/library/org.argeo.library.ui/OSGI-INF/fsEntryArea.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/library/org.argeo.library.ui/OSGI-INF/l10n/bundle.properties b/library/org.argeo.library.ui/OSGI-INF/l10n/bundle.properties deleted file mode 100644 index 8015421..0000000 --- a/library/org.argeo.library.ui/OSGI-INF/l10n/bundle.properties +++ /dev/null @@ -1 +0,0 @@ -content=content diff --git a/library/org.argeo.library.ui/bnd.bnd b/library/org.argeo.library.ui/bnd.bnd deleted file mode 100644 index 71f4618..0000000 --- a/library/org.argeo.library.ui/bnd.bnd +++ /dev/null @@ -1,12 +0,0 @@ -Service-Component:\ -OSGI-INF/contentEntryArea.xml,\ -OSGI-INF/fsEntryArea.xml,\ -OSGI-INF/contentLayer.xml,\ -OSGI-INF/documentsFolder.xml - -Import-Package:\ -org.eclipse.swt,\ -javax.jcr.nodetype,\ -org.argeo.api,\ -org.argeo.suite.ui,\ -* \ No newline at end of file diff --git a/library/org.argeo.library.ui/build.properties b/library/org.argeo.library.ui/build.properties deleted file mode 100644 index 0859c52..0000000 --- a/library/org.argeo.library.ui/build.properties +++ /dev/null @@ -1,7 +0,0 @@ -output.. = bin/ -bin.includes = META-INF/,\ - .,\ - OSGI-INF/,\ - OSGI-INF/contentLayer.xml,\ - OSGI-INF/documentsFolder.xml -source.. = src/ diff --git a/library/org.argeo.library.ui/config/contentEntryArea.properties b/library/org.argeo.library.ui/config/contentEntryArea.properties deleted file mode 100644 index 855fe97..0000000 --- a/library/org.argeo.library.ui/config/contentEntryArea.properties +++ /dev/null @@ -1 +0,0 @@ -service.pid=argeo.library.ui.contentEntryArea diff --git a/library/org.argeo.library.ui/config/contentLayer.properties b/library/org.argeo.library.ui/config/contentLayer.properties deleted file mode 100644 index c1ca8e3..0000000 --- a/library/org.argeo.library.ui/config/contentLayer.properties +++ /dev/null @@ -1,6 +0,0 @@ -service.pid=argeo.library.ui.contentLayer - -title=%content -icon=documents - -entity.type=nt:folder,nt:file,entity:space,entity:document diff --git a/library/org.argeo.library.ui/config/documentsFolder.properties b/library/org.argeo.library.ui/config/documentsFolder.properties deleted file mode 100644 index 349e930..0000000 --- a/library/org.argeo.library.ui/config/documentsFolder.properties +++ /dev/null @@ -1 +0,0 @@ -entity.type=nt:folder \ No newline at end of file diff --git a/library/org.argeo.library.ui/config/fsEntryArea.properties b/library/org.argeo.library.ui/config/fsEntryArea.properties deleted file mode 100644 index 0bceaf0..0000000 --- a/library/org.argeo.library.ui/config/fsEntryArea.properties +++ /dev/null @@ -1 +0,0 @@ -service.pid=argeo.library.ui.fsEntryArea diff --git a/library/org.argeo.library.ui/pom.xml b/library/org.argeo.library.ui/pom.xml deleted file mode 100644 index 259e5ee..0000000 --- a/library/org.argeo.library.ui/pom.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - 4.0.0 - - org.argeo.suite - library - 2.3-SNAPSHOT - .. - - org.argeo.library.ui - Documents UI - jar - - - org.argeo.suite - org.argeo.suite.ui - 2.3-SNAPSHOT - - - - - org.argeo.tp - argeo-tp-rap-e4 - ${version.argeo-tp} - pom - provided - - - - org.argeo.commons - org.argeo.eclipse.ui.rap - ${version.argeo-commons} - provided - - - - diff --git a/library/org.argeo.library.ui/src/org/argeo/library/ui/ContentEntryArea.java b/library/org.argeo.library.ui/src/org/argeo/library/ui/ContentEntryArea.java deleted file mode 100644 index 8b884eb..0000000 --- a/library/org.argeo.library.ui/src/org/argeo/library/ui/ContentEntryArea.java +++ /dev/null @@ -1,170 +0,0 @@ -package org.argeo.library.ui; - -import java.util.SortedMap; -import java.util.TreeMap; - -import javax.jcr.Node; -import javax.jcr.NodeIterator; -import javax.jcr.RepositoryException; -import javax.jcr.Session; -import javax.jcr.nodetype.NodeType; -import javax.jcr.query.Query; - -import org.argeo.cms.ui.CmsTheme; -import org.argeo.cms.ui.CmsUiProvider; -import org.argeo.cms.ui.CmsView; -import org.argeo.cms.ui.util.CmsUiUtils; -import org.argeo.entity.EntityType; -import org.argeo.jcr.Jcr; -import org.argeo.jcr.JcrException; -import org.argeo.suite.ui.SuiteEvent; -import org.argeo.suite.ui.SuiteIcon; -import org.argeo.suite.ui.widgets.TreeOrSearchArea; -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.jface.viewers.DoubleClickEvent; -import org.eclipse.jface.viewers.IDoubleClickListener; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.TreeViewerColumn; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; - -public class ContentEntryArea implements CmsUiProvider { - - @Override - public Control createUi(Composite parent, Node context) throws RepositoryException { - CmsTheme theme = CmsTheme.getCmsTheme(parent); - - parent.setLayout(new GridLayout()); - Ui ui = new Ui(parent, SWT.NONE); - ui.setLayoutData(CmsUiUtils.fillAll()); - - TreeViewerColumn nameCol = new TreeViewerColumn(ui.getTreeViewer(), SWT.NONE); - nameCol.getColumn().setWidth(400); - nameCol.setLabelProvider(new ColumnLabelProvider() { - - @Override - public String getText(Object element) { - Node node = (Node) element; - return Jcr.getTitle(node); - } - - @Override - public Image getImage(Object element) { - Node node = (Node) element; - Image icon; - if (Jcr.isNodeType(node, NodeType.NT_FOLDER)) { - icon = SuiteIcon.folder.getSmallIcon(theme); - } else if (Jcr.isNodeType(node, NodeType.NT_FILE)) { - // TODO check recognized document types - icon = SuiteIcon.document.getSmallIcon(theme); - } else if (Jcr.isNodeType(node, EntityType.document.get())) { - icon = SuiteIcon.document.getSmallIcon(theme); - } else { - if (!isLeaf(node)) - icon = SuiteIcon.folder.getSmallIcon(theme); - else - icon = null; - } - return icon; - } - - }); - - ui.getTreeViewer().addDoubleClickListener(new IDoubleClickListener() { - - @Override - public void doubleClick(DoubleClickEvent event) { - Node user = (Node) ui.getTreeViewer().getStructuredSelection().getFirstElement(); - if (user != null) { - CmsView.getCmsView(parent).sendEvent(SuiteEvent.openNewPart.topic(), - SuiteEvent.eventProperties(user)); - } - - } - }); - ui.getTreeViewer().addSelectionChangedListener(new ISelectionChangedListener() { - public void selectionChanged(SelectionChangedEvent event) { - Node user = (Node) ui.getTreeViewer().getStructuredSelection().getFirstElement(); - if (user != null) { - CmsView.getCmsView(parent).sendEvent(SuiteEvent.refreshPart.topic(), - SuiteEvent.eventProperties(user)); - } - } - }); - - ui.getTreeViewer().setContentProvider(new SpacesContentProvider()); - ui.getTreeViewer().setInput(context.getSession()); - return ui; - } - - protected boolean isLeaf(Node node) { - return Jcr.isNodeType(node, EntityType.entity.get()) || Jcr.isNodeType(node, EntityType.document.get()) - || Jcr.isNodeType(node, NodeType.NT_FILE); - } - - class Ui extends TreeOrSearchArea { - - public Ui(Composite parent, int style) { - super(parent, style); - } - - } - - class SpacesContentProvider implements ITreeContentProvider { - - @Override - public Object[] getElements(Object inputElement) { - Session session = (Session) inputElement; - try { - Query query = session.getWorkspace().getQueryManager() - .createQuery("SELECT * FROM [" + EntityType.space.get() + "]", Query.JCR_SQL2); - NodeIterator spacesIt = query.execute().getNodes(); - SortedMap map = new TreeMap<>(); - while (spacesIt.hasNext()) { - Node space = spacesIt.nextNode(); - String path = space.getPath(); - map.put(path, space); - } - return map.values().toArray(); - } catch (RepositoryException e) { - throw new JcrException(e); - } - } - - @Override - public Object[] getChildren(Object parentElement) { - Node parent = (Node) parentElement; - if (isLeaf(parent)) - return null; - return Jcr.getNodes(parent).toArray(); - } - - @Override - public Object getParent(Object element) { - Node node = (Node) element; - return Jcr.getParent(node); - } - - @Override - public boolean hasChildren(Object element) { - Node node = (Node) element; - return !isLeaf(node); - } - - @Override - public void dispose() { - } - - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - - } - -} diff --git a/library/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsContextMenu.java b/library/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsContextMenu.java deleted file mode 100644 index 03de251..0000000 --- a/library/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsContextMenu.java +++ /dev/null @@ -1,177 +0,0 @@ -package org.argeo.library.ui; - -import static org.argeo.library.ui.DocumentsUiService.ACTION_ID_BOOKMARK_FOLDER; -import static org.argeo.library.ui.DocumentsUiService.ACTION_ID_CREATE_FOLDER; -import static org.argeo.library.ui.DocumentsUiService.ACTION_ID_DELETE; -import static org.argeo.library.ui.DocumentsUiService.ACTION_ID_DOWNLOAD_FOLDER; -import static org.argeo.library.ui.DocumentsUiService.ACTION_ID_RENAME; -import static org.argeo.library.ui.DocumentsUiService.ACTION_ID_SHARE_FOLDER; -import static org.argeo.library.ui.DocumentsUiService.ACTION_ID_UPLOAD_FILE; - -import java.nio.file.Files; -import java.nio.file.Path; - -import org.argeo.suite.ui.widgets.AbstractConnectContextMenu; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.widgets.Control; - -/** Generic popup context menu to manage NIO Path in a Viewer. */ -public class DocumentsContextMenu extends AbstractConnectContextMenu { - // Local context - private final DocumentsFolderComposite browser; - private final DocumentsUiService uiService; -// private final Repository repository; - - private final static String[] DEFAULT_ACTIONS = { ACTION_ID_CREATE_FOLDER, ACTION_ID_BOOKMARK_FOLDER, - ACTION_ID_SHARE_FOLDER, ACTION_ID_DOWNLOAD_FOLDER, ACTION_ID_UPLOAD_FILE, ACTION_ID_RENAME, - ACTION_ID_DELETE }; - - private Path currFolderPath; - - public DocumentsContextMenu(DocumentsFolderComposite browser, - DocumentsUiService documentsUiService) { - super(browser.getDisplay(), DEFAULT_ACTIONS); - this.browser = browser; - this.uiService = documentsUiService; -// this.repository = repository; - - createControl(); - } - - public void setCurrFolderPath(Path currFolderPath) { - this.currFolderPath = currFolderPath; - } - - protected boolean aboutToShow(Control source, Point location, IStructuredSelection selection) { - boolean emptySel = true; - boolean multiSel = false; - boolean isFolder = true; - if (selection != null && !selection.isEmpty()) { - emptySel = false; - multiSel = selection.size() > 1; - if (!multiSel && selection.getFirstElement() instanceof Path) { - isFolder = Files.isDirectory((Path) selection.getFirstElement()); - } - } - if (emptySel) { - setVisible(true, ACTION_ID_CREATE_FOLDER, ACTION_ID_UPLOAD_FILE, ACTION_ID_BOOKMARK_FOLDER); - setVisible(false, ACTION_ID_SHARE_FOLDER, ACTION_ID_DOWNLOAD_FOLDER, ACTION_ID_RENAME, ACTION_ID_DELETE - ); - } else if (multiSel) { - setVisible(true, ACTION_ID_CREATE_FOLDER, ACTION_ID_UPLOAD_FILE, ACTION_ID_DELETE, - ACTION_ID_BOOKMARK_FOLDER); - setVisible(false, ACTION_ID_SHARE_FOLDER, ACTION_ID_DOWNLOAD_FOLDER, ACTION_ID_RENAME); - } else if (isFolder) { - setVisible(true, ACTION_ID_CREATE_FOLDER, ACTION_ID_UPLOAD_FILE, ACTION_ID_RENAME, ACTION_ID_DELETE, - ACTION_ID_BOOKMARK_FOLDER); - setVisible(false, - // to be implemented - ACTION_ID_SHARE_FOLDER, ACTION_ID_DOWNLOAD_FOLDER); - } else { - setVisible(true, ACTION_ID_CREATE_FOLDER, ACTION_ID_UPLOAD_FILE, ACTION_ID_RENAME, - ACTION_ID_DELETE); - setVisible(false, ACTION_ID_SHARE_FOLDER, ACTION_ID_DOWNLOAD_FOLDER, ACTION_ID_BOOKMARK_FOLDER); - } - return true; - } - - public void show(Control source, Point location, IStructuredSelection selection, Path currFolderPath) { - // TODO find a better way to retrieve the parent path (cannot be deduced - // from table content because it will fail on an empty folder) - this.currFolderPath = currFolderPath; - super.show(source, location, selection); - - } - - @Override - protected boolean performAction(String actionId) { - switch (actionId) { - case ACTION_ID_CREATE_FOLDER: - createFolder(); - break; - case ACTION_ID_BOOKMARK_FOLDER: - bookmarkFolder(); - break; - case ACTION_ID_RENAME: - renameItem(); - break; - case ACTION_ID_DELETE: - deleteItems(); - break; -// case ACTION_ID_OPEN: -// openFile(); -// break; - case ACTION_ID_UPLOAD_FILE: - uploadFiles(); - break; - default: - throw new IllegalArgumentException("Unimplemented action " + actionId); - // case ACTION_ID_SHARE_FOLDER: - // return "Share Folder"; - // case ACTION_ID_DOWNLOAD_FOLDER: - // return "Download as zip archive"; - } - browser.setFocus(); - return false; - } - - @Override - protected String getLabel(String actionId) { - return uiService.getLabel(actionId); - } - - private void openFile() { - IStructuredSelection selection = ((IStructuredSelection) browser.getViewer().getSelection()); - if (selection.isEmpty() || selection.size() > 1) - // Should never happen - return; - Path toOpenPath = ((Path) selection.getFirstElement()); - uiService.openFile(toOpenPath); - } - - private void deleteItems() { - IStructuredSelection selection = ((IStructuredSelection) browser.getViewer().getSelection()); - if (selection.isEmpty()) - return; - else if (uiService.deleteItems(getParentShell(), selection)) - browser.refresh(); - } - - private void renameItem() { - IStructuredSelection selection = ((IStructuredSelection) browser.getViewer().getSelection()); - if (selection.isEmpty() || selection.size() > 1) - // Should never happen - return; - Path toRenamePath = ((Path) selection.getFirstElement()); - if (uiService.renameItem(getParentShell(), currFolderPath, toRenamePath)) - browser.refresh(); - } - - private void createFolder() { - if (uiService.createFolder(getParentShell(), currFolderPath)) - browser.refresh(); - } - - private void bookmarkFolder() { - Path toBookmarkPath = null; - IStructuredSelection selection = ((IStructuredSelection) browser.getViewer().getSelection()); - if (selection.isEmpty()) - toBookmarkPath = currFolderPath; - else if (selection.size() > 1) - toBookmarkPath = currFolderPath; - else if (selection.size() == 1) { - Path currSelected = ((Path) selection.getFirstElement()); - if (Files.isDirectory(currSelected)) - toBookmarkPath = currSelected; - else - return; - } - //uiService.bookmarkFolder(toBookmarkPath, repository, null); - } - - private void uploadFiles() { - if (uiService.uploadFiles(getParentShell(), currFolderPath)) - browser.refresh(); - } -} diff --git a/library/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsFileComposite.java b/library/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsFileComposite.java deleted file mode 100644 index 10cf3bd..0000000 --- a/library/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsFileComposite.java +++ /dev/null @@ -1,125 +0,0 @@ -package org.argeo.library.ui; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.spi.FileSystemProvider; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.cms.fs.CmsFsUtils; -import org.argeo.cms.ui.util.CmsUiUtils; -import org.argeo.eclipse.ui.EclipseUiUtils; -import org.argeo.eclipse.ui.fs.FsUiUtils; -import org.argeo.eclipse.ui.specific.UiContext; -import org.eclipse.swt.SWT; -import org.eclipse.swt.browser.Browser; -import org.eclipse.swt.custom.SashForm; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; - -/** - * Default Documents file composite: a sashForm with a browser in the middle and - * meta data at right hand side. - */ -public class DocumentsFileComposite extends Composite { - private static final long serialVersionUID = -7567632342889241793L; - - private final static Log log = LogFactory.getLog(DocumentsFileComposite.class); - - private final Node currentBaseContext; - - // UI Parts for the browser - private Composite rightPannelCmp; - - public DocumentsFileComposite(Composite parent, int style, Node context, - FileSystemProvider fsp) { - super(parent, style); - this.currentBaseContext = context; - this.setLayout(EclipseUiUtils.noSpaceGridLayout()); - SashForm form = new SashForm(this, SWT.HORIZONTAL); - - Composite centerCmp = new Composite(form, SWT.BORDER | SWT.NO_FOCUS); - createDisplay(centerCmp); - - rightPannelCmp = new Composite(form, SWT.NO_FOCUS); - - Path path = CmsFsUtils.getPath(fsp, context); - setOverviewInput(path); - form.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - form.setWeights(new int[] { 55, 20 }); - } - - private void createDisplay(final Composite parent) { - parent.setLayout(EclipseUiUtils.noSpaceGridLayout()); - Browser browser = new Browser(parent, SWT.NONE); - // browser.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, - // true)); - browser.setLayoutData(EclipseUiUtils.fillAll()); - try { - // FIXME make it more robust - String url = CmsUiUtils.getDataUrl(currentBaseContext, UiContext.getHttpRequest()); - // FIXME issue with the redirection to https - if (url.startsWith("http://") && !url.startsWith("http://localhost")) - url = "https://" + url.substring("http://".length(), url.length()); - if (log.isTraceEnabled()) - log.debug("Trying to display " + url); - browser.setUrl(url); - browser.layout(true, true); - } catch (RepositoryException re) { - throw new IllegalStateException("Cannot open file at " + currentBaseContext, re); - } - } - - /** - * Recreates the content of the box that displays information about the current - * selected Path. - */ - private void setOverviewInput(Path path) { - try { - EclipseUiUtils.clear(rightPannelCmp); - rightPannelCmp.setLayout(new GridLayout()); - if (path != null) { - // if (isImg(context)) { - // EditableImage image = new Img(parent, RIGHT, context, - // imageWidth); - // image.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, - // true, false, - // 2, 1)); - // } - - Label contextL = new Label(rightPannelCmp, SWT.NONE); - contextL.setText(path.getFileName().toString()); - contextL.setFont(EclipseUiUtils.getBoldFont(rightPannelCmp)); - addProperty(rightPannelCmp, "Last modified", Files.getLastModifiedTime(path).toString()); - // addProperty(rightPannelCmp, "Owner", - // Files.getOwner(path).getName()); - if (Files.isDirectory(path)) { - addProperty(rightPannelCmp, "Type", "Folder"); - } else { - String mimeType = Files.probeContentType(path); - if (EclipseUiUtils.isEmpty(mimeType)) - mimeType = "Unknown"; - addProperty(rightPannelCmp, "Type", mimeType); - addProperty(rightPannelCmp, "Size", FsUiUtils.humanReadableByteCount(Files.size(path), false)); - } - } - rightPannelCmp.layout(true, true); - } catch (IOException e) { - throw new IllegalStateException("Cannot display details for " + path.toString(), e); - } - } - - // Simplify UI implementation - private void addProperty(Composite parent, String propName, String value) { - Label propLbl = new Label(parent, SWT.NONE); - //propLbl.setText(ConnectUtils.replaceAmpersand(propName + ": " + value)); - propLbl.setText(value); - //CmsUiUtils.markup(propLbl); - } -} diff --git a/library/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsFolderComposite.java b/library/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsFolderComposite.java deleted file mode 100644 index a686074..0000000 --- a/library/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsFolderComposite.java +++ /dev/null @@ -1,455 +0,0 @@ -package org.argeo.library.ui; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.attribute.FileTime; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -import javax.jcr.Node; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.cms.ui.fs.FileDrop; -import org.argeo.cms.ui.fs.FsStyles; -import org.argeo.cms.ui.util.CmsUiUtils; -import org.argeo.eclipse.ui.ColumnDefinition; -import org.argeo.eclipse.ui.EclipseUiUtils; -import org.argeo.eclipse.ui.fs.FileIconNameLabelProvider; -import org.argeo.eclipse.ui.fs.FsTableViewer; -import org.argeo.eclipse.ui.fs.FsUiConstants; -import org.argeo.eclipse.ui.fs.FsUiUtils; -import org.argeo.eclipse.ui.fs.NioFileLabelProvider; -import org.argeo.eclipse.ui.fs.ParentDir; -import org.eclipse.jface.viewers.DoubleClickEvent; -import org.eclipse.jface.viewers.IDoubleClickListener; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.SashForm; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.KeyListener; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.MouseAdapter; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.layout.RowData; -import org.eclipse.swt.layout.RowLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.Text; - -/** - * Default Documents folder composite: a sashForm layout with a simple table in - * the middle and an overview at right hand side. - */ -public class DocumentsFolderComposite extends Composite { - private final static Log log = LogFactory.getLog(DocumentsFolderComposite.class); - private static final long serialVersionUID = -40347919096946585L; - - private final Node currentBaseContext; - - private final DocumentsUiService documentUiService = new DocumentsUiService(); - - // UI Parts for the browser - private Composite filterCmp; - private Composite breadCrumbCmp; - private Text filterTxt; - private FsTableViewer directoryDisplayViewer; - private Composite rightPanelCmp; - - private DocumentsContextMenu contextMenu; - private DateFormat dateFormat = new SimpleDateFormat("YYYY-MM-dd HH:mm"); - - // Local context - private Path initialPath; - private Path currentFolder; - - public DocumentsFolderComposite(Composite parent, int style, Node context) { - super(parent, style); - this.currentBaseContext = context; - - this.setLayout(EclipseUiUtils.noSpaceGridLayout()); - - SashForm form = new SashForm(this, SWT.HORIZONTAL); - - Composite centerCmp = new Composite(form, SWT.BORDER | SWT.NO_FOCUS); - createDisplay(centerCmp); - - rightPanelCmp = new Composite(form, SWT.NO_FOCUS); - - form.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - form.setWeights(new int[] { 55, 20 }); - } - - public void populate(Path path) { - initialPath = path; - directoryDisplayViewer.setInitialPath(initialPath); - setInput(path); - } - - void refresh() { - modifyFilter(false); - } - - private void createDisplay(final Composite parent) { - parent.setLayout(EclipseUiUtils.noSpaceGridLayout()); - - // top filter - filterCmp = new Composite(parent, SWT.NO_FOCUS); - filterCmp.setLayoutData(EclipseUiUtils.fillWidth()); - RowLayout rl = new RowLayout(SWT.HORIZONTAL); - rl.wrap = true; - rl.center = true; - filterCmp.setLayout(rl); - // addFilterPanel(filterCmp); - - // Main display - directoryDisplayViewer = new FsTableViewer(parent, SWT.MULTI); - List colDefs = new ArrayList<>(); - colDefs.add(new ColumnDefinition(new FileIconNameLabelProvider(), " Name", 250)); - colDefs.add(new ColumnDefinition(new NioFileLabelProvider(FsUiConstants.PROPERTY_SIZE), "Size", 100)); -// colDefs.add(new ColumnDefinition(new NioFileLabelProvider(FsUiConstants.PROPERTY_TYPE), "Type", 150)); - colDefs.add(new ColumnDefinition(new NioFileLabelProvider(FsUiConstants.PROPERTY_LAST_MODIFIED), - "Last modified", 400)); - final Table table = directoryDisplayViewer.configureDefaultTable(colDefs); - table.setLayoutData(EclipseUiUtils.fillAll()); - - directoryDisplayViewer.addSelectionChangedListener(new ISelectionChangedListener() { - - @Override - public void selectionChanged(SelectionChangedEvent event) { - IStructuredSelection selection = (IStructuredSelection) directoryDisplayViewer.getSelection(); - Path selected = null; - if (selection.isEmpty()) - setSelected(null); - else { - Object o = selection.getFirstElement(); - if (o instanceof Path) - selected = (Path) o; - else if (o instanceof ParentDir) - selected = ((ParentDir) o).getPath(); - } - if (selected != null) { - // TODO manage multiple selection - setSelected(selected); - } - } - }); - - directoryDisplayViewer.addDoubleClickListener(new IDoubleClickListener() { - @Override - public void doubleClick(DoubleClickEvent event) { - IStructuredSelection selection = (IStructuredSelection) directoryDisplayViewer.getSelection(); - Path selected = null; - if (!selection.isEmpty()) { - Object o = selection.getFirstElement(); - if (o instanceof Path) - selected = (Path) o; - else if (o instanceof ParentDir) - selected = ((ParentDir) o).getPath(); - } - if (selected != null) { - if (Files.isDirectory(selected)) - setInput(selected); - else - externalNavigateTo(selected); - } - } - }); - - // The context menu - contextMenu = new DocumentsContextMenu(this, documentUiService); - - table.addMouseListener(new MouseAdapter() { - private static final long serialVersionUID = 6737579410648595940L; - - @Override - public void mouseDown(MouseEvent e) { - if (e.button == 3) { - // contextMenu.setCurrFolderPath(currDisplayedFolder); - contextMenu.show(table, new Point(e.x, e.y), - (IStructuredSelection) directoryDisplayViewer.getSelection(), currentFolder); - } - } - }); - - FileDrop fileDrop = new FileDrop() { - - @Override - protected void processFileUpload(InputStream in, String fileName, String contetnType) throws IOException { - Path file = currentFolder.resolve(fileName); - Files.copy(in, file); - refresh(); - } - }; - fileDrop.createDropTarget(directoryDisplayViewer.getTable()); - } - - /** - * Overwrite to enable single sourcing between workbench and CMS navigation - */ - protected void externalNavigateTo(Path path) { - - } - - private void addPathElementBtn(Path path) { - Button elemBtn = new Button(breadCrumbCmp, SWT.PUSH); - String nameStr; - if (path.toString().equals("/")) - nameStr = "[jcr:root]"; - else - nameStr = path.getFileName().toString(); -// elemBtn.setText(nameStr + " >> "); - elemBtn.setText(nameStr); - CmsUiUtils.style(elemBtn, FsStyles.BREAD_CRUMB_BTN); - elemBtn.addSelectionListener(new SelectionAdapter() { - private static final long serialVersionUID = -4103695476023480651L; - - @Override - public void widgetSelected(SelectionEvent e) { - setInput(path); - } - }); - } - - public void setInput(Path path) { - if (path.equals(currentFolder)) - return; - // below initial path - if (!initialPath.equals(path) && initialPath.startsWith(path)) - return; - currentFolder = path; - - Path diff = initialPath.relativize(currentFolder); - - for (Control child : filterCmp.getChildren()) - if (!child.equals(filterTxt)) - child.dispose(); - - // Bread crumbs - breadCrumbCmp = new Composite(filterCmp, SWT.NO_FOCUS); - CmsUiUtils.style(breadCrumbCmp, FsStyles.BREAD_CRUMB_BTN); - RowLayout breadCrumbLayout = new RowLayout(); - breadCrumbLayout.spacing = 0; - breadCrumbLayout.marginTop = 0; - breadCrumbLayout.marginBottom = 0; - breadCrumbLayout.marginRight = 0; - breadCrumbLayout.marginLeft = 0; - breadCrumbCmp.setLayout(breadCrumbLayout); - addPathElementBtn(initialPath); - Path currTarget = initialPath; - if (!diff.toString().equals("")) - for (Path pathElem : diff) { - currTarget = currTarget.resolve(pathElem); - addPathElementBtn(currTarget); - } - - if (filterTxt != null) { - filterTxt.setText(""); - filterTxt.moveBelow(null); - } else { - modifyFilter(false); - } - setSelected(null); - filterCmp.getParent().layout(true, true); - } - - private void setSelected(Path path) { - if (path == null) - setOverviewInput(currentFolder); - else - setOverviewInput(path); - } - - public Viewer getViewer() { - return directoryDisplayViewer; - } - - /** - * Recreates the content of the box that displays information about the current - * selected Path. - */ - private void setOverviewInput(Path path) { - try { - EclipseUiUtils.clear(rightPanelCmp); - rightPanelCmp.setLayout(new GridLayout()); - if (path != null) { - // if (isImg(context)) { - // EditableImage image = new Img(parent, RIGHT, context, - // imageWidth); - // image.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, - // true, false, - // 2, 1)); - // } - - Label contextL = new Label(rightPanelCmp, SWT.NONE); - contextL.setText(path.getFileName().toString()); - contextL.setFont(EclipseUiUtils.getBoldFont(rightPanelCmp)); - FileTime lastModified = Files.getLastModifiedTime(path); - if (lastModified.toMillis() != 0) - try { - String lastModifiedStr = dateFormat.format(new Date(lastModified.toMillis())); - addProperty(rightPanelCmp, "Last modified", lastModifiedStr); - } catch (Exception e) { - log.error("Workarounded issue while getting last update date for " + path, e); - addProperty(rightPanelCmp, "Last modified", "-"); - } - // addProperty(rightPannelCmp, "Owner", - // Files.getOwner(path).getName()); - if (Files.isDirectory(path)) { - addProperty(rightPanelCmp, "Type", "Folder"); - } else { - String mimeType = Files.probeContentType(path); - if (EclipseUiUtils.isEmpty(mimeType)) - mimeType = "Unknown"; - addProperty(rightPanelCmp, "Type", mimeType); - addProperty(rightPanelCmp, "Size", FsUiUtils.humanReadableByteCount(Files.size(path), false)); - } - - // read all attributes -// Map attrs = Files.readAttributes(path, "*"); -// for (String attr : attrs.keySet()) { -// Object value = attrs.get(attr); -// String str; -// if (value instanceof Calendar) { -// str = dateFormat.format(((Calendar) value).getTime()); -// } else { -// str = value.toString(); -// } -// addProperty(rightPanelCmp, attr, str); -// -// } - } - rightPanelCmp.layout(true, true); - } catch (IOException e) { - throw new IllegalStateException("Cannot display details for " + path.toString(), e); - } - } - - private void addFilterPanel(Composite parent) { - // parent.setLayout(EclipseUiUtils.noSpaceGridLayout(new GridLayout(2, - // false))); - - filterTxt = new Text(parent, SWT.SEARCH | SWT.ICON_CANCEL); - filterTxt.setMessage("Search current folder"); - filterTxt.setLayoutData(new RowData(250, SWT.DEFAULT)); - filterTxt.addModifyListener(new ModifyListener() { - private static final long serialVersionUID = 1L; - - public void modifyText(ModifyEvent event) { - modifyFilter(false); - } - }); - filterTxt.addKeyListener(new KeyListener() { - private static final long serialVersionUID = 2533535233583035527L; - - @Override - public void keyReleased(KeyEvent e) { - } - - @Override - public void keyPressed(KeyEvent e) { - // boolean shiftPressed = (e.stateMask & SWT.SHIFT) != 0; - // // boolean altPressed = (e.stateMask & SWT.ALT) != 0; - // FilterEntitiesVirtualTable currTable = null; - // if (currEdited != null) { - // FilterEntitiesVirtualTable table = - // browserCols.get(currEdited); - // if (table != null && !table.isDisposed()) - // currTable = table; - // } - // - // if (e.keyCode == SWT.ARROW_DOWN) - // currTable.setFocus(); - // else if (e.keyCode == SWT.BS) { - // if (filterTxt.getText().equals("") - // && !(currEdited.getNameCount() == 1 || - // currEdited.equals(initialPath))) { - // Path oldEdited = currEdited; - // Path parentPath = currEdited.getParent(); - // setEdited(parentPath); - // if (browserCols.containsKey(parentPath)) - // browserCols.get(parentPath).setSelected(oldEdited); - // filterTxt.setFocus(); - // e.doit = false; - // } - // } else if (e.keyCode == SWT.TAB && !shiftPressed) { - // Path uniqueChild = getOnlyChild(currEdited, - // filterTxt.getText()); - // if (uniqueChild != null) { - // // Highlight the unique chosen child - // currTable.setSelected(uniqueChild); - // setEdited(uniqueChild); - // } - // filterTxt.setFocus(); - // e.doit = false; - // } - } - }); - } - - // private Path getOnlyChild(Path parent, String filter) { - // try (DirectoryStream stream = - // Files.newDirectoryStream(currDisplayedFolder, filter + "*")) { - // Path uniqueChild = null; - // boolean moreThanOne = false; - // loop: for (Path entry : stream) { - // if (uniqueChild == null) { - // uniqueChild = entry; - // } else { - // moreThanOne = true; - // break loop; - // } - // } - // if (!moreThanOne) - // return uniqueChild; - // return null; - // } catch (IOException ioe) { - // throw new DocumentsException( - // "Unable to determine unique child existence and get it under " + parent + - // " with filter " + filter, - // ioe); - // } - // } - - private void modifyFilter(boolean fromOutside) { - if (!fromOutside) - if (currentFolder != null) { - String filter; - if (filterTxt != null) - filter = filterTxt.getText() + "*"; - else - filter = "*"; - directoryDisplayViewer.setInput(currentFolder, filter); - } - } - - // Simplify UI implementation - private void addProperty(Composite parent, String propName, String value) { - Label propLbl = new Label(parent, SWT.NONE); - //propLbl.setText(ConnectUtils.replaceAmpersand(propName + ": " + value)); - propLbl.setText(value); - //CmsUiUtils.markup(propLbl); - } - - public Path getCurrentFolder() { - return currentFolder; - } - -} diff --git a/library/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsFolderUiProvider.java b/library/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsFolderUiProvider.java deleted file mode 100644 index bdc194b..0000000 --- a/library/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsFolderUiProvider.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.argeo.library.ui; - -import java.nio.file.Path; -import java.nio.file.spi.FileSystemProvider; - -import javax.jcr.Node; -import javax.jcr.RepositoryException; - -import org.argeo.cms.fs.CmsFsUtils; -import org.argeo.cms.ui.CmsUiProvider; -import org.argeo.cms.ui.CmsView; -import org.argeo.cms.ui.util.CmsUiUtils; -import org.argeo.jcr.Jcr; -import org.argeo.suite.ui.SuiteEvent; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; - -/** UI provider of a document folder. */ -public class DocumentsFolderUiProvider implements CmsUiProvider { - private FileSystemProvider nodeFileSystemProvider; - - @Override - public Control createUi(Composite parent, Node context) throws RepositoryException { - CmsView cmsView = CmsView.getCmsView(parent); - DocumentsFolderComposite dfc = new DocumentsFolderComposite(parent, SWT.NONE, context) { - - @Override - protected void externalNavigateTo(Path path) { - Node folderNode = cmsView.doAs(() -> CmsFsUtils.getNode(Jcr.getSession(context).getRepository(), path)); - parent.addDisposeListener((e1) -> Jcr.logout(folderNode)); - cmsView.sendEvent(SuiteEvent.openNewPart.topic(), SuiteEvent.eventProperties(folderNode)); - } - }; - dfc.setLayoutData(CmsUiUtils.fillAll()); - dfc.populate(cmsView.doAs(() -> CmsFsUtils.getPath(nodeFileSystemProvider, context))); - return dfc; - } - - public void setNodeFileSystemProvider(FileSystemProvider nodeFileSystemProvider) { - this.nodeFileSystemProvider = nodeFileSystemProvider; - } - -} diff --git a/library/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsTreeUiProvider.java b/library/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsTreeUiProvider.java deleted file mode 100644 index 4660515..0000000 --- a/library/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsTreeUiProvider.java +++ /dev/null @@ -1,80 +0,0 @@ -package org.argeo.library.ui; - -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.spi.FileSystemProvider; - -import javax.jcr.Node; -import javax.jcr.Repository; -import javax.jcr.RepositoryException; - -import org.argeo.api.NodeConstants; -import org.argeo.api.NodeUtils; -import org.argeo.cms.fs.CmsFsUtils; -import org.argeo.cms.ui.CmsUiProvider; -import org.argeo.cms.ui.CmsView; -import org.argeo.cms.ui.util.CmsUiUtils; -import org.argeo.eclipse.ui.fs.FsTreeViewer; -import org.argeo.jcr.Jcr; -import org.argeo.suite.ui.SuiteEvent; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; - -/** Tree view of a user root folders. */ -public class DocumentsTreeUiProvider implements CmsUiProvider { - private FileSystemProvider nodeFileSystemProvider; - private Repository repository; - - @Override - public Control createUi(Composite parent, Node context) throws RepositoryException { - parent.setLayout(new GridLayout()); - FsTreeViewer fsTreeViewer = new FsTreeViewer(parent, SWT.NONE); - fsTreeViewer.configureDefaultSingleColumnTable(500); - CmsView cmsView = CmsView.getCmsView(parent); - Node homeNode = NodeUtils.getUserHome(cmsView.doAs(() -> Jcr.login(repository, NodeConstants.HOME_WORKSPACE))); - parent.addDisposeListener((e1) -> Jcr.logout(homeNode)); - Path homePath = CmsFsUtils.getPath(nodeFileSystemProvider, homeNode); - fsTreeViewer.addSelectionChangedListener((e) -> { - IStructuredSelection selection = (IStructuredSelection) fsTreeViewer.getSelection(); - if (selection.isEmpty()) - return; - else { - Path newSelected = (Path) selection.getFirstElement(); - if (Files.isDirectory(newSelected)) { - Node folderNode = cmsView.doAs(() -> CmsFsUtils.getNode(repository, newSelected)); - parent.addDisposeListener((e1) -> Jcr.logout(folderNode)); - cmsView.sendEvent(SuiteEvent.refreshPart.topic(), SuiteEvent.eventProperties(folderNode)); - } - } - }); - fsTreeViewer.addDoubleClickListener((e) -> { - IStructuredSelection selection = (IStructuredSelection) fsTreeViewer.getSelection(); - if (selection.isEmpty()) - return; - else { - Path newSelected = (Path) selection.getFirstElement(); - if (Files.isDirectory(newSelected)) { - Node folderNode = cmsView.doAs(() -> CmsFsUtils.getNode(repository, newSelected)); - parent.addDisposeListener((e1) -> Jcr.logout(folderNode)); - cmsView.sendEvent(SuiteEvent.openNewPart.topic(), SuiteEvent.eventProperties(folderNode)); - } - } - }); - fsTreeViewer.setPathsInput(homePath); - fsTreeViewer.getControl().setLayoutData(CmsUiUtils.fillAll()); - fsTreeViewer.getControl().getParent().layout(true, true); - return fsTreeViewer.getControl(); - } - - public void setNodeFileSystemProvider(FileSystemProvider nodeFileSystemProvider) { - this.nodeFileSystemProvider = nodeFileSystemProvider; - } - - public void setRepository(Repository repository) { - this.repository = repository; - } - -} diff --git a/library/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsUiService.java b/library/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsUiService.java deleted file mode 100644 index ad13d28..0000000 --- a/library/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsUiService.java +++ /dev/null @@ -1,310 +0,0 @@ -package org.argeo.library.ui; - -import static org.argeo.cms.ui.dialogs.CmsMessageDialog.openConfirm; -import static org.argeo.cms.ui.dialogs.CmsMessageDialog.openError; -import static org.argeo.cms.ui.dialogs.SingleValueDialog.ask; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.lang.reflect.Method; -import java.net.URI; -import java.nio.file.DirectoryNotEmptyException; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.cms.ui.dialogs.CmsFeedback; -import org.argeo.eclipse.ui.EclipseUiUtils; -import org.argeo.eclipse.ui.specific.OpenFile; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.FileDialog; -import org.eclipse.swt.widgets.Shell; - -public class DocumentsUiService { - private final static Log log = LogFactory.getLog(DocumentsUiService.class); - - // Default known actions - public final static String ACTION_ID_CREATE_FOLDER = "createFolder"; - public final static String ACTION_ID_BOOKMARK_FOLDER = "bookmarkFolder"; - public final static String ACTION_ID_SHARE_FOLDER = "shareFolder"; - public final static String ACTION_ID_DOWNLOAD_FOLDER = "downloadFolder"; - public final static String ACTION_ID_RENAME = "rename"; - public final static String ACTION_ID_DELETE = "delete"; - public final static String ACTION_ID_UPLOAD_FILE = "uploadFiles"; - // public final static String ACTION_ID_OPEN = "open"; - public final static String ACTION_ID_DELETE_BOOKMARK = "deleteBookmark"; - public final static String ACTION_ID_RENAME_BOOKMARK = "renameBookmark"; - - public String getLabel(String actionId) { - switch (actionId) { - case ACTION_ID_CREATE_FOLDER: - return "Create Folder"; - case ACTION_ID_BOOKMARK_FOLDER: - return "Bookmark Folder"; - case ACTION_ID_SHARE_FOLDER: - return "Share Folder"; - case ACTION_ID_DOWNLOAD_FOLDER: - return "Download as zip archive"; - case ACTION_ID_RENAME: - return "Rename"; - case ACTION_ID_DELETE: - return "Delete"; - case ACTION_ID_UPLOAD_FILE: - return "Upload Files"; -// case ACTION_ID_OPEN: -// return "Open"; - case ACTION_ID_DELETE_BOOKMARK: - return "Delete bookmark"; - case ACTION_ID_RENAME_BOOKMARK: - return "Rename bookmark"; - default: - throw new IllegalArgumentException("Unknown action ID " + actionId); - } - } - - public void openFile(Path toOpenPath) { - try { - String name = toOpenPath.getFileName().toString(); - File tmpFile = File.createTempFile("tmp", name); - tmpFile.deleteOnExit(); - try (OutputStream os = new FileOutputStream(tmpFile)) { - Files.copy(toOpenPath, os); - } catch (IOException e) { - throw new IllegalStateException("Cannot open copy " + name + " to tmpFile.", e); - } - String uri = Paths.get(tmpFile.getAbsolutePath()).toUri().toString(); - Map params = new HashMap(); - params.put(OpenFile.PARAM_FILE_NAME, name); - params.put(OpenFile.PARAM_FILE_URI, uri); - // FIXME open file without a command - // CommandUtils.callCommand(OpenFile.ID, params); - } catch (IOException e1) { - throw new IllegalStateException("Cannot create tmp copy of " + toOpenPath, e1); - } - } - - public boolean deleteItems(Shell shell, IStructuredSelection selection) { - if (selection.isEmpty()) - return false; - - StringBuilder builder = new StringBuilder(); - @SuppressWarnings("unchecked") - Iterator iterator = selection.iterator(); - List paths = new ArrayList<>(); - - while (iterator.hasNext()) { - Path path = (Path) iterator.next(); - builder.append(path.getFileName() + ", "); - paths.add(path); - } - String msg = "You are about to delete following elements: " + builder.substring(0, builder.length() - 2) - + ". Are you sure?"; - if (openConfirm(msg)) { - for (Path path : paths) { - try { - // recursively delete directory and its content - Files.walkFileTree(path, new SimpleFileVisitor() { - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - Files.delete(file); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { - Files.delete(dir); - return FileVisitResult.CONTINUE; - } - }); - } catch (DirectoryNotEmptyException e) { - String errMsg = path.getFileName() + " cannot be deleted: directory is not empty."; - openError( errMsg); - throw new IllegalArgumentException("Cannot delete path " + path, e); - } catch (IOException e) { - String errMsg = e.toString(); - openError(errMsg); - throw new IllegalArgumentException("Cannot delete path " + path, e); - } - } - return true; - } - return false; - } - - public boolean renameItem(Shell shell, Path parentFolderPath, Path toRenamePath) { - String msg = "Enter a new name:"; - String name = ask( msg, toRenamePath.getFileName().toString()); - // TODO enhance check of name validity - if (EclipseUiUtils.notEmpty(name)) { - try { - Path child = parentFolderPath.resolve(name); - if (Files.exists(child)) { - String errMsg = "An object named " + name + " already exists at " + parentFolderPath.toString() - + ", please provide another name"; - openError( errMsg); - throw new IllegalArgumentException(errMsg); - } else { - Files.move(toRenamePath, child); - return true; - } - } catch (IOException e) { - throw new IllegalStateException("Cannot rename " + name + " at " + parentFolderPath.toString(), e); - } - } - return false; - } - - public boolean createFolder(Shell shell, Path currFolderPath) { - String msg = "Enter a name:"; - String name = ask( msg); - // TODO enhance check of name validity - if (EclipseUiUtils.notEmpty(name)) { - name = name.trim(); - try { - Path child = currFolderPath.resolve(name); - if (Files.exists(child)) { - String errMsg = "A folder named " + name + " already exists at " + currFolderPath.toString() - + ", cannot create"; - openError(errMsg); - throw new IllegalArgumentException(errMsg); - } else { - Files.createDirectories(child); - return true; - } - } catch (IOException e) { - throw new IllegalStateException("Cannot create folder " + name + " at " + currFolderPath.toString(), e); - } - } - return false; - } - -// public void bookmarkFolder(Path toBookmarkPath, Repository repository, DocumentsService documentsService) { -// String msg = "Provide a name:"; -// String name = SingleQuestion.ask("Create bookmark", msg, toBookmarkPath.getFileName().toString()); -// if (EclipseUiUtils.notEmpty(name)) -// documentsService.createFolderBookmark(toBookmarkPath, name, repository); -// } - - public boolean uploadFiles(Shell shell, Path currFolderPath) { -// shell = Display.getCurrent().getActiveShell();// ignore argument - try { - FileDialog dialog = new FileDialog(shell, SWT.MULTI); - dialog.setText("Choose one or more files to upload"); - - if (EclipseUiUtils.notEmpty(dialog.open())) { - String[] names = dialog.getFileNames(); - // Workaround small differences between RAP and RCP - // 1. returned names are absolute path on RAP and - // relative in RCP - // 2. in RCP we must use getFilterPath that does not - // exists on RAP - Method filterMethod = null; - Path parPath = null; - try { - filterMethod = dialog.getClass().getDeclaredMethod("getFilterPath"); - String filterPath = (String) filterMethod.invoke(dialog); - parPath = Paths.get(filterPath); - } catch (NoSuchMethodException nsme) { // RAP - } - if (names.length == 0) - return false; - else { - loop: for (String name : names) { - Path tmpPath = Paths.get(name); - if (parPath != null) - tmpPath = parPath.resolve(tmpPath); - if (Files.exists(tmpPath)) { - URI uri = tmpPath.toUri(); - String uriStr = uri.toString(); - - if (Files.isDirectory(tmpPath)) { - openError( - "Upload of directories in the system is not yet implemented"); - continue loop; - } - Path targetPath = currFolderPath.resolve(tmpPath.getFileName().toString()); - try (InputStream in = new FileInputStream(tmpPath.toFile())) { - Files.copy(in, targetPath); - Files.delete(tmpPath); - } - if (log.isDebugEnabled()) - log.debug("copied uploaded file " + uriStr + " to " + targetPath.toString()); - } else { - String msg = "Cannot copy tmp file from " + tmpPath.toString(); - if (parPath != null) - msg += "\nPlease remember that file upload fails when choosing files from the \"Recently Used\" bookmarks on some OS"; - openError( msg); - continue loop; - } - } - return true; - } - } - } catch (Exception e) { - CmsFeedback.show("Cannot import files to " + currFolderPath,e); - } - return false; - } - -// public boolean deleteBookmark(Shell shell, IStructuredSelection selection, Node bookmarkParent) { -// if (selection.isEmpty()) -// return false; -// -// StringBuilder builder = new StringBuilder(); -// @SuppressWarnings("unchecked") -// Iterator iterator = selection.iterator(); -// List nodes = new ArrayList<>(); -// -// while (iterator.hasNext()) { -// Node node = (Node) iterator.next(); -// builder.append(Jcr.get(node, Property.JCR_TITLE) + ", "); -// nodes.add(node); -// } -// String msg = "You are about to delete following bookmark: " + builder.substring(0, builder.length() - 2) -// + ". Are you sure?"; -// if (MessageDialog.openConfirm(shell, "Confirm deletion", msg)) { -// Session session = Jcr.session(bookmarkParent); -// try { -// if (session.hasPendingChanges()) -// throw new DocumentsException("Cannot remove bookmarks, session is not clean"); -// for (Node path : nodes) -// path.remove(); -// bookmarkParent.getSession().save(); -// return true; -// } catch (RepositoryException e) { -// JcrUtils.discardQuietly(session); -// throw new DocumentsException("Cannot delete bookmarks " + builder.toString(), e); -// } -// } -// return false; -// } - -// public boolean renameBookmark(IStructuredSelection selection) { -// if (selection.isEmpty() || selection.size() > 1) -// return false; -// Node toRename = (Node) selection.getFirstElement(); -// String msg = "Please provide a new name."; -// String name = SingleQuestion.ask("Rename bookmark", msg, ConnectJcrUtils.get(toRename, Property.JCR_TITLE)); -// if (EclipseUiUtils.notEmpty(name) -// && ConnectJcrUtils.setJcrProperty(toRename, Property.JCR_TITLE, PropertyType.STRING, name)) { -// ConnectJcrUtils.saveIfNecessary(toRename); -// return true; -// } -// return false; -// } -} diff --git a/library/pom.xml b/library/pom.xml deleted file mode 100644 index 6cc06d2..0000000 --- a/library/pom.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - 4.0.0 - - org.argeo.suite - argeo-suite - 2.3-SNAPSHOT - .. - - library - Argeo Library Components - pom - - org.argeo.library.ui - - diff --git a/org.argeo.entity.api/.classpath b/org.argeo.entity.api/.classpath new file mode 100644 index 0000000..e801ebf --- /dev/null +++ b/org.argeo.entity.api/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.argeo.entity.api/.gitignore b/org.argeo.entity.api/.gitignore new file mode 100644 index 0000000..09e3bc9 --- /dev/null +++ b/org.argeo.entity.api/.gitignore @@ -0,0 +1,2 @@ +/bin/ +/target/ diff --git a/org.argeo.entity.api/.project b/org.argeo.entity.api/.project new file mode 100644 index 0000000..1269cce --- /dev/null +++ b/org.argeo.entity.api/.project @@ -0,0 +1,28 @@ + + + org.argeo.entity.api + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/org.argeo.entity.api/META-INF/.gitignore b/org.argeo.entity.api/META-INF/.gitignore new file mode 100644 index 0000000..4854a41 --- /dev/null +++ b/org.argeo.entity.api/META-INF/.gitignore @@ -0,0 +1 @@ +/MANIFEST.MF diff --git a/org.argeo.entity.api/bnd.bnd b/org.argeo.entity.api/bnd.bnd new file mode 100644 index 0000000..ab46172 --- /dev/null +++ b/org.argeo.entity.api/bnd.bnd @@ -0,0 +1,5 @@ +Require-Capability:\ +cms.datamodel;filter:="(name=jcrx)" + +Provide-Capability:\ +cms.datamodel; name=entity; cnd=/org/argeo/entity/entity.cnd diff --git a/org.argeo.entity.api/build.properties b/org.argeo.entity.api/build.properties new file mode 100644 index 0000000..34d2e4d --- /dev/null +++ b/org.argeo.entity.api/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/org.argeo.entity.api/pom.xml b/org.argeo.entity.api/pom.xml new file mode 100644 index 0000000..d20f3f6 --- /dev/null +++ b/org.argeo.entity.api/pom.xml @@ -0,0 +1,21 @@ + + + 4.0.0 + + org.argeo.suite + argeo-suite + 2.3-SNAPSHOT + .. + + org.argeo.entity.api + Entity API + jar + + + + org.argeo.commons + org.argeo.enterprise + ${version.argeo-commons} + + + diff --git a/org.argeo.entity.api/src/org/argeo/entity/EntityConstants.java b/org.argeo.entity.api/src/org/argeo/entity/EntityConstants.java new file mode 100644 index 0000000..93021e0 --- /dev/null +++ b/org.argeo.entity.api/src/org/argeo/entity/EntityConstants.java @@ -0,0 +1,8 @@ +package org.argeo.entity; + +/** 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"; + +} diff --git a/org.argeo.entity.api/src/org/argeo/entity/EntityDefinition.java b/org.argeo.entity.api/src/org/argeo/entity/EntityDefinition.java new file mode 100644 index 0000000..08aff61 --- /dev/null +++ b/org.argeo.entity.api/src/org/argeo/entity/EntityDefinition.java @@ -0,0 +1,10 @@ +package org.argeo.entity; + +import javax.jcr.Node; + +/** The definition of an entity, a composite configurable data structure. */ +public interface EntityDefinition { + String getEditorId(Node entity); + + String getType(); +} diff --git a/org.argeo.entity.api/src/org/argeo/entity/EntityMimeType.java b/org.argeo.entity.api/src/org/argeo/entity/EntityMimeType.java new file mode 100644 index 0000000..997f1be --- /dev/null +++ b/org.argeo.entity.api/src/org/argeo/entity/EntityMimeType.java @@ -0,0 +1,60 @@ +package org.argeo.entity; + +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; + } + +} diff --git a/org.argeo.entity.api/src/org/argeo/entity/EntityNames.java b/org.argeo.entity.api/src/org/argeo/entity/EntityNames.java new file mode 100644 index 0000000..ede7447 --- /dev/null +++ b/org.argeo.entity.api/src/org/argeo/entity/EntityNames.java @@ -0,0 +1,61 @@ +package org.argeo.entity; + +import org.argeo.naming.LdapAttrs; + +/** 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"; + + final String ENTITY_TYPE = "entity:type"; + // final String ENTITY_UID = "entity:uid"; + // final String ENTITY_NAME = "entity:name"; + + // GENERIC CONCEPTS + /** The language which is relevant. */ + final String XML_LANG = "xml:lang"; + /** The date which is relevant. */ + final String ENTITY_DATE = "entity:date"; + @Deprecated + final String ENTITY_RELATED_TO = "entity:relatedTo"; + + // DEFAULT FOLDER NAMES + final String MEDIA = "media"; + final String FILES = "files"; + + // LDAP-LIKE ENTITIES + @Deprecated + final String DISPLAY_NAME = LdapAttrs.displayName.property(); + // Persons + @Deprecated + final String GIVEN_NAME = LdapAttrs.givenName.property(); + @Deprecated + final String SURNAME = LdapAttrs.sn.property(); + @Deprecated + final String EMAIL = LdapAttrs.mail.property(); + @Deprecated + final String OU = LdapAttrs.ou.property(); + + // WGS84 + final String GEO_LAT = "geo:lat"; + final String GEO_LONG = "geo:long"; + final String GEO_ALT = "geo:alt"; + + // SVG + final String SVG_WIDTH = "svg:width"; + final String SVG_HEIGHT = "svg:height"; + final String SVG_LENGTH = "svg:length"; + final String SVG_UNIT = "svg:unit"; + final String SVG_DUR = "svg:dur"; + final String SVG_DIRECTION = "svg:direction"; +} diff --git a/org.argeo.entity.api/src/org/argeo/entity/EntityType.java b/org.argeo.entity.api/src/org/argeo/entity/EntityType.java new file mode 100644 index 0000000..089cdcf --- /dev/null +++ b/org.argeo.entity.api/src/org/argeo/entity/EntityType.java @@ -0,0 +1,42 @@ +package org.argeo.entity; + +/** Types related to entities. */ +public enum EntityType implements JcrName { + // entity + entity, local, relatedTo, + // structure + space, document, + // typology + typologies, terms, term, + // form + form, formSet, formSubmission, + // graphics + box, + // geography + geopoint, bearing, + // ldap + person, user; + + @Override + public String getPrefix() { + return prefix(); + } + + public static String prefix() { + return "entity"; + } + + public String basePath() { + return '/' + name(); + } + + @Override + public String getNamespace() { + return namespace(); + } + + public static String namespace() { + return "http://www.argeo.org/ns/entity"; + } + +} diff --git a/org.argeo.entity.api/src/org/argeo/entity/EntityTypes.java b/org.argeo.entity.api/src/org/argeo/entity/EntityTypes.java new file mode 100644 index 0000000..ef35147 --- /dev/null +++ b/org.argeo.entity.api/src/org/argeo/entity/EntityTypes.java @@ -0,0 +1,10 @@ +package org.argeo.entity; + +/** Types related to entities. */ +@Deprecated +public interface EntityTypes { + final static String ENTITY_ENTITY = "entity:entity"; + final static String ENTITY_DEFINITION = "entity:definition"; + + final static String ENTITY_PERSON = "entity:person"; +} diff --git a/org.argeo.entity.api/src/org/argeo/entity/JcrName.java b/org.argeo.entity.api/src/org/argeo/entity/JcrName.java new file mode 100644 index 0000000..322c42e --- /dev/null +++ b/org.argeo.entity.api/src/org/argeo/entity/JcrName.java @@ -0,0 +1,30 @@ +package org.argeo.entity; + +import java.util.function.Supplier; + +/** Can be applied to {@link Enum}s in order to generate prefixed names. */ +@FunctionalInterface +public interface JcrName extends Supplier { + String name(); + + default String getPrefix() { + return null; + } + + default String getNamespace() { + return null; + } + + @Override + default String get() { + String prefix = getPrefix(); + return prefix != null ? prefix + ":" + name() : name(); + } + + default String withNamespace() { + String namespace = getNamespace(); + if (namespace == null) + throw new UnsupportedOperationException("No namespace is specified for " + getClass()); + return "{" + namespace + "}" + name(); + } +} diff --git a/org.argeo.entity.api/src/org/argeo/entity/Term.java b/org.argeo.entity.api/src/org/argeo/entity/Term.java new file mode 100644 index 0000000..3bf075a --- /dev/null +++ b/org.argeo.entity.api/src/org/argeo/entity/Term.java @@ -0,0 +1,22 @@ +package org.argeo.entity; + +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 getSubTerms(); + + Term getParentTerm(); + +} diff --git a/org.argeo.entity.api/src/org/argeo/entity/TermsManager.java b/org.argeo.entity.api/src/org/argeo/entity/TermsManager.java new file mode 100644 index 0000000..7564ff9 --- /dev/null +++ b/org.argeo.entity.api/src/org/argeo/entity/TermsManager.java @@ -0,0 +1,13 @@ +package org.argeo.entity; + +import java.util.List; + +/** Provides optimised access and utilities around terms typologies. */ +public interface TermsManager { + Typology getTypology(String typology); + + Term getTerm(String id); + + List listAllTerms(String typology); + +} diff --git a/org.argeo.entity.api/src/org/argeo/entity/Typology.java b/org.argeo.entity.api/src/org/argeo/entity/Typology.java new file mode 100644 index 0000000..5be27e3 --- /dev/null +++ b/org.argeo.entity.api/src/org/argeo/entity/Typology.java @@ -0,0 +1,15 @@ +package org.argeo.entity; + +import java.util.List; + +/** A structured and exhaustive set of {@link Term}s. */ +public interface Typology { + + String getId(); + + boolean isFlat(); + + List getSubTerms(); + + Term findTermByName(String name); +} diff --git a/org.argeo.entity.api/src/org/argeo/entity/entity.cnd b/org.argeo.entity.api/src/org/argeo/entity/entity.cnd new file mode 100644 index 0000000..2ea89f9 --- /dev/null +++ b/org.argeo.entity.api/src/org/argeo/entity/entity.cnd @@ -0,0 +1,114 @@ +// Standard namespaces + + +// see https://www.w3.org/2003/01/geo/ + + + + + + +[entity:entity] > mix:created, mix:referenceable +mixin + +[entity:local] > entity:entity +mixin +- entity:type (String) m + +[entity:relatedTo] +mixin ++ entity:relatedTo (nt:address) * + +// +// ENTITY DEFINITION +// +//[entity:definition] > entity:composite, mix:created, mix:lastModified, mix:referenceable +//- entity:type (String) multiple + +//[entity:part] + +//[entity:reference] + +//[entity:composite] +//orderable +//+ * (entity:part) +//+ * (entity:reference) +//+ * (entity:composite) + +[entity:query] > nt:query, mix:referenceable + +[entity:querySet] ++ * (entity:query) = entity:query * + +// +// STRUCTURE +// +[entity:space] +mixin + +[entity:document] +mixin + +// +// TYPOLOGY +// +[entity:typologies] ++ * (entity:terms) = entity:terms + +[entity:term] +orderable +- name (NAME) +- * (*) ++ term (entity:term) = entity:term * + +[entity:terms] > mix:referenceable +orderable ++ term (entity:term) = entity:term * + +// +// FORM +// +[entity:form] +mixin ++ queries (entity:querySet) = entity:querySet + +[entity:formSubmission] +mixin + +[entity:formSet] > mix:title +mixin + +// +// GRAPHICS +// +[entity:box] +mixin +- svg:width (DOUBLE) +- svg:height (DOUBLE) +- svg:length (DOUBLE) +- svg:unit (STRING) +- svg:dur (DOUBLE) + +// LDAP-LIKE ENTITIES +// A real person +[entity:person] > entity:entity +mixin +- ldap:sn (String) +- ldap:givenName (String) +- ldap:mail (String) * + +[entity:user] > entity:person +mixin +- ldap:distinguishedName (String) +- ldap:uid (String) + +// GEOGRAPHY +[entity:geopoint] +mixin +- geo:long (DOUBLE) +- geo:lat (DOUBLE) +- geo:alt (DOUBLE) + +[entity:bearing] +mixin +- svg:direction (DOUBLE) diff --git a/org.argeo.entity.core/.classpath b/org.argeo.entity.core/.classpath new file mode 100644 index 0000000..e801ebf --- /dev/null +++ b/org.argeo.entity.core/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.argeo.entity.core/.gitignore b/org.argeo.entity.core/.gitignore new file mode 100644 index 0000000..09e3bc9 --- /dev/null +++ b/org.argeo.entity.core/.gitignore @@ -0,0 +1,2 @@ +/bin/ +/target/ diff --git a/org.argeo.entity.core/.project b/org.argeo.entity.core/.project new file mode 100644 index 0000000..1acff84 --- /dev/null +++ b/org.argeo.entity.core/.project @@ -0,0 +1,28 @@ + + + org.argeo.entity.core + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/org.argeo.entity.core/META-INF/.gitignore b/org.argeo.entity.core/META-INF/.gitignore new file mode 100644 index 0000000..4854a41 --- /dev/null +++ b/org.argeo.entity.core/META-INF/.gitignore @@ -0,0 +1 @@ +/MANIFEST.MF diff --git a/org.argeo.entity.core/bnd.bnd b/org.argeo.entity.core/bnd.bnd new file mode 100644 index 0000000..e69de29 diff --git a/org.argeo.entity.core/build.properties b/org.argeo.entity.core/build.properties new file mode 100644 index 0000000..34d2e4d --- /dev/null +++ b/org.argeo.entity.core/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/org.argeo.entity.core/pom.xml b/org.argeo.entity.core/pom.xml new file mode 100644 index 0000000..090ce00 --- /dev/null +++ b/org.argeo.entity.core/pom.xml @@ -0,0 +1,27 @@ + + + 4.0.0 + + org.argeo.suite + argeo-suite + 2.3-SNAPSHOT + .. + + org.argeo.entity.core + Entity Reference Implementation + jar + + + org.argeo.suite + org.argeo.entity.api + 2.3-SNAPSHOT + + + + + org.argeo.commons + org.argeo.cms + ${version.argeo-commons} + + + diff --git a/org.argeo.entity.core/src/org/argeo/entity/core/JcrEntityDefinition.java b/org.argeo.entity.core/src/org/argeo/entity/core/JcrEntityDefinition.java new file mode 100644 index 0000000..6eb086d --- /dev/null +++ b/org.argeo.entity.core/src/org/argeo/entity/core/JcrEntityDefinition.java @@ -0,0 +1,73 @@ +package org.argeo.entity.core; + +import java.util.Map; + +import javax.jcr.Node; +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +import org.argeo.api.NodeUtils; +import org.argeo.entity.EntityConstants; +import org.argeo.entity.EntityDefinition; +import org.argeo.jcr.Jcr; +import org.osgi.framework.BundleContext; + +/** An entity definition based on a JCR data structure. */ +public class JcrEntityDefinition implements EntityDefinition { + private Repository repository; + + private String type; + private String defaultEditorId; + + public void init(BundleContext bundleContext, Map properties) throws RepositoryException { + Session adminSession = NodeUtils.openDataAdminSession(repository, null); + try { + type = properties.get(EntityConstants.TYPE); + if (type == null) + throw new IllegalArgumentException("Entity type property " + EntityConstants.TYPE + " must be set."); + defaultEditorId = properties.get(EntityConstants.DEFAULT_EDITOR_ID); +// String definitionPath = EntityNames.ENTITY_DEFINITIONS_PATH + '/' + type; +// if (!adminSession.itemExists(definitionPath)) { +// Node entityDefinition = JcrUtils.mkdirs(adminSession, definitionPath, EntityTypes.ENTITY_DEFINITION); +//// entityDefinition.addMixin(EntityTypes.ENTITY_DEFINITION); +// adminSession.save(); +// } + initJcr(adminSession); + } finally { + Jcr.logout(adminSession); + } + } + + /** To be overridden in order to perform additional initialisations. */ + protected void initJcr(Session adminSession) throws RepositoryException { + + } + + public void destroy(BundleContext bundleContext, Map properties) throws RepositoryException { + + } + + @Override + public String getEditorId(Node entity) { + return defaultEditorId; + } + + @Override + public String getType() { + return type; + } + + protected Repository getRepository() { + return repository; + } + + public void setRepository(Repository repository) { + this.repository = repository; + } + + public String toString() { + return "Entity Definition " + getType(); + } + +} diff --git a/org.argeo.entity.ui/.classpath b/org.argeo.entity.ui/.classpath new file mode 100644 index 0000000..e801ebf --- /dev/null +++ b/org.argeo.entity.ui/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.argeo.entity.ui/.gitignore b/org.argeo.entity.ui/.gitignore new file mode 100644 index 0000000..09e3bc9 --- /dev/null +++ b/org.argeo.entity.ui/.gitignore @@ -0,0 +1,2 @@ +/bin/ +/target/ diff --git a/org.argeo.entity.ui/.project b/org.argeo.entity.ui/.project new file mode 100644 index 0000000..a1f7177 --- /dev/null +++ b/org.argeo.entity.ui/.project @@ -0,0 +1,28 @@ + + + org.argeo.entity.ui + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/org.argeo.entity.ui/META-INF/.gitignore b/org.argeo.entity.ui/META-INF/.gitignore new file mode 100644 index 0000000..4854a41 --- /dev/null +++ b/org.argeo.entity.ui/META-INF/.gitignore @@ -0,0 +1 @@ +/MANIFEST.MF diff --git a/org.argeo.entity.ui/bnd.bnd b/org.argeo.entity.ui/bnd.bnd new file mode 100644 index 0000000..e7cd4cb --- /dev/null +++ b/org.argeo.entity.ui/bnd.bnd @@ -0,0 +1,3 @@ +Import-Package:\ +org.eclipse.swt,\ +* \ No newline at end of file diff --git a/org.argeo.entity.ui/build.properties b/org.argeo.entity.ui/build.properties new file mode 100644 index 0000000..34d2e4d --- /dev/null +++ b/org.argeo.entity.ui/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/org.argeo.entity.ui/pom.xml b/org.argeo.entity.ui/pom.xml new file mode 100644 index 0000000..10c5918 --- /dev/null +++ b/org.argeo.entity.ui/pom.xml @@ -0,0 +1,43 @@ + + + 4.0.0 + + org.argeo.suite + argeo-suite + 2.3-SNAPSHOT + .. + + org.argeo.entity.ui + Entity UI + jar + + + org.argeo.suite + org.argeo.entity.core + 2.3-SNAPSHOT + + + + + org.argeo.commons + org.argeo.cms.ui + ${version.argeo-commons} + + + + + org.argeo.commons + org.argeo.eclipse.ui.rap + ${version.argeo-commons} + + + + + org.argeo.tp + argeo-tp-rap-e4 + ${version.argeo-tp} + pom + provided + + + diff --git a/org.argeo.entity.ui/src/org/argeo/entity/ui/forms/AbstractTermsPart.java b/org.argeo.entity.ui/src/org/argeo/entity/ui/forms/AbstractTermsPart.java new file mode 100644 index 0000000..36ae274 --- /dev/null +++ b/org.argeo.entity.ui/src/org/argeo/entity/ui/forms/AbstractTermsPart.java @@ -0,0 +1,131 @@ +package org.argeo.entity.ui.forms; + +import javax.jcr.Item; + +import org.argeo.cms.Localized; +import org.argeo.cms.ui.CmsTheme; +import org.argeo.cms.ui.util.CmsIcon; +import org.argeo.cms.ui.util.CmsUiUtils; +import org.argeo.cms.ui.viewers.EditablePart; +import org.argeo.cms.ui.widgets.ContextOverlay; +import org.argeo.cms.ui.widgets.StyledControl; +import org.argeo.entity.Term; +import org.argeo.entity.TermsManager; +import org.argeo.entity.Typology; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.ToolItem; + +/** Common logic between single and mutliple terms editable part. */ +public abstract class AbstractTermsPart extends StyledControl implements EditablePart { + private static final long serialVersionUID = -5497097995341927710L; + protected final TermsManager termsManager; + protected final Typology typology; + + private final boolean editable; + + private CmsIcon deleteIcon; + private CmsIcon addIcon; + private CmsIcon cancelIcon; + + private Color highlightColor; + private Composite highlight; + + protected final CmsTheme theme; + + public AbstractTermsPart(Composite parent, int style, Item item, TermsManager termsManager, String typology) { + super(parent, style, item); + if (item == null) + throw new IllegalArgumentException("Item cannot be null"); + this.termsManager = termsManager; + this.typology = termsManager.getTypology(typology); + this.theme = CmsTheme.getCmsTheme(parent); + editable = !(SWT.READ_ONLY == (style & SWT.READ_ONLY)); + highlightColor = parent.getDisplay().getSystemColor(SWT.COLOR_GRAY); + } + + public boolean isEditable() { + return editable; + } + + protected void createHighlight(Composite block) { + highlight = new Composite(block, SWT.NONE); + highlight.setBackground(highlightColor); + GridData highlightGd = new GridData(SWT.FILL, SWT.FILL, false, false); + highlightGd.widthHint = 5; + highlightGd.heightHint = 3; + highlight.setLayoutData(highlightGd); + + } + + protected String getTermLabel(Term term) { + if (term instanceof Localized) + return ((Localized) term).lead(); + else + return term.getName(); + + } + + protected abstract void refresh(ContextOverlay contextArea, String filter, Text txt); + + protected boolean isTermSelectable(Term term) { + return true; + } + + protected void processTermListLabel(Term term, Label label) { + + } + + protected void setControlLayoutData(Control control) { + control.setLayoutData(CmsUiUtils.fillAll()); + } + + protected void setContainerLayoutData(Composite composite) { + composite.setLayoutData(CmsUiUtils.fillAll()); + } + + // + // STYLING + // + public void setDeleteIcon(CmsIcon deleteIcon) { + this.deleteIcon = deleteIcon; + } + + public void setAddIcon(CmsIcon addIcon) { + this.addIcon = addIcon; + } + + public void setCancelIcon(CmsIcon cancelIcon) { + this.cancelIcon = cancelIcon; + } + + protected TermsManager getTermsManager() { + return termsManager; + } + + protected void styleDelete(ToolItem deleteItem) { + if (deleteIcon != null) + deleteItem.setImage(deleteIcon.getSmallIcon(theme)); + else + deleteItem.setText("-"); + } + + protected void styleCancel(ToolItem cancelItem) { + if (cancelIcon != null) + cancelItem.setImage(cancelIcon.getSmallIcon(theme)); + else + cancelItem.setText("X"); + } + + protected void styleAdd(ToolItem addItem) { + if (addIcon != null) + addItem.setImage(addIcon.getSmallIcon(theme)); + else + addItem.setText("+"); + } +} diff --git a/org.argeo.entity.ui/src/org/argeo/entity/ui/forms/MultiTermsPart.java b/org.argeo.entity.ui/src/org/argeo/entity/ui/forms/MultiTermsPart.java new file mode 100644 index 0000000..8d40763 --- /dev/null +++ b/org.argeo.entity.ui/src/org/argeo/entity/ui/forms/MultiTermsPart.java @@ -0,0 +1,207 @@ +package org.argeo.entity.ui.forms; + +import java.util.ArrayList; +import java.util.List; + +import javax.jcr.Item; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.cms.ui.forms.FormStyle; +import org.argeo.cms.ui.util.CmsUiUtils; +import org.argeo.cms.ui.viewers.EditablePart; +import org.argeo.cms.ui.widgets.ContextOverlay; +import org.argeo.eclipse.ui.MouseDoubleClick; +import org.argeo.eclipse.ui.MouseDown; +import org.argeo.eclipse.ui.Selected; +import org.argeo.entity.Term; +import org.argeo.entity.TermsManager; +import org.argeo.jcr.Jcr; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.swt.widgets.ToolItem; + +/** {@link EditablePart} for multiple terms. */ +public class MultiTermsPart extends AbstractTermsPart { + private static final long serialVersionUID = -4961135649177920808L; + private final static Log log = LogFactory.getLog(MultiTermsPart.class); + + public MultiTermsPart(Composite parent, int style, Item item, TermsManager termsManager, String typology) { + super(parent, style, item, termsManager, typology); + } + + @Override + protected Control createControl(Composite box, String style) { + Composite placeholder = new Composite(box, SWT.NONE); + + boolean vertical = SWT.VERTICAL == (getStyle() & SWT.VERTICAL); + RowLayout rl = new RowLayout(vertical ? SWT.VERTICAL : SWT.HORIZONTAL); + rl = CmsUiUtils.noMarginsRowLayout(rl); +// rl.wrap = true; +// rl.justify = true; + placeholder.setLayout(rl); + List currentValue = getValue(); + if (currentValue != null && !currentValue.isEmpty()) { + for (Term value : currentValue) { + Composite block = new Composite(placeholder, SWT.NONE); + block.setLayout(CmsUiUtils.noSpaceGridLayout(3)); + Label lbl = new Label(block, SWT.NONE); + String display = getTermLabel(value); + lbl.setText(display); + CmsUiUtils.style(lbl, style == null ? FormStyle.propertyText.style() : style); + processTermListLabel(value, lbl); + if (isEditable()) + lbl.addMouseListener((MouseDoubleClick) (e) -> { + startEditing(); + }); + if (isEditing()) { + ToolBar toolBar = new ToolBar(block, SWT.HORIZONTAL); + ToolItem deleteItem = new ToolItem(toolBar, SWT.FLAT); + styleDelete(deleteItem); + deleteItem.addSelectionListener((Selected) (e) -> { + // we retrieve them again here because they may have changed + List curr = getValue(); + List newValue = new ArrayList<>(); + for (Term v : curr) { + if (!v.equals(value)) + newValue.add(v); + } + setValue(newValue); + block.dispose(); + layout(true, true); + }); + + } + } + } else {// empty + if (isEditable() && !isEditing()) { + ToolBar toolBar = new ToolBar(placeholder, SWT.HORIZONTAL); + ToolItem addItem = new ToolItem(toolBar, SWT.FLAT); + styleAdd(addItem); + addItem.addSelectionListener((Selected) (e) -> { + startEditing(); + }); + } + } + + if (isEditing()) { + Composite block = new Composite(placeholder, SWT.NONE); + block.setLayout(CmsUiUtils.noSpaceGridLayout(3)); + + createHighlight(block); + + Text txt = new Text(block, SWT.SINGLE | SWT.BORDER); + txt.setLayoutData(CmsUiUtils.fillWidth()); +// txt.setMessage("[new]"); + + CmsUiUtils.style(txt, style == null ? FormStyle.propertyText.style() : style); + + ToolBar toolBar = new ToolBar(block, SWT.HORIZONTAL); + ToolItem cancelItem = new ToolItem(toolBar, SWT.FLAT); + styleCancel(cancelItem); + cancelItem.addSelectionListener((Selected) (e) -> { + stopEditing(); + }); + + ContextOverlay contextOverlay = new ContextOverlay(txt, SWT.NONE) { + private static final long serialVersionUID = -7980078594405384874L; + + @Override + protected void onHide() { + stopEditing(); + } + }; + contextOverlay.setLayout(new GridLayout()); + // filter + txt.addModifyListener((e) -> { + String filter = txt.getText().toLowerCase(); + if ("".equals(filter.trim())) + filter = null; + refresh(contextOverlay, filter, txt); + }); + txt.addFocusListener(new FocusListener() { + private static final long serialVersionUID = -6024501573409619949L; + + @Override + public void focusLost(FocusEvent event) { +// if (!contextOverlay.isDisposed() && contextOverlay.isShellVisible()) +// getDisplay().asyncExec(() -> stopEditing()); + } + + @Override + public void focusGained(FocusEvent event) { + // txt.setText(""); + if (!contextOverlay.isDisposed() && !contextOverlay.isShellVisible()) + refresh(contextOverlay, null, txt); + } + }); + layout(new Control[] { txt }); + // getDisplay().asyncExec(() -> txt.setFocus()); + } + return placeholder; + } + + @Override + protected void refresh(ContextOverlay contextArea, String filter, Text txt) { + CmsUiUtils.clear(contextArea); + List terms = termsManager.listAllTerms(typology.getId()); + List currentValue = getValue(); + terms: for (Term term : terms) { + if (currentValue != null && currentValue.contains(term)) + continue terms; + String display = getTermLabel(term); + if (filter != null && !display.toLowerCase().contains(filter)) + continue terms; + Label termL = new Label(contextArea, SWT.WRAP); + termL.setText(display); + processTermListLabel(term, termL); + if (isTermSelectable(term)) + termL.addMouseListener((MouseDown) (e) -> { + List newValue = new ArrayList<>(); + List curr = getValue(); + if (currentValue != null) + newValue.addAll(curr); + newValue.add(term); + setValue(newValue); + contextArea.hide(); + stopEditing(); + }); + } + contextArea.show(); + } + + protected List getValue() { + String property = typology.getId(); + List curr = Jcr.getMultiple(getNode(), property); + List res = new ArrayList<>(); + if (curr != null) + terms: for (String str : curr) { + Term term = termsManager.getTerm(str); + if (term == null) { + log.warn("Ignoring term " + str + " for " + getNode() + ", as it was not found."); + continue terms; + } + res.add(term); + } + return res; + } + + protected void setValue(List value) { + String property = typology.getId(); + List ids = new ArrayList<>(); + for (Term term : value) { + ids.add(term.getId()); + } + Jcr.set(getNode(), property, ids); + Jcr.save(getNode()); + } + +} diff --git a/org.argeo.entity.ui/src/org/argeo/entity/ui/forms/SingleTermPart.java b/org.argeo.entity.ui/src/org/argeo/entity/ui/forms/SingleTermPart.java new file mode 100644 index 0000000..0b5948a --- /dev/null +++ b/org.argeo.entity.ui/src/org/argeo/entity/ui/forms/SingleTermPart.java @@ -0,0 +1,159 @@ +package org.argeo.entity.ui.forms; + +import java.util.List; + +import javax.jcr.Item; + +import org.argeo.cms.ui.forms.FormStyle; +import org.argeo.cms.ui.util.CmsUiUtils; +import org.argeo.cms.ui.viewers.EditablePart; +import org.argeo.cms.ui.widgets.ContextOverlay; +import org.argeo.eclipse.ui.MouseDoubleClick; +import org.argeo.eclipse.ui.MouseDown; +import org.argeo.eclipse.ui.Selected; +import org.argeo.entity.Term; +import org.argeo.entity.TermsManager; +import org.argeo.jcr.Jcr; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.swt.widgets.ToolItem; + +/** {@link EditablePart} for terms. */ +public class SingleTermPart extends AbstractTermsPart { + private static final long serialVersionUID = -4961135649177920808L; + + public SingleTermPart(Composite parent, int style, Item item, TermsManager termsManager, String typology) { + super(parent, style, item, termsManager, typology); + } + + @Override + protected Control createControl(Composite box, String style) { + if (isEditing()) { + Composite block = new Composite(box, SWT.NONE); + block.setLayout(CmsUiUtils.noSpaceGridLayout(3)); + + createHighlight(block); + + Text txt = new Text(block, SWT.SINGLE | SWT.BORDER); + CmsUiUtils.style(txt, style == null ? FormStyle.propertyText.style() : style); + + ToolBar toolBar = new ToolBar(block, SWT.HORIZONTAL); + ToolItem deleteItem = new ToolItem(toolBar, SWT.PUSH); + styleDelete(deleteItem); + deleteItem.addSelectionListener((Selected) (e) -> { + setValue(null); + stopEditing(); + }); + ToolItem cancelItem = new ToolItem(toolBar, SWT.PUSH); + styleCancel(cancelItem); + cancelItem.addSelectionListener((Selected) (e) -> { + stopEditing(); + }); + + ContextOverlay contextOverlay = new ContextOverlay(txt, SWT.NONE) { + private static final long serialVersionUID = -7980078594405384874L; + + @Override + protected void onHide() { + stopEditing(); + } + }; + contextOverlay.setLayout(new GridLayout()); + // filter + txt.addModifyListener((e) -> { + String filter = txt.getText().toLowerCase(); + if ("".equals(filter.trim())) + filter = null; + refresh(contextOverlay, filter, txt); + }); + txt.addFocusListener(new FocusListener() { + private static final long serialVersionUID = -6024501573409619949L; + + @Override + public void focusLost(FocusEvent event) { +// if (!contextOverlay.isDisposed() && contextOverlay.isShellVisible()) +// getDisplay().asyncExec(() -> stopEditing()); + } + + @Override + public void focusGained(FocusEvent event) { + // txt.setText(""); + if (!contextOverlay.isDisposed() && !contextOverlay.isShellVisible()) + refresh(contextOverlay, null, txt); + } + }); + layout(new Control[] { block }); + getDisplay().asyncExec(() -> txt.setFocus()); + return block; + } else { + Composite block = new Composite(box, SWT.NONE); + block.setLayout(CmsUiUtils.noSpaceGridLayout(2)); + Term currentValue = getValue(); + if (currentValue != null) { + Label lbl = new Label(block, SWT.SINGLE); + String display = getTermLabel(currentValue); + lbl.setText(display); + CmsUiUtils.style(lbl, style == null ? FormStyle.propertyText.style() : style); + processTermListLabel(currentValue, lbl); + if (isEditable()) { + lbl.addMouseListener((MouseDoubleClick) (e) -> { + startEditing(); + }); + } + } else { + if (isEditable()) { + ToolBar toolBar = new ToolBar(block, SWT.HORIZONTAL); + ToolItem addItem = new ToolItem(toolBar, SWT.FLAT); + styleAdd(addItem); + addItem.addSelectionListener((Selected) (e) -> { + startEditing(); + }); + } + } + return block; + } + } + + @Override + protected void refresh(ContextOverlay contextArea, String filter, Text txt) { + CmsUiUtils.clear(contextArea); + List terms = termsManager.listAllTerms(typology.getId()); + terms: for (Term term : terms) { + String display = getTermLabel(term); + if (filter != null && !display.toLowerCase().contains(filter)) + continue terms; + Label termL = new Label(contextArea, SWT.WRAP); + termL.setText(display); + processTermListLabel(term, termL); + if (isTermSelectable(term)) + termL.addMouseListener((MouseDown) (e) -> { + setValue(term); + contextArea.hide(); + stopEditing(); + }); + } + contextArea.show(); + // txt.setFocus(); + } + + protected Term getValue() { + String property = typology.getId(); + String id = Jcr.get(getNode(), property); + Term term = termsManager.getTerm(id); + + return term; + } + + protected void setValue(Term value) { + String property = typology.getId(); + Jcr.set(getNode(), property, value != null ? value.getId() : null); + Jcr.save(getNode()); + } +} diff --git a/org.argeo.geo.ui/.classpath b/org.argeo.geo.ui/.classpath new file mode 100644 index 0000000..e801ebf --- /dev/null +++ b/org.argeo.geo.ui/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.argeo.geo.ui/.gitignore b/org.argeo.geo.ui/.gitignore new file mode 100644 index 0000000..09e3bc9 --- /dev/null +++ b/org.argeo.geo.ui/.gitignore @@ -0,0 +1,2 @@ +/bin/ +/target/ diff --git a/org.argeo.geo.ui/.project b/org.argeo.geo.ui/.project new file mode 100644 index 0000000..a25e06f --- /dev/null +++ b/org.argeo.geo.ui/.project @@ -0,0 +1,33 @@ + + + org.argeo.geo.ui + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.pde.ds.core.builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/org.argeo.geo.ui/META-INF/.gitignore b/org.argeo.geo.ui/META-INF/.gitignore new file mode 100644 index 0000000..4854a41 --- /dev/null +++ b/org.argeo.geo.ui/META-INF/.gitignore @@ -0,0 +1 @@ +/MANIFEST.MF diff --git a/org.argeo.geo.ui/OSGI-INF/l10n/bundle.properties b/org.argeo.geo.ui/OSGI-INF/l10n/bundle.properties new file mode 100644 index 0000000..3ded5eb --- /dev/null +++ b/org.argeo.geo.ui/OSGI-INF/l10n/bundle.properties @@ -0,0 +1 @@ +map=map diff --git a/org.argeo.geo.ui/OSGI-INF/mapLayer.xml b/org.argeo.geo.ui/OSGI-INF/mapLayer.xml new file mode 100644 index 0000000..7cf8487 --- /dev/null +++ b/org.argeo.geo.ui/OSGI-INF/mapLayer.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/org.argeo.geo.ui/OSGI-INF/overviewMap.xml b/org.argeo.geo.ui/OSGI-INF/overviewMap.xml new file mode 100644 index 0000000..c75200a --- /dev/null +++ b/org.argeo.geo.ui/OSGI-INF/overviewMap.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/org.argeo.geo.ui/bnd.bnd b/org.argeo.geo.ui/bnd.bnd new file mode 100644 index 0000000..4fdb49b --- /dev/null +++ b/org.argeo.geo.ui/bnd.bnd @@ -0,0 +1,17 @@ +Import-Package:\ +javax.jcr.nodetype,\ +org.osgi.service.event,\ +com.fasterxml.jackson.core,\ +org.argeo.suite.ui,\ +org.argeo.api,\ +org.eclipse.swt,\ +org.eclipse.jface.viewers,\ +org.osgi.framework,\ +* + +Service-Component:\ +OSGI-INF/mapLayer.xml,\ +OSGI-INF/overviewMap.xml + +Provide-Capability:\ +cms.publish;pkg=org.djapps.on.openheritage.ui,file="*.png,*.js,*.html" \ No newline at end of file diff --git a/org.argeo.geo.ui/build.properties b/org.argeo.geo.ui/build.properties new file mode 100644 index 0000000..34d2e4d --- /dev/null +++ b/org.argeo.geo.ui/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/org.argeo.geo.ui/config/mapLayer.properties b/org.argeo.geo.ui/config/mapLayer.properties new file mode 100644 index 0000000..37bf3c7 --- /dev/null +++ b/org.argeo.geo.ui/config/mapLayer.properties @@ -0,0 +1,6 @@ +service.pid=argeo.geo.ui.mapLayer + +title=%map +icon=map + +entity.type=entity:geopoint diff --git a/org.argeo.geo.ui/config/overviewMap.properties b/org.argeo.geo.ui/config/overviewMap.properties new file mode 100644 index 0000000..d842c98 --- /dev/null +++ b/org.argeo.geo.ui/config/overviewMap.properties @@ -0,0 +1 @@ +service.pid=argeo.geo.ui.overviewMap diff --git a/org.argeo.geo.ui/pom.xml b/org.argeo.geo.ui/pom.xml new file mode 100644 index 0000000..cfe3a0e --- /dev/null +++ b/org.argeo.geo.ui/pom.xml @@ -0,0 +1,37 @@ + + + 4.0.0 + + org.argeo.suite + argeo-suite + 2.3-SNAPSHOT + .. + + org.argeo.geo.ui + Geography UI + jar + + + org.argeo.suite + org.argeo.suite.ui + 2.3-SNAPSHOT + + + + + org.argeo.tp + argeo-tp-rap-e4 + ${version.argeo-tp} + pom + provided + + + + org.argeo.commons + org.argeo.eclipse.ui.rap + ${version.argeo-commons} + provided + + + + diff --git a/org.argeo.geo.ui/src/org/argeo/geo/GeoJsonUtils.java b/org.argeo.geo.ui/src/org/argeo/geo/GeoJsonUtils.java new file mode 100644 index 0000000..0d58480 --- /dev/null +++ b/org.argeo.geo.ui/src/org/argeo/geo/GeoJsonUtils.java @@ -0,0 +1,24 @@ +package org.argeo.geo; + +import java.util.Map; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + +/** Geo data utilities. */ +public class GeoJsonUtils { + + /** Add these properties to all features. */ + public static void addProperties(JsonNode tree, Map map) { + for (JsonNode feature : tree.get("features")) { + ObjectNode properties = (ObjectNode) feature.get("properties"); + for (String key : map.keySet()) { + properties.put(key, map.get(key)); + } + } + } + + /** Singleton. */ + private GeoJsonUtils() { + } +} diff --git a/org.argeo.geo.ui/src/org/argeo/geo/GeoToSvg.java b/org.argeo.geo.ui/src/org/argeo/geo/GeoToSvg.java new file mode 100644 index 0000000..4d593f2 --- /dev/null +++ b/org.argeo.geo.ui/src/org/argeo/geo/GeoToSvg.java @@ -0,0 +1,69 @@ +package org.argeo.geo; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Writer; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** Converts a geographical feature to an SVG. */ +public class GeoToSvg { + public void convertGeoJsonToSvg(Path source, Path target) { + ObjectMapper objectMapper = new ObjectMapper(); + try (InputStream in = Files.newInputStream(source); + Writer out = Files.newBufferedWriter(target, StandardCharsets.UTF_8)) { + JsonNode tree = objectMapper.readTree(in); + JsonNode coord = tree.get("features").get(0).get("geometry").get("coordinates"); + double ratio = 100; + double minX = Double.POSITIVE_INFINITY; + double maxX = Double.NEGATIVE_INFINITY; + double minY = Double.POSITIVE_INFINITY; + double maxY = Double.NEGATIVE_INFINITY; + List shapes = new ArrayList<>(); + for (JsonNode shape : coord) { + StringBuffer sb = new StringBuffer(); + sb.append(" maxY) + maxY = y; + double lng = latlng.get(1).asDouble(); + double x = lng * ratio; + if (x < minX) + minX = x; + if (x > maxX) + maxX = x; + sb.append(y + "," + x + " "); + } + sb.append("\">"); + sb.append("\n"); + shapes.add(sb.toString()); + } + + double width = maxX - minX; + double height = maxY - minY; + out.write("\n"); + for (String shape : shapes) { + out.write(shape); + out.write("\n"); + } + out.write(""); + } catch (IOException e) { + throw new RuntimeException("Cannot convert " + source + " to " + target, e); + } + } + +} diff --git a/org.argeo.geo.ui/src/org/argeo/support/openlayers/OLMap.java b/org.argeo.geo.ui/src/org/argeo/support/openlayers/OLMap.java new file mode 100644 index 0000000..ac104c6 --- /dev/null +++ b/org.argeo.geo.ui/src/org/argeo/support/openlayers/OLMap.java @@ -0,0 +1,21 @@ +package org.argeo.support.openlayers; + +import org.argeo.cms.ui.util.CmsUiUtils; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; + +public class OLMap extends Composite { + private Label div; + + public OLMap(Composite parent, int style) { + super(parent, style); + setLayout(CmsUiUtils.noSpaceGridLayout()); + div = new Label(this, SWT.NONE); + CmsUiUtils.markup(div); + CmsUiUtils.disableMarkupValidation(div); + div.setText("
"); + div.setLayoutData(CmsUiUtils.fillAll()); + } + +} diff --git a/org.argeo.geo.ui/src/org/argeo/support/openlayers/OpenLayersMap.java b/org.argeo.geo.ui/src/org/argeo/support/openlayers/OpenLayersMap.java new file mode 100644 index 0000000..5357149 --- /dev/null +++ b/org.argeo.geo.ui/src/org/argeo/support/openlayers/OpenLayersMap.java @@ -0,0 +1,301 @@ +package org.argeo.support.openlayers; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.api.NodeConstants; +import org.argeo.cms.ui.CmsView; +import org.argeo.cms.ui.util.CmsUiUtils; +import org.argeo.entity.EntityNames; +import org.argeo.entity.EntityType; +import org.argeo.suite.ui.SuiteEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.browser.Browser; +import org.eclipse.swt.browser.BrowserFunction; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; + +/** Display a map. */ +public class OpenLayersMap extends Composite { + private static final long serialVersionUID = 1055893020490283622L; + + private final static Log log = LogFactory.getLog(OpenLayersMap.class); + + private Browser browser; + private boolean renderCompleted = false; + + private Double centerLng = null, centerLat = null; + private Integer zoom = null; + private String vectorSource = null; + private String gpxSource = null; + + private String vectorSourceStyle; + + private List geoJsonSources = new ArrayList<>(); + private Map vectorSources = new HashMap<>(); + private Map layerStyles = new HashMap<>(); + + private CmsView cmsView; + + public OpenLayersMap(Composite parent, int style, URL mapHtml) { + super(parent, style); + cmsView = CmsView.getCmsView(parent); + setLayout(new GridLayout()); + + browser = new Browser(this, SWT.BORDER); + browser.setLayoutData(CmsUiUtils.fillAll()); + String html; + try (InputStream in = mapHtml.openStream()) { + html = IOUtils.toString(in, StandardCharsets.UTF_8); + } catch (IOException e) { + throw new RuntimeException(e); + } + new RenderCompleted(browser, "renderCompleted"); + new OnFeatureSelect(browser, "onFeatureSelect"); + new OnFeatureUnselect(browser, "onFeatureUnselect"); + new OnFeatureClick(browser, "onFeatureClick"); + browser.setText(html); + } + + public void setCenter(Double lng, Double lat) { + if (isRenderCompleted()) + browser.evaluate("map.getView().setCenter(ol.proj.fromLonLat([" + lng + ", " + lat + "]))"); + this.centerLat = lat; + this.centerLng = lng; + } + + public synchronized void setRenderCompleted(boolean renderCompleted) { + this.renderCompleted = renderCompleted; + notifyAll(); + } + + public synchronized boolean isRenderCompleted() { + return renderCompleted; + } + + @Override + public synchronized void dispose() { + long timeout = 500; + long begin = System.currentTimeMillis(); + while (!isRenderCompleted() && ((System.currentTimeMillis() - begin) < timeout)) { + try { + wait(50); + } catch (InterruptedException e) { + // silent + } + } + super.dispose(); + } + + public void setZoom(int zoom) { + if (isRenderCompleted()) + browser.evaluate("map.getView().setZoom(" + zoom + ")"); + this.zoom = zoom; + } + + protected String asVectorSource(List geoPoints) throws RepositoryException { + boolean first = true; + StringBuffer sb = new StringBuffer("new ol.source.Vector({ features: ["); + for (int i = 0; i < geoPoints.size(); i++) { + Node node = geoPoints.get(i); + if (node.isNodeType(EntityType.geopoint.get())) { + if (first) + first = false; + else + sb.append(","); + Double lng = node.getProperty(EntityNames.GEO_LONG).getDouble(); + Double lat = node.getProperty(EntityNames.GEO_LAT).getDouble(); + sb.append("new ol.Feature({ geometry:"); + sb.append("new ol.geom.Point(ol.proj.fromLonLat(["); + sb.append(lng).append(',').append(lat); + sb.append("]))"); + sb.append(",path:\"").append(node.getPath()).append("\""); + sb.append(",name:\"").append(node.getName()).append("\""); + String entityType = null; + if (node.isNodeType(EntityType.local.get())) { + entityType = node.getProperty(EntityNames.ENTITY_TYPE).getString(); + sb.append(", type:'").append(entityType).append("'"); + } + sb.append("})"); + } + } + sb.append("]"); + sb.append(" })"); + return sb.toString(); + } + + public void addPoints(List geoPoints) throws RepositoryException { + this.vectorSource = asVectorSource(geoPoints); + if (log.isTraceEnabled()) + log.trace("Vector source: " + vectorSource); + renderVectorSource(); + } + + public void addPoints(String layerName, List geoPoints, String style) throws RepositoryException { + this.vectorSources.put(layerName, asVectorSource(geoPoints)); + if (style != null) { + layerStyles.put(layerName, style); + } + renderVectorSources(); + } + + protected void renderVectorSource() { + if (vectorSource == null) + return; + if (isRenderCompleted()) { +// String style = ", style: new ol.style.Style({ image: new ol.style.Icon({ src: '/pkg/org.djapps.on.openheritage.ui/map_oc.png' }) })"; + String style = vectorSourceStyle != null ? ", style: " + vectorSourceStyle : ""; +// String style = ""; + String toEvaluate = "map.addLayer(new ol.layer.Vector({ source: " + vectorSource + style + "}));"; +// System.out.println(toEvaluate); + browser.execute(toEvaluate); + } + } + + protected void renderVectorSources() { + if (vectorSources.isEmpty()) + return; + if (isRenderCompleted()) { + StringBuilder toExecute = new StringBuilder(); + for (String name : vectorSources.keySet()) { + String style = layerStyles.containsKey(name) ? ", style: " + layerStyles.get(name) : ""; + String toEvaluate = "map.addLayer(new ol.layer.Vector({ source: " + vectorSources.get(name) + style + + ",name: '" + name + "'}));"; + toExecute.append(toEvaluate); + } + System.out.println(toExecute); + browser.execute(toExecute.toString()); + } + } + + public void addPoint(Double lng, Double lat) { + this.vectorSource = "new ol.source.Vector({ features: [ new ol.Feature({ geometry:" + + " new ol.geom.Point(ol.proj.fromLonLat([" + lng + ", " + lat + "])) }) ] })"; +// if (renderCompleted) { +// browser.evaluate( +// "map.addLayer(new ol.layer.Vector({ source: new ol.source.Vector({ features: [ new ol.Feature({ geometry:" +// + " new ol.geom.Point(ol.proj.fromLonLat([" + lng + ", " + lat + "])) }) ] }) }));"); +// } + renderVectorSource(); + } + + public void addGpx(String path) { + this.gpxSource = "new ol.source.Vector({ url: '" + path + "', format: new ol.format.GPX() })"; + renderGpxSource(); + } + + protected void renderGpxSource() { + if (gpxSource == null) + return; + if (isRenderCompleted()) + browser.evaluate("map.addLayer(new ol.layer.Vector({ source: " + gpxSource + "}));"); + } + + public void addGeoJson(String path) { + String geoJsonSource = "new ol.source.Vector({ url: '" + path + "', format: new ol.format.GeoJSON() })"; + geoJsonSources.add(geoJsonSource); + renderGeoJsonSources(); + } + + protected void renderGeoJsonSources() { + if (geoJsonSources.isEmpty()) + return; + if (isRenderCompleted()) { + for (String geoJson : geoJsonSources) { + browser.evaluate("map.addLayer(new ol.layer.Vector({ source: " + geoJson + "}));"); + } + } + } + + public void setVectorSourceStyle(String vectorSourceStyle) { + this.vectorSourceStyle = vectorSourceStyle; + } + + private class RenderCompleted extends BrowserFunction { + + RenderCompleted(Browser browser, String name) { + super(browser, name); + } + + @Override + public Object function(Object[] arguments) { + try { + if (!isRenderCompleted()) { + setRenderCompleted(true); + if (zoom != null) + setZoom(zoom); + if (centerLat != null && centerLng != null) { + setCenter(centerLng, centerLat); + } + if (!geoJsonSources.isEmpty()) + renderGeoJsonSources(); + if (gpxSource != null) + renderGpxSource(); + if (vectorSource != null) + renderVectorSource(); + if (!vectorSources.isEmpty()) + renderVectorSources(); + } + return null; + } catch (Exception e) { + log.error("Cannot render map", e); + return null; + } + } + } + + private class OnFeatureSelect extends BrowserFunction { + + OnFeatureSelect(Browser browser, String name) { + super(browser, name); + } + + @Override + public Object function(Object[] arguments) { + if (arguments.length == 0) + return null; + String path = arguments[0].toString(); + Map properties = new HashMap<>(); + properties.put(SuiteEvent.NODE_PATH, path); + properties.put(SuiteEvent.WORKSPACE, NodeConstants.SYS_WORKSPACE); + cmsView.sendEvent(SuiteEvent.refreshPart.topic(), properties); + return null; + } + } + + private class OnFeatureUnselect extends BrowserFunction { + + OnFeatureUnselect(Browser browser, String name) { + super(browser, name); + } + + @Override + public Object function(Object[] arguments) { + return null; + } + } + + private class OnFeatureClick extends BrowserFunction { + + OnFeatureClick(Browser browser, String name) { + super(browser, name); + } + + @Override + public Object function(Object[] arguments) { + return null; + } + } +} diff --git a/org.argeo.geo.ui/src/org/argeo/support/openlayers/OverviewMap.java b/org.argeo.geo.ui/src/org/argeo/support/openlayers/OverviewMap.java new file mode 100644 index 0000000..b2fd01e --- /dev/null +++ b/org.argeo.geo.ui/src/org/argeo/support/openlayers/OverviewMap.java @@ -0,0 +1,66 @@ +package org.argeo.support.openlayers; + +import java.util.List; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.observation.Event; +import javax.jcr.observation.EventIterator; +import javax.jcr.observation.EventListener; +import javax.jcr.query.Query; + +import org.argeo.cms.ui.CmsUiProvider; +import org.argeo.cms.ui.util.CmsUiUtils; +import org.argeo.entity.EntityType; +import org.argeo.jcr.JcrException; +import org.argeo.jcr.JcrUtils; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + +/** Displays an overview map. */ +public class OverviewMap implements CmsUiProvider { + + @Override + public Control createUi(Composite parent, Node context) throws RepositoryException { + parent.setLayout(new GridLayout()); + refreshUi(parent, context); + + try { + String[] nodeTypes = { EntityType.geopoint.get() }; + context.getSession().getWorkspace().getObservationManager().addEventListener(new EventListener() { + + @Override + public void onEvent(EventIterator events) { + if (!parent.isDisposed()) + parent.getDisplay().asyncExec(() -> { + try { + refreshUi(parent, context); + } catch (RepositoryException e) { + throw new JcrException(e); + } + }); + } + }, Event.PROPERTY_CHANGED | Event.NODE_ADDED | Event.NODE_REMOVED | Event.PROPERTY_ADDED, "/", true, null, + nodeTypes, false); + } catch (RepositoryException e) { + throw new IllegalStateException("Cannot add JCR observer", e); + } + + return parent; + } + + protected void refreshUi(Composite parent, Node context) throws RepositoryException { + CmsUiUtils.clear(parent); + Query query = context.getSession().getWorkspace().getQueryManager() + .createQuery("SELECT * FROM [" + EntityType.geopoint.get() + "]", Query.JCR_SQL2); + List geoPoints = JcrUtils.nodeIteratorToList(query.execute().getNodes()); + OpenLayersMap map = new OpenLayersMap(parent, SWT.NONE, getClass().getResource("map-osm.html")); + map.setLayoutData(CmsUiUtils.fillAll()); + + // apafMap.setZoom(7); + // apafMap.setCenter(-2.472, 8.010); + map.addPoints(geoPoints); + } +} diff --git a/org.argeo.geo.ui/src/org/argeo/support/openlayers/map-osm.html b/org.argeo.geo.ui/src/org/argeo/support/openlayers/map-osm.html new file mode 100644 index 0000000..157d708 --- /dev/null +++ b/org.argeo.geo.ui/src/org/argeo/support/openlayers/map-osm.html @@ -0,0 +1,41 @@ + + + + + + + +
+ + + \ No newline at end of file diff --git a/org.argeo.geo.ui/src/org/argeo/support/openlayers/map.js b/org.argeo.geo.ui/src/org/argeo/support/openlayers/map.js new file mode 100644 index 0000000..68489fb --- /dev/null +++ b/org.argeo.geo.ui/src/org/argeo/support/openlayers/map.js @@ -0,0 +1,11 @@ +var map = new ol.Map({ + target : 'map', + layers : [ new ol.layer.Tile({ + source : new ol.source.OSM() + }) ], + view : new ol.View({ + center : ol.proj.fromLonLat([ 34, 34 ]), + zoom : 4 + }) +}); + \ No newline at end of file diff --git a/org.argeo.library.ui/.classpath b/org.argeo.library.ui/.classpath new file mode 100644 index 0000000..e801ebf --- /dev/null +++ b/org.argeo.library.ui/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.argeo.library.ui/.gitignore b/org.argeo.library.ui/.gitignore new file mode 100644 index 0000000..09e3bc9 --- /dev/null +++ b/org.argeo.library.ui/.gitignore @@ -0,0 +1,2 @@ +/bin/ +/target/ diff --git a/org.argeo.library.ui/.project b/org.argeo.library.ui/.project new file mode 100644 index 0000000..6aa2010 --- /dev/null +++ b/org.argeo.library.ui/.project @@ -0,0 +1,33 @@ + + + org.argeo.library.ui + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.pde.ds.core.builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/org.argeo.library.ui/META-INF/.gitignore b/org.argeo.library.ui/META-INF/.gitignore new file mode 100644 index 0000000..4854a41 --- /dev/null +++ b/org.argeo.library.ui/META-INF/.gitignore @@ -0,0 +1 @@ +/MANIFEST.MF diff --git a/org.argeo.library.ui/OSGI-INF/contentEntryArea.xml b/org.argeo.library.ui/OSGI-INF/contentEntryArea.xml new file mode 100644 index 0000000..0b5646e --- /dev/null +++ b/org.argeo.library.ui/OSGI-INF/contentEntryArea.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/org.argeo.library.ui/OSGI-INF/contentLayer.xml b/org.argeo.library.ui/OSGI-INF/contentLayer.xml new file mode 100644 index 0000000..0dae1af --- /dev/null +++ b/org.argeo.library.ui/OSGI-INF/contentLayer.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/org.argeo.library.ui/OSGI-INF/documentsFolder.xml b/org.argeo.library.ui/OSGI-INF/documentsFolder.xml new file mode 100644 index 0000000..d7d71f0 --- /dev/null +++ b/org.argeo.library.ui/OSGI-INF/documentsFolder.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/org.argeo.library.ui/OSGI-INF/fsEntryArea.xml b/org.argeo.library.ui/OSGI-INF/fsEntryArea.xml new file mode 100644 index 0000000..540f4ff --- /dev/null +++ b/org.argeo.library.ui/OSGI-INF/fsEntryArea.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/org.argeo.library.ui/OSGI-INF/l10n/bundle.properties b/org.argeo.library.ui/OSGI-INF/l10n/bundle.properties new file mode 100644 index 0000000..8015421 --- /dev/null +++ b/org.argeo.library.ui/OSGI-INF/l10n/bundle.properties @@ -0,0 +1 @@ +content=content diff --git a/org.argeo.library.ui/bnd.bnd b/org.argeo.library.ui/bnd.bnd new file mode 100644 index 0000000..71f4618 --- /dev/null +++ b/org.argeo.library.ui/bnd.bnd @@ -0,0 +1,12 @@ +Service-Component:\ +OSGI-INF/contentEntryArea.xml,\ +OSGI-INF/fsEntryArea.xml,\ +OSGI-INF/contentLayer.xml,\ +OSGI-INF/documentsFolder.xml + +Import-Package:\ +org.eclipse.swt,\ +javax.jcr.nodetype,\ +org.argeo.api,\ +org.argeo.suite.ui,\ +* \ No newline at end of file diff --git a/org.argeo.library.ui/build.properties b/org.argeo.library.ui/build.properties new file mode 100644 index 0000000..0859c52 --- /dev/null +++ b/org.argeo.library.ui/build.properties @@ -0,0 +1,7 @@ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + OSGI-INF/,\ + OSGI-INF/contentLayer.xml,\ + OSGI-INF/documentsFolder.xml +source.. = src/ diff --git a/org.argeo.library.ui/config/contentEntryArea.properties b/org.argeo.library.ui/config/contentEntryArea.properties new file mode 100644 index 0000000..855fe97 --- /dev/null +++ b/org.argeo.library.ui/config/contentEntryArea.properties @@ -0,0 +1 @@ +service.pid=argeo.library.ui.contentEntryArea diff --git a/org.argeo.library.ui/config/contentLayer.properties b/org.argeo.library.ui/config/contentLayer.properties new file mode 100644 index 0000000..c1ca8e3 --- /dev/null +++ b/org.argeo.library.ui/config/contentLayer.properties @@ -0,0 +1,6 @@ +service.pid=argeo.library.ui.contentLayer + +title=%content +icon=documents + +entity.type=nt:folder,nt:file,entity:space,entity:document diff --git a/org.argeo.library.ui/config/documentsFolder.properties b/org.argeo.library.ui/config/documentsFolder.properties new file mode 100644 index 0000000..349e930 --- /dev/null +++ b/org.argeo.library.ui/config/documentsFolder.properties @@ -0,0 +1 @@ +entity.type=nt:folder \ No newline at end of file diff --git a/org.argeo.library.ui/config/fsEntryArea.properties b/org.argeo.library.ui/config/fsEntryArea.properties new file mode 100644 index 0000000..0bceaf0 --- /dev/null +++ b/org.argeo.library.ui/config/fsEntryArea.properties @@ -0,0 +1 @@ +service.pid=argeo.library.ui.fsEntryArea diff --git a/org.argeo.library.ui/pom.xml b/org.argeo.library.ui/pom.xml new file mode 100644 index 0000000..672634a --- /dev/null +++ b/org.argeo.library.ui/pom.xml @@ -0,0 +1,37 @@ + + + 4.0.0 + + org.argeo.suite + argeo-suite + 2.3-SNAPSHOT + .. + + org.argeo.library.ui + Documents UI + jar + + + org.argeo.suite + org.argeo.suite.ui + 2.3-SNAPSHOT + + + + + org.argeo.tp + argeo-tp-rap-e4 + ${version.argeo-tp} + pom + provided + + + + org.argeo.commons + org.argeo.eclipse.ui.rap + ${version.argeo-commons} + provided + + + + diff --git a/org.argeo.library.ui/src/org/argeo/library/ui/ContentEntryArea.java b/org.argeo.library.ui/src/org/argeo/library/ui/ContentEntryArea.java new file mode 100644 index 0000000..8b884eb --- /dev/null +++ b/org.argeo.library.ui/src/org/argeo/library/ui/ContentEntryArea.java @@ -0,0 +1,170 @@ +package org.argeo.library.ui; + +import java.util.SortedMap; +import java.util.TreeMap; + +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.nodetype.NodeType; +import javax.jcr.query.Query; + +import org.argeo.cms.ui.CmsTheme; +import org.argeo.cms.ui.CmsUiProvider; +import org.argeo.cms.ui.CmsView; +import org.argeo.cms.ui.util.CmsUiUtils; +import org.argeo.entity.EntityType; +import org.argeo.jcr.Jcr; +import org.argeo.jcr.JcrException; +import org.argeo.suite.ui.SuiteEvent; +import org.argeo.suite.ui.SuiteIcon; +import org.argeo.suite.ui.widgets.TreeOrSearchArea; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TreeViewerColumn; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + +public class ContentEntryArea implements CmsUiProvider { + + @Override + public Control createUi(Composite parent, Node context) throws RepositoryException { + CmsTheme theme = CmsTheme.getCmsTheme(parent); + + parent.setLayout(new GridLayout()); + Ui ui = new Ui(parent, SWT.NONE); + ui.setLayoutData(CmsUiUtils.fillAll()); + + TreeViewerColumn nameCol = new TreeViewerColumn(ui.getTreeViewer(), SWT.NONE); + nameCol.getColumn().setWidth(400); + nameCol.setLabelProvider(new ColumnLabelProvider() { + + @Override + public String getText(Object element) { + Node node = (Node) element; + return Jcr.getTitle(node); + } + + @Override + public Image getImage(Object element) { + Node node = (Node) element; + Image icon; + if (Jcr.isNodeType(node, NodeType.NT_FOLDER)) { + icon = SuiteIcon.folder.getSmallIcon(theme); + } else if (Jcr.isNodeType(node, NodeType.NT_FILE)) { + // TODO check recognized document types + icon = SuiteIcon.document.getSmallIcon(theme); + } else if (Jcr.isNodeType(node, EntityType.document.get())) { + icon = SuiteIcon.document.getSmallIcon(theme); + } else { + if (!isLeaf(node)) + icon = SuiteIcon.folder.getSmallIcon(theme); + else + icon = null; + } + return icon; + } + + }); + + ui.getTreeViewer().addDoubleClickListener(new IDoubleClickListener() { + + @Override + public void doubleClick(DoubleClickEvent event) { + Node user = (Node) ui.getTreeViewer().getStructuredSelection().getFirstElement(); + if (user != null) { + CmsView.getCmsView(parent).sendEvent(SuiteEvent.openNewPart.topic(), + SuiteEvent.eventProperties(user)); + } + + } + }); + ui.getTreeViewer().addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + Node user = (Node) ui.getTreeViewer().getStructuredSelection().getFirstElement(); + if (user != null) { + CmsView.getCmsView(parent).sendEvent(SuiteEvent.refreshPart.topic(), + SuiteEvent.eventProperties(user)); + } + } + }); + + ui.getTreeViewer().setContentProvider(new SpacesContentProvider()); + ui.getTreeViewer().setInput(context.getSession()); + return ui; + } + + protected boolean isLeaf(Node node) { + return Jcr.isNodeType(node, EntityType.entity.get()) || Jcr.isNodeType(node, EntityType.document.get()) + || Jcr.isNodeType(node, NodeType.NT_FILE); + } + + class Ui extends TreeOrSearchArea { + + public Ui(Composite parent, int style) { + super(parent, style); + } + + } + + class SpacesContentProvider implements ITreeContentProvider { + + @Override + public Object[] getElements(Object inputElement) { + Session session = (Session) inputElement; + try { + Query query = session.getWorkspace().getQueryManager() + .createQuery("SELECT * FROM [" + EntityType.space.get() + "]", Query.JCR_SQL2); + NodeIterator spacesIt = query.execute().getNodes(); + SortedMap map = new TreeMap<>(); + while (spacesIt.hasNext()) { + Node space = spacesIt.nextNode(); + String path = space.getPath(); + map.put(path, space); + } + return map.values().toArray(); + } catch (RepositoryException e) { + throw new JcrException(e); + } + } + + @Override + public Object[] getChildren(Object parentElement) { + Node parent = (Node) parentElement; + if (isLeaf(parent)) + return null; + return Jcr.getNodes(parent).toArray(); + } + + @Override + public Object getParent(Object element) { + Node node = (Node) element; + return Jcr.getParent(node); + } + + @Override + public boolean hasChildren(Object element) { + Node node = (Node) element; + return !isLeaf(node); + } + + @Override + public void dispose() { + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + } + +} diff --git a/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsContextMenu.java b/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsContextMenu.java new file mode 100644 index 0000000..03de251 --- /dev/null +++ b/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsContextMenu.java @@ -0,0 +1,177 @@ +package org.argeo.library.ui; + +import static org.argeo.library.ui.DocumentsUiService.ACTION_ID_BOOKMARK_FOLDER; +import static org.argeo.library.ui.DocumentsUiService.ACTION_ID_CREATE_FOLDER; +import static org.argeo.library.ui.DocumentsUiService.ACTION_ID_DELETE; +import static org.argeo.library.ui.DocumentsUiService.ACTION_ID_DOWNLOAD_FOLDER; +import static org.argeo.library.ui.DocumentsUiService.ACTION_ID_RENAME; +import static org.argeo.library.ui.DocumentsUiService.ACTION_ID_SHARE_FOLDER; +import static org.argeo.library.ui.DocumentsUiService.ACTION_ID_UPLOAD_FILE; + +import java.nio.file.Files; +import java.nio.file.Path; + +import org.argeo.suite.ui.widgets.AbstractConnectContextMenu; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Control; + +/** Generic popup context menu to manage NIO Path in a Viewer. */ +public class DocumentsContextMenu extends AbstractConnectContextMenu { + // Local context + private final DocumentsFolderComposite browser; + private final DocumentsUiService uiService; +// private final Repository repository; + + private final static String[] DEFAULT_ACTIONS = { ACTION_ID_CREATE_FOLDER, ACTION_ID_BOOKMARK_FOLDER, + ACTION_ID_SHARE_FOLDER, ACTION_ID_DOWNLOAD_FOLDER, ACTION_ID_UPLOAD_FILE, ACTION_ID_RENAME, + ACTION_ID_DELETE }; + + private Path currFolderPath; + + public DocumentsContextMenu(DocumentsFolderComposite browser, + DocumentsUiService documentsUiService) { + super(browser.getDisplay(), DEFAULT_ACTIONS); + this.browser = browser; + this.uiService = documentsUiService; +// this.repository = repository; + + createControl(); + } + + public void setCurrFolderPath(Path currFolderPath) { + this.currFolderPath = currFolderPath; + } + + protected boolean aboutToShow(Control source, Point location, IStructuredSelection selection) { + boolean emptySel = true; + boolean multiSel = false; + boolean isFolder = true; + if (selection != null && !selection.isEmpty()) { + emptySel = false; + multiSel = selection.size() > 1; + if (!multiSel && selection.getFirstElement() instanceof Path) { + isFolder = Files.isDirectory((Path) selection.getFirstElement()); + } + } + if (emptySel) { + setVisible(true, ACTION_ID_CREATE_FOLDER, ACTION_ID_UPLOAD_FILE, ACTION_ID_BOOKMARK_FOLDER); + setVisible(false, ACTION_ID_SHARE_FOLDER, ACTION_ID_DOWNLOAD_FOLDER, ACTION_ID_RENAME, ACTION_ID_DELETE + ); + } else if (multiSel) { + setVisible(true, ACTION_ID_CREATE_FOLDER, ACTION_ID_UPLOAD_FILE, ACTION_ID_DELETE, + ACTION_ID_BOOKMARK_FOLDER); + setVisible(false, ACTION_ID_SHARE_FOLDER, ACTION_ID_DOWNLOAD_FOLDER, ACTION_ID_RENAME); + } else if (isFolder) { + setVisible(true, ACTION_ID_CREATE_FOLDER, ACTION_ID_UPLOAD_FILE, ACTION_ID_RENAME, ACTION_ID_DELETE, + ACTION_ID_BOOKMARK_FOLDER); + setVisible(false, + // to be implemented + ACTION_ID_SHARE_FOLDER, ACTION_ID_DOWNLOAD_FOLDER); + } else { + setVisible(true, ACTION_ID_CREATE_FOLDER, ACTION_ID_UPLOAD_FILE, ACTION_ID_RENAME, + ACTION_ID_DELETE); + setVisible(false, ACTION_ID_SHARE_FOLDER, ACTION_ID_DOWNLOAD_FOLDER, ACTION_ID_BOOKMARK_FOLDER); + } + return true; + } + + public void show(Control source, Point location, IStructuredSelection selection, Path currFolderPath) { + // TODO find a better way to retrieve the parent path (cannot be deduced + // from table content because it will fail on an empty folder) + this.currFolderPath = currFolderPath; + super.show(source, location, selection); + + } + + @Override + protected boolean performAction(String actionId) { + switch (actionId) { + case ACTION_ID_CREATE_FOLDER: + createFolder(); + break; + case ACTION_ID_BOOKMARK_FOLDER: + bookmarkFolder(); + break; + case ACTION_ID_RENAME: + renameItem(); + break; + case ACTION_ID_DELETE: + deleteItems(); + break; +// case ACTION_ID_OPEN: +// openFile(); +// break; + case ACTION_ID_UPLOAD_FILE: + uploadFiles(); + break; + default: + throw new IllegalArgumentException("Unimplemented action " + actionId); + // case ACTION_ID_SHARE_FOLDER: + // return "Share Folder"; + // case ACTION_ID_DOWNLOAD_FOLDER: + // return "Download as zip archive"; + } + browser.setFocus(); + return false; + } + + @Override + protected String getLabel(String actionId) { + return uiService.getLabel(actionId); + } + + private void openFile() { + IStructuredSelection selection = ((IStructuredSelection) browser.getViewer().getSelection()); + if (selection.isEmpty() || selection.size() > 1) + // Should never happen + return; + Path toOpenPath = ((Path) selection.getFirstElement()); + uiService.openFile(toOpenPath); + } + + private void deleteItems() { + IStructuredSelection selection = ((IStructuredSelection) browser.getViewer().getSelection()); + if (selection.isEmpty()) + return; + else if (uiService.deleteItems(getParentShell(), selection)) + browser.refresh(); + } + + private void renameItem() { + IStructuredSelection selection = ((IStructuredSelection) browser.getViewer().getSelection()); + if (selection.isEmpty() || selection.size() > 1) + // Should never happen + return; + Path toRenamePath = ((Path) selection.getFirstElement()); + if (uiService.renameItem(getParentShell(), currFolderPath, toRenamePath)) + browser.refresh(); + } + + private void createFolder() { + if (uiService.createFolder(getParentShell(), currFolderPath)) + browser.refresh(); + } + + private void bookmarkFolder() { + Path toBookmarkPath = null; + IStructuredSelection selection = ((IStructuredSelection) browser.getViewer().getSelection()); + if (selection.isEmpty()) + toBookmarkPath = currFolderPath; + else if (selection.size() > 1) + toBookmarkPath = currFolderPath; + else if (selection.size() == 1) { + Path currSelected = ((Path) selection.getFirstElement()); + if (Files.isDirectory(currSelected)) + toBookmarkPath = currSelected; + else + return; + } + //uiService.bookmarkFolder(toBookmarkPath, repository, null); + } + + private void uploadFiles() { + if (uiService.uploadFiles(getParentShell(), currFolderPath)) + browser.refresh(); + } +} diff --git a/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsFileComposite.java b/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsFileComposite.java new file mode 100644 index 0000000..10cf3bd --- /dev/null +++ b/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsFileComposite.java @@ -0,0 +1,125 @@ +package org.argeo.library.ui; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.spi.FileSystemProvider; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.cms.fs.CmsFsUtils; +import org.argeo.cms.ui.util.CmsUiUtils; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.eclipse.ui.fs.FsUiUtils; +import org.argeo.eclipse.ui.specific.UiContext; +import org.eclipse.swt.SWT; +import org.eclipse.swt.browser.Browser; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; + +/** + * Default Documents file composite: a sashForm with a browser in the middle and + * meta data at right hand side. + */ +public class DocumentsFileComposite extends Composite { + private static final long serialVersionUID = -7567632342889241793L; + + private final static Log log = LogFactory.getLog(DocumentsFileComposite.class); + + private final Node currentBaseContext; + + // UI Parts for the browser + private Composite rightPannelCmp; + + public DocumentsFileComposite(Composite parent, int style, Node context, + FileSystemProvider fsp) { + super(parent, style); + this.currentBaseContext = context; + this.setLayout(EclipseUiUtils.noSpaceGridLayout()); + SashForm form = new SashForm(this, SWT.HORIZONTAL); + + Composite centerCmp = new Composite(form, SWT.BORDER | SWT.NO_FOCUS); + createDisplay(centerCmp); + + rightPannelCmp = new Composite(form, SWT.NO_FOCUS); + + Path path = CmsFsUtils.getPath(fsp, context); + setOverviewInput(path); + form.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + form.setWeights(new int[] { 55, 20 }); + } + + private void createDisplay(final Composite parent) { + parent.setLayout(EclipseUiUtils.noSpaceGridLayout()); + Browser browser = new Browser(parent, SWT.NONE); + // browser.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, + // true)); + browser.setLayoutData(EclipseUiUtils.fillAll()); + try { + // FIXME make it more robust + String url = CmsUiUtils.getDataUrl(currentBaseContext, UiContext.getHttpRequest()); + // FIXME issue with the redirection to https + if (url.startsWith("http://") && !url.startsWith("http://localhost")) + url = "https://" + url.substring("http://".length(), url.length()); + if (log.isTraceEnabled()) + log.debug("Trying to display " + url); + browser.setUrl(url); + browser.layout(true, true); + } catch (RepositoryException re) { + throw new IllegalStateException("Cannot open file at " + currentBaseContext, re); + } + } + + /** + * Recreates the content of the box that displays information about the current + * selected Path. + */ + private void setOverviewInput(Path path) { + try { + EclipseUiUtils.clear(rightPannelCmp); + rightPannelCmp.setLayout(new GridLayout()); + if (path != null) { + // if (isImg(context)) { + // EditableImage image = new Img(parent, RIGHT, context, + // imageWidth); + // image.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, + // true, false, + // 2, 1)); + // } + + Label contextL = new Label(rightPannelCmp, SWT.NONE); + contextL.setText(path.getFileName().toString()); + contextL.setFont(EclipseUiUtils.getBoldFont(rightPannelCmp)); + addProperty(rightPannelCmp, "Last modified", Files.getLastModifiedTime(path).toString()); + // addProperty(rightPannelCmp, "Owner", + // Files.getOwner(path).getName()); + if (Files.isDirectory(path)) { + addProperty(rightPannelCmp, "Type", "Folder"); + } else { + String mimeType = Files.probeContentType(path); + if (EclipseUiUtils.isEmpty(mimeType)) + mimeType = "Unknown"; + addProperty(rightPannelCmp, "Type", mimeType); + addProperty(rightPannelCmp, "Size", FsUiUtils.humanReadableByteCount(Files.size(path), false)); + } + } + rightPannelCmp.layout(true, true); + } catch (IOException e) { + throw new IllegalStateException("Cannot display details for " + path.toString(), e); + } + } + + // Simplify UI implementation + private void addProperty(Composite parent, String propName, String value) { + Label propLbl = new Label(parent, SWT.NONE); + //propLbl.setText(ConnectUtils.replaceAmpersand(propName + ": " + value)); + propLbl.setText(value); + //CmsUiUtils.markup(propLbl); + } +} diff --git a/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsFolderComposite.java b/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsFolderComposite.java new file mode 100644 index 0000000..a686074 --- /dev/null +++ b/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsFolderComposite.java @@ -0,0 +1,455 @@ +package org.argeo.library.ui; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.attribute.FileTime; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import javax.jcr.Node; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.cms.ui.fs.FileDrop; +import org.argeo.cms.ui.fs.FsStyles; +import org.argeo.cms.ui.util.CmsUiUtils; +import org.argeo.eclipse.ui.ColumnDefinition; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.eclipse.ui.fs.FileIconNameLabelProvider; +import org.argeo.eclipse.ui.fs.FsTableViewer; +import org.argeo.eclipse.ui.fs.FsUiConstants; +import org.argeo.eclipse.ui.fs.FsUiUtils; +import org.argeo.eclipse.ui.fs.NioFileLabelProvider; +import org.argeo.eclipse.ui.fs.ParentDir; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowData; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.Text; + +/** + * Default Documents folder composite: a sashForm layout with a simple table in + * the middle and an overview at right hand side. + */ +public class DocumentsFolderComposite extends Composite { + private final static Log log = LogFactory.getLog(DocumentsFolderComposite.class); + private static final long serialVersionUID = -40347919096946585L; + + private final Node currentBaseContext; + + private final DocumentsUiService documentUiService = new DocumentsUiService(); + + // UI Parts for the browser + private Composite filterCmp; + private Composite breadCrumbCmp; + private Text filterTxt; + private FsTableViewer directoryDisplayViewer; + private Composite rightPanelCmp; + + private DocumentsContextMenu contextMenu; + private DateFormat dateFormat = new SimpleDateFormat("YYYY-MM-dd HH:mm"); + + // Local context + private Path initialPath; + private Path currentFolder; + + public DocumentsFolderComposite(Composite parent, int style, Node context) { + super(parent, style); + this.currentBaseContext = context; + + this.setLayout(EclipseUiUtils.noSpaceGridLayout()); + + SashForm form = new SashForm(this, SWT.HORIZONTAL); + + Composite centerCmp = new Composite(form, SWT.BORDER | SWT.NO_FOCUS); + createDisplay(centerCmp); + + rightPanelCmp = new Composite(form, SWT.NO_FOCUS); + + form.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + form.setWeights(new int[] { 55, 20 }); + } + + public void populate(Path path) { + initialPath = path; + directoryDisplayViewer.setInitialPath(initialPath); + setInput(path); + } + + void refresh() { + modifyFilter(false); + } + + private void createDisplay(final Composite parent) { + parent.setLayout(EclipseUiUtils.noSpaceGridLayout()); + + // top filter + filterCmp = new Composite(parent, SWT.NO_FOCUS); + filterCmp.setLayoutData(EclipseUiUtils.fillWidth()); + RowLayout rl = new RowLayout(SWT.HORIZONTAL); + rl.wrap = true; + rl.center = true; + filterCmp.setLayout(rl); + // addFilterPanel(filterCmp); + + // Main display + directoryDisplayViewer = new FsTableViewer(parent, SWT.MULTI); + List colDefs = new ArrayList<>(); + colDefs.add(new ColumnDefinition(new FileIconNameLabelProvider(), " Name", 250)); + colDefs.add(new ColumnDefinition(new NioFileLabelProvider(FsUiConstants.PROPERTY_SIZE), "Size", 100)); +// colDefs.add(new ColumnDefinition(new NioFileLabelProvider(FsUiConstants.PROPERTY_TYPE), "Type", 150)); + colDefs.add(new ColumnDefinition(new NioFileLabelProvider(FsUiConstants.PROPERTY_LAST_MODIFIED), + "Last modified", 400)); + final Table table = directoryDisplayViewer.configureDefaultTable(colDefs); + table.setLayoutData(EclipseUiUtils.fillAll()); + + directoryDisplayViewer.addSelectionChangedListener(new ISelectionChangedListener() { + + @Override + public void selectionChanged(SelectionChangedEvent event) { + IStructuredSelection selection = (IStructuredSelection) directoryDisplayViewer.getSelection(); + Path selected = null; + if (selection.isEmpty()) + setSelected(null); + else { + Object o = selection.getFirstElement(); + if (o instanceof Path) + selected = (Path) o; + else if (o instanceof ParentDir) + selected = ((ParentDir) o).getPath(); + } + if (selected != null) { + // TODO manage multiple selection + setSelected(selected); + } + } + }); + + directoryDisplayViewer.addDoubleClickListener(new IDoubleClickListener() { + @Override + public void doubleClick(DoubleClickEvent event) { + IStructuredSelection selection = (IStructuredSelection) directoryDisplayViewer.getSelection(); + Path selected = null; + if (!selection.isEmpty()) { + Object o = selection.getFirstElement(); + if (o instanceof Path) + selected = (Path) o; + else if (o instanceof ParentDir) + selected = ((ParentDir) o).getPath(); + } + if (selected != null) { + if (Files.isDirectory(selected)) + setInput(selected); + else + externalNavigateTo(selected); + } + } + }); + + // The context menu + contextMenu = new DocumentsContextMenu(this, documentUiService); + + table.addMouseListener(new MouseAdapter() { + private static final long serialVersionUID = 6737579410648595940L; + + @Override + public void mouseDown(MouseEvent e) { + if (e.button == 3) { + // contextMenu.setCurrFolderPath(currDisplayedFolder); + contextMenu.show(table, new Point(e.x, e.y), + (IStructuredSelection) directoryDisplayViewer.getSelection(), currentFolder); + } + } + }); + + FileDrop fileDrop = new FileDrop() { + + @Override + protected void processFileUpload(InputStream in, String fileName, String contetnType) throws IOException { + Path file = currentFolder.resolve(fileName); + Files.copy(in, file); + refresh(); + } + }; + fileDrop.createDropTarget(directoryDisplayViewer.getTable()); + } + + /** + * Overwrite to enable single sourcing between workbench and CMS navigation + */ + protected void externalNavigateTo(Path path) { + + } + + private void addPathElementBtn(Path path) { + Button elemBtn = new Button(breadCrumbCmp, SWT.PUSH); + String nameStr; + if (path.toString().equals("/")) + nameStr = "[jcr:root]"; + else + nameStr = path.getFileName().toString(); +// elemBtn.setText(nameStr + " >> "); + elemBtn.setText(nameStr); + CmsUiUtils.style(elemBtn, FsStyles.BREAD_CRUMB_BTN); + elemBtn.addSelectionListener(new SelectionAdapter() { + private static final long serialVersionUID = -4103695476023480651L; + + @Override + public void widgetSelected(SelectionEvent e) { + setInput(path); + } + }); + } + + public void setInput(Path path) { + if (path.equals(currentFolder)) + return; + // below initial path + if (!initialPath.equals(path) && initialPath.startsWith(path)) + return; + currentFolder = path; + + Path diff = initialPath.relativize(currentFolder); + + for (Control child : filterCmp.getChildren()) + if (!child.equals(filterTxt)) + child.dispose(); + + // Bread crumbs + breadCrumbCmp = new Composite(filterCmp, SWT.NO_FOCUS); + CmsUiUtils.style(breadCrumbCmp, FsStyles.BREAD_CRUMB_BTN); + RowLayout breadCrumbLayout = new RowLayout(); + breadCrumbLayout.spacing = 0; + breadCrumbLayout.marginTop = 0; + breadCrumbLayout.marginBottom = 0; + breadCrumbLayout.marginRight = 0; + breadCrumbLayout.marginLeft = 0; + breadCrumbCmp.setLayout(breadCrumbLayout); + addPathElementBtn(initialPath); + Path currTarget = initialPath; + if (!diff.toString().equals("")) + for (Path pathElem : diff) { + currTarget = currTarget.resolve(pathElem); + addPathElementBtn(currTarget); + } + + if (filterTxt != null) { + filterTxt.setText(""); + filterTxt.moveBelow(null); + } else { + modifyFilter(false); + } + setSelected(null); + filterCmp.getParent().layout(true, true); + } + + private void setSelected(Path path) { + if (path == null) + setOverviewInput(currentFolder); + else + setOverviewInput(path); + } + + public Viewer getViewer() { + return directoryDisplayViewer; + } + + /** + * Recreates the content of the box that displays information about the current + * selected Path. + */ + private void setOverviewInput(Path path) { + try { + EclipseUiUtils.clear(rightPanelCmp); + rightPanelCmp.setLayout(new GridLayout()); + if (path != null) { + // if (isImg(context)) { + // EditableImage image = new Img(parent, RIGHT, context, + // imageWidth); + // image.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, + // true, false, + // 2, 1)); + // } + + Label contextL = new Label(rightPanelCmp, SWT.NONE); + contextL.setText(path.getFileName().toString()); + contextL.setFont(EclipseUiUtils.getBoldFont(rightPanelCmp)); + FileTime lastModified = Files.getLastModifiedTime(path); + if (lastModified.toMillis() != 0) + try { + String lastModifiedStr = dateFormat.format(new Date(lastModified.toMillis())); + addProperty(rightPanelCmp, "Last modified", lastModifiedStr); + } catch (Exception e) { + log.error("Workarounded issue while getting last update date for " + path, e); + addProperty(rightPanelCmp, "Last modified", "-"); + } + // addProperty(rightPannelCmp, "Owner", + // Files.getOwner(path).getName()); + if (Files.isDirectory(path)) { + addProperty(rightPanelCmp, "Type", "Folder"); + } else { + String mimeType = Files.probeContentType(path); + if (EclipseUiUtils.isEmpty(mimeType)) + mimeType = "Unknown"; + addProperty(rightPanelCmp, "Type", mimeType); + addProperty(rightPanelCmp, "Size", FsUiUtils.humanReadableByteCount(Files.size(path), false)); + } + + // read all attributes +// Map attrs = Files.readAttributes(path, "*"); +// for (String attr : attrs.keySet()) { +// Object value = attrs.get(attr); +// String str; +// if (value instanceof Calendar) { +// str = dateFormat.format(((Calendar) value).getTime()); +// } else { +// str = value.toString(); +// } +// addProperty(rightPanelCmp, attr, str); +// +// } + } + rightPanelCmp.layout(true, true); + } catch (IOException e) { + throw new IllegalStateException("Cannot display details for " + path.toString(), e); + } + } + + private void addFilterPanel(Composite parent) { + // parent.setLayout(EclipseUiUtils.noSpaceGridLayout(new GridLayout(2, + // false))); + + filterTxt = new Text(parent, SWT.SEARCH | SWT.ICON_CANCEL); + filterTxt.setMessage("Search current folder"); + filterTxt.setLayoutData(new RowData(250, SWT.DEFAULT)); + filterTxt.addModifyListener(new ModifyListener() { + private static final long serialVersionUID = 1L; + + public void modifyText(ModifyEvent event) { + modifyFilter(false); + } + }); + filterTxt.addKeyListener(new KeyListener() { + private static final long serialVersionUID = 2533535233583035527L; + + @Override + public void keyReleased(KeyEvent e) { + } + + @Override + public void keyPressed(KeyEvent e) { + // boolean shiftPressed = (e.stateMask & SWT.SHIFT) != 0; + // // boolean altPressed = (e.stateMask & SWT.ALT) != 0; + // FilterEntitiesVirtualTable currTable = null; + // if (currEdited != null) { + // FilterEntitiesVirtualTable table = + // browserCols.get(currEdited); + // if (table != null && !table.isDisposed()) + // currTable = table; + // } + // + // if (e.keyCode == SWT.ARROW_DOWN) + // currTable.setFocus(); + // else if (e.keyCode == SWT.BS) { + // if (filterTxt.getText().equals("") + // && !(currEdited.getNameCount() == 1 || + // currEdited.equals(initialPath))) { + // Path oldEdited = currEdited; + // Path parentPath = currEdited.getParent(); + // setEdited(parentPath); + // if (browserCols.containsKey(parentPath)) + // browserCols.get(parentPath).setSelected(oldEdited); + // filterTxt.setFocus(); + // e.doit = false; + // } + // } else if (e.keyCode == SWT.TAB && !shiftPressed) { + // Path uniqueChild = getOnlyChild(currEdited, + // filterTxt.getText()); + // if (uniqueChild != null) { + // // Highlight the unique chosen child + // currTable.setSelected(uniqueChild); + // setEdited(uniqueChild); + // } + // filterTxt.setFocus(); + // e.doit = false; + // } + } + }); + } + + // private Path getOnlyChild(Path parent, String filter) { + // try (DirectoryStream stream = + // Files.newDirectoryStream(currDisplayedFolder, filter + "*")) { + // Path uniqueChild = null; + // boolean moreThanOne = false; + // loop: for (Path entry : stream) { + // if (uniqueChild == null) { + // uniqueChild = entry; + // } else { + // moreThanOne = true; + // break loop; + // } + // } + // if (!moreThanOne) + // return uniqueChild; + // return null; + // } catch (IOException ioe) { + // throw new DocumentsException( + // "Unable to determine unique child existence and get it under " + parent + + // " with filter " + filter, + // ioe); + // } + // } + + private void modifyFilter(boolean fromOutside) { + if (!fromOutside) + if (currentFolder != null) { + String filter; + if (filterTxt != null) + filter = filterTxt.getText() + "*"; + else + filter = "*"; + directoryDisplayViewer.setInput(currentFolder, filter); + } + } + + // Simplify UI implementation + private void addProperty(Composite parent, String propName, String value) { + Label propLbl = new Label(parent, SWT.NONE); + //propLbl.setText(ConnectUtils.replaceAmpersand(propName + ": " + value)); + propLbl.setText(value); + //CmsUiUtils.markup(propLbl); + } + + public Path getCurrentFolder() { + return currentFolder; + } + +} diff --git a/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsFolderUiProvider.java b/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsFolderUiProvider.java new file mode 100644 index 0000000..bdc194b --- /dev/null +++ b/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsFolderUiProvider.java @@ -0,0 +1,44 @@ +package org.argeo.library.ui; + +import java.nio.file.Path; +import java.nio.file.spi.FileSystemProvider; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; + +import org.argeo.cms.fs.CmsFsUtils; +import org.argeo.cms.ui.CmsUiProvider; +import org.argeo.cms.ui.CmsView; +import org.argeo.cms.ui.util.CmsUiUtils; +import org.argeo.jcr.Jcr; +import org.argeo.suite.ui.SuiteEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + +/** UI provider of a document folder. */ +public class DocumentsFolderUiProvider implements CmsUiProvider { + private FileSystemProvider nodeFileSystemProvider; + + @Override + public Control createUi(Composite parent, Node context) throws RepositoryException { + CmsView cmsView = CmsView.getCmsView(parent); + DocumentsFolderComposite dfc = new DocumentsFolderComposite(parent, SWT.NONE, context) { + + @Override + protected void externalNavigateTo(Path path) { + Node folderNode = cmsView.doAs(() -> CmsFsUtils.getNode(Jcr.getSession(context).getRepository(), path)); + parent.addDisposeListener((e1) -> Jcr.logout(folderNode)); + cmsView.sendEvent(SuiteEvent.openNewPart.topic(), SuiteEvent.eventProperties(folderNode)); + } + }; + dfc.setLayoutData(CmsUiUtils.fillAll()); + dfc.populate(cmsView.doAs(() -> CmsFsUtils.getPath(nodeFileSystemProvider, context))); + return dfc; + } + + public void setNodeFileSystemProvider(FileSystemProvider nodeFileSystemProvider) { + this.nodeFileSystemProvider = nodeFileSystemProvider; + } + +} diff --git a/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsTreeUiProvider.java b/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsTreeUiProvider.java new file mode 100644 index 0000000..4660515 --- /dev/null +++ b/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsTreeUiProvider.java @@ -0,0 +1,80 @@ +package org.argeo.library.ui; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.spi.FileSystemProvider; + +import javax.jcr.Node; +import javax.jcr.Repository; +import javax.jcr.RepositoryException; + +import org.argeo.api.NodeConstants; +import org.argeo.api.NodeUtils; +import org.argeo.cms.fs.CmsFsUtils; +import org.argeo.cms.ui.CmsUiProvider; +import org.argeo.cms.ui.CmsView; +import org.argeo.cms.ui.util.CmsUiUtils; +import org.argeo.eclipse.ui.fs.FsTreeViewer; +import org.argeo.jcr.Jcr; +import org.argeo.suite.ui.SuiteEvent; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + +/** Tree view of a user root folders. */ +public class DocumentsTreeUiProvider implements CmsUiProvider { + private FileSystemProvider nodeFileSystemProvider; + private Repository repository; + + @Override + public Control createUi(Composite parent, Node context) throws RepositoryException { + parent.setLayout(new GridLayout()); + FsTreeViewer fsTreeViewer = new FsTreeViewer(parent, SWT.NONE); + fsTreeViewer.configureDefaultSingleColumnTable(500); + CmsView cmsView = CmsView.getCmsView(parent); + Node homeNode = NodeUtils.getUserHome(cmsView.doAs(() -> Jcr.login(repository, NodeConstants.HOME_WORKSPACE))); + parent.addDisposeListener((e1) -> Jcr.logout(homeNode)); + Path homePath = CmsFsUtils.getPath(nodeFileSystemProvider, homeNode); + fsTreeViewer.addSelectionChangedListener((e) -> { + IStructuredSelection selection = (IStructuredSelection) fsTreeViewer.getSelection(); + if (selection.isEmpty()) + return; + else { + Path newSelected = (Path) selection.getFirstElement(); + if (Files.isDirectory(newSelected)) { + Node folderNode = cmsView.doAs(() -> CmsFsUtils.getNode(repository, newSelected)); + parent.addDisposeListener((e1) -> Jcr.logout(folderNode)); + cmsView.sendEvent(SuiteEvent.refreshPart.topic(), SuiteEvent.eventProperties(folderNode)); + } + } + }); + fsTreeViewer.addDoubleClickListener((e) -> { + IStructuredSelection selection = (IStructuredSelection) fsTreeViewer.getSelection(); + if (selection.isEmpty()) + return; + else { + Path newSelected = (Path) selection.getFirstElement(); + if (Files.isDirectory(newSelected)) { + Node folderNode = cmsView.doAs(() -> CmsFsUtils.getNode(repository, newSelected)); + parent.addDisposeListener((e1) -> Jcr.logout(folderNode)); + cmsView.sendEvent(SuiteEvent.openNewPart.topic(), SuiteEvent.eventProperties(folderNode)); + } + } + }); + fsTreeViewer.setPathsInput(homePath); + fsTreeViewer.getControl().setLayoutData(CmsUiUtils.fillAll()); + fsTreeViewer.getControl().getParent().layout(true, true); + return fsTreeViewer.getControl(); + } + + public void setNodeFileSystemProvider(FileSystemProvider nodeFileSystemProvider) { + this.nodeFileSystemProvider = nodeFileSystemProvider; + } + + public void setRepository(Repository repository) { + this.repository = repository; + } + +} diff --git a/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsUiService.java b/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsUiService.java new file mode 100644 index 0000000..ad13d28 --- /dev/null +++ b/org.argeo.library.ui/src/org/argeo/library/ui/DocumentsUiService.java @@ -0,0 +1,310 @@ +package org.argeo.library.ui; + +import static org.argeo.cms.ui.dialogs.CmsMessageDialog.openConfirm; +import static org.argeo.cms.ui.dialogs.CmsMessageDialog.openError; +import static org.argeo.cms.ui.dialogs.SingleValueDialog.ask; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.reflect.Method; +import java.net.URI; +import java.nio.file.DirectoryNotEmptyException; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.cms.ui.dialogs.CmsFeedback; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.eclipse.ui.specific.OpenFile; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Shell; + +public class DocumentsUiService { + private final static Log log = LogFactory.getLog(DocumentsUiService.class); + + // Default known actions + public final static String ACTION_ID_CREATE_FOLDER = "createFolder"; + public final static String ACTION_ID_BOOKMARK_FOLDER = "bookmarkFolder"; + public final static String ACTION_ID_SHARE_FOLDER = "shareFolder"; + public final static String ACTION_ID_DOWNLOAD_FOLDER = "downloadFolder"; + public final static String ACTION_ID_RENAME = "rename"; + public final static String ACTION_ID_DELETE = "delete"; + public final static String ACTION_ID_UPLOAD_FILE = "uploadFiles"; + // public final static String ACTION_ID_OPEN = "open"; + public final static String ACTION_ID_DELETE_BOOKMARK = "deleteBookmark"; + public final static String ACTION_ID_RENAME_BOOKMARK = "renameBookmark"; + + public String getLabel(String actionId) { + switch (actionId) { + case ACTION_ID_CREATE_FOLDER: + return "Create Folder"; + case ACTION_ID_BOOKMARK_FOLDER: + return "Bookmark Folder"; + case ACTION_ID_SHARE_FOLDER: + return "Share Folder"; + case ACTION_ID_DOWNLOAD_FOLDER: + return "Download as zip archive"; + case ACTION_ID_RENAME: + return "Rename"; + case ACTION_ID_DELETE: + return "Delete"; + case ACTION_ID_UPLOAD_FILE: + return "Upload Files"; +// case ACTION_ID_OPEN: +// return "Open"; + case ACTION_ID_DELETE_BOOKMARK: + return "Delete bookmark"; + case ACTION_ID_RENAME_BOOKMARK: + return "Rename bookmark"; + default: + throw new IllegalArgumentException("Unknown action ID " + actionId); + } + } + + public void openFile(Path toOpenPath) { + try { + String name = toOpenPath.getFileName().toString(); + File tmpFile = File.createTempFile("tmp", name); + tmpFile.deleteOnExit(); + try (OutputStream os = new FileOutputStream(tmpFile)) { + Files.copy(toOpenPath, os); + } catch (IOException e) { + throw new IllegalStateException("Cannot open copy " + name + " to tmpFile.", e); + } + String uri = Paths.get(tmpFile.getAbsolutePath()).toUri().toString(); + Map params = new HashMap(); + params.put(OpenFile.PARAM_FILE_NAME, name); + params.put(OpenFile.PARAM_FILE_URI, uri); + // FIXME open file without a command + // CommandUtils.callCommand(OpenFile.ID, params); + } catch (IOException e1) { + throw new IllegalStateException("Cannot create tmp copy of " + toOpenPath, e1); + } + } + + public boolean deleteItems(Shell shell, IStructuredSelection selection) { + if (selection.isEmpty()) + return false; + + StringBuilder builder = new StringBuilder(); + @SuppressWarnings("unchecked") + Iterator iterator = selection.iterator(); + List paths = new ArrayList<>(); + + while (iterator.hasNext()) { + Path path = (Path) iterator.next(); + builder.append(path.getFileName() + ", "); + paths.add(path); + } + String msg = "You are about to delete following elements: " + builder.substring(0, builder.length() - 2) + + ". Are you sure?"; + if (openConfirm(msg)) { + for (Path path : paths) { + try { + // recursively delete directory and its content + Files.walkFileTree(path, new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + Files.delete(file); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + Files.delete(dir); + return FileVisitResult.CONTINUE; + } + }); + } catch (DirectoryNotEmptyException e) { + String errMsg = path.getFileName() + " cannot be deleted: directory is not empty."; + openError( errMsg); + throw new IllegalArgumentException("Cannot delete path " + path, e); + } catch (IOException e) { + String errMsg = e.toString(); + openError(errMsg); + throw new IllegalArgumentException("Cannot delete path " + path, e); + } + } + return true; + } + return false; + } + + public boolean renameItem(Shell shell, Path parentFolderPath, Path toRenamePath) { + String msg = "Enter a new name:"; + String name = ask( msg, toRenamePath.getFileName().toString()); + // TODO enhance check of name validity + if (EclipseUiUtils.notEmpty(name)) { + try { + Path child = parentFolderPath.resolve(name); + if (Files.exists(child)) { + String errMsg = "An object named " + name + " already exists at " + parentFolderPath.toString() + + ", please provide another name"; + openError( errMsg); + throw new IllegalArgumentException(errMsg); + } else { + Files.move(toRenamePath, child); + return true; + } + } catch (IOException e) { + throw new IllegalStateException("Cannot rename " + name + " at " + parentFolderPath.toString(), e); + } + } + return false; + } + + public boolean createFolder(Shell shell, Path currFolderPath) { + String msg = "Enter a name:"; + String name = ask( msg); + // TODO enhance check of name validity + if (EclipseUiUtils.notEmpty(name)) { + name = name.trim(); + try { + Path child = currFolderPath.resolve(name); + if (Files.exists(child)) { + String errMsg = "A folder named " + name + " already exists at " + currFolderPath.toString() + + ", cannot create"; + openError(errMsg); + throw new IllegalArgumentException(errMsg); + } else { + Files.createDirectories(child); + return true; + } + } catch (IOException e) { + throw new IllegalStateException("Cannot create folder " + name + " at " + currFolderPath.toString(), e); + } + } + return false; + } + +// public void bookmarkFolder(Path toBookmarkPath, Repository repository, DocumentsService documentsService) { +// String msg = "Provide a name:"; +// String name = SingleQuestion.ask("Create bookmark", msg, toBookmarkPath.getFileName().toString()); +// if (EclipseUiUtils.notEmpty(name)) +// documentsService.createFolderBookmark(toBookmarkPath, name, repository); +// } + + public boolean uploadFiles(Shell shell, Path currFolderPath) { +// shell = Display.getCurrent().getActiveShell();// ignore argument + try { + FileDialog dialog = new FileDialog(shell, SWT.MULTI); + dialog.setText("Choose one or more files to upload"); + + if (EclipseUiUtils.notEmpty(dialog.open())) { + String[] names = dialog.getFileNames(); + // Workaround small differences between RAP and RCP + // 1. returned names are absolute path on RAP and + // relative in RCP + // 2. in RCP we must use getFilterPath that does not + // exists on RAP + Method filterMethod = null; + Path parPath = null; + try { + filterMethod = dialog.getClass().getDeclaredMethod("getFilterPath"); + String filterPath = (String) filterMethod.invoke(dialog); + parPath = Paths.get(filterPath); + } catch (NoSuchMethodException nsme) { // RAP + } + if (names.length == 0) + return false; + else { + loop: for (String name : names) { + Path tmpPath = Paths.get(name); + if (parPath != null) + tmpPath = parPath.resolve(tmpPath); + if (Files.exists(tmpPath)) { + URI uri = tmpPath.toUri(); + String uriStr = uri.toString(); + + if (Files.isDirectory(tmpPath)) { + openError( + "Upload of directories in the system is not yet implemented"); + continue loop; + } + Path targetPath = currFolderPath.resolve(tmpPath.getFileName().toString()); + try (InputStream in = new FileInputStream(tmpPath.toFile())) { + Files.copy(in, targetPath); + Files.delete(tmpPath); + } + if (log.isDebugEnabled()) + log.debug("copied uploaded file " + uriStr + " to " + targetPath.toString()); + } else { + String msg = "Cannot copy tmp file from " + tmpPath.toString(); + if (parPath != null) + msg += "\nPlease remember that file upload fails when choosing files from the \"Recently Used\" bookmarks on some OS"; + openError( msg); + continue loop; + } + } + return true; + } + } + } catch (Exception e) { + CmsFeedback.show("Cannot import files to " + currFolderPath,e); + } + return false; + } + +// public boolean deleteBookmark(Shell shell, IStructuredSelection selection, Node bookmarkParent) { +// if (selection.isEmpty()) +// return false; +// +// StringBuilder builder = new StringBuilder(); +// @SuppressWarnings("unchecked") +// Iterator iterator = selection.iterator(); +// List nodes = new ArrayList<>(); +// +// while (iterator.hasNext()) { +// Node node = (Node) iterator.next(); +// builder.append(Jcr.get(node, Property.JCR_TITLE) + ", "); +// nodes.add(node); +// } +// String msg = "You are about to delete following bookmark: " + builder.substring(0, builder.length() - 2) +// + ". Are you sure?"; +// if (MessageDialog.openConfirm(shell, "Confirm deletion", msg)) { +// Session session = Jcr.session(bookmarkParent); +// try { +// if (session.hasPendingChanges()) +// throw new DocumentsException("Cannot remove bookmarks, session is not clean"); +// for (Node path : nodes) +// path.remove(); +// bookmarkParent.getSession().save(); +// return true; +// } catch (RepositoryException e) { +// JcrUtils.discardQuietly(session); +// throw new DocumentsException("Cannot delete bookmarks " + builder.toString(), e); +// } +// } +// return false; +// } + +// public boolean renameBookmark(IStructuredSelection selection) { +// if (selection.isEmpty() || selection.size() > 1) +// return false; +// Node toRename = (Node) selection.getFirstElement(); +// String msg = "Please provide a new name."; +// String name = SingleQuestion.ask("Rename bookmark", msg, ConnectJcrUtils.get(toRename, Property.JCR_TITLE)); +// if (EclipseUiUtils.notEmpty(name) +// && ConnectJcrUtils.setJcrProperty(toRename, Property.JCR_TITLE, PropertyType.STRING, name)) { +// ConnectJcrUtils.saveIfNecessary(toRename); +// return true; +// } +// return false; +// } +} diff --git a/org.argeo.people.ui/.classpath b/org.argeo.people.ui/.classpath new file mode 100644 index 0000000..e801ebf --- /dev/null +++ b/org.argeo.people.ui/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.argeo.people.ui/.gitignore b/org.argeo.people.ui/.gitignore new file mode 100644 index 0000000..09e3bc9 --- /dev/null +++ b/org.argeo.people.ui/.gitignore @@ -0,0 +1,2 @@ +/bin/ +/target/ diff --git a/org.argeo.people.ui/.project b/org.argeo.people.ui/.project new file mode 100644 index 0000000..b3d17df --- /dev/null +++ b/org.argeo.people.ui/.project @@ -0,0 +1,33 @@ + + + org.argeo.people.ui + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.pde.ds.core.builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/org.argeo.people.ui/META-INF/.gitignore b/org.argeo.people.ui/META-INF/.gitignore new file mode 100644 index 0000000..4854a41 --- /dev/null +++ b/org.argeo.people.ui/META-INF/.gitignore @@ -0,0 +1 @@ +/MANIFEST.MF diff --git a/org.argeo.people.ui/OSGI-INF/l10n/bundle.properties b/org.argeo.people.ui/OSGI-INF/l10n/bundle.properties new file mode 100644 index 0000000..e619de4 --- /dev/null +++ b/org.argeo.people.ui/OSGI-INF/l10n/bundle.properties @@ -0,0 +1 @@ +people=people diff --git a/org.argeo.people.ui/OSGI-INF/peopleEntryArea.xml b/org.argeo.people.ui/OSGI-INF/peopleEntryArea.xml new file mode 100644 index 0000000..9601294 --- /dev/null +++ b/org.argeo.people.ui/OSGI-INF/peopleEntryArea.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/org.argeo.people.ui/OSGI-INF/peopleLayer.xml b/org.argeo.people.ui/OSGI-INF/peopleLayer.xml new file mode 100644 index 0000000..09392aa --- /dev/null +++ b/org.argeo.people.ui/OSGI-INF/peopleLayer.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/org.argeo.people.ui/OSGI-INF/personUiProvider.xml b/org.argeo.people.ui/OSGI-INF/personUiProvider.xml new file mode 100644 index 0000000..abd2d8d --- /dev/null +++ b/org.argeo.people.ui/OSGI-INF/personUiProvider.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/org.argeo.people.ui/bnd.bnd b/org.argeo.people.ui/bnd.bnd new file mode 100644 index 0000000..1b92ebb --- /dev/null +++ b/org.argeo.people.ui/bnd.bnd @@ -0,0 +1,16 @@ +Import-Package:\ +javax.jcr.nodetype,\ +org.osgi.service.event,\ +org.argeo.suite.ui,\ +org.argeo.api,\ +org.eclipse.swt,\ +org.eclipse.jface.viewers,\ +org.eclipse.jface.window,\ +org.osgi.framework,\ +* + +Service-Component:\ +OSGI-INF/peopleLayer.xml,\ +OSGI-INF/personUiProvider.xml,\ +OSGI-INF/peopleEntryArea.xml + diff --git a/org.argeo.people.ui/build.properties b/org.argeo.people.ui/build.properties new file mode 100644 index 0000000..34d2e4d --- /dev/null +++ b/org.argeo.people.ui/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/org.argeo.people.ui/config/peopleEntryArea.properties b/org.argeo.people.ui/config/peopleEntryArea.properties new file mode 100644 index 0000000..37b28f9 --- /dev/null +++ b/org.argeo.people.ui/config/peopleEntryArea.properties @@ -0,0 +1 @@ +service.pid=argeo.people.ui.peopleEntryArea diff --git a/org.argeo.people.ui/config/peopleLayer.properties b/org.argeo.people.ui/config/peopleLayer.properties new file mode 100644 index 0000000..adadb7b --- /dev/null +++ b/org.argeo.people.ui/config/peopleLayer.properties @@ -0,0 +1,7 @@ +service.pid=argeo.people.ui.peopleLayer + +icon=people +weights=5000,5000 +title=%people + +entity.type=entity:person \ No newline at end of file diff --git a/org.argeo.people.ui/config/personUiProvider.properties b/org.argeo.people.ui/config/personUiProvider.properties new file mode 100644 index 0000000..8c40c7d --- /dev/null +++ b/org.argeo.people.ui/config/personUiProvider.properties @@ -0,0 +1,3 @@ +service.pid=argeo.people.ui.personUiProvider + +entity.type=entity:person \ No newline at end of file diff --git a/org.argeo.people.ui/pom.xml b/org.argeo.people.ui/pom.xml new file mode 100644 index 0000000..d211fc7 --- /dev/null +++ b/org.argeo.people.ui/pom.xml @@ -0,0 +1,37 @@ + + + 4.0.0 + + org.argeo.suite + argeo-suite + 2.3-SNAPSHOT + .. + + org.argeo.people.ui + People UI + jar + + + org.argeo.suite + org.argeo.suite.ui + 2.3-SNAPSHOT + + + + + org.argeo.tp + argeo-tp-rap-e4 + ${version.argeo-tp} + pom + provided + + + + org.argeo.commons + org.argeo.eclipse.ui.rap + ${version.argeo-commons} + provided + + + + diff --git a/org.argeo.people.ui/src/org/argeo/people/ui/PeopleEntryArea.java b/org.argeo.people.ui/src/org/argeo/people/ui/PeopleEntryArea.java new file mode 100644 index 0000000..2fd38da --- /dev/null +++ b/org.argeo.people.ui/src/org/argeo/people/ui/PeopleEntryArea.java @@ -0,0 +1,184 @@ +package org.argeo.people.ui; + +import java.util.Set; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; + +import org.argeo.cms.CmsUserManager; +import org.argeo.cms.ui.CmsTheme; +import org.argeo.cms.ui.CmsUiProvider; +import org.argeo.cms.ui.CmsView; +import org.argeo.cms.ui.dialogs.CmsWizardDialog; +import org.argeo.cms.ui.util.CmsUiUtils; +import org.argeo.eclipse.ui.Selected; +import org.argeo.naming.LdapAttrs; +import org.argeo.suite.SuiteRole; +import org.argeo.suite.ui.SuiteEvent; +import org.argeo.suite.ui.SuiteIcon; +import org.argeo.suite.ui.dialogs.NewUserWizard; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.window.Window; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.swt.widgets.ToolItem; +import org.osgi.service.useradmin.User; + +/** Entry to the admin area. */ +public class PeopleEntryArea implements CmsUiProvider { + + private CmsUserManager cmsUserManager; + + @Override + public Control createUi(Composite parent, Node context) throws RepositoryException { + CmsTheme theme = CmsTheme.getCmsTheme(parent); + parent.setLayout(new GridLayout()); + TableViewer usersViewer = new TableViewer(parent); + usersViewer.setContentProvider(new UsersContentProvider()); + + TableViewerColumn idCol = new TableViewerColumn(usersViewer, SWT.NONE); + idCol.getColumn().setWidth(70); + idCol.setLabelProvider(new ColumnLabelProvider() { + + @Override + public String getText(Object element) { + + return getUserProperty(element, LdapAttrs.uid.name()); + } + }); + + TableViewerColumn givenNameCol = new TableViewerColumn(usersViewer, SWT.NONE); + givenNameCol.getColumn().setWidth(150); + givenNameCol.setLabelProvider(new ColumnLabelProvider() { + + @Override + public String getText(Object element) { + + return getUserProperty(element, LdapAttrs.givenName.name()); + } + }); + + TableViewerColumn snCol = new TableViewerColumn(usersViewer, SWT.NONE); + snCol.getColumn().setWidth(150); + snCol.setLabelProvider(new ColumnLabelProvider() { + + @Override + public String getText(Object element) { + + return getUserProperty(element, LdapAttrs.sn.name()); + } + }); + + TableViewerColumn mailCol = new TableViewerColumn(usersViewer, SWT.NONE); + mailCol.getColumn().setWidth(400); + mailCol.setLabelProvider(new ColumnLabelProvider() { + + @Override + public String getText(Object element) { + + return getUserProperty(element, LdapAttrs.mail.name()); + } + }); + + Composite bottom = new Composite(parent, SWT.NONE); + bottom.setLayoutData(CmsUiUtils.fillWidth()); + bottom.setLayout(CmsUiUtils.noSpaceGridLayout()); + ToolBar bottomToolBar = new ToolBar(bottom, SWT.NONE); + bottomToolBar.setLayoutData(new GridData(SWT.END, SWT.FILL, true, false)); + ToolItem deleteItem = new ToolItem(bottomToolBar, SWT.FLAT); + deleteItem.setEnabled(false); +// CmsUiUtils.style(deleteItem, SuiteStyle.recentItems); + deleteItem.setImage(SuiteIcon.delete.getSmallIcon(theme)); + ToolItem addItem = new ToolItem(bottomToolBar, SWT.FLAT); + addItem.setImage(SuiteIcon.add.getSmallIcon(theme)); + usersViewer.addDoubleClickListener(new IDoubleClickListener() { + + @Override + public void doubleClick(DoubleClickEvent event) { + User user = (User) usersViewer.getStructuredSelection().getFirstElement(); + if (user != null) { +// Node userNode = getOrCreateUserNode(user, context); + CmsView.getCmsView(parent).sendEvent(SuiteEvent.openNewPart.topic(), + SuiteEvent.eventProperties(user)); + } + + } + }); + usersViewer.addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + User user = (User) usersViewer.getStructuredSelection().getFirstElement(); + if (user != null) { +// Node userNode = getOrCreateUserNode(user, context); + CmsView.getCmsView(parent).sendEvent(SuiteEvent.refreshPart.topic(), + SuiteEvent.eventProperties(user)); + deleteItem.setEnabled(true); + } else { + deleteItem.setEnabled(false); + } + } + }); + + addItem.addSelectionListener((Selected) (e) -> { + // SuiteUtils.getOrCreateUserNode(adminSession, userDn); + Wizard wizard = new NewUserWizard(null); + CmsWizardDialog dialog = new CmsWizardDialog(parent.getShell(), wizard); + // WizardDialog dialog = new WizardDialog(shell, wizard); + if (dialog.open() == Window.OK) { + // TODO create + } + }); + + usersViewer.getTable().setLayoutData(CmsUiUtils.fillAll()); + usersViewer.setInput(cmsUserManager); + + return usersViewer.getTable(); + } + +// private Node getOrCreateUserNode(User user, Node context) { +// return JcrUtils.mkdirs(Jcr.getSession(context), +// "/" + EntityType.user.name() + "/" + getUserProperty(user, LdapAttrs.uid.name()), +// EntityType.user.get()); +// } + + private String getUserProperty(Object element, String key) { + Object value = ((User) element).getProperties().get(key); + return value != null ? value.toString() : null; + } + + class UsersContentProvider implements IStructuredContentProvider { + + @Override + public Object[] getElements(Object inputElement) { + CmsUserManager cum = (CmsUserManager) inputElement; + Set users = cum.listUsersInGroup(SuiteRole.coworker.dn(), null); + return users.toArray(); + } + + @Override + public void dispose() { + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + } + + public void setCmsUserManager(CmsUserManager cmsUserManager) { + this.cmsUserManager = cmsUserManager; + } + +} diff --git a/org.argeo.people.ui/src/org/argeo/people/ui/PersonUiProvider.java b/org.argeo.people.ui/src/org/argeo/people/ui/PersonUiProvider.java new file mode 100644 index 0000000..d2ea2fe --- /dev/null +++ b/org.argeo.people.ui/src/org/argeo/people/ui/PersonUiProvider.java @@ -0,0 +1,88 @@ +package org.argeo.people.ui; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; + +import org.argeo.cms.CmsUserManager; +import org.argeo.cms.ui.CmsUiProvider; +import org.argeo.cms.ui.util.CmsUiUtils; +import org.argeo.cms.ui.viewers.Section; +import org.argeo.naming.LdapAttrs; +import org.argeo.suite.ui.SuiteMsg; +import org.argeo.suite.ui.SuiteUiUtils; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Text; +import org.osgi.service.useradmin.User; + +/** Edit a suite user. */ +public class PersonUiProvider implements CmsUiProvider { + private String[] availableRoles; + private CmsUserManager cmsUserManager; + + @Override + public Control createUi(Composite parent, Node context) throws RepositoryException { + Section main = new Section(parent, SWT.NONE, context); + main.setLayoutData(CmsUiUtils.fillAll()); + + String uid = context.getName(); + User user = cmsUserManager.getUserFromLocalId(uid); + +// Text givenName = new Text(main, SWT.SINGLE); +// givenName.setText(getUserProperty(user, LdapAttrs.givenName.name())); + Text givenName = SuiteUiUtils.addFormInput(main, SuiteMsg.firstName.lead(), + getUserProperty(user, LdapAttrs.givenName.name())); + + Text sn = SuiteUiUtils.addFormInput(main, SuiteMsg.lastName.lead(), getUserProperty(user, LdapAttrs.sn.name())); + // sn.setText(getUserProperty(user, LdapAttrs.sn.name())); + + Text email = SuiteUiUtils.addFormInput(main, SuiteMsg.email.lead(), + getUserProperty(user, LdapAttrs.mail.name())); + // email.setText(getUserProperty(user, LdapAttrs.mail.name())); + + Text uidT = SuiteUiUtils.addFormLine(main, "uid", getUserProperty(user, LdapAttrs.uid.name())); + uidT.setText(uid); + +// Label dnL = new Label(main, SWT.NONE); +// dnL.setText(user.getName()); + + // roles + // Section rolesSection = new Section(main, SWT.NONE, context); + Group rolesSection = new Group(main, SWT.NONE); + rolesSection.setText("Roles"); + rolesSection.setLayoutData(CmsUiUtils.fillWidth()); + rolesSection.setLayout(new GridLayout()); + // new Label(rolesSection, SWT.NONE).setText("Roles:"); + List roles = Arrays.asList(cmsUserManager.getUserRoles(user.getName())); + for (String role : availableRoles) { + // new Label(rolesSection, SWT.NONE).setText(role); + Button radio = new Button(rolesSection, SWT.CHECK); + radio.setText(role); + if (roles.contains(role)) + radio.setSelection(true); + } + + return main; + } + + public void setCmsUserManager(CmsUserManager cmsUserManager) { + this.cmsUserManager = cmsUserManager; + } + + private String getUserProperty(Object element, String key) { + Object value = ((User) element).getProperties().get(key); + return value != null ? value.toString() : null; + } + + public void init(Map properties) { + availableRoles = (String[]) properties.get("availableRoles"); + } +} diff --git a/org.argeo.people.ui/src/org/argeo/people/ui/SuiteUserUiProvider.java b/org.argeo.people.ui/src/org/argeo/people/ui/SuiteUserUiProvider.java new file mode 100644 index 0000000..aa83cd2 --- /dev/null +++ b/org.argeo.people.ui/src/org/argeo/people/ui/SuiteUserUiProvider.java @@ -0,0 +1,88 @@ +package org.argeo.people.ui; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; + +import org.argeo.cms.CmsUserManager; +import org.argeo.cms.ui.CmsUiProvider; +import org.argeo.cms.ui.util.CmsUiUtils; +import org.argeo.cms.ui.viewers.Section; +import org.argeo.naming.LdapAttrs; +import org.argeo.suite.ui.SuiteMsg; +import org.argeo.suite.ui.SuiteUiUtils; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Text; +import org.osgi.service.useradmin.User; + +/** Edit a suite user. */ +public class SuiteUserUiProvider implements CmsUiProvider { + private String[] availableRoles; + private CmsUserManager cmsUserManager; + + @Override + public Control createUi(Composite parent, Node context) throws RepositoryException { + Section main = new Section(parent, SWT.NONE, context); + main.setLayoutData(CmsUiUtils.fillAll()); + + String uid = context.getName(); + User user = cmsUserManager.getUserFromLocalId(uid); + +// Text givenName = new Text(main, SWT.SINGLE); +// givenName.setText(getUserProperty(user, LdapAttrs.givenName.name())); + Text givenName = SuiteUiUtils.addFormInput(main, SuiteMsg.firstName.lead(), + getUserProperty(user, LdapAttrs.givenName.name())); + + Text sn = SuiteUiUtils.addFormInput(main, SuiteMsg.lastName.lead(), getUserProperty(user, LdapAttrs.sn.name())); + // sn.setText(getUserProperty(user, LdapAttrs.sn.name())); + + Text email = SuiteUiUtils.addFormInput(main, SuiteMsg.email.lead(), + getUserProperty(user, LdapAttrs.mail.name())); + // email.setText(getUserProperty(user, LdapAttrs.mail.name())); + + Text uidT = SuiteUiUtils.addFormLine(main, "uid", getUserProperty(user, LdapAttrs.uid.name())); + uidT.setText(uid); + +// Label dnL = new Label(main, SWT.NONE); +// dnL.setText(user.getName()); + + // roles + // Section rolesSection = new Section(main, SWT.NONE, context); + Group rolesSection = new Group(main, SWT.NONE); + rolesSection.setText("Roles"); + rolesSection.setLayoutData(CmsUiUtils.fillWidth()); + rolesSection.setLayout(new GridLayout()); + // new Label(rolesSection, SWT.NONE).setText("Roles:"); + List roles = Arrays.asList(cmsUserManager.getUserRoles(user.getName())); + for (String role : availableRoles) { + // new Label(rolesSection, SWT.NONE).setText(role); + Button radio = new Button(rolesSection, SWT.CHECK); + radio.setText(role); + if (roles.contains(role)) + radio.setSelection(true); + } + + return main; + } + + public void setCmsUserManager(CmsUserManager cmsUserManager) { + this.cmsUserManager = cmsUserManager; + } + + private String getUserProperty(Object element, String key) { + Object value = ((User) element).getProperties().get(key); + return value != null ? value.toString() : null; + } + + public void init(Map properties) { + availableRoles = (String[]) properties.get("availableRoles"); + } +} diff --git a/org.argeo.people.ui/src/org/argeo/people/ui/SuiteUsersEntryArea.java b/org.argeo.people.ui/src/org/argeo/people/ui/SuiteUsersEntryArea.java new file mode 100644 index 0000000..66f3eda --- /dev/null +++ b/org.argeo.people.ui/src/org/argeo/people/ui/SuiteUsersEntryArea.java @@ -0,0 +1,184 @@ +package org.argeo.people.ui; + +import java.util.Set; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; + +import org.argeo.cms.CmsUserManager; +import org.argeo.cms.ui.CmsTheme; +import org.argeo.cms.ui.CmsUiProvider; +import org.argeo.cms.ui.CmsView; +import org.argeo.cms.ui.dialogs.CmsWizardDialog; +import org.argeo.cms.ui.util.CmsUiUtils; +import org.argeo.eclipse.ui.Selected; +import org.argeo.naming.LdapAttrs; +import org.argeo.suite.SuiteRole; +import org.argeo.suite.ui.SuiteEvent; +import org.argeo.suite.ui.SuiteIcon; +import org.argeo.suite.ui.dialogs.NewUserWizard; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.window.Window; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.swt.widgets.ToolItem; +import org.osgi.service.useradmin.User; + +/** Entry to the admin area. */ +public class SuiteUsersEntryArea implements CmsUiProvider { + + private CmsUserManager cmsUserManager; + + @Override + public Control createUi(Composite parent, Node context) throws RepositoryException { + CmsTheme theme = CmsTheme.getCmsTheme(parent); + parent.setLayout(new GridLayout()); + TableViewer usersViewer = new TableViewer(parent); + usersViewer.setContentProvider(new UsersContentProvider()); + + TableViewerColumn idCol = new TableViewerColumn(usersViewer, SWT.NONE); + idCol.getColumn().setWidth(70); + idCol.setLabelProvider(new ColumnLabelProvider() { + + @Override + public String getText(Object element) { + + return getUserProperty(element, LdapAttrs.uid.name()); + } + }); + + TableViewerColumn givenNameCol = new TableViewerColumn(usersViewer, SWT.NONE); + givenNameCol.getColumn().setWidth(150); + givenNameCol.setLabelProvider(new ColumnLabelProvider() { + + @Override + public String getText(Object element) { + + return getUserProperty(element, LdapAttrs.givenName.name()); + } + }); + + TableViewerColumn snCol = new TableViewerColumn(usersViewer, SWT.NONE); + snCol.getColumn().setWidth(150); + snCol.setLabelProvider(new ColumnLabelProvider() { + + @Override + public String getText(Object element) { + + return getUserProperty(element, LdapAttrs.sn.name()); + } + }); + + TableViewerColumn mailCol = new TableViewerColumn(usersViewer, SWT.NONE); + mailCol.getColumn().setWidth(400); + mailCol.setLabelProvider(new ColumnLabelProvider() { + + @Override + public String getText(Object element) { + + return getUserProperty(element, LdapAttrs.mail.name()); + } + }); + + Composite bottom = new Composite(parent, SWT.NONE); + bottom.setLayoutData(CmsUiUtils.fillWidth()); + bottom.setLayout(CmsUiUtils.noSpaceGridLayout()); + ToolBar bottomToolBar = new ToolBar(bottom, SWT.NONE); + bottomToolBar.setLayoutData(new GridData(SWT.END, SWT.FILL, true, false)); + ToolItem deleteItem = new ToolItem(bottomToolBar, SWT.FLAT); + deleteItem.setEnabled(false); +// CmsUiUtils.style(deleteItem, SuiteStyle.recentItems); + deleteItem.setImage(SuiteIcon.delete.getSmallIcon(theme)); + ToolItem addItem = new ToolItem(bottomToolBar, SWT.FLAT); + addItem.setImage(SuiteIcon.add.getSmallIcon(theme)); + usersViewer.addDoubleClickListener(new IDoubleClickListener() { + + @Override + public void doubleClick(DoubleClickEvent event) { + User user = (User) usersViewer.getStructuredSelection().getFirstElement(); + if (user != null) { +// Node userNode = getOrCreateUserNode(user, context); + CmsView.getCmsView(parent).sendEvent(SuiteEvent.openNewPart.topic(), + SuiteEvent.eventProperties(user)); + } + + } + }); + usersViewer.addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + User user = (User) usersViewer.getStructuredSelection().getFirstElement(); + if (user != null) { +// Node userNode = getOrCreateUserNode(user, context); + CmsView.getCmsView(parent).sendEvent(SuiteEvent.refreshPart.topic(), + SuiteEvent.eventProperties(user)); + deleteItem.setEnabled(true); + } else { + deleteItem.setEnabled(false); + } + } + }); + + addItem.addSelectionListener((Selected) (e) -> { + // SuiteUtils.getOrCreateUserNode(adminSession, userDn); + Wizard wizard = new NewUserWizard(null); + CmsWizardDialog dialog = new CmsWizardDialog(parent.getShell(), wizard); + // WizardDialog dialog = new WizardDialog(shell, wizard); + if (dialog.open() == Window.OK) { + // TODO create + } + }); + + usersViewer.getTable().setLayoutData(CmsUiUtils.fillAll()); + usersViewer.setInput(cmsUserManager); + + return usersViewer.getTable(); + } + +// private Node getOrCreateUserNode(User user, Node context) { +// return JcrUtils.mkdirs(Jcr.getSession(context), +// "/" + EntityType.user.name() + "/" + getUserProperty(user, LdapAttrs.uid.name()), +// EntityType.user.get()); +// } + + private String getUserProperty(Object element, String key) { + Object value = ((User) element).getProperties().get(key); + return value != null ? value.toString() : null; + } + + class UsersContentProvider implements IStructuredContentProvider { + + @Override + public Object[] getElements(Object inputElement) { + CmsUserManager cum = (CmsUserManager) inputElement; + Set users = cum.listUsersInGroup(SuiteRole.coworker.dn(), null); + return users.toArray(); + } + + @Override + public void dispose() { + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + } + + public void setCmsUserManager(CmsUserManager cmsUserManager) { + this.cmsUserManager = cmsUserManager; + } + +} diff --git a/org.argeo.publishing.ui/.classpath b/org.argeo.publishing.ui/.classpath new file mode 100644 index 0000000..e801ebf --- /dev/null +++ b/org.argeo.publishing.ui/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.argeo.publishing.ui/.gitignore b/org.argeo.publishing.ui/.gitignore new file mode 100644 index 0000000..09e3bc9 --- /dev/null +++ b/org.argeo.publishing.ui/.gitignore @@ -0,0 +1,2 @@ +/bin/ +/target/ diff --git a/org.argeo.publishing.ui/.project b/org.argeo.publishing.ui/.project new file mode 100644 index 0000000..5e90066 --- /dev/null +++ b/org.argeo.publishing.ui/.project @@ -0,0 +1,33 @@ + + + org.argeo.publishing.ui + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.pde.ds.core.builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/org.argeo.publishing.ui/META-INF/.gitignore b/org.argeo.publishing.ui/META-INF/.gitignore new file mode 100644 index 0000000..4854a41 --- /dev/null +++ b/org.argeo.publishing.ui/META-INF/.gitignore @@ -0,0 +1 @@ +/MANIFEST.MF diff --git a/org.argeo.publishing.ui/OSGI-INF/dbk4Converter.xml b/org.argeo.publishing.ui/OSGI-INF/dbk4Converter.xml new file mode 100644 index 0000000..66526d9 --- /dev/null +++ b/org.argeo.publishing.ui/OSGI-INF/dbk4Converter.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.argeo.publishing.ui/OSGI-INF/dbkServlet.xml b/org.argeo.publishing.ui/OSGI-INF/dbkServlet.xml new file mode 100644 index 0000000..05522d5 --- /dev/null +++ b/org.argeo.publishing.ui/OSGI-INF/dbkServlet.xml @@ -0,0 +1,11 @@ + + + + + + + + "/> + + + diff --git a/org.argeo.publishing.ui/OSGI-INF/documentUiProvider.xml b/org.argeo.publishing.ui/OSGI-INF/documentUiProvider.xml new file mode 100644 index 0000000..5cee79f --- /dev/null +++ b/org.argeo.publishing.ui/OSGI-INF/documentUiProvider.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/org.argeo.publishing.ui/OSGI-INF/fontsServlet.xml b/org.argeo.publishing.ui/OSGI-INF/fontsServlet.xml new file mode 100644 index 0000000..6ca1c41 --- /dev/null +++ b/org.argeo.publishing.ui/OSGI-INF/fontsServlet.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/org.argeo.publishing.ui/OSGI-INF/htmlServletContext.xml b/org.argeo.publishing.ui/OSGI-INF/htmlServletContext.xml new file mode 100644 index 0000000..e0c1f6b --- /dev/null +++ b/org.argeo.publishing.ui/OSGI-INF/htmlServletContext.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/org.argeo.publishing.ui/OSGI-INF/l10n/bundle.properties b/org.argeo.publishing.ui/OSGI-INF/l10n/bundle.properties new file mode 100644 index 0000000..302f555 --- /dev/null +++ b/org.argeo.publishing.ui/OSGI-INF/l10n/bundle.properties @@ -0,0 +1,12 @@ +paragraph=paragraph +section=section +media=media +style=style + +insertParagraph=insert paragraph +deleteParagraph=delete paragraph +deleteSection=delete section + +insertPicture=insert picture +insertVideo=insert video +deleteMedia=delete media \ No newline at end of file diff --git a/org.argeo.publishing.ui/OSGI-INF/wwwLayer.xml b/org.argeo.publishing.ui/OSGI-INF/wwwLayer.xml new file mode 100644 index 0000000..497d652 --- /dev/null +++ b/org.argeo.publishing.ui/OSGI-INF/wwwLayer.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/org.argeo.publishing.ui/bnd.bnd b/org.argeo.publishing.ui/bnd.bnd new file mode 100644 index 0000000..67c0dd9 --- /dev/null +++ b/org.argeo.publishing.ui/bnd.bnd @@ -0,0 +1,23 @@ +Import-Package:\ +org.osgi.service.http.context,\ +javax.jcr.nodetype,\ +org.osgi.service.event,\ +org.argeo.suite.ui,\ +org.argeo.api,\ +org.eclipse.swt,\ +org.eclipse.jface.viewers,\ +org.osgi.framework,\ +org.apache.xml.serializer,\ +org.eclipse.rap.rwt,\ +* + +Provide-Capability:\ +cms.datamodel; name=docbook; cnd=/org/argeo/docbook/docbook.cnd; abstract=true + +Service-Component:\ +OSGI-INF/fontsServlet.xml,\ +OSGI-INF/htmlServletContext.xml,\ +OSGI-INF/dbkServlet.xml,\ +OSGI-INF/documentUiProvider.xml,\ +OSGI-INF/wwwLayer.xml,\ +OSGI-INF/dbk4Converter.xml diff --git a/org.argeo.publishing.ui/build.properties b/org.argeo.publishing.ui/build.properties new file mode 100644 index 0000000..e97efd7 --- /dev/null +++ b/org.argeo.publishing.ui/build.properties @@ -0,0 +1,7 @@ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + OSGI-INF/,\ + OSGI-INF/documentUiProvider.xml,\ + OSGI-INF/dbk4Converter.xml +source.. = src/ diff --git a/org.argeo.publishing.ui/config/documentUiProvider.properties b/org.argeo.publishing.ui/config/documentUiProvider.properties new file mode 100644 index 0000000..855735d --- /dev/null +++ b/org.argeo.publishing.ui/config/documentUiProvider.properties @@ -0,0 +1,3 @@ +service.pid=argeo.publishing.ui.documentUiProvider + +entity.type=entity:document,nt:file \ No newline at end of file diff --git a/org.argeo.publishing.ui/config/wwwLayer.properties b/org.argeo.publishing.ui/config/wwwLayer.properties new file mode 100644 index 0000000..d29fa5b --- /dev/null +++ b/org.argeo.publishing.ui/config/wwwLayer.properties @@ -0,0 +1,4 @@ +service.pid=argeo.publishing.ui.wwwLayer + +title=Web +icon=map \ No newline at end of file diff --git a/org.argeo.publishing.ui/pom.xml b/org.argeo.publishing.ui/pom.xml new file mode 100644 index 0000000..f26aeb4 --- /dev/null +++ b/org.argeo.publishing.ui/pom.xml @@ -0,0 +1,37 @@ + + + 4.0.0 + + org.argeo.suite + argeo-suite + 2.3-SNAPSHOT + .. + + org.argeo.publishing.ui + Publishing UI + jar + + + org.argeo.suite + org.argeo.suite.ui + 2.3-SNAPSHOT + + + + + org.argeo.tp + argeo-tp-rap-e4 + ${version.argeo-tp} + pom + provided + + + + org.argeo.commons + org.argeo.eclipse.ui.rap + ${version.argeo-commons} + provided + + + + diff --git a/org.argeo.publishing.ui/src/org/argeo/docbook/Dbk4Converter.java b/org.argeo.publishing.ui/src/org/argeo/docbook/Dbk4Converter.java new file mode 100644 index 0000000..916dddd --- /dev/null +++ b/org.argeo.publishing.ui/src/org/argeo/docbook/Dbk4Converter.java @@ -0,0 +1,100 @@ +package org.argeo.docbook; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +import javax.jcr.ImportUUIDBehavior; +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Templates; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; + +import org.apache.xalan.processor.TransformerFactoryImpl; +import org.argeo.jcr.JcrException; +import org.w3c.dom.Document; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** Convert from DocBook v4 to DocBook v5, using the official XSL. */ +public class Dbk4Converter { + private final Templates templates; + + public Dbk4Converter() { + try (InputStream in = getClass().getResourceAsStream("db4-upgrade.xsl")) { + Source xsl = new StreamSource(in); + TransformerFactory transformerFactory = new TransformerFactoryImpl(); + templates = transformerFactory.newTemplates(xsl); + } catch (IOException | TransformerConfigurationException e) { + throw new RuntimeException("Cannot initialise DocBook v4 converter", e); + } + } + + public void importXml(Node baseNode, InputStream in) throws IOException { + try (ByteArrayOutputStream out = new ByteArrayOutputStream();) { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setXIncludeAware(true); + factory.setNamespaceAware(true); + DocumentBuilder docBuilder = factory.newDocumentBuilder(); + Document doc = docBuilder.parse(new InputSource(in)); + Source xmlInput = new DOMSource(doc); + +// ContentHandler contentHandler = baseNode.getSession().getImportContentHandler(baseNode.getPath(), +// ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING); + + Transformer transformer = templates.newTransformer(); + Result xmlOutput = new StreamResult(out); + transformer.transform(xmlInput, xmlOutput); + try (InputStream dbk5in = new ByteArrayInputStream(out.toByteArray())) { + baseNode.getSession().importXML(baseNode.getPath(), dbk5in, + ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING); + } + } catch (RepositoryException e) { + throw new JcrException("Cannot import XML to " + baseNode, e); + } catch (TransformerException | SAXException | ParserConfigurationException e) { + throw new RuntimeException("Cannot import DocBook v4 to " + baseNode, e); + } + + } + + public static void main(String[] args) { + try { + + Source xsl = new StreamSource(new File("/usr/share/xml/docbook5/stylesheet/upgrade/db4-upgrade.xsl")); + TransformerFactory transformerFactory = new TransformerFactoryImpl(); + Templates templates = transformerFactory.newTemplates(xsl); + + File inputDir = new File(args[0]); + File outputDir = new File(args[1]); + + for (File inputFile : inputDir.listFiles()) { + Result xmlOutput = new StreamResult(new File(outputDir, inputFile.getName())); + + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setXIncludeAware(true); + factory.setNamespaceAware(true); + DocumentBuilder docBuilder = factory.newDocumentBuilder(); + Document doc = docBuilder.parse(inputFile); + Source xmlInput = new DOMSource(doc); + Transformer transformer = templates.newTransformer(); + transformer.transform(xmlInput, xmlOutput); + } + } catch (Throwable e) { + e.printStackTrace(); + } + } + +} diff --git a/org.argeo.publishing.ui/src/org/argeo/docbook/DbkAttr.java b/org.argeo.publishing.ui/src/org/argeo/docbook/DbkAttr.java new file mode 100644 index 0000000..84097e2 --- /dev/null +++ b/org.argeo.publishing.ui/src/org/argeo/docbook/DbkAttr.java @@ -0,0 +1,13 @@ +package org.argeo.docbook; + +/** Supported DocBook attributes. */ +public enum DbkAttr { + role, + // + fileref, contentwidth, contentdepth + // + ; + + public final static String XLINK_HREF = "xlink:href"; + +} diff --git a/org.argeo.publishing.ui/src/org/argeo/docbook/DbkMsg.java b/org.argeo.publishing.ui/src/org/argeo/docbook/DbkMsg.java new file mode 100644 index 0000000..8e87231 --- /dev/null +++ b/org.argeo.publishing.ui/src/org/argeo/docbook/DbkMsg.java @@ -0,0 +1,14 @@ +package org.argeo.docbook; + +import org.argeo.cms.Localized; + +/** DocBook related messages. */ +public enum DbkMsg implements Localized { + paragraph, deleteParagraph, + // + section, deleteSection, + // + media, deleteMedia, insertPicture, insertVideo, insertParagraph, + // + ; +} diff --git a/org.argeo.publishing.ui/src/org/argeo/docbook/DbkType.java b/org.argeo.publishing.ui/src/org/argeo/docbook/DbkType.java new file mode 100644 index 0000000..005d165 --- /dev/null +++ b/org.argeo.publishing.ui/src/org/argeo/docbook/DbkType.java @@ -0,0 +1,35 @@ +package org.argeo.docbook; + +import org.argeo.entity.JcrName; + +/** Supported DocBook elements */ +public enum DbkType implements JcrName { + book, article, section, + // + info, title, para, + // + mediaobject, imageobject, imagedata, videoobject, videodata, caption, + // + link, + // + ; + + @Override + public String getPrefix() { + return prefix(); + } + + public static String prefix() { + return "dbk"; + } + + @Override + public String getNamespace() { + return namespace(); + } + + public static String namespace() { + return "http://docbook.org/ns/docbook"; + } + +} diff --git a/org.argeo.publishing.ui/src/org/argeo/docbook/DbkUtils.java b/org.argeo.publishing.ui/src/org/argeo/docbook/DbkUtils.java new file mode 100644 index 0000000..151bf10 --- /dev/null +++ b/org.argeo.publishing.ui/src/org/argeo/docbook/DbkUtils.java @@ -0,0 +1,254 @@ +package org.argeo.docbook; + +import static org.argeo.docbook.DbkType.para; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; + +import javax.jcr.ImportUUIDBehavior; +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.PathNotFoundException; +import javax.jcr.RepositoryException; +import javax.jcr.ValueFormatException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.entity.EntityType; +import org.argeo.jcr.Jcr; +import org.argeo.jcr.JcrException; +import org.argeo.jcr.JcrUtils; +import org.argeo.jcr.JcrxApi; + +/** Utilities around DocBook. */ +public class DbkUtils { + private final static Log log = LogFactory.getLog(DbkUtils.class); + + /** Get or add a DocBook element. */ + public static Node getOrAddDbk(Node parent, DbkType child) { + try { + if (!parent.hasNode(child.get())) { + return addDbk(parent, child); + } else { + return parent.getNode(child.get()); + } + } catch (RepositoryException e) { + throw new JcrException("Cannot get or add element " + child.get() + " to " + parent, e); + } + } + + /** Add a DocBook element to this node. */ + public static Node addDbk(Node parent, DbkType child) { + try { + Node node = parent.addNode(child.get(), child.get()); + return node; + } catch (RepositoryException e) { + throw new JcrException("Cannot add element " + child.get() + " to " + parent, e); + } + } + + /** Whether this DocBook element is of this type. */ + public static boolean isDbk(Node node, DbkType type) { + return Jcr.getName(node).equals(type.get()); + } + + /** Whether this node is a DocBook type. */ + public static boolean isDbk(Node node) { + String name = Jcr.getName(node); + for (DbkType type : DbkType.values()) { + if (name.equals(type.get())) + return true; + } + return false; + } + + public static String getTitle(Node node) { + return JcrxApi.getXmlValue(node, DbkType.title.get()); + } + + public static void setTitle(Node node, String txt) { + Node titleNode = getOrAddDbk(node, DbkType.title); + JcrxApi.setXmlValue(node, titleNode, txt); + } + + public static Node getMetadata(Node infoContainer) { + try { + if (!infoContainer.hasNode(DbkType.info.get())) + return null; + Node info = infoContainer.getNode(DbkType.info.get()); + if (!info.hasNode(EntityType.local.get())) + return null; + return info.getNode(EntityType.local.get()); + } catch (RepositoryException e) { + throw new JcrException("Cannot retrieve metadata from " + infoContainer, e); + } + } + + public static Node getChildByRole(Node parent, String role) { + try { + NodeIterator baseSections = parent.getNodes(); + while (baseSections.hasNext()) { + Node n = baseSections.nextNode(); + String r = Jcr.get(n, DbkAttr.role.name()); + if (r != null && r.equals(role)) + return n; + } + return null; + } catch (RepositoryException e) { + throw new JcrException("Cannot get child from " + parent + " with role " + role, e); + } + } + + public static Node addParagraph(Node node, String txt) { + Node p = addDbk(node, para); + JcrxApi.setXmlValue(node, p, txt); + return p; + } + + /** + * Removes a paragraph if it empty. The sesison is not saved. + * + * @return true if the paragraph was empty and it was removed + */ + public static boolean removeIfEmptyParagraph(Node node) { + try { + if (isDbk(node, DbkType.para)) { + NodeIterator nit = node.getNodes(); + if (!nit.hasNext()) { + node.remove(); + return true; + } + Node first = nit.nextNode(); + if (nit.hasNext()) + return false; + if (first.getName().equals(Jcr.JCR_XMLTEXT)) { + String str = Jcr.get(first, Jcr.JCR_XMLCHARACTERS); + if (str != null && str.trim().equals("")) { + node.remove(); + return true; + } + } else { + return false; + } + } + return false; + } catch (RepositoryException e) { + throw new JcrException("Cannot remove possibly empty paragraph", e); + } + } + + public static Node insertImageAfter(Node sibling) { + try { + + Node parent = sibling.getParent(); + Node mediaNode = addDbk(parent, DbkType.mediaobject); + // TODO optimise? + parent.orderBefore(mediaNode.getName() + "[" + mediaNode.getIndex() + "]", + sibling.getName() + "[" + sibling.getIndex() + "]"); + parent.orderBefore(sibling.getName() + "[" + sibling.getIndex() + "]", + mediaNode.getName() + "[" + mediaNode.getIndex() + "]"); + + Node imageNode = addDbk(mediaNode, DbkType.imageobject); + Node imageDataNode = addDbk(imageNode, DbkType.imagedata); +// Node infoNode = imageNode.addNode(DocBookTypes.INFO, DocBookTypes.INFO); +// Node fileNode = JcrUtils.copyBytesAsFile(mediaFolder, EntityType.box.get(), new byte[0]); +// fileNode.addMixin(EntityType.box.get()); +// fileNode.setProperty(EntityNames.SVG_WIDTH, 0); +// fileNode.setProperty(EntityNames.SVG_LENGTH, 0); +// fileNode.addMixin(NodeType.MIX_MIMETYPE); +// +// // we assume this is a folder next to the main DocBook document +// // TODO make it more robust and generic +// String fileRef = mediaNode.getName(); +// imageDataNode.setProperty(DocBookNames.DBK_FILEREF, fileRef); + return mediaNode; + } catch (RepositoryException e) { + throw new JcrException("Cannot insert empty image after " + sibling, e); + } + } + + public static Node insertVideoAfter(Node sibling) { + try { + + Node parent = sibling.getParent(); + Node mediaNode = addDbk(parent, DbkType.mediaobject); + // TODO optimise? + parent.orderBefore(mediaNode.getName() + "[" + mediaNode.getIndex() + "]", + sibling.getName() + "[" + sibling.getIndex() + "]"); + parent.orderBefore(sibling.getName() + "[" + sibling.getIndex() + "]", + mediaNode.getName() + "[" + mediaNode.getIndex() + "]"); + + Node videoNode = addDbk(mediaNode, DbkType.videoobject); + Node videoDataNode = addDbk(videoNode, DbkType.videodata); + return mediaNode; + } catch (RepositoryException e) { + throw new JcrException("Cannot insert empty image after " + sibling, e); + } + } + + public static String getMediaFileref(Node node) { + try { + Node mediadata; + if (node.hasNode(DbkType.imageobject.get())) { + mediadata = node.getNode(DbkType.imageobject.get()).getNode(DbkType.imagedata.get()); + } else if (node.hasNode(DbkType.videoobject.get())) { + mediadata = node.getNode(DbkType.videoobject.get()).getNode(DbkType.videodata.get()); + } else { + throw new IllegalArgumentException("Fileref not found in " + node); + } + + if (mediadata.hasProperty(DbkAttr.fileref.name())) { + return mediadata.getProperty(DbkAttr.fileref.name()).getString(); + } else { + return null; + } + } catch (RepositoryException e) { + throw new JcrException("Cannot retrieve file ref from " + node, e); + } + } + + public static void exportXml(Node node, OutputStream out) throws IOException { + try { + node.getSession().exportDocumentView(node.getPath(), out, false, false); + } catch (RepositoryException e) { + throw new JcrException("Cannot export " + node + " to XML", e); + } + } + + public static void exportToFs(Node baseNode, DbkType type, Path directory) { + String fileName = Jcr.getName(baseNode) + ".dbk.xml"; + Path filePath = directory.resolve(fileName); + Node docBookNode = Jcr.getNode(baseNode, type.get()); + if (docBookNode == null) + throw new IllegalArgumentException("No " + type.get() + " under " + baseNode); + try { + Files.createDirectories(directory); + try (OutputStream out = Files.newOutputStream(filePath)) { + exportXml(docBookNode, out); + } + JcrUtils.copyFilesToFs(baseNode, directory, true); + if (log.isDebugEnabled()) + log.debug("DocBook " + baseNode + " exported to " + filePath.toAbsolutePath()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static void importXml(Node baseNode, InputStream in) throws IOException { + try { + baseNode.getSession().importXML(baseNode.getPath(), in, + ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING); + } catch (RepositoryException e) { + throw new JcrException("Cannot import XML to " + baseNode, e); + } + + } + + /** Singleton. */ + private DbkUtils() { + } + +} diff --git a/org.argeo.publishing.ui/src/org/argeo/docbook/db4-upgrade.xsl b/org.argeo.publishing.ui/src/org/argeo/docbook/db4-upgrade.xsl new file mode 100644 index 0000000..00096be --- /dev/null +++ b/org.argeo.publishing.ui/src/org/argeo/docbook/db4-upgrade.xsl @@ -0,0 +1,1398 @@ + + + + + + + + + + + + + + + + + UNKNOWN + + + + + + + + + + + + Converted by db4-upgrade version + + + + + + + + + + + + + + + + + + Check + + title. + + + + + + + + + + + + + + + Check + + : no title. + + + + + + + + + + + Check + + titleabbrev. + + + + + + + + + + + + + + + + + + + Check + + subtitle. + + + + + + + + + + + + + + + + + + + + + + + + + + + + Check + + title. + + + + + + + + + + + + + + + + + + + + + + Check + + titleabbrev. + + + + + + + + + + + + + + + + + + + Check + + subtitle. + + + + + + + + + + + + + + + + + + + + + + + + + + Discarding title from refentryinfo! + + + + + + + + Discarding titleabbrev from refentryinfo! + + + + + + + + Discarding subtitle from refentryinfo! + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Dropping class attribute from productname + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Convert equation without title to informal equation. + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Check conversion of srccredit + (othercredit="srccredit"). + + + + + ??? + + + + + + + + + + + + + + comment + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Converting invpartnumber to biblioid otherclass="invpartnumber". + + + + + + + + + + + + + + Converting contractsponsor to othercredit="contractsponsor". + + + + + + + + + + + + + + + + + + + + + Converting contractnum to othercredit="contractnum". + + + + + ??? + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Check conversion of collabname + (orgname role="collabname"). + + + + + + + + + + + + Discarding modespec ( + + ). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Check conversion of contrib + (othercontrib="contrib"). + + + + ??? + + + + + + + + + + + + + + + + + + + + Converting ulink to link. + + + + + + + + + + + + + + Converting ulink to uri. + + + + + + + + + + + + + + + + + + Discarding linkmode on olink. + + + + + + + + + Converting olink targetdocent to targetdoc. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -01- + + + + + -02- + + + + + -03- + + + + + -04- + + + + + -05- + + + + + -06- + + + + + -07- + + + + + -08- + + + + + -09- + + + + + -10- + + + + + -11- + + + + + -12- + + + + + + + + + + + + -01- + + + + + -02- + + + + + -03- + + + + + -04- + + + + + -05- + + + + + -06- + + + + + -07- + + + + + -08- + + + + + -09- + + + + + -10- + + + + + -11- + + + + + -12- + + + + + + + + + + + + + + + + + + Converted + + into + + for + + + + + + + + + + + + + + Unparseable date: + + in + + (Using default: + + ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Check abstract; moved into info correctly? + + + + + + + + + + + significance + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + beginpage pagenum= + + + Replacing beginpage with comment + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Discarding moreinfo on + + + + + + + + + + + + + + + + + + + + + Discarding float on + + + + + + + Adding floatstyle='normal' on + + + + + normal + + + + + + + Discarding float on + + + + + + + + Discarding float on + + + + + + + Adding floatstyle=' + + ' on + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Converting refmiscinfo@role=type to + @class=other,otherclass=type + + + other + type + + + + + + + + + + + + + + + + + 5.0 + + + + + + + + + 5.0 + + + + + + + + + + + + + + + + + + + ( + + ) + + + +
diff --git a/org.argeo.publishing.ui/src/org/argeo/docbook/docbook-full.cnd b/org.argeo.publishing.ui/src/org/argeo/docbook/docbook-full.cnd new file mode 100644 index 0000000..79c3882 --- /dev/null +++ b/org.argeo.publishing.ui/src/org/argeo/docbook/docbook-full.cnd @@ -0,0 +1,2998 @@ + + + +// + +[argeodbk:titled] +mixin + + dbk:info (dbk:info) = dbk:info * + + dbk:title (dbk:title) = dbk:title * + + dbk:titleabbrev (dbk:titleabbrev) = dbk:titleabbrev * + +[argeodbk:linkingAttributes] +mixin + - linkend (String) + - xlink:actuate (String) + - xlink:arcrole (String) + - xlink:href (String) + - xlink:role (String) + - xlink:show (String) + - xlink:title (String) + - xlink:type (String) + +[argeodbk:freeText] +mixin + + dbk:phrase (dbk:phrase) = dbk:phrase * + + dbk:replaceable (dbk:replaceable) = dbk:replaceable * + + jcr:xmltext (jcrx:xmltext) = jcrx:xmltext * + +[argeodbk:markupInlines] +mixin + + dbk:code (dbk:code) = dbk:code * + + dbk:constant (dbk:constant) = dbk:constant * + + dbk:email (dbk:email) = dbk:email * + + dbk:literal (dbk:literal) = dbk:literal * + + dbk:markup (dbk:markup) = dbk:markup * + + dbk:symbol (dbk:symbol) = dbk:symbol * + + dbk:tag (dbk:tag) = dbk:tag * + + dbk:token (dbk:token) = dbk:token * + + dbk:uri (dbk:uri) = dbk:uri * + +[argeodbk:listElements] +mixin + + dbk:bibliolist (dbk:bibliolist) = dbk:bibliolist * + + dbk:calloutlist (dbk:calloutlist) = dbk:calloutlist * + + dbk:glosslist (dbk:glosslist) = dbk:glosslist * + + dbk:itemizedlist (dbk:itemizedlist) = dbk:itemizedlist * + + dbk:orderedlist (dbk:orderedlist) = dbk:orderedlist * + + dbk:procedure (dbk:procedure) = dbk:procedure * + + dbk:qandaset (dbk:qandaset) = dbk:qandaset * + + dbk:segmentedlist (dbk:segmentedlist) = dbk:segmentedlist * + + dbk:simplelist (dbk:simplelist) = dbk:simplelist * + + dbk:variablelist (dbk:variablelist) = dbk:variablelist * + +[argeodbk:paragraphElements] +mixin + + dbk:formalpara (dbk:formalpara) = dbk:formalpara * + + dbk:para (dbk:para) = dbk:para * + + dbk:simpara (dbk:simpara) = dbk:simpara * + +[argeodbk:indexingInlines] +mixin + + dbk:indexterm (dbk:indexterm) = dbk:indexterm * + +[argeodbk:techDocElements] +mixin + + dbk:caution (dbk:caution) = dbk:caution * + + dbk:classsynopsis (dbk:classsynopsis) = dbk:classsynopsis * + + dbk:cmdsynopsis (dbk:cmdsynopsis) = dbk:cmdsynopsis * + + dbk:constraintdef (dbk:constraintdef) = dbk:constraintdef * + + dbk:constructorsynopsis (dbk:constructorsynopsis) = dbk:constructorsynopsis * + + dbk:destructorsynopsis (dbk:destructorsynopsis) = dbk:destructorsynopsis * + + dbk:equation (dbk:equation) = dbk:equation * + + dbk:example (dbk:example) = dbk:example * + + dbk:fieldsynopsis (dbk:fieldsynopsis) = dbk:fieldsynopsis * + + dbk:figure (dbk:figure) = dbk:figure * + + dbk:funcsynopsis (dbk:funcsynopsis) = dbk:funcsynopsis * + + dbk:important (dbk:important) = dbk:important * + + dbk:informalequation (dbk:informalequation) = dbk:informalequation * + + dbk:informalexample (dbk:informalexample) = dbk:informalexample * + + dbk:informalfigure (dbk:informalfigure) = dbk:informalfigure * + + dbk:informaltable (dbk:informaltable) = dbk:informaltable * + + dbk:literallayout (dbk:literallayout) = dbk:literallayout * + + dbk:methodsynopsis (dbk:methodsynopsis) = dbk:methodsynopsis * + + dbk:msgset (dbk:msgset) = dbk:msgset * + + dbk:note (dbk:note) = dbk:note * + + dbk:productionset (dbk:productionset) = dbk:productionset * + + dbk:programlisting (dbk:programlisting) = dbk:programlisting * + + dbk:programlistingco (dbk:programlistingco) = dbk:programlistingco * + + dbk:screen (dbk:screen) = dbk:screen * + + dbk:screenco (dbk:screenco) = dbk:screenco * + + dbk:synopsis (dbk:synopsis) = dbk:synopsis * + + dbk:table (dbk:table) = dbk:table * + + dbk:task (dbk:task) = dbk:task * + + dbk:tip (dbk:tip) = dbk:tip * + + dbk:warning (dbk:warning) = dbk:warning * + +[argeodbk:techDocInlines] +mixin + + dbk:accel (dbk:accel) = dbk:accel * + + dbk:application (dbk:application) = dbk:application * + + dbk:classname (dbk:classname) = dbk:classname * + + dbk:command (dbk:command) = dbk:command * + + dbk:computeroutput (dbk:computeroutput) = dbk:computeroutput * + + dbk:database (dbk:database) = dbk:database * + + dbk:envar (dbk:envar) = dbk:envar * + + dbk:errorcode (dbk:errorcode) = dbk:errorcode * + + dbk:errorname (dbk:errorname) = dbk:errorname * + + dbk:errortext (dbk:errortext) = dbk:errortext * + + dbk:errortype (dbk:errortype) = dbk:errortype * + + dbk:exceptionname (dbk:exceptionname) = dbk:exceptionname * + + dbk:filename (dbk:filename) = dbk:filename * + + dbk:function (dbk:function) = dbk:function * + + dbk:guibutton (dbk:guibutton) = dbk:guibutton * + + dbk:guiicon (dbk:guiicon) = dbk:guiicon * + + dbk:guilabel (dbk:guilabel) = dbk:guilabel * + + dbk:guimenu (dbk:guimenu) = dbk:guimenu * + + dbk:guimenuitem (dbk:guimenuitem) = dbk:guimenuitem * + + dbk:guisubmenu (dbk:guisubmenu) = dbk:guisubmenu * + + dbk:hardware (dbk:hardware) = dbk:hardware * + + dbk:initializer (dbk:initializer) = dbk:initializer * + + dbk:inlineequation (dbk:inlineequation) = dbk:inlineequation * + + dbk:interfacename (dbk:interfacename) = dbk:interfacename * + + dbk:keycap (dbk:keycap) = dbk:keycap * + + dbk:keycode (dbk:keycode) = dbk:keycode * + + dbk:keycombo (dbk:keycombo) = dbk:keycombo * + + dbk:keysym (dbk:keysym) = dbk:keysym * + + dbk:menuchoice (dbk:menuchoice) = dbk:menuchoice * + + dbk:methodname (dbk:methodname) = dbk:methodname * + + dbk:modifier (dbk:modifier) = dbk:modifier * + + dbk:mousebutton (dbk:mousebutton) = dbk:mousebutton * + + dbk:nonterminal (dbk:nonterminal) = dbk:nonterminal * + + dbk:ooclass (dbk:ooclass) = dbk:ooclass * + + dbk:ooexception (dbk:ooexception) = dbk:ooexception * + + dbk:oointerface (dbk:oointerface) = dbk:oointerface * + + dbk:option (dbk:option) = dbk:option * + + dbk:optional (dbk:optional) = dbk:optional * + + dbk:package (dbk:package) = dbk:package * + + dbk:parameter (dbk:parameter) = dbk:parameter * + + dbk:productname (dbk:productname) = dbk:productname * + + dbk:productnumber (dbk:productnumber) = dbk:productnumber * + + dbk:prompt (dbk:prompt) = dbk:prompt * + + dbk:property (dbk:property) = dbk:property * + + dbk:returnvalue (dbk:returnvalue) = dbk:returnvalue * + + dbk:shortcut (dbk:shortcut) = dbk:shortcut * + + dbk:systemitem (dbk:systemitem) = dbk:systemitem * + + dbk:termdef (dbk:termdef) = dbk:termdef * + + dbk:trademark (dbk:trademark) = dbk:trademark * + + dbk:type (dbk:type) = dbk:type * + + dbk:userinput (dbk:userinput) = dbk:userinput * + + dbk:varname (dbk:varname) = dbk:varname * + +[argeodbk:publishingElements] +mixin + + dbk:address (dbk:address) = dbk:address * + + dbk:blockquote (dbk:blockquote) = dbk:blockquote * + + dbk:epigraph (dbk:epigraph) = dbk:epigraph * + + dbk:sidebar (dbk:sidebar) = dbk:sidebar * + +[argeodbk:ubiquitousInlines] +mixin + + dbk:alt (dbk:alt) = dbk:alt * + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:biblioref (dbk:biblioref) = dbk:biblioref * + + dbk:inlinemediaobject (dbk:inlinemediaobject) = dbk:inlinemediaobject * + + dbk:link (dbk:link) = dbk:link * + + dbk:olink (dbk:olink) = dbk:olink * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:subscript (dbk:subscript) = dbk:subscript * + + dbk:superscript (dbk:superscript) = dbk:superscript * + + dbk:xref (dbk:xref) = dbk:xref * + +[argeodbk:abstractSection] +mixin + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bibliography (dbk:bibliography) = dbk:bibliography * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:glossary (dbk:glossary) = dbk:glossary * + + dbk:index (dbk:index) = dbk:index * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + + dbk:toc (dbk:toc) = dbk:toc * + - label (String) + - status (String) + +[argeodbk:bibliographyInlines] +mixin + + dbk:author (dbk:author) = dbk:author * + + dbk:citation (dbk:citation) = dbk:citation * + + dbk:citebiblioid (dbk:citebiblioid) = dbk:citebiblioid * + + dbk:citerefentry (dbk:citerefentry) = dbk:citerefentry * + + dbk:citetitle (dbk:citetitle) = dbk:citetitle * + + dbk:editor (dbk:editor) = dbk:editor * + + dbk:jobtitle (dbk:jobtitle) = dbk:jobtitle * + + dbk:org (dbk:org) = dbk:org * + + dbk:orgname (dbk:orgname) = dbk:orgname * + + dbk:person (dbk:person) = dbk:person * + + dbk:personname (dbk:personname) = dbk:personname * + +[argeodbk:publishingInlines] +mixin + + dbk:abbrev (dbk:abbrev) = dbk:abbrev * + + dbk:acronym (dbk:acronym) = dbk:acronym * + + dbk:coref (dbk:coref) = dbk:coref * + + dbk:date (dbk:date) = dbk:date * + + dbk:emphasis (dbk:emphasis) = dbk:emphasis * + + dbk:firstterm (dbk:firstterm) = dbk:firstterm * + + dbk:footnote (dbk:footnote) = dbk:footnote * + + dbk:footnoteref (dbk:footnoteref) = dbk:footnoteref * + + dbk:foreignphrase (dbk:foreignphrase) = dbk:foreignphrase * + + dbk:glossterm (dbk:glossterm) = dbk:glossterm * + + dbk:quote (dbk:quote) = dbk:quote * + + dbk:wordasword (dbk:wordasword) = dbk:wordasword * + +[argeodbk:base] +abstract +orderable + - annotations (String) + - arch (String) + - audience (String) + - condition (String) + - conformance (String) + - dir (String) + - os (String) + - remap (String) + - revision (String) + - revisionflag (String) + - role (String) + - security (String) + - userlevel (String) + - vendor (String) + - version (String) + - wordsize (String) + - xreflabel (String) + +[dbk:abbrev] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + + dbk:trademark (dbk:trademark) = dbk:trademark * + +[dbk:abstract] > argeodbk:base, argeodbk:linkingAttributes, argeodbk:paragraphElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + +[dbk:accel] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:acknowledgements] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + - label (String) + - status (String) + +[dbk:acronym] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + + dbk:trademark (dbk:trademark) = dbk:trademark * + +[dbk:address] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + + dbk:city (dbk:city) = dbk:city * + + dbk:country (dbk:country) = dbk:country * + + dbk:email (dbk:email) = dbk:email * + + dbk:fax (dbk:fax) = dbk:fax * + + dbk:otheraddr (dbk:otheraddr) = dbk:otheraddr * + + dbk:personname (dbk:personname) = dbk:personname * + + dbk:phone (dbk:phone) = dbk:phone * + + dbk:pob (dbk:pob) = dbk:pob * + + dbk:postcode (dbk:postcode) = dbk:postcode * + + dbk:state (dbk:state) = dbk:state * + + dbk:street (dbk:street) = dbk:street * + + dbk:uri (dbk:uri) = dbk:uri * + - continuation (String) + - language (String) + - linenumbering (String) + - startinglinenumber (String) + - xml:space (String) + +[dbk:affiliation] > argeodbk:base, argeodbk:linkingAttributes + + dbk:address (dbk:address) = dbk:address * + + dbk:jobtitle (dbk:jobtitle) = dbk:jobtitle * + + dbk:org (dbk:org) = dbk:org + + dbk:orgdiv (dbk:orgdiv) = dbk:orgdiv * + + dbk:orgname (dbk:orgname) = dbk:orgname + + dbk:shortaffil (dbk:shortaffil) = dbk:shortaffil + +[dbk:alt] > argeodbk:base + + dbk:inlinemediaobject (dbk:inlinemediaobject) = dbk:inlinemediaobject * + + jcr:xmltext (jcrx:xmltext) = jcrx:xmltext * + +[dbk:anchor] > argeodbk:base + +[dbk:annotation] > argeodbk:base, argeodbk:indexingInlines, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + - annotates (String) + +[dbk:answer] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:label (dbk:label) = dbk:label + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + +[dbk:appendix] > argeodbk:abstractSection, argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:refentry (dbk:refentry) = dbk:refentry * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:sect1 (dbk:sect1) = dbk:sect1 * + + dbk:section (dbk:section) = dbk:section * + + dbk:simplesect (dbk:simplesect) = dbk:simplesect * + + dbk:simplesect (dbk:simplesect) = dbk:simplesect * + +[dbk:application] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + - class (String) + +[dbk:arc] > argeodbk:base + - xlink:from (String) + - xlink:to (String) + +[dbk:area] > argeodbk:base + + dbk:alt (dbk:alt) = dbk:alt + - coords (String) + - label (String) + - linkends (String) + - otherunits (String) + - units (String) + +[dbk:areaset] > argeodbk:base + + dbk:area (dbk:area) = dbk:area * + - label (String) + - linkends (String) + - otherunits (String) + - units (String) + +[dbk:areaspec] > argeodbk:base, argeodbk:linkingAttributes + + dbk:area (dbk:area) = dbk:area * + + dbk:areaset (dbk:areaset) = dbk:areaset * + - otherunits (String) + - units (String) + +[dbk:arg] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + + dbk:arg (dbk:arg) = dbk:arg * + + dbk:group (dbk:group) = dbk:group * + + dbk:option (dbk:option) = dbk:option * + + dbk:sbr (dbk:sbr) = dbk:sbr * + + dbk:synopfragmentref (dbk:synopfragmentref) = dbk:synopfragmentref * + - choice (String) + - rep (String) + +[dbk:article] > argeodbk:abstractSection, argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:acknowledgements (dbk:acknowledgements) = dbk:acknowledgements * + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:appendix (dbk:appendix) = dbk:appendix * + + dbk:colophon (dbk:colophon) = dbk:colophon * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:refentry (dbk:refentry) = dbk:refentry * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:sect1 (dbk:sect1) = dbk:sect1 * + + dbk:section (dbk:section) = dbk:section * + + dbk:simplesect (dbk:simplesect) = dbk:simplesect * + + dbk:simplesect (dbk:simplesect) = dbk:simplesect * + - class (String) + +[dbk:artpagenums] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:attribution] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + + dbk:citation (dbk:citation) = dbk:citation * + + dbk:citetitle (dbk:citetitle) = dbk:citetitle * + + dbk:person (dbk:person) = dbk:person * + + dbk:personname (dbk:personname) = dbk:personname * + +[dbk:audiodata] > argeodbk:base + + dbk:info (dbk:info) = dbk:info + - entityref (String) + - fileref (String) + - format (String) + +[dbk:audioobject] > argeodbk:base, argeodbk:linkingAttributes + + dbk:audiodata (dbk:audiodata) = dbk:audiodata + + dbk:info (dbk:info) = dbk:info + +[dbk:author] > argeodbk:base, argeodbk:linkingAttributes + + dbk:address (dbk:address) = dbk:address * + + dbk:affiliation (dbk:affiliation) = dbk:affiliation * + + dbk:contrib (dbk:contrib) = dbk:contrib * + + dbk:email (dbk:email) = dbk:email * + + dbk:orgdiv (dbk:orgdiv) = dbk:orgdiv * + + dbk:orgname (dbk:orgname) = dbk:orgname + + dbk:personblurb (dbk:personblurb) = dbk:personblurb * + + dbk:personname (dbk:personname) = dbk:personname + + dbk:uri (dbk:uri) = dbk:uri * + +[dbk:authorgroup] > argeodbk:base, argeodbk:linkingAttributes + + dbk:author (dbk:author) = dbk:author * + + dbk:editor (dbk:editor) = dbk:editor * + + dbk:othercredit (dbk:othercredit) = dbk:othercredit * + +[dbk:authorinitials] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:bibliocoverage] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + - otherspatial (String) + - othertemporal (String) + - spatial (String) + - temporal (String) + +[dbk:bibliodiv] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:biblioentry (dbk:biblioentry) = dbk:biblioentry * + + dbk:bibliomixed (dbk:bibliomixed) = dbk:bibliomixed * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + - label (String) + - status (String) + +[dbk:biblioentry] > argeodbk:base, argeodbk:linkingAttributes, argeodbk:publishingInlines + + dbk:abstract (dbk:abstract) = dbk:abstract * + + dbk:address (dbk:address) = dbk:address * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:artpagenums (dbk:artpagenums) = dbk:artpagenums * + + dbk:author (dbk:author) = dbk:author * + + dbk:authorgroup (dbk:authorgroup) = dbk:authorgroup * + + dbk:authorinitials (dbk:authorinitials) = dbk:authorinitials * + + dbk:bibliocoverage (dbk:bibliocoverage) = dbk:bibliocoverage * + + dbk:biblioid (dbk:biblioid) = dbk:biblioid * + + dbk:bibliomisc (dbk:bibliomisc) = dbk:bibliomisc * + + dbk:bibliomset (dbk:bibliomset) = dbk:bibliomset * + + dbk:bibliorelation (dbk:bibliorelation) = dbk:bibliorelation * + + dbk:biblioset (dbk:biblioset) = dbk:biblioset * + + dbk:bibliosource (dbk:bibliosource) = dbk:bibliosource * + + dbk:citebiblioid (dbk:citebiblioid) = dbk:citebiblioid * + + dbk:citerefentry (dbk:citerefentry) = dbk:citerefentry * + + dbk:citetitle (dbk:citetitle) = dbk:citetitle * + + dbk:collab (dbk:collab) = dbk:collab * + + dbk:confgroup (dbk:confgroup) = dbk:confgroup * + + dbk:contractnum (dbk:contractnum) = dbk:contractnum * + + dbk:contractsponsor (dbk:contractsponsor) = dbk:contractsponsor * + + dbk:copyright (dbk:copyright) = dbk:copyright * + + dbk:cover (dbk:cover) = dbk:cover * + + dbk:edition (dbk:edition) = dbk:edition * + + dbk:editor (dbk:editor) = dbk:editor * + + dbk:extendedlink (dbk:extendedlink) = dbk:extendedlink * + + dbk:issuenum (dbk:issuenum) = dbk:issuenum * + + dbk:itermset (dbk:itermset) = dbk:itermset * + + dbk:keywordset (dbk:keywordset) = dbk:keywordset * + + dbk:legalnotice (dbk:legalnotice) = dbk:legalnotice * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:org (dbk:org) = dbk:org * + + dbk:orgname (dbk:orgname) = dbk:orgname * + + dbk:othercredit (dbk:othercredit) = dbk:othercredit * + + dbk:pagenums (dbk:pagenums) = dbk:pagenums * + + dbk:person (dbk:person) = dbk:person * + + dbk:personblurb (dbk:personblurb) = dbk:personblurb * + + dbk:personname (dbk:personname) = dbk:personname * + + dbk:phrase (dbk:phrase) = dbk:phrase * + + dbk:printhistory (dbk:printhistory) = dbk:printhistory * + + dbk:productname (dbk:productname) = dbk:productname * + + dbk:productnumber (dbk:productnumber) = dbk:productnumber * + + dbk:pubdate (dbk:pubdate) = dbk:pubdate * + + dbk:publisher (dbk:publisher) = dbk:publisher * + + dbk:publishername (dbk:publishername) = dbk:publishername * + + dbk:releaseinfo (dbk:releaseinfo) = dbk:releaseinfo * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:seriesvolnums (dbk:seriesvolnums) = dbk:seriesvolnums * + + dbk:subjectset (dbk:subjectset) = dbk:subjectset * + + dbk:subscript (dbk:subscript) = dbk:subscript * + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + + dbk:superscript (dbk:superscript) = dbk:superscript * + + dbk:title (dbk:title) = dbk:title * + + dbk:titleabbrev (dbk:titleabbrev) = dbk:titleabbrev * + + dbk:volumenum (dbk:volumenum) = dbk:volumenum * + +[dbk:bibliography] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bibliodiv (dbk:bibliodiv) = dbk:bibliodiv * + + dbk:biblioentry (dbk:biblioentry) = dbk:biblioentry * + + dbk:bibliomixed (dbk:bibliomixed) = dbk:bibliomixed * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + - label (String) + - status (String) + +[dbk:biblioid] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + - class (String) + - otherclass (String) + +[dbk:bibliolist] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:biblioentry (dbk:biblioentry) = dbk:biblioentry * + + dbk:bibliomixed (dbk:bibliomixed) = dbk:bibliomixed * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + +[dbk:bibliomisc] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:bibliomixed] > argeodbk:base, argeodbk:linkingAttributes, argeodbk:publishingInlines + + dbk:abstract (dbk:abstract) = dbk:abstract * + + dbk:address (dbk:address) = dbk:address * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:artpagenums (dbk:artpagenums) = dbk:artpagenums * + + dbk:author (dbk:author) = dbk:author * + + dbk:authorgroup (dbk:authorgroup) = dbk:authorgroup * + + dbk:authorinitials (dbk:authorinitials) = dbk:authorinitials * + + dbk:bibliocoverage (dbk:bibliocoverage) = dbk:bibliocoverage * + + dbk:biblioid (dbk:biblioid) = dbk:biblioid * + + dbk:bibliomisc (dbk:bibliomisc) = dbk:bibliomisc * + + dbk:bibliomset (dbk:bibliomset) = dbk:bibliomset * + + dbk:bibliorelation (dbk:bibliorelation) = dbk:bibliorelation * + + dbk:biblioset (dbk:biblioset) = dbk:biblioset * + + dbk:bibliosource (dbk:bibliosource) = dbk:bibliosource * + + dbk:citebiblioid (dbk:citebiblioid) = dbk:citebiblioid * + + dbk:citerefentry (dbk:citerefentry) = dbk:citerefentry * + + dbk:citetitle (dbk:citetitle) = dbk:citetitle * + + dbk:collab (dbk:collab) = dbk:collab * + + dbk:confgroup (dbk:confgroup) = dbk:confgroup * + + dbk:contractnum (dbk:contractnum) = dbk:contractnum * + + dbk:contractsponsor (dbk:contractsponsor) = dbk:contractsponsor * + + dbk:copyright (dbk:copyright) = dbk:copyright * + + dbk:cover (dbk:cover) = dbk:cover * + + dbk:edition (dbk:edition) = dbk:edition * + + dbk:editor (dbk:editor) = dbk:editor * + + dbk:extendedlink (dbk:extendedlink) = dbk:extendedlink * + + dbk:issuenum (dbk:issuenum) = dbk:issuenum * + + dbk:itermset (dbk:itermset) = dbk:itermset * + + dbk:keywordset (dbk:keywordset) = dbk:keywordset * + + dbk:legalnotice (dbk:legalnotice) = dbk:legalnotice * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:org (dbk:org) = dbk:org * + + dbk:orgname (dbk:orgname) = dbk:orgname * + + dbk:othercredit (dbk:othercredit) = dbk:othercredit * + + dbk:pagenums (dbk:pagenums) = dbk:pagenums * + + dbk:person (dbk:person) = dbk:person * + + dbk:personblurb (dbk:personblurb) = dbk:personblurb * + + dbk:personname (dbk:personname) = dbk:personname * + + dbk:phrase (dbk:phrase) = dbk:phrase * + + dbk:printhistory (dbk:printhistory) = dbk:printhistory * + + dbk:productname (dbk:productname) = dbk:productname * + + dbk:productnumber (dbk:productnumber) = dbk:productnumber * + + dbk:pubdate (dbk:pubdate) = dbk:pubdate * + + dbk:publisher (dbk:publisher) = dbk:publisher * + + dbk:publishername (dbk:publishername) = dbk:publishername * + + dbk:releaseinfo (dbk:releaseinfo) = dbk:releaseinfo * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:seriesvolnums (dbk:seriesvolnums) = dbk:seriesvolnums * + + dbk:subjectset (dbk:subjectset) = dbk:subjectset * + + dbk:subscript (dbk:subscript) = dbk:subscript * + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + + dbk:superscript (dbk:superscript) = dbk:superscript * + + dbk:title (dbk:title) = dbk:title * + + dbk:titleabbrev (dbk:titleabbrev) = dbk:titleabbrev * + + dbk:volumenum (dbk:volumenum) = dbk:volumenum * + + jcr:xmltext (jcrx:xmltext) = jcrx:xmltext * + +[dbk:bibliomset] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:publishingInlines, argeodbk:ubiquitousInlines + + dbk:abstract (dbk:abstract) = dbk:abstract * + + dbk:address (dbk:address) = dbk:address * + + dbk:artpagenums (dbk:artpagenums) = dbk:artpagenums * + + dbk:author (dbk:author) = dbk:author * + + dbk:authorgroup (dbk:authorgroup) = dbk:authorgroup * + + dbk:authorinitials (dbk:authorinitials) = dbk:authorinitials * + + dbk:bibliocoverage (dbk:bibliocoverage) = dbk:bibliocoverage * + + dbk:biblioid (dbk:biblioid) = dbk:biblioid * + + dbk:bibliomisc (dbk:bibliomisc) = dbk:bibliomisc * + + dbk:bibliomset (dbk:bibliomset) = dbk:bibliomset * + + dbk:bibliorelation (dbk:bibliorelation) = dbk:bibliorelation * + + dbk:biblioset (dbk:biblioset) = dbk:biblioset * + + dbk:bibliosource (dbk:bibliosource) = dbk:bibliosource * + + dbk:citebiblioid (dbk:citebiblioid) = dbk:citebiblioid * + + dbk:citerefentry (dbk:citerefentry) = dbk:citerefentry * + + dbk:citetitle (dbk:citetitle) = dbk:citetitle * + + dbk:collab (dbk:collab) = dbk:collab * + + dbk:confgroup (dbk:confgroup) = dbk:confgroup * + + dbk:contractnum (dbk:contractnum) = dbk:contractnum * + + dbk:contractsponsor (dbk:contractsponsor) = dbk:contractsponsor * + + dbk:copyright (dbk:copyright) = dbk:copyright * + + dbk:cover (dbk:cover) = dbk:cover * + + dbk:edition (dbk:edition) = dbk:edition * + + dbk:editor (dbk:editor) = dbk:editor * + + dbk:extendedlink (dbk:extendedlink) = dbk:extendedlink * + + dbk:issuenum (dbk:issuenum) = dbk:issuenum * + + dbk:itermset (dbk:itermset) = dbk:itermset * + + dbk:keywordset (dbk:keywordset) = dbk:keywordset * + + dbk:legalnotice (dbk:legalnotice) = dbk:legalnotice * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:org (dbk:org) = dbk:org * + + dbk:orgname (dbk:orgname) = dbk:orgname * + + dbk:othercredit (dbk:othercredit) = dbk:othercredit * + + dbk:pagenums (dbk:pagenums) = dbk:pagenums * + + dbk:person (dbk:person) = dbk:person * + + dbk:personblurb (dbk:personblurb) = dbk:personblurb * + + dbk:personname (dbk:personname) = dbk:personname * + + dbk:printhistory (dbk:printhistory) = dbk:printhistory * + + dbk:productname (dbk:productname) = dbk:productname * + + dbk:productnumber (dbk:productnumber) = dbk:productnumber * + + dbk:pubdate (dbk:pubdate) = dbk:pubdate * + + dbk:publisher (dbk:publisher) = dbk:publisher * + + dbk:publishername (dbk:publishername) = dbk:publishername * + + dbk:releaseinfo (dbk:releaseinfo) = dbk:releaseinfo * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:seriesvolnums (dbk:seriesvolnums) = dbk:seriesvolnums * + + dbk:subjectset (dbk:subjectset) = dbk:subjectset * + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + + dbk:title (dbk:title) = dbk:title * + + dbk:titleabbrev (dbk:titleabbrev) = dbk:titleabbrev * + + dbk:volumenum (dbk:volumenum) = dbk:volumenum * + - relation (String) + +[dbk:biblioref] > argeodbk:base, argeodbk:linkingAttributes + - begin (String) + - end (String) + - endterm (Reference) + - units (String) + - xrefstyle (String) + +[dbk:bibliorelation] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + - class (String) + - otherclass (String) + - othertype (String) + - type (String) + +[dbk:biblioset] > argeodbk:base, argeodbk:linkingAttributes, argeodbk:publishingInlines + + dbk:abstract (dbk:abstract) = dbk:abstract * + + dbk:address (dbk:address) = dbk:address * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:artpagenums (dbk:artpagenums) = dbk:artpagenums * + + dbk:author (dbk:author) = dbk:author * + + dbk:authorgroup (dbk:authorgroup) = dbk:authorgroup * + + dbk:authorinitials (dbk:authorinitials) = dbk:authorinitials * + + dbk:bibliocoverage (dbk:bibliocoverage) = dbk:bibliocoverage * + + dbk:biblioid (dbk:biblioid) = dbk:biblioid * + + dbk:bibliomisc (dbk:bibliomisc) = dbk:bibliomisc * + + dbk:bibliomset (dbk:bibliomset) = dbk:bibliomset * + + dbk:bibliorelation (dbk:bibliorelation) = dbk:bibliorelation * + + dbk:biblioset (dbk:biblioset) = dbk:biblioset * + + dbk:bibliosource (dbk:bibliosource) = dbk:bibliosource * + + dbk:citebiblioid (dbk:citebiblioid) = dbk:citebiblioid * + + dbk:citerefentry (dbk:citerefentry) = dbk:citerefentry * + + dbk:citetitle (dbk:citetitle) = dbk:citetitle * + + dbk:collab (dbk:collab) = dbk:collab * + + dbk:confgroup (dbk:confgroup) = dbk:confgroup * + + dbk:contractnum (dbk:contractnum) = dbk:contractnum * + + dbk:contractsponsor (dbk:contractsponsor) = dbk:contractsponsor * + + dbk:copyright (dbk:copyright) = dbk:copyright * + + dbk:cover (dbk:cover) = dbk:cover * + + dbk:edition (dbk:edition) = dbk:edition * + + dbk:editor (dbk:editor) = dbk:editor * + + dbk:extendedlink (dbk:extendedlink) = dbk:extendedlink * + + dbk:issuenum (dbk:issuenum) = dbk:issuenum * + + dbk:itermset (dbk:itermset) = dbk:itermset * + + dbk:keywordset (dbk:keywordset) = dbk:keywordset * + + dbk:legalnotice (dbk:legalnotice) = dbk:legalnotice * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:org (dbk:org) = dbk:org * + + dbk:orgname (dbk:orgname) = dbk:orgname * + + dbk:othercredit (dbk:othercredit) = dbk:othercredit * + + dbk:pagenums (dbk:pagenums) = dbk:pagenums * + + dbk:person (dbk:person) = dbk:person * + + dbk:personblurb (dbk:personblurb) = dbk:personblurb * + + dbk:personname (dbk:personname) = dbk:personname * + + dbk:phrase (dbk:phrase) = dbk:phrase * + + dbk:printhistory (dbk:printhistory) = dbk:printhistory * + + dbk:productname (dbk:productname) = dbk:productname * + + dbk:productnumber (dbk:productnumber) = dbk:productnumber * + + dbk:pubdate (dbk:pubdate) = dbk:pubdate * + + dbk:publisher (dbk:publisher) = dbk:publisher * + + dbk:publishername (dbk:publishername) = dbk:publishername * + + dbk:releaseinfo (dbk:releaseinfo) = dbk:releaseinfo * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:seriesvolnums (dbk:seriesvolnums) = dbk:seriesvolnums * + + dbk:subjectset (dbk:subjectset) = dbk:subjectset * + + dbk:subscript (dbk:subscript) = dbk:subscript * + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + + dbk:superscript (dbk:superscript) = dbk:superscript * + + dbk:title (dbk:title) = dbk:title * + + dbk:titleabbrev (dbk:titleabbrev) = dbk:titleabbrev * + + dbk:volumenum (dbk:volumenum) = dbk:volumenum * + - relation (String) + +[dbk:bibliosource] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + - class (String) + - otherclass (String) + +[dbk:blockquote] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:attribution (dbk:attribution) = dbk:attribution + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + +[dbk:book] > argeodbk:base, argeodbk:linkingAttributes, argeodbk:titled + + dbk:acknowledgements (dbk:acknowledgements) = dbk:acknowledgements * + + dbk:appendix (dbk:appendix) = dbk:appendix * + + dbk:article (dbk:article) = dbk:article * + + dbk:bibliography (dbk:bibliography) = dbk:bibliography * + + dbk:chapter (dbk:chapter) = dbk:chapter * + + dbk:colophon (dbk:colophon) = dbk:colophon * + + dbk:dedication (dbk:dedication) = dbk:dedication * + + dbk:glossary (dbk:glossary) = dbk:glossary * + + dbk:index (dbk:index) = dbk:index * + + dbk:part (dbk:part) = dbk:part * + + dbk:preface (dbk:preface) = dbk:preface * + + dbk:reference (dbk:reference) = dbk:reference * + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + + dbk:toc (dbk:toc) = dbk:toc * + - label (String) + - status (String) + +[dbk:bridgehead] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + - otherrenderas (String) + - renderas (String) + +[dbk:callout] > argeodbk:base, argeodbk:indexingInlines, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + - arearefs (String) + +[dbk:calloutlist] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:callout (dbk:callout) = dbk:callout * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + +[dbk:caption] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + jcr:xmltext (jcrx:xmltext) = jcrx:xmltext * + - class (String) + - lang (String) + - onclick (String) + - ondblclick (String) + - onkeydown (String) + - onkeypress (String) + - onkeyup (String) + - onmousedown (String) + - onmousemove (String) + - onmouseout (String) + - onmouseover (String) + - onmouseup (String) + - style (String) + - title (String) + +[dbk:caution] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + +[dbk:chapter] > argeodbk:abstractSection, argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:refentry (dbk:refentry) = dbk:refentry * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:sect1 (dbk:sect1) = dbk:sect1 * + + dbk:section (dbk:section) = dbk:section * + + dbk:simplesect (dbk:simplesect) = dbk:simplesect * + + dbk:simplesect (dbk:simplesect) = dbk:simplesect * + +[dbk:citation] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + +[dbk:citebiblioid] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + - class (String) + - otherclass (String) + +[dbk:citerefentry] > argeodbk:base, argeodbk:linkingAttributes + + dbk:manvolnum (dbk:manvolnum) = dbk:manvolnum + + dbk:refentrytitle (dbk:refentrytitle) = dbk:refentrytitle + +[dbk:citetitle] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + - pubwork (String) + +[dbk:city] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:classname] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:classsynopsis] > argeodbk:base, argeodbk:linkingAttributes + + dbk:classsynopsisinfo (dbk:classsynopsisinfo) = dbk:classsynopsisinfo * + + dbk:constructorsynopsis (dbk:constructorsynopsis) = dbk:constructorsynopsis * + + dbk:destructorsynopsis (dbk:destructorsynopsis) = dbk:destructorsynopsis * + + dbk:fieldsynopsis (dbk:fieldsynopsis) = dbk:fieldsynopsis * + + dbk:methodsynopsis (dbk:methodsynopsis) = dbk:methodsynopsis * + + dbk:ooclass (dbk:ooclass) = dbk:ooclass * + + dbk:ooexception (dbk:ooexception) = dbk:ooexception * + + dbk:oointerface (dbk:oointerface) = dbk:oointerface * + - class (String) + - language (String) + +[dbk:classsynopsisinfo] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + + dbk:co (dbk:co) = dbk:co * + + dbk:info (dbk:info) = dbk:info * + + dbk:lineannotation (dbk:lineannotation) = dbk:lineannotation * + + dbk:textobject (dbk:textobject) = dbk:textobject * + - continuation (String) + - language (String) + - linenumbering (String) + - startinglinenumber (String) + - xml:space (String) + +[dbk:cmdsynopsis] > argeodbk:base, argeodbk:linkingAttributes + + dbk:arg (dbk:arg) = dbk:arg * + + dbk:command (dbk:command) = dbk:command * + + dbk:group (dbk:group) = dbk:group * + + dbk:info (dbk:info) = dbk:info + + dbk:sbr (dbk:sbr) = dbk:sbr * + + dbk:synopfragment (dbk:synopfragment) = dbk:synopfragment * + - cmdlength (String) + - label (String) + - sepchar (String) + +[dbk:co] > argeodbk:base + - label (String) + - linkends (String) + +[dbk:code] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + + dbk:classname (dbk:classname) = dbk:classname * + + dbk:exceptionname (dbk:exceptionname) = dbk:exceptionname * + + dbk:function (dbk:function) = dbk:function * + + dbk:initializer (dbk:initializer) = dbk:initializer * + + dbk:interfacename (dbk:interfacename) = dbk:interfacename * + + dbk:methodname (dbk:methodname) = dbk:methodname * + + dbk:modifier (dbk:modifier) = dbk:modifier * + + dbk:ooclass (dbk:ooclass) = dbk:ooclass * + + dbk:ooexception (dbk:ooexception) = dbk:ooexception * + + dbk:oointerface (dbk:oointerface) = dbk:oointerface * + + dbk:parameter (dbk:parameter) = dbk:parameter * + + dbk:returnvalue (dbk:returnvalue) = dbk:returnvalue * + + dbk:type (dbk:type) = dbk:type * + + dbk:varname (dbk:varname) = dbk:varname * + - language (String) + +[dbk:col] > nt:base + - align (String) + - annotations (String) + - arch (String) + - audience (String) + - char (String) + - charoff (String) + - class (String) + - condition (String) + - conformance (String) + - dir (String) + - lang (String) + - onclick (String) + - ondblclick (String) + - onkeydown (String) + - onkeypress (String) + - onkeyup (String) + - onmousedown (String) + - onmousemove (String) + - onmouseout (String) + - onmouseover (String) + - onmouseup (String) + - os (String) + - remap (String) + - revision (String) + - revisionflag (String) + - security (String) + - span (String) + - style (String) + - title (String) + - userlevel (String) + - valign (String) + - vendor (String) + - version (String) + - width (String) + - wordsize (String) + - xreflabel (String) + - xml:base (String) + - xml:id (String) + - xml:lang (String) + +[dbk:colgroup] > nt:base + + dbk:col (dbk:col) = dbk:col * + - align (String) + - annotations (String) + - arch (String) + - audience (String) + - char (String) + - charoff (String) + - class (String) + - condition (String) + - conformance (String) + - dir (String) + - lang (String) + - onclick (String) + - ondblclick (String) + - onkeydown (String) + - onkeypress (String) + - onkeyup (String) + - onmousedown (String) + - onmousemove (String) + - onmouseout (String) + - onmouseover (String) + - onmouseup (String) + - os (String) + - remap (String) + - revision (String) + - revisionflag (String) + - security (String) + - span (String) + - style (String) + - title (String) + - userlevel (String) + - valign (String) + - vendor (String) + - version (String) + - width (String) + - wordsize (String) + - xreflabel (String) + - xml:base (String) + - xml:id (String) + - xml:lang (String) + +[dbk:collab] > argeodbk:base, argeodbk:linkingAttributes + + dbk:affiliation (dbk:affiliation) = dbk:affiliation * + + dbk:org (dbk:org) = dbk:org * + + dbk:orgname (dbk:orgname) = dbk:orgname * + + dbk:person (dbk:person) = dbk:person * + + dbk:personname (dbk:personname) = dbk:personname * + +[dbk:colophon] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + - label (String) + - status (String) + +[dbk:colspec] > argeodbk:base, argeodbk:linkingAttributes + - align (String) + - char (String) + - charoff (String) + - colname (String) + - colnum (String) + - colsep (String) + - colwidth (String) + - rowsep (String) + +[dbk:command] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:computeroutput] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:ubiquitousInlines + + dbk:co (dbk:co) = dbk:co * + + dbk:command (dbk:command) = dbk:command * + + dbk:computeroutput (dbk:computeroutput) = dbk:computeroutput * + + dbk:envar (dbk:envar) = dbk:envar * + + dbk:filename (dbk:filename) = dbk:filename * + + dbk:nonterminal (dbk:nonterminal) = dbk:nonterminal * + + dbk:option (dbk:option) = dbk:option * + + dbk:optional (dbk:optional) = dbk:optional * + + dbk:package (dbk:package) = dbk:package * + + dbk:parameter (dbk:parameter) = dbk:parameter * + + dbk:prompt (dbk:prompt) = dbk:prompt * + + dbk:property (dbk:property) = dbk:property * + + dbk:replaceable (dbk:replaceable) = dbk:replaceable * + + dbk:systemitem (dbk:systemitem) = dbk:systemitem * + + dbk:termdef (dbk:termdef) = dbk:termdef * + + dbk:userinput (dbk:userinput) = dbk:userinput * + + jcr:xmltext (jcrx:xmltext) = jcrx:xmltext * + +[dbk:confdates] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:confgroup] > argeodbk:base, argeodbk:linkingAttributes + + dbk:address (dbk:address) = dbk:address * + + dbk:confdates (dbk:confdates) = dbk:confdates * + + dbk:confnum (dbk:confnum) = dbk:confnum * + + dbk:confsponsor (dbk:confsponsor) = dbk:confsponsor * + + dbk:conftitle (dbk:conftitle) = dbk:conftitle * + +[dbk:confnum] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:confsponsor] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:conftitle] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:constant] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + - class (String) + +[dbk:constraint] > argeodbk:base, argeodbk:linkingAttributes + +[dbk:constraintdef] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + +[dbk:constructorsynopsis] > argeodbk:base, argeodbk:linkingAttributes + + dbk:exceptionname (dbk:exceptionname) = dbk:exceptionname * + + dbk:methodname (dbk:methodname) = dbk:methodname + + dbk:methodparam (dbk:methodparam) = dbk:methodparam * + + dbk:modifier (dbk:modifier) = dbk:modifier * + + dbk:void (dbk:void) = dbk:void + - language (String) + +[dbk:contractnum] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:contractsponsor] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:contrib] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:copyright] > argeodbk:base, argeodbk:linkingAttributes + + dbk:holder (dbk:holder) = dbk:holder * + + dbk:year (dbk:year) = dbk:year * + +[dbk:coref] > argeodbk:base, argeodbk:linkingAttributes + - label (String) + +[dbk:country] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:cover] > argeodbk:base, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:classsynopsis (dbk:classsynopsis) = dbk:classsynopsis * + + dbk:cmdsynopsis (dbk:cmdsynopsis) = dbk:cmdsynopsis * + + dbk:constraintdef (dbk:constraintdef) = dbk:constraintdef * + + dbk:constructorsynopsis (dbk:constructorsynopsis) = dbk:constructorsynopsis * + + dbk:destructorsynopsis (dbk:destructorsynopsis) = dbk:destructorsynopsis * + + dbk:fieldsynopsis (dbk:fieldsynopsis) = dbk:fieldsynopsis * + + dbk:funcsynopsis (dbk:funcsynopsis) = dbk:funcsynopsis * + + dbk:informalequation (dbk:informalequation) = dbk:informalequation * + + dbk:informalexample (dbk:informalexample) = dbk:informalexample * + + dbk:informalfigure (dbk:informalfigure) = dbk:informalfigure * + + dbk:informaltable (dbk:informaltable) = dbk:informaltable * + + dbk:literallayout (dbk:literallayout) = dbk:literallayout * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:methodsynopsis (dbk:methodsynopsis) = dbk:methodsynopsis * + + dbk:msgset (dbk:msgset) = dbk:msgset * + + dbk:productionset (dbk:productionset) = dbk:productionset * + + dbk:programlisting (dbk:programlisting) = dbk:programlisting * + + dbk:programlistingco (dbk:programlistingco) = dbk:programlistingco * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screen (dbk:screen) = dbk:screen * + + dbk:screenco (dbk:screenco) = dbk:screenco * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:synopsis (dbk:synopsis) = dbk:synopsis * + + dbk:task (dbk:task) = dbk:task * + +[dbk:database] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + - class (String) + +[dbk:date] > argeodbk:base, argeodbk:linkingAttributes + + jcr:xmltext (jcrx:xmltext) = jcrx:xmltext * + +[dbk:dedication] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + - label (String) + - status (String) + +[dbk:destructorsynopsis] > argeodbk:base, argeodbk:linkingAttributes + + dbk:exceptionname (dbk:exceptionname) = dbk:exceptionname * + + dbk:methodname (dbk:methodname) = dbk:methodname + + dbk:methodparam (dbk:methodparam) = dbk:methodparam * + + dbk:modifier (dbk:modifier) = dbk:modifier * + + dbk:void (dbk:void) = dbk:void + - language (String) + +[dbk:edition] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:editor] > argeodbk:base, argeodbk:linkingAttributes + + dbk:address (dbk:address) = dbk:address * + + dbk:affiliation (dbk:affiliation) = dbk:affiliation * + + dbk:contrib (dbk:contrib) = dbk:contrib * + + dbk:email (dbk:email) = dbk:email * + + dbk:orgdiv (dbk:orgdiv) = dbk:orgdiv * + + dbk:orgname (dbk:orgname) = dbk:orgname + + dbk:personblurb (dbk:personblurb) = dbk:personblurb * + + dbk:personname (dbk:personname) = dbk:personname + + dbk:uri (dbk:uri) = dbk:uri * + +[dbk:email] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:emphasis] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + +[dbk:entry] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:markupInlines, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:publishingInlines, argeodbk:techDocElements, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + - align (String) + - char (String) + - charoff (String) + - colname (String) + - colsep (String) + - morerows (String) + - nameend (String) + - namest (String) + - rotate (String) + - rowsep (String) + - spanname (String) + - valign (String) + +[dbk:entrytbl] > argeodbk:base, argeodbk:linkingAttributes + + dbk:colspec (dbk:colspec) = dbk:colspec * + + dbk:spanspec (dbk:spanspec) = dbk:spanspec * + + dbk:tbody (dbk:tbody) = dbk:tbody + + dbk:thead (dbk:thead) = dbk:thead + - align (String) + - char (String) + - charoff (String) + - colname (String) + - cols (String) + - colsep (String) + - nameend (String) + - namest (String) + - rowsep (String) + - spanname (String) + - tgroupstyle (String) + +[dbk:envar] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:epigraph] > argeodbk:base, argeodbk:linkingAttributes, argeodbk:paragraphElements + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:attribution (dbk:attribution) = dbk:attribution + + dbk:info (dbk:info) = dbk:info + + dbk:literallayout (dbk:literallayout) = dbk:literallayout * + +[dbk:equation] > argeodbk:base, argeodbk:linkingAttributes, argeodbk:titled + + dbk:alt (dbk:alt) = dbk:alt + + dbk:caption (dbk:caption) = dbk:caption + + dbk:mathphrase (dbk:mathphrase) = dbk:mathphrase * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + - floatstyle (String) + - label (String) + - pgwide (String) + +[dbk:errorcode] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:errorname] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:errortext] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:errortype] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:example] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:caption (dbk:caption) = dbk:caption + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + - floatstyle (String) + - label (String) + - pgwide (String) + - width (String) + +[dbk:exceptionname] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:extendedlink] > argeodbk:base + + dbk:arc (dbk:arc) = dbk:arc * + + dbk:locator (dbk:locator) = dbk:locator * + +[dbk:fax] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:fieldsynopsis] > argeodbk:base, argeodbk:linkingAttributes + + dbk:initializer (dbk:initializer) = dbk:initializer + + dbk:modifier (dbk:modifier) = dbk:modifier * + + dbk:type (dbk:type) = dbk:type + + dbk:varname (dbk:varname) = dbk:varname + - language (String) + +[dbk:figure] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:caption (dbk:caption) = dbk:caption + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + - floatstyle (String) + - label (String) + - pgwide (String) + +[dbk:filename] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + - class (String) + - path (String) + +[dbk:firstname] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:firstterm] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + - baseform (String) + +[dbk:footnote] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + - label (String) + +[dbk:footnoteref] > argeodbk:base, argeodbk:linkingAttributes + - label (String) + +[dbk:foreignphrase] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:publishingInlines + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:application (dbk:application) = dbk:application * + + dbk:biblioref (dbk:biblioref) = dbk:biblioref * + + dbk:database (dbk:database) = dbk:database * + + dbk:hardware (dbk:hardware) = dbk:hardware * + + dbk:inlinemediaobject (dbk:inlinemediaobject) = dbk:inlinemediaobject * + + dbk:link (dbk:link) = dbk:link * + + dbk:olink (dbk:olink) = dbk:olink * + + dbk:phrase (dbk:phrase) = dbk:phrase * + + dbk:productname (dbk:productname) = dbk:productname * + + dbk:productnumber (dbk:productnumber) = dbk:productnumber * + + dbk:subscript (dbk:subscript) = dbk:subscript * + + dbk:superscript (dbk:superscript) = dbk:superscript * + + dbk:trademark (dbk:trademark) = dbk:trademark * + + dbk:xref (dbk:xref) = dbk:xref * + + jcr:xmltext (jcrx:xmltext) = jcrx:xmltext * + +[dbk:formalpara] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:titled + + dbk:para (dbk:para) = dbk:para + +[dbk:funcdef] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + + dbk:function (dbk:function) = dbk:function * + + dbk:type (dbk:type) = dbk:type * + +[dbk:funcparams] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:funcprototype] > argeodbk:base, argeodbk:linkingAttributes + + dbk:funcdef (dbk:funcdef) = dbk:funcdef + + dbk:modifier (dbk:modifier) = dbk:modifier * + + dbk:paramdef (dbk:paramdef) = dbk:paramdef * + + dbk:varargs (dbk:varargs) = dbk:varargs + + dbk:varargs (dbk:varargs) = dbk:varargs + + dbk:void (dbk:void) = dbk:void + +[dbk:funcsynopsis] > argeodbk:base, argeodbk:linkingAttributes + + dbk:funcprototype (dbk:funcprototype) = dbk:funcprototype * + + dbk:funcsynopsisinfo (dbk:funcsynopsisinfo) = dbk:funcsynopsisinfo * + + dbk:info (dbk:info) = dbk:info + - language (String) + +[dbk:funcsynopsisinfo] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + + dbk:co (dbk:co) = dbk:co * + + dbk:info (dbk:info) = dbk:info * + + dbk:lineannotation (dbk:lineannotation) = dbk:lineannotation * + + dbk:textobject (dbk:textobject) = dbk:textobject * + - continuation (String) + - language (String) + - linenumbering (String) + - startinglinenumber (String) + - xml:space (String) + +[dbk:function] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:glossary] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bibliography (dbk:bibliography) = dbk:bibliography + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:glossdiv (dbk:glossdiv) = dbk:glossdiv * + + dbk:glossentry (dbk:glossentry) = dbk:glossentry * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + - label (String) + - status (String) + +[dbk:glossdef] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:glossseealso (dbk:glossseealso) = dbk:glossseealso * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + - subject (String) + +[dbk:glossdiv] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:glossentry (dbk:glossentry) = dbk:glossentry * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + - label (String) + - status (String) + +[dbk:glossentry] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes + + dbk:abbrev (dbk:abbrev) = dbk:abbrev + + dbk:acronym (dbk:acronym) = dbk:acronym + + dbk:glossdef (dbk:glossdef) = dbk:glossdef * + + dbk:glosssee (dbk:glosssee) = dbk:glosssee + + dbk:glossterm (dbk:glossterm) = dbk:glossterm + - sortas (String) + +[dbk:glosslist] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:glossentry (dbk:glossentry) = dbk:glossentry * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + +[dbk:glosssee] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + - otherterm (Reference) + +[dbk:glossseealso] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + - otherterm (Reference) + +[dbk:glossterm] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + - baseform (String) + +[dbk:group] > argeodbk:base, argeodbk:linkingAttributes + + dbk:arg (dbk:arg) = dbk:arg * + + dbk:group (dbk:group) = dbk:group * + + dbk:option (dbk:option) = dbk:option * + + dbk:replaceable (dbk:replaceable) = dbk:replaceable * + + dbk:sbr (dbk:sbr) = dbk:sbr * + + dbk:synopfragmentref (dbk:synopfragmentref) = dbk:synopfragmentref * + - choice (String) + - rep (String) + +[dbk:guibutton] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + + dbk:accel (dbk:accel) = dbk:accel * + +[dbk:guiicon] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + + dbk:accel (dbk:accel) = dbk:accel * + +[dbk:guilabel] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + + dbk:accel (dbk:accel) = dbk:accel * + +[dbk:guimenu] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + + dbk:accel (dbk:accel) = dbk:accel * + +[dbk:guimenuitem] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + + dbk:accel (dbk:accel) = dbk:accel * + +[dbk:guisubmenu] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + + dbk:accel (dbk:accel) = dbk:accel * + +[dbk:hardware] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:holder] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:honorific] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:imagedata] > argeodbk:base + + dbk:info (dbk:info) = dbk:info + - align (String) + - contentdepth (String) + - contentwidth (String) + - depth (String) + - entityref (String) + - fileref (String) + - format (String) + - scale (String) + - scalefit (String) + - valign (String) + - width (String) + +[dbk:imageobject] > argeodbk:base, argeodbk:linkingAttributes + + dbk:imagedata (dbk:imagedata) = dbk:imagedata + + dbk:info (dbk:info) = dbk:info + +[dbk:imageobjectco] > argeodbk:base, argeodbk:linkingAttributes + + dbk:areaspec (dbk:areaspec) = dbk:areaspec + + dbk:calloutlist (dbk:calloutlist) = dbk:calloutlist * + + dbk:imageobject (dbk:imageobject) = dbk:imageobject * + + dbk:info (dbk:info) = dbk:info + +[dbk:important] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + +[dbk:index] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:indexdiv (dbk:indexdiv) = dbk:indexdiv * + + dbk:indexentry (dbk:indexentry) = dbk:indexentry * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + - label (String) + - status (String) + - type (String) + +[dbk:indexdiv] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:indexentry (dbk:indexentry) = dbk:indexentry * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + - label (String) + - status (String) + +[dbk:indexentry] > argeodbk:base, argeodbk:linkingAttributes + + dbk:primaryie (dbk:primaryie) = dbk:primaryie + + dbk:secondaryie (dbk:secondaryie) = dbk:secondaryie * + + dbk:seealsoie (dbk:seealsoie) = dbk:seealsoie * + + dbk:seeie (dbk:seeie) = dbk:seeie * + + dbk:tertiaryie (dbk:tertiaryie) = dbk:tertiaryie * + +[dbk:indexterm] > argeodbk:base, argeodbk:linkingAttributes + + dbk:primary (dbk:primary) = dbk:primary + + dbk:secondary (dbk:secondary) = dbk:secondary + + dbk:see (dbk:see) = dbk:see + + dbk:seealso (dbk:seealso) = dbk:seealso * + + dbk:tertiary (dbk:tertiary) = dbk:tertiary + - class (String) + - pagenum (String) + - scope (String) + - significance (String) + - startref (Reference) + - type (String) + - zone (String) + +[dbk:info] > argeodbk:base + + dbk:abstract (dbk:abstract) = dbk:abstract * + + dbk:address (dbk:address) = dbk:address * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:artpagenums (dbk:artpagenums) = dbk:artpagenums * + + dbk:author (dbk:author) = dbk:author * + + dbk:authorgroup (dbk:authorgroup) = dbk:authorgroup * + + dbk:authorinitials (dbk:authorinitials) = dbk:authorinitials * + + dbk:bibliocoverage (dbk:bibliocoverage) = dbk:bibliocoverage * + + dbk:biblioid (dbk:biblioid) = dbk:biblioid * + + dbk:bibliomisc (dbk:bibliomisc) = dbk:bibliomisc * + + dbk:bibliomset (dbk:bibliomset) = dbk:bibliomset * + + dbk:bibliorelation (dbk:bibliorelation) = dbk:bibliorelation * + + dbk:biblioset (dbk:biblioset) = dbk:biblioset * + + dbk:bibliosource (dbk:bibliosource) = dbk:bibliosource * + + dbk:collab (dbk:collab) = dbk:collab * + + dbk:confgroup (dbk:confgroup) = dbk:confgroup * + + dbk:contractnum (dbk:contractnum) = dbk:contractnum * + + dbk:contractsponsor (dbk:contractsponsor) = dbk:contractsponsor * + + dbk:copyright (dbk:copyright) = dbk:copyright * + + dbk:cover (dbk:cover) = dbk:cover * + + dbk:date (dbk:date) = dbk:date * + + dbk:edition (dbk:edition) = dbk:edition * + + dbk:editor (dbk:editor) = dbk:editor * + + dbk:extendedlink (dbk:extendedlink) = dbk:extendedlink * + + dbk:issuenum (dbk:issuenum) = dbk:issuenum * + + dbk:itermset (dbk:itermset) = dbk:itermset * + + dbk:keywordset (dbk:keywordset) = dbk:keywordset * + + dbk:legalnotice (dbk:legalnotice) = dbk:legalnotice * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:org (dbk:org) = dbk:org * + + dbk:orgname (dbk:orgname) = dbk:orgname * + + dbk:othercredit (dbk:othercredit) = dbk:othercredit * + + dbk:pagenums (dbk:pagenums) = dbk:pagenums * + + dbk:printhistory (dbk:printhistory) = dbk:printhistory * + + dbk:productname (dbk:productname) = dbk:productname * + + dbk:productnumber (dbk:productnumber) = dbk:productnumber * + + dbk:pubdate (dbk:pubdate) = dbk:pubdate * + + dbk:publisher (dbk:publisher) = dbk:publisher * + + dbk:publishername (dbk:publishername) = dbk:publishername * + + dbk:releaseinfo (dbk:releaseinfo) = dbk:releaseinfo * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:seriesvolnums (dbk:seriesvolnums) = dbk:seriesvolnums * + + dbk:subjectset (dbk:subjectset) = dbk:subjectset * + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + + dbk:title (dbk:title) = dbk:title * + + dbk:titleabbrev (dbk:titleabbrev) = dbk:titleabbrev * + + dbk:volumenum (dbk:volumenum) = dbk:volumenum * + + * (nt:base) = nt:unstructured * + +[dbk:informalequation] > argeodbk:base, argeodbk:linkingAttributes + + dbk:alt (dbk:alt) = dbk:alt + + dbk:caption (dbk:caption) = dbk:caption + + dbk:info (dbk:info) = dbk:info + + dbk:mathphrase (dbk:mathphrase) = dbk:mathphrase * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + +[dbk:informalexample] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:caption (dbk:caption) = dbk:caption + + dbk:info (dbk:info) = dbk:info + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + - floatstyle (String) + - width (String) + +[dbk:informalfigure] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:caption (dbk:caption) = dbk:caption + + dbk:info (dbk:info) = dbk:info + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + - floatstyle (String) + - label (String) + - pgwide (String) + +[dbk:informaltable] > argeodbk:base, argeodbk:linkingAttributes + + dbk:col (dbk:col) = dbk:col * + + dbk:colgroup (dbk:colgroup) = dbk:colgroup * + + dbk:info (dbk:info) = dbk:info + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:tbody (dbk:tbody) = dbk:tbody * + + dbk:textobject (dbk:textobject) = dbk:textobject * + + dbk:tfoot (dbk:tfoot) = dbk:tfoot + + dbk:tgroup (dbk:tgroup) = dbk:tgroup * + + dbk:thead (dbk:thead) = dbk:thead + + dbk:tr (dbk:tr) = dbk:tr * + - border (String) + - cellpadding (String) + - cellspacing (String) + - class (String) + - colsep (String) + - floatstyle (String) + - frame (String) + - lang (String) + - onclick (String) + - ondblclick (String) + - onkeydown (String) + - onkeypress (String) + - onkeyup (String) + - onmousedown (String) + - onmousemove (String) + - onmouseout (String) + - onmouseover (String) + - onmouseup (String) + - orient (String) + - pgwide (String) + - rowheader (String) + - rowsep (String) + - rules (String) + - style (String) + - summary (String) + - tabstyle (String) + - title (String) + - width (String) + +[dbk:initializer] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:inlineequation] > argeodbk:base, argeodbk:linkingAttributes + + dbk:alt (dbk:alt) = dbk:alt + + dbk:inlinemediaobject (dbk:inlinemediaobject) = dbk:inlinemediaobject * + + dbk:mathphrase (dbk:mathphrase) = dbk:mathphrase * + +[dbk:inlinemediaobject] > argeodbk:base, argeodbk:linkingAttributes + + dbk:alt (dbk:alt) = dbk:alt + + dbk:audioobject (dbk:audioobject) = dbk:audioobject * + + dbk:imageobject (dbk:imageobject) = dbk:imageobject * + + dbk:imageobjectco (dbk:imageobjectco) = dbk:imageobjectco * + + dbk:info (dbk:info) = dbk:info + + dbk:textobject (dbk:textobject) = dbk:textobject * + + dbk:videoobject (dbk:videoobject) = dbk:videoobject * + +[dbk:interfacename] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:issuenum] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:itemizedlist] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:listitem (dbk:listitem) = dbk:listitem * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + - mark (String) + - spacing (String) + +[dbk:itermset] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes + +[dbk:jobtitle] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:keycap] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + - function (String) + - otherfunction (String) + +[dbk:keycode] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:keycombo] > argeodbk:base, argeodbk:linkingAttributes + + dbk:keycap (dbk:keycap) = dbk:keycap * + + dbk:keycombo (dbk:keycombo) = dbk:keycombo * + + dbk:keysym (dbk:keysym) = dbk:keysym * + + dbk:mousebutton (dbk:mousebutton) = dbk:mousebutton * + - action (String) + - otheraction (String) + +[dbk:keysym] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:keyword] > argeodbk:base, argeodbk:linkingAttributes + + jcr:xmltext (jcrx:xmltext) = jcrx:xmltext * + +[dbk:keywordset] > argeodbk:base, argeodbk:linkingAttributes + + dbk:keyword (dbk:keyword) = dbk:keyword * + +[dbk:label] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:legalnotice] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + +[dbk:lhs] > argeodbk:base, argeodbk:linkingAttributes + + jcr:xmltext (jcrx:xmltext) = jcrx:xmltext * + +[dbk:lineage] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:lineannotation] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:link] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + - endterm (Reference) + - xrefstyle (String) + +[dbk:listitem] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + - override (String) + +[dbk:literal] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:literallayout] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + + dbk:co (dbk:co) = dbk:co * + + dbk:info (dbk:info) = dbk:info * + + dbk:lineannotation (dbk:lineannotation) = dbk:lineannotation * + + dbk:textobject (dbk:textobject) = dbk:textobject * + - class (String) + - continuation (String) + - language (String) + - linenumbering (String) + - startinglinenumber (String) + - xml:space (String) + +[dbk:locator] > argeodbk:base + - xlink:label (String) + +[dbk:manvolnum] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:markup] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:mathphrase] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + + dbk:emphasis (dbk:emphasis) = dbk:emphasis * + +[dbk:mediaobject] > argeodbk:base, argeodbk:linkingAttributes + + dbk:alt (dbk:alt) = dbk:alt + + dbk:audioobject (dbk:audioobject) = dbk:audioobject * + + dbk:caption (dbk:caption) = dbk:caption + + dbk:imageobject (dbk:imageobject) = dbk:imageobject * + + dbk:imageobjectco (dbk:imageobjectco) = dbk:imageobjectco * + + dbk:info (dbk:info) = dbk:info + + dbk:textobject (dbk:textobject) = dbk:textobject * + + dbk:videoobject (dbk:videoobject) = dbk:videoobject * + +[dbk:member] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + +[dbk:menuchoice] > argeodbk:base, argeodbk:linkingAttributes + + dbk:guibutton (dbk:guibutton) = dbk:guibutton * + + dbk:guiicon (dbk:guiicon) = dbk:guiicon * + + dbk:guilabel (dbk:guilabel) = dbk:guilabel * + + dbk:guimenu (dbk:guimenu) = dbk:guimenu * + + dbk:guimenuitem (dbk:guimenuitem) = dbk:guimenuitem * + + dbk:guisubmenu (dbk:guisubmenu) = dbk:guisubmenu * + + dbk:shortcut (dbk:shortcut) = dbk:shortcut + +[dbk:methodname] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:methodparam] > argeodbk:base, argeodbk:linkingAttributes + + dbk:funcparams (dbk:funcparams) = dbk:funcparams + + dbk:initializer (dbk:initializer) = dbk:initializer + + dbk:modifier (dbk:modifier) = dbk:modifier * + + dbk:modifier (dbk:modifier) = dbk:modifier * + + dbk:parameter (dbk:parameter) = dbk:parameter + + dbk:type (dbk:type) = dbk:type * + - choice (String) + - rep (String) + +[dbk:methodsynopsis] > argeodbk:base, argeodbk:linkingAttributes + + dbk:exceptionname (dbk:exceptionname) = dbk:exceptionname * + + dbk:methodname (dbk:methodname) = dbk:methodname + + dbk:methodparam (dbk:methodparam) = dbk:methodparam * + + dbk:modifier (dbk:modifier) = dbk:modifier * + + dbk:type (dbk:type) = dbk:type + + dbk:void (dbk:void) = dbk:void + - language (String) + +[dbk:modifier] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + - xml:space (String) + +[dbk:mousebutton] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:msg] > argeodbk:base, argeodbk:linkingAttributes, argeodbk:titled + + dbk:msgmain (dbk:msgmain) = dbk:msgmain + + dbk:msgrel (dbk:msgrel) = dbk:msgrel * + + dbk:msgsub (dbk:msgsub) = dbk:msgsub * + +[dbk:msgaud] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:msgentry] > argeodbk:base, argeodbk:linkingAttributes + + dbk:msg (dbk:msg) = dbk:msg * + + dbk:msgexplan (dbk:msgexplan) = dbk:msgexplan * + + dbk:msginfo (dbk:msginfo) = dbk:msginfo + +[dbk:msgexplan] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + +[dbk:msginfo] > argeodbk:base, argeodbk:linkingAttributes + + dbk:msgaud (dbk:msgaud) = dbk:msgaud * + + dbk:msglevel (dbk:msglevel) = dbk:msglevel * + + dbk:msgorig (dbk:msgorig) = dbk:msgorig * + +[dbk:msglevel] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:msgmain] > argeodbk:base, argeodbk:linkingAttributes, argeodbk:titled + + dbk:msgtext (dbk:msgtext) = dbk:msgtext + +[dbk:msgorig] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:msgrel] > argeodbk:base, argeodbk:linkingAttributes, argeodbk:titled + + dbk:msgtext (dbk:msgtext) = dbk:msgtext + +[dbk:msgset] > argeodbk:base, argeodbk:linkingAttributes, argeodbk:titled + + dbk:msgentry (dbk:msgentry) = dbk:msgentry * + + dbk:simplemsgentry (dbk:simplemsgentry) = dbk:simplemsgentry * + +[dbk:msgsub] > argeodbk:base, argeodbk:linkingAttributes, argeodbk:titled + + dbk:msgtext (dbk:msgtext) = dbk:msgtext + +[dbk:msgtext] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + +[dbk:nonterminal] > argeodbk:base, argeodbk:linkingAttributes + + jcr:xmltext (jcrx:xmltext) = jcrx:xmltext * + - def (String) + +[dbk:note] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + +[dbk:olink] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + - localinfo (String) + - targetdoc (String) + - targetptr (String) + - type (String) + - xrefstyle (String) + +[dbk:ooclass] > argeodbk:base, argeodbk:linkingAttributes + + dbk:classname (dbk:classname) = dbk:classname + + dbk:modifier (dbk:modifier) = dbk:modifier * + + dbk:package (dbk:package) = dbk:package * + +[dbk:ooexception] > argeodbk:base, argeodbk:linkingAttributes + + dbk:exceptionname (dbk:exceptionname) = dbk:exceptionname + + dbk:modifier (dbk:modifier) = dbk:modifier * + + dbk:package (dbk:package) = dbk:package * + +[dbk:oointerface] > argeodbk:base, argeodbk:linkingAttributes + + dbk:interfacename (dbk:interfacename) = dbk:interfacename + + dbk:modifier (dbk:modifier) = dbk:modifier * + + dbk:package (dbk:package) = dbk:package * + +[dbk:option] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:optional] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:orderedlist] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:listitem (dbk:listitem) = dbk:listitem * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + - continuation (String) + - inheritnum (String) + - numeration (String) + - spacing (String) + - startingnumber (String) + +[dbk:org] > argeodbk:base, argeodbk:linkingAttributes + + dbk:address (dbk:address) = dbk:address * + + dbk:affiliation (dbk:affiliation) = dbk:affiliation * + + dbk:email (dbk:email) = dbk:email * + + dbk:orgdiv (dbk:orgdiv) = dbk:orgdiv * + + dbk:orgname (dbk:orgname) = dbk:orgname + + dbk:uri (dbk:uri) = dbk:uri * + +[dbk:orgdiv] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + +[dbk:orgname] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + - class (String) + - otherclass (String) + +[dbk:otheraddr] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:othercredit] > argeodbk:base, argeodbk:linkingAttributes + + dbk:address (dbk:address) = dbk:address * + + dbk:affiliation (dbk:affiliation) = dbk:affiliation * + + dbk:contrib (dbk:contrib) = dbk:contrib * + + dbk:email (dbk:email) = dbk:email * + + dbk:orgdiv (dbk:orgdiv) = dbk:orgdiv * + + dbk:orgname (dbk:orgname) = dbk:orgname + + dbk:personblurb (dbk:personblurb) = dbk:personblurb * + + dbk:personname (dbk:personname) = dbk:personname + + dbk:uri (dbk:uri) = dbk:uri * + - class (String) + - otherclass (String) + +[dbk:othername] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:package] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:pagenums] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:para] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:markupInlines, argeodbk:publishingElements, argeodbk:publishingInlines, argeodbk:techDocElements, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:info (dbk:info) = dbk:info * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + +[dbk:paramdef] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + + dbk:funcparams (dbk:funcparams) = dbk:funcparams * + + dbk:initializer (dbk:initializer) = dbk:initializer * + + dbk:parameter (dbk:parameter) = dbk:parameter * + + dbk:type (dbk:type) = dbk:type * + - choice (String) + +[dbk:parameter] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + - class (String) + +[dbk:part] > argeodbk:base, argeodbk:linkingAttributes, argeodbk:titled + + dbk:acknowledgements (dbk:acknowledgements) = dbk:acknowledgements * + + dbk:appendix (dbk:appendix) = dbk:appendix * + + dbk:article (dbk:article) = dbk:article * + + dbk:bibliography (dbk:bibliography) = dbk:bibliography * + + dbk:chapter (dbk:chapter) = dbk:chapter * + + dbk:colophon (dbk:colophon) = dbk:colophon * + + dbk:dedication (dbk:dedication) = dbk:dedication * + + dbk:glossary (dbk:glossary) = dbk:glossary * + + dbk:index (dbk:index) = dbk:index * + + dbk:partintro (dbk:partintro) = dbk:partintro + + dbk:preface (dbk:preface) = dbk:preface * + + dbk:refentry (dbk:refentry) = dbk:refentry * + + dbk:reference (dbk:reference) = dbk:reference * + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + + dbk:toc (dbk:toc) = dbk:toc * + - label (String) + - status (String) + +[dbk:partintro] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:refentry (dbk:refentry) = dbk:refentry * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:sect1 (dbk:sect1) = dbk:sect1 * + + dbk:section (dbk:section) = dbk:section * + + dbk:simplesect (dbk:simplesect) = dbk:simplesect * + + dbk:simplesect (dbk:simplesect) = dbk:simplesect * + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + - label (String) + - status (String) + +[dbk:person] > argeodbk:base, argeodbk:linkingAttributes + + dbk:address (dbk:address) = dbk:address * + + dbk:affiliation (dbk:affiliation) = dbk:affiliation * + + dbk:email (dbk:email) = dbk:email * + + dbk:personblurb (dbk:personblurb) = dbk:personblurb * + + dbk:personname (dbk:personname) = dbk:personname + + dbk:uri (dbk:uri) = dbk:uri * + +[dbk:personblurb] > argeodbk:base, argeodbk:linkingAttributes, argeodbk:paragraphElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + +[dbk:personname] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + + dbk:firstname (dbk:firstname) = dbk:firstname * + + dbk:honorific (dbk:honorific) = dbk:honorific * + + dbk:lineage (dbk:lineage) = dbk:lineage * + + dbk:othername (dbk:othername) = dbk:othername * + + dbk:surname (dbk:surname) = dbk:surname * + +[dbk:phone] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:phrase] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + +[dbk:pob] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:postcode] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:preface] > argeodbk:abstractSection, argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:refentry (dbk:refentry) = dbk:refentry * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:sect1 (dbk:sect1) = dbk:sect1 * + + dbk:section (dbk:section) = dbk:section * + + dbk:simplesect (dbk:simplesect) = dbk:simplesect * + + dbk:simplesect (dbk:simplesect) = dbk:simplesect * + +[dbk:primary] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + - sortas (String) + +[dbk:primaryie] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + - linkends (String) + +[dbk:printhistory] > argeodbk:base, argeodbk:linkingAttributes, argeodbk:paragraphElements + + dbk:anchor (dbk:anchor) = dbk:anchor * + +[dbk:procedure] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:step (dbk:step) = dbk:step * + +[dbk:production] > argeodbk:base, argeodbk:linkingAttributes + + dbk:constraint (dbk:constraint) = dbk:constraint * + + dbk:lhs (dbk:lhs) = dbk:lhs + + dbk:rhs (dbk:rhs) = dbk:rhs + +[dbk:productionrecap] > argeodbk:base, argeodbk:linkingAttributes + +[dbk:productionset] > argeodbk:base, argeodbk:linkingAttributes, argeodbk:titled + + dbk:production (dbk:production) = dbk:production * + + dbk:productionrecap (dbk:productionrecap) = dbk:productionrecap * + +[dbk:productname] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + - class (String) + +[dbk:productnumber] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:programlisting] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + + dbk:co (dbk:co) = dbk:co * + + dbk:info (dbk:info) = dbk:info * + + dbk:lineannotation (dbk:lineannotation) = dbk:lineannotation * + + dbk:textobject (dbk:textobject) = dbk:textobject * + - continuation (String) + - language (String) + - linenumbering (String) + - startinglinenumber (String) + - width (String) + - xml:space (String) + +[dbk:programlistingco] > argeodbk:base, argeodbk:linkingAttributes + + dbk:areaspec (dbk:areaspec) = dbk:areaspec + + dbk:calloutlist (dbk:calloutlist) = dbk:calloutlist * + + dbk:info (dbk:info) = dbk:info + + dbk:programlisting (dbk:programlisting) = dbk:programlisting + +[dbk:prompt] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + + dbk:co (dbk:co) = dbk:co * + +[dbk:property] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:pubdate] > argeodbk:base, argeodbk:linkingAttributes + + jcr:xmltext (jcrx:xmltext) = jcrx:xmltext * + +[dbk:publisher] > argeodbk:base, argeodbk:linkingAttributes + + dbk:address (dbk:address) = dbk:address * + + dbk:publishername (dbk:publishername) = dbk:publishername + +[dbk:publishername] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:qandadiv] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:qandadiv (dbk:qandadiv) = dbk:qandadiv * + + dbk:qandaentry (dbk:qandaentry) = dbk:qandaentry * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + +[dbk:qandaentry] > argeodbk:base, argeodbk:linkingAttributes, argeodbk:titled + + dbk:answer (dbk:answer) = dbk:answer * + + dbk:question (dbk:question) = dbk:question + +[dbk:qandaset] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:qandadiv (dbk:qandadiv) = dbk:qandadiv * + + dbk:qandaentry (dbk:qandaentry) = dbk:qandaentry * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + - defaultlabel (String) + +[dbk:question] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:label (dbk:label) = dbk:label + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + +[dbk:quote] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + +[dbk:refclass] > argeodbk:base, argeodbk:linkingAttributes + + dbk:application (dbk:application) = dbk:application * + + jcr:xmltext (jcrx:xmltext) = jcrx:xmltext * + +[dbk:refdescriptor] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + +[dbk:refentry] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes + + dbk:info (dbk:info) = dbk:info + + dbk:refmeta (dbk:refmeta) = dbk:refmeta + + dbk:refnamediv (dbk:refnamediv) = dbk:refnamediv * + + dbk:refsect1 (dbk:refsect1) = dbk:refsect1 * + + dbk:refsection (dbk:refsection) = dbk:refsection * + + dbk:refsynopsisdiv (dbk:refsynopsisdiv) = dbk:refsynopsisdiv + - label (String) + - status (String) + +[dbk:refentrytitle] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + +[dbk:reference] > argeodbk:base, argeodbk:linkingAttributes, argeodbk:titled + + dbk:partintro (dbk:partintro) = dbk:partintro + + dbk:refentry (dbk:refentry) = dbk:refentry * + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + - label (String) + - status (String) + +[dbk:refmeta] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes + + dbk:manvolnum (dbk:manvolnum) = dbk:manvolnum + + dbk:refentrytitle (dbk:refentrytitle) = dbk:refentrytitle + + dbk:refmiscinfo (dbk:refmiscinfo) = dbk:refmiscinfo * + +[dbk:refmiscinfo] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + - class (String) + - otherclass (String) + +[dbk:refname] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + +[dbk:refnamediv] > argeodbk:base, argeodbk:linkingAttributes + + dbk:refclass (dbk:refclass) = dbk:refclass * + + dbk:refdescriptor (dbk:refdescriptor) = dbk:refdescriptor + + dbk:refname (dbk:refname) = dbk:refname * + + dbk:refpurpose (dbk:refpurpose) = dbk:refpurpose + +[dbk:refpurpose] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + +[dbk:refsect1] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:refsect2 (dbk:refsect2) = dbk:refsect2 * + + dbk:refsect2 (dbk:refsect2) = dbk:refsect2 * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + - label (String) + - status (String) + +[dbk:refsect2] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:refsect3 (dbk:refsect3) = dbk:refsect3 * + + dbk:refsect3 (dbk:refsect3) = dbk:refsect3 * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + - label (String) + - status (String) + +[dbk:refsect3] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + - label (String) + - status (String) + +[dbk:refsection] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:refsection (dbk:refsection) = dbk:refsection * + + dbk:refsection (dbk:refsection) = dbk:refsection * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + - label (String) + - status (String) + +[dbk:refsynopsisdiv] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:refsect2 (dbk:refsect2) = dbk:refsect2 * + + dbk:refsection (dbk:refsection) = dbk:refsection * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + +[dbk:releaseinfo] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:remark] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:replaceable] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + + dbk:co (dbk:co) = dbk:co * + - class (String) + +[dbk:returnvalue] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:revdescription] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + +[dbk:revhistory] > argeodbk:base, argeodbk:linkingAttributes, argeodbk:titled + + dbk:revision (dbk:revision) = dbk:revision * + +[dbk:revision] > argeodbk:base, argeodbk:linkingAttributes + + dbk:author (dbk:author) = dbk:author * + + dbk:authorinitials (dbk:authorinitials) = dbk:authorinitials * + + dbk:date (dbk:date) = dbk:date + + dbk:revdescription (dbk:revdescription) = dbk:revdescription + + dbk:revnumber (dbk:revnumber) = dbk:revnumber + + dbk:revremark (dbk:revremark) = dbk:revremark + +[dbk:revnumber] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:revremark] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:rhs] > argeodbk:base, argeodbk:linkingAttributes + + dbk:lineannotation (dbk:lineannotation) = dbk:lineannotation * + + dbk:nonterminal (dbk:nonterminal) = dbk:nonterminal * + + dbk:sbr (dbk:sbr) = dbk:sbr * + + jcr:xmltext (jcrx:xmltext) = jcrx:xmltext * + +[dbk:row] > argeodbk:base, argeodbk:linkingAttributes + + dbk:entry (dbk:entry) = dbk:entry * + + dbk:entrytbl (dbk:entrytbl) = dbk:entrytbl * + - rowsep (String) + - valign (String) + +[dbk:sbr] > argeodbk:base + +[dbk:screen] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + + dbk:co (dbk:co) = dbk:co * + + dbk:info (dbk:info) = dbk:info * + + dbk:lineannotation (dbk:lineannotation) = dbk:lineannotation * + + dbk:textobject (dbk:textobject) = dbk:textobject * + - continuation (String) + - language (String) + - linenumbering (String) + - startinglinenumber (String) + - width (String) + - xml:space (String) + +[dbk:screenco] > argeodbk:base, argeodbk:linkingAttributes + + dbk:areaspec (dbk:areaspec) = dbk:areaspec + + dbk:calloutlist (dbk:calloutlist) = dbk:calloutlist * + + dbk:info (dbk:info) = dbk:info + + dbk:screen (dbk:screen) = dbk:screen + +[dbk:screenshot] > argeodbk:base, argeodbk:linkingAttributes, argeodbk:titled + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + +[dbk:secondary] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + - sortas (String) + +[dbk:secondaryie] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + - linkends (String) + +[dbk:sect1] > argeodbk:abstractSection, argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:sect2 (dbk:sect2) = dbk:sect2 * + + dbk:simplesect (dbk:simplesect) = dbk:simplesect * + + dbk:simplesect (dbk:simplesect) = dbk:simplesect * + +[dbk:sect2] > argeodbk:abstractSection, argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:sect3 (dbk:sect3) = dbk:sect3 * + + dbk:simplesect (dbk:simplesect) = dbk:simplesect * + + dbk:simplesect (dbk:simplesect) = dbk:simplesect * + +[dbk:sect3] > argeodbk:abstractSection, argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:sect4 (dbk:sect4) = dbk:sect4 * + + dbk:simplesect (dbk:simplesect) = dbk:simplesect * + + dbk:simplesect (dbk:simplesect) = dbk:simplesect * + +[dbk:sect4] > argeodbk:abstractSection, argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:sect5 (dbk:sect5) = dbk:sect5 * + + dbk:simplesect (dbk:simplesect) = dbk:simplesect * + + dbk:simplesect (dbk:simplesect) = dbk:simplesect * + +[dbk:sect5] > argeodbk:abstractSection, argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:simplesect (dbk:simplesect) = dbk:simplesect * + + dbk:simplesect (dbk:simplesect) = dbk:simplesect * + +[dbk:section] > argeodbk:abstractSection, argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:refentry (dbk:refentry) = dbk:refentry * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:section (dbk:section) = dbk:section * + + dbk:simplesect (dbk:simplesect) = dbk:simplesect * + + dbk:simplesect (dbk:simplesect) = dbk:simplesect * + +[dbk:see] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + +[dbk:seealso] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + +[dbk:seealsoie] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + - linkends (String) + +[dbk:seeie] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + +[dbk:seg] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + +[dbk:seglistitem] > argeodbk:base, argeodbk:linkingAttributes + + dbk:seg (dbk:seg) = dbk:seg * + +[dbk:segmentedlist] > argeodbk:base, argeodbk:linkingAttributes, argeodbk:titled + + dbk:seglistitem (dbk:seglistitem) = dbk:seglistitem * + + dbk:segtitle (dbk:segtitle) = dbk:segtitle * + +[dbk:segtitle] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + +[dbk:seriesvolnums] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:set] > argeodbk:base, argeodbk:linkingAttributes, argeodbk:titled + + dbk:book (dbk:book) = dbk:book * + + dbk:set (dbk:set) = dbk:set * + + dbk:setindex (dbk:setindex) = dbk:setindex + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + + dbk:toc (dbk:toc) = dbk:toc + - label (String) + - status (String) + +[dbk:setindex] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:indexdiv (dbk:indexdiv) = dbk:indexdiv * + + dbk:indexentry (dbk:indexentry) = dbk:indexentry * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + - label (String) + - status (String) + - type (String) + +[dbk:shortaffil] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:shortcut] > argeodbk:base, argeodbk:linkingAttributes + + dbk:keycap (dbk:keycap) = dbk:keycap * + + dbk:keycombo (dbk:keycombo) = dbk:keycombo * + + dbk:keysym (dbk:keysym) = dbk:keysym * + + dbk:mousebutton (dbk:mousebutton) = dbk:mousebutton * + - action (String) + - otheraction (String) + +[dbk:sidebar] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + +[dbk:simpara] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + + dbk:info (dbk:info) = dbk:info * + +[dbk:simplelist] > argeodbk:base, argeodbk:linkingAttributes + + dbk:member (dbk:member) = dbk:member * + - columns (String) + - type (String) + +[dbk:simplemsgentry] > argeodbk:base, argeodbk:linkingAttributes + + dbk:msgexplan (dbk:msgexplan) = dbk:msgexplan * + + dbk:msgtext (dbk:msgtext) = dbk:msgtext + - msgaud (String) + - msglevel (String) + - msgorig (String) + +[dbk:simplesect] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + - label (String) + - status (String) + +[dbk:spanspec] > argeodbk:base, argeodbk:linkingAttributes + - align (String) + - char (String) + - charoff (String) + - colsep (String) + - nameend (String) + - namest (String) + - rowsep (String) + - spanname (String) + +[dbk:state] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:step] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:stepalternatives (dbk:stepalternatives) = dbk:stepalternatives + + dbk:substeps (dbk:substeps) = dbk:substeps + - performance (String) + +[dbk:stepalternatives] > argeodbk:base, argeodbk:linkingAttributes + + dbk:info (dbk:info) = dbk:info + + dbk:step (dbk:step) = dbk:step * + - performance (String) + +[dbk:street] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:subject] > argeodbk:base, argeodbk:linkingAttributes + + dbk:subjectterm (dbk:subjectterm) = dbk:subjectterm * + - weight (String) + +[dbk:subjectset] > argeodbk:base, argeodbk:linkingAttributes + + dbk:subject (dbk:subject) = dbk:subject * + - scheme (String) + +[dbk:subjectterm] > argeodbk:base, argeodbk:linkingAttributes + + jcr:xmltext (jcrx:xmltext) = jcrx:xmltext * + +[dbk:subscript] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:substeps] > argeodbk:base, argeodbk:linkingAttributes + + dbk:step (dbk:step) = dbk:step * + - performance (String) + +[dbk:subtitle] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + +[dbk:superscript] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:surname] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:symbol] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + - class (String) + +[dbk:synopfragment] > argeodbk:base, argeodbk:linkingAttributes + + dbk:arg (dbk:arg) = dbk:arg * + + dbk:group (dbk:group) = dbk:group * + +[dbk:synopfragmentref] > argeodbk:base, argeodbk:linkingAttributes + + jcr:xmltext (jcrx:xmltext) = jcrx:xmltext * + +[dbk:synopsis] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + + dbk:co (dbk:co) = dbk:co * + + dbk:info (dbk:info) = dbk:info * + + dbk:lineannotation (dbk:lineannotation) = dbk:lineannotation * + + dbk:textobject (dbk:textobject) = dbk:textobject * + - continuation (String) + - label (String) + - language (String) + - linenumbering (String) + - startinglinenumber (String) + - xml:space (String) + +[dbk:systemitem] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + + dbk:co (dbk:co) = dbk:co * + - class (String) + +[dbk:table] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:titled + + dbk:caption (dbk:caption) = dbk:caption + + dbk:col (dbk:col) = dbk:col * + + dbk:colgroup (dbk:colgroup) = dbk:colgroup * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:tbody (dbk:tbody) = dbk:tbody * + + dbk:textobject (dbk:textobject) = dbk:textobject * + + dbk:tfoot (dbk:tfoot) = dbk:tfoot + + dbk:tgroup (dbk:tgroup) = dbk:tgroup * + + dbk:thead (dbk:thead) = dbk:thead + + dbk:tr (dbk:tr) = dbk:tr * + - border (String) + - cellpadding (String) + - cellspacing (String) + - class (String) + - colsep (String) + - floatstyle (String) + - frame (String) + - label (String) + - lang (String) + - onclick (String) + - ondblclick (String) + - onkeydown (String) + - onkeypress (String) + - onkeyup (String) + - onmousedown (String) + - onmousemove (String) + - onmouseout (String) + - onmouseover (String) + - onmouseup (String) + - orient (String) + - pgwide (String) + - rowheader (String) + - rowsep (String) + - rules (String) + - shortentry (String) + - style (String) + - summary (String) + - tabstyle (String) + - title (String) + - tocentry (String) + - width (String) + +[dbk:tag] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + - class (String) + - namespace (String) + +[dbk:task] > argeodbk:base, argeodbk:linkingAttributes, argeodbk:titled + + dbk:example (dbk:example) = dbk:example * + + dbk:procedure (dbk:procedure) = dbk:procedure + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + + dbk:taskprerequisites (dbk:taskprerequisites) = dbk:taskprerequisites + + dbk:taskrelated (dbk:taskrelated) = dbk:taskrelated + + dbk:tasksummary (dbk:tasksummary) = dbk:tasksummary + +[dbk:taskprerequisites] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + +[dbk:taskrelated] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + +[dbk:tasksummary] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + +[dbk:tbody] > argeodbk:base, argeodbk:linkingAttributes + + dbk:row (dbk:row) = dbk:row * + + dbk:tr (dbk:tr) = dbk:tr * + - align (String) + - char (String) + - charoff (String) + - class (String) + - lang (String) + - onclick (String) + - ondblclick (String) + - onkeydown (String) + - onkeypress (String) + - onkeyup (String) + - onmousedown (String) + - onmousemove (String) + - onmouseout (String) + - onmouseover (String) + - onmouseup (String) + - style (String) + - title (String) + - valign (String) + +[dbk:td] > argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:listElements, argeodbk:markupInlines, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:publishingInlines, argeodbk:techDocElements, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + - abbr (String) + - align (String) + - annotations (String) + - arch (String) + - audience (String) + - axis (String) + - char (String) + - charoff (String) + - class (String) + - colspan (String) + - condition (String) + - conformance (String) + - dir (String) + - headers (String) + - lang (String) + - onclick (String) + - ondblclick (String) + - onkeydown (String) + - onkeypress (String) + - onkeyup (String) + - onmousedown (String) + - onmousemove (String) + - onmouseout (String) + - onmouseover (String) + - onmouseup (String) + - os (String) + - remap (String) + - revision (String) + - revisionflag (String) + - rowspan (String) + - scope (String) + - security (String) + - style (String) + - title (String) + - userlevel (String) + - valign (String) + - vendor (String) + - version (String) + - wordsize (String) + - xreflabel (String) + - xml:base (String) + - xml:id (String) + - xml:lang (String) + +[dbk:term] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + +[dbk:termdef] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + - baseform (String) + - sortas (String) + +[dbk:tertiary] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + - sortas (String) + +[dbk:tertiaryie] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + - linkends (String) + +[dbk:textdata] > argeodbk:base + + dbk:info (dbk:info) = dbk:info + - encoding (String) + - entityref (String) + - fileref (String) + - format (String) + +[dbk:textobject] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:info (dbk:info) = dbk:info + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:phrase (dbk:phrase) = dbk:phrase + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:textdata (dbk:textdata) = dbk:textdata + +[dbk:tfoot] > argeodbk:base, argeodbk:linkingAttributes + + dbk:colspec (dbk:colspec) = dbk:colspec * + + dbk:row (dbk:row) = dbk:row * + + dbk:tr (dbk:tr) = dbk:tr * + - align (String) + - char (String) + - charoff (String) + - class (String) + - lang (String) + - onclick (String) + - ondblclick (String) + - onkeydown (String) + - onkeypress (String) + - onkeyup (String) + - onmousedown (String) + - onmousemove (String) + - onmouseout (String) + - onmouseover (String) + - onmouseup (String) + - style (String) + - title (String) + - valign (String) + +[dbk:tgroup] > argeodbk:base, argeodbk:linkingAttributes + + dbk:colspec (dbk:colspec) = dbk:colspec * + + dbk:spanspec (dbk:spanspec) = dbk:spanspec * + + dbk:tbody (dbk:tbody) = dbk:tbody + + dbk:tfoot (dbk:tfoot) = dbk:tfoot + + dbk:thead (dbk:thead) = dbk:thead + - align (String) + - char (String) + - charoff (String) + - cols (String) + - colsep (String) + - rowsep (String) + - tgroupstyle (String) + +[dbk:th] > argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:listElements, argeodbk:markupInlines, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:publishingInlines, argeodbk:techDocElements, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + - abbr (String) + - align (String) + - annotations (String) + - arch (String) + - audience (String) + - axis (String) + - char (String) + - charoff (String) + - class (String) + - colspan (String) + - condition (String) + - conformance (String) + - dir (String) + - headers (String) + - lang (String) + - onclick (String) + - ondblclick (String) + - onkeydown (String) + - onkeypress (String) + - onkeyup (String) + - onmousedown (String) + - onmousemove (String) + - onmouseout (String) + - onmouseover (String) + - onmouseup (String) + - os (String) + - remap (String) + - revision (String) + - revisionflag (String) + - rowspan (String) + - scope (String) + - security (String) + - style (String) + - title (String) + - userlevel (String) + - valign (String) + - vendor (String) + - version (String) + - wordsize (String) + - xreflabel (String) + - xml:base (String) + - xml:id (String) + - xml:lang (String) + +[dbk:thead] > argeodbk:base, argeodbk:linkingAttributes + + dbk:colspec (dbk:colspec) = dbk:colspec * + + dbk:row (dbk:row) = dbk:row * + + dbk:tr (dbk:tr) = dbk:tr * + - align (String) + - char (String) + - charoff (String) + - class (String) + - lang (String) + - onclick (String) + - ondblclick (String) + - onkeydown (String) + - onkeypress (String) + - onkeyup (String) + - onmousedown (String) + - onmousemove (String) + - onmouseout (String) + - onmouseover (String) + - onmouseup (String) + - style (String) + - title (String) + - valign (String) + +[dbk:tip] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + +[dbk:title] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + +[dbk:titleabbrev] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + +[dbk:toc] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:tocdiv (dbk:tocdiv) = dbk:tocdiv * + + dbk:tocentry (dbk:tocentry) = dbk:tocentry * + +[dbk:tocdiv] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + + dbk:tocdiv (dbk:tocdiv) = dbk:tocdiv * + + dbk:tocentry (dbk:tocentry) = dbk:tocentry * + - pagenum (String) + +[dbk:tocentry] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + - pagenum (String) + +[dbk:token] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:tr] > nt:base + + dbk:td (dbk:td) = dbk:td * + + dbk:th (dbk:th) = dbk:th * + - align (String) + - annotations (String) + - arch (String) + - audience (String) + - char (String) + - charoff (String) + - class (String) + - condition (String) + - conformance (String) + - dir (String) + - lang (String) + - onclick (String) + - ondblclick (String) + - onkeydown (String) + - onkeypress (String) + - onkeyup (String) + - onmousedown (String) + - onmousemove (String) + - onmouseout (String) + - onmouseover (String) + - onmouseup (String) + - os (String) + - remap (String) + - revision (String) + - revisionflag (String) + - security (String) + - style (String) + - title (String) + - userlevel (String) + - valign (String) + - vendor (String) + - version (String) + - wordsize (String) + - xreflabel (String) + - xml:base (String) + - xml:id (String) + - xml:lang (String) + +[dbk:trademark] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + - class (String) + +[dbk:type] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:uri] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + - type (String) + +[dbk:userinput] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:ubiquitousInlines + + dbk:accel (dbk:accel) = dbk:accel * + + dbk:co (dbk:co) = dbk:co * + + dbk:command (dbk:command) = dbk:command * + + dbk:computeroutput (dbk:computeroutput) = dbk:computeroutput * + + dbk:envar (dbk:envar) = dbk:envar * + + dbk:filename (dbk:filename) = dbk:filename * + + dbk:guibutton (dbk:guibutton) = dbk:guibutton * + + dbk:guiicon (dbk:guiicon) = dbk:guiicon * + + dbk:guilabel (dbk:guilabel) = dbk:guilabel * + + dbk:guimenu (dbk:guimenu) = dbk:guimenu * + + dbk:guimenuitem (dbk:guimenuitem) = dbk:guimenuitem * + + dbk:guisubmenu (dbk:guisubmenu) = dbk:guisubmenu * + + dbk:keycap (dbk:keycap) = dbk:keycap * + + dbk:keycode (dbk:keycode) = dbk:keycode * + + dbk:keycombo (dbk:keycombo) = dbk:keycombo * + + dbk:keysym (dbk:keysym) = dbk:keysym * + + dbk:menuchoice (dbk:menuchoice) = dbk:menuchoice * + + dbk:mousebutton (dbk:mousebutton) = dbk:mousebutton * + + dbk:nonterminal (dbk:nonterminal) = dbk:nonterminal * + + dbk:option (dbk:option) = dbk:option * + + dbk:optional (dbk:optional) = dbk:optional * + + dbk:package (dbk:package) = dbk:package * + + dbk:parameter (dbk:parameter) = dbk:parameter * + + dbk:prompt (dbk:prompt) = dbk:prompt * + + dbk:property (dbk:property) = dbk:property * + + dbk:replaceable (dbk:replaceable) = dbk:replaceable * + + dbk:shortcut (dbk:shortcut) = dbk:shortcut * + + dbk:systemitem (dbk:systemitem) = dbk:systemitem * + + dbk:termdef (dbk:termdef) = dbk:termdef * + + dbk:userinput (dbk:userinput) = dbk:userinput * + + jcr:xmltext (jcrx:xmltext) = jcrx:xmltext * + +[dbk:varargs] > argeodbk:base, argeodbk:linkingAttributes + +[dbk:variablelist] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + + dbk:varlistentry (dbk:varlistentry) = dbk:varlistentry * + - spacing (String) + - termlength (String) + +[dbk:varlistentry] > argeodbk:base, argeodbk:linkingAttributes + + dbk:listitem (dbk:listitem) = dbk:listitem + + dbk:term (dbk:term) = dbk:term * + +[dbk:varname] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:videodata] > argeodbk:base + + dbk:info (dbk:info) = dbk:info + - align (String) + - contentdepth (String) + - contentwidth (String) + - depth (String) + - entityref (String) + - fileref (String) + - format (String) + - scale (String) + - scalefit (String) + - valign (String) + - width (String) + +[dbk:videoobject] > argeodbk:base, argeodbk:linkingAttributes + + dbk:info (dbk:info) = dbk:info + + dbk:videodata (dbk:videodata) = dbk:videodata + +[dbk:void] > argeodbk:base, argeodbk:linkingAttributes + +[dbk:volumenum] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:warning] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:bridgehead (dbk:bridgehead) = dbk:bridgehead * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:revhistory (dbk:revhistory) = dbk:revhistory * + + dbk:screenshot (dbk:screenshot) = dbk:screenshot * + +[dbk:wordasword] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:xref] > argeodbk:base, argeodbk:linkingAttributes + - endterm (Reference) + - xrefstyle (String) + +[dbk:year] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +//[xs:anyType] > nt:base +// + * (nt:base) +// + jcr:xmltext (jcrx:xmltext) = jcrx:xmltext * +// - * (undefined) + + diff --git a/org.argeo.publishing.ui/src/org/argeo/docbook/docbook.cnd b/org.argeo.publishing.ui/src/org/argeo/docbook/docbook.cnd new file mode 100644 index 0000000..5514e64 --- /dev/null +++ b/org.argeo.publishing.ui/src/org/argeo/docbook/docbook.cnd @@ -0,0 +1,527 @@ + + + + +[argeodbk:titled] +mixin + + dbk:info (dbk:info) = dbk:info * + + dbk:title (dbk:title) = dbk:title * + +[argeodbk:linkingAttributes] +mixin + - linkend (String) + - xlink:actuate (String) + - xlink:arcrole (String) + - xlink:href (String) + - xlink:role (String) + - xlink:show (String) + - xlink:title (String) + - xlink:type (String) + +[argeodbk:freeText] +mixin + + dbk:phrase (dbk:phrase) = dbk:phrase * + + dbk:replaceable (dbk:replaceable) = dbk:replaceable * + + jcr:xmltext (jcrx:xmltext) = jcrx:xmltext * + +[argeodbk:markupInlines] +mixin + +[argeodbk:listElements] +mixin + + dbk:itemizedlist (dbk:itemizedlist) = dbk:itemizedlist * + + dbk:orderedlist (dbk:orderedlist) = dbk:orderedlist * + + dbk:simplelist (dbk:simplelist) = dbk:simplelist * + +[argeodbk:paragraphElements] +mixin + + dbk:para (dbk:para) = dbk:para * + +[argeodbk:indexingInlines] +mixin + +[argeodbk:techDocElements] +mixin + + dbk:table (dbk:table) = dbk:table * + +[argeodbk:techDocInlines] +mixin + +[argeodbk:publishingElements] +mixin + +[argeodbk:ubiquitousInlines] +mixin + + dbk:alt (dbk:alt) = dbk:alt * + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:biblioref (dbk:biblioref) = dbk:biblioref * + + dbk:inlinemediaobject (dbk:inlinemediaobject) = dbk:inlinemediaobject * + + dbk:link (dbk:link) = dbk:link * + + dbk:olink (dbk:olink) = dbk:olink * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:subscript (dbk:subscript) = dbk:subscript * + + dbk:superscript (dbk:superscript) = dbk:superscript * + + dbk:xref (dbk:xref) = dbk:xref * + +[argeodbk:abstractSection] +mixin + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:remark (dbk:remark) = dbk:remark * + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + - label (String) + - status (String) + +[argeodbk:bibliographyInlines] +mixin + + dbk:author (dbk:author) = dbk:author * + + dbk:editor (dbk:editor) = dbk:editor * + + dbk:orgname (dbk:orgname) = dbk:orgname * + + dbk:personname (dbk:personname) = dbk:personname * + +[argeodbk:publishingInlines] +mixin + + dbk:emphasis (dbk:emphasis) = dbk:emphasis * + +[argeodbk:base] +abstract +orderable + - annotations (String) + - arch (String) + - audience (String) + - condition (String) + - conformance (String) + - dir (String) + - os (String) + - remap (String) + - revision (String) + - revisionflag (String) + - role (String) + - security (String) + - userlevel (String) + - vendor (String) + - version (String) + - wordsize (String) + - xreflabel (String) + +[dbk:alt] > argeodbk:base + + dbk:inlinemediaobject (dbk:inlinemediaobject) = dbk:inlinemediaobject * + + jcr:xmltext (jcrx:xmltext) = jcrx:xmltext * + +[dbk:anchor] > argeodbk:base + +[dbk:annotation] > argeodbk:base, argeodbk:indexingInlines, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + - annotates (String) + +[dbk:article] > argeodbk:abstractSection, argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:section (dbk:section) = dbk:section * + - class (String) + +[dbk:audiodata] > argeodbk:base + + dbk:info (dbk:info) = dbk:info + - entityref (String) + - fileref (String) + - format (String) + +[dbk:audioobject] > argeodbk:base, argeodbk:linkingAttributes + + dbk:audiodata (dbk:audiodata) = dbk:audiodata + + dbk:info (dbk:info) = dbk:info + +[dbk:author] > argeodbk:base, argeodbk:linkingAttributes + + dbk:orgdiv (dbk:orgdiv) = dbk:orgdiv * + + dbk:orgname (dbk:orgname) = dbk:orgname + + dbk:personblurb (dbk:personblurb) = dbk:personblurb * + + dbk:personname (dbk:personname) = dbk:personname + +[dbk:biblioref] > argeodbk:base, argeodbk:linkingAttributes + - begin (String) + - end (String) + - endterm (Reference) + - units (String) + - xrefstyle (String) + +[dbk:book] > argeodbk:base, argeodbk:linkingAttributes, argeodbk:titled + + dbk:article (dbk:article) = dbk:article * + + dbk:chapter (dbk:chapter) = dbk:chapter * + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + - label (String) + - status (String) + +[dbk:caption] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + + jcr:xmltext (jcrx:xmltext) = jcrx:xmltext * + - class (String) + - lang (String) + - onclick (String) + - ondblclick (String) + - onkeydown (String) + - onkeypress (String) + - onkeyup (String) + - onmousedown (String) + - onmousemove (String) + - onmouseout (String) + - onmouseover (String) + - onmouseup (String) + - style (String) + - title (String) + +[dbk:chapter] > argeodbk:abstractSection, argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:section (dbk:section) = dbk:section * + +[dbk:colspec] > argeodbk:base, argeodbk:linkingAttributes + - align (String) + - char (String) + - charoff (String) + - colname (String) + - colnum (String) + - colsep (String) + - colwidth (String) + - rowsep (String) + +[dbk:editor] > argeodbk:base, argeodbk:linkingAttributes + + dbk:orgdiv (dbk:orgdiv) = dbk:orgdiv * + + dbk:orgname (dbk:orgname) = dbk:orgname + + dbk:personblurb (dbk:personblurb) = dbk:personblurb * + + dbk:personname (dbk:personname) = dbk:personname + +[dbk:emphasis] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + +[dbk:entry] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:markupInlines, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:publishingInlines, argeodbk:techDocElements, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + - align (String) + - char (String) + - charoff (String) + - colname (String) + - colsep (String) + - morerows (String) + - nameend (String) + - namest (String) + - rotate (String) + - rowsep (String) + - spanname (String) + - valign (String) + +[dbk:entrytbl] > argeodbk:base, argeodbk:linkingAttributes + + dbk:colspec (dbk:colspec) = dbk:colspec * + + dbk:spanspec (dbk:spanspec) = dbk:spanspec * + + dbk:tbody (dbk:tbody) = dbk:tbody + + dbk:thead (dbk:thead) = dbk:thead + - align (String) + - char (String) + - charoff (String) + - colname (String) + - cols (String) + - colsep (String) + - nameend (String) + - namest (String) + - rowsep (String) + - spanname (String) + - tgroupstyle (String) + +[dbk:imagedata] > argeodbk:base + + dbk:info (dbk:info) = dbk:info + - align (String) + - contentdepth (String) + - contentwidth (String) + - depth (String) + - entityref (String) + - fileref (String) + - format (String) + - scale (String) + - scalefit (String) + - valign (String) + - width (String) + +[dbk:imageobject] > argeodbk:base, argeodbk:linkingAttributes + + dbk:imagedata (dbk:imagedata) = dbk:imagedata + + dbk:info (dbk:info) = dbk:info + +[dbk:info] > argeodbk:base + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:author (dbk:author) = dbk:author * + + dbk:editor (dbk:editor) = dbk:editor * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:orgname (dbk:orgname) = dbk:orgname * + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + + dbk:title (dbk:title) = dbk:title * + + * (nt:base) = nt:unstructured * + +[dbk:inlinemediaobject] > argeodbk:base, argeodbk:linkingAttributes + + dbk:alt (dbk:alt) = dbk:alt + + dbk:audioobject (dbk:audioobject) = dbk:audioobject * + + dbk:imageobject (dbk:imageobject) = dbk:imageobject * + + dbk:info (dbk:info) = dbk:info + + dbk:textobject (dbk:textobject) = dbk:textobject * + + dbk:videoobject (dbk:videoobject) = dbk:videoobject * + +[dbk:itemizedlist] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:listitem (dbk:listitem) = dbk:listitem * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + - mark (String) + - spacing (String) + +[dbk:link] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + - endterm (Reference) + - xrefstyle (String) + +[dbk:listitem] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + - override (String) + +[dbk:mediaobject] > argeodbk:base, argeodbk:linkingAttributes + + dbk:alt (dbk:alt) = dbk:alt + + dbk:audioobject (dbk:audioobject) = dbk:audioobject * + + dbk:caption (dbk:caption) = dbk:caption + + dbk:imageobject (dbk:imageobject) = dbk:imageobject * + + dbk:info (dbk:info) = dbk:info + + dbk:textobject (dbk:textobject) = dbk:textobject * + + dbk:videoobject (dbk:videoobject) = dbk:videoobject * + +[dbk:olink] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + - localinfo (String) + - targetdoc (String) + - targetptr (String) + - type (String) + - xrefstyle (String) + +[dbk:orderedlist] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:listitem (dbk:listitem) = dbk:listitem * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:remark (dbk:remark) = dbk:remark * + - continuation (String) + - inheritnum (String) + - numeration (String) + - spacing (String) + - startingnumber (String) + +[dbk:orgdiv] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + +[dbk:orgname] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + - class (String) + - otherclass (String) + +[dbk:para] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:markupInlines, argeodbk:publishingElements, argeodbk:publishingInlines, argeodbk:techDocElements, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + + dbk:info (dbk:info) = dbk:info * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + +[dbk:personblurb] > argeodbk:base, argeodbk:linkingAttributes, argeodbk:paragraphElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + +[dbk:personname] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:phrase] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + +[dbk:remark] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:replaceable] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + - class (String) + +[dbk:row] > argeodbk:base, argeodbk:linkingAttributes + + dbk:entry (dbk:entry) = dbk:entry * + + dbk:entrytbl (dbk:entrytbl) = dbk:entrytbl * + - rowsep (String) + - valign (String) + +[dbk:section] > argeodbk:abstractSection, argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements, argeodbk:titled + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:section (dbk:section) = dbk:section * + +[dbk:set] > argeodbk:base, argeodbk:linkingAttributes, argeodbk:titled + + dbk:book (dbk:book) = dbk:book * + + dbk:set (dbk:set) = dbk:set * + + dbk:subtitle (dbk:subtitle) = dbk:subtitle * + - label (String) + - status (String) + +[dbk:simplelist] > argeodbk:base, argeodbk:linkingAttributes + - columns (String) + - type (String) + +[dbk:spanspec] > argeodbk:base, argeodbk:linkingAttributes + - align (String) + - char (String) + - charoff (String) + - colsep (String) + - nameend (String) + - namest (String) + - rowsep (String) + - spanname (String) + +[dbk:subscript] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:subtitle] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + +[dbk:superscript] > argeodbk:base, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:ubiquitousInlines + +[dbk:table] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:titled + + dbk:caption (dbk:caption) = dbk:caption + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:tbody (dbk:tbody) = dbk:tbody * + + dbk:textobject (dbk:textobject) = dbk:textobject * + + dbk:tfoot (dbk:tfoot) = dbk:tfoot + + dbk:tgroup (dbk:tgroup) = dbk:tgroup * + + dbk:thead (dbk:thead) = dbk:thead + - border (String) + - cellpadding (String) + - cellspacing (String) + - class (String) + - colsep (String) + - floatstyle (String) + - frame (String) + - label (String) + - lang (String) + - onclick (String) + - ondblclick (String) + - onkeydown (String) + - onkeypress (String) + - onkeyup (String) + - onmousedown (String) + - onmousemove (String) + - onmouseout (String) + - onmouseover (String) + - onmouseup (String) + - orient (String) + - pgwide (String) + - rowheader (String) + - rowsep (String) + - rules (String) + - shortentry (String) + - style (String) + - summary (String) + - tabstyle (String) + - title (String) + - tocentry (String) + - width (String) + +[dbk:tbody] > argeodbk:base, argeodbk:linkingAttributes + + dbk:row (dbk:row) = dbk:row * + - align (String) + - char (String) + - charoff (String) + - class (String) + - lang (String) + - onclick (String) + - ondblclick (String) + - onkeydown (String) + - onkeypress (String) + - onkeyup (String) + - onmousedown (String) + - onmousemove (String) + - onmouseout (String) + - onmouseover (String) + - onmouseup (String) + - style (String) + - title (String) + - valign (String) + +[dbk:textobject] > argeodbk:base, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:listElements, argeodbk:paragraphElements, argeodbk:publishingElements, argeodbk:techDocElements + + dbk:anchor (dbk:anchor) = dbk:anchor * + + dbk:annotation (dbk:annotation) = dbk:annotation * + + dbk:info (dbk:info) = dbk:info + + dbk:mediaobject (dbk:mediaobject) = dbk:mediaobject * + + dbk:phrase (dbk:phrase) = dbk:phrase + + dbk:remark (dbk:remark) = dbk:remark * + +[dbk:tfoot] > argeodbk:base, argeodbk:linkingAttributes + + dbk:colspec (dbk:colspec) = dbk:colspec * + + dbk:row (dbk:row) = dbk:row * + - align (String) + - char (String) + - charoff (String) + - class (String) + - lang (String) + - onclick (String) + - ondblclick (String) + - onkeydown (String) + - onkeypress (String) + - onkeyup (String) + - onmousedown (String) + - onmousemove (String) + - onmouseout (String) + - onmouseover (String) + - onmouseup (String) + - style (String) + - title (String) + - valign (String) + +[dbk:tgroup] > argeodbk:base, argeodbk:linkingAttributes + + dbk:colspec (dbk:colspec) = dbk:colspec * + + dbk:spanspec (dbk:spanspec) = dbk:spanspec * + + dbk:tbody (dbk:tbody) = dbk:tbody + + dbk:tfoot (dbk:tfoot) = dbk:tfoot + + dbk:thead (dbk:thead) = dbk:thead + - align (String) + - char (String) + - charoff (String) + - cols (String) + - colsep (String) + - rowsep (String) + - tgroupstyle (String) + +[dbk:thead] > argeodbk:base, argeodbk:linkingAttributes + + dbk:colspec (dbk:colspec) = dbk:colspec * + + dbk:row (dbk:row) = dbk:row * + - align (String) + - char (String) + - charoff (String) + - class (String) + - lang (String) + - onclick (String) + - ondblclick (String) + - onkeydown (String) + - onkeypress (String) + - onkeyup (String) + - onmousedown (String) + - onmousemove (String) + - onmouseout (String) + - onmouseover (String) + - onmouseup (String) + - style (String) + - title (String) + - valign (String) + +[dbk:title] > argeodbk:base, argeodbk:bibliographyInlines, argeodbk:freeText, argeodbk:indexingInlines, argeodbk:linkingAttributes, argeodbk:markupInlines, argeodbk:publishingInlines, argeodbk:techDocInlines, argeodbk:ubiquitousInlines + +[dbk:videodata] > argeodbk:base + + dbk:info (dbk:info) = dbk:info + - align (String) + - contentdepth (String) + - contentwidth (String) + - depth (String) + - entityref (String) + - fileref (String) + - format (String) + - scale (String) + - scalefit (String) + - valign (String) + - width (String) + +[dbk:videoobject] > argeodbk:base, argeodbk:linkingAttributes + + dbk:info (dbk:info) = dbk:info + + dbk:videodata (dbk:videodata) = dbk:videodata + +[dbk:xref] > argeodbk:base, argeodbk:linkingAttributes + - endterm (Reference) + - xrefstyle (String) + + diff --git a/org.argeo.publishing.ui/src/org/argeo/docbook/ui/AbstractDbkViewer.java b/org.argeo.publishing.ui/src/org/argeo/docbook/ui/AbstractDbkViewer.java new file mode 100644 index 0000000..e900093 --- /dev/null +++ b/org.argeo.publishing.ui/src/org/argeo/docbook/ui/AbstractDbkViewer.java @@ -0,0 +1,1035 @@ +package org.argeo.docbook.ui; + +import static org.argeo.cms.ui.util.CmsUiUtils.fillWidth; +import static org.argeo.docbook.DbkType.para; +import static org.argeo.docbook.DbkUtils.addDbk; +import static org.argeo.docbook.DbkUtils.isDbk; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Observer; + +import javax.jcr.Item; +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.cms.ui.CmsEditable; +import org.argeo.cms.ui.util.CmsUiUtils; +import org.argeo.cms.ui.viewers.AbstractPageViewer; +import org.argeo.cms.ui.viewers.EditablePart; +import org.argeo.cms.ui.viewers.NodePart; +import org.argeo.cms.ui.viewers.PropertyPart; +import org.argeo.cms.ui.viewers.Section; +import org.argeo.cms.ui.viewers.SectionPart; +import org.argeo.cms.ui.widgets.EditableText; +import org.argeo.cms.ui.widgets.StyledControl; +import org.argeo.docbook.DbkAttr; +import org.argeo.docbook.DbkType; +import org.argeo.docbook.DbkUtils; +import org.argeo.jcr.Jcr; +import org.argeo.jcr.JcrException; +import org.argeo.jcr.JcrUtils; +import org.eclipse.rap.fileupload.FileDetails; +import org.eclipse.rap.fileupload.FileUploadEvent; +import org.eclipse.rap.fileupload.FileUploadHandler; +import org.eclipse.rap.fileupload.FileUploadListener; +import org.eclipse.rap.rwt.RWT; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; + +/** Base class for text viewers and editors. */ +public abstract class AbstractDbkViewer extends AbstractPageViewer implements KeyListener, Observer { + private static final long serialVersionUID = -2401274679492339668L; + private final static Log log = LogFactory.getLog(AbstractDbkViewer.class); + + private final Section mainSection; + + private TextInterpreter textInterpreter = new DbkTextInterpreter(); + private DbkImageManager imageManager; + + private FileUploadListener fileUploadListener; + private DbkContextMenu styledTools; + + private final boolean flat; + + private boolean showMainTitle = true; + + private Integer maxMediaWidth = null; + private String defaultSectionStyle; + + protected AbstractDbkViewer(Section parent, int style, CmsEditable cmsEditable) { + super(parent, style, cmsEditable); +// CmsView cmsView = CmsView.getCmsView(parent); +// imageManager = cmsView.getImageManager(); + flat = SWT.FLAT == (style & SWT.FLAT); + + if (getCmsEditable().canEdit()) { + fileUploadListener = new FUL(); + styledTools = new DbkContextMenu(this, parent.getShell()); + } + this.mainSection = parent; + Node baseFolder = Jcr.getParent(mainSection.getNode()); + imageManager = new DbkImageManager(baseFolder); + initModelIfNeeded(mainSection.getNode()); + // layout(this.mainSection); + } + + @Override + public Control getControl() { + return mainSection; + } + + protected void refresh(Control control) throws RepositoryException { + if (!(control instanceof Section)) + return; + long begin = System.currentTimeMillis(); + Section section = (Section) control; + if (section instanceof TextSection) { + CmsUiUtils.clear(section); + Node node = section.getNode(); + TextSection textSection = (TextSection) section; + String style = node.hasProperty(DbkAttr.role.name()) ? node.getProperty(DbkAttr.role.name()).getString() + : getDefaultSectionStyle(); + if (style != null) + CmsUiUtils.style(textSection, style); + + // Title + Node titleNode = null; + // We give priority to ./title vs ./info/title, like the DocBook XSL + if (node.hasNode(DbkType.title.get())) { + titleNode = node.getNode(DbkType.title.get()); + } else if (node.hasNode(DbkType.info.get() + '/' + DbkType.title.get())) { + titleNode = node.getNode(DbkType.info.get() + '/' + DbkType.title.get()); + } + + if (titleNode != null) { + boolean showTitle = getMainSection() == section ? showMainTitle : true; + if (showTitle) { + if (section.getHeader() == null) + section.createHeader(); + DbkSectionTitle title = newSectionTitle(textSection, titleNode); + title.setLayoutData(CmsUiUtils.fillWidth()); + updateContent(title); + } + } + + // content + for (NodeIterator ni = node.getNodes(); ni.hasNext();) { + Node child = ni.nextNode(); + SectionPart sectionPart = null; + if (isDbk(child, DbkType.mediaobject)) { + if (child.hasNode(DbkType.imageobject.get())) { + sectionPart = newImg(textSection, child); + } else if (child.hasNode(DbkType.videoobject.get())) { + sectionPart = newVideo(textSection, child); + } else { + throw new IllegalArgumentException("Unsupported media object " + child); + } + } else if (isDbk(child, DbkType.info)) { + // TODO enrich UI based on info + } else if (isDbk(child, DbkType.title)) { + // already managed + } else if (isDbk(child, para)) { + sectionPart = newParagraph(textSection, child); + } else if (isDbk(child, DbkType.section)) { + sectionPart = newSectionPart(textSection, child); +// if (sectionPart == null) +// throw new IllegalArgumentException("Unsupported node " + child); + // TODO list node types in exception + } else { + throw new IllegalArgumentException("Unsupported node type for " + child); + } + if (sectionPart != null && sectionPart instanceof Control) + ((Control) sectionPart).setLayoutData(CmsUiUtils.fillWidth()); + } + +// if (!flat) + for (NodeIterator ni = section.getNode().getNodes(DbkType.section.get()); ni.hasNext();) { + Node child = ni.nextNode(); + if (isDbk(child, DbkType.section)) { + TextSection newSection = newTextSection(section, child); + newSection.setLayoutData(CmsUiUtils.fillWidth()); + refresh(newSection); + } + } + } else { + for (Section s : section.getSubSections().values()) + refresh(s); + } + // section.layout(true, true); + long duration = System.currentTimeMillis() - begin; +// System.out.println(duration + " ms - " + DbkUtils.getTitle(section.getNode())); + } + + /** To be overridden in order to provide additional SectionPart types */ + protected TextSection newTextSection(Section section, Node node) { + return new TextSection(section, SWT.NONE, node); + } + + /** To be overridden in order to provide additional SectionPart types */ + protected SectionPart newSectionPart(TextSection textSection, Node node) { + return null; + } + + // CRUD + protected Paragraph newParagraph(TextSection parent, Node node) throws RepositoryException { + Paragraph paragraph = new Paragraph(parent, parent.getStyle(), node); + updateContent(paragraph); + paragraph.setLayoutData(fillWidth()); + paragraph.setMouseListener(getMouseListener()); + paragraph.setFocusListener(getFocusListener()); + return paragraph; + } + + protected DbkImg newImg(TextSection parent, Node node) { + try { + DbkImg img = new DbkImg(parent, parent.getStyle(), node, imageManager); + GridData imgGd; + if (maxMediaWidth != null) { + imgGd = new GridData(SWT.CENTER, SWT.FILL, false, false); + imgGd.widthHint = maxMediaWidth; + img.setPreferredSize(new Point(maxMediaWidth, 0)); + } else { + imgGd = CmsUiUtils.grabWidth(SWT.CENTER, SWT.DEFAULT); + } + img.setLayoutData(imgGd); + updateContent(img); + img.setMouseListener(getMouseListener()); + img.setFocusListener(getFocusListener()); + return img; + } catch (RepositoryException e) { + throw new JcrException("Cannot add new image " + node, e); + } + } + + protected DbkVideo newVideo(TextSection parent, Node node) { + try { + DbkVideo video = new DbkVideo(parent, getCmsEditable().canEdit() ? SWT.NONE : SWT.READ_ONLY, node); + GridData gd; + if (maxMediaWidth != null) { + gd = new GridData(SWT.CENTER, SWT.FILL, false, false); + // TODO, manage size +// gd.widthHint = maxMediaWidth; +// gd.heightHint = (int) (gd.heightHint * 0.5625); + } else { + gd = new GridData(SWT.CENTER, SWT.FILL, false, false); +// gd.widthHint = video.getWidth(); +// gd.heightHint = video.getHeight(); + } + video.setLayoutData(gd); + updateContent(video); + return video; + } catch (RepositoryException e) { + throw new JcrException("Cannot add new image " + node, e); + } + } + + protected DbkSectionTitle newSectionTitle(TextSection parent, Node titleNode) throws RepositoryException { + int style = parent.getStyle(); + Composite titleParent = newSectionHeader(parent); + if (parent.isTitleReadOnly()) + style = style | SWT.READ_ONLY; + DbkSectionTitle title = new DbkSectionTitle(titleParent, style, titleNode); + updateContent(title); + title.setMouseListener(getMouseListener()); + title.setFocusListener(getFocusListener()); + return title; + } + + /** + * To be overridden in order to provide additional processing at the section + * level. + * + * @return the parent to use for the {@link DbkSectionTitle}, by default + * {@link Section#getHeader()} + */ + protected Composite newSectionHeader(TextSection section) { + return section.getHeader(); + } + + protected DbkSectionTitle prepareSectionTitle(Section newSection, String titleText) throws RepositoryException { + Node sectionNode = newSection.getNode(); + Node titleNode = DbkUtils.getOrAddDbk(sectionNode, DbkType.title); + getTextInterpreter().write(titleNode, titleText); + if (newSection.getHeader() == null) + newSection.createHeader(); + DbkSectionTitle sectionTitle = newSectionTitle((TextSection) newSection, sectionNode); + return sectionTitle; + } + + protected void updateContent(EditablePart part) throws RepositoryException { + if (part instanceof SectionPart) { + SectionPart sectionPart = (SectionPart) part; + Node partNode = sectionPart.getNode(); + + if (part instanceof StyledControl && (sectionPart.getSection() instanceof TextSection)) { + TextSection section = (TextSection) sectionPart.getSection(); + StyledControl styledControl = (StyledControl) part; + if (isDbk(partNode, para)) { + String style = partNode.hasProperty(DbkAttr.role.name()) + ? partNode.getProperty(DbkAttr.role.name()).getString() + : section.getDefaultTextStyle(); + styledControl.setStyle(style); + } + } + // use control AFTER setting style, since it may have been reset + + if (part instanceof EditableText) { + EditableText paragraph = (EditableText) part; + if (paragraph == getEdited()) + paragraph.setText(textInterpreter.raw(partNode)); + else + paragraph.setText(textInterpreter.readSimpleHtml(partNode)); + } else if (part instanceof DbkImg) { + DbkImg editableImage = (DbkImg) part; + // imageManager.load(partNode, part.getControl(), + // editableImage.getPreferredImageSize()); + } else if (part instanceof DbkVideo) { + DbkVideo video = (DbkVideo) part; + video.load(part.getControl()); + } + } else if (part instanceof DbkSectionTitle) { + DbkSectionTitle title = (DbkSectionTitle) part; + title.setStyle(title.getSection().getTitleStyle()); + // use control AFTER setting style + if (title == getEdited()) + title.setText(textInterpreter.read(title.getNode())); + else + title.setText(textInterpreter.readSimpleHtml(title.getNode())); + } + } + + // OVERRIDDEN FROM PARENT VIEWER + @Override + protected void save(EditablePart part) throws RepositoryException { + if (part instanceof EditableText) { + EditableText et = (EditableText) part; + if (!et.getEditable()) + return; + String text = ((Text) et.getControl()).getText(); + + // String[] lines = text.split("[\r\n]+"); + String[] lines = { text }; + assert lines.length != 0; + saveLine(part, lines[0]); + if (lines.length > 1) { + ArrayList toLayout = new ArrayList(); + if (part instanceof Paragraph) { + Paragraph currentParagraph = (Paragraph) et; + Section section = currentParagraph.getSection(); + Node sectionNode = section.getNode(); + Node currentParagraphN = currentParagraph.getNode(); + for (int i = 1; i < lines.length; i++) { + Node newNode = addDbk(sectionNode, para); + // newNode.addMixin(CmsTypes.CMS_STYLED); + saveLine(newNode, lines[i]); + // second node was create as last, if it is not the next + // one, it + // means there are some in between and we can take the + // one at + // index+1 for the re-order + if (newNode.getIndex() > currentParagraphN.getIndex() + 1) { + sectionNode.orderBefore(p(newNode.getIndex()), p(currentParagraphN.getIndex() + 1)); + } + Paragraph newParagraph = newParagraph((TextSection) section, newNode); + newParagraph.moveBelow(currentParagraph); + toLayout.add(newParagraph); + + currentParagraph = newParagraph; + currentParagraphN = newNode; + } + } + // TODO or rather return the created paragraphs? + layout(toLayout.toArray(new Control[toLayout.size()])); + } + persistChanges(et.getNode()); + } + } + + protected void saveLine(EditablePart part, String line) { + if (part instanceof NodePart) { + saveLine(((NodePart) part).getNode(), line); + } else if (part instanceof PropertyPart) { + saveLine(((PropertyPart) part).getProperty(), line); + } else { + throw new IllegalArgumentException("Unsupported part " + part); + } + } + + protected void saveLine(Item item, String line) { + line = line.trim(); + textInterpreter.write(item, line); + } + + @Override + protected void prepare(EditablePart part, Object caretPosition) { + Control control = part.getControl(); + if (control instanceof Text) { + Text text = (Text) control; + if (caretPosition != null) + if (caretPosition instanceof Integer) + text.setSelection((Integer) caretPosition); + else if (caretPosition instanceof Point) { +// layout(text); +// // TODO find a way to position the caret at the right place +// Point clickLocation = (Point) caretPosition; +// Point withinText = text.toControl(clickLocation); +// Rectangle bounds = text.getBounds(); +// int width = bounds.width; +// int height = bounds.height; +// int textLength = text.getText().length(); +// float area = width * height; +// float proportion = withinText.y * width + withinText.x; +// int pos = (int) (textLength * (proportion / area)); +// text.setSelection(pos); + } + text.setData(RWT.ACTIVE_KEYS, new String[] { "BACKSPACE", "ESC", "TAB", "SHIFT+TAB", "ALT+ARROW_LEFT", + "ALT+ARROW_RIGHT", "ALT+ARROW_UP", "ALT+ARROW_DOWN", "RETURN", "CTRL+RETURN", "ENTER", "DELETE" }); + text.setData(RWT.CANCEL_KEYS, new String[] { "RETURN", "ALT+ARROW_LEFT", "ALT+ARROW_RIGHT" }); + text.addKeyListener(this); + } else if (part instanceof DbkImg) { + ((DbkImg) part).setFileUploadListener(fileUploadListener); + } + } + + // REQUIRED BY CONTEXT MENU + void setParagraphStyle(Paragraph paragraph, String style) { + try { + Node paragraphNode = paragraph.getNode(); + if (style == null) {// default + if (paragraphNode.hasProperty(DbkAttr.role.name())) + paragraphNode.getProperty(DbkAttr.role.name()).remove(); + } else { + paragraphNode.setProperty(DbkAttr.role.name(), style); + } + persistChanges(paragraphNode); + updateContent(paragraph); + layoutPage(); + } catch (RepositoryException e1) { + throw new JcrException("Cannot set style " + style + " on " + paragraph, e1); + } + } + + SectionPart insertPart(Section section, Node node) { + try { + refresh(section); + layoutPage(); + for (Control control : section.getChildren()) { + if (control instanceof SectionPart) { + SectionPart sectionPart = (SectionPart) control; + Node partNode = sectionPart.getNode(); + if (partNode.getPath().equals(node.getPath())) + return sectionPart; + } + } + throw new IllegalStateException("New section part " + node + "not found"); + } catch (RepositoryException e) { + throw new JcrException("Cannot insert part " + node + " in section " + section.getNode(), e); + } + } + + void addParagraph(SectionPart partBefore, String txt) { + Section section = partBefore.getSection(); + SectionPart nextSectionPart = section.nextSectionPart(partBefore); + Node newNode = addDbk(section.getNode(), para); + textInterpreter.write(newNode, txt != null ? txt : ""); + if (nextSectionPart != null) { + try { + Node nextNode = nextSectionPart.getNode(); + section.getNode().orderBefore(Jcr.getIndexedName(newNode), Jcr.getIndexedName(nextNode)); + } catch (RepositoryException e) { + throw new JcrException("Cannot order " + newNode + " before " + nextSectionPart.getNode(), e); + } + } + Jcr.save(newNode); + Paragraph paragraph = (Paragraph) insertPart(partBefore.getSection(), newNode); + edit(paragraph, 0); + } + + void deletePart(SectionPart sectionPart) { + try { + Node node = sectionPart.getNode(); + Session session = node.getSession(); + if (sectionPart instanceof DbkImg) { + if (!isDbk(node, DbkType.mediaobject)) + throw new IllegalArgumentException("Node " + node + " is not a media object."); + } + node.remove(); + session.save(); + if (sectionPart instanceof Control) + ((Control) sectionPart).dispose(); + layoutPage(); + } catch (RepositoryException e1) { + throw new JcrException("Cannot delete " + sectionPart, e1); + } + } + + void deleteSection(Section section) { + try { + Node node = section.getNode(); + Session session = node.getSession(); + node.remove(); + session.save(); + section.dispose(); + layoutPage(); + } catch (RepositoryException e1) { + throw new JcrException("Cannot delete " + section, e1); + } + } + + String getRawParagraphText(Paragraph paragraph) { + return textInterpreter.raw(paragraph.getNode()); + } + + // COMMANDS + protected void splitEdit() { + checkEdited(); + try { + if (getEdited() instanceof Paragraph) { + Paragraph paragraph = (Paragraph) getEdited(); + Text text = (Text) paragraph.getControl(); + int caretPosition = text.getCaretPosition(); + String txt = text.getText(); + String first = txt.substring(0, caretPosition); + String second = txt.substring(caretPosition); + Node firstNode = paragraph.getNode(); + Node sectionNode = firstNode.getParent(); + + // FIXME set content the DocBook way + // firstNode.setProperty(CMS_CONTENT, first); + Node secondNode = addDbk(sectionNode, para); + // secondNode.addMixin(CmsTypes.CMS_STYLED); + + // second node was create as last, if it is not the next one, it + // means there are some in between and we can take the one at + // index+1 for the re-order + if (secondNode.getIndex() > firstNode.getIndex() + 1) { + sectionNode.orderBefore(p(secondNode.getIndex()), p(firstNode.getIndex() + 1)); + } + + // if we die in between, at least we still have the whole text + // in the first node + try { + textInterpreter.write(secondNode, second); + textInterpreter.write(firstNode, first); + } catch (Exception e) { + // so that no additional nodes are created: + JcrUtils.discardUnderlyingSessionQuietly(firstNode); + throw e; + } + + persistChanges(firstNode); + + Paragraph secondParagraph = paragraphSplitted(paragraph, secondNode); + edit(secondParagraph, 0); + } else if (getEdited() instanceof DbkSectionTitle) { + DbkSectionTitle sectionTitle = (DbkSectionTitle) getEdited(); + Text text = (Text) sectionTitle.getControl(); + String txt = text.getText(); + int caretPosition = text.getCaretPosition(); + Section section = sectionTitle.getSection(); + Node sectionNode = section.getNode(); + Node paragraphNode = addDbk(sectionNode, para); + // paragraphNode.addMixin(CmsTypes.CMS_STYLED); + + textInterpreter.write(paragraphNode, txt.substring(caretPosition)); + textInterpreter.write(sectionNode.getNode(DbkType.title.get()), txt.substring(0, caretPosition)); + sectionNode.orderBefore(p(paragraphNode.getIndex()), p(1)); + persistChanges(sectionNode); + + Paragraph paragraph = sectionTitleSplitted(sectionTitle, paragraphNode); + // section.layout(); + edit(paragraph, 0); + } + } catch (RepositoryException e) { + throw new JcrException("Cannot split " + getEdited(), e); + } + } + + protected void mergeWithPrevious() { + checkEdited(); + try { + Paragraph paragraph = (Paragraph) getEdited(); + Text text = (Text) paragraph.getControl(); + String txt = text.getText(); + Node paragraphNode = paragraph.getNode(); + if (paragraphNode.getIndex() == 1) + return;// do nothing + Node sectionNode = paragraphNode.getParent(); + Node previousNode = sectionNode.getNode(p(paragraphNode.getIndex() - 1)); + String previousTxt = textInterpreter.read(previousNode); + textInterpreter.write(previousNode, previousTxt + txt); + paragraphNode.remove(); + persistChanges(sectionNode); + + Paragraph previousParagraph = paragraphMergedWithPrevious(paragraph, previousNode); + edit(previousParagraph, previousTxt.length()); + } catch (RepositoryException e) { + throw new JcrException("Cannot stop editing", e); + } + } + + protected void mergeWithNext() { + checkEdited(); + try { + Paragraph paragraph = (Paragraph) getEdited(); + Text text = (Text) paragraph.getControl(); + String txt = text.getText(); + Node paragraphNode = paragraph.getNode(); + Node sectionNode = paragraphNode.getParent(); + NodeIterator paragraphNodes = sectionNode.getNodes(DbkType.para.get()); + long size = paragraphNodes.getSize(); + if (paragraphNode.getIndex() == size) + return;// do nothing + Node nextNode = sectionNode.getNode(p(paragraphNode.getIndex() + 1)); + String nextTxt = textInterpreter.read(nextNode); + textInterpreter.write(paragraphNode, txt + nextTxt); + + Section section = paragraph.getSection(); + Paragraph removed = (Paragraph) section.getSectionPart(nextNode.getIdentifier()); + + nextNode.remove(); + persistChanges(sectionNode); + + paragraphMergedWithNext(paragraph, removed); + edit(paragraph, txt.length()); + } catch (RepositoryException e) { + throw new JcrException("Cannot stop editing", e); + } + } + + protected synchronized void upload(EditablePart part) { + try { + if (part instanceof SectionPart) { + SectionPart sectionPart = (SectionPart) part; + Node partNode = sectionPart.getNode(); + int partIndex = partNode.getIndex(); + Section section = sectionPart.getSection(); + Node sectionNode = section.getNode(); + + if (part instanceof Paragraph) { + // FIXME adapt to DocBook +// Node newNode = sectionNode.addNode(DocBookNames.DBK_MEDIAOBJECT, NodeType.NT_FILE); +// newNode.addNode(Node.JCR_CONTENT, NodeType.NT_RESOURCE); +// JcrUtils.copyBytesAsFile(sectionNode, p(newNode.getIndex()), new byte[0]); +// if (partIndex < newNode.getIndex() - 1) { +// // was not last +// sectionNode.orderBefore(p(newNode.getIndex()), p(partIndex - 1)); +// } +// // sectionNode.orderBefore(p(partNode.getIndex()), +// // p(newNode.getIndex())); +// persistChanges(sectionNode); +// DbkImg img = newImg((TextSection) section, newNode); +// edit(img, null); +// layout(img.getControl()); + } else if (part instanceof DbkImg) { + if (getEdited() == part) + return; + edit(part, null); + layoutPage(); + } + } + } catch (RepositoryException e) { + throw new JcrException("Cannot upload", e); + } + } + + protected void deepen() { + if (flat) + return; + checkEdited(); + try { + if (getEdited() instanceof Paragraph) { + Paragraph paragraph = (Paragraph) getEdited(); + Text text = (Text) paragraph.getControl(); + String txt = text.getText(); + Node paragraphNode = paragraph.getNode(); + Section section = paragraph.getSection(); + Node sectionNode = section.getNode(); + // main title + if (section == mainSection && section instanceof TextSection && paragraphNode.getIndex() == 1 + && !sectionNode.hasNode(DbkType.title.get())) { + DbkSectionTitle sectionTitle = prepareSectionTitle(section, txt); + edit(sectionTitle, 0); + return; + } + Node newSectionNode = addDbk(sectionNode, DbkType.section); + // newSectionNode.addMixin(NodeType.MIX_TITLE); + sectionNode.orderBefore(h(newSectionNode.getIndex()), h(1)); + + int paragraphIndex = paragraphNode.getIndex(); + String sectionPath = sectionNode.getPath(); + String newSectionPath = newSectionNode.getPath(); + while (sectionNode.hasNode(p(paragraphIndex + 1))) { + Node parag = sectionNode.getNode(p(paragraphIndex + 1)); + sectionNode.getSession().move(sectionPath + '/' + p(paragraphIndex + 1), + newSectionPath + '/' + DbkType.para.get()); + SectionPart sp = section.getSectionPart(parag.getIdentifier()); + if (sp instanceof Control) + ((Control) sp).dispose(); + } + // create title + Node titleNode = DbkUtils.addDbk(newSectionNode, DbkType.title); + // newSectionNode.addNode(DocBookType.TITLE, DocBookType.TITLE); + getTextInterpreter().write(titleNode, txt); + + TextSection newSection = new TextSection(section, section.getStyle(), newSectionNode); + newSection.setLayoutData(CmsUiUtils.fillWidth()); + newSection.moveBelow(paragraph); + + // dispose + paragraphNode.remove(); + paragraph.dispose(); + + refresh(newSection); + newSection.getParent().layout(); + layout(newSection); + persistChanges(sectionNode); + } else if (getEdited() instanceof DbkSectionTitle) { + DbkSectionTitle sectionTitle = (DbkSectionTitle) getEdited(); + Section section = sectionTitle.getSection(); + Section parentSection = section.getParentSection(); + if (parentSection == null) + return;// cannot deepen main section + Node sectionN = section.getNode(); + Node parentSectionN = parentSection.getNode(); + if (sectionN.getIndex() == 1) + return;// cannot deepen first section + Node previousSectionN = parentSectionN.getNode(h(sectionN.getIndex() - 1)); + NodeIterator subSections = previousSectionN.getNodes(DbkType.section.get()); + int subsectionsCount = (int) subSections.getSize(); + previousSectionN.getSession().move(sectionN.getPath(), + previousSectionN.getPath() + "/" + h(subsectionsCount + 1)); + section.dispose(); + TextSection newSection = new TextSection(section, section.getStyle(), sectionN); + refresh(newSection); + persistChanges(previousSectionN); + } + } catch (RepositoryException e) { + throw new JcrException("Cannot deepen " + getEdited(), e); + } + } + + protected void undeepen() { + if (flat) + return; + checkEdited(); + try { + if (getEdited() instanceof Paragraph) { + upload(getEdited()); + } else if (getEdited() instanceof DbkSectionTitle) { + DbkSectionTitle sectionTitle = (DbkSectionTitle) getEdited(); + Section section = sectionTitle.getSection(); + Node sectionNode = section.getNode(); + Section parentSection = section.getParentSection(); + if (parentSection == null) + return;// cannot undeepen main section + + // choose in which section to merge + Section mergedSection; + if (sectionNode.getIndex() == 1) + mergedSection = section.getParentSection(); + else { + Map parentSubsections = parentSection.getSubSections(); + ArrayList
lst = new ArrayList
(parentSubsections.values()); + mergedSection = lst.get(sectionNode.getIndex() - 1); + } + Node mergedNode = mergedSection.getNode(); + boolean mergedHasSubSections = mergedNode.hasNode(DbkType.section.get()); + + // title as paragraph + Node newParagrapheNode = addDbk(mergedNode, para); + // newParagrapheNode.addMixin(CmsTypes.CMS_STYLED); + if (mergedHasSubSections) + mergedNode.orderBefore(p(newParagrapheNode.getIndex()), h(1)); + String txt = getTextInterpreter().read(sectionNode.getNode(DbkType.title.get())); + getTextInterpreter().write(newParagrapheNode, txt); + // move + NodeIterator paragraphs = sectionNode.getNodes(para.get()); + while (paragraphs.hasNext()) { + Node p = paragraphs.nextNode(); + SectionPart sp = section.getSectionPart(p.getIdentifier()); + if (sp instanceof Control) + ((Control) sp).dispose(); + mergedNode.getSession().move(p.getPath(), mergedNode.getPath() + '/' + para.get()); + if (mergedHasSubSections) + mergedNode.orderBefore(p(p.getIndex()), h(1)); + } + + Iterator
subsections = section.getSubSections().values().iterator(); + // NodeIterator sections = sectionNode.getNodes(CMS_H); + while (subsections.hasNext()) { + Section subsection = subsections.next(); + Node s = subsection.getNode(); + mergedNode.getSession().move(s.getPath(), mergedNode.getPath() + '/' + DbkType.section.get()); + subsection.dispose(); + } + + // remove section + section.getNode().remove(); + section.dispose(); + + refresh(mergedSection); + mergedSection.getParent().layout(); + layout(mergedSection); + persistChanges(mergedNode); + } + } catch (RepositoryException e) { + throw new JcrException("Cannot undeepen " + getEdited(), e); + } + } + + // UI CHANGES + protected Paragraph paragraphSplitted(Paragraph paragraph, Node newNode) throws RepositoryException { + Section section = paragraph.getSection(); + updateContent(paragraph); + Paragraph newParagraph = newParagraph((TextSection) section, newNode); + newParagraph.setLayoutData(CmsUiUtils.fillWidth()); + newParagraph.moveBelow(paragraph); + layout(paragraph.getControl(), newParagraph.getControl()); + return newParagraph; + } + + protected Paragraph sectionTitleSplitted(DbkSectionTitle sectionTitle, Node newNode) throws RepositoryException { + updateContent(sectionTitle); + Paragraph newParagraph = newParagraph(sectionTitle.getSection(), newNode); + // we assume beforeFirst is not null since there was a sectionTitle + newParagraph.moveBelow(sectionTitle.getSection().getHeader()); + layout(sectionTitle.getControl(), newParagraph.getControl()); + return newParagraph; + } + + protected Paragraph paragraphMergedWithPrevious(Paragraph removed, Node remaining) throws RepositoryException { + Section section = removed.getSection(); + removed.dispose(); + + Paragraph paragraph = (Paragraph) section.getSectionPart(remaining.getIdentifier()); + updateContent(paragraph); + layout(paragraph.getControl()); + return paragraph; + } + + protected void paragraphMergedWithNext(Paragraph remaining, Paragraph removed) throws RepositoryException { + removed.dispose(); + updateContent(remaining); + layout(remaining.getControl()); + } + + // UTILITIES + protected String p(Integer index) { + StringBuilder sb = new StringBuilder(6); + sb.append(para.get()).append('[').append(index).append(']'); + return sb.toString(); + } + + protected String h(Integer index) { + StringBuilder sb = new StringBuilder(5); + sb.append(DbkType.section.get()).append('[').append(index).append(']'); + return sb.toString(); + } + + // GETTERS / SETTERS + public Section getMainSection() { + return mainSection; + } + + public boolean isFlat() { + return flat; + } + + public TextInterpreter getTextInterpreter() { + return textInterpreter; + } + + // KEY LISTENER + @Override + public void keyPressed(KeyEvent ke) { + if (log.isTraceEnabled()) + log.trace(ke); + + if (getEdited() == null) + return; + boolean altPressed = (ke.stateMask & SWT.ALT) != 0; + boolean shiftPressed = (ke.stateMask & SWT.SHIFT) != 0; + boolean ctrlPressed = (ke.stateMask & SWT.CTRL) != 0; + + try { + // Common + if (ke.keyCode == SWT.ESC) { +// cancelEdit(); + saveEdit(); + } else if (ke.character == '\r') { + if (!shiftPressed) + splitEdit(); + } else if (ke.character == 'z') { + if (ctrlPressed) + cancelEdit(); + } else if (ke.character == 'S') { + if (ctrlPressed) + saveEdit(); + } else if (ke.character == '\t') { + if (!shiftPressed) { + deepen(); + } else if (shiftPressed) { + undeepen(); + } + } else { + if (getEdited() instanceof Paragraph) { + Paragraph paragraph = (Paragraph) getEdited(); + Section section = paragraph.getSection(); + if (altPressed && ke.keyCode == SWT.ARROW_RIGHT) { + edit(section.nextSectionPart(paragraph), 0); + } else if (altPressed && ke.keyCode == SWT.ARROW_LEFT) { + edit(section.previousSectionPart(paragraph), 0); + } else if (ke.character == SWT.BS) { + Text text = (Text) paragraph.getControl(); + int caretPosition = text.getCaretPosition(); + if (caretPosition == 0) { + mergeWithPrevious(); + } + } else if (ke.character == SWT.DEL) { + Text text = (Text) paragraph.getControl(); + int caretPosition = text.getCaretPosition(); + int charcount = text.getCharCount(); + if (caretPosition == charcount) { + mergeWithNext(); + } + } + } + } + } catch (Exception e) { + ke.doit = false; + notifyEditionException(e); + } + } + + @Override + public void keyReleased(KeyEvent e) { + } + + // MOUSE LISTENER + @Override + protected MouseListener createMouseListener() { + return new ML(); + } + + private class ML extends MouseAdapter { + private static final long serialVersionUID = 8526890859876770905L; + + @Override + public void mouseDoubleClick(MouseEvent e) { + if (e.button == 1) { + Control source = (Control) e.getSource(); + EditablePart composite = findDataParent(source); + Point point = new Point(e.x, e.y); + if (composite instanceof DbkImg) { + if (getCmsEditable().canEdit()) { + if (getCmsEditable().isEditing() && !(getEdited() instanceof DbkImg)) { + if (source == mainSection) + return; + EditablePart part = findDataParent(source); + upload(part); + } else { + getCmsEditable().startEditing(); + } + } + } else if (source instanceof Label) { + Label lbl = (Label) source; + Rectangle bounds = lbl.getBounds(); + float width = bounds.width; + float height = bounds.height; + float textLength = lbl.getText().length(); + float area = width * height; + float charArea = area / textLength; + float lines = textLength / width; + float proportion = point.y * width + point.x; + int pos = (int) (textLength * (proportion / area)); + // TODO refine it + edit(composite, (Integer) pos); + } else { + edit(composite, source.toDisplay(point)); + } + } + } + + @Override + public void mouseDown(MouseEvent e) { + if (getCmsEditable().isEditing()) { + if (e.button == 3) { + EditablePart composite = findDataParent((Control) e.getSource()); + if (styledTools != null) { + List styles = getAvailableStyles(composite); + styledTools.show(composite, new Point(e.x, e.y), styles); + } + } + } + } + + @Override + public void mouseUp(MouseEvent e) { + } + } + + protected List getAvailableStyles(EditablePart editablePart) { + return new ArrayList<>(); + } + + public void setMaxMediaWidth(Integer maxMediaWidth) { + this.maxMediaWidth = maxMediaWidth; + } + + public void setShowMainTitle(boolean showMainTitle) { + this.showMainTitle = showMainTitle; + } + + public String getDefaultSectionStyle() { + return defaultSectionStyle; + } + + public void setDefaultSectionStyle(String defaultSectionStyle) { + this.defaultSectionStyle = defaultSectionStyle; + } + + // FILE UPLOAD LISTENER + private class FUL implements FileUploadListener { + public void uploadProgress(FileUploadEvent event) { + // TODO Monitor upload progress + } + + public void uploadFailed(FileUploadEvent event) { + throw new RuntimeException("Upload failed " + event, event.getException()); + } + + public void uploadFinished(FileUploadEvent event) { + for (FileDetails file : event.getFileDetails()) { + if (log.isDebugEnabled()) + log.debug("Received: " + file.getFileName()); + } + mainSection.getDisplay().syncExec(new Runnable() { + @Override + public void run() { + saveEdit(); + } + }); + FileUploadHandler uploadHandler = (FileUploadHandler) event.getSource(); + uploadHandler.dispose(); + } + } +} \ No newline at end of file diff --git a/org.argeo.publishing.ui/src/org/argeo/docbook/ui/CustomDbkEditor.java b/org.argeo.publishing.ui/src/org/argeo/docbook/ui/CustomDbkEditor.java new file mode 100644 index 0000000..561b1e1 --- /dev/null +++ b/org.argeo.publishing.ui/src/org/argeo/docbook/ui/CustomDbkEditor.java @@ -0,0 +1,23 @@ +package org.argeo.docbook.ui; + +import javax.jcr.Node; + +import org.argeo.cms.ui.CmsEditable; +import org.argeo.cms.ui.viewers.Section; +import org.eclipse.swt.widgets.Composite; + +/** + * Manages hardcoded sections as an arbitrary hierarchy under the main section, + * which contains no text and no title. + */ +public class CustomDbkEditor extends AbstractDbkViewer { + private static final long serialVersionUID = 656302500183820802L; + + public CustomDbkEditor(Composite parent, int style, Node textNode, CmsEditable cmsEditable) { + this(new Section(parent, style, textNode), style, cmsEditable); + } + + public CustomDbkEditor(Section parent, int style, CmsEditable cmsEditable) { + super(parent, style, cmsEditable); + } +} diff --git a/org.argeo.publishing.ui/src/org/argeo/docbook/ui/DbkContextMenu.java b/org.argeo.publishing.ui/src/org/argeo/docbook/ui/DbkContextMenu.java new file mode 100644 index 0000000..6046bf2 --- /dev/null +++ b/org.argeo.publishing.ui/src/org/argeo/docbook/ui/DbkContextMenu.java @@ -0,0 +1,230 @@ +package org.argeo.docbook.ui; + +import java.util.ArrayList; +import java.util.List; + +import javax.jcr.Node; + +import org.argeo.cms.ui.CmsEditable; +import org.argeo.cms.ui.util.CmsUiUtils; +import org.argeo.cms.ui.viewers.EditablePart; +import org.argeo.cms.ui.viewers.NodePart; +import org.argeo.cms.ui.viewers.Section; +import org.argeo.cms.ui.viewers.SectionPart; +import org.argeo.cms.ui.widgets.EditableText; +import org.argeo.cms.ui.widgets.Img; +import org.argeo.docbook.DbkMsg; +import org.argeo.docbook.DbkUtils; +import org.argeo.eclipse.ui.MouseDown; +import org.argeo.jcr.Jcr; +import org.eclipse.rap.rwt.RWT; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.ShellEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; + +/** Dialog to edit a text part. */ +class DbkContextMenu { + private final AbstractDbkViewer textViewer; + + private Shell shell; + + DbkContextMenu(AbstractDbkViewer textViewer, Shell parentShell) { +// shell = new Shell(display, SWT.NO_TRIM | SWT.BORDER | SWT.ON_TOP); + shell = new Shell(parentShell, SWT.BORDER); +// super(display, SWT.NO_TRIM | SWT.BORDER | SWT.ON_TOP); + this.textViewer = textViewer; + shell.setLayout(new GridLayout()); + // shell.setData(RWT.CUSTOM_VARIANT, TEXT_STYLED_TOOLS_DIALOG); + + shell.addShellListener(new ToolsShellListener()); + } + + void show(EditablePart editablePart, Point location, List availableStyles) { + if (shell.isVisible()) + shell.setVisible(false); + CmsUiUtils.clear(shell); + Composite parent = shell; + CmsEditable cmsEditable = textViewer.getCmsEditable(); +// if (availableStyles.isEmpty()) +// return; + + if (editablePart instanceof Paragraph) { + Paragraph paragraph = (Paragraph) editablePart; + deletePartB(parent, DbkMsg.deleteParagraph.lead(), paragraph); + insertMediaB(parent, paragraph); + + } else if (editablePart instanceof Img) { + Img img = (Img) editablePart; + deletePartB(parent, DbkMsg.deleteMedia.lead(), img); + insertMediaB(parent, img); + insertParagraphB(parent, DbkMsg.insertParagraph.lead(), img); + + } else if (editablePart instanceof DbkSectionTitle) { + DbkSectionTitle sectionTitle = (DbkSectionTitle) editablePart; + TextSection section = sectionTitle.getSection(); + if (!section.isTitleReadOnly()) { + Label deleteB = new Label(shell, SWT.NONE); + deleteB.setText(DbkMsg.deleteSection.lead()); + deleteB.addMouseListener((MouseDown) (e) -> { + textViewer.deleteSection(section); + hide(); + }); + } + insertMediaB(parent, sectionTitle.getSection(), sectionTitle); + } + + StyledToolMouseListener stml = new StyledToolMouseListener(editablePart); + List styleButtons = new ArrayList(); + if (cmsEditable.isEditing()) { + for (String style : availableStyles) { + StyleButton styleButton = new StyleButton(shell, SWT.WRAP); + if (!"".equals(style)) + styleButton.setStyle(style); + else + styleButton.setStyle(null); + styleButton.setMouseListener(stml); + styleButtons.add(styleButton); + } + } else if (cmsEditable.canEdit()) { + // Edit +// Label editButton = new Label(shell, SWT.NONE); +// editButton.setText("Edit"); +// editButton.addMouseListener(stml); + } + + if (editablePart instanceof Paragraph) { + final int size = 32; + String text = textViewer.getRawParagraphText((Paragraph) editablePart); + String textToShow = text.length() > size ? text.substring(0, size - 3) + "..." : text; + for (StyleButton styleButton : styleButtons) { + styleButton.setText((styleButton.style == null ? "default" : styleButton.style) + " : " + textToShow); + } + } + + shell.pack(); + shell.layout(); + if (editablePart instanceof Control) { + int height = shell.getSize().y; + int parentShellHeight = shell.getShell().getSize().y; + if ((location.y + height) < parentShellHeight) { + shell.setLocation(((Control) editablePart).toDisplay(location.x, location.y)); + } else { + shell.setLocation(((Control) editablePart).toDisplay(location.x, location.y - parentShellHeight)); + } + } + + if (shell.getChildren().length != 0) + shell.open(); + } + + void hide() { + shell.setVisible(false); + } + + protected void insertMediaB(Composite parent, SectionPart sectionPart) { + insertMediaB(parent, sectionPart.getSection(), sectionPart); + } + + protected void insertMediaB(Composite parent, Section section, NodePart nodePart) { + Label insertPictureB = new Label(parent, SWT.NONE); + insertPictureB.setText(DbkMsg.insertPicture.lead()); + insertPictureB.addMouseListener((MouseDown) (e) -> { + Node newNode = DbkUtils.insertImageAfter(nodePart.getNode()); + Jcr.save(newNode); + textViewer.insertPart(section, newNode); + hide(); + }); + Label insertVideoB = new Label(parent, SWT.NONE); + insertVideoB.setText(DbkMsg.insertVideo.lead()); + insertVideoB.addMouseListener((MouseDown) (e) -> { + Node newNode = DbkUtils.insertVideoAfter(nodePart.getNode()); + Jcr.save(newNode); + textViewer.insertPart(section, newNode); + hide(); + }); + + } + + protected void insertParagraphB(Composite parent, String msg, SectionPart sectionPart) { + Label insertMediaB = new Label(parent, SWT.NONE); + insertMediaB.setText(msg); + insertMediaB.addMouseListener((MouseDown) (e) -> { + textViewer.addParagraph(sectionPart, null); + hide(); + }); + } + + protected void deletePartB(Composite parent, String msg, SectionPart sectionPart) { + Label deleteB = new Label(shell, SWT.NONE); + deleteB.setText(msg); + deleteB.addMouseListener((MouseDown) (e) -> { + textViewer.deletePart(sectionPart); + hide(); + }); + } + + class StyleButton extends EditableText { + private static final long serialVersionUID = 7731102609123946115L; + + String style; + + public StyleButton(Composite parent, int style) { + super(parent, style); + } + + @Override + public void setStyle(String style) { + this.style = style; + super.setStyle(style); + } + +// private Label label; +// +// public StyleButton(Composite parent, int swtStyle) { +// super(parent, SWT.NONE); +// setLayout(new GridLayout()); +// label = new Label(this, swtStyle); +// } +// +// public Label getLabel() { +// return label; +// } + + } + + class StyledToolMouseListener extends MouseAdapter { + private static final long serialVersionUID = 8516297091549329043L; + private EditablePart editablePart; + + public StyledToolMouseListener(EditablePart editablePart) { + super(); + this.editablePart = editablePart; + } + + @Override + public void mouseDown(MouseEvent e) { + // TODO make it more robust. + Label sb = (Label) e.getSource(); + Object style = sb.getData(RWT.CUSTOM_VARIANT); + textViewer.setParagraphStyle((Paragraph) editablePart, style == null ? null : style.toString()); + hide(); + } + } + + class ToolsShellListener extends org.eclipse.swt.events.ShellAdapter { + private static final long serialVersionUID = 8432350564023247241L; + + @Override + public void shellDeactivated(ShellEvent e) { + hide(); + } + + } +} diff --git a/org.argeo.publishing.ui/src/org/argeo/docbook/ui/DbkImageManager.java b/org.argeo.publishing.ui/src/org/argeo/docbook/ui/DbkImageManager.java new file mode 100644 index 0000000..25a466a --- /dev/null +++ b/org.argeo.publishing.ui/src/org/argeo/docbook/ui/DbkImageManager.java @@ -0,0 +1,154 @@ +package org.argeo.docbook.ui; + +import static javax.jcr.Node.JCR_CONTENT; +import static javax.jcr.Property.JCR_DATA; +import static javax.jcr.nodetype.NodeType.NT_FILE; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; + +import javax.jcr.Binary; +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.nodetype.NodeType; + +import org.argeo.cms.ui.CmsImageManager; +import org.argeo.cms.ui.util.CmsUiUtils; +import org.argeo.cms.ui.util.DefaultImageManager; +import org.argeo.docbook.DbkUtils; +import org.argeo.docbook.DbkAttr; +import org.argeo.docbook.DbkType; +import org.argeo.entity.EntityNames; +import org.argeo.entity.EntityType; +import org.argeo.jcr.JcrException; +import org.argeo.jcr.JcrUtils; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.Point; + +/** Add DocBook images support to {@link CmsImageManager}. */ +public class DbkImageManager extends DefaultImageManager { + private Node baseFolder = null; + + public DbkImageManager(Node baseFolder) { + this.baseFolder = baseFolder; + } + + Node getImageDataNode(Node mediaObjectNode) throws RepositoryException { + if (mediaObjectNode.hasNode(DbkType.imageobject.get())) { + Node imageDataNode = mediaObjectNode.getNode(DbkType.imageobject.get()).getNode(DbkType.imagedata.get()); + return imageDataNode; + } else { + throw new IllegalStateException("No image data found for " + mediaObjectNode); + } + } + + @Override + public Binary getImageBinary(Node node) throws RepositoryException { + Node fileNode = null; + if (DbkUtils.isDbk(node, DbkType.mediaobject)) { + Node imageDataNode = getImageDataNode(node); + fileNode = getFileNode(imageDataNode); + } + if (node.isNodeType(NT_FILE)) { + fileNode = node; + } + if (fileNode != null) { + return node.getNode(JCR_CONTENT).getProperty(JCR_DATA).getBinary(); + } else { + return null; + } + } + + public Point getImageSize(Node mediaObjectNode) throws RepositoryException { + Node imageDataNode = getImageDataNode(mediaObjectNode); + Node fileNode = getFileNode(imageDataNode); + if (fileNode == null) + return new Point(0, 0); + Point intrinsicSize; + if (fileNode.hasProperty(EntityNames.SVG_WIDTH) && fileNode.hasProperty(EntityNames.SVG_HEIGHT)) { + int width = (int) fileNode.getProperty(EntityNames.SVG_WIDTH).getLong(); + int height = (int) fileNode.getProperty(EntityNames.SVG_HEIGHT).getLong(); + intrinsicSize = new Point(width, height); + } else { + try (InputStream in = JcrUtils.getFileAsStream(fileNode)) { + ImageData id = new ImageData(in); + intrinsicSize = updateSize(fileNode, id); + } catch (IOException e) { + throw new RuntimeException("Cannot load file " + fileNode, e); + } + } + // TODO interpret image data infos + return intrinsicSize; + } + + protected Point updateSize(Node fileNode, ImageData id) throws RepositoryException { + fileNode.addMixin(EntityType.box.get()); + fileNode.setProperty(EntityNames.SVG_WIDTH, id.width); + fileNode.setProperty(EntityNames.SVG_HEIGHT, id.height); + return new Point(id.width, id.height); + } + + @Override + protected void processNewImageFile(Node mediaObjectNode, Node fileNode, ImageData id) + throws RepositoryException, IOException { + Node imageDataNode = getImageDataNode(mediaObjectNode); + updateSize(fileNode, id); + String filePath = fileNode.getPath(); + String relPath = filePath.substring(baseFolder.getPath().length() + 1); + imageDataNode.setProperty(DbkAttr.fileref.name(), relPath); + } + + @Override + public String getImageUrl(Node mediaObjectNode) throws RepositoryException { + Node imageDataNode = getImageDataNode(mediaObjectNode); + // TODO factorise + String fileref = null; + if (imageDataNode.hasProperty(DbkAttr.fileref.name())) + fileref = imageDataNode.getProperty(DbkAttr.fileref.name()).getString(); + if (fileref == null) + return null; + URI fileUri; + try { + // FIXME it messes up with the '/' + fileUri = new URI(URLEncoder.encode(fileref, StandardCharsets.UTF_8.toString())); + } catch (URISyntaxException | UnsupportedEncodingException e) { + throw new IllegalArgumentException("File ref in " + imageDataNode + " is badly formatted", e); + } + if (fileUri.getScheme() != null) + return fileUri.toString(); + // local + Node fileNode = getFileNode(imageDataNode); + String url = CmsUiUtils.getDataPathForUrl(fileNode); + return url; + } + + protected Node getFileNode(Node imageDataNode) throws RepositoryException { + // FIXME make URL use case more robust + String fileref = null; + if (imageDataNode.hasProperty(DbkAttr.fileref.name())) + fileref = imageDataNode.getProperty(DbkAttr.fileref.name()).getString(); + if (fileref == null) + return null; + Node fileNode; + if (fileref.startsWith("/")) + fileNode = baseFolder.getSession().getNode(fileref); + else + fileNode = baseFolder.getNode(fileref); + return fileNode; + } + + protected Node getMediaFolder() { + try { + // TODO check edition status + Node mediaFolder = JcrUtils.getOrAdd(baseFolder, EntityNames.MEDIA, NodeType.NT_FOLDER); + return mediaFolder; + } catch (RepositoryException e) { + throw new JcrException("Cannot get media folder", e); + } + } +} diff --git a/org.argeo.publishing.ui/src/org/argeo/docbook/ui/DbkImg.java b/org.argeo.publishing.ui/src/org/argeo/docbook/ui/DbkImg.java new file mode 100644 index 0000000..cb4ce2e --- /dev/null +++ b/org.argeo.publishing.ui/src/org/argeo/docbook/ui/DbkImg.java @@ -0,0 +1,70 @@ +package org.argeo.docbook.ui; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; + +import org.argeo.cms.ui.util.CmsUiUtils; +import org.argeo.cms.ui.widgets.Img; +import org.eclipse.rap.fileupload.FileUploadEvent; +import org.eclipse.rap.fileupload.FileUploadHandler; +import org.eclipse.rap.fileupload.FileUploadListener; +import org.eclipse.rap.fileupload.FileUploadReceiver; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + +/** DocBook specific image area. */ +public class DbkImg extends Img { + private static final long serialVersionUID = -6150996708899219074L; + + public DbkImg(Composite parent, int swtStyle, Node imgNode, DbkImageManager imageManager) + throws RepositoryException { + super(parent, swtStyle, imgNode, imageManager); + } + + @Override + protected Node getUploadFolder() { + Node mediaFolder = ((DbkImageManager) getImageManager()).getMediaFolder(); + return mediaFolder; + } + + @Override + protected String getUploadName() { + return null; + } + + @Override + protected void setContainerLayoutData(Composite composite) { + composite.setLayoutData(CmsUiUtils.grabWidth(SWT.CENTER, SWT.DEFAULT)); + } + + @Override + protected void setControlLayoutData(Control control) { + control.setLayoutData(CmsUiUtils.grabWidth(SWT.CENTER, SWT.DEFAULT)); + } + + @Override + protected FileUploadHandler prepareUpload(FileUploadReceiver receiver) { + FileUploadHandler fileUploadHandler = super.prepareUpload(receiver); + fileUploadHandler.addUploadListener(new FileUploadListener() { + + @Override + public void uploadProgress(FileUploadEvent event) { + // TODO Auto-generated method stub + + } + + @Override + public void uploadFinished(FileUploadEvent event) { + } + + @Override + public void uploadFailed(FileUploadEvent event) { + // TODO Auto-generated method stub + + } + }); + return fileUploadHandler; + } + +} diff --git a/org.argeo.publishing.ui/src/org/argeo/docbook/ui/DbkSectionTitle.java b/org.argeo.publishing.ui/src/org/argeo/docbook/ui/DbkSectionTitle.java new file mode 100644 index 0000000..92fd2b8 --- /dev/null +++ b/org.argeo.publishing.ui/src/org/argeo/docbook/ui/DbkSectionTitle.java @@ -0,0 +1,30 @@ +package org.argeo.docbook.ui; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; + +import org.argeo.cms.ui.viewers.EditablePart; +import org.argeo.cms.ui.viewers.NodePart; +import org.argeo.cms.ui.widgets.EditableText; +import org.eclipse.swt.widgets.Composite; + +/** The title of a section, based on an XML text node. */ +public class DbkSectionTitle extends EditableText implements EditablePart, NodePart { + private static final long serialVersionUID = -1787983154946583171L; + + private final TextSection section; + + public DbkSectionTitle(Composite parent, int swtStyle, Node titleNode) throws RepositoryException { + super(parent, swtStyle, titleNode); + section = (TextSection) TextSection.findSection(this); + } + + public TextSection getSection() { + return section; + } + + @Override + public Node getItem() throws RepositoryException { + return getNode(); + } +} diff --git a/org.argeo.publishing.ui/src/org/argeo/docbook/ui/DbkTextInterpreter.java b/org.argeo.publishing.ui/src/org/argeo/docbook/ui/DbkTextInterpreter.java new file mode 100644 index 0000000..c853535 --- /dev/null +++ b/org.argeo.publishing.ui/src/org/argeo/docbook/ui/DbkTextInterpreter.java @@ -0,0 +1,283 @@ +package org.argeo.docbook.ui; + +import static org.argeo.docbook.DbkType.para; +import static org.argeo.docbook.DbkType.title; +import static org.argeo.docbook.DbkUtils.isDbk; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringReader; +import java.nio.charset.StandardCharsets; +import java.util.List; + +import javax.jcr.ImportUUIDBehavior; +import javax.jcr.Item; +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.Property; +import javax.jcr.PropertyIterator; +import javax.jcr.RepositoryException; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.apache.commons.io.IOUtils; +import org.argeo.docbook.DbkAttr; +import org.argeo.docbook.DbkType; +import org.argeo.jcr.Jcr; +import org.argeo.jcr.JcrException; + +/** Based on HTML with a few Wiki-like shortcuts. */ +public class DbkTextInterpreter implements TextInterpreter { + private DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + + private String linkCssClass = DbkType.link.name(); + + @Override + public void write(Item item, String content) { + try { + if (item instanceof Node) { + Node node = (Node) item; + if (isDbk(node, para) || isDbk(node, title)) { + String raw = convertToStorage(node, content); + validateBeforeStoring(raw); + + String jcrUuid = node.getIdentifier(); +// if (node.hasProperty(Property.JCR_UUID)) +// jcrUuid = node.getProperty(Property.JCR_UUID).getString(); +// else { +// // TODO use time based +// jcrUuid = UUID.randomUUID().toString(); +// node.setProperty(Property.JCR_UUID, jcrUuid); +// node.getSession().save(); +// } + + StringBuilder namespaces = new StringBuilder(); + namespaces.append(" xmlns:dbk=\"http://docbook.org/ns/docbook\""); + namespaces.append(" xmlns:jcr=\"http://www.jcp.org/jcr/1.0\""); + namespaces.append(" xmlns:xlink=\"http://www.w3.org/1999/xlink\""); + raw = "<" + node.getName() + " jcr:uuid=\"" + jcrUuid + "\"" + namespaces + ">" + raw + ""; +// System.out.println(raw); + try (InputStream in = new ByteArrayInputStream(raw.getBytes(StandardCharsets.UTF_8))) { + node.getSession().importXML(node.getParent().getPath(), in, + ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING); + // node.getSession().save(); + } catch (IOException e) { + throw new IllegalArgumentException("Cannot parse raw content of " + node, e); + } + +// try { +// DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); +// Document document; +// try (Reader in = new StringReader(raw)) { +// document = documentBuilder.parse(new InputSource(in)); +// } +// NodeList nl = document.getChildNodes(); +// for (int i = 0; i < nl.getLength(); i++) { +// org.w3c.dom.Node n = nl.item(i); +// if (node instanceof Text) { +// +// } +// } +// } catch (ParserConfigurationException | SAXException | IOException e) { +// throw new IllegalArgumentException("Cannot parse raw content of " + node, e); +// } + +// Node jcrText; +// if (!node.hasNode(Jcr.JCR_XMLTEXT)) +// jcrText = node.addNode(Jcr.JCR_XMLTEXT, JcrxType.JCRX_XMLTEXT); +// else +// jcrText = node.getNode(Jcr.JCR_XMLTEXT); +// jcrText.setProperty(Jcr.JCR_XMLCHARACTERS, raw); + } else { + throw new IllegalArgumentException("Don't know how to interpret " + node); + } + } else {// property + Property property = (Property) item; + property.setValue(content); + } + // item.getSession().save(); + } catch (RepositoryException e) { + throw new JcrException("Cannot set content on " + item, e); + } + } + + @Override + public String read(Item item) { + try { + String raw = raw(item); + return convertFromStorage(item, raw); + } catch (RepositoryException e) { + throw new JcrException("Cannot get " + item + " for edit", e); + } + } + + @Override + public String raw(Item item) { + try { + item.getSession().refresh(true); + if (item instanceof Node) { + Node node = (Node) item; + if (isDbk(node, para) || isDbk(node, title)) { + StringBuilder sb = new StringBuilder(); + readXml(node, sb); +// NodeIterator nit = node.getNodes(); +// while (nit.hasNext()) { +// Node child = nit.nextNode(); +// if (child.getName().equals(Jcr.JCR_XMLTEXT)) { +// Node jcrText = node.getNode(Jcr.JCR_XMLTEXT); +// String txt = jcrText.getProperty(Jcr.JCR_XMLCHARACTERS).getString(); +// // TODO make it more robust +// // txt = txt.replace("\n", "").replace("\t", ""); +// txt = txt.replace("\t", " "); +// sb.append(txt); +// } else { +// try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { +// child.getSession().exportDocumentView(child.getPath(), out, true, false); +// sb.append(new String(out.toByteArray(), StandardCharsets.UTF_8)); +// } catch (IOException e) { +// throw new IllegalStateException("Cannot export " + child, e); +// } +// } +// } + return sb.toString(); + } else { + throw new IllegalArgumentException("Don't know how to interpret " + node); + } + } else {// property + Property property = (Property) item; + return property.getString(); + } + } catch (RepositoryException e) { + throw new JcrException("Cannot get " + item + " content", e); + } + } + + private void readXml(Node node, StringBuilder sb) throws RepositoryException { + NodeIterator nit = node.getNodes(); + while (nit.hasNext()) { + Node child = nit.nextNode(); + if (child.getName().equals(Jcr.JCR_XMLTEXT)) { + String txt = child.getProperty(Jcr.JCR_XMLCHARACTERS).getString(); + // TODO make it more robust + // txt = txt.replace("\n", "").replace("\t", ""); + txt = txt.replace("\t", " "); + sb.append(txt); + } else { + sb.append('<').append(child.getName()); + PropertyIterator pit = child.getProperties(); + properties: while (pit.hasNext()) { + Property p = pit.nextProperty(); + if (p.getName().startsWith("jcr:")) + continue properties; + sb.append(' ').append(p.getName()).append("=\"").append(p.getString()).append('\"'); + } + sb.append('>'); + readXml(child, sb); +// try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { +// child.getSession().exportDocumentView(child.getPath(), out, true, false); +// sb.append(new String(out.toByteArray(), StandardCharsets.UTF_8)); +// } catch (IOException e) { +// throw new IllegalStateException("Cannot export " + child, e); +// } + sb.append("'); + } + } + } + + private void readAsSimpleHtml(Node node, StringBuilder sb) throws RepositoryException { + NodeIterator nit = node.getNodes(); + while (nit.hasNext()) { + Node child = nit.nextNode(); + if (child.getName().equals(Jcr.JCR_XMLTEXT)) { + String txt = child.getProperty(Jcr.JCR_XMLCHARACTERS).getString(); + // TODO make it more robust + // txt = txt.replace("\n", "").replace("\t", ""); + txt = txt.replace("\t", " "); + String html = textToSimpleHtml(txt); + sb.append(html); + } else if (child.getName().equals(DbkType.link.get())) { + if (child.hasProperty(DbkAttr.XLINK_HREF)) { + String href = child.getProperty(DbkAttr.XLINK_HREF).getString(); + // TODO deal with other forbidden XML characters? + href = href.replace("&", "&"); + sb.append(""); + readAsSimpleHtml(child, sb); + sb.append(""); + } + } else { + // ignore + } + } + } + + private String textToSimpleHtml(String raw) { + // FIXME the saved data should be corrected instead. + if (raw.indexOf('&') >= 0) { + raw = raw.replace("&", "&"); + } + if (raw.indexOf('<') >= 0) { + raw = raw.replace("<", "<"); + } + if (raw.indexOf('>') >= 0) { + raw = raw.replace(">", ">"); + } + if (raw.indexOf('\"') >= 0) { + raw = raw.replace("\"", """); + } + if (raw.indexOf('\'') >= 0) { + raw = raw.replace("\'", "'"); + } +// raw = "" + raw + ""; + if (raw.length() == 0) + return raw; + try (StringReader reader = new StringReader(raw)) { + List lines = IOUtils.readLines(reader); + if (lines.size() == 1) + return lines.get(0); + StringBuilder sb = new StringBuilder(raw.length() + lines.size() * BR_LENGTH); + for (int i = 0; i < lines.size(); i++) { + if (i != 0) + sb.append("
"); + sb.append(lines.get(i)); + } + return sb.toString(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + final static int BR_LENGTH = "
".length(); + + public String readSimpleHtml(Item item) { + try { + StringBuilder sb = new StringBuilder(); +// sb.append("
"); + readAsSimpleHtml((Node) item, sb); +// sb.append("
"); +// System.out.println(sb); + return sb.toString(); + } catch (RepositoryException e) { + throw new JcrException("Cannot convert " + item + " to simple HTML", e); + } + } + + // EXTENSIBILITY + /** + * To be overridden, in order to make sure that only valid strings are being + * stored. + */ + protected void validateBeforeStoring(String raw) { + } + + /** To be overridden, in order to support additional formatting. */ + protected String convertToStorage(Item item, String content) throws RepositoryException { + return content; + + } + + /** To be overridden, in order to support additional formatting. */ + protected String convertFromStorage(Item item, String content) throws RepositoryException { + return content; + } +} diff --git a/org.argeo.publishing.ui/src/org/argeo/docbook/ui/DbkVideo.java b/org.argeo.publishing.ui/src/org/argeo/docbook/ui/DbkVideo.java new file mode 100644 index 0000000..5c3d057 --- /dev/null +++ b/org.argeo.publishing.ui/src/org/argeo/docbook/ui/DbkVideo.java @@ -0,0 +1,227 @@ +package org.argeo.docbook.ui; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Map; + +import javax.jcr.Item; +import javax.jcr.Node; +import javax.jcr.RepositoryException; + +import org.argeo.cms.ui.util.CmsUiUtils; +import org.argeo.cms.ui.viewers.NodePart; +import org.argeo.cms.ui.viewers.Section; +import org.argeo.cms.ui.viewers.SectionPart; +import org.argeo.cms.ui.widgets.StyledControl; +import org.argeo.docbook.DbkAttr; +import org.argeo.docbook.DbkType; +import org.argeo.docbook.DbkUtils; +import org.argeo.eclipse.ui.Selected; +import org.argeo.jcr.Jcr; +import org.argeo.jcr.JcrException; +import org.argeo.naming.NamingUtils; +import org.eclipse.swt.SWT; +import org.eclipse.swt.browser.Browser; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Text; + +public class DbkVideo extends StyledControl implements SectionPart, NodePart { + private static final long serialVersionUID = -8753232181570351880L; + private Section section; + + private int width = 640; + private int height = 360; + + private boolean editable; + + public DbkVideo(Composite parent, int style, Node node) { + this(Section.findSection(parent), parent, style, node); + } + + DbkVideo(Section section, Composite parent, int style, Node node) { + super(parent, style, node); + editable = !(SWT.READ_ONLY == (style & SWT.READ_ONLY)); + this.section = section; + setStyle(DbkType.videoobject.name()); + } + + @Override + protected Control createControl(Composite box, String style) { + Node mediaobject = getNode(); + Composite wrapper = new Composite(box, SWT.NONE); + wrapper.setLayout(CmsUiUtils.noSpaceGridLayout()); + + Composite browserC = new Composite(wrapper, SWT.NONE); + browserC.setLayout(CmsUiUtils.noSpaceGridLayout()); + GridData gd = new GridData(SWT.CENTER, SWT.FILL, true, true); + gd.widthHint = getWidth(); + gd.heightHint = getHeight(); + browserC.setLayoutData(gd); +// wrapper.setLayoutData(CmsUiUtils.fillAll()); + Browser browser = new Browser(browserC, SWT.NONE); + + if (editable) { + Composite editor = new Composite(wrapper, SWT.BORDER); + editor.setLayout(new GridLayout(3, false)); + editor.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + String fileref = DbkUtils.getMediaFileref(mediaobject); + Text text = new Text(editor, SWT.SINGLE); + if (fileref != null) + text.setText(fileref); + else + text.setMessage("Embed URL of the video"); + text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + Button updateB = new Button(editor, SWT.FLAT); + updateB.setText("Update"); + updateB.addSelectionListener(new Selected() { + + @Override + public void widgetSelected(SelectionEvent e) { + try { + Node videodata = mediaobject.getNode(DbkType.videoobject.get()) + .getNode(DbkType.videodata.get()); + String txt = text.getText(); + URI uri; + try { + uri = new URI(txt); + } catch (URISyntaxException e1) { + text.setText(""); + text.setMessage("Invalid URL"); + return; + } + + // Transform watch URL in embed + // YouTube + String videoId = null; + if ("www.youtube.com".equals(uri.getHost()) || "youtube.com".equals(uri.getHost()) + || "youtu.be".equals(uri.getHost())) { + if ("www.youtube.com".equals(uri.getHost()) || "youtube.com".equals(uri.getHost())) { + if ("/watch".equals(uri.getPath())) { + Map> map = NamingUtils.queryToMap(uri); + videoId = map.get("v").get(0); + } + } else if ("youtu.be".equals(uri.getHost())) { + videoId = uri.getPath().substring(1); + } + if (videoId != null) { + try { + uri = new URI("https://www.youtube.com/embed/" + videoId); + text.setText(uri.toString()); + } catch (URISyntaxException e1) { + throw new IllegalStateException(e1); + } + } + } + + // Vimeo + if ("vimeo.com".equals(uri.getHost())) { + videoId = uri.getPath().substring(1); + if (videoId != null) { + try { + uri = new URI("https://player.vimeo.com/video/" + videoId); + text.setText(uri.toString()); + } catch (URISyntaxException e1) { + throw new IllegalStateException(e1); + } + } + } + + videodata.setProperty(DbkAttr.fileref.name(), uri.toString()); + // TODO better integrate it in the edition lifecycle + videodata.getSession().save(); + load(browser); + } catch (RepositoryException e1) { + throw new JcrException("Cannot update " + mediaobject, e1); + } + + } + }); + + Button deleteB = new Button(editor, SWT.FLAT); + deleteB.setText("Delete"); + deleteB.addSelectionListener(new Selected() { + + @Override + public void widgetSelected(SelectionEvent e) { + try { + mediaobject.remove(); + mediaobject.getSession().save(); + dispose(); + getSection().getParent().layout(true, true); + } catch (RepositoryException e1) { + throw new JcrException("Cannot update " + mediaobject, e1); + } + + } + }); + } + + // TODO caption + return browser; + } + + public void load(Control control) { + try { + if (control instanceof Browser) { + Browser browser = (Browser) control; + getNode().getSession(); + String fileref = DbkUtils.getMediaFileref(getNode()); + if (fileref != null) { + // TODO manage self-hosted videos + // TODO for YouTube videos, check whether the URL starts with + // https://www.youtube.com/embed/ and not https://www.youtube.com/watch?v= + StringBuilder html = new StringBuilder(); + html.append( + "