<!-- Entity Framework -->
<dependency>
<groupId>org.argeo.suite</groupId>
- <artifactId>org.argeo.entity.api</artifactId>
- <version>2.3-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.argeo.suite</groupId>
- <artifactId>org.argeo.entity.core</artifactId>
- <version>2.3-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.argeo.suite</groupId>
- <artifactId>org.argeo.entity.ui</artifactId>
+ <artifactId>org.argeo.app.api</artifactId>
<version>2.3-SNAPSHOT</version>
</dependency>
+<!-- <dependency> -->
+<!-- <groupId>org.argeo.suite</groupId> -->
+<!-- <artifactId>org.argeo.entity.core</artifactId> -->
+<!-- <version>2.3-SNAPSHOT</version> -->
+<!-- </dependency> -->
+<!-- <dependency> -->
+<!-- <groupId>org.argeo.suite</groupId> -->
+<!-- <artifactId>org.argeo.entity.ui</artifactId> -->
+<!-- <version>2.3-SNAPSHOT</version> -->
+<!-- </dependency> -->
<!-- Argeo Suite Icons -->
<dependency>
<!-- Argeo Suite -->
<dependency>
<groupId>org.argeo.suite</groupId>
- <artifactId>org.argeo.suite.core</artifactId>
+ <artifactId>org.argeo.app.core</artifactId>
<version>2.3-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.argeo.suite</groupId>
- <artifactId>org.argeo.suite.ui</artifactId>
+ <artifactId>org.argeo.app.ui</artifactId>
<version>2.3-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.argeo.suite</groupId>
- <artifactId>org.argeo.suite.theme.default</artifactId>
+ <artifactId>org.argeo.app.theme.default</artifactId>
<version>2.3-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.argeo.suite</groupId>
- <artifactId>org.argeo.suite.ui.rap</artifactId>
+ <artifactId>org.argeo.app.ui.rap</artifactId>
<version>2.3-SNAPSHOT</version>
</dependency>
<!-- Argeo People -->
- <dependency>
- <groupId>org.argeo.suite</groupId>
- <artifactId>org.argeo.people.ui</artifactId>
- <version>2.3-SNAPSHOT</version>
- </dependency>
+<!-- <dependency> -->
+<!-- <groupId>org.argeo.suite</groupId> -->
+<!-- <artifactId>org.argeo.people.ui</artifactId> -->
+<!-- <version>2.3-SNAPSHOT</version> -->
+<!-- </dependency> -->
<!-- Argeo Library -->
- <dependency>
- <groupId>org.argeo.suite</groupId>
- <artifactId>org.argeo.library.ui</artifactId>
- <version>2.3-SNAPSHOT</version>
- </dependency>
+<!-- <dependency> -->
+<!-- <groupId>org.argeo.suite</groupId> -->
+<!-- <artifactId>org.argeo.library.ui</artifactId> -->
+<!-- <version>2.3-SNAPSHOT</version> -->
+<!-- </dependency> -->
<!-- Argeo Environment -->
- <dependency>
- <groupId>org.argeo.suite</groupId>
- <artifactId>org.argeo.geo.ui</artifactId>
- <version>2.3-SNAPSHOT</version>
- </dependency>
+<!-- <dependency> -->
+<!-- <groupId>org.argeo.suite</groupId> -->
+<!-- <artifactId>org.argeo.geo.ui</artifactId> -->
+<!-- <version>2.3-SNAPSHOT</version> -->
+<!-- </dependency> -->
<!-- Argeo Publishing -->
<dependency>
<groupId>org.argeo.suite</groupId>
- <artifactId>org.argeo.publishing.ui</artifactId>
+ <artifactId>org.argeo.app.servlet.publish</artifactId>
<version>2.3-SNAPSHOT</version>
</dependency>
<!-- Argeo Knowledge -->
+<!-- <dependency> -->
+<!-- <groupId>org.argeo.suite</groupId> -->
+<!-- <artifactId>org.argeo.support.xforms</artifactId> -->
+<!-- <version>2.3-SNAPSHOT</version> -->
+<!-- </dependency> -->
<dependency>
<groupId>org.argeo.suite</groupId>
- <artifactId>org.argeo.support.xforms</artifactId>
- <version>2.3-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.argeo.suite</groupId>
- <artifactId>org.argeo.support.odk</artifactId>
- <version>2.3-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.argeo.suite</groupId>
- <artifactId>org.argeo.support.geonames</artifactId>
+ <artifactId>org.argeo.app.servlet.odk</artifactId>
<version>2.3-SNAPSHOT</version>
</dependency>
+<!-- <dependency> -->
+<!-- <groupId>org.argeo.suite</groupId> -->
+<!-- <artifactId>org.argeo.support.geonames</artifactId> -->
+<!-- <version>2.3-SNAPSHOT</version> -->
+<!-- </dependency> -->
<!-- PDFBox -->
<dependency>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
--- /dev/null
+/bin/
+/target/
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.argeo.app.api</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
--- /dev/null
+/MANIFEST.MF
--- /dev/null
+Require-Capability:\
+cms.datamodel;filter:="(name=jcrx)"
+
+Provide-Capability:\
+cms.datamodel; name=entity; cnd=/org/argeo/entity/entity.cnd
--- /dev/null
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.argeo.suite</groupId>
+ <artifactId>argeo-suite</artifactId>
+ <version>2.3-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <artifactId>org.argeo.app.api</artifactId>
+ <name>Suite API</name>
+ <packaging>jar</packaging>
+ <dependencies>
+ <!-- Argeo Commons -->
+ <dependency>
+ <groupId>org.argeo.commons</groupId>
+ <artifactId>org.argeo.util</artifactId>
+ <version>${version.argeo-commons}</version>
+ </dependency>
+ </dependencies>
+</project>
--- /dev/null
+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";
+
+}
--- /dev/null
+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();
+}
--- /dev/null
+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;
+ }
+
+}
--- /dev/null
+package org.argeo.entity;
+
+import org.argeo.util.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";
+}
--- /dev/null
+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";
+ }
+
+}
--- /dev/null
+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";
+}
--- /dev/null
+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> {
+ 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();
+ }
+}
--- /dev/null
+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<? extends Term> getSubTerms();
+
+ Term getParentTerm();
+
+}
--- /dev/null
+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<Term> listAllTerms(String typology);
+
+}
--- /dev/null
+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<? extends Term> getSubTerms();
+
+ Term findTermByName(String name);
+}
--- /dev/null
+// Standard namespaces
+<xsd = "http://www.w3.org/2001/XMLSchema">
+<h = "http://www.w3.org/1999/xhtml">
+// see https://www.w3.org/2003/01/geo/
+<geo = "http://www.w3.org/2003/01/geo/wgs84_pos#">
+<svg = "http://www.w3.org/2000/svg">
+
+<ldap = "http://www.argeo.org/ns/ldap">
+<entity = 'http://www.argeo.org/ns/entity'>
+
+[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)
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
--- /dev/null
+/bin/
+/target/
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.argeo.app.core</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ds.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
--- /dev/null
+/MANIFEST.MF
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy" name="Suite Maintenance Service">
+ <implementation class="org.argeo.suite.core.SuiteMaintenanceService"/>
+ <reference bind="setRepository" cardinality="1..1" interface="javax.jcr.Repository" name="Repository" policy="static" target="(cn=entity)"/>
+ <reference bind="setUserTransaction" cardinality="1..1" interface="javax.transaction.UserTransaction" name="UserTransaction" policy="static"/>
+ <reference bind="setUserAdmin" cardinality="1..1" interface="org.osgi.service.useradmin.UserAdmin" name="UserAdmin" policy="static"/>
+</scr:component>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy" name="Suite Terms Manager">
+ <implementation class="org.argeo.suite.core.SuiteTermsManager"/>
+ <reference bind="setRepository" cardinality="1..1" interface="javax.jcr.Repository" name="Repository" policy="static" target="(cn=entity)"/>
+ <service>
+ <provide interface="org.argeo.entity.TermsManager"/>
+ </service>
+</scr:component>
--- /dev/null
+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,\
+com.fasterxml.jackson.core,\
+org.argeo.entity,\
+*
\ No newline at end of file
--- /dev/null
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ OSGI-INF/
+source.. = src/
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.argeo.suite</groupId>
+ <artifactId>argeo-suite</artifactId>
+ <version>2.3-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <artifactId>org.argeo.app.core</artifactId>
+ <name>Suite Core</name>
+ <packaging>jar</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>org.argeo.suite</groupId>
+ <artifactId>org.argeo.app.api</artifactId>
+ <version>2.3-SNAPSHOT</version>
+ </dependency>
+
+ <!-- Argeo Commons -->
+ <dependency>
+ <groupId>org.argeo.commons</groupId>
+ <artifactId>org.argeo.cms</artifactId>
+ <version>${version.argeo-commons}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.commons</groupId>
+ <artifactId>org.argeo.cms.jcr</artifactId>
+ <version>${version.argeo-commons}</version>
+ </dependency>
+ </dependencies>
+</project>
--- /dev/null
+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();
+ }
+ }
+
+}
--- /dev/null
+package org.argeo.docbook;
+
+/** Supported DocBook attributes. */
+public enum DbkAttr {
+ role,
+ //
+ fileref, contentwidth, contentdepth
+ //
+ ;
+
+ public final static String XLINK_HREF = "xlink:href";
+
+}
--- /dev/null
+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,
+ //
+ ;
+}
--- /dev/null
+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";
+ }
+
+}
--- /dev/null
+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.argeo.api.cms.CmsLog;
+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 CmsLog log = CmsLog.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() {
+ }
+
+}
--- /dev/null
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:exsl="http://exslt.org/common"
+ xmlns:db = "http://docbook.org/ns/docbook"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ exclude-result-prefixes="exsl db"
+ version="1.0">
+
+<!--
+# ======================================================================
+# This file is part of DocBook V5.0CR5
+#
+# Copyright 2005 Norman Walsh, Sun Microsystems, Inc., and the
+# Organization for the Advancement of Structured Information
+# Standards (OASIS).
+#
+# Release: $Id: db4-upgrade.xsl 7660 2008-02-06 13:48:36Z nwalsh $
+#
+# Permission to use, copy, modify and distribute this stylesheet
+# and its accompanying documentation for any purpose and without fee
+# is hereby granted in perpetuity, provided that the above copyright
+# notice and this paragraph appear in all copies. The copyright
+# holders make no representation about the suitability of the schema
+# for any purpose. It is provided "as is" without expressed or implied
+# warranty.
+#
+# Please direct all questions, bug reports, or suggestions for changes
+# to the docbook@lists.oasis-open.org mailing list. For more
+# information, see http://www.oasis-open.org/docbook/.
+#
+# ======================================================================
+-->
+
+<xsl:variable name="version" select="'1.0'"/>
+
+<xsl:output method="xml" encoding="utf-8" indent="no" omit-xml-declaration="yes"/>
+
+<xsl:preserve-space elements="*"/>
+<xsl:param name="rootid">
+ <xsl:choose>
+ <xsl:when test="/*/@id">
+ <xsl:value-of select="/*/@id"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>UNKNOWN</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:param>
+
+<xsl:param name="defaultDate" select="''"/>
+
+<xsl:template match="/">
+ <xsl:variable name="converted">
+ <xsl:apply-templates/>
+ </xsl:variable>
+ <xsl:comment>
+ <xsl:text> Converted by db4-upgrade version </xsl:text>
+ <xsl:value-of select="$version"/>
+ <xsl:text> </xsl:text>
+ </xsl:comment>
+ <xsl:text> </xsl:text>
+ <xsl:apply-templates select="exsl:node-set($converted)/*" mode="addNS"/>
+</xsl:template>
+
+<xsl:template match="bookinfo|chapterinfo|articleinfo|artheader|appendixinfo
+ |blockinfo
+ |bibliographyinfo|glossaryinfo|indexinfo|setinfo
+ |setindexinfo
+ |sect1info|sect2info|sect3info|sect4info|sect5info
+ |sectioninfo
+ |refsect1info|refsect2info|refsect3info|refsectioninfo
+ |referenceinfo|partinfo"
+ priority="200">
+ <info>
+ <xsl:call-template name="copy.attributes"/>
+
+ <!-- titles can be inside or outside or both. fix that -->
+ <xsl:choose>
+ <xsl:when test="title and following-sibling::title">
+ <xsl:if test="title != following-sibling::title">
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Check </xsl:text>
+ <xsl:value-of select="name(..)"/>
+ <xsl:text> title.</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:apply-templates select="title" mode="copy"/>
+ </xsl:when>
+ <xsl:when test="title">
+ <xsl:apply-templates select="title" mode="copy"/>
+ </xsl:when>
+ <xsl:when test="following-sibling::title">
+ <xsl:apply-templates select="following-sibling::title" mode="copy"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Check </xsl:text>
+ <xsl:value-of select="name(..)"/>
+ <xsl:text>: no title.</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <xsl:choose>
+ <xsl:when test="titleabbrev and following-sibling::titleabbrev">
+ <xsl:if test="titleabbrev != following-sibling::titleabbrev">
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Check </xsl:text>
+ <xsl:value-of select="name(..)"/>
+ <xsl:text> titleabbrev.</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:apply-templates select="titleabbrev" mode="copy"/>
+ </xsl:when>
+ <xsl:when test="titleabbrev">
+ <xsl:apply-templates select="titleabbrev" mode="copy"/>
+ </xsl:when>
+ <xsl:when test="following-sibling::titleabbrev">
+ <xsl:apply-templates select="following-sibling::titleabbrev" mode="copy"/>
+ </xsl:when>
+ </xsl:choose>
+
+ <xsl:choose>
+ <xsl:when test="subtitle and following-sibling::subtitle">
+ <xsl:if test="subtitle != following-sibling::subtitle">
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Check </xsl:text>
+ <xsl:value-of select="name(..)"/>
+ <xsl:text> subtitle.</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:apply-templates select="subtitle" mode="copy"/>
+ </xsl:when>
+ <xsl:when test="subtitle">
+ <xsl:apply-templates select="subtitle" mode="copy"/>
+ </xsl:when>
+ <xsl:when test="following-sibling::subtitle">
+ <xsl:apply-templates select="following-sibling::subtitle" mode="copy"/>
+ </xsl:when>
+ </xsl:choose>
+
+ <xsl:apply-templates/>
+ </info>
+</xsl:template>
+
+<xsl:template match="objectinfo|prefaceinfo|refsynopsisdivinfo
+ |screeninfo|sidebarinfo"
+ priority="200">
+ <info>
+ <xsl:call-template name="copy.attributes"/>
+
+ <!-- titles can be inside or outside or both. fix that -->
+ <xsl:choose>
+ <xsl:when test="title and following-sibling::title">
+ <xsl:if test="title != following-sibling::title">
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Check </xsl:text>
+ <xsl:value-of select="name(..)"/>
+ <xsl:text> title.</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:apply-templates select="title" mode="copy"/>
+ </xsl:when>
+ <xsl:when test="title">
+ <xsl:apply-templates select="title" mode="copy"/>
+ </xsl:when>
+ <xsl:when test="following-sibling::title">
+ <xsl:apply-templates select="following-sibling::title" mode="copy"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <!-- it's ok if there's no title on these -->
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <xsl:choose>
+ <xsl:when test="titleabbrev and following-sibling::titleabbrev">
+ <xsl:if test="titleabbrev != following-sibling::titleabbrev">
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Check </xsl:text>
+ <xsl:value-of select="name(..)"/>
+ <xsl:text> titleabbrev.</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:apply-templates select="titleabbrev" mode="copy"/>
+ </xsl:when>
+ <xsl:when test="titleabbrev">
+ <xsl:apply-templates select="titleabbrev" mode="copy"/>
+ </xsl:when>
+ <xsl:when test="following-sibling::titleabbrev">
+ <xsl:apply-templates select="following-sibling::titleabbrev" mode="copy"/>
+ </xsl:when>
+ </xsl:choose>
+
+ <xsl:choose>
+ <xsl:when test="subtitle and following-sibling::subtitle">
+ <xsl:if test="subtitle != following-sibling::subtitle">
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Check </xsl:text>
+ <xsl:value-of select="name(..)"/>
+ <xsl:text> subtitle.</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:apply-templates select="subtitle" mode="copy"/>
+ </xsl:when>
+ <xsl:when test="subtitle">
+ <xsl:apply-templates select="subtitle" mode="copy"/>
+ </xsl:when>
+ <xsl:when test="following-sibling::subtitle">
+ <xsl:apply-templates select="following-sibling::subtitle" mode="copy"/>
+ </xsl:when>
+ </xsl:choose>
+
+ <xsl:apply-templates/>
+ </info>
+</xsl:template>
+
+<xsl:template match="refentryinfo"
+ priority="200">
+ <info>
+ <xsl:call-template name="copy.attributes"/>
+
+ <!-- titles can be inside or outside or both. fix that -->
+ <xsl:if test="title">
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Discarding title from refentryinfo!</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+
+ <xsl:if test="titleabbrev">
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Discarding titleabbrev from refentryinfo!</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+
+ <xsl:if test="subtitle">
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Discarding subtitle from refentryinfo!</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+
+ <xsl:apply-templates/>
+ </info>
+</xsl:template>
+
+<xsl:template match="refmiscinfo"
+ priority="200">
+ <refmiscinfo>
+ <xsl:call-template name="copy.attributes">
+ <xsl:with-param name="suppress" select="'class'"/>
+ </xsl:call-template>
+ <xsl:if test="@class">
+ <xsl:choose>
+ <xsl:when test="@class = 'source'
+ or @class = 'version'
+ or @class = 'manual'
+ or @class = 'sectdesc'
+ or @class = 'software'">
+ <xsl:attribute name="class">
+ <xsl:value-of select="@class"/>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:attribute name="class">
+ <xsl:value-of select="'other'"/>
+ </xsl:attribute>
+ <xsl:attribute name="otherclass">
+ <xsl:value-of select="@class"/>
+ </xsl:attribute>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:if>
+ <xsl:apply-templates/>
+ </refmiscinfo>
+</xsl:template>
+
+<xsl:template match="corpauthor" priority="200">
+ <author>
+ <xsl:call-template name="copy.attributes"/>
+ <orgname>
+ <xsl:apply-templates/>
+ </orgname>
+ </author>
+</xsl:template>
+
+<xsl:template match="corpname" priority="200">
+ <orgname>
+ <xsl:call-template name="copy.attributes"/>
+ <xsl:apply-templates/>
+ </orgname>
+</xsl:template>
+
+<xsl:template match="author[not(personname)]|editor[not(personname)]|othercredit[not(personname)]" priority="200">
+ <xsl:copy>
+ <xsl:call-template name="copy.attributes"/>
+ <personname>
+ <xsl:apply-templates select="honorific|firstname|surname|othername|lineage"/>
+ </personname>
+ <xsl:apply-templates select="*[not(self::honorific|self::firstname|self::surname
+ |self::othername|self::lineage)]"/>
+ </xsl:copy>
+</xsl:template>
+
+<xsl:template match="address|programlisting|screen|funcsynopsisinfo
+ |classsynopsisinfo|literallayout" priority="200">
+ <xsl:copy>
+ <xsl:call-template name="copy.attributes">
+ <xsl:with-param name="suppress" select="'format'"/>
+ </xsl:call-template>
+ <xsl:apply-templates/>
+ </xsl:copy>
+</xsl:template>
+
+<xsl:template match="productname[@class]" priority="200">
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Dropping class attribute from productname</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+ <xsl:copy>
+ <xsl:call-template name="copy.attributes">
+ <xsl:with-param name="suppress" select="'class'"/>
+ </xsl:call-template>
+ <xsl:apply-templates/>
+ </xsl:copy>
+</xsl:template>
+
+<xsl:template match="dedication|preface|chapter|appendix|part|partintro
+ |article|bibliography|glossary|glossdiv|index
+ |reference[not(referenceinfo)]
+ |book" priority="200">
+ <xsl:choose>
+ <xsl:when test="not(dedicationinfo|prefaceinfo|chapterinfo
+ |appendixinfo|partinfo
+ |articleinfo|artheader|bibliographyinfo
+ |glossaryinfo|indexinfo
+ |bookinfo)">
+ <xsl:copy>
+ <xsl:call-template name="copy.attributes"/>
+ <xsl:if test="title|subtitle|titleabbrev">
+ <info>
+ <xsl:apply-templates select="title" mode="copy"/>
+ <xsl:apply-templates select="titleabbrev" mode="copy"/>
+ <xsl:apply-templates select="subtitle" mode="copy"/>
+ <xsl:apply-templates select="abstract" mode="copy"/>
+ </info>
+ </xsl:if>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy>
+ <xsl:call-template name="copy.attributes"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="formalpara|figure|table[tgroup]|example|blockquote
+ |caution|important|note|warning|tip
+ |bibliodiv|glossarydiv|indexdiv
+ |orderedlist|itemizedlist|variablelist|procedure
+ |task|tasksummary|taskprerequisites|taskrelated
+ |sidebar"
+ priority="200">
+ <xsl:choose>
+ <xsl:when test="blockinfo">
+ <xsl:copy>
+ <xsl:call-template name="copy.attributes"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy>
+ <xsl:call-template name="copy.attributes"/>
+
+ <xsl:if test="title|titleabbrev|subtitle">
+ <info>
+ <xsl:apply-templates select="title" mode="copy"/>
+ <xsl:apply-templates select="titleabbrev" mode="copy"/>
+ <xsl:apply-templates select="subtitle" mode="copy"/>
+ </info>
+ </xsl:if>
+
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="equation" priority="200">
+ <xsl:choose>
+ <xsl:when test="not(title)">
+ <xsl:call-template name="emit-message">
+ <xsl:with-param
+ name="message"
+ >Convert equation without title to informal equation.</xsl:with-param>
+ </xsl:call-template>
+ <informalequation>
+ <xsl:call-template name="copy.attributes"/>
+ <xsl:apply-templates/>
+ </informalequation>
+ </xsl:when>
+ <xsl:when test="blockinfo">
+ <xsl:copy>
+ <xsl:call-template name="copy.attributes"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy>
+ <xsl:call-template name="copy.attributes"/>
+ <info>
+ <xsl:apply-templates select="title" mode="copy"/>
+ <xsl:apply-templates select="titleabbrev" mode="copy"/>
+ <xsl:apply-templates select="subtitle" mode="copy"/>
+ </info>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="sect1|sect2|sect3|sect4|sect5|section"
+ priority="200">
+ <section>
+ <xsl:call-template name="copy.attributes"/>
+
+ <xsl:if test="not(sect1info|sect2info|sect3info|sect4info|sect5info|sectioninfo)">
+ <info>
+ <xsl:apply-templates select="title" mode="copy"/>
+ <xsl:apply-templates select="titleabbrev" mode="copy"/>
+ <xsl:apply-templates select="subtitle" mode="copy"/>
+ <xsl:apply-templates select="abstract" mode="copy"/>
+ </info>
+ </xsl:if>
+ <xsl:apply-templates/>
+ </section>
+</xsl:template>
+
+<xsl:template match="simplesect"
+ priority="200">
+ <simplesect>
+ <xsl:call-template name="copy.attributes"/>
+ <info>
+ <xsl:apply-templates select="title" mode="copy"/>
+ <xsl:apply-templates select="titleabbrev" mode="copy"/>
+ <xsl:apply-templates select="subtitle" mode="copy"/>
+ <xsl:apply-templates select="abstract" mode="copy"/>
+ </info>
+ <xsl:apply-templates/>
+ </simplesect>
+</xsl:template>
+
+<xsl:template match="refsect1|refsect2|refsect3|refsection" priority="200">
+ <refsection>
+ <xsl:call-template name="copy.attributes"/>
+
+ <xsl:if test="not(refsect1info|refsect2info|refsect3info|refsectioninfo)">
+ <info>
+ <xsl:apply-templates select="title" mode="copy"/>
+ <xsl:apply-templates select="titleabbrev" mode="copy"/>
+ <xsl:apply-templates select="subtitle" mode="copy"/>
+ <xsl:apply-templates select="abstract" mode="copy"/>
+ </info>
+ </xsl:if>
+ <xsl:apply-templates/>
+ </refsection>
+</xsl:template>
+
+<xsl:template match="imagedata|videodata|audiodata|textdata" priority="200">
+ <xsl:copy>
+ <xsl:call-template name="copy.attributes">
+ <xsl:with-param name="suppress" select="'srccredit'"/>
+ </xsl:call-template>
+ <xsl:if test="@srccredit">
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Check conversion of srccredit </xsl:text>
+ <xsl:text>(othercredit="srccredit").</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+ <info>
+ <othercredit class="other" otherclass="srccredit">
+ <orgname>???</orgname>
+ <contrib>
+ <xsl:value-of select="@srccredit"/>
+ </contrib>
+ </othercredit>
+ </info>
+ </xsl:if>
+ </xsl:copy>
+</xsl:template>
+
+<xsl:template match="sgmltag" priority="200">
+ <tag>
+ <xsl:call-template name="copy.attributes"/>
+ <xsl:if test="@class = 'sgmlcomment'">
+ <xsl:attribute name="class">comment</xsl:attribute>
+ </xsl:if>
+ <xsl:apply-templates/>
+ </tag>
+</xsl:template>
+
+<xsl:template match="inlinegraphic[@format='linespecific']" priority="210">
+ <textobject>
+ <textdata>
+ <xsl:call-template name="copy.attributes"/>
+ </textdata>
+ </textobject>
+</xsl:template>
+
+<xsl:template match="inlinegraphic" priority="200">
+ <inlinemediaobject>
+ <imageobject>
+ <imagedata>
+ <xsl:call-template name="copy.attributes"/>
+ </imagedata>
+ </imageobject>
+ </inlinemediaobject>
+</xsl:template>
+
+<xsl:template match="graphic[@format='linespecific']" priority="210">
+ <mediaobject>
+ <textobject>
+ <textdata>
+ <xsl:call-template name="copy.attributes"/>
+ </textdata>
+ </textobject>
+ </mediaobject>
+</xsl:template>
+
+<xsl:template match="graphic" priority="200">
+ <mediaobject>
+ <imageobject>
+ <imagedata>
+ <xsl:call-template name="copy.attributes"/>
+ </imagedata>
+ </imageobject>
+ </mediaobject>
+</xsl:template>
+
+<xsl:template match="pubsnumber" priority="200">
+ <biblioid class="pubsnumber">
+ <xsl:call-template name="copy.attributes"/>
+ <xsl:apply-templates/>
+ </biblioid>
+</xsl:template>
+
+<xsl:template match="invpartnumber" priority="200">
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Converting invpartnumber to biblioid otherclass="invpartnumber".</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+ <biblioid class="other" otherclass="invpartnumber">
+ <xsl:call-template name="copy.attributes"/>
+ <xsl:apply-templates/>
+ </biblioid>
+</xsl:template>
+
+<xsl:template match="contractsponsor" priority="200">
+ <xsl:variable name="contractnum"
+ select="preceding-sibling::contractnum|following-sibling::contractnum"/>
+
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Converting contractsponsor to othercredit="contractsponsor".</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+
+ <othercredit class="other" otherclass="contractsponsor">
+ <orgname>
+ <xsl:call-template name="copy.attributes"/>
+ <xsl:apply-templates/>
+ </orgname>
+ <xsl:for-each select="$contractnum">
+ <contrib role="contractnum">
+ <xsl:apply-templates select="node()"/>
+ </contrib>
+ </xsl:for-each>
+ </othercredit>
+</xsl:template>
+
+<xsl:template match="contractnum" priority="200">
+ <xsl:if test="not(preceding-sibling::contractsponsor
+ |following-sibling::contractsponsor)
+ and not(preceding-sibling::contractnum)">
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Converting contractnum to othercredit="contractnum".</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+
+ <othercredit class="other" otherclass="contractnum">
+ <orgname>???</orgname>
+ <xsl:for-each select="self::contractnum
+ |preceding-sibling::contractnum
+ |following-sibling::contractnum">
+ <contrib>
+ <xsl:apply-templates select="node()"/>
+ </contrib>
+ </xsl:for-each>
+ </othercredit>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="isbn|issn" priority="200">
+ <biblioid class="{local-name(.)}">
+ <xsl:call-template name="copy.attributes"/>
+ <xsl:apply-templates/>
+ </biblioid>
+</xsl:template>
+
+<xsl:template match="biblioid[count(*) = 1
+ and ulink
+ and normalize-space(text()) = '']" priority="200">
+ <biblioid xlink:href="{ulink/@url}">
+ <xsl:call-template name="copy.attributes"/>
+ <xsl:apply-templates select="ulink/node()"/>
+ </biblioid>
+</xsl:template>
+
+<xsl:template match="authorblurb" priority="200">
+ <personblurb>
+ <xsl:call-template name="copy.attributes"/>
+ <xsl:apply-templates/>
+ </personblurb>
+</xsl:template>
+
+<xsl:template match="collabname" priority="200">
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Check conversion of collabname </xsl:text>
+ <xsl:text>(orgname role="collabname").</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+ <orgname role="collabname">
+ <xsl:call-template name="copy.attributes"/>
+ <xsl:apply-templates/>
+ </orgname>
+</xsl:template>
+
+<xsl:template match="modespec" priority="200">
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Discarding modespec (</xsl:text>
+ <xsl:value-of select="."/>
+ <xsl:text>).</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+</xsl:template>
+
+<xsl:template match="mediaobjectco" priority="200">
+ <mediaobject>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates/>
+ </mediaobject>
+</xsl:template>
+
+<xsl:template match="remark" priority="200">
+ <!-- get rid of any embedded markup -->
+ <remark>
+ <xsl:copy-of select="@*"/>
+ <xsl:value-of select="."/>
+ </remark>
+</xsl:template>
+
+<xsl:template match="biblioentry/title
+ |bibliomset/title
+ |biblioset/title
+ |bibliomixed/title" priority="400">
+ <citetitle>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates/>
+ </citetitle>
+</xsl:template>
+
+<xsl:template match="biblioentry/titleabbrev|biblioentry/subtitle
+ |bibliomset/titleabbrev|bibliomset/subtitle
+ |biblioset/titleabbrev|biblioset/subtitle
+ |bibliomixed/titleabbrev|bibliomixed/subtitle"
+ priority="400">
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+</xsl:template>
+
+<xsl:template match="biblioentry/contrib
+ |bibliomset/contrib
+ |bibliomixed/contrib" priority="200">
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Check conversion of contrib </xsl:text>
+ <xsl:text>(othercontrib="contrib").</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+ <othercredit class="other" otherclass="contrib">
+ <orgname>???</orgname>
+ <contrib>
+ <xsl:call-template name="copy.attributes"/>
+ <xsl:apply-templates/>
+ </contrib>
+ </othercredit>
+</xsl:template>
+
+<xsl:template match="link" priority="200">
+ <xsl:copy>
+ <xsl:call-template name="copy.attributes"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+</xsl:template>
+
+<xsl:template match="ulink" priority="200">
+ <xsl:choose>
+ <xsl:when test="node()">
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Converting ulink to link.</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+
+ <link xlink:href="{@url}">
+ <xsl:call-template name="copy.attributes">
+ <xsl:with-param name="suppress" select="'url'"/>
+ </xsl:call-template>
+ <xsl:apply-templates/>
+ </link>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Converting ulink to uri.</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+
+ <uri xlink:href="{@url}">
+ <xsl:call-template name="copy.attributes">
+ <xsl:with-param name="suppress" select="'url'"/>
+ </xsl:call-template>
+ <xsl:value-of select="@url"/>
+ </uri>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="olink" priority="200">
+ <xsl:if test="@linkmode">
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Discarding linkmode on olink.</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+
+ <xsl:choose>
+ <xsl:when test="@targetdocent">
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Converting olink targetdocent to targetdoc.</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+
+ <olink targetdoc="{unparsed-entity-uri(@targetdocent)}">
+ <xsl:for-each select="@*">
+ <xsl:if test="name(.) != 'targetdocent'
+ and name(.) != 'linkmode'">
+ <xsl:copy/>
+ </xsl:if>
+ </xsl:for-each>
+ <xsl:apply-templates/>
+ </olink>
+ </xsl:when>
+ <xsl:otherwise>
+ <olink>
+ <xsl:for-each select="@*">
+ <xsl:if test="name(.) != 'linkmode'">
+ <xsl:copy/>
+ </xsl:if>
+ </xsl:for-each>
+ <xsl:apply-templates/>
+ </olink>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="biblioentry/firstname
+ |biblioentry/surname
+ |biblioentry/othername
+ |biblioentry/lineage
+ |biblioentry/honorific
+ |bibliomset/firstname
+ |bibliomset/surname
+ |bibliomset/othername
+ |bibliomset/lineage
+ |bibliomset/honorific" priority="200">
+ <xsl:choose>
+ <xsl:when test="preceding-sibling::firstname
+ |preceding-sibling::surname
+ |preceding-sibling::othername
+ |preceding-sibling::lineage
+ |preceding-sibling::honorific">
+ <!-- nop -->
+ </xsl:when>
+ <xsl:otherwise>
+ <personname>
+ <xsl:apply-templates select="../firstname
+ |../surname
+ |../othername
+ |../lineage
+ |../honorific" mode="copy"/>
+ </personname>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="areaset" priority="200">
+ <xsl:copy>
+ <xsl:call-template name="copy.attributes">
+ <xsl:with-param name="suppress" select="'coords'"/>
+ </xsl:call-template>
+ <xsl:apply-templates/>
+ </xsl:copy>
+</xsl:template>
+
+<xsl:template match="date|pubdate" priority="200">
+ <xsl:variable name="rp1" select="substring-before(normalize-space(.), ' ')"/>
+ <xsl:variable name="rp2"
+ select="substring-before(substring-after(normalize-space(.), ' '),
+ ' ')"/>
+ <xsl:variable name="rp3"
+ select="substring-after(substring-after(normalize-space(.), ' '), ' ')"/>
+
+ <xsl:variable name="p1">
+ <xsl:choose>
+ <xsl:when test="contains($rp1, ',')">
+ <xsl:value-of select="substring-before($rp1, ',')"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$rp1"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:variable name="p2">
+ <xsl:choose>
+ <xsl:when test="contains($rp2, ',')">
+ <xsl:value-of select="substring-before($rp2, ',')"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$rp2"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:variable name="p3">
+ <xsl:choose>
+ <xsl:when test="contains($rp3, ',')">
+ <xsl:value-of select="substring-before($rp3, ',')"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$rp3"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:variable name="date">
+ <xsl:choose>
+ <xsl:when test="string($p1+1) != 'NaN' and string($p3+1) != 'NaN'">
+ <xsl:choose>
+ <xsl:when test="$p2 = 'Jan' or $p2 = 'January'">
+ <xsl:number value="$p3" format="0001"/>
+ <xsl:text>-01-</xsl:text>
+ <xsl:number value="$p1" format="01"/>
+ </xsl:when>
+ <xsl:when test="$p2 = 'Feb' or $p2 = 'February'">
+ <xsl:number value="$p3" format="0001"/>
+ <xsl:text>-02-</xsl:text>
+ <xsl:number value="$p1" format="01"/>
+ </xsl:when>
+ <xsl:when test="$p2 = 'Mar' or $p2 = 'March'">
+ <xsl:number value="$p3" format="0001"/>
+ <xsl:text>-03-</xsl:text>
+ <xsl:number value="$p1" format="01"/>
+ </xsl:when>
+ <xsl:when test="$p2 = 'Apr' or $p2 = 'April'">
+ <xsl:number value="$p3" format="0001"/>
+ <xsl:text>-04-</xsl:text>
+ <xsl:number value="$p1" format="01"/>
+ </xsl:when>
+ <xsl:when test="$p2 = 'May'">
+ <xsl:number value="$p3" format="0001"/>
+ <xsl:text>-05-</xsl:text>
+ <xsl:number value="$p1" format="01"/>
+ </xsl:when>
+ <xsl:when test="$p2 = 'Jun' or $p2 = 'June'">
+ <xsl:number value="$p3" format="0001"/>
+ <xsl:text>-06-</xsl:text>
+ <xsl:number value="$p1" format="01"/>
+ </xsl:when>
+ <xsl:when test="$p2 = 'Jul' or $p2 = 'July'">
+ <xsl:number value="$p3" format="0001"/>
+ <xsl:text>-07-</xsl:text>
+ <xsl:number value="$p1" format="01"/>
+ </xsl:when>
+ <xsl:when test="$p2 = 'Aug' or $p2 = 'August'">
+ <xsl:number value="$p3" format="0001"/>
+ <xsl:text>-08-</xsl:text>
+ <xsl:number value="$p1" format="01"/>
+ </xsl:when>
+ <xsl:when test="$p2 = 'Sep' or $p2 = 'September'">
+ <xsl:number value="$p3" format="0001"/>
+ <xsl:text>-09-</xsl:text>
+ <xsl:number value="$p1" format="01"/>
+ </xsl:when>
+ <xsl:when test="$p2 = 'Oct' or $p2 = 'October'">
+ <xsl:number value="$p3" format="0001"/>
+ <xsl:text>-10-</xsl:text>
+ <xsl:number value="$p1" format="01"/>
+ </xsl:when>
+ <xsl:when test="$p2 = 'Nov' or $p2 = 'November'">
+ <xsl:number value="$p3" format="0001"/>
+ <xsl:text>-11-</xsl:text>
+ <xsl:number value="$p1" format="01"/>
+ </xsl:when>
+ <xsl:when test="$p2 = 'Dec' or $p2 = 'December'">
+ <xsl:number value="$p3" format="0001"/>
+ <xsl:text>-12-</xsl:text>
+ <xsl:number value="$p1" format="01"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:when test="string($p2+1) != 'NaN' and string($p3+1) != 'NaN'">
+ <xsl:choose>
+ <xsl:when test="$p1 = 'Jan' or $p1 = 'January'">
+ <xsl:number value="$p3" format="0001"/>
+ <xsl:text>-01-</xsl:text>
+ <xsl:number value="$p2" format="01"/>
+ </xsl:when>
+ <xsl:when test="$p1 = 'Feb' or $p1 = 'February'">
+ <xsl:number value="$p3" format="0001"/>
+ <xsl:text>-02-</xsl:text>
+ <xsl:number value="$p2" format="01"/>
+ </xsl:when>
+ <xsl:when test="$p1 = 'Mar' or $p1 = 'March'">
+ <xsl:number value="$p3" format="0001"/>
+ <xsl:text>-03-</xsl:text>
+ <xsl:number value="$p2" format="01"/>
+ </xsl:when>
+ <xsl:when test="$p1 = 'Apr' or $p1 = 'April'">
+ <xsl:number value="$p3" format="0001"/>
+ <xsl:text>-04-</xsl:text>
+ <xsl:number value="$p2" format="01"/>
+ </xsl:when>
+ <xsl:when test="$p1 = 'May'">
+ <xsl:number value="$p3" format="0001"/>
+ <xsl:text>-05-</xsl:text>
+ <xsl:number value="$p2" format="01"/>
+ </xsl:when>
+ <xsl:when test="$p1 = 'Jun' or $p1 = 'June'">
+ <xsl:number value="$p3" format="0001"/>
+ <xsl:text>-06-</xsl:text>
+ <xsl:number value="$p2" format="01"/>
+ </xsl:when>
+ <xsl:when test="$p1 = 'Jul' or $p1 = 'July'">
+ <xsl:number value="$p3" format="0001"/>
+ <xsl:text>-07-</xsl:text>
+ <xsl:number value="$p2" format="01"/>
+ </xsl:when>
+ <xsl:when test="$p1 = 'Aug' or $p1 = 'August'">
+ <xsl:number value="$p3" format="0001"/>
+ <xsl:text>-08-</xsl:text>
+ <xsl:number value="$p2" format="01"/>
+ </xsl:when>
+ <xsl:when test="$p1 = 'Sep' or $p1 = 'September'">
+ <xsl:number value="$p3" format="0001"/>
+ <xsl:text>-09-</xsl:text>
+ <xsl:number value="$p2" format="01"/>
+ </xsl:when>
+ <xsl:when test="$p1 = 'Oct' or $p1 = 'October'">
+ <xsl:number value="$p3" format="0001"/>
+ <xsl:text>-10-</xsl:text>
+ <xsl:number value="$p2" format="01"/>
+ </xsl:when>
+ <xsl:when test="$p1 = 'Nov' or $p1 = 'November'">
+ <xsl:number value="$p3" format="0001"/>
+ <xsl:text>-11-</xsl:text>
+ <xsl:number value="$p2" format="01"/>
+ </xsl:when>
+ <xsl:when test="$p1 = 'Dec' or $p1 = 'December'">
+ <xsl:number value="$p3" format="0001"/>
+ <xsl:text>-12-</xsl:text>
+ <xsl:number value="$p2" format="01"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="normalize-space($date) != normalize-space(.)">
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Converted </xsl:text>
+ <xsl:value-of select="normalize-space(.)"/>
+ <xsl:text> into </xsl:text>
+ <xsl:value-of select="$date"/>
+ <xsl:text> for </xsl:text>
+ <xsl:value-of select="name(.)"/>
+ </xsl:with-param>
+ </xsl:call-template>
+
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:value-of select="$date"/>
+ </xsl:copy>
+ </xsl:when>
+
+ <xsl:when test="$defaultDate != ''">
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Unparseable date: </xsl:text>
+ <xsl:value-of select="normalize-space(.)"/>
+ <xsl:text> in </xsl:text>
+ <xsl:value-of select="name(.)"/>
+ <xsl:text> (Using default: </xsl:text>
+ <xsl:value-of select="$defaultDate"/>
+ <xsl:text>)</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:copy-of select="$defaultDate"/>
+ <xsl:comment>
+ <xsl:value-of select="."/>
+ </xsl:comment>
+ </xsl:copy>
+ </xsl:when>
+
+ <xsl:otherwise>
+ <!-- these don't really matter anymore
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Unparseable date: </xsl:text>
+ <xsl:value-of select="normalize-space(.)"/>
+ <xsl:text> in </xsl:text>
+ <xsl:value-of select="name(.)"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ -->
+ <xsl:copy>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="title|subtitle|titleabbrev" priority="300">
+ <!-- nop -->
+</xsl:template>
+
+<xsl:template match="abstract" priority="300">
+ <xsl:if test="not(contains(name(parent::*),'info'))">
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Check abstract; moved into info correctly?</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="indexterm">
+ <!-- don't copy the defaulted significance='normal' attribute -->
+ <indexterm>
+ <xsl:call-template name="copy.attributes">
+ <xsl:with-param name="suppress">
+ <xsl:if test="@significance = 'normal'">significance</xsl:if>
+ </xsl:with-param>
+ </xsl:call-template>
+ <xsl:apply-templates/>
+ </indexterm>
+</xsl:template>
+
+<xsl:template match="ackno" priority="200">
+ <acknowledgements>
+ <xsl:copy-of select="@*"/>
+ <para>
+ <xsl:apply-templates/>
+ </para>
+ </acknowledgements>
+</xsl:template>
+
+<xsl:template match="lot|lotentry|tocback|tocchap|tocfront|toclevel1|
+ toclevel2|toclevel3|toclevel4|toclevel5|tocpart" priority="200">
+ <tocdiv>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates/>
+ </tocdiv>
+</xsl:template>
+
+<xsl:template match="action" priority="200">
+ <phrase remap="action">
+ <xsl:call-template name="copy.attributes"/>
+ <xsl:apply-templates/>
+ </phrase>
+</xsl:template>
+
+<xsl:template match="beginpage" priority="200">
+ <xsl:comment> beginpage pagenum=<xsl:value-of select="@pagenum"/> </xsl:comment>
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Replacing beginpage with comment</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+</xsl:template>
+
+<xsl:template match="structname|structfield" priority="200">
+ <varname remap="{local-name(.)}">
+ <xsl:call-template name="copy.attributes"/>
+ <xsl:apply-templates/>
+ </varname>
+</xsl:template>
+
+<!-- ====================================================================== -->
+
+<!-- 6 Feb 2008, ndw changed mode=copy so that it only copies the first level,
+ then it switches back to "normal" mode so that other rewriting templates
+ catch embedded fixes -->
+
+<!--
+<xsl:template match="ulink" priority="200" mode="copy">
+ <xsl:choose>
+ <xsl:when test="node()">
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Converting ulink to phrase.</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+
+ <phrase xlink:href="{@url}">
+ <xsl:call-template name="copy.attributes">
+ <xsl:with-param name="suppress" select="'url'"/>
+ </xsl:call-template>
+ <xsl:apply-templates/>
+ </phrase>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Converting ulink to uri.</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+
+ <uri xlink:href="{@url}">
+ <xsl:call-template name="copy.attributes">
+ <xsl:with-param name="suppress" select="'url'"/>
+ </xsl:call-template>
+ <xsl:value-of select="@url"/>
+ </uri>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="sgmltag" priority="200" mode="copy">
+ <tag>
+ <xsl:call-template name="copy.attributes"/>
+ <xsl:apply-templates/>
+ </tag>
+</xsl:template>
+-->
+
+<xsl:template match="*" mode="copy">
+ <xsl:copy>
+ <xsl:call-template name="copy.attributes"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+</xsl:template>
+
+<!--
+<xsl:template match="comment()|processing-instruction()|text()" mode="copy">
+ <xsl:copy/>
+</xsl:template>
+-->
+
+<!-- ====================================================================== -->
+
+<xsl:template match="*">
+ <xsl:copy>
+ <xsl:call-template name="copy.attributes"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+</xsl:template>
+
+<xsl:template match="comment()|processing-instruction()|text()">
+ <xsl:copy/>
+</xsl:template>
+
+<!-- ====================================================================== -->
+
+<xsl:template name="copy.attributes">
+ <xsl:param name="src" select="."/>
+ <xsl:param name="suppress" select="''"/>
+
+ <xsl:for-each select="$src/@*">
+ <xsl:choose>
+ <xsl:when test="local-name(.) = 'moreinfo'">
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Discarding moreinfo on </xsl:text>
+ <xsl:value-of select="local-name($src)"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="local-name(.) = 'lang'">
+ <xsl:attribute name="xml:lang">
+ <xsl:value-of select="."/>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:when test="local-name(.) = 'id'">
+ <xsl:attribute name="xml:id">
+ <xsl:value-of select="."/>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:when test="$suppress = local-name(.)"/>
+ <xsl:when test="local-name(.) = 'float'">
+ <xsl:choose>
+ <xsl:when test=". = '1'">
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Discarding float on </xsl:text>
+ <xsl:value-of select="local-name($src)"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ <xsl:if test="not($src/@floatstyle)">
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Adding floatstyle='normal' on </xsl:text>
+ <xsl:value-of select="local-name($src)"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ <xsl:attribute name="floatstyle">
+ <xsl:text>normal</xsl:text>
+ </xsl:attribute>
+ </xsl:if>
+ </xsl:when>
+ <xsl:when test=". = '0'">
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Discarding float on </xsl:text>
+ <xsl:value-of select="local-name($src)"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Discarding float on </xsl:text>
+ <xsl:value-of select="local-name($src)"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ <xsl:if test="not($src/@floatstyle)">
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Adding floatstyle='</xsl:text>
+ <xsl:value-of select="."/>
+ <xsl:text>' on </xsl:text>
+ <xsl:value-of select="local-name($src)"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ <xsl:attribute name="floatstyle">
+ <xsl:value-of select="."/>
+ </xsl:attribute>
+ </xsl:if>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:when test="local-name(.) = 'entityref'">
+ <xsl:attribute name="fileref">
+ <xsl:value-of select="unparsed-entity-uri(@entityref)"/>
+ </xsl:attribute>
+ </xsl:when>
+
+ <xsl:when test="local-name($src) = 'simplemsgentry'
+ and local-name(.) = 'audience'">
+ <xsl:attribute name="msgaud">
+ <xsl:value-of select="."/>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:when test="local-name($src) = 'simplemsgentry'
+ and local-name(.) = 'origin'">
+ <xsl:attribute name="msgorig">
+ <xsl:value-of select="."/>
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:when test="local-name($src) = 'simplemsgentry'
+ and local-name(.) = 'level'">
+ <xsl:attribute name="msglevel">
+ <xsl:value-of select="."/>
+ </xsl:attribute>
+ </xsl:when>
+
+ <!-- * for upgrading XSL litprog params documentation -->
+ <xsl:when test="local-name($src) = 'refmiscinfo'
+ and local-name(.) = 'role'
+ and . = 'type'
+ ">
+ <xsl:call-template name="emit-message">
+ <xsl:with-param name="message">
+ <xsl:text>Converting refmiscinfo@role=type to </xsl:text>
+ <xsl:text>@class=other,otherclass=type</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+ <xsl:attribute name="class">other</xsl:attribute>
+ <xsl:attribute name="otherclass">type</xsl:attribute>
+ </xsl:when>
+
+ <xsl:otherwise>
+ <xsl:copy/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+</xsl:template>
+
+<!-- ====================================================================== -->
+
+<xsl:template match="*" mode="addNS">
+ <xsl:choose>
+ <xsl:when test="namespace-uri(.) = ''">
+ <xsl:element name="{local-name(.)}"
+ namespace="http://docbook.org/ns/docbook">
+ <xsl:if test="not(parent::*)">
+ <xsl:attribute name="version">5.0</xsl:attribute>
+ </xsl:if>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates mode="addNS"/>
+ </xsl:element>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:copy>
+ <xsl:if test="not(parent::*)">
+ <xsl:attribute name="version">5.0</xsl:attribute>
+ </xsl:if>
+ <xsl:copy-of select="@*"/>
+ <xsl:apply-templates mode="addNS"/>
+ </xsl:copy>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="comment()|processing-instruction()|text()" mode="addNS">
+ <xsl:copy/>
+</xsl:template>
+
+<!-- ====================================================================== -->
+
+<xsl:template name="emit-message">
+ <xsl:param name="message"/>
+ <xsl:message>
+ <xsl:value-of select="$message"/>
+ <xsl:text> (</xsl:text>
+ <xsl:value-of select="$rootid"/>
+ <xsl:text>)</xsl:text>
+ </xsl:message>
+</xsl:template>
+
+</xsl:stylesheet>
--- /dev/null
+<dbk = 'http://docbook.org/ns/docbook'>
+<argeodbk = 'http://www.argeo.org/ns/argeodbk'>
+<xlink = 'http://www.w3.org/1999/xlink'>
+//<xs = 'http://www.w3.org/2001/XMLSchema'>
+
+[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)
+
+
--- /dev/null
+<dbk = 'http://docbook.org/ns/docbook'>
+<argeodbk = 'http://www.argeo.org/ns/argeodbk'>
+<xlink = 'http://www.w3.org/1999/xlink'>
+
+[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)
+
+
--- /dev/null
+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.cms.jcr.CmsJcrUtils;
+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<String, String> properties) throws RepositoryException {
+ Session adminSession = CmsJcrUtils.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<String, String> 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();
+ }
+
+}
--- /dev/null
+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<String, String> 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() {
+ }
+}
--- /dev/null
+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<String> shapes = new ArrayList<>();
+ for (JsonNode shape : coord) {
+ StringBuffer sb = new StringBuffer();
+ sb.append("<polyline style=\"stroke-width:0.00000003;stroke:#000000;\" points=\"");
+ for (JsonNode latlng : shape) {
+ double lat = latlng.get(0).asDouble();
+ double y = lat * ratio;
+ if (y < minY)
+ minY = y;
+ if (y > 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("</polyline>\n");
+ shapes.add(sb.toString());
+ }
+
+ double width = maxX - minX;
+ double height = maxY - minY;
+ out.write("<svg xmlns=\"http://www.w3.org/2000/svg\"\n");
+ out.write(" width=\"" + (int) (width * 1000) + "\"\n");
+ out.write(" height=\"" + (int) (height * 1000) + "\"\n");
+ out.write(" viewBox=\"" + minX + "," + minY + "," + width + "," + height + "\"\n");
+ out.write(">\n");
+ for (String shape : shapes) {
+ out.write(shape);
+ out.write("\n");
+ }
+ out.write("</svg>");
+ } catch (IOException e) {
+ throw new RuntimeException("Cannot convert " + source + " to " + target, e);
+ }
+ }
+
+}
--- /dev/null
+package org.argeo.suite;
+
+import java.util.Map;
+
+import org.argeo.api.cms.CmsLog;
+
+/**
+ * A container for an object whose relevance can be ranked. Typically used in an
+ * OSGi context with the service.ranking property.
+ */
+public class RankedObject<T> {
+ private final static CmsLog log = CmsLog.getLog(RankedObject.class);
+
+ private final static String SERVICE_RANKING = "service.ranking";
+// private final static String SERVICE_ID = "service.id";
+
+ private T object;
+ private Map<String, Object> properties;
+ private final Long rank;
+
+ public RankedObject(T object, Map<String, Object> properties) {
+ this(object, properties, extractRanking(properties));
+ }
+
+ public RankedObject(T object, Map<String, Object> properties, Long rank) {
+ super();
+ this.object = object;
+ this.properties = properties;
+ this.rank = rank;
+ }
+
+ private static Long extractRanking(Map<String, Object> 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<String, Object> 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 <K, T> RankedObject<T> putIfHigherRank(Map<K, RankedObject<T>> map, K key, T object,
+ Map<String, Object> properties) {
+ RankedObject<T> rankedObject = new RankedObject<>(object, properties);
+ if (!map.containsKey(key)) {
+ map.put(key, rankedObject);
+ if (log.isTraceEnabled())
+ log.trace(
+ "Added " + key + " as " + object.getClass().getName() + " with rank " + rankedObject.getRank());
+ return rankedObject;
+ } else {
+ RankedObject<T> current = map.get(key);
+ if (current.getRank() <= rankedObject.getRank()) {
+ map.put(key, rankedObject);
+ if (log.isTraceEnabled())
+ log.trace("Replaced " + key + " by " + object.getClass().getName() + " with rank "
+ + rankedObject.getRank());
+ return rankedObject;
+ } else {
+ return current;
+ }
+ }
+
+ }
+
+}
--- /dev/null
+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<RankingKey> {
+ 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<String, Object> 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);
+ }
+}
--- /dev/null
+package org.argeo.suite;
+
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.util.naming.Distinguished;
+import org.argeo.util.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(CmsConstants.ROLES_BASEDN).toString();
+ }
+}
--- /dev/null
+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.cms.CmsSession;
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.entity.EntityType;
+import org.argeo.jackrabbit.security.JackrabbitSecurityUtils;
+import org.argeo.jcr.JcrException;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.util.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(), CmsConstants.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<String> extractRoles(String[] semiColArr) {
+ Set<String> 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;
+ }
+
+}
--- /dev/null
+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.argeo.api.cms.CmsLog;
+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 CmsLog log = CmsLog.getLog(AbstractMaintenanceService.class);
+
+ protected List<String> getTypologies() {
+ return new ArrayList<>();
+ }
+
+ protected String getTypologiesLoadBase() {
+ return "/sys/terms";
+ }
+
+ protected void loadTypologies(Node customBaseNode) throws RepositoryException, IOException {
+ List<String> 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;
+ }
+ }
+
+}
--- /dev/null
+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.cms.CmsConstants;
+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(), CmsConstants.ROLE_USER_ADMIN,
+ Privilege.JCR_ALL);
+ //JcrUtils.addPrivilege(adminSession, "/", SuiteRole.coworker.dn(), Privilege.JCR_READ);
+ }
+
+}
--- /dev/null
+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<SuiteTerm> 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<SuiteTerm> getSubTerms() {
+ return subTerms;
+ }
+
+ @Override
+ public SuiteTerm getParentTerm() {
+ return parentTerm;
+ }
+
+}
--- /dev/null
+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.cms.CmsConstants;
+import org.argeo.cms.jcr.CmsJcrUtils;
+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<String, SuiteTerm> terms = new HashMap<>();
+ private final Map<String, SuiteTypology> typologies = new HashMap<>();
+
+ // JCR
+ private Repository repository;
+ private Session adminSession;
+
+ public void init() {
+ adminSession = CmsJcrUtils.openDataAdminSession(repository, CmsConstants.SYS_WORKSPACE);
+ }
+
+ @Override
+ public List<Term> listAllTerms(String typology) {
+ List<Term> 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;
+ }
+
+}
--- /dev/null
+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<SuiteTerm> 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<SuiteTerm> getSubTerms() {
+ return subTerms;
+ }
+
+ public List<SuiteTerm> getAllTerms() {
+ if (isFlat)
+ return subTerms;
+ else {
+ List<SuiteTerm> terms = new ArrayList<>();
+ for (SuiteTerm subTerm : subTerms) {
+ terms.add(subTerm);
+ collectSubTerms(terms, subTerm);
+ }
+ return terms;
+ }
+ }
+
+ public Term findTermByName(String name) {
+ List<SuiteTerm> 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<SuiteTerm> collected) {
+ if (term.getName().equals(name)) {
+ collected.add(term);
+ }
+ for (SuiteTerm subTerm : term.getSubTerms()) {
+ collectTermsByName(subTerm, name, collected);
+ }
+ }
+
+ private void collectSubTerms(List<SuiteTerm> terms, SuiteTerm term) {
+ for (SuiteTerm subTerm : term.getSubTerms()) {
+ terms.add(subTerm);
+ collectSubTerms(terms, subTerm);
+ }
+ }
+
+}
--- /dev/null
+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<Tbl> tables = new ArrayList<>();
+ protected List<String> text = new ArrayList<>();
+ protected Map<String, byte[]> media = new TreeMap<>();
+ private Set<String> mediaDigests = new HashSet<>();
+
+ protected void processTextItem(List<String> 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<Tr> 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<Tr> 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<Tc> 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<Tc> 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<String> getText() {
+ return text;
+ }
+
+ public List<Tbl> getTables() {
+ return tables;
+ }
+
+ public Map<String, byte[]> 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");
+ }
+ }
+
+}
--- /dev/null
+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.jackrabbit.util.ISO9075;
+import org.argeo.api.cms.CmsLog;
+
+/** Ease XPath generation for JCR requests */
+public class XPathUtils {
+ private final static CmsLog log = CmsLog.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() {
+
+ }
+}
--- /dev/null
+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<String> 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<GeonamesAdm> upperLevels = new ArrayList<>();
+
+ private List<String> row;
+
+ /** Initialise from a row in the main Geonames table. */
+ public GeonamesAdm(List<String> 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<Long, GeonamesAdm> 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<String, String> transform) {
+ if (transform != null)
+ return transform.apply(name);
+ else
+ return name;
+
+ }
+
+ public String getAsciiName() {
+ return asciiName;
+ }
+
+ public List<String> 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<String> 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<GeonamesAdm> 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 + ")";
+ }
+
+}
--- /dev/null
+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<Long, GeonamesAdm> geonamesAdms = new HashMap<>();
+
+ /** Loads the data. */
+ public void parse(InputStream in) {
+ Map<String, Long> countryGeonameIds = new HashMap<>();
+ Map<String, Long> admin1GeonameIds = new HashMap<>();
+ CsvParser csvParser = new CsvParser() {
+
+ @Override
+ protected void processLine(Integer lineNumber, List<String> header, List<String> 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<Long, GeonamesAdm> 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<String> header, List<String> 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);
+ }
+ }
+
+}
--- /dev/null
+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<String, String> 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;
+ }
+
+}
--- /dev/null
+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();
+}
--- /dev/null
+package org.argeo.support.odk;
+
+/** Names related to ODK. */
+public interface OdkNames {
+
+ public final static String H_HTML = "h:html";
+}
--- /dev/null
+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.argeo.api.cms.CmsLog;
+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 CmsLog log = CmsLog.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() {
+
+ }
+
+}
--- /dev/null
+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";
+ }
+
+}
--- /dev/null
+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";
+ }
+
+}
--- /dev/null
+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";
+ }
+
+}
--- /dev/null
+<jr = "http://openrosa.org/javarosa">
+<orx = "http://openrosa.org/xforms">
+<orxList = "http://openrosa.org/xforms/xformsList">
+<orxManifest = "http://openrosa.org/xforms/xformsManifest">
+<odk = "http://www.opendatakit.org/xforms">
+
+
+[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) *
+
+
--- /dev/null
+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;
+}
--- /dev/null
+<xforms = "http://www.w3.org/2002/xforms">
+
+[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 *
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
--- /dev/null
+/bin/
+/target/
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.argeo.app.servlet.odk</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ds.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
--- /dev/null
+/MANIFEST.MF
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="ODK Form List Servlet">
+ <implementation class="org.argeo.support.odk.servlet.OdkFormListServlet"/>
+ <service>
+ <provide interface="javax.servlet.Servlet"/>
+ </service>
+ <property name="osgi.http.whiteboard.servlet.pattern" type="String" value="/formList/*"/>
+ <property name="osgi.http.whiteboard.context.select" type="String" value="(osgi.http.whiteboard.context.name=odkServletContext)"/>
+ <reference bind="addForm" cardinality="0..n" interface="org.argeo.support.odk.OdkForm" name="OdkForm" policy="dynamic" unbind="removeForm"/>
+ <reference bind="setRepository" cardinality="1..1" interface="javax.jcr.Repository" name="Repository" policy="static" target="(cn=odk)"/>
+</scr:component>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="ODK Form Servlet">
+ <implementation class="org.argeo.support.odk.servlet.OdkFormServlet"/>
+ <service>
+ <provide interface="javax.servlet.Servlet"/>
+ </service>
+ <property name="osgi.http.whiteboard.servlet.pattern" type="String" value="/form/*"/>
+ <property name="osgi.http.whiteboard.context.select" type="String" value="(osgi.http.whiteboard.context.name=odkServletContext)"/>
+ <reference bind="addForm" cardinality="0..n" interface="org.argeo.support.odk.OdkForm" name="OdkForm" policy="dynamic" unbind="removeForm"/>
+ <reference bind="setRepository" cardinality="1..1" interface="javax.jcr.Repository" name="Repository" policy="static" target="(cn=odk)"/>
+</scr:component>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="ODK Manifest Servlet">
+ <implementation class="org.argeo.support.odk.servlet.OdkManifestServlet"/>
+ <service>
+ <provide interface="javax.servlet.Servlet"/>
+ </service>
+ <property name="osgi.http.whiteboard.servlet.pattern" type="String" value="/formManifest/*"/>
+ <property name="osgi.http.whiteboard.context.select" type="String" value="(osgi.http.whiteboard.context.name=odkServletContext)"/>
+ <reference bind="setRepository" cardinality="1..1" interface="javax.jcr.Repository" name="Repository" policy="static" target="(cn=odk)"/>
+</scr:component>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy" name="ODK Servlet Context">
+ <implementation class="org.argeo.support.odk.servlet.OdkServletContext"/>
+ <service>
+ <provide interface="org.osgi.service.http.context.ServletContextHelper"/>
+ </service>
+ <property name="osgi.http.whiteboard.context.name" type="String" value="odkServletContext"/>
+ <property name="osgi.http.whiteboard.context.path" type="String" value="/api/odk"/>
+</scr:component>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="ODK Submission Servlet">
+ <implementation class="org.argeo.support.odk.servlet.OdkSubmissionServlet"/>
+ <service>
+ <provide interface="javax.servlet.Servlet"/>
+ </service>
+ <property name="osgi.http.whiteboard.servlet.pattern" type="String" value="/submission"/>
+ <property name="osgi.http.whiteboard.context.select" type="String" value="(osgi.http.whiteboard.context.name=odkServletContext)"/>
+ <property name="osgi.http.whiteboard.servlet.multipart.enabled" type="String" value="true"/>
+ <reference bind="setRepository" cardinality="1..1" interface="javax.jcr.Repository" name="Repository" policy="static" target="(cn=odk)"/>
+ <reference bind="addSubmissionListener" cardinality="0..n" interface="org.argeo.support.xforms.FormSubmissionListener" name="FormSubmissionListener" policy="dynamic" unbind="removeSubmissionListener"/>
+</scr:component>
--- /dev/null
+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,\
+javax.jcr.nodetype,\
+*
--- /dev/null
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ OSGI-INF/,\
+ OSGI-INF/odkServletContext.xml
+source.. = src/
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.argeo.suite</groupId>
+ <artifactId>argeo-suite</artifactId>
+ <version>2.3-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <artifactId>org.argeo.app.servlet.odk</artifactId>
+ <name>ODK Servlets</name>
+ <packaging>jar</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>org.argeo.suite</groupId>
+ <artifactId>org.argeo.app.core</artifactId>
+ <version>2.3-SNAPSHOT</version>
+ </dependency>
+
+ <!-- Argeo Commons -->
+ <dependency>
+ <groupId>org.argeo.commons</groupId>
+ <artifactId>org.argeo.cms.servlet</artifactId>
+ <version>${version.argeo-commons}</version>
+ </dependency>
+ </dependencies>
+</project>
--- /dev/null
+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.argeo.api.cms.CmsConstants;
+import org.argeo.api.cms.CmsLog;
+import org.argeo.cms.auth.RemoteAuthUtils;
+import org.argeo.cms.servlet.ServletHttpRequest;
+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 CmsLog log = CmsLog.getLog(OdkFormListServlet.class);
+
+ private Set<OdkForm> 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 = RemoteAuthUtils.doAs(() -> Jcr.login(repository, CmsConstants.SYS_WORKSPACE),
+ new ServletHttpRequest(req));
+// session = NodeUtils.openDataAdminSession(repository, NodeConstants.SYS_WORKSPACE);
+ Writer writer = resp.getWriter();
+ writer.append("<?xml version='1.0' encoding='UTF-8' ?>");
+ writer.append("<xforms xmlns=\"http://openrosa.org/xforms/xformsList\">");
+ 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("<xform>");
+ sb.append("<formID>" + node.getProperty(OrxListName.formID.get()).getString() + "</formID>");
+ sb.append("<name>" + Jcr.getTitle(node) + "</name>");
+ sb.append("<version>" + node.getProperty(OrxListName.version.get()).getString() + "</version>");
+ sb.append("<hash>md5:" + JcrxApi.getChecksum(node, JcrxApi.MD5) + "</hash>");
+ if (node.hasProperty(Property.JCR_DESCRIPTION))
+ sb.append("<name>" + node.getProperty(Property.JCR_DESCRIPTION).getString() + "</name>");
+ sb.append("<downloadUrl>" + protocol + "://" + serverName
+ + (serverPort == 80 || serverPort == 443 ? "" : ":" + serverPort) + "/api/odk/form"
+ + node.getPath() + "</downloadUrl>");
+ if (node.hasNode(OrxManifestName.manifest.name())) {
+ sb.append("<manifestUrl>" + protocol + "://" + serverName
+ + (serverPort == 80 || serverPort == 443 ? "" : ":" + serverPort)
+ + "/api/odk/formManifest" + node.getNode(OrxManifestName.manifest.name()).getPath()
+ + "</manifestUrl>");
+ }
+ sb.append("</xform>");
+ } else if (node.isNodeType(EntityType.formSet.get())) {
+ sb.append("<xforms-group>");
+ sb.append("<groupId>" + node.getPath() + "</groupId>");
+ sb.append("<name>" + node.getProperty(Property.JCR_TITLE).getString() + "</name>");
+ sb.append("<listUrl>" + protocol + "://" + serverName
+ + (serverPort == 80 || serverPort == 443 ? "" : ":" + serverPort) + "/api/odk/formList"
+ + node.getPath() + "</listUrl>");
+ sb.append("</xforms-group>");
+ }
+ 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("<xform>");
+ sb.append("<formID>" + form.getFormId() + "</formID>");
+ sb.append("<name>" + form.getName() + "</name>");
+ sb.append("<version>" + form.getVersion() + "</version>");
+ sb.append("<hash>" + form.getHash(null) + "</hash>");
+ sb.append("<descriptionText>" + form.getDescription() + "</descriptionText>");
+ sb.append("<downloadUrl>" + protocol + "://" + serverName
+ + (serverPort == 80 || serverPort == 443 ? "" : ":" + serverPort) + "/api/odk/form/"
+ + form.getFileName() + "</downloadUrl>");
+ sb.append("</xform>");
+ String str = sb.toString();
+ if (log.isDebugEnabled())
+ log.debug(str);
+ writer.append(str);
+ }
+ }
+ writer.append("</xforms>");
+ }
+
+ public void addForm(OdkForm odkForm) {
+ odkForms.add(odkForm);
+ }
+
+ public void removeForm(OdkForm odkForm) {
+ odkForms.remove(odkForm);
+ }
+
+ public void setRepository(Repository repository) {
+ this.repository = repository;
+ }
+
+}
--- /dev/null
+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.auth.RemoteAuthUtils;
+import org.argeo.cms.servlet.ServletHttpRequest;
+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<String, OdkForm> 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 = RemoteAuthUtils.doAs(() -> Jcr.login(repository, null), new ServletHttpRequest(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;
+ }
+
+}
--- /dev/null
+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.auth.RemoteAuthUtils;
+import org.argeo.cms.servlet.ServletHttpRequest;
+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 = RemoteAuthUtils.doAs(() -> Jcr.login(repository, null), new ServletHttpRequest(req));
+
+ try {
+ Node node = session.getNode(pathInfo);
+ if (node.isNodeType(OrxManifestName.manifest.get())) {
+ resp.setContentType(EntityMimeType.XML.toHttpContentType());
+ Writer writer = resp.getWriter();
+ writer.append("<?xml version='1.0' encoding='UTF-8' ?>");
+ writer.append("<manifest xmlns=\"http://openrosa.org/xforms/xformsManifest\">");
+ 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("<mediaFile>");
+ writer.append("<filename>");
+ // Work around bug in ODK Collect not supporting paths
+ // writer.append(target.getPath().substring(1) + ".xml");
+ writer.append(target.getIdentifier() + "." + mimeType.getDefaultExtension());
+ writer.append("</filename>");
+
+ 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("<hash>");
+ writer.append("md5sum:" + DigestUtils.encodeHexString(out.getMessageDigest().digest()));
+ writer.append("</hash>");
+ }
+
+// try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
+// session.exportDocumentView(target.getPath(), out, true, false);
+// String fileCsum = DigestUtils.digest(DigestUtils.MD5, out.toByteArray());
+// writer.append("<hash>");
+// writer.append("md5sum:" + fileCsum);
+// writer.append("</hash>");
+// }
+ writer.append("<downloadUrl>" + protocol + "://" + serverName
+ + (serverPort == 80 || serverPort == 443 ? "" : ":" + serverPort)
+ + "/api/odk/formManifest" + file.getPath() + "</downloadUrl>");
+ }
+ writer.append("</mediaFile>");
+ }
+ }
+
+ writer.append("</manifest>");
+ } 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<String> 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;
+ }
+
+}
--- /dev/null
+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());
+
+ }
+
+}
--- /dev/null
+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.argeo.api.cms.CmsSession;
+import org.argeo.api.cms.CmsLog;
+import org.argeo.cms.auth.RemoteAuthRequest;
+import org.argeo.cms.auth.RemoteAuthUtils;
+import org.argeo.cms.jcr.CmsJcrUtils;
+import org.argeo.cms.servlet.ServletHttpRequest;
+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 CmsLog log = CmsLog.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<FormSubmissionListener> 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);
+
+ RemoteAuthRequest request = new ServletHttpRequest(req);
+ Session session = RemoteAuthUtils.doAs(() -> Jcr.login(repository, null), request);
+
+ try {
+// Node submissions = JcrUtils.mkdirs(session,
+// "/" + EntityType.form.get() + "/" + EntityNames.SUBMISSIONS_BASE);
+ CmsSession cmsSession = RemoteAuthUtils.getCmsSession(request);
+
+ ClassLoader currentContextCl = Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(RemoteAuthUtils.class.getClassLoader());
+ Session adminSession = null;
+ try {
+ // TODO centralise at a deeper level
+ adminSession = CmsJcrUtils.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("<OpenRosaResponse xmlns=\"http://openrosa.org/http/response\">"
+ + "<message>Form Received!</message>" + "</OpenRosaResponse>");
+
+ }
+
+ 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);
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
--- /dev/null
+/bin/
+/target/
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.argeo.app.servlet.publish</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ds.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
--- /dev/null
+/MANIFEST.MF
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="DocBook 4 Converter">
+ <implementation class="org.argeo.docbook.Dbk4Converter"/>
+ <service>
+ <provide interface="org.argeo.docbook.Dbk4Converter"/>
+ </service>
+</scr:component>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="DocBook Servlet">
+ <implementation class="org.argeo.publishing.servlet.DbkServlet"/>
+ <service>
+ <provide interface="javax.servlet.Servlet"/>
+ </service>
+ <property name="osgi.http.whiteboard.servlet.pattern" type="String" value="/dbk/*"/>
+ <property name="osgi.http.whiteboard.context.select" type="String" value="(osgi.http.whiteboard.context.name=htmlServletContext)"/>"/>
+ <reference bind="setRepository" cardinality="1..1" interface="javax.jcr.Repository" name="Repository" policy="static" target="(cn=ego)"/>
+ <reference bind="addTheme" cardinality="0..n" interface="org.argeo.cms.ui.CmsTheme" name="CmsTheme" policy="dynamic" unbind="removeTheme"/>
+</scr:component>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0">
+ <implementation class="org.argeo.publishing.ui.DocumentUiProvider"/>
+ <service>
+ <provide interface="org.argeo.cms.ui.CmsUiProvider"/>
+ </service>
+ <properties entry="config/documentUiProvider.properties"/>
+</scr:component>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0">
+ <implementation class="org.argeo.publishing.servlet.FontsServlet"/>
+ <service>
+ <provide interface="javax.servlet.Servlet"/>
+ </service>
+ <property name="osgi.http.whiteboard.servlet.pattern" type="String" value="/fonts/*"/>
+ <property name="osgi.http.whiteboard.context.select" type="String" value="(osgi.http.whiteboard.context.name=default)"/>
+ <reference bind="addTheme" cardinality="0..n" interface="org.argeo.cms.ui.CmsTheme" name="CmsTheme" policy="dynamic" unbind="removeTheme"/>
+</scr:component>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy">
+ <implementation class="org.argeo.cms.servlet.CmsServletContext"/>
+ <service>
+ <provide interface="org.osgi.service.http.context.ServletContextHelper"/>
+ </service>
+ <property name="osgi.http.whiteboard.context.name" type="String" value="htmlServletContext"/>
+ <property name="osgi.http.whiteboard.context.path" type="String" value="/html"/>
+</scr:component>
--- /dev/null
+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
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy">
+ <implementation class="org.argeo.suite.ui.DefaultEditionLayer"/>
+ <properties entry="config/wwwLayer.properties"/>
+ <service>
+ <provide interface="org.argeo.suite.ui.SuiteLayer"/>
+ </service>
+ <reference bind="setWorkArea" cardinality="1..1" interface="org.argeo.cms.ui.CmsUiProvider" name="CmsUiProvider" policy="dynamic" target="(service.pid=argeo.publishing.ui.documentUiProvider)"/>
+</scr:component>
--- /dev/null
+Import-Package:\
+org.osgi.service.http.context,\
+javax.jcr.nodetype,\
+org.osgi.service.event,\
+org.argeo.suite.ui,\
+org.eclipse.swt,\
+org.eclipse.jface.viewers,\
+org.osgi.framework,\
+org.apache.xml.serializer,\
+org.eclipse.rap.rwt,\
+org.argeo.entity,\
+*
+
+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
--- /dev/null
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ OSGI-INF/,\
+ OSGI-INF/documentUiProvider.xml,\
+ OSGI-INF/dbk4Converter.xml
+source.. = src/
--- /dev/null
+service.pid=argeo.publishing.ui.documentUiProvider
+
+entity.type=entity:document,nt:file
\ No newline at end of file
--- /dev/null
+service.pid=argeo.publishing.ui.wwwLayer
+
+title=Web
+icon=map
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.argeo.suite</groupId>
+ <artifactId>argeo-suite</artifactId>
+ <version>2.3-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <artifactId>org.argeo.app.servlet.publish</artifactId>
+ <name>Publishing Servlets</name>
+ <packaging>jar</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>org.argeo.suite</groupId>
+ <artifactId>org.argeo.app.core</artifactId>
+ <version>2.3-SNAPSHOT</version>
+ </dependency>
+
+ <!-- Argeo Commons -->
+ <dependency>
+ <groupId>org.argeo.commons</groupId>
+ <artifactId>org.argeo.cms.servlet</artifactId>
+ <version>${version.argeo-commons}</version>
+ </dependency>
+ </dependencies>
+</project>
--- /dev/null
+package org.argeo.publishing.servlet;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Collections;
+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 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.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+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.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.xalan.processor.TransformerFactoryImpl;
+import org.argeo.api.cms.CmsTheme;
+import org.argeo.cms.auth.RemoteAuthUtils;
+import org.argeo.cms.servlet.ServletHttpRequest;
+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.w3c.dom.Document;
+
+/**
+ * A servlet transforming a dbk:* JCR node into HTML, using the DocBook XSL.
+ */
+public class DbkServlet extends HttpServlet {
+ private static final long serialVersionUID = 6906020513498289335L;
+
+ private Repository repository;
+
+ private DocumentBuilderFactory documentBuilderFactory;
+ private TransformerFactory transformerFactory;
+ private Templates docBoookTemplates;
+
+ private Map<String, CmsTheme> themes = Collections.synchronizedMap(new HashMap<>());
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+
+ String pathInfo = req.getPathInfo();
+ if (pathInfo.startsWith("//"))
+ pathInfo = pathInfo.substring(1);
+ String path = URLDecoder.decode(pathInfo, StandardCharsets.UTF_8);
+
+ if (path.toLowerCase().endsWith(".css")) {
+ path = path.substring(1);
+ int firstSlash = path.indexOf('/');
+ String themeId = path.substring(0, firstSlash);
+ String cssPath = path.substring(firstSlash);
+ CmsTheme cmsTheme = themes.get(themeId);
+ if (cmsTheme == null)
+ throw new IllegalArgumentException("Theme " + themeId + " not found.");
+ resp.setContentType("text/css");
+ IOUtils.copy(cmsTheme.getResourceAsStream(cssPath), resp.getOutputStream());
+ return;
+ }
+
+ if (path.toLowerCase().endsWith("/index.html")) {
+ path = path.substring(0, path.length() - "/index.html".length());
+ }
+
+ Session session = null;
+ try {
+ session = RemoteAuthUtils.doAs(() -> Jcr.login(repository, null), new ServletHttpRequest(req));
+ Node node = session.getNode(path);
+
+ if (node.hasNode(DbkType.article.get())) {
+ Node dbkNode = node.getNode(DbkType.article.get());
+ if (DbkUtils.isDbk(dbkNode)) {
+ CmsTheme cmsTheme = null;
+ String themeId = req.getParameter("themeId");
+ if (themeId != null) {
+ cmsTheme = themes.get(themeId);
+ if (cmsTheme == null)
+ throw new IllegalArgumentException("Theme " + themeId + " not found.");
+ }
+
+ // TODO customise DocBook so that it outputs UTF-8
+ // see http://www.sagehill.net/docbookxsl/OutputEncoding.html
+ resp.setContentType("text/html; charset=ISO-8859-1");
+
+ // TODO optimise with pipes, SAX, etc. ?
+ byte[] arr;
+ try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
+ session.exportDocumentView(dbkNode.getPath(), out, true, false);
+ arr = out.toByteArray();
+// System.out.println(new String(arr, StandardCharsets.UTF_8));
+ } catch (RepositoryException e) {
+ throw new JcrException(e);
+ }
+
+ try (InputStream in = new ByteArrayInputStream(arr);
+// ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ) {
+
+ Result xmlOutput = new StreamResult(resp.getOutputStream());
+
+ DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder();
+// Document doc = docBuilder.parse(new File(
+// System.getProperty("user.home") + "/dev/git/gpl/argeo-qa/doc/platform/argeo-platform.dbk.xml"));
+ Document doc = docBuilder.parse(in);
+ Source xmlInput = new DOMSource(doc);
+
+ Transformer transformer = docBoookTemplates.newTransformer();
+
+ // gather CSS
+ if (cmsTheme != null) {
+ StringBuilder sb = new StringBuilder();
+ for (String cssPath : cmsTheme.getWebCssPaths()) {
+ sb.append(req.getContextPath()).append(req.getServletPath()).append('/');
+ sb.append(themeId).append('/').append(cssPath).append(' ');
+ }
+ // FIXME make it more generic
+ sb.append("https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap")
+ .append(' ');
+ sb.append(
+ "https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,300;0,400;0,600;1,400&display=swap")
+ .append(' ');
+ if (sb.length() > 0)
+ transformer.setParameter("html.stylesheet", sb.toString());
+ }
+ transformer.transform(xmlInput, xmlOutput);
+// resp.getOutputStream().write(out.toByteArray());
+ } catch (Exception e) {
+ throw new ServletException("Cannot transform " + path, e);
+ }
+ }
+ } else {
+ if (node.isNodeType(NodeType.NT_FILE)) {// media download etc.
+ String fileNameLowerCase = node.getName().toLowerCase();
+ if (fileNameLowerCase.endsWith(".jpg") || fileNameLowerCase.endsWith(".jpeg")) {
+ resp.setContentType("image/jpeg");
+ } else if (fileNameLowerCase.endsWith(".png")) {
+ resp.setContentType("image/png");
+ } else if (fileNameLowerCase.endsWith(".gif")) {
+ resp.setContentType("image/gif");
+ } else if (fileNameLowerCase.endsWith(".svg")) {
+ resp.setContentType("image/svg+xml");
+ } else {
+ // TODO know more content types...
+ resp.setHeader("Content-Disposition", "attachment; filename=\"" + node.getName() + "\"");
+ }
+ IOUtils.copy(JcrUtils.getFileAsStream(node), resp.getOutputStream());
+ } else {
+ throw new IllegalArgumentException("Unsupported node " + node);
+ }
+ }
+ } catch (RepositoryException e1) {
+ throw new JcrException(e1);
+ } finally {
+ Jcr.logout(session);
+ }
+ }
+
+ @Override
+ public void init() throws ServletException {
+
+ // TODO improve configuration and provisioning of DocBook XSL
+ String xslBase = System.getProperty("argeo.docbook.xsl");
+ if (xslBase == null) {
+ String defaultXslBase = "/opt/docbook-xsl";
+ if (!Files.exists(Paths.get(defaultXslBase))) {
+ throw new ServletException("System property argeo.docbook.xsl is not set and default location "
+ + defaultXslBase + " does not exist.");
+ } else {
+ xslBase = defaultXslBase;
+ }
+ }
+ String xsl = xslBase + "/html/docbook.xsl";
+
+ documentBuilderFactory = DocumentBuilderFactory.newInstance();
+ documentBuilderFactory.setXIncludeAware(true);
+ documentBuilderFactory.setNamespaceAware(true);
+
+ // We must explicitly use the non-XSLTC transformer, as XSLTC is not working
+ // with DocBook stylesheets
+ transformerFactory = new TransformerFactoryImpl();
+
+ Source xslSource = new StreamSource(xsl);
+ try {
+ docBoookTemplates = transformerFactory.newTemplates(xslSource);
+ if (docBoookTemplates == null)
+ throw new ServletException("Could not instantiate XSL " + xsl);
+ } catch (TransformerConfigurationException e) {
+ throw new ServletException("Cannot instantiate XSL " + xsl, e);
+ }
+ }
+
+ public void setRepository(Repository repository) {
+ this.repository = repository;
+ }
+
+ public void addTheme(CmsTheme theme, Map<String, String> properties) {
+ themes.put(theme.getThemeId(), theme);
+ }
+
+ public void removeTheme(CmsTheme theme, Map<String, String> properties) {
+ themes.remove(theme.getThemeId());
+ }
+
+}
--- /dev/null
+package org.argeo.publishing.servlet;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.io.IOUtils;
+import org.argeo.api.cms.CmsTheme;
+
+/** Serves fonts locally. */
+public class FontsServlet extends HttpServlet {
+ private static final long serialVersionUID = 6009572962850708537L;
+ private Map<String, CmsTheme> themes = Collections.synchronizedMap(new HashMap<>());
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ String font = req.getPathInfo();
+ font = font.substring(1, font.length());
+ for (CmsTheme theme : themes.values()) {
+ for (String fontPath : theme.getFontsPaths()) {
+ if (fontPath.endsWith(font)) {
+ if (font.endsWith(".woff"))
+ resp.setContentType("font/woff");
+ else if (font.endsWith(".woff2"))
+ resp.setContentType("font/woff2");
+ try (InputStream in = theme.loadPath(fontPath)) {
+ IOUtils.copy(in, resp.getOutputStream());
+ return;
+ }
+ }
+ }
+ }
+ resp.setStatus(404);
+ }
+
+ public void addTheme(CmsTheme theme, Map<String, String> properties) {
+ themes.put(theme.getThemeId(), theme);
+ }
+
+ public void removeTheme(CmsTheme theme, Map<String, String> properties) {
+ themes.remove(theme.getThemeId());
+ }
+
+}
--- /dev/null
+/bin/
+/target/
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.argeo.app.theme.default</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ds.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ </natures>
+</projectDescription>
--- /dev/null
+/MANIFEST.MF
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy" name="Argeo Suite Default Theme">
+ <implementation class="org.argeo.cms.swt.osgi.BundleCmsSwtTheme"/>
+ <service>
+ <provide interface="org.argeo.api.cms.CmsTheme"/>
+ </service>
+</scr:component>
--- /dev/null
+Service-Component:\
+OSGI-INF/cmsTheme.xml
+
+Import-Package:\
+org.argeo.cms.swt.osgi,\
+*
\ No newline at end of file
--- /dev/null
+bin.includes = META-INF/,\
+ OSGI-INF/
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.argeo.suite</groupId>
+ <artifactId>argeo-suite</artifactId>
+ <version>2.3-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <artifactId>org.argeo.app.theme.default</artifactId>
+ <name>Suite Default Theme</name>
+ <packaging>jar</packaging>
+ <dependencies>
+ </dependencies>
+</project>
--- /dev/null
+.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;
+}
--- /dev/null
+.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
--- /dev/null
+/bin/
+/target/
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.argeo.app.ui.rap</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ds.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ </natures>
+</projectDescription>
--- /dev/null
+/MANIFEST.MF
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy" name="Argeo Suite Web App">
+ <implementation class="org.argeo.cms.web.CmsWebApp"/>
+ <property name="contextName" type="String" value="argeo"/>
+ <reference bind="setCmsApp" cardinality="1..1" interface="org.argeo.api.cms.CmsApp" name="CmsApp" policy="dynamic" target="(service.pid=argeo.suite.ui.app)" unbind="unsetCmsApp"/>
+ <reference bind="setEventAdmin" cardinality="1..1" interface="org.osgi.service.event.EventAdmin" name="EventAdmin" policy="static"/>
+</scr:component>
--- /dev/null
+Service-Component: OSGI-INF/cmsWebApp.xml
+
+Import-Package:\
+org.argeo.cms.web;resolution:=optional,\
+org.eclipse.rap.rwt.application;resolution:=optional,\
+*;resolution:=optional
--- /dev/null
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ OSGI-INF/
+source.. = src/
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.argeo.suite</groupId>
+ <artifactId>argeo-suite</artifactId>
+ <version>2.3-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <artifactId>org.argeo.app.ui.rap</artifactId>
+ <name>Suite UI RAP</name>
+ <packaging>jar</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>org.argeo.suite</groupId>
+ <artifactId>org.argeo.app.ui</artifactId>
+ <version>2.3-SNAPSHOT</version>
+ </dependency>
+
+ <!-- Eclipse E4 -->
+ <dependency>
+ <groupId>org.argeo.tp</groupId>
+ <artifactId>argeo-tp-rap-e4</artifactId>
+ <version>${version.argeo-tp}</version>
+ <type>pom</type>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
--- /dev/null
+/bin/
+/target/
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.argeo.app.ui</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ds.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
--- /dev/null
+/MANIFEST.MF
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy" immediate="false" name="Admin Lead Pane">
+ <implementation class="org.argeo.suite.ui.DefaultLeadPane"/>
+ <service>
+ <provide interface="org.argeo.cms.ui.CmsUiProvider"/>
+ </service>
+ <properties entry="config/adminLeadPane.properties"/>
+ <property name="defaultLayers" type="String">argeo.suite.ui.termsLayer
+ </property>
+ <reference bind="addLayer" cardinality="1..n" interface="org.argeo.suite.ui.SuiteLayer" name="SuiteLayer" policy="dynamic" unbind="removeLayer"/>
+</scr:component>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy" name="Argeo Suite App">
+ <implementation class="org.argeo.suite.ui.SuiteApp"/>
+ <service>
+ <provide interface="org.argeo.api.cms.CmsApp"/>
+ <provide interface="org.osgi.service.event.EventHandler"/>
+ </service>
+ <properties entry="config/cmsApp.properties"/>
+ <reference bind="addUiProvider" cardinality="0..n" interface="org.argeo.cms.ui.CmsUiProvider" name="CmsUiProvider" policy="dynamic" unbind="removeUiProvider"/>
+ <reference bind="addTheme" cardinality="1..n" interface="org.argeo.api.cms.CmsTheme" name="CmsTheme" policy="dynamic" unbind="removeTheme"/>
+ <reference bind="setRepository" cardinality="1..1" interface="javax.jcr.Repository" name="Repository" policy="dynamic" target="(cn=ego)"/>
+ <reference bind="addLayer" cardinality="1..n" interface="org.argeo.suite.ui.SuiteLayer" name="SuiteLayer" policy="dynamic" unbind="removeLayer"/>
+ <reference bind="setCmsUserManager" cardinality="1..1" interface="org.argeo.cms.CmsUserManager" name="CmsUserManager" policy="static"/>
+</scr:component>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="Default Dashboard">
+ <implementation class="org.argeo.suite.ui.DefaultDashboard"/>
+ <service>
+ <provide interface="org.argeo.cms.ui.CmsUiProvider"/>
+ </service>
+ <properties entry="config/dashboard.properties"/>
+</scr:component>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="Dashboard Layer">
+ <implementation class="org.argeo.suite.ui.DefaultEditionLayer"/>
+ <service>
+ <provide interface="org.argeo.suite.ui.SuiteLayer"/>
+ </service>
+ <properties entry="config/dashboardLayer.properties"/>
+ <reference bind="setEntryArea" cardinality="1..1" interface="org.argeo.cms.ui.CmsUiProvider" name="CmsUiProvider" policy="dynamic" target="(service.pid=argeo.suite.ui.recentItems)"/>
+</scr:component>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy" name="Event Recorder">
+ <implementation class="org.argeo.suite.ui.EventRecorder"/>
+ <service>
+ <provide interface="org.osgi.service.event.EventHandler"/>
+ </service>
+ <properties entry="config/eventRecorder.properties"/>
+</scr:component>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy" immediate="false" name="Default Suite Footer">
+ <implementation class="org.argeo.suite.ui.DefaultFooter"/>
+ <service>
+ <provide interface="org.argeo.cms.ui.CmsUiProvider"/>
+ </service>
+ <properties entry="config/footer.properties"/>
+</scr:component>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy" immediate="false" name="Default Suite Header">
+ <implementation class="org.argeo.suite.ui.DefaultHeader"/>
+ <service>
+ <provide interface="org.argeo.cms.ui.CmsUiProvider"/>
+ </service>
+ <properties entry="config/header.properties"/>
+</scr:component>
--- /dev/null
+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.
--- /dev/null
+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.
--- /dev/null
+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.
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy" immediate="false" name="Default Lead Pane">
+ <implementation class="org.argeo.suite.ui.DefaultLeadPane"/>
+ <service>
+ <provide interface="org.argeo.cms.ui.CmsUiProvider"/>
+ </service>
+ <properties entry="config/leadPane.properties"/>
+ <property name="defaultLayers" type="String">argeo.suite.ui.dashboardLayer
+argeo.library.ui.contentLayer
+argeo.people.ui.peopleLayer
+argeo.geo.ui.mapLayer
+ </property>
+ <reference bind="addLayer" cardinality="1..n" interface="org.argeo.suite.ui.SuiteLayer" name="SuiteLayer" policy="dynamic" unbind="removeLayer"/>
+</scr:component>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="Default Login Screen">
+ <implementation class="org.argeo.suite.ui.DefaultLoginScreen"/>
+ <properties entry="config/loginScreen.properties"/>
+ <service>
+ <provide interface="org.argeo.cms.ui.CmsUiProvider"/>
+ </service>
+</scr:component>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" name="Default Recent Items">
+ <implementation class="org.argeo.suite.ui.RecentItems"/>
+ <service>
+ <provide interface="org.argeo.cms.ui.CmsUiProvider"/>
+ </service>
+ <properties entry="config/recentItems.properties"/>
+</scr:component>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="Terms Entry Area">
+ <implementation class="org.argeo.suite.ui.TermsEntryArea"/>
+ <service>
+ <provide interface="org.argeo.cms.ui.CmsUiProvider"/>
+ </service>
+ <properties entry="config/termsEntryArea.properties"/>
+</scr:component>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="Terms Layer">
+ <implementation class="org.argeo.suite.ui.DefaultEditionLayer"/>
+ <service>
+ <provide interface="org.argeo.suite.ui.SuiteLayer"/>
+ </service>
+ <properties entry="config/termsLayer.properties"/>
+ <reference bind="setEntryArea" cardinality="1..1" interface="org.argeo.cms.ui.CmsUiProvider" name="CmsUiProvider" policy="dynamic" target="(service.pid=argeo.suite.ui.termsEntryArea)"/>
+</scr:component>
--- /dev/null
+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.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,\
+org.eclipse.rap.rwt,\
+*
--- /dev/null
+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/
--- /dev/null
+service.pid=argeo.suite.ui.adminLeadPane
--- /dev/null
+service.pid=argeo.suite.ui.app
+
+event.topics=argeo/suite/*
\ No newline at end of file
--- /dev/null
+service.pid=argeo.suite.ui.dashboard
--- /dev/null
+service.pid=argeo.suite.ui.dashboardLayer
+
+title=Dashboard
+icon=dashboard
\ No newline at end of file
--- /dev/null
+service.pid=argeo.suite.ui.eventRecorder
+
+event.topics=argeo/suite/*
\ No newline at end of file
--- /dev/null
+service.pid=argeo.suite.ui.footer
--- /dev/null
+service.pid=argeo.suite.ui.header
+argeo.suite.ui=true
+
+argeo.suite.ui.header.title=%appTitle
\ No newline at end of file
--- /dev/null
+service.pid=argeo.suite.ui.leadPane
--- /dev/null
+service.pid=argeo.suite.ui.loginScreen
--- /dev/null
+service.pid=argeo.suite.ui.recentItems
--- /dev/null
+service.pid=argeo.suite.ui.termsEntryArea
--- /dev/null
+service.pid=argeo.suite.ui.termsLayer
+title=Terms
+icon=dashboard
+
+entity.type=entity:terms,entity:term
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.argeo.suite</groupId>
+ <artifactId>argeo-suite</artifactId>
+ <version>2.3-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <artifactId>org.argeo.app.ui</artifactId>
+ <name>Suite UI</name>
+ <packaging>jar</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>org.argeo.suite</groupId>
+ <artifactId>org.argeo.app.core</artifactId>
+ <version>2.3-SNAPSHOT</version>
+ </dependency>
+<!-- <dependency> -->
+<!-- <groupId>org.argeo.suite</groupId> -->
+<!-- <artifactId>org.argeo.entity.ui</artifactId> -->
+<!-- <version>2.3-SNAPSHOT</version> -->
+<!-- </dependency> -->
+
+ <!-- Argeo Commons -->
+ <dependency>
+ <groupId>org.argeo.commons</groupId>
+ <artifactId>org.argeo.cms.ui</artifactId>
+ <version>${version.argeo-commons}</version>
+ </dependency>
+ <!-- Specific -->
+ <dependency>
+ <groupId>org.argeo.commons.rap</groupId>
+ <artifactId>org.argeo.swt.specific.rap</artifactId>
+ <version>${version.argeo-commons}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <!-- Eclipse E4 -->
+ <dependency>
+ <groupId>org.argeo.tp</groupId>
+ <artifactId>argeo-tp-rap-e4</artifactId>
+ <version>${version.argeo-tp}</version>
+ <type>pom</type>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+</project>
--- /dev/null
+package org.argeo.docbook.ui;
+
+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.argeo.api.cms.Cms2DSize;
+import org.argeo.api.cms.CmsEditable;
+import org.argeo.api.cms.CmsLog;
+import org.argeo.cms.swt.CmsSwtUtils;
+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 CmsLog log = CmsLog.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) {
+ CmsSwtUtils.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)
+ CmsSwtUtils.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(CmsSwtUtils.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(CmsSwtUtils.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(CmsSwtUtils.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(CmsSwtUtils.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 Cms2DSize(maxMediaWidth, 0));
+ } else {
+ imgGd = CmsSwtUtils.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<Control> toLayout = new ArrayList<Control>();
+ 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(CmsSwtUtils.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<String, Section> parentSubsections = parentSection.getSubSections();
+ ArrayList<Section> lst = new ArrayList<Section>(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<Section> 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(CmsSwtUtils.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<String> styles = getAvailableStyles(composite);
+ styledTools.show(composite, new Point(e.x, e.y), styles);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void mouseUp(MouseEvent e) {
+ }
+ }
+
+ protected List<String> 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
--- /dev/null
+package org.argeo.docbook.ui;
+
+import javax.jcr.Node;
+
+import org.argeo.api.cms.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);
+ }
+}
--- /dev/null
+package org.argeo.docbook.ui;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jcr.Node;
+
+import org.argeo.api.cms.CmsEditable;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.swt.MouseDown;
+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.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<String> availableStyles) {
+ if (shell.isVisible())
+ shell.setVisible(false);
+ CmsSwtUtils.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<StyleButton> styleButtons = new ArrayList<DbkContextMenu.StyleButton>();
+ 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();
+ }
+
+ }
+}
--- /dev/null
+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.api.cms.Cms2DSize;
+import org.argeo.api.cms.CmsImageManager;
+import org.argeo.cms.ui.util.CmsUiUtils;
+import org.argeo.cms.ui.util.DefaultImageManager;
+import org.argeo.docbook.DbkAttr;
+import org.argeo.docbook.DbkType;
+import org.argeo.docbook.DbkUtils;
+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;
+
+/** 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) {
+ try {
+ 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);
+ }
+ } catch (RepositoryException e) {
+ throw new JcrException(e);
+ }
+ }
+
+ @Override
+ public Binary getImageBinary(Node node) {
+ Node fileNode = null;
+ if (DbkUtils.isDbk(node, DbkType.mediaobject)) {
+ Node imageDataNode = getImageDataNode(node);
+ fileNode = getFileNode(imageDataNode);
+ }
+ try {
+ if (node.isNodeType(NT_FILE)) {
+ fileNode = node;
+ }
+ if (fileNode != null) {
+ return node.getNode(JCR_CONTENT).getProperty(JCR_DATA).getBinary();
+ } else {
+ return null;
+ }
+ } catch (RepositoryException e) {
+ throw new JcrException(e);
+ }
+ }
+
+ public Cms2DSize getImageSize(Node mediaObjectNode) {
+ Node imageDataNode = getImageDataNode(mediaObjectNode);
+ Node fileNode = getFileNode(imageDataNode);
+ if (fileNode == null)
+ return new Cms2DSize(0, 0);
+ try {
+ Cms2DSize 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 Cms2DSize(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;
+ } catch (RepositoryException e) {
+ throw new JcrException(e);
+ }
+ }
+
+ protected Cms2DSize 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 Cms2DSize(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) {
+ Node imageDataNode = getImageDataNode(mediaObjectNode);
+ // TODO factorise
+ String fileref = null;
+ try {
+ if (imageDataNode.hasProperty(DbkAttr.fileref.name()))
+ fileref = imageDataNode.getProperty(DbkAttr.fileref.name()).getString();
+ } catch (RepositoryException e) {
+ throw new JcrException(e);
+ }
+ 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) {
+ // FIXME make URL use case more robust
+ try {
+ 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;
+ } catch (RepositoryException e) {
+ throw new JcrException(e);
+ }
+ }
+
+ 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);
+ }
+ }
+}
--- /dev/null
+package org.argeo.docbook.ui;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.argeo.cms.swt.CmsSwtUtils;
+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(CmsSwtUtils.grabWidth(SWT.CENTER, SWT.DEFAULT));
+ }
+
+ @Override
+ protected void setControlLayoutData(Control control) {
+ control.setLayoutData(CmsSwtUtils.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;
+ }
+
+}
--- /dev/null
+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();
+ }
+}
--- /dev/null
+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 + "</"
+ + node.getName() + ">";
+// 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("</").append(child.getName()).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("<a class='" + linkCssClass + "' href='").append(href).append("'>");
+ readAsSimpleHtml(child, sb);
+ sb.append("</a>");
+ }
+ } 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 = "<span style='text-align:justify'>" + raw + "</span>";
+ if (raw.length() == 0)
+ return raw;
+ try (StringReader reader = new StringReader(raw)) {
+ List<String> 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("<br/>");
+ sb.append(lines.get(i));
+ }
+ return sb.toString();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ final static int BR_LENGTH = "<br/>".length();
+
+ public String readSimpleHtml(Item item) {
+ try {
+ StringBuilder sb = new StringBuilder();
+// sb.append("<div style='text-align: justify;'>");
+ readAsSimpleHtml((Node) item, sb);
+// sb.append("</div>");
+// 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;
+ }
+}
--- /dev/null
+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.swt.CmsSwtUtils;
+import org.argeo.cms.swt.Selected;
+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.jcr.Jcr;
+import org.argeo.jcr.JcrException;
+import org.argeo.util.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(CmsSwtUtils.noSpaceGridLayout());
+
+ Composite browserC = new Composite(wrapper, SWT.NONE);
+ browserC.setLayout(CmsSwtUtils.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<String, List<String>> 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(
+ "<iframe frameborder=\"0\" allow=\"autoplay; fullscreen; picture-in-picture\" allowfullscreen=\"true\"");
+ // TODO make size configurable
+ html.append("width=\"").append(width).append("\" height=\"").append(height).append("\" ");
+ html.append("src=\"").append(fileref).append("\" ");
+ html.append("/>");
+ browser.setText(html.toString());
+ }
+ }
+ } catch (RepositoryException e) {
+ throw new JcrException("Cannot retrieve src for video " + getNode(), e);
+ }
+ }
+
+ @Override
+ protected void setContainerLayoutData(Composite composite) {
+ composite.setLayoutData(new GridData(SWT.CENTER, SWT.FILL, true, true));
+ }
+
+ @Override
+ protected void setControlLayoutData(Control control) {
+ control.setLayoutData(CmsSwtUtils.fillAll());
+ }
+
+ @Override
+ public Item getItem() throws RepositoryException {
+ return getNode();
+ }
+
+ @Override
+ public String getPartId() {
+ return getNodeId();
+ }
+
+ @Override
+ public Section getSection() {
+ return section;
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+}
--- /dev/null
+package org.argeo.docbook.ui;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.nodetype.NodeType;
+
+import org.argeo.api.cms.CmsEditable;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.ui.CmsUiProvider;
+import org.argeo.cms.ui.util.CmsLink;
+import org.argeo.cms.ui.viewers.JcrVersionCmsEditable;
+import org.argeo.cms.ui.widgets.ScrolledPage;
+import org.argeo.docbook.DbkType;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * Display the text of the context, and provide an editor if the user can edit.
+ */
+public class DocumentPage implements CmsUiProvider {
+ public final static String WWW = "www";
+
+ @Override
+ public Control createUi(Composite parent, Node context) throws RepositoryException {
+
+ ScrolledPage page = new ScrolledPage(parent, SWT.NONE);
+ page.setLayout(CmsSwtUtils.noSpaceGridLayout());
+ GridData textGd = CmsSwtUtils.fillAll();
+ page.setLayoutData(textGd);
+
+ if (context.isNodeType(DbkType.article.get())) {
+ CmsEditable cmsEditable = new JcrVersionCmsEditable(context);
+ if (cmsEditable.canEdit())
+ new TextEditorHeader(cmsEditable, parent, SWT.NONE).setLayoutData(CmsSwtUtils.fillWidth());
+ if (!cmsEditable.isEditing())
+ cmsEditable.startEditing();
+ new DocumentTextEditor(page, SWT.FLAT, context, cmsEditable);
+ } else {
+ parent.setBackgroundMode(SWT.INHERIT_NONE);
+ if (context.getSession().hasPermission(context.getPath(), Session.ACTION_ADD_NODE)) {
+// new DocumentTextEditor(page, SWT.FLAT, indexNode, cmsEditable);
+// textGd.heightHint = 400;
+
+ for (NodeIterator ni = context.getNodes(); ni.hasNext();) {
+ Node textNode = ni.nextNode();
+ if (textNode.isNodeType(NodeType.NT_FOLDER))
+ new CmsLink(textNode.getName() + "/", textNode.getPath()).createUi(parent, textNode);
+ }
+ for (NodeIterator ni = context.getNodes(); ni.hasNext();) {
+ Node textNode = ni.nextNode();
+ if (textNode.isNodeType(DbkType.article.get()) && !textNode.getName().equals(WWW))
+ new CmsLink(textNode.getName(), textNode.getPath()).createUi(parent, textNode);
+ }
+ }
+ }
+ return page;
+ }
+}
--- /dev/null
+package org.argeo.docbook.ui;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.argeo.api.cms.CmsEditable;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.docbook.DbkUtils;
+import org.argeo.docbook.DbkType;
+import org.eclipse.swt.widgets.Composite;
+
+/** Text editor where sections and subsections can be managed by the user. */
+public class DocumentTextEditor extends AbstractDbkViewer {
+ private static final long serialVersionUID = 6049661610883342325L;
+
+ public DocumentTextEditor(Composite parent, int style, Node textNode, CmsEditable cmsEditable) {
+ super(new TextSection(parent, style, textNode), style, cmsEditable);
+// refresh();
+ getMainSection().setLayoutData(CmsSwtUtils.fillWidth());
+ }
+
+ @Override
+ protected void initModel(Node textNode) throws RepositoryException {
+ if (isFlat()) {
+ DbkUtils.addParagraph(textNode, "");
+ }
+// else
+// textNode.setProperty(DocBookNames.DBK_TITLE, textNode.getName());
+ }
+
+ @Override
+ protected Boolean isModelInitialized(Node textNode) throws RepositoryException {
+ return textNode.hasNode(DbkType.title.get()) || textNode.hasNode(DbkType.para.get())
+ || (!isFlat() && textNode.hasNode(DbkType.section.get()));
+ }
+
+}
--- /dev/null
+package org.argeo.docbook.ui;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.ui.viewers.SectionPart;
+import org.argeo.cms.ui.widgets.EditableText;
+import org.argeo.cms.ui.widgets.TextStyles;
+import org.argeo.docbook.DbkType;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+
+/** An editable paragraph. */
+public class Paragraph extends EditableText implements SectionPart {
+ private static final long serialVersionUID = 3746457776229542887L;
+
+ private final TextSection section;
+
+ public Paragraph(TextSection section, int style, Node node) throws RepositoryException {
+ super(section, style, node);
+ this.section = section;
+ CmsSwtUtils.style(this, DbkType.para.name());
+ }
+
+ public TextSection getSection() {
+ return section;
+ }
+
+ @Override
+ protected Label createLabel(Composite box, String style) {
+ Label lbl = super.createLabel(box, style);
+ CmsSwtUtils.disableMarkupValidation(lbl);
+ return lbl;
+ }
+
+ @Override
+ public String getPartId() {
+ return getNodeId();
+ }
+
+ @Override
+ public Node getItem() throws RepositoryException {
+ return getNode();
+ }
+
+ @Override
+ public String toString() {
+ return "Paragraph #" + getPartId();
+ }
+}
--- /dev/null
+package org.argeo.docbook.ui;
+
+import java.util.Observable;
+import java.util.Observer;
+
+import org.argeo.api.cms.CmsEditable;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.ui.widgets.TextStyles;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+
+/** Adds editing capabilities to a page editing text */
+public class TextEditorHeader implements SelectionListener, Observer {
+ private static final long serialVersionUID = 4186756396045701253L;
+
+ private final CmsEditable cmsEditable;
+ private Button publish;
+
+ private Composite parent;
+ private Composite display;
+ private Object layoutData;
+
+ public TextEditorHeader(CmsEditable cmsEditable, Composite parent, int style) {
+ this.cmsEditable = cmsEditable;
+ this.parent = parent;
+ if (this.cmsEditable instanceof Observable)
+ ((Observable) this.cmsEditable).addObserver(this);
+ refresh();
+ }
+
+ protected void refresh() {
+ if (display != null && !display.isDisposed())
+ display.dispose();
+ display = null;
+ publish = null;
+ if (cmsEditable.isEditing()) {
+ display = new Composite(parent, SWT.NONE);
+ // display.setBackgroundMode(SWT.INHERIT_NONE);
+ display.setLayoutData(layoutData);
+ display.setLayout(CmsSwtUtils.noSpaceGridLayout());
+ CmsSwtUtils.style(display, TextStyles.TEXT_EDITOR_HEADER);
+ publish = new Button(display, SWT.FLAT | SWT.PUSH);
+ publish.setText(getPublishButtonLabel());
+ CmsSwtUtils.style(publish, TextStyles.TEXT_EDITOR_HEADER);
+ publish.addSelectionListener(this);
+ display.moveAbove(null);
+ }
+ parent.layout();
+ }
+
+ private String getPublishButtonLabel() {
+ if (cmsEditable.isEditing())
+ return "Publish";
+ else
+ return "Edit";
+ }
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ if (e.getSource() == publish) {
+ if (cmsEditable.isEditing()) {
+ cmsEditable.stopEditing();
+ } else {
+ cmsEditable.startEditing();
+ }
+ // publish.setText(getPublishButtonLabel());
+ }
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ }
+
+ @Override
+ public void update(Observable o, Object arg) {
+ if (o == cmsEditable) {
+ // publish.setText(getPublishButtonLabel());
+ refresh();
+ }
+ }
+
+ public void setLayoutData(Object layoutData) {
+ this.layoutData = layoutData;
+ if (display != null && !display.isDisposed())
+ display.setLayoutData(layoutData);
+ }
+
+}
\ No newline at end of file
--- /dev/null
+package org.argeo.docbook.ui;
+
+import javax.jcr.Item;
+
+/** Convert from/to data layer to/from presentation layer. */
+public interface TextInterpreter {
+ String raw(Item item);
+
+ String read(Item item);
+
+ String readSimpleHtml(Item item);
+
+ void write(Item item, String content);
+}
--- /dev/null
+package org.argeo.docbook.ui;
+
+import javax.jcr.Node;
+
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.ui.viewers.EditablePart;
+import org.argeo.cms.ui.viewers.Section;
+import org.argeo.cms.ui.widgets.TextStyles;
+import org.argeo.docbook.DbkType;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+/** An editable section. */
+public class TextSection extends Section {
+ private static final long serialVersionUID = -8625209546243220689L;
+ private String defaultTextStyle = DbkType.para.name();
+ private String titleStyle;
+
+ private final boolean flat;
+
+ private boolean titleReadOnly = false;
+
+ private final int level;
+
+ public TextSection(Composite parent, int style, Node node) {
+ this(parent, findSection(parent), style, node);
+ }
+
+ public TextSection(TextSection section, int style, Node node) {
+ this(section, section.getParentSection(), style, node);
+ }
+
+ private TextSection(Composite parent, Section parentSection, int style, Node node) {
+ super(parent, parentSection, style, node);
+ flat = SWT.FLAT == (style & SWT.FLAT);
+ if (parentSection instanceof TextSection) {
+ level = ((TextSection) parentSection).getLevel() + 1;
+ } else {
+ level = 0;
+ }
+ CmsSwtUtils.style(this, DbkType.section.name());
+ }
+
+ public String getDefaultTextStyle() {
+ return defaultTextStyle;
+ }
+
+ public boolean isFlat() {
+ return flat;
+ }
+
+ /** The level of this section, similar to h1, h2, etc. in HTML. */
+ public int getLevel() {
+ return level;
+ }
+
+ public String getTitleStyle() {
+ if (titleStyle != null)
+ return titleStyle;
+ // TODO make base H styles configurable
+// Integer relativeDepth = getRelativeDepth();
+// System.out.println("Level: " + getLevel());
+ return "h" + (getLevel() + 1);
+ }
+
+ public void setDefaultTextStyle(String defaultTextStyle) {
+ this.defaultTextStyle = defaultTextStyle;
+ }
+
+ public void setTitleStyle(String titleStyle) {
+ this.titleStyle = titleStyle;
+ }
+
+ public boolean isTitleReadOnly() {
+ return titleReadOnly;
+ }
+
+ public void setTitleReadOnly(boolean titleReadOnly) {
+ this.titleReadOnly = titleReadOnly;
+ }
+}
--- /dev/null
+package org.argeo.entity.ui.forms;
+
+import javax.jcr.Item;
+
+import org.argeo.api.cms.CmsTheme;
+import org.argeo.cms.Localized;
+import org.argeo.cms.swt.CmsIcon;
+import org.argeo.cms.swt.CmsSwtUtils;
+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 = CmsSwtUtils.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(CmsSwtUtils.fillAll());
+ }
+
+ protected void setContainerLayoutData(Composite composite) {
+ composite.setLayoutData(CmsSwtUtils.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("+");
+ }
+}
--- /dev/null
+package org.argeo.entity.ui.forms;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jcr.Item;
+
+import org.argeo.api.cms.CmsLog;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.swt.MouseDoubleClick;
+import org.argeo.cms.swt.MouseDown;
+import org.argeo.cms.swt.Selected;
+import org.argeo.cms.ui.forms.FormStyle;
+import org.argeo.cms.ui.viewers.EditablePart;
+import org.argeo.cms.ui.widgets.ContextOverlay;
+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 CmsLog log = CmsLog.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 = CmsSwtUtils.noMarginsRowLayout(rl);
+// rl.wrap = true;
+// rl.justify = true;
+ placeholder.setLayout(rl);
+ List<Term> currentValue = getValue();
+ if (currentValue != null && !currentValue.isEmpty()) {
+ for (Term value : currentValue) {
+ Composite block = new Composite(placeholder, SWT.NONE);
+ block.setLayout(CmsSwtUtils.noSpaceGridLayout(3));
+ Label lbl = new Label(block, SWT.NONE);
+ String display = getTermLabel(value);
+ lbl.setText(display);
+ CmsSwtUtils.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<Term> curr = getValue();
+ List<Term> 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(CmsSwtUtils.noSpaceGridLayout(3));
+
+ createHighlight(block);
+
+ Text txt = new Text(block, SWT.SINGLE | SWT.BORDER);
+ txt.setLayoutData(CmsSwtUtils.fillWidth());
+// txt.setMessage("[new]");
+
+ CmsSwtUtils.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) {
+ CmsSwtUtils.clear(contextArea);
+ List<? extends Term> terms = termsManager.listAllTerms(typology.getId());
+ List<Term> 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<Term> newValue = new ArrayList<>();
+ List<Term> curr = getValue();
+ if (currentValue != null)
+ newValue.addAll(curr);
+ newValue.add(term);
+ setValue(newValue);
+ contextArea.hide();
+ stopEditing();
+ });
+ }
+ contextArea.show();
+ }
+
+ protected List<Term> getValue() {
+ String property = typology.getId();
+ List<String> curr = Jcr.getMultiple(getNode(), property);
+ List<Term> 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<Term> value) {
+ String property = typology.getId();
+ List<String> ids = new ArrayList<>();
+ for (Term term : value) {
+ ids.add(term.getId());
+ }
+ Jcr.set(getNode(), property, ids);
+ Jcr.save(getNode());
+ }
+
+}
--- /dev/null
+package org.argeo.entity.ui.forms;
+
+import java.util.List;
+
+import javax.jcr.Item;
+
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.swt.MouseDoubleClick;
+import org.argeo.cms.swt.MouseDown;
+import org.argeo.cms.swt.Selected;
+import org.argeo.cms.ui.forms.FormStyle;
+import org.argeo.cms.ui.viewers.EditablePart;
+import org.argeo.cms.ui.widgets.ContextOverlay;
+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(CmsSwtUtils.noSpaceGridLayout(3));
+
+ createHighlight(block);
+
+ Text txt = new Text(block, SWT.SINGLE | SWT.BORDER);
+ CmsSwtUtils.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(CmsSwtUtils.noSpaceGridLayout(2));
+ Term currentValue = getValue();
+ if (currentValue != null) {
+ Label lbl = new Label(block, SWT.SINGLE);
+ String display = getTermLabel(currentValue);
+ lbl.setText(display);
+ CmsSwtUtils.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) {
+ CmsSwtUtils.clear(contextArea);
+ List<? extends Term> 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());
+ }
+}
--- /dev/null
+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.api.cms.CmsTheme;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.ui.CmsUiProvider;
+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 = CmsSwtUtils.getCmsTheme(parent);
+
+ parent.setLayout(new GridLayout());
+ Ui ui = new Ui(parent, SWT.NONE);
+ ui.setLayoutData(CmsSwtUtils.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) {
+ CmsSwtUtils.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) {
+ CmsSwtUtils.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<String, Node> 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) {
+ }
+
+ }
+
+}
--- /dev/null
+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();
+ }
+}
--- /dev/null
+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 org.argeo.api.cms.CmsLog;
+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 CmsLog log = CmsLog.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());
+ // 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);
+ }
+
+ /**
+ * 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 = "<i>Unknown</i>";
+ 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);
+ }
+}
--- /dev/null
+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.argeo.api.cms.CmsLog;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.ui.fs.FileDrop;
+import org.argeo.cms.ui.fs.FsStyles;
+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 CmsLog log = CmsLog.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<ColumnDefinition> 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);
+ CmsSwtUtils.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);
+ CmsSwtUtils.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 = "<i>Unknown</i>";
+ addProperty(rightPanelCmp, "Type", mimeType);
+ addProperty(rightPanelCmp, "Size", FsUiUtils.humanReadableByteCount(Files.size(path), false));
+ }
+
+ // read all attributes
+// Map<String, Object> 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<Path> 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;
+ }
+
+}
--- /dev/null
+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.api.cms.CmsView;
+import org.argeo.cms.fs.CmsFsUtils;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.ui.CmsUiProvider;
+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 = CmsSwtUtils.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(CmsSwtUtils.fillAll());
+ dfc.populate(cmsView.doAs(() -> CmsFsUtils.getPath(nodeFileSystemProvider, context)));
+ return dfc;
+ }
+
+ public void setNodeFileSystemProvider(FileSystemProvider nodeFileSystemProvider) {
+ this.nodeFileSystemProvider = nodeFileSystemProvider;
+ }
+
+}
--- /dev/null
+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.cms.CmsView;
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.cms.fs.CmsFsUtils;
+import org.argeo.cms.jcr.CmsJcrUtils;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.ui.CmsUiProvider;
+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 = CmsSwtUtils.getCmsView(parent);
+ Node homeNode = CmsJcrUtils.getUserHome(cmsView.doAs(() -> Jcr.login(repository, CmsConstants.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(CmsSwtUtils.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;
+ }
+
+}
--- /dev/null
+package org.argeo.library.ui;
+
+import static org.argeo.cms.swt.dialogs.CmsMessageDialog.openConfirm;
+import static org.argeo.cms.swt.dialogs.CmsMessageDialog.openError;
+import static org.argeo.cms.swt.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.argeo.api.cms.CmsLog;
+import org.argeo.cms.swt.dialogs.CmsFeedback;
+import org.argeo.eclipse.ui.EclipseUiUtils;
+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 CmsLog log = CmsLog.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<String, String> params = new HashMap<String, String>();
+// 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<Object> iterator = selection.iterator();
+ List<Path> 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<Path>() {
+ @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<Object> iterator = selection.iterator();
+// List<Node> 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;
+// }
+}
--- /dev/null
+package org.argeo.people.ui;
+
+import java.util.Set;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.argeo.api.cms.CmsTheme;
+import org.argeo.cms.CmsUserManager;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.swt.Selected;
+import org.argeo.cms.swt.dialogs.CmsWizardDialog;
+import org.argeo.cms.ui.CmsUiProvider;
+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.argeo.util.naming.LdapAttrs;
+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 = CmsSwtUtils.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(CmsSwtUtils.fillWidth());
+ bottom.setLayout(CmsSwtUtils.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);
+ CmsSwtUtils.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);
+ CmsSwtUtils.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(CmsSwtUtils.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<User> 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;
+ }
+
+}
--- /dev/null
+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.swt.CmsSwtUtils;
+import org.argeo.cms.ui.CmsUiProvider;
+import org.argeo.cms.ui.viewers.Section;
+import org.argeo.suite.ui.SuiteMsg;
+import org.argeo.suite.ui.SuiteUiUtils;
+import org.argeo.util.naming.LdapAttrs;
+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(CmsSwtUtils.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(CmsSwtUtils.fillWidth());
+ rolesSection.setLayout(new GridLayout());
+ // new Label(rolesSection, SWT.NONE).setText("Roles:");
+ List<String> 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<String, Object> properties) {
+ availableRoles = (String[]) properties.get("availableRoles");
+ }
+}
--- /dev/null
+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.swt.CmsSwtUtils;
+import org.argeo.cms.ui.CmsUiProvider;
+import org.argeo.cms.ui.viewers.Section;
+import org.argeo.suite.ui.SuiteMsg;
+import org.argeo.suite.ui.SuiteUiUtils;
+import org.argeo.util.naming.LdapAttrs;
+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(CmsSwtUtils.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(CmsSwtUtils.fillWidth());
+ rolesSection.setLayout(new GridLayout());
+ // new Label(rolesSection, SWT.NONE).setText("Roles:");
+ List<String> 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<String, Object> properties) {
+ availableRoles = (String[]) properties.get("availableRoles");
+ }
+}
--- /dev/null
+package org.argeo.people.ui;
+
+import java.util.Set;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.argeo.api.cms.CmsTheme;
+import org.argeo.cms.CmsUserManager;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.swt.Selected;
+import org.argeo.cms.swt.dialogs.CmsWizardDialog;
+import org.argeo.cms.ui.CmsUiProvider;
+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.argeo.util.naming.LdapAttrs;
+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 = CmsSwtUtils.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(CmsSwtUtils.fillWidth());
+ bottom.setLayout(CmsSwtUtils.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);
+ CmsSwtUtils.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);
+ CmsSwtUtils.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(CmsSwtUtils.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<User> 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;
+ }
+
+}
--- /dev/null
+package org.argeo.publishing.ui;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.NodeType;
+
+import org.argeo.api.cms.CmsEditable;
+import org.argeo.api.cms.CmsView;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.ui.CmsUiProvider;
+import org.argeo.cms.ui.util.CmsLink;
+import org.argeo.cms.ui.util.CmsUiUtils;
+import org.argeo.cms.ui.viewers.JcrVersionCmsEditable;
+import org.argeo.cms.ui.widgets.ScrolledPage;
+import org.argeo.docbook.DbkType;
+import org.argeo.docbook.ui.AbstractDbkViewer;
+import org.argeo.docbook.ui.DocumentTextEditor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+public class DocumentUiProvider implements CmsUiProvider {
+
+ @Override
+ public Control createUi(Composite parent, Node context) throws RepositoryException {
+ CmsView cmsView = CmsSwtUtils.getCmsView(parent);
+ CmsEditable cmsEditable = new JcrVersionCmsEditable(context);
+ if (context.hasNode(DbkType.article.get())) {
+ Node textNode = context.getNode(DbkType.article.get());
+ // Title
+ parent.setLayout(CmsSwtUtils.noSpaceGridLayout());
+
+ CmsLink toHtml = new CmsLink("To HTML", "/html/dbk" + context.getPath()+"/index.html");
+ toHtml.createUiPart(parent, context);
+
+ ScrolledPage page = new ScrolledPage(parent, SWT.NONE);
+ page.setLayoutData(CmsSwtUtils.fillAll());
+ page.setLayout(CmsSwtUtils.noSpaceGridLayout());
+
+ cmsView.runAs(() -> {
+ AbstractDbkViewer dbkEditor = new DocumentTextEditor(page, SWT.NONE, textNode, cmsEditable);
+ dbkEditor.refresh();
+ });
+ return page;
+
+ } else if (context.isNodeType(NodeType.NT_FILE)) {
+ String fileName = context.getName();
+ if (fileName.endsWith(".pdf")) {
+ Browser browser = new Browser(parent, SWT.NONE);
+ String dataPath = CmsUiUtils.getDataPath(context);
+ browser.setUrl(dataPath);
+ browser.setLayoutData(CmsSwtUtils.fillAll());
+ return browser;
+ }
+ }
+ return null;
+ }
+
+}
--- /dev/null
+package org.argeo.publishing.ui;
+
+import static org.argeo.suite.ui.SuiteApp.DEFAULT_THEME_ID_PROPERTY;
+import static org.argeo.suite.ui.SuiteApp.DEFAULT_UI_NAME_PROPERTY;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.Session;
+
+import org.argeo.api.cms.CmsApp;
+import org.argeo.api.cms.CmsUi;
+import org.argeo.api.cms.CmsLog;
+import org.argeo.cms.AbstractCmsApp;
+import org.argeo.cms.ui.CmsUiProvider;
+import org.argeo.jcr.Jcr;
+import org.argeo.suite.ui.SuiteApp;
+import org.argeo.util.LangUtils;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.osgi.framework.Constants;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventHandler;
+
+/**
+ * A {@link CmsApp} dedicated to publishing, typically a public or internal web
+ * site.
+ */
+public class PublishingApp extends AbstractCmsApp implements EventHandler {
+ private final static CmsLog log = CmsLog.getLog(PublishingApp.class);
+
+ private String pid;
+ private String defaultThemeId;
+ private String defaultUiName = "";
+
+ private String publicBasePath = null;
+
+ private CmsUiProvider landingPage;
+ private CmsUiProvider defaultProvider = new DocumentUiProvider();
+
+ private Repository repository;
+
+ public void init(Map<String, String> properties) {
+ 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);
+ publicBasePath = LangUtils.get(properties, SuiteApp.PUBLIC_BASE_PATH_PROPERTY);
+ pid = properties.get(Constants.SERVICE_PID);
+
+ if (log.isDebugEnabled())
+ log.info("Publishing App " + pid + " started");
+ }
+
+ public void destroy(Map<String, String> properties) {
+ if (log.isDebugEnabled())
+ log.info("Publishing App " + pid + " stopped");
+
+ }
+
+ @Override
+ public Set<String> getUiNames() {
+ Set<String> uiNames = new HashSet<>();
+ uiNames.add(defaultUiName);
+ return uiNames;
+ }
+
+ @Override
+ public CmsUi initUi(Object uiParent) {
+ Composite parent = (Composite) uiParent;
+// Session adminSession = NodeUtils.openDataAdminSession(getRepository(), null);
+ Session session = Jcr.login(getRepository(), null);
+ parent.setLayout(new GridLayout());
+ Node indexNode = Jcr.getNode(session, publicBasePath + "/index");
+// try {
+// indexNode = JcrUtils.getOrAdd(Jcr.getRootNode(adminSession), DocumentPage.WWW, DbkType.article.get());
+// adminSession.save();
+// } catch (RepositoryException e) {
+// throw new IllegalStateException(e);
+// }
+
+ Control page;
+ if (landingPage != null) {
+ page = landingPage.createUiPart(parent, indexNode);
+ } else {
+ page = defaultProvider.createUiPart(parent, indexNode);
+ }
+ return (CmsUi) page;
+ }
+
+ @Override
+ public void refreshUi(CmsUi cmsUi, String state) {
+ Composite parent = (Composite) cmsUi;
+ parent.setLayout(new GridLayout());
+ if (landingPage != null)
+ landingPage.createUiPart(parent, null);
+ else
+ defaultProvider.createUiPart(parent, null);
+ }
+
+ @Override
+ public void setState(CmsUi cmsUi, String state) {
+
+ }
+
+ @Override
+ protected String getThemeId(String uiName) {
+ return defaultThemeId;
+ }
+
+ public void setLandingPage(CmsUiProvider landingPage) {
+ this.landingPage = landingPage;
+ }
+
+ @Override
+ public void handleEvent(Event event) {
+ // TODO listen to some events
+
+ }
+
+ public Repository getRepository() {
+ return repository;
+ }
+
+ public void setRepository(Repository repository) {
+ this.repository = repository;
+ }
+
+}
--- /dev/null
+package org.argeo.publishing.ui;
+
+import org.argeo.api.cms.CmsStyle;
+
+/** Publishing styles. */
+public enum PublishingStyle implements CmsStyle {
+ // general
+ page, coverTitle, coverSubTitle, coverTagline, bannerLine1, bannerLine2,
+ // meta data
+ tag, menu,
+ // text style
+ title, subTitle, chapo, para, sectionTitle, subSectionTitle,
+ // links
+ internalLink,
+ // composite style
+ framed, line;
+
+ @Override
+ public String getClassPrefix() {
+ return "argeo-publishing";
+ }
+
+}
--- /dev/null
+package org.argeo.suite.ui;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.argeo.api.cms.CmsView;
+import org.argeo.cms.auth.CurrentUser;
+import org.argeo.cms.swt.CmsSwtUtils;
+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;
+
+/** Provides a dashboard. */
+public class DefaultDashboard implements CmsUiProvider {
+
+ @Override
+ public Control createUi(Composite parent, Node context) throws RepositoryException {
+ parent.setLayout(new GridLayout());
+ CmsView cmsView = CmsSwtUtils.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;
+ }
+
+}
--- /dev/null
+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.api.cms.CmsTheme;
+import org.argeo.cms.Localized;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.ui.CmsUiProvider;
+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<String> 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);
+ CmsSwtUtils.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 = CmsSwtUtils.getCmsTheme(parent);
+ TabbedArea tabbedArea = createTabbedArea(parent, theme);
+ return tabbedArea;
+ }
+ }
+
+ @Override
+ public void view(CmsUiProvider uiProvider, Composite workAreaC, Node context) {
+ if (workArea != null) {
+ try {
+ CmsSwtUtils.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<String, Object> 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<String, String> 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(CmsSwtUtils.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 = CmsSwtUtils.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 = CmsSwtUtils.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 = CmsSwtUtils.getCmsTheme(parent);
+
+ setLayout(CmsSwtUtils.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(CmsSwtUtils.fillHeight());
+
+ GridLayout editorAreaLayout = CmsSwtUtils.noSpaceGridLayout();
+// editorAreaLayout.verticalSpacing = 0;
+// editorAreaLayout.marginBottom = 0;
+// editorAreaLayout.marginHeight = 0;
+// editorAreaLayout.marginLeft = 0;
+// editorAreaLayout.marginRight = 0;
+ editorC.setLayout(editorAreaLayout);
+ editorC.setLayoutData(CmsSwtUtils.fillAll());
+
+ tabbedArea = createTabbedArea(editorC, theme);
+ }
+
+ TabbedArea getTabbedArea() {
+ return tabbedArea;
+ }
+
+ Composite getEntryArea() {
+ return entryC;
+ }
+ }
+
+}
\ No newline at end of file
--- /dev/null
+package org.argeo.suite.ui;
+
+import java.util.Map;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.ui.CmsUiProvider;
+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(CmsSwtUtils.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<String, String> properties) {
+ }
+
+ public void destroy(BundleContext bundleContext, Map<String, String> properties) {
+
+ }
+}
--- /dev/null
+package org.argeo.suite.ui;
+
+import java.util.Map;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.argeo.api.cms.CmsTheme;
+import org.argeo.api.cms.CmsView;
+import org.argeo.cms.Localized;
+import org.argeo.cms.auth.CurrentUser;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.ui.CmsUiProvider;
+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 = CmsSwtUtils.getCmsView(parent);
+ CmsTheme theme = CmsSwtUtils.getCmsTheme(parent);
+
+ parent.setLayout(CmsSwtUtils.noSpaceGridLayout(new GridLayout(3, true)));
+
+ // TODO right to left
+ Composite lead = new Composite(parent, SWT.NONE);
+ CmsSwtUtils.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());
+ CmsSwtUtils.style(lbl, SuiteStyle.headerTitle);
+ lbl.setLayoutData(CmsSwtUtils.fillWidth());
+
+ Composite middle = new Composite(parent, SWT.NONE);
+ CmsSwtUtils.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);
+ CmsSwtUtils.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);
+ CmsSwtUtils.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<String, String> 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<String, String> properties) {
+
+ }
+
+ public Localized getTitle() {
+ return title;
+ }
+
+}
--- /dev/null
+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.argeo.api.cms.CmsView;
+import org.argeo.api.cms.CmsLog;
+import org.argeo.cms.Localized;
+import org.argeo.cms.auth.CurrentUser;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.ui.CmsUiProvider;
+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 CmsLog log = CmsLog.getLog(DefaultLeadPane.class);
+
+ public static enum Property {
+ defaultLayers, adminLayers;
+ }
+
+ private Map<String, RankedObject<SuiteLayer>> layers = Collections.synchronizedSortedMap(new TreeMap<>());
+ private List<String> defaultLayers;
+ private List<String> adminLayers = new ArrayList<>();
+
+ private ClassLoader l10nClassLoader;
+
+ @Override
+ public Control createUi(Composite parent, Node node) throws RepositoryException {
+ CmsView cmsView = CmsSwtUtils.getCmsView(parent);
+ parent.setLayout(CmsSwtUtils.noSpaceGridLayout());
+ Composite appLayersC = new Composite(parent, SWT.NONE);
+ CmsSwtUtils.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);
+ CmsSwtUtils.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<String> 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<String> layerRoles = SuiteUtils.extractRoles(semiColArr);
+ if (layers.containsKey(layerId)) {
+ if (!layerRoles.isEmpty()) {
+ Set<String> intersection = new HashSet<String>(layerRoles);
+ intersection.retainAll(userRoles);
+ if (intersection.isEmpty())
+ continue layers;// skip unauthorized layer
+ }
+ RankedObject<SuiteLayer> 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<String, Object> 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<String, String> properties) {
+
+ }
+
+ public void addLayer(SuiteLayer layer, Map<String, Object> 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<String, Object> 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<SuiteLayer>(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;
+// }
+}
--- /dev/null
+package org.argeo.suite.ui;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.argeo.api.cms.CmsView;
+import org.argeo.cms.auth.CurrentUser;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.swt.auth.CmsLogin;
+import org.argeo.cms.ui.CmsUiProvider;
+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 = CmsSwtUtils.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();
+ }
+
+}
--- /dev/null
+package org.argeo.suite.ui;
+
+import org.argeo.api.cms.CmsLog;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventHandler;
+
+/** Record UI events. */
+public class EventRecorder implements EventHandler {
+ private final static CmsLog log = CmsLog.getLog(EventRecorder.class);
+
+ public void init() {
+
+ }
+
+ public void destroy() {
+
+ }
+
+ @Override
+ public void handleEvent(Event event) {
+ if (log.isTraceEnabled())
+ log.trace(event);
+
+ }
+
+}
--- /dev/null
+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.api.cms.CmsTheme;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.ui.CmsUiProvider;
+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 = CmsSwtUtils.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(CmsSwtUtils.fillAll());
+
+ Composite bottom = new Composite(parent, SWT.NONE);
+ bottom.setLayoutData(CmsSwtUtils.fillWidth());
+ bottom.setLayout(CmsSwtUtils.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)
+ CmsSwtUtils.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) {
+ CmsSwtUtils.getCmsView(parent).sendEvent(SuiteEvent.refreshPart.topic(),
+ SuiteEvent.eventProperties(node));
+ deleteItem.setEnabled(true);
+ } else {
+ deleteItem.setEnabled(false);
+ }
+ }
+ });
+
+ return entityViewer.filterTxt;
+
+ }
+
+ public void init(Map<String, String> 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<Node> 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<Node>) newInput;
+ }
+
+ public Object[] getElements(Object arg0) {
+ return nodes.toArray();
+ }
+ }
+ }
+}
--- /dev/null
+package org.argeo.suite.ui;
+
+import static org.argeo.api.cms.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.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.nodetype.NodeType;
+import javax.naming.InvalidNameException;
+import javax.naming.ldap.LdapName;
+
+import org.argeo.api.cms.CmsSession;
+import org.argeo.api.cms.CmsTheme;
+import org.argeo.api.cms.CmsUi;
+import org.argeo.api.cms.CmsView;
+import org.argeo.api.cms.CmsLog;
+import org.argeo.cms.AbstractCmsApp;
+import org.argeo.cms.CmsUserManager;
+import org.argeo.cms.LocaleUtils;
+import org.argeo.cms.Localized;
+import org.argeo.cms.jcr.CmsJcrUtils;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.swt.dialogs.CmsFeedback;
+import org.argeo.cms.ui.CmsUiProvider;
+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 CmsLog log = CmsLog.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<String, RankedObject<CmsUiProvider>> uiProvidersByPid = Collections.synchronizedMap(new HashMap<>());
+ private Map<String, RankedObject<CmsUiProvider>> uiProvidersByType = Collections.synchronizedMap(new HashMap<>());
+ private Map<String, RankedObject<SuiteLayer>> layersByPid = Collections.synchronizedSortedMap(new TreeMap<>());
+ private Map<String, RankedObject<SuiteLayer>> layersByType = Collections.synchronizedSortedMap(new TreeMap<>());
+
+ private CmsUserManager cmsUserManager;
+
+ // TODO make more optimal or via CmsSession/CmsView
+ private Map<String, SuiteUi> managedUis = new HashMap<>();
+
+ private Repository repository;
+
+
+ public void init(Map<String, Object> 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<String, Object> properties) {
+ for (SuiteUi ui : managedUis.values())
+ if (!ui.isDisposed())
+ ui.dispose();
+ if (log.isDebugEnabled())
+ log.info("Argeo Suite App stopped");
+
+ }
+
+ @Override
+ public Set<String> getUiNames() {
+ HashSet<String> uiNames = new HashSet<>();
+ uiNames.add(defaultUiName);
+ uiNames.add(adminUiName);
+ return uiNames;
+ }
+
+ @Override
+ public CmsUi initUi(Object parent) {
+ Composite uiParent =(Composite) parent;
+ String uiName = uiParent.getData(UI_NAME_PROPERTY) != null ? uiParent.getData(UI_NAME_PROPERTY).toString() : null;
+ CmsView cmsView = CmsSwtUtils.getCmsView(uiParent);
+ if (cmsView == null)
+ throw new IllegalStateException("No CMS view is registered.");
+ CmsTheme theme = getTheme(uiName);
+ if (theme != null)
+ CmsSwtUtils.registerCmsTheme(uiParent.getShell(), theme);
+ SuiteUi argeoSuiteUi = new SuiteUi(uiParent, 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(CmsUi cmsUi, String state) {
+ try {
+ Node context = null;
+ SuiteUi ui = (SuiteUi) cmsUi;
+
+ 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 = CmsSwtUtils.getCmsView(ui);
+ 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 = CmsJcrUtils.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(ui, 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) {
+ CmsSwtUtils.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> T findByType(Map<String, RankedObject<T>> byType, Node context) {
+ if (context == null)
+ throw new IllegalArgumentException("A node should be provided");
+ try {
+ // mixins
+ Set<String> types = new TreeSet<>();
+ for (NodeType mixinType : context.getMixinNodeTypes()) {
+ String mixinTypeName = mixinType.getName();
+ if (byType.containsKey(mixinTypeName)) {
+ types.add(mixinTypeName);
+ }
+ for (NodeType superType : mixinType.getDeclaredSupertypes()) {
+ if (byType.containsKey(superType.getName())) {
+ types.add(superType.getName());
+ }
+ }
+ }
+ // primary node type
+ NodeType primaryType = context.getPrimaryNodeType();
+ String primaryTypeName = primaryType.getName();
+ if (byType.containsKey(primaryTypeName)) {
+ types.add(primaryTypeName);
+ }
+ for (NodeType superType : primaryType.getDeclaredSupertypes()) {
+ if (byType.containsKey(superType.getName())) {
+ types.add(superType.getName());
+ }
+ }
+ // entity type
+ if (context.isNodeType(EntityType.entity.get())) {
+ if (context.hasProperty(EntityNames.ENTITY_TYPE)) {
+ String entityTypeName = context.getProperty(EntityNames.ENTITY_TYPE).getString();
+ if (byType.containsKey(entityTypeName)) {
+ types.add(entityTypeName);
+ }
+ }
+ }
+
+// if (context.getPath().equals("/")) {// root node
+// types.add("nt:folder");
+// }
+ if (CmsJcrUtils.isUserHome(context) && byType.containsKey("nt:folder")) {// home node
+ types.add("nt:folder");
+ }
+
+ if (types.size() == 0)
+ throw new IllegalArgumentException("No type found for " + context + " (" + listTypes(context) + ")");
+ String type = types.iterator().next();
+ if (!byType.containsKey(type))
+ throw new IllegalArgumentException("No component found for " + context + " with type " + type);
+ return byType.get(type).get();
+ } catch (RepositoryException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ 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(CmsUi cmsUi, String state) {
+ if (state == null)
+ return;
+ if (!state.startsWith("/")) {
+ if (cmsUi instanceof SuiteUi) {
+ SuiteUi ui = (SuiteUi) cmsUi;
+ if (LOGIN.equals(state)) {
+ String appTitle = "";
+ if (ui.getTitle() != null)
+ appTitle = ui.getTitle().lead();
+ ui.getCmsView().stateChanged(state, appTitle);
+ return;
+ }
+ Map<String, Object> 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) cmsUi;
+ 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 = CmsJcrUtils.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<String, Object> 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<String> types = LangUtils.toStringList(properties.get(EntityConstants.TYPE));
+ for (String type : types)
+ RankedObject.putIfHigherRank(uiProvidersByType, type, uiProvider, properties);
+ }
+ }
+
+ public void removeUiProvider(CmsUiProvider uiProvider, Map<String, Object> 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<CmsUiProvider>(uiProvider, properties))) {
+ uiProvidersByPid.remove(pid);
+ }
+ }
+ }
+ if (properties.containsKey(EntityConstants.TYPE)) {
+ List<String> types = LangUtils.toStringList(properties.get(EntityConstants.TYPE));
+ for (String type : types) {
+ if (uiProvidersByType.containsKey(type)) {
+ if (uiProvidersByType.get(type).equals(new RankedObject<CmsUiProvider>(uiProvider, properties))) {
+ uiProvidersByType.remove(type);
+ }
+ }
+ }
+ }
+ }
+
+ public void addLayer(SuiteLayer layer, Map<String, Object> 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<String> types = LangUtils.toStringList(properties.get(EntityConstants.TYPE));
+ for (String type : types)
+ RankedObject.putIfHigherRank(layersByType, type, layer, properties);
+ }
+ }
+
+ public void removeLayer(SuiteLayer layer, Map<String, Object> 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<SuiteLayer>(layer, properties))) {
+ layersByPid.remove(pid);
+ }
+ }
+ }
+ if (properties.containsKey(EntityConstants.TYPE)) {
+ List<String> types = LangUtils.toStringList(properties.get(EntityConstants.TYPE));
+ for (String type : types) {
+ if (layersByType.containsKey(type)) {
+ if (layersByType.get(type).equals(new RankedObject<CmsUiProvider>(layer, properties))) {
+ layersByType.remove(type);
+ }
+ }
+ }
+ }
+ }
+
+ public void setCmsUserManager(CmsUserManager cmsUserManager) {
+ this.cmsUserManager = cmsUserManager;
+ }
+
+ public Repository getRepository() {
+ return repository;
+ }
+
+ public void setRepository(Repository repository) {
+ this.repository = repository;
+ }
+
+
+}
--- /dev/null
+package org.argeo.suite.ui;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jcr.Node;
+
+import org.argeo.api.cms.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<String, Object> eventProperties(Node node) {
+ Map<String, Object> properties = new HashMap<>();
+ properties.put(NODE_PATH, Jcr.getPath(node));
+ properties.put(WORKSPACE, Jcr.getWorkspaceName(node));
+ return properties;
+ }
+
+ public static Map<String, Object> eventProperties(User user) {
+ Map<String, Object> properties = new HashMap<>();
+ properties.put(USERNAME, user.getName());
+ return properties;
+ }
+}
--- /dev/null
+package org.argeo.suite.ui;
+
+import org.argeo.cms.swt.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;
+}
--- /dev/null
+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;
+ }
+}
--- /dev/null
+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;
+}
--- /dev/null
+package org.argeo.suite.ui;
+
+import org.argeo.api.cms.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";
+ }
+
+}
--- /dev/null
+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.argeo.api.cms.CmsUi;
+import org.argeo.api.cms.CmsView;
+import org.argeo.api.cms.CmsLog;
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.cms.Localized;
+import org.argeo.cms.swt.CmsSwtUtils;
+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 implements CmsUi {
+ private static final long serialVersionUID = 6207018859086689108L;
+ private final static CmsLog log = CmsLog.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<String, SuiteLayer> layers = new HashMap<>();
+ private Map<String, Composite> workAreas = new HashMap<>();
+ private String currentLayerId = null;
+
+ private CmsView cmsView;
+
+ public SuiteUi(Composite parent, int style) {
+ super(parent, style);
+ cmsView = CmsSwtUtils.getCmsView(parent);
+ this.setLayout(CmsSwtUtils.noSpaceGridLayout());
+
+ header = new Composite(this, SWT.NONE);
+ header.setLayout(CmsSwtUtils.noSpaceGridLayout());
+ CmsSwtUtils.style(header, SuiteStyle.header);
+ header.setLayoutData(CmsSwtUtils.fillWidth());
+
+ belowHeader = new Composite(this, SWT.NONE);
+ belowHeader.setLayoutData(CmsSwtUtils.fillAll());
+
+ footer = new Composite(this, SWT.NONE);
+ footer.setLayout(CmsSwtUtils.noSpaceGridLayout());
+ CmsSwtUtils.style(footer, SuiteStyle.footer);
+ footer.setLayoutData(CmsSwtUtils.fillWidth());
+ }
+
+ public void refreshBelowHeader(boolean initApp) {
+ CmsSwtUtils.clear(belowHeader);
+ int style = getStyle();
+ if (initApp) {
+ belowHeader.setLayout(CmsSwtUtils.noSpaceGridLayout(3));
+
+ if (SWT.RIGHT_TO_LEFT == (style & SWT.RIGHT_TO_LEFT)) {// arabic, hebrew, etc.
+ sidePane = new Composite(belowHeader, SWT.NONE);
+ sidePane.setLayout(CmsSwtUtils.noSpaceGridLayout());
+ sidePane.setLayoutData(CmsSwtUtils.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(CmsSwtUtils.noSpaceGridLayout());
+ sidePane.setLayoutData(CmsSwtUtils.fillHeight());
+ }
+ leadPane.setLayoutData(CmsSwtUtils.fillHeight());
+ leadPane.setLayout(CmsSwtUtils.noSpaceGridLayout());
+ CmsSwtUtils.style(leadPane, SuiteStyle.leadPane);
+
+ dynamicArea.setLayoutData(CmsSwtUtils.fillAll());
+ dynamicArea.setLayout(new FormLayout());
+
+ } else {
+ belowHeader.setLayout(CmsSwtUtils.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));
+ CmsSwtUtils.style(workArea, SuiteStyle.workArea);
+ workArea.setLayoutData(CmsSwtUtils.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(CmsConstants.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 (CmsConstants.SYS_WORKSPACE.equals(workspaceName))
+ return sysSession;
+ else if (CmsConstants.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;
+ }
+
+}
--- /dev/null
+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.api.cms.CmsEditable;
+import org.argeo.api.cms.CmsEvent;
+import org.argeo.api.cms.CmsStyle;
+import org.argeo.api.cms.CmsTheme;
+import org.argeo.api.cms.CmsView;
+import org.argeo.cms.LocaleUtils;
+import org.argeo.cms.Localized;
+import org.argeo.cms.auth.CurrentUser;
+import org.argeo.cms.swt.CmsIcon;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.swt.dialogs.LightweightDialog;
+import org.argeo.cms.ui.util.CmsLink;
+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(CmsSwtUtils.fillWidth());
+ CmsSwtUtils.style(titleBar, SuiteStyle.titleContainer);
+
+ titleBar.setLayout(CmsSwtUtils.noSpaceGridLayout(new GridLayout(2, false)));
+ Label titleLbl = new Label(titleBar, SWT.NONE);
+ titleLbl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
+ CmsSwtUtils.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));
+ CmsSwtUtils.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));
+ CmsSwtUtils.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));
+ CmsSwtUtils.style(txt, SuiteStyle.simpleText);
+ return txt;
+ }
+
+ public static Text addFormInputField(Composite parent, String placeholder) {
+ Text txt = new Text(parent, SWT.BORDER);
+
+ GridData gridData = CmsSwtUtils.fillWidth();
+ txt.setLayoutData(gridData);
+
+ if (placeholder != null)
+ txt.setText(placeholder);
+
+ CmsSwtUtils.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));
+ CmsSwtUtils.style(lineComposite, SuiteStyle.formLine);
+ addFormLabel(lineComposite, label);
+ Text txt = addFormTextField(lineComposite, text, null);
+ txt.setEditable(false);
+ txt.setLayoutData(CmsSwtUtils.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));
+ CmsSwtUtils.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(CmsSwtUtils.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));
+ CmsSwtUtils.style(lineComposite, SuiteStyle.formLine);
+ addFormLabel(lineComposite, label);
+ Text txt = addFormInputField(lineComposite, placeholder);
+ txt.setLayoutData(CmsSwtUtils.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));
+ CmsSwtUtils.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(CmsSwtUtils.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(CmsSwtUtils.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(CmsSwtUtils.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));
+ CmsSwtUtils.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);
+ CmsSwtUtils.markup(img);
+ StringBuffer txt = new StringBuffer();
+ String target = toLink(link);
+ if (target != null)
+ txt.append("<a href='").append(target).append("'>");
+ txt.append(CmsUiUtils.img(fileNode, width.toString(), height.toString()));
+ if (target != null)
+ txt.append("</a>");
+ 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(CmsSwtUtils.fillAll());
+ scroll.setLayout(CmsSwtUtils.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(CmsSwtUtils.fillAll());
+ Label bigImg = new Label(c, SWT.NONE);
+ CmsSwtUtils.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) {
+ return node != null ? "#" + CmsUiUtils.cleanPathForUrl(SuiteApp.nodeToState(node)) : null;
+ }
+
+ 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);
+ CmsSwtUtils.markup(lbl);
+ StringBuilder txt = new StringBuilder();
+ txt.append("<a class='" + plainCssAnchorClass + "'");
+ txt.append(" href='").append(url).append("'");
+ if (newWindow) {
+ txt.append(" target='blank_'");
+ }
+ txt.append(">");
+ txt.append(label);
+ txt.append("</a>");
+ 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 = CmsSwtUtils.getCmsTheme(parent);
+ Button button = new Button(parent, SWT.PUSH);
+ CmsSwtUtils.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);
+ CmsSwtUtils.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));
+ }
+ CmsSwtUtils.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);
+// }
+// }
+
+}
--- /dev/null
+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;
+ }
+
+}
--- /dev/null
+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);
+// }
+}
--- /dev/null
+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();
+ }
+ }
+}
--- /dev/null
+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();
+ }
+ }
+}
--- /dev/null
+package org.argeo.suite.ui.widgets;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.argeo.cms.swt.CmsSwtUtils;
+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<String, Button> actionButtons = new HashMap<String, Button>();
+
+ 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());
+ CmsSwtUtils.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);
+}
--- /dev/null
+package org.argeo.suite.ui.widgets;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.argeo.cms.swt.CmsSwtUtils;
+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)
+ CmsSwtUtils.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<String> getFilteredValues(String filter);
+
+ protected void refreshValues() {
+ List<String> 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);
+ }
+ }
+ });
+ }
+}
--- /dev/null
+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();
+ };
+
+}
--- /dev/null
+package org.argeo.suite.ui.widgets;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jcr.Node;
+
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.swt.Selected;
+import org.argeo.cms.ui.CmsUiProvider;
+import org.argeo.cms.ui.viewers.Section;
+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<Section> 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);
+ CmsSwtUtils.style(parent, bodyStyle);
+
+ setLayout(CmsSwtUtils.noSpaceGridLayout());
+
+ // TODO manage tabs at bottom or sides
+ headers = new Composite(this, SWT.NONE);
+ headers.setLayoutData(CmsSwtUtils.fillWidth());
+ body = new Composite(this, SWT.NONE);
+ body.setLayoutData(CmsSwtUtils.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(CmsSwtUtils.noSpaceGridLayout(new GridLayout(tabCount, true)));
+
+ if (sections.size() == 0) {
+ Composite emptyHeader = new Composite(headers, SWT.NONE);
+ emptyHeader.setLayoutData(CmsSwtUtils.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);
+ CmsSwtUtils.style(sectionHeader, selected ? tabSelectedStyle : tabStyle);
+ int headerColumns = singleTab ? 1 : 2;
+ sectionHeader.setLayout(new GridLayout(headerColumns, false));
+ sectionHeader.setLayout(CmsSwtUtils.noSpaceGridLayout(headerColumns));
+ Button title = new Button(sectionHeader, SWT.FLAT);
+ CmsSwtUtils.style(title, selected ? tabSelectedStyle : tabStyle);
+ title.setLayoutData(CmsSwtUtils.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");
+ CmsSwtUtils.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)
+ CmsSwtUtils.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();
+ CmsSwtUtils.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;
+ }
+
+}
--- /dev/null
+package org.argeo.suite.ui.widgets;
+
+import org.argeo.cms.swt.CmsSwtUtils;
+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(CmsSwtUtils.fillWidth());
+ createSearchUi(searchC);
+
+ Composite bodyC = new Composite(parent, SWT.NONE);
+ bodyC.setLayoutData(CmsSwtUtils.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(CmsSwtUtils.noSpaceGridLayout());
+ searchT = new Text(parent, SWT.MULTI | SWT.BORDER);
+ searchT.setLayoutData(CmsSwtUtils.fillWidth());
+ }
+
+ protected void createTreeUi(Composite parent) {
+ parent.setLayout(CmsSwtUtils.noSpaceGridLayout());
+ treeViewer = new TreeViewer(parent);
+ treeViewer.getTree().setLayoutData(CmsSwtUtils.fillAll());
+ }
+
+ protected void createSearchResultsUi(Composite parent) {
+ parent.setLayout(CmsSwtUtils.noSpaceGridLayout());
+ searchResultsViewer = new TreeViewer(parent);
+ searchResultsViewer.getTree().setLayoutData(CmsSwtUtils.fillAll());
+ }
+
+ public TreeViewer getTreeViewer() {
+ return treeViewer;
+ }
+
+ public TreeViewer getSearchResultsViewer() {
+ return searchResultsViewer;
+ }
+
+}
--- /dev/null
+package org.argeo.support.openlayers;
+
+import org.argeo.cms.swt.CmsSwtUtils;
+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(CmsSwtUtils.noSpaceGridLayout());
+ div = new Label(this, SWT.NONE);
+ CmsSwtUtils.markup(div);
+ CmsSwtUtils.disableMarkupValidation(div);
+ div.setText("<div id='map'></div>");
+ div.setLayoutData(CmsSwtUtils.fillAll());
+ }
+
+}
--- /dev/null
+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.argeo.api.cms.CmsView;
+import org.argeo.api.cms.CmsLog;
+import org.argeo.api.cms.CmsConstants;
+import org.argeo.cms.swt.CmsSwtUtils;
+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 CmsLog log = CmsLog.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<String> geoJsonSources = new ArrayList<>();
+ private Map<String, String> vectorSources = new HashMap<>();
+ private Map<String, String> layerStyles = new HashMap<>();
+
+ private CmsView cmsView;
+
+ public OpenLayersMap(Composite parent, int style, URL mapHtml) {
+ super(parent, style);
+ cmsView = CmsSwtUtils.getCmsView(parent);
+ setLayout(new GridLayout());
+
+ browser = new Browser(this, SWT.BORDER);
+ browser.setLayoutData(CmsSwtUtils.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<Node> 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<Node> geoPoints) throws RepositoryException {
+ this.vectorSource = asVectorSource(geoPoints);
+ if (log.isTraceEnabled())
+ log.trace("Vector source: " + vectorSource);
+ renderVectorSource();
+ }
+
+ public void addPoints(String layerName, List<Node> 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<String, Object> properties = new HashMap<>();
+ properties.put(SuiteEvent.NODE_PATH, path);
+ properties.put(SuiteEvent.WORKSPACE, CmsConstants.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;
+ }
+ }
+}
--- /dev/null
+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.swt.CmsSwtUtils;
+import org.argeo.cms.ui.CmsUiProvider;
+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 {
+ CmsSwtUtils.clear(parent);
+ Query query = context.getSession().getWorkspace().getQueryManager()
+ .createQuery("SELECT * FROM [" + EntityType.geopoint.get() + "]", Query.JCR_SQL2);
+ List<Node> geoPoints = JcrUtils.nodeIteratorToList(query.execute().getNodes());
+ OpenLayersMap map = new OpenLayersMap(parent, SWT.NONE, getClass().getResource("map-osm.html"));
+ map.setLayoutData(CmsSwtUtils.fillAll());
+
+ // apafMap.setZoom(7);
+ // apafMap.setCenter(-2.472, 8.010);
+ map.addPoints(geoPoints);
+ }
+}
--- /dev/null
+<html lang="en">
+<head>
+<link rel="stylesheet"
+ href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.4.3/css/ol.css"
+ type="text/css">
+<style>
+</style>
+<script
+ src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.4.3/build/ol.js"></script>
+</head>
+<body>
+ <div id="map" class="map"></div>
+ <script type="text/javascript">
+ // default OSM
+ var source_OSM = new ol.source.OSM();
+
+ var map = new ol.Map({
+ target : 'map',
+ layers : [ new ol.layer.Tile({
+ source : source_OSM
+ }) ],
+ view : new ol.View({
+ center : ol.proj.fromLonLat([ 34, 34 ]),
+ zoom : 4
+ })
+ });
+ map.on('rendercomplete', e => {
+ console.log('Render completed.');
+ renderCompleted();
+ });
+ var select = new ol.interaction.Select();
+ map.addInteraction(select);
+ select.on('select',function (e) {
+ if(e.selected.length>0){
+ console.log('Feature selected: '+e.selected[0].get('path'));
+ onFeatureSelect(e.selected[0].get('path'));
+ }
+ });
+ </script>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+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
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
- <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
- <classpathentry kind="src" path="src"/>
- <classpathentry kind="output" path="bin"/>
-</classpath>
+++ /dev/null
-/bin/
-/target/
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>org.argeo.entity.api</name>
- <comment></comment>
- <projects>
- </projects>
- <buildSpec>
- <buildCommand>
- <name>org.eclipse.jdt.core.javabuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.ManifestBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.SchemaBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>org.eclipse.pde.PluginNature</nature>
- <nature>org.eclipse.jdt.core.javanature</nature>
- </natures>
-</projectDescription>
+++ /dev/null
-/MANIFEST.MF
+++ /dev/null
-Require-Capability:\
-cms.datamodel;filter:="(name=jcrx)"
-
-Provide-Capability:\
-cms.datamodel; name=entity; cnd=/org/argeo/entity/entity.cnd
+++ /dev/null
-source.. = src/
-output.. = bin/
-bin.includes = META-INF/,\
- .
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.argeo.suite</groupId>
- <artifactId>argeo-suite</artifactId>
- <version>2.3-SNAPSHOT</version>
- <relativePath>..</relativePath>
- </parent>
- <artifactId>org.argeo.entity.api</artifactId>
- <name>Entity API</name>
- <packaging>jar</packaging>
- <dependencies>
- <!-- Argeo Commons -->
- <dependency>
- <groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.util</artifactId>
- <version>${version.argeo-commons}</version>
- </dependency>
- </dependencies>
-</project>
+++ /dev/null
-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";
-
-}
+++ /dev/null
-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();
-}
+++ /dev/null
-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;
- }
-
-}
+++ /dev/null
-package org.argeo.entity;
-
-import org.argeo.util.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";
-}
+++ /dev/null
-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";
- }
-
-}
+++ /dev/null
-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";
-}
+++ /dev/null
-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> {
- 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();
- }
-}
+++ /dev/null
-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<? extends Term> getSubTerms();
-
- Term getParentTerm();
-
-}
+++ /dev/null
-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<Term> listAllTerms(String typology);
-
-}
+++ /dev/null
-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<? extends Term> getSubTerms();
-
- Term findTermByName(String name);
-}
+++ /dev/null
-// Standard namespaces
-<xsd = "http://www.w3.org/2001/XMLSchema">
-<h = "http://www.w3.org/1999/xhtml">
-// see https://www.w3.org/2003/01/geo/
-<geo = "http://www.w3.org/2003/01/geo/wgs84_pos#">
-<svg = "http://www.w3.org/2000/svg">
-
-<ldap = "http://www.argeo.org/ns/ldap">
-<entity = 'http://www.argeo.org/ns/entity'>
-
-[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)
<dependencies>
<dependency>
<groupId>org.argeo.suite</groupId>
- <artifactId>org.argeo.entity.api</artifactId>
+ <artifactId>org.argeo.app.api</artifactId>
<version>2.3-SNAPSHOT</version>
</dependency>
+++ /dev/null
-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.cms.jcr.CmsJcrUtils;
-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<String, String> properties) throws RepositoryException {
- Session adminSession = CmsJcrUtils.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<String, String> 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();
- }
-
-}
+++ /dev/null
-package org.argeo.entity.ui.forms;
-
-import javax.jcr.Item;
-
-import org.argeo.api.cms.CmsTheme;
-import org.argeo.cms.Localized;
-import org.argeo.cms.swt.CmsIcon;
-import org.argeo.cms.swt.CmsSwtUtils;
-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 = CmsSwtUtils.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(CmsSwtUtils.fillAll());
- }
-
- protected void setContainerLayoutData(Composite composite) {
- composite.setLayoutData(CmsSwtUtils.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("+");
- }
-}
+++ /dev/null
-package org.argeo.entity.ui.forms;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.jcr.Item;
-
-import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.swt.MouseDoubleClick;
-import org.argeo.cms.swt.MouseDown;
-import org.argeo.cms.swt.Selected;
-import org.argeo.cms.ui.forms.FormStyle;
-import org.argeo.cms.ui.viewers.EditablePart;
-import org.argeo.cms.ui.widgets.ContextOverlay;
-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 CmsLog log = CmsLog.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 = CmsSwtUtils.noMarginsRowLayout(rl);
-// rl.wrap = true;
-// rl.justify = true;
- placeholder.setLayout(rl);
- List<Term> currentValue = getValue();
- if (currentValue != null && !currentValue.isEmpty()) {
- for (Term value : currentValue) {
- Composite block = new Composite(placeholder, SWT.NONE);
- block.setLayout(CmsSwtUtils.noSpaceGridLayout(3));
- Label lbl = new Label(block, SWT.NONE);
- String display = getTermLabel(value);
- lbl.setText(display);
- CmsSwtUtils.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<Term> curr = getValue();
- List<Term> 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(CmsSwtUtils.noSpaceGridLayout(3));
-
- createHighlight(block);
-
- Text txt = new Text(block, SWT.SINGLE | SWT.BORDER);
- txt.setLayoutData(CmsSwtUtils.fillWidth());
-// txt.setMessage("[new]");
-
- CmsSwtUtils.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) {
- CmsSwtUtils.clear(contextArea);
- List<? extends Term> terms = termsManager.listAllTerms(typology.getId());
- List<Term> 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<Term> newValue = new ArrayList<>();
- List<Term> curr = getValue();
- if (currentValue != null)
- newValue.addAll(curr);
- newValue.add(term);
- setValue(newValue);
- contextArea.hide();
- stopEditing();
- });
- }
- contextArea.show();
- }
-
- protected List<Term> getValue() {
- String property = typology.getId();
- List<String> curr = Jcr.getMultiple(getNode(), property);
- List<Term> 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<Term> value) {
- String property = typology.getId();
- List<String> ids = new ArrayList<>();
- for (Term term : value) {
- ids.add(term.getId());
- }
- Jcr.set(getNode(), property, ids);
- Jcr.save(getNode());
- }
-
-}
+++ /dev/null
-package org.argeo.entity.ui.forms;
-
-import java.util.List;
-
-import javax.jcr.Item;
-
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.swt.MouseDoubleClick;
-import org.argeo.cms.swt.MouseDown;
-import org.argeo.cms.swt.Selected;
-import org.argeo.cms.ui.forms.FormStyle;
-import org.argeo.cms.ui.viewers.EditablePart;
-import org.argeo.cms.ui.widgets.ContextOverlay;
-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(CmsSwtUtils.noSpaceGridLayout(3));
-
- createHighlight(block);
-
- Text txt = new Text(block, SWT.SINGLE | SWT.BORDER);
- CmsSwtUtils.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(CmsSwtUtils.noSpaceGridLayout(2));
- Term currentValue = getValue();
- if (currentValue != null) {
- Label lbl = new Label(block, SWT.SINGLE);
- String display = getTermLabel(currentValue);
- lbl.setText(display);
- CmsSwtUtils.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) {
- CmsSwtUtils.clear(contextArea);
- List<? extends Term> 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());
- }
-}
+++ /dev/null
-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<String, String> 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() {
- }
-}
+++ /dev/null
-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<String> shapes = new ArrayList<>();
- for (JsonNode shape : coord) {
- StringBuffer sb = new StringBuffer();
- sb.append("<polyline style=\"stroke-width:0.00000003;stroke:#000000;\" points=\"");
- for (JsonNode latlng : shape) {
- double lat = latlng.get(0).asDouble();
- double y = lat * ratio;
- if (y < minY)
- minY = y;
- if (y > 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("</polyline>\n");
- shapes.add(sb.toString());
- }
-
- double width = maxX - minX;
- double height = maxY - minY;
- out.write("<svg xmlns=\"http://www.w3.org/2000/svg\"\n");
- out.write(" width=\"" + (int) (width * 1000) + "\"\n");
- out.write(" height=\"" + (int) (height * 1000) + "\"\n");
- out.write(" viewBox=\"" + minX + "," + minY + "," + width + "," + height + "\"\n");
- out.write(">\n");
- for (String shape : shapes) {
- out.write(shape);
- out.write("\n");
- }
- out.write("</svg>");
- } catch (IOException e) {
- throw new RuntimeException("Cannot convert " + source + " to " + target, e);
- }
- }
-
-}
+++ /dev/null
-package org.argeo.support.openlayers;
-
-import org.argeo.cms.swt.CmsSwtUtils;
-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(CmsSwtUtils.noSpaceGridLayout());
- div = new Label(this, SWT.NONE);
- CmsSwtUtils.markup(div);
- CmsSwtUtils.disableMarkupValidation(div);
- div.setText("<div id='map'></div>");
- div.setLayoutData(CmsSwtUtils.fillAll());
- }
-
-}
+++ /dev/null
-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.argeo.api.cms.CmsView;
-import org.argeo.api.cms.CmsLog;
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.cms.swt.CmsSwtUtils;
-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 CmsLog log = CmsLog.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<String> geoJsonSources = new ArrayList<>();
- private Map<String, String> vectorSources = new HashMap<>();
- private Map<String, String> layerStyles = new HashMap<>();
-
- private CmsView cmsView;
-
- public OpenLayersMap(Composite parent, int style, URL mapHtml) {
- super(parent, style);
- cmsView = CmsSwtUtils.getCmsView(parent);
- setLayout(new GridLayout());
-
- browser = new Browser(this, SWT.BORDER);
- browser.setLayoutData(CmsSwtUtils.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<Node> 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<Node> geoPoints) throws RepositoryException {
- this.vectorSource = asVectorSource(geoPoints);
- if (log.isTraceEnabled())
- log.trace("Vector source: " + vectorSource);
- renderVectorSource();
- }
-
- public void addPoints(String layerName, List<Node> 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<String, Object> properties = new HashMap<>();
- properties.put(SuiteEvent.NODE_PATH, path);
- properties.put(SuiteEvent.WORKSPACE, CmsConstants.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;
- }
- }
-}
+++ /dev/null
-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.swt.CmsSwtUtils;
-import org.argeo.cms.ui.CmsUiProvider;
-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 {
- CmsSwtUtils.clear(parent);
- Query query = context.getSession().getWorkspace().getQueryManager()
- .createQuery("SELECT * FROM [" + EntityType.geopoint.get() + "]", Query.JCR_SQL2);
- List<Node> geoPoints = JcrUtils.nodeIteratorToList(query.execute().getNodes());
- OpenLayersMap map = new OpenLayersMap(parent, SWT.NONE, getClass().getResource("map-osm.html"));
- map.setLayoutData(CmsSwtUtils.fillAll());
-
- // apafMap.setZoom(7);
- // apafMap.setCenter(-2.472, 8.010);
- map.addPoints(geoPoints);
- }
-}
+++ /dev/null
-<html lang="en">
-<head>
-<link rel="stylesheet"
- href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.4.3/css/ol.css"
- type="text/css">
-<style>
-</style>
-<script
- src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.4.3/build/ol.js"></script>
-</head>
-<body>
- <div id="map" class="map"></div>
- <script type="text/javascript">
- // default OSM
- var source_OSM = new ol.source.OSM();
-
- var map = new ol.Map({
- target : 'map',
- layers : [ new ol.layer.Tile({
- source : source_OSM
- }) ],
- view : new ol.View({
- center : ol.proj.fromLonLat([ 34, 34 ]),
- zoom : 4
- })
- });
- map.on('rendercomplete', e => {
- console.log('Render completed.');
- renderCompleted();
- });
- var select = new ol.interaction.Select();
- map.addInteraction(select);
- select.on('select',function (e) {
- if(e.selected.length>0){
- console.log('Feature selected: '+e.selected[0].get('path'));
- onFeatureSelect(e.selected[0].get('path'));
- }
- });
- </script>
-</body>
-</html>
\ No newline at end of file
+++ /dev/null
-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
+++ /dev/null
-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.api.cms.CmsTheme;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.ui.CmsUiProvider;
-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 = CmsSwtUtils.getCmsTheme(parent);
-
- parent.setLayout(new GridLayout());
- Ui ui = new Ui(parent, SWT.NONE);
- ui.setLayoutData(CmsSwtUtils.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) {
- CmsSwtUtils.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) {
- CmsSwtUtils.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<String, Node> 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) {
- }
-
- }
-
-}
+++ /dev/null
-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();
- }
-}
+++ /dev/null
-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 org.argeo.api.cms.CmsLog;
-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 CmsLog log = CmsLog.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());
- // 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);
- }
-
- /**
- * 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 = "<i>Unknown</i>";
- 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);
- }
-}
+++ /dev/null
-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.argeo.api.cms.CmsLog;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.ui.fs.FileDrop;
-import org.argeo.cms.ui.fs.FsStyles;
-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 CmsLog log = CmsLog.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<ColumnDefinition> 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);
- CmsSwtUtils.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);
- CmsSwtUtils.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 = "<i>Unknown</i>";
- addProperty(rightPanelCmp, "Type", mimeType);
- addProperty(rightPanelCmp, "Size", FsUiUtils.humanReadableByteCount(Files.size(path), false));
- }
-
- // read all attributes
-// Map<String, Object> 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<Path> 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;
- }
-
-}
+++ /dev/null
-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.api.cms.CmsView;
-import org.argeo.cms.fs.CmsFsUtils;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.ui.CmsUiProvider;
-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 = CmsSwtUtils.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(CmsSwtUtils.fillAll());
- dfc.populate(cmsView.doAs(() -> CmsFsUtils.getPath(nodeFileSystemProvider, context)));
- return dfc;
- }
-
- public void setNodeFileSystemProvider(FileSystemProvider nodeFileSystemProvider) {
- this.nodeFileSystemProvider = nodeFileSystemProvider;
- }
-
-}
+++ /dev/null
-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.cms.CmsView;
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.cms.fs.CmsFsUtils;
-import org.argeo.cms.jcr.CmsJcrUtils;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.ui.CmsUiProvider;
-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 = CmsSwtUtils.getCmsView(parent);
- Node homeNode = CmsJcrUtils.getUserHome(cmsView.doAs(() -> Jcr.login(repository, CmsConstants.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(CmsSwtUtils.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;
- }
-
-}
+++ /dev/null
-package org.argeo.library.ui;
-
-import static org.argeo.cms.swt.dialogs.CmsMessageDialog.openConfirm;
-import static org.argeo.cms.swt.dialogs.CmsMessageDialog.openError;
-import static org.argeo.cms.swt.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.argeo.api.cms.CmsLog;
-import org.argeo.cms.swt.dialogs.CmsFeedback;
-import org.argeo.eclipse.ui.EclipseUiUtils;
-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 CmsLog log = CmsLog.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<String, String> params = new HashMap<String, String>();
-// 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<Object> iterator = selection.iterator();
- List<Path> 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<Path>() {
- @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<Object> iterator = selection.iterator();
-// List<Node> 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;
-// }
-}
+++ /dev/null
-package org.argeo.people.ui;
-
-import java.util.Set;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.api.cms.CmsTheme;
-import org.argeo.cms.CmsUserManager;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.swt.Selected;
-import org.argeo.cms.swt.dialogs.CmsWizardDialog;
-import org.argeo.cms.ui.CmsUiProvider;
-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.argeo.util.naming.LdapAttrs;
-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 = CmsSwtUtils.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(CmsSwtUtils.fillWidth());
- bottom.setLayout(CmsSwtUtils.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);
- CmsSwtUtils.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);
- CmsSwtUtils.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(CmsSwtUtils.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<User> 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;
- }
-
-}
+++ /dev/null
-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.swt.CmsSwtUtils;
-import org.argeo.cms.ui.CmsUiProvider;
-import org.argeo.cms.ui.viewers.Section;
-import org.argeo.suite.ui.SuiteMsg;
-import org.argeo.suite.ui.SuiteUiUtils;
-import org.argeo.util.naming.LdapAttrs;
-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(CmsSwtUtils.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(CmsSwtUtils.fillWidth());
- rolesSection.setLayout(new GridLayout());
- // new Label(rolesSection, SWT.NONE).setText("Roles:");
- List<String> 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<String, Object> properties) {
- availableRoles = (String[]) properties.get("availableRoles");
- }
-}
+++ /dev/null
-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.swt.CmsSwtUtils;
-import org.argeo.cms.ui.CmsUiProvider;
-import org.argeo.cms.ui.viewers.Section;
-import org.argeo.suite.ui.SuiteMsg;
-import org.argeo.suite.ui.SuiteUiUtils;
-import org.argeo.util.naming.LdapAttrs;
-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(CmsSwtUtils.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(CmsSwtUtils.fillWidth());
- rolesSection.setLayout(new GridLayout());
- // new Label(rolesSection, SWT.NONE).setText("Roles:");
- List<String> 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<String, Object> properties) {
- availableRoles = (String[]) properties.get("availableRoles");
- }
-}
+++ /dev/null
-package org.argeo.people.ui;
-
-import java.util.Set;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.api.cms.CmsTheme;
-import org.argeo.cms.CmsUserManager;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.swt.Selected;
-import org.argeo.cms.swt.dialogs.CmsWizardDialog;
-import org.argeo.cms.ui.CmsUiProvider;
-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.argeo.util.naming.LdapAttrs;
-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 = CmsSwtUtils.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(CmsSwtUtils.fillWidth());
- bottom.setLayout(CmsSwtUtils.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);
- CmsSwtUtils.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);
- CmsSwtUtils.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(CmsSwtUtils.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<User> 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;
- }
-
-}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
- <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
- <classpathentry kind="src" path="src"/>
- <classpathentry kind="output" path="bin"/>
-</classpath>
+++ /dev/null
-/bin/
-/target/
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>org.argeo.publishing.ui</name>
- <comment></comment>
- <projects>
- </projects>
- <buildSpec>
- <buildCommand>
- <name>org.eclipse.jdt.core.javabuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.ManifestBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.SchemaBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.ds.core.builder</name>
- <arguments>
- </arguments>
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>org.eclipse.pde.PluginNature</nature>
- <nature>org.eclipse.jdt.core.javanature</nature>
- </natures>
-</projectDescription>
+++ /dev/null
-/MANIFEST.MF
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="DocBook 4 Converter">
- <implementation class="org.argeo.docbook.Dbk4Converter"/>
- <service>
- <provide interface="org.argeo.docbook.Dbk4Converter"/>
- </service>
-</scr:component>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="DocBook Servlet">
- <implementation class="org.argeo.publishing.servlet.DbkServlet"/>
- <service>
- <provide interface="javax.servlet.Servlet"/>
- </service>
- <property name="osgi.http.whiteboard.servlet.pattern" type="String" value="/dbk/*"/>
- <property name="osgi.http.whiteboard.context.select" type="String" value="(osgi.http.whiteboard.context.name=htmlServletContext)"/>"/>
- <reference bind="setRepository" cardinality="1..1" interface="javax.jcr.Repository" name="Repository" policy="static" target="(cn=ego)"/>
- <reference bind="addTheme" cardinality="0..n" interface="org.argeo.cms.ui.CmsTheme" name="CmsTheme" policy="dynamic" unbind="removeTheme"/>
-</scr:component>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0">
- <implementation class="org.argeo.publishing.ui.DocumentUiProvider"/>
- <service>
- <provide interface="org.argeo.cms.ui.CmsUiProvider"/>
- </service>
- <properties entry="config/documentUiProvider.properties"/>
-</scr:component>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0">
- <implementation class="org.argeo.publishing.servlet.FontsServlet"/>
- <service>
- <provide interface="javax.servlet.Servlet"/>
- </service>
- <property name="osgi.http.whiteboard.servlet.pattern" type="String" value="/fonts/*"/>
- <property name="osgi.http.whiteboard.context.select" type="String" value="(osgi.http.whiteboard.context.name=default)"/>
- <reference bind="addTheme" cardinality="0..n" interface="org.argeo.cms.ui.CmsTheme" name="CmsTheme" policy="dynamic" unbind="removeTheme"/>
-</scr:component>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy">
- <implementation class="org.argeo.cms.servlet.CmsServletContext"/>
- <service>
- <provide interface="org.osgi.service.http.context.ServletContextHelper"/>
- </service>
- <property name="osgi.http.whiteboard.context.name" type="String" value="htmlServletContext"/>
- <property name="osgi.http.whiteboard.context.path" type="String" value="/html"/>
-</scr:component>
+++ /dev/null
-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
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy">
- <implementation class="org.argeo.suite.ui.DefaultEditionLayer"/>
- <properties entry="config/wwwLayer.properties"/>
- <service>
- <provide interface="org.argeo.suite.ui.SuiteLayer"/>
- </service>
- <reference bind="setWorkArea" cardinality="1..1" interface="org.argeo.cms.ui.CmsUiProvider" name="CmsUiProvider" policy="dynamic" target="(service.pid=argeo.publishing.ui.documentUiProvider)"/>
-</scr:component>
+++ /dev/null
-Import-Package:\
-org.osgi.service.http.context,\
-javax.jcr.nodetype,\
-org.osgi.service.event,\
-org.argeo.suite.ui,\
-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
+++ /dev/null
-output.. = bin/
-bin.includes = META-INF/,\
- .,\
- OSGI-INF/,\
- OSGI-INF/documentUiProvider.xml,\
- OSGI-INF/dbk4Converter.xml
-source.. = src/
+++ /dev/null
-service.pid=argeo.publishing.ui.documentUiProvider
-
-entity.type=entity:document,nt:file
\ No newline at end of file
+++ /dev/null
-service.pid=argeo.publishing.ui.wwwLayer
-
-title=Web
-icon=map
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.argeo.suite</groupId>
- <artifactId>argeo-suite</artifactId>
- <version>2.3-SNAPSHOT</version>
- <relativePath>..</relativePath>
- </parent>
- <artifactId>org.argeo.publishing.ui</artifactId>
- <name>Publishing UI</name>
- <packaging>jar</packaging>
- <dependencies>
- <dependency>
- <groupId>org.argeo.suite</groupId>
- <artifactId>org.argeo.suite.ui</artifactId>
- <version>2.3-SNAPSHOT</version>
- </dependency>
-
- <!-- Specific -->
- <dependency>
- <groupId>org.argeo.commons.rap</groupId>
- <artifactId>org.argeo.swt.specific.rap</artifactId>
- <version>${version.argeo-commons}</version>
- <scope>provided</scope>
- </dependency>
-
- <!-- Eclipse E4 -->
- <dependency>
- <groupId>org.argeo.tp</groupId>
- <artifactId>argeo-tp-rap-e4</artifactId>
- <version>${version.argeo-tp}</version>
- <type>pom</type>
- <scope>provided</scope>
- </dependency>
-
- </dependencies>
-</project>
+++ /dev/null
-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();
- }
- }
-
-}
+++ /dev/null
-package org.argeo.docbook;
-
-/** Supported DocBook attributes. */
-public enum DbkAttr {
- role,
- //
- fileref, contentwidth, contentdepth
- //
- ;
-
- public final static String XLINK_HREF = "xlink:href";
-
-}
+++ /dev/null
-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,
- //
- ;
-}
+++ /dev/null
-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";
- }
-
-}
+++ /dev/null
-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.argeo.api.cms.CmsLog;
-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 CmsLog log = CmsLog.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() {
- }
-
-}
+++ /dev/null
-<?xml version="1.0"?>
-<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
- xmlns:exsl="http://exslt.org/common"
- xmlns:db = "http://docbook.org/ns/docbook"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- exclude-result-prefixes="exsl db"
- version="1.0">
-
-<!--
-# ======================================================================
-# This file is part of DocBook V5.0CR5
-#
-# Copyright 2005 Norman Walsh, Sun Microsystems, Inc., and the
-# Organization for the Advancement of Structured Information
-# Standards (OASIS).
-#
-# Release: $Id: db4-upgrade.xsl 7660 2008-02-06 13:48:36Z nwalsh $
-#
-# Permission to use, copy, modify and distribute this stylesheet
-# and its accompanying documentation for any purpose and without fee
-# is hereby granted in perpetuity, provided that the above copyright
-# notice and this paragraph appear in all copies. The copyright
-# holders make no representation about the suitability of the schema
-# for any purpose. It is provided "as is" without expressed or implied
-# warranty.
-#
-# Please direct all questions, bug reports, or suggestions for changes
-# to the docbook@lists.oasis-open.org mailing list. For more
-# information, see http://www.oasis-open.org/docbook/.
-#
-# ======================================================================
--->
-
-<xsl:variable name="version" select="'1.0'"/>
-
-<xsl:output method="xml" encoding="utf-8" indent="no" omit-xml-declaration="yes"/>
-
-<xsl:preserve-space elements="*"/>
-<xsl:param name="rootid">
- <xsl:choose>
- <xsl:when test="/*/@id">
- <xsl:value-of select="/*/@id"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:text>UNKNOWN</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
-</xsl:param>
-
-<xsl:param name="defaultDate" select="''"/>
-
-<xsl:template match="/">
- <xsl:variable name="converted">
- <xsl:apply-templates/>
- </xsl:variable>
- <xsl:comment>
- <xsl:text> Converted by db4-upgrade version </xsl:text>
- <xsl:value-of select="$version"/>
- <xsl:text> </xsl:text>
- </xsl:comment>
- <xsl:text> </xsl:text>
- <xsl:apply-templates select="exsl:node-set($converted)/*" mode="addNS"/>
-</xsl:template>
-
-<xsl:template match="bookinfo|chapterinfo|articleinfo|artheader|appendixinfo
- |blockinfo
- |bibliographyinfo|glossaryinfo|indexinfo|setinfo
- |setindexinfo
- |sect1info|sect2info|sect3info|sect4info|sect5info
- |sectioninfo
- |refsect1info|refsect2info|refsect3info|refsectioninfo
- |referenceinfo|partinfo"
- priority="200">
- <info>
- <xsl:call-template name="copy.attributes"/>
-
- <!-- titles can be inside or outside or both. fix that -->
- <xsl:choose>
- <xsl:when test="title and following-sibling::title">
- <xsl:if test="title != following-sibling::title">
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Check </xsl:text>
- <xsl:value-of select="name(..)"/>
- <xsl:text> title.</xsl:text>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- <xsl:apply-templates select="title" mode="copy"/>
- </xsl:when>
- <xsl:when test="title">
- <xsl:apply-templates select="title" mode="copy"/>
- </xsl:when>
- <xsl:when test="following-sibling::title">
- <xsl:apply-templates select="following-sibling::title" mode="copy"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Check </xsl:text>
- <xsl:value-of select="name(..)"/>
- <xsl:text>: no title.</xsl:text>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:otherwise>
- </xsl:choose>
-
- <xsl:choose>
- <xsl:when test="titleabbrev and following-sibling::titleabbrev">
- <xsl:if test="titleabbrev != following-sibling::titleabbrev">
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Check </xsl:text>
- <xsl:value-of select="name(..)"/>
- <xsl:text> titleabbrev.</xsl:text>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- <xsl:apply-templates select="titleabbrev" mode="copy"/>
- </xsl:when>
- <xsl:when test="titleabbrev">
- <xsl:apply-templates select="titleabbrev" mode="copy"/>
- </xsl:when>
- <xsl:when test="following-sibling::titleabbrev">
- <xsl:apply-templates select="following-sibling::titleabbrev" mode="copy"/>
- </xsl:when>
- </xsl:choose>
-
- <xsl:choose>
- <xsl:when test="subtitle and following-sibling::subtitle">
- <xsl:if test="subtitle != following-sibling::subtitle">
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Check </xsl:text>
- <xsl:value-of select="name(..)"/>
- <xsl:text> subtitle.</xsl:text>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- <xsl:apply-templates select="subtitle" mode="copy"/>
- </xsl:when>
- <xsl:when test="subtitle">
- <xsl:apply-templates select="subtitle" mode="copy"/>
- </xsl:when>
- <xsl:when test="following-sibling::subtitle">
- <xsl:apply-templates select="following-sibling::subtitle" mode="copy"/>
- </xsl:when>
- </xsl:choose>
-
- <xsl:apply-templates/>
- </info>
-</xsl:template>
-
-<xsl:template match="objectinfo|prefaceinfo|refsynopsisdivinfo
- |screeninfo|sidebarinfo"
- priority="200">
- <info>
- <xsl:call-template name="copy.attributes"/>
-
- <!-- titles can be inside or outside or both. fix that -->
- <xsl:choose>
- <xsl:when test="title and following-sibling::title">
- <xsl:if test="title != following-sibling::title">
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Check </xsl:text>
- <xsl:value-of select="name(..)"/>
- <xsl:text> title.</xsl:text>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- <xsl:apply-templates select="title" mode="copy"/>
- </xsl:when>
- <xsl:when test="title">
- <xsl:apply-templates select="title" mode="copy"/>
- </xsl:when>
- <xsl:when test="following-sibling::title">
- <xsl:apply-templates select="following-sibling::title" mode="copy"/>
- </xsl:when>
- <xsl:otherwise>
- <!-- it's ok if there's no title on these -->
- </xsl:otherwise>
- </xsl:choose>
-
- <xsl:choose>
- <xsl:when test="titleabbrev and following-sibling::titleabbrev">
- <xsl:if test="titleabbrev != following-sibling::titleabbrev">
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Check </xsl:text>
- <xsl:value-of select="name(..)"/>
- <xsl:text> titleabbrev.</xsl:text>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- <xsl:apply-templates select="titleabbrev" mode="copy"/>
- </xsl:when>
- <xsl:when test="titleabbrev">
- <xsl:apply-templates select="titleabbrev" mode="copy"/>
- </xsl:when>
- <xsl:when test="following-sibling::titleabbrev">
- <xsl:apply-templates select="following-sibling::titleabbrev" mode="copy"/>
- </xsl:when>
- </xsl:choose>
-
- <xsl:choose>
- <xsl:when test="subtitle and following-sibling::subtitle">
- <xsl:if test="subtitle != following-sibling::subtitle">
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Check </xsl:text>
- <xsl:value-of select="name(..)"/>
- <xsl:text> subtitle.</xsl:text>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- <xsl:apply-templates select="subtitle" mode="copy"/>
- </xsl:when>
- <xsl:when test="subtitle">
- <xsl:apply-templates select="subtitle" mode="copy"/>
- </xsl:when>
- <xsl:when test="following-sibling::subtitle">
- <xsl:apply-templates select="following-sibling::subtitle" mode="copy"/>
- </xsl:when>
- </xsl:choose>
-
- <xsl:apply-templates/>
- </info>
-</xsl:template>
-
-<xsl:template match="refentryinfo"
- priority="200">
- <info>
- <xsl:call-template name="copy.attributes"/>
-
- <!-- titles can be inside or outside or both. fix that -->
- <xsl:if test="title">
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Discarding title from refentryinfo!</xsl:text>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
-
- <xsl:if test="titleabbrev">
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Discarding titleabbrev from refentryinfo!</xsl:text>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
-
- <xsl:if test="subtitle">
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Discarding subtitle from refentryinfo!</xsl:text>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
-
- <xsl:apply-templates/>
- </info>
-</xsl:template>
-
-<xsl:template match="refmiscinfo"
- priority="200">
- <refmiscinfo>
- <xsl:call-template name="copy.attributes">
- <xsl:with-param name="suppress" select="'class'"/>
- </xsl:call-template>
- <xsl:if test="@class">
- <xsl:choose>
- <xsl:when test="@class = 'source'
- or @class = 'version'
- or @class = 'manual'
- or @class = 'sectdesc'
- or @class = 'software'">
- <xsl:attribute name="class">
- <xsl:value-of select="@class"/>
- </xsl:attribute>
- </xsl:when>
- <xsl:otherwise>
- <xsl:attribute name="class">
- <xsl:value-of select="'other'"/>
- </xsl:attribute>
- <xsl:attribute name="otherclass">
- <xsl:value-of select="@class"/>
- </xsl:attribute>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:if>
- <xsl:apply-templates/>
- </refmiscinfo>
-</xsl:template>
-
-<xsl:template match="corpauthor" priority="200">
- <author>
- <xsl:call-template name="copy.attributes"/>
- <orgname>
- <xsl:apply-templates/>
- </orgname>
- </author>
-</xsl:template>
-
-<xsl:template match="corpname" priority="200">
- <orgname>
- <xsl:call-template name="copy.attributes"/>
- <xsl:apply-templates/>
- </orgname>
-</xsl:template>
-
-<xsl:template match="author[not(personname)]|editor[not(personname)]|othercredit[not(personname)]" priority="200">
- <xsl:copy>
- <xsl:call-template name="copy.attributes"/>
- <personname>
- <xsl:apply-templates select="honorific|firstname|surname|othername|lineage"/>
- </personname>
- <xsl:apply-templates select="*[not(self::honorific|self::firstname|self::surname
- |self::othername|self::lineage)]"/>
- </xsl:copy>
-</xsl:template>
-
-<xsl:template match="address|programlisting|screen|funcsynopsisinfo
- |classsynopsisinfo|literallayout" priority="200">
- <xsl:copy>
- <xsl:call-template name="copy.attributes">
- <xsl:with-param name="suppress" select="'format'"/>
- </xsl:call-template>
- <xsl:apply-templates/>
- </xsl:copy>
-</xsl:template>
-
-<xsl:template match="productname[@class]" priority="200">
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Dropping class attribute from productname</xsl:text>
- </xsl:with-param>
- </xsl:call-template>
- <xsl:copy>
- <xsl:call-template name="copy.attributes">
- <xsl:with-param name="suppress" select="'class'"/>
- </xsl:call-template>
- <xsl:apply-templates/>
- </xsl:copy>
-</xsl:template>
-
-<xsl:template match="dedication|preface|chapter|appendix|part|partintro
- |article|bibliography|glossary|glossdiv|index
- |reference[not(referenceinfo)]
- |book" priority="200">
- <xsl:choose>
- <xsl:when test="not(dedicationinfo|prefaceinfo|chapterinfo
- |appendixinfo|partinfo
- |articleinfo|artheader|bibliographyinfo
- |glossaryinfo|indexinfo
- |bookinfo)">
- <xsl:copy>
- <xsl:call-template name="copy.attributes"/>
- <xsl:if test="title|subtitle|titleabbrev">
- <info>
- <xsl:apply-templates select="title" mode="copy"/>
- <xsl:apply-templates select="titleabbrev" mode="copy"/>
- <xsl:apply-templates select="subtitle" mode="copy"/>
- <xsl:apply-templates select="abstract" mode="copy"/>
- </info>
- </xsl:if>
- <xsl:apply-templates/>
- </xsl:copy>
- </xsl:when>
- <xsl:otherwise>
- <xsl:copy>
- <xsl:call-template name="copy.attributes"/>
- <xsl:apply-templates/>
- </xsl:copy>
- </xsl:otherwise>
- </xsl:choose>
-</xsl:template>
-
-<xsl:template match="formalpara|figure|table[tgroup]|example|blockquote
- |caution|important|note|warning|tip
- |bibliodiv|glossarydiv|indexdiv
- |orderedlist|itemizedlist|variablelist|procedure
- |task|tasksummary|taskprerequisites|taskrelated
- |sidebar"
- priority="200">
- <xsl:choose>
- <xsl:when test="blockinfo">
- <xsl:copy>
- <xsl:call-template name="copy.attributes"/>
- <xsl:apply-templates/>
- </xsl:copy>
- </xsl:when>
- <xsl:otherwise>
- <xsl:copy>
- <xsl:call-template name="copy.attributes"/>
-
- <xsl:if test="title|titleabbrev|subtitle">
- <info>
- <xsl:apply-templates select="title" mode="copy"/>
- <xsl:apply-templates select="titleabbrev" mode="copy"/>
- <xsl:apply-templates select="subtitle" mode="copy"/>
- </info>
- </xsl:if>
-
- <xsl:apply-templates/>
- </xsl:copy>
- </xsl:otherwise>
- </xsl:choose>
-</xsl:template>
-
-<xsl:template match="equation" priority="200">
- <xsl:choose>
- <xsl:when test="not(title)">
- <xsl:call-template name="emit-message">
- <xsl:with-param
- name="message"
- >Convert equation without title to informal equation.</xsl:with-param>
- </xsl:call-template>
- <informalequation>
- <xsl:call-template name="copy.attributes"/>
- <xsl:apply-templates/>
- </informalequation>
- </xsl:when>
- <xsl:when test="blockinfo">
- <xsl:copy>
- <xsl:call-template name="copy.attributes"/>
- <xsl:apply-templates/>
- </xsl:copy>
- </xsl:when>
- <xsl:otherwise>
- <xsl:copy>
- <xsl:call-template name="copy.attributes"/>
- <info>
- <xsl:apply-templates select="title" mode="copy"/>
- <xsl:apply-templates select="titleabbrev" mode="copy"/>
- <xsl:apply-templates select="subtitle" mode="copy"/>
- </info>
- <xsl:apply-templates/>
- </xsl:copy>
- </xsl:otherwise>
- </xsl:choose>
-</xsl:template>
-
-<xsl:template match="sect1|sect2|sect3|sect4|sect5|section"
- priority="200">
- <section>
- <xsl:call-template name="copy.attributes"/>
-
- <xsl:if test="not(sect1info|sect2info|sect3info|sect4info|sect5info|sectioninfo)">
- <info>
- <xsl:apply-templates select="title" mode="copy"/>
- <xsl:apply-templates select="titleabbrev" mode="copy"/>
- <xsl:apply-templates select="subtitle" mode="copy"/>
- <xsl:apply-templates select="abstract" mode="copy"/>
- </info>
- </xsl:if>
- <xsl:apply-templates/>
- </section>
-</xsl:template>
-
-<xsl:template match="simplesect"
- priority="200">
- <simplesect>
- <xsl:call-template name="copy.attributes"/>
- <info>
- <xsl:apply-templates select="title" mode="copy"/>
- <xsl:apply-templates select="titleabbrev" mode="copy"/>
- <xsl:apply-templates select="subtitle" mode="copy"/>
- <xsl:apply-templates select="abstract" mode="copy"/>
- </info>
- <xsl:apply-templates/>
- </simplesect>
-</xsl:template>
-
-<xsl:template match="refsect1|refsect2|refsect3|refsection" priority="200">
- <refsection>
- <xsl:call-template name="copy.attributes"/>
-
- <xsl:if test="not(refsect1info|refsect2info|refsect3info|refsectioninfo)">
- <info>
- <xsl:apply-templates select="title" mode="copy"/>
- <xsl:apply-templates select="titleabbrev" mode="copy"/>
- <xsl:apply-templates select="subtitle" mode="copy"/>
- <xsl:apply-templates select="abstract" mode="copy"/>
- </info>
- </xsl:if>
- <xsl:apply-templates/>
- </refsection>
-</xsl:template>
-
-<xsl:template match="imagedata|videodata|audiodata|textdata" priority="200">
- <xsl:copy>
- <xsl:call-template name="copy.attributes">
- <xsl:with-param name="suppress" select="'srccredit'"/>
- </xsl:call-template>
- <xsl:if test="@srccredit">
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Check conversion of srccredit </xsl:text>
- <xsl:text>(othercredit="srccredit").</xsl:text>
- </xsl:with-param>
- </xsl:call-template>
- <info>
- <othercredit class="other" otherclass="srccredit">
- <orgname>???</orgname>
- <contrib>
- <xsl:value-of select="@srccredit"/>
- </contrib>
- </othercredit>
- </info>
- </xsl:if>
- </xsl:copy>
-</xsl:template>
-
-<xsl:template match="sgmltag" priority="200">
- <tag>
- <xsl:call-template name="copy.attributes"/>
- <xsl:if test="@class = 'sgmlcomment'">
- <xsl:attribute name="class">comment</xsl:attribute>
- </xsl:if>
- <xsl:apply-templates/>
- </tag>
-</xsl:template>
-
-<xsl:template match="inlinegraphic[@format='linespecific']" priority="210">
- <textobject>
- <textdata>
- <xsl:call-template name="copy.attributes"/>
- </textdata>
- </textobject>
-</xsl:template>
-
-<xsl:template match="inlinegraphic" priority="200">
- <inlinemediaobject>
- <imageobject>
- <imagedata>
- <xsl:call-template name="copy.attributes"/>
- </imagedata>
- </imageobject>
- </inlinemediaobject>
-</xsl:template>
-
-<xsl:template match="graphic[@format='linespecific']" priority="210">
- <mediaobject>
- <textobject>
- <textdata>
- <xsl:call-template name="copy.attributes"/>
- </textdata>
- </textobject>
- </mediaobject>
-</xsl:template>
-
-<xsl:template match="graphic" priority="200">
- <mediaobject>
- <imageobject>
- <imagedata>
- <xsl:call-template name="copy.attributes"/>
- </imagedata>
- </imageobject>
- </mediaobject>
-</xsl:template>
-
-<xsl:template match="pubsnumber" priority="200">
- <biblioid class="pubsnumber">
- <xsl:call-template name="copy.attributes"/>
- <xsl:apply-templates/>
- </biblioid>
-</xsl:template>
-
-<xsl:template match="invpartnumber" priority="200">
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Converting invpartnumber to biblioid otherclass="invpartnumber".</xsl:text>
- </xsl:with-param>
- </xsl:call-template>
- <biblioid class="other" otherclass="invpartnumber">
- <xsl:call-template name="copy.attributes"/>
- <xsl:apply-templates/>
- </biblioid>
-</xsl:template>
-
-<xsl:template match="contractsponsor" priority="200">
- <xsl:variable name="contractnum"
- select="preceding-sibling::contractnum|following-sibling::contractnum"/>
-
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Converting contractsponsor to othercredit="contractsponsor".</xsl:text>
- </xsl:with-param>
- </xsl:call-template>
-
- <othercredit class="other" otherclass="contractsponsor">
- <orgname>
- <xsl:call-template name="copy.attributes"/>
- <xsl:apply-templates/>
- </orgname>
- <xsl:for-each select="$contractnum">
- <contrib role="contractnum">
- <xsl:apply-templates select="node()"/>
- </contrib>
- </xsl:for-each>
- </othercredit>
-</xsl:template>
-
-<xsl:template match="contractnum" priority="200">
- <xsl:if test="not(preceding-sibling::contractsponsor
- |following-sibling::contractsponsor)
- and not(preceding-sibling::contractnum)">
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Converting contractnum to othercredit="contractnum".</xsl:text>
- </xsl:with-param>
- </xsl:call-template>
-
- <othercredit class="other" otherclass="contractnum">
- <orgname>???</orgname>
- <xsl:for-each select="self::contractnum
- |preceding-sibling::contractnum
- |following-sibling::contractnum">
- <contrib>
- <xsl:apply-templates select="node()"/>
- </contrib>
- </xsl:for-each>
- </othercredit>
- </xsl:if>
-</xsl:template>
-
-<xsl:template match="isbn|issn" priority="200">
- <biblioid class="{local-name(.)}">
- <xsl:call-template name="copy.attributes"/>
- <xsl:apply-templates/>
- </biblioid>
-</xsl:template>
-
-<xsl:template match="biblioid[count(*) = 1
- and ulink
- and normalize-space(text()) = '']" priority="200">
- <biblioid xlink:href="{ulink/@url}">
- <xsl:call-template name="copy.attributes"/>
- <xsl:apply-templates select="ulink/node()"/>
- </biblioid>
-</xsl:template>
-
-<xsl:template match="authorblurb" priority="200">
- <personblurb>
- <xsl:call-template name="copy.attributes"/>
- <xsl:apply-templates/>
- </personblurb>
-</xsl:template>
-
-<xsl:template match="collabname" priority="200">
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Check conversion of collabname </xsl:text>
- <xsl:text>(orgname role="collabname").</xsl:text>
- </xsl:with-param>
- </xsl:call-template>
- <orgname role="collabname">
- <xsl:call-template name="copy.attributes"/>
- <xsl:apply-templates/>
- </orgname>
-</xsl:template>
-
-<xsl:template match="modespec" priority="200">
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Discarding modespec (</xsl:text>
- <xsl:value-of select="."/>
- <xsl:text>).</xsl:text>
- </xsl:with-param>
- </xsl:call-template>
-</xsl:template>
-
-<xsl:template match="mediaobjectco" priority="200">
- <mediaobject>
- <xsl:copy-of select="@*"/>
- <xsl:apply-templates/>
- </mediaobject>
-</xsl:template>
-
-<xsl:template match="remark" priority="200">
- <!-- get rid of any embedded markup -->
- <remark>
- <xsl:copy-of select="@*"/>
- <xsl:value-of select="."/>
- </remark>
-</xsl:template>
-
-<xsl:template match="biblioentry/title
- |bibliomset/title
- |biblioset/title
- |bibliomixed/title" priority="400">
- <citetitle>
- <xsl:copy-of select="@*"/>
- <xsl:apply-templates/>
- </citetitle>
-</xsl:template>
-
-<xsl:template match="biblioentry/titleabbrev|biblioentry/subtitle
- |bibliomset/titleabbrev|bibliomset/subtitle
- |biblioset/titleabbrev|biblioset/subtitle
- |bibliomixed/titleabbrev|bibliomixed/subtitle"
- priority="400">
- <xsl:copy>
- <xsl:copy-of select="@*"/>
- <xsl:apply-templates/>
- </xsl:copy>
-</xsl:template>
-
-<xsl:template match="biblioentry/contrib
- |bibliomset/contrib
- |bibliomixed/contrib" priority="200">
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Check conversion of contrib </xsl:text>
- <xsl:text>(othercontrib="contrib").</xsl:text>
- </xsl:with-param>
- </xsl:call-template>
- <othercredit class="other" otherclass="contrib">
- <orgname>???</orgname>
- <contrib>
- <xsl:call-template name="copy.attributes"/>
- <xsl:apply-templates/>
- </contrib>
- </othercredit>
-</xsl:template>
-
-<xsl:template match="link" priority="200">
- <xsl:copy>
- <xsl:call-template name="copy.attributes"/>
- <xsl:apply-templates/>
- </xsl:copy>
-</xsl:template>
-
-<xsl:template match="ulink" priority="200">
- <xsl:choose>
- <xsl:when test="node()">
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Converting ulink to link.</xsl:text>
- </xsl:with-param>
- </xsl:call-template>
-
- <link xlink:href="{@url}">
- <xsl:call-template name="copy.attributes">
- <xsl:with-param name="suppress" select="'url'"/>
- </xsl:call-template>
- <xsl:apply-templates/>
- </link>
- </xsl:when>
- <xsl:otherwise>
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Converting ulink to uri.</xsl:text>
- </xsl:with-param>
- </xsl:call-template>
-
- <uri xlink:href="{@url}">
- <xsl:call-template name="copy.attributes">
- <xsl:with-param name="suppress" select="'url'"/>
- </xsl:call-template>
- <xsl:value-of select="@url"/>
- </uri>
- </xsl:otherwise>
- </xsl:choose>
-</xsl:template>
-
-<xsl:template match="olink" priority="200">
- <xsl:if test="@linkmode">
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Discarding linkmode on olink.</xsl:text>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
-
- <xsl:choose>
- <xsl:when test="@targetdocent">
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Converting olink targetdocent to targetdoc.</xsl:text>
- </xsl:with-param>
- </xsl:call-template>
-
- <olink targetdoc="{unparsed-entity-uri(@targetdocent)}">
- <xsl:for-each select="@*">
- <xsl:if test="name(.) != 'targetdocent'
- and name(.) != 'linkmode'">
- <xsl:copy/>
- </xsl:if>
- </xsl:for-each>
- <xsl:apply-templates/>
- </olink>
- </xsl:when>
- <xsl:otherwise>
- <olink>
- <xsl:for-each select="@*">
- <xsl:if test="name(.) != 'linkmode'">
- <xsl:copy/>
- </xsl:if>
- </xsl:for-each>
- <xsl:apply-templates/>
- </olink>
- </xsl:otherwise>
- </xsl:choose>
-</xsl:template>
-
-<xsl:template match="biblioentry/firstname
- |biblioentry/surname
- |biblioentry/othername
- |biblioentry/lineage
- |biblioentry/honorific
- |bibliomset/firstname
- |bibliomset/surname
- |bibliomset/othername
- |bibliomset/lineage
- |bibliomset/honorific" priority="200">
- <xsl:choose>
- <xsl:when test="preceding-sibling::firstname
- |preceding-sibling::surname
- |preceding-sibling::othername
- |preceding-sibling::lineage
- |preceding-sibling::honorific">
- <!-- nop -->
- </xsl:when>
- <xsl:otherwise>
- <personname>
- <xsl:apply-templates select="../firstname
- |../surname
- |../othername
- |../lineage
- |../honorific" mode="copy"/>
- </personname>
- </xsl:otherwise>
- </xsl:choose>
-</xsl:template>
-
-<xsl:template match="areaset" priority="200">
- <xsl:copy>
- <xsl:call-template name="copy.attributes">
- <xsl:with-param name="suppress" select="'coords'"/>
- </xsl:call-template>
- <xsl:apply-templates/>
- </xsl:copy>
-</xsl:template>
-
-<xsl:template match="date|pubdate" priority="200">
- <xsl:variable name="rp1" select="substring-before(normalize-space(.), ' ')"/>
- <xsl:variable name="rp2"
- select="substring-before(substring-after(normalize-space(.), ' '),
- ' ')"/>
- <xsl:variable name="rp3"
- select="substring-after(substring-after(normalize-space(.), ' '), ' ')"/>
-
- <xsl:variable name="p1">
- <xsl:choose>
- <xsl:when test="contains($rp1, ',')">
- <xsl:value-of select="substring-before($rp1, ',')"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$rp1"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:variable name="p2">
- <xsl:choose>
- <xsl:when test="contains($rp2, ',')">
- <xsl:value-of select="substring-before($rp2, ',')"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$rp2"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:variable name="p3">
- <xsl:choose>
- <xsl:when test="contains($rp3, ',')">
- <xsl:value-of select="substring-before($rp3, ',')"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$rp3"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:variable name="date">
- <xsl:choose>
- <xsl:when test="string($p1+1) != 'NaN' and string($p3+1) != 'NaN'">
- <xsl:choose>
- <xsl:when test="$p2 = 'Jan' or $p2 = 'January'">
- <xsl:number value="$p3" format="0001"/>
- <xsl:text>-01-</xsl:text>
- <xsl:number value="$p1" format="01"/>
- </xsl:when>
- <xsl:when test="$p2 = 'Feb' or $p2 = 'February'">
- <xsl:number value="$p3" format="0001"/>
- <xsl:text>-02-</xsl:text>
- <xsl:number value="$p1" format="01"/>
- </xsl:when>
- <xsl:when test="$p2 = 'Mar' or $p2 = 'March'">
- <xsl:number value="$p3" format="0001"/>
- <xsl:text>-03-</xsl:text>
- <xsl:number value="$p1" format="01"/>
- </xsl:when>
- <xsl:when test="$p2 = 'Apr' or $p2 = 'April'">
- <xsl:number value="$p3" format="0001"/>
- <xsl:text>-04-</xsl:text>
- <xsl:number value="$p1" format="01"/>
- </xsl:when>
- <xsl:when test="$p2 = 'May'">
- <xsl:number value="$p3" format="0001"/>
- <xsl:text>-05-</xsl:text>
- <xsl:number value="$p1" format="01"/>
- </xsl:when>
- <xsl:when test="$p2 = 'Jun' or $p2 = 'June'">
- <xsl:number value="$p3" format="0001"/>
- <xsl:text>-06-</xsl:text>
- <xsl:number value="$p1" format="01"/>
- </xsl:when>
- <xsl:when test="$p2 = 'Jul' or $p2 = 'July'">
- <xsl:number value="$p3" format="0001"/>
- <xsl:text>-07-</xsl:text>
- <xsl:number value="$p1" format="01"/>
- </xsl:when>
- <xsl:when test="$p2 = 'Aug' or $p2 = 'August'">
- <xsl:number value="$p3" format="0001"/>
- <xsl:text>-08-</xsl:text>
- <xsl:number value="$p1" format="01"/>
- </xsl:when>
- <xsl:when test="$p2 = 'Sep' or $p2 = 'September'">
- <xsl:number value="$p3" format="0001"/>
- <xsl:text>-09-</xsl:text>
- <xsl:number value="$p1" format="01"/>
- </xsl:when>
- <xsl:when test="$p2 = 'Oct' or $p2 = 'October'">
- <xsl:number value="$p3" format="0001"/>
- <xsl:text>-10-</xsl:text>
- <xsl:number value="$p1" format="01"/>
- </xsl:when>
- <xsl:when test="$p2 = 'Nov' or $p2 = 'November'">
- <xsl:number value="$p3" format="0001"/>
- <xsl:text>-11-</xsl:text>
- <xsl:number value="$p1" format="01"/>
- </xsl:when>
- <xsl:when test="$p2 = 'Dec' or $p2 = 'December'">
- <xsl:number value="$p3" format="0001"/>
- <xsl:text>-12-</xsl:text>
- <xsl:number value="$p1" format="01"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:when>
- <xsl:when test="string($p2+1) != 'NaN' and string($p3+1) != 'NaN'">
- <xsl:choose>
- <xsl:when test="$p1 = 'Jan' or $p1 = 'January'">
- <xsl:number value="$p3" format="0001"/>
- <xsl:text>-01-</xsl:text>
- <xsl:number value="$p2" format="01"/>
- </xsl:when>
- <xsl:when test="$p1 = 'Feb' or $p1 = 'February'">
- <xsl:number value="$p3" format="0001"/>
- <xsl:text>-02-</xsl:text>
- <xsl:number value="$p2" format="01"/>
- </xsl:when>
- <xsl:when test="$p1 = 'Mar' or $p1 = 'March'">
- <xsl:number value="$p3" format="0001"/>
- <xsl:text>-03-</xsl:text>
- <xsl:number value="$p2" format="01"/>
- </xsl:when>
- <xsl:when test="$p1 = 'Apr' or $p1 = 'April'">
- <xsl:number value="$p3" format="0001"/>
- <xsl:text>-04-</xsl:text>
- <xsl:number value="$p2" format="01"/>
- </xsl:when>
- <xsl:when test="$p1 = 'May'">
- <xsl:number value="$p3" format="0001"/>
- <xsl:text>-05-</xsl:text>
- <xsl:number value="$p2" format="01"/>
- </xsl:when>
- <xsl:when test="$p1 = 'Jun' or $p1 = 'June'">
- <xsl:number value="$p3" format="0001"/>
- <xsl:text>-06-</xsl:text>
- <xsl:number value="$p2" format="01"/>
- </xsl:when>
- <xsl:when test="$p1 = 'Jul' or $p1 = 'July'">
- <xsl:number value="$p3" format="0001"/>
- <xsl:text>-07-</xsl:text>
- <xsl:number value="$p2" format="01"/>
- </xsl:when>
- <xsl:when test="$p1 = 'Aug' or $p1 = 'August'">
- <xsl:number value="$p3" format="0001"/>
- <xsl:text>-08-</xsl:text>
- <xsl:number value="$p2" format="01"/>
- </xsl:when>
- <xsl:when test="$p1 = 'Sep' or $p1 = 'September'">
- <xsl:number value="$p3" format="0001"/>
- <xsl:text>-09-</xsl:text>
- <xsl:number value="$p2" format="01"/>
- </xsl:when>
- <xsl:when test="$p1 = 'Oct' or $p1 = 'October'">
- <xsl:number value="$p3" format="0001"/>
- <xsl:text>-10-</xsl:text>
- <xsl:number value="$p2" format="01"/>
- </xsl:when>
- <xsl:when test="$p1 = 'Nov' or $p1 = 'November'">
- <xsl:number value="$p3" format="0001"/>
- <xsl:text>-11-</xsl:text>
- <xsl:number value="$p2" format="01"/>
- </xsl:when>
- <xsl:when test="$p1 = 'Dec' or $p1 = 'December'">
- <xsl:number value="$p3" format="0001"/>
- <xsl:text>-12-</xsl:text>
- <xsl:number value="$p2" format="01"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:choose>
- <xsl:when test="normalize-space($date) != normalize-space(.)">
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Converted </xsl:text>
- <xsl:value-of select="normalize-space(.)"/>
- <xsl:text> into </xsl:text>
- <xsl:value-of select="$date"/>
- <xsl:text> for </xsl:text>
- <xsl:value-of select="name(.)"/>
- </xsl:with-param>
- </xsl:call-template>
-
- <xsl:copy>
- <xsl:copy-of select="@*"/>
- <xsl:value-of select="$date"/>
- </xsl:copy>
- </xsl:when>
-
- <xsl:when test="$defaultDate != ''">
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Unparseable date: </xsl:text>
- <xsl:value-of select="normalize-space(.)"/>
- <xsl:text> in </xsl:text>
- <xsl:value-of select="name(.)"/>
- <xsl:text> (Using default: </xsl:text>
- <xsl:value-of select="$defaultDate"/>
- <xsl:text>)</xsl:text>
- </xsl:with-param>
- </xsl:call-template>
-
- <xsl:copy>
- <xsl:copy-of select="@*"/>
- <xsl:copy-of select="$defaultDate"/>
- <xsl:comment>
- <xsl:value-of select="."/>
- </xsl:comment>
- </xsl:copy>
- </xsl:when>
-
- <xsl:otherwise>
- <!-- these don't really matter anymore
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Unparseable date: </xsl:text>
- <xsl:value-of select="normalize-space(.)"/>
- <xsl:text> in </xsl:text>
- <xsl:value-of select="name(.)"/>
- </xsl:with-param>
- </xsl:call-template>
- -->
- <xsl:copy>
- <xsl:copy-of select="@*"/>
- <xsl:apply-templates/>
- </xsl:copy>
- </xsl:otherwise>
- </xsl:choose>
-</xsl:template>
-
-<xsl:template match="title|subtitle|titleabbrev" priority="300">
- <!-- nop -->
-</xsl:template>
-
-<xsl:template match="abstract" priority="300">
- <xsl:if test="not(contains(name(parent::*),'info'))">
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Check abstract; moved into info correctly?</xsl:text>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
-</xsl:template>
-
-<xsl:template match="indexterm">
- <!-- don't copy the defaulted significance='normal' attribute -->
- <indexterm>
- <xsl:call-template name="copy.attributes">
- <xsl:with-param name="suppress">
- <xsl:if test="@significance = 'normal'">significance</xsl:if>
- </xsl:with-param>
- </xsl:call-template>
- <xsl:apply-templates/>
- </indexterm>
-</xsl:template>
-
-<xsl:template match="ackno" priority="200">
- <acknowledgements>
- <xsl:copy-of select="@*"/>
- <para>
- <xsl:apply-templates/>
- </para>
- </acknowledgements>
-</xsl:template>
-
-<xsl:template match="lot|lotentry|tocback|tocchap|tocfront|toclevel1|
- toclevel2|toclevel3|toclevel4|toclevel5|tocpart" priority="200">
- <tocdiv>
- <xsl:copy-of select="@*"/>
- <xsl:apply-templates/>
- </tocdiv>
-</xsl:template>
-
-<xsl:template match="action" priority="200">
- <phrase remap="action">
- <xsl:call-template name="copy.attributes"/>
- <xsl:apply-templates/>
- </phrase>
-</xsl:template>
-
-<xsl:template match="beginpage" priority="200">
- <xsl:comment> beginpage pagenum=<xsl:value-of select="@pagenum"/> </xsl:comment>
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Replacing beginpage with comment</xsl:text>
- </xsl:with-param>
- </xsl:call-template>
-</xsl:template>
-
-<xsl:template match="structname|structfield" priority="200">
- <varname remap="{local-name(.)}">
- <xsl:call-template name="copy.attributes"/>
- <xsl:apply-templates/>
- </varname>
-</xsl:template>
-
-<!-- ====================================================================== -->
-
-<!-- 6 Feb 2008, ndw changed mode=copy so that it only copies the first level,
- then it switches back to "normal" mode so that other rewriting templates
- catch embedded fixes -->
-
-<!--
-<xsl:template match="ulink" priority="200" mode="copy">
- <xsl:choose>
- <xsl:when test="node()">
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Converting ulink to phrase.</xsl:text>
- </xsl:with-param>
- </xsl:call-template>
-
- <phrase xlink:href="{@url}">
- <xsl:call-template name="copy.attributes">
- <xsl:with-param name="suppress" select="'url'"/>
- </xsl:call-template>
- <xsl:apply-templates/>
- </phrase>
- </xsl:when>
- <xsl:otherwise>
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Converting ulink to uri.</xsl:text>
- </xsl:with-param>
- </xsl:call-template>
-
- <uri xlink:href="{@url}">
- <xsl:call-template name="copy.attributes">
- <xsl:with-param name="suppress" select="'url'"/>
- </xsl:call-template>
- <xsl:value-of select="@url"/>
- </uri>
- </xsl:otherwise>
- </xsl:choose>
-</xsl:template>
-
-<xsl:template match="sgmltag" priority="200" mode="copy">
- <tag>
- <xsl:call-template name="copy.attributes"/>
- <xsl:apply-templates/>
- </tag>
-</xsl:template>
--->
-
-<xsl:template match="*" mode="copy">
- <xsl:copy>
- <xsl:call-template name="copy.attributes"/>
- <xsl:apply-templates/>
- </xsl:copy>
-</xsl:template>
-
-<!--
-<xsl:template match="comment()|processing-instruction()|text()" mode="copy">
- <xsl:copy/>
-</xsl:template>
--->
-
-<!-- ====================================================================== -->
-
-<xsl:template match="*">
- <xsl:copy>
- <xsl:call-template name="copy.attributes"/>
- <xsl:apply-templates/>
- </xsl:copy>
-</xsl:template>
-
-<xsl:template match="comment()|processing-instruction()|text()">
- <xsl:copy/>
-</xsl:template>
-
-<!-- ====================================================================== -->
-
-<xsl:template name="copy.attributes">
- <xsl:param name="src" select="."/>
- <xsl:param name="suppress" select="''"/>
-
- <xsl:for-each select="$src/@*">
- <xsl:choose>
- <xsl:when test="local-name(.) = 'moreinfo'">
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Discarding moreinfo on </xsl:text>
- <xsl:value-of select="local-name($src)"/>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:when>
- <xsl:when test="local-name(.) = 'lang'">
- <xsl:attribute name="xml:lang">
- <xsl:value-of select="."/>
- </xsl:attribute>
- </xsl:when>
- <xsl:when test="local-name(.) = 'id'">
- <xsl:attribute name="xml:id">
- <xsl:value-of select="."/>
- </xsl:attribute>
- </xsl:when>
- <xsl:when test="$suppress = local-name(.)"/>
- <xsl:when test="local-name(.) = 'float'">
- <xsl:choose>
- <xsl:when test=". = '1'">
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Discarding float on </xsl:text>
- <xsl:value-of select="local-name($src)"/>
- </xsl:with-param>
- </xsl:call-template>
- <xsl:if test="not($src/@floatstyle)">
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Adding floatstyle='normal' on </xsl:text>
- <xsl:value-of select="local-name($src)"/>
- </xsl:with-param>
- </xsl:call-template>
- <xsl:attribute name="floatstyle">
- <xsl:text>normal</xsl:text>
- </xsl:attribute>
- </xsl:if>
- </xsl:when>
- <xsl:when test=". = '0'">
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Discarding float on </xsl:text>
- <xsl:value-of select="local-name($src)"/>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:when>
- <xsl:otherwise>
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Discarding float on </xsl:text>
- <xsl:value-of select="local-name($src)"/>
- </xsl:with-param>
- </xsl:call-template>
- <xsl:if test="not($src/@floatstyle)">
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Adding floatstyle='</xsl:text>
- <xsl:value-of select="."/>
- <xsl:text>' on </xsl:text>
- <xsl:value-of select="local-name($src)"/>
- </xsl:with-param>
- </xsl:call-template>
- <xsl:attribute name="floatstyle">
- <xsl:value-of select="."/>
- </xsl:attribute>
- </xsl:if>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:when>
- <xsl:when test="local-name(.) = 'entityref'">
- <xsl:attribute name="fileref">
- <xsl:value-of select="unparsed-entity-uri(@entityref)"/>
- </xsl:attribute>
- </xsl:when>
-
- <xsl:when test="local-name($src) = 'simplemsgentry'
- and local-name(.) = 'audience'">
- <xsl:attribute name="msgaud">
- <xsl:value-of select="."/>
- </xsl:attribute>
- </xsl:when>
- <xsl:when test="local-name($src) = 'simplemsgentry'
- and local-name(.) = 'origin'">
- <xsl:attribute name="msgorig">
- <xsl:value-of select="."/>
- </xsl:attribute>
- </xsl:when>
- <xsl:when test="local-name($src) = 'simplemsgentry'
- and local-name(.) = 'level'">
- <xsl:attribute name="msglevel">
- <xsl:value-of select="."/>
- </xsl:attribute>
- </xsl:when>
-
- <!-- * for upgrading XSL litprog params documentation -->
- <xsl:when test="local-name($src) = 'refmiscinfo'
- and local-name(.) = 'role'
- and . = 'type'
- ">
- <xsl:call-template name="emit-message">
- <xsl:with-param name="message">
- <xsl:text>Converting refmiscinfo@role=type to </xsl:text>
- <xsl:text>@class=other,otherclass=type</xsl:text>
- </xsl:with-param>
- </xsl:call-template>
- <xsl:attribute name="class">other</xsl:attribute>
- <xsl:attribute name="otherclass">type</xsl:attribute>
- </xsl:when>
-
- <xsl:otherwise>
- <xsl:copy/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:for-each>
-</xsl:template>
-
-<!-- ====================================================================== -->
-
-<xsl:template match="*" mode="addNS">
- <xsl:choose>
- <xsl:when test="namespace-uri(.) = ''">
- <xsl:element name="{local-name(.)}"
- namespace="http://docbook.org/ns/docbook">
- <xsl:if test="not(parent::*)">
- <xsl:attribute name="version">5.0</xsl:attribute>
- </xsl:if>
- <xsl:copy-of select="@*"/>
- <xsl:apply-templates mode="addNS"/>
- </xsl:element>
- </xsl:when>
- <xsl:otherwise>
- <xsl:copy>
- <xsl:if test="not(parent::*)">
- <xsl:attribute name="version">5.0</xsl:attribute>
- </xsl:if>
- <xsl:copy-of select="@*"/>
- <xsl:apply-templates mode="addNS"/>
- </xsl:copy>
- </xsl:otherwise>
- </xsl:choose>
-</xsl:template>
-
-<xsl:template match="comment()|processing-instruction()|text()" mode="addNS">
- <xsl:copy/>
-</xsl:template>
-
-<!-- ====================================================================== -->
-
-<xsl:template name="emit-message">
- <xsl:param name="message"/>
- <xsl:message>
- <xsl:value-of select="$message"/>
- <xsl:text> (</xsl:text>
- <xsl:value-of select="$rootid"/>
- <xsl:text>)</xsl:text>
- </xsl:message>
-</xsl:template>
-
-</xsl:stylesheet>
+++ /dev/null
-<dbk = 'http://docbook.org/ns/docbook'>
-<argeodbk = 'http://www.argeo.org/ns/argeodbk'>
-<xlink = 'http://www.w3.org/1999/xlink'>
-//<xs = 'http://www.w3.org/2001/XMLSchema'>
-
-[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)
-
-
+++ /dev/null
-<dbk = 'http://docbook.org/ns/docbook'>
-<argeodbk = 'http://www.argeo.org/ns/argeodbk'>
-<xlink = 'http://www.w3.org/1999/xlink'>
-
-[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)
-
-
+++ /dev/null
-package org.argeo.docbook.ui;
-
-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.argeo.api.cms.Cms2DSize;
-import org.argeo.api.cms.CmsEditable;
-import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.swt.CmsSwtUtils;
-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 CmsLog log = CmsLog.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) {
- CmsSwtUtils.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)
- CmsSwtUtils.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(CmsSwtUtils.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(CmsSwtUtils.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(CmsSwtUtils.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(CmsSwtUtils.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 Cms2DSize(maxMediaWidth, 0));
- } else {
- imgGd = CmsSwtUtils.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<Control> toLayout = new ArrayList<Control>();
- 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(CmsSwtUtils.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<String, Section> parentSubsections = parentSection.getSubSections();
- ArrayList<Section> lst = new ArrayList<Section>(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<Section> 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(CmsSwtUtils.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<String> styles = getAvailableStyles(composite);
- styledTools.show(composite, new Point(e.x, e.y), styles);
- }
- }
- }
- }
-
- @Override
- public void mouseUp(MouseEvent e) {
- }
- }
-
- protected List<String> 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
+++ /dev/null
-package org.argeo.docbook.ui;
-
-import javax.jcr.Node;
-
-import org.argeo.api.cms.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);
- }
-}
+++ /dev/null
-package org.argeo.docbook.ui;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.jcr.Node;
-
-import org.argeo.api.cms.CmsEditable;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.swt.MouseDown;
-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.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<String> availableStyles) {
- if (shell.isVisible())
- shell.setVisible(false);
- CmsSwtUtils.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<StyleButton> styleButtons = new ArrayList<DbkContextMenu.StyleButton>();
- 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();
- }
-
- }
-}
+++ /dev/null
-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.api.cms.Cms2DSize;
-import org.argeo.api.cms.CmsImageManager;
-import org.argeo.cms.ui.util.CmsUiUtils;
-import org.argeo.cms.ui.util.DefaultImageManager;
-import org.argeo.docbook.DbkAttr;
-import org.argeo.docbook.DbkType;
-import org.argeo.docbook.DbkUtils;
-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;
-
-/** 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) {
- try {
- 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);
- }
- } catch (RepositoryException e) {
- throw new JcrException(e);
- }
- }
-
- @Override
- public Binary getImageBinary(Node node) {
- Node fileNode = null;
- if (DbkUtils.isDbk(node, DbkType.mediaobject)) {
- Node imageDataNode = getImageDataNode(node);
- fileNode = getFileNode(imageDataNode);
- }
- try {
- if (node.isNodeType(NT_FILE)) {
- fileNode = node;
- }
- if (fileNode != null) {
- return node.getNode(JCR_CONTENT).getProperty(JCR_DATA).getBinary();
- } else {
- return null;
- }
- } catch (RepositoryException e) {
- throw new JcrException(e);
- }
- }
-
- public Cms2DSize getImageSize(Node mediaObjectNode) {
- Node imageDataNode = getImageDataNode(mediaObjectNode);
- Node fileNode = getFileNode(imageDataNode);
- if (fileNode == null)
- return new Cms2DSize(0, 0);
- try {
- Cms2DSize 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 Cms2DSize(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;
- } catch (RepositoryException e) {
- throw new JcrException(e);
- }
- }
-
- protected Cms2DSize 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 Cms2DSize(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) {
- Node imageDataNode = getImageDataNode(mediaObjectNode);
- // TODO factorise
- String fileref = null;
- try {
- if (imageDataNode.hasProperty(DbkAttr.fileref.name()))
- fileref = imageDataNode.getProperty(DbkAttr.fileref.name()).getString();
- } catch (RepositoryException e) {
- throw new JcrException(e);
- }
- 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) {
- // FIXME make URL use case more robust
- try {
- 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;
- } catch (RepositoryException e) {
- throw new JcrException(e);
- }
- }
-
- 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);
- }
- }
-}
+++ /dev/null
-package org.argeo.docbook.ui;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.cms.swt.CmsSwtUtils;
-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(CmsSwtUtils.grabWidth(SWT.CENTER, SWT.DEFAULT));
- }
-
- @Override
- protected void setControlLayoutData(Control control) {
- control.setLayoutData(CmsSwtUtils.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;
- }
-
-}
+++ /dev/null
-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();
- }
-}
+++ /dev/null
-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 + "</"
- + node.getName() + ">";
-// 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("</").append(child.getName()).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("<a class='" + linkCssClass + "' href='").append(href).append("'>");
- readAsSimpleHtml(child, sb);
- sb.append("</a>");
- }
- } 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 = "<span style='text-align:justify'>" + raw + "</span>";
- if (raw.length() == 0)
- return raw;
- try (StringReader reader = new StringReader(raw)) {
- List<String> 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("<br/>");
- sb.append(lines.get(i));
- }
- return sb.toString();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- final static int BR_LENGTH = "<br/>".length();
-
- public String readSimpleHtml(Item item) {
- try {
- StringBuilder sb = new StringBuilder();
-// sb.append("<div style='text-align: justify;'>");
- readAsSimpleHtml((Node) item, sb);
-// sb.append("</div>");
-// 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;
- }
-}
+++ /dev/null
-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.swt.CmsSwtUtils;
-import org.argeo.cms.swt.Selected;
-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.jcr.Jcr;
-import org.argeo.jcr.JcrException;
-import org.argeo.util.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(CmsSwtUtils.noSpaceGridLayout());
-
- Composite browserC = new Composite(wrapper, SWT.NONE);
- browserC.setLayout(CmsSwtUtils.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<String, List<String>> 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(
- "<iframe frameborder=\"0\" allow=\"autoplay; fullscreen; picture-in-picture\" allowfullscreen=\"true\"");
- // TODO make size configurable
- html.append("width=\"").append(width).append("\" height=\"").append(height).append("\" ");
- html.append("src=\"").append(fileref).append("\" ");
- html.append("/>");
- browser.setText(html.toString());
- }
- }
- } catch (RepositoryException e) {
- throw new JcrException("Cannot retrieve src for video " + getNode(), e);
- }
- }
-
- @Override
- protected void setContainerLayoutData(Composite composite) {
- composite.setLayoutData(new GridData(SWT.CENTER, SWT.FILL, true, true));
- }
-
- @Override
- protected void setControlLayoutData(Control control) {
- control.setLayoutData(CmsSwtUtils.fillAll());
- }
-
- @Override
- public Item getItem() throws RepositoryException {
- return getNode();
- }
-
- @Override
- public String getPartId() {
- return getNodeId();
- }
-
- @Override
- public Section getSection() {
- return section;
- }
-
- public int getWidth() {
- return width;
- }
-
- public int getHeight() {
- return height;
- }
-
-}
+++ /dev/null
-package org.argeo.docbook.ui;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.nodetype.NodeType;
-
-import org.argeo.api.cms.CmsEditable;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.ui.CmsUiProvider;
-import org.argeo.cms.ui.util.CmsLink;
-import org.argeo.cms.ui.viewers.JcrVersionCmsEditable;
-import org.argeo.cms.ui.widgets.ScrolledPage;
-import org.argeo.docbook.DbkType;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-
-/**
- * Display the text of the context, and provide an editor if the user can edit.
- */
-public class DocumentPage implements CmsUiProvider {
- public final static String WWW = "www";
-
- @Override
- public Control createUi(Composite parent, Node context) throws RepositoryException {
-
- ScrolledPage page = new ScrolledPage(parent, SWT.NONE);
- page.setLayout(CmsSwtUtils.noSpaceGridLayout());
- GridData textGd = CmsSwtUtils.fillAll();
- page.setLayoutData(textGd);
-
- if (context.isNodeType(DbkType.article.get())) {
- CmsEditable cmsEditable = new JcrVersionCmsEditable(context);
- if (cmsEditable.canEdit())
- new TextEditorHeader(cmsEditable, parent, SWT.NONE).setLayoutData(CmsSwtUtils.fillWidth());
- if (!cmsEditable.isEditing())
- cmsEditable.startEditing();
- new DocumentTextEditor(page, SWT.FLAT, context, cmsEditable);
- } else {
- parent.setBackgroundMode(SWT.INHERIT_NONE);
- if (context.getSession().hasPermission(context.getPath(), Session.ACTION_ADD_NODE)) {
-// new DocumentTextEditor(page, SWT.FLAT, indexNode, cmsEditable);
-// textGd.heightHint = 400;
-
- for (NodeIterator ni = context.getNodes(); ni.hasNext();) {
- Node textNode = ni.nextNode();
- if (textNode.isNodeType(NodeType.NT_FOLDER))
- new CmsLink(textNode.getName() + "/", textNode.getPath()).createUi(parent, textNode);
- }
- for (NodeIterator ni = context.getNodes(); ni.hasNext();) {
- Node textNode = ni.nextNode();
- if (textNode.isNodeType(DbkType.article.get()) && !textNode.getName().equals(WWW))
- new CmsLink(textNode.getName(), textNode.getPath()).createUi(parent, textNode);
- }
- }
- }
- return page;
- }
-}
+++ /dev/null
-package org.argeo.docbook.ui;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.api.cms.CmsEditable;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.docbook.DbkUtils;
-import org.argeo.docbook.DbkType;
-import org.eclipse.swt.widgets.Composite;
-
-/** Text editor where sections and subsections can be managed by the user. */
-public class DocumentTextEditor extends AbstractDbkViewer {
- private static final long serialVersionUID = 6049661610883342325L;
-
- public DocumentTextEditor(Composite parent, int style, Node textNode, CmsEditable cmsEditable) {
- super(new TextSection(parent, style, textNode), style, cmsEditable);
-// refresh();
- getMainSection().setLayoutData(CmsSwtUtils.fillWidth());
- }
-
- @Override
- protected void initModel(Node textNode) throws RepositoryException {
- if (isFlat()) {
- DbkUtils.addParagraph(textNode, "");
- }
-// else
-// textNode.setProperty(DocBookNames.DBK_TITLE, textNode.getName());
- }
-
- @Override
- protected Boolean isModelInitialized(Node textNode) throws RepositoryException {
- return textNode.hasNode(DbkType.title.get()) || textNode.hasNode(DbkType.para.get())
- || (!isFlat() && textNode.hasNode(DbkType.section.get()));
- }
-
-}
+++ /dev/null
-package org.argeo.docbook.ui;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.ui.viewers.SectionPart;
-import org.argeo.cms.ui.widgets.EditableText;
-import org.argeo.cms.ui.widgets.TextStyles;
-import org.argeo.docbook.DbkType;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-
-/** An editable paragraph. */
-public class Paragraph extends EditableText implements SectionPart {
- private static final long serialVersionUID = 3746457776229542887L;
-
- private final TextSection section;
-
- public Paragraph(TextSection section, int style, Node node) throws RepositoryException {
- super(section, style, node);
- this.section = section;
- CmsSwtUtils.style(this, DbkType.para.name());
- }
-
- public TextSection getSection() {
- return section;
- }
-
- @Override
- protected Label createLabel(Composite box, String style) {
- Label lbl = super.createLabel(box, style);
- CmsSwtUtils.disableMarkupValidation(lbl);
- return lbl;
- }
-
- @Override
- public String getPartId() {
- return getNodeId();
- }
-
- @Override
- public Node getItem() throws RepositoryException {
- return getNode();
- }
-
- @Override
- public String toString() {
- return "Paragraph #" + getPartId();
- }
-}
+++ /dev/null
-package org.argeo.docbook.ui;
-
-import java.util.Observable;
-import java.util.Observer;
-
-import org.argeo.api.cms.CmsEditable;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.ui.widgets.TextStyles;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-
-/** Adds editing capabilities to a page editing text */
-public class TextEditorHeader implements SelectionListener, Observer {
- private static final long serialVersionUID = 4186756396045701253L;
-
- private final CmsEditable cmsEditable;
- private Button publish;
-
- private Composite parent;
- private Composite display;
- private Object layoutData;
-
- public TextEditorHeader(CmsEditable cmsEditable, Composite parent, int style) {
- this.cmsEditable = cmsEditable;
- this.parent = parent;
- if (this.cmsEditable instanceof Observable)
- ((Observable) this.cmsEditable).addObserver(this);
- refresh();
- }
-
- protected void refresh() {
- if (display != null && !display.isDisposed())
- display.dispose();
- display = null;
- publish = null;
- if (cmsEditable.isEditing()) {
- display = new Composite(parent, SWT.NONE);
- // display.setBackgroundMode(SWT.INHERIT_NONE);
- display.setLayoutData(layoutData);
- display.setLayout(CmsSwtUtils.noSpaceGridLayout());
- CmsSwtUtils.style(display, TextStyles.TEXT_EDITOR_HEADER);
- publish = new Button(display, SWT.FLAT | SWT.PUSH);
- publish.setText(getPublishButtonLabel());
- CmsSwtUtils.style(publish, TextStyles.TEXT_EDITOR_HEADER);
- publish.addSelectionListener(this);
- display.moveAbove(null);
- }
- parent.layout();
- }
-
- private String getPublishButtonLabel() {
- if (cmsEditable.isEditing())
- return "Publish";
- else
- return "Edit";
- }
-
- @Override
- public void widgetSelected(SelectionEvent e) {
- if (e.getSource() == publish) {
- if (cmsEditable.isEditing()) {
- cmsEditable.stopEditing();
- } else {
- cmsEditable.startEditing();
- }
- // publish.setText(getPublishButtonLabel());
- }
- }
-
- @Override
- public void widgetDefaultSelected(SelectionEvent e) {
- }
-
- @Override
- public void update(Observable o, Object arg) {
- if (o == cmsEditable) {
- // publish.setText(getPublishButtonLabel());
- refresh();
- }
- }
-
- public void setLayoutData(Object layoutData) {
- this.layoutData = layoutData;
- if (display != null && !display.isDisposed())
- display.setLayoutData(layoutData);
- }
-
-}
\ No newline at end of file
+++ /dev/null
-package org.argeo.docbook.ui;
-
-import javax.jcr.Item;
-
-/** Convert from/to data layer to/from presentation layer. */
-public interface TextInterpreter {
- String raw(Item item);
-
- String read(Item item);
-
- String readSimpleHtml(Item item);
-
- void write(Item item, String content);
-}
+++ /dev/null
-package org.argeo.docbook.ui;
-
-import javax.jcr.Node;
-
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.ui.viewers.EditablePart;
-import org.argeo.cms.ui.viewers.Section;
-import org.argeo.cms.ui.widgets.TextStyles;
-import org.argeo.docbook.DbkType;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-
-/** An editable section. */
-public class TextSection extends Section {
- private static final long serialVersionUID = -8625209546243220689L;
- private String defaultTextStyle = DbkType.para.name();
- private String titleStyle;
-
- private final boolean flat;
-
- private boolean titleReadOnly = false;
-
- private final int level;
-
- public TextSection(Composite parent, int style, Node node) {
- this(parent, findSection(parent), style, node);
- }
-
- public TextSection(TextSection section, int style, Node node) {
- this(section, section.getParentSection(), style, node);
- }
-
- private TextSection(Composite parent, Section parentSection, int style, Node node) {
- super(parent, parentSection, style, node);
- flat = SWT.FLAT == (style & SWT.FLAT);
- if (parentSection instanceof TextSection) {
- level = ((TextSection) parentSection).getLevel() + 1;
- } else {
- level = 0;
- }
- CmsSwtUtils.style(this, DbkType.section.name());
- }
-
- public String getDefaultTextStyle() {
- return defaultTextStyle;
- }
-
- public boolean isFlat() {
- return flat;
- }
-
- /** The level of this section, similar to h1, h2, etc. in HTML. */
- public int getLevel() {
- return level;
- }
-
- public String getTitleStyle() {
- if (titleStyle != null)
- return titleStyle;
- // TODO make base H styles configurable
-// Integer relativeDepth = getRelativeDepth();
-// System.out.println("Level: " + getLevel());
- return "h" + (getLevel() + 1);
- }
-
- public void setDefaultTextStyle(String defaultTextStyle) {
- this.defaultTextStyle = defaultTextStyle;
- }
-
- public void setTitleStyle(String titleStyle) {
- this.titleStyle = titleStyle;
- }
-
- public boolean isTitleReadOnly() {
- return titleReadOnly;
- }
-
- public void setTitleReadOnly(boolean titleReadOnly) {
- this.titleReadOnly = titleReadOnly;
- }
-}
+++ /dev/null
-package org.argeo.publishing.servlet;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URLDecoder;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.Collections;
-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 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.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-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.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-import javax.xml.transform.stream.StreamSource;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.xalan.processor.TransformerFactoryImpl;
-import org.argeo.api.cms.CmsTheme;
-import org.argeo.cms.auth.RemoteAuthUtils;
-import org.argeo.cms.servlet.ServletHttpRequest;
-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.w3c.dom.Document;
-
-/**
- * A servlet transforming a dbk:* JCR node into HTML, using the DocBook XSL.
- */
-public class DbkServlet extends HttpServlet {
- private static final long serialVersionUID = 6906020513498289335L;
-
- private Repository repository;
-
- private DocumentBuilderFactory documentBuilderFactory;
- private TransformerFactory transformerFactory;
- private Templates docBoookTemplates;
-
- private Map<String, CmsTheme> themes = Collections.synchronizedMap(new HashMap<>());
-
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-
- String pathInfo = req.getPathInfo();
- if (pathInfo.startsWith("//"))
- pathInfo = pathInfo.substring(1);
- String path = URLDecoder.decode(pathInfo, StandardCharsets.UTF_8);
-
- if (path.toLowerCase().endsWith(".css")) {
- path = path.substring(1);
- int firstSlash = path.indexOf('/');
- String themeId = path.substring(0, firstSlash);
- String cssPath = path.substring(firstSlash);
- CmsTheme cmsTheme = themes.get(themeId);
- if (cmsTheme == null)
- throw new IllegalArgumentException("Theme " + themeId + " not found.");
- resp.setContentType("text/css");
- IOUtils.copy(cmsTheme.getResourceAsStream(cssPath), resp.getOutputStream());
- return;
- }
-
- if (path.toLowerCase().endsWith("/index.html")) {
- path = path.substring(0, path.length() - "/index.html".length());
- }
-
- Session session = null;
- try {
- session = RemoteAuthUtils.doAs(() -> Jcr.login(repository, null), new ServletHttpRequest(req));
- Node node = session.getNode(path);
-
- if (node.hasNode(DbkType.article.get())) {
- Node dbkNode = node.getNode(DbkType.article.get());
- if (DbkUtils.isDbk(dbkNode)) {
- CmsTheme cmsTheme = null;
- String themeId = req.getParameter("themeId");
- if (themeId != null) {
- cmsTheme = themes.get(themeId);
- if (cmsTheme == null)
- throw new IllegalArgumentException("Theme " + themeId + " not found.");
- }
-
- // TODO customise DocBook so that it outputs UTF-8
- // see http://www.sagehill.net/docbookxsl/OutputEncoding.html
- resp.setContentType("text/html; charset=ISO-8859-1");
-
- // TODO optimise with pipes, SAX, etc. ?
- byte[] arr;
- try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
- session.exportDocumentView(dbkNode.getPath(), out, true, false);
- arr = out.toByteArray();
-// System.out.println(new String(arr, StandardCharsets.UTF_8));
- } catch (RepositoryException e) {
- throw new JcrException(e);
- }
-
- try (InputStream in = new ByteArrayInputStream(arr);
-// ByteArrayOutputStream out = new ByteArrayOutputStream();
- ) {
-
- Result xmlOutput = new StreamResult(resp.getOutputStream());
-
- DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder();
-// Document doc = docBuilder.parse(new File(
-// System.getProperty("user.home") + "/dev/git/gpl/argeo-qa/doc/platform/argeo-platform.dbk.xml"));
- Document doc = docBuilder.parse(in);
- Source xmlInput = new DOMSource(doc);
-
- Transformer transformer = docBoookTemplates.newTransformer();
-
- // gather CSS
- if (cmsTheme != null) {
- StringBuilder sb = new StringBuilder();
- for (String cssPath : cmsTheme.getWebCssPaths()) {
- sb.append(req.getContextPath()).append(req.getServletPath()).append('/');
- sb.append(themeId).append('/').append(cssPath).append(' ');
- }
- // FIXME make it more generic
- sb.append("https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap")
- .append(' ');
- sb.append(
- "https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,300;0,400;0,600;1,400&display=swap")
- .append(' ');
- if (sb.length() > 0)
- transformer.setParameter("html.stylesheet", sb.toString());
- }
- transformer.transform(xmlInput, xmlOutput);
-// resp.getOutputStream().write(out.toByteArray());
- } catch (Exception e) {
- throw new ServletException("Cannot transform " + path, e);
- }
- }
- } else {
- if (node.isNodeType(NodeType.NT_FILE)) {// media download etc.
- String fileNameLowerCase = node.getName().toLowerCase();
- if (fileNameLowerCase.endsWith(".jpg") || fileNameLowerCase.endsWith(".jpeg")) {
- resp.setContentType("image/jpeg");
- } else if (fileNameLowerCase.endsWith(".png")) {
- resp.setContentType("image/png");
- } else if (fileNameLowerCase.endsWith(".gif")) {
- resp.setContentType("image/gif");
- } else if (fileNameLowerCase.endsWith(".svg")) {
- resp.setContentType("image/svg+xml");
- } else {
- // TODO know more content types...
- resp.setHeader("Content-Disposition", "attachment; filename=\"" + node.getName() + "\"");
- }
- IOUtils.copy(JcrUtils.getFileAsStream(node), resp.getOutputStream());
- } else {
- throw new IllegalArgumentException("Unsupported node " + node);
- }
- }
- } catch (RepositoryException e1) {
- throw new JcrException(e1);
- } finally {
- Jcr.logout(session);
- }
- }
-
- @Override
- public void init() throws ServletException {
-
- // TODO improve configuration and provisioning of DocBook XSL
- String xslBase = System.getProperty("argeo.docbook.xsl");
- if (xslBase == null) {
- String defaultXslBase = "/opt/docbook-xsl";
- if (!Files.exists(Paths.get(defaultXslBase))) {
- throw new ServletException("System property argeo.docbook.xsl is not set and default location "
- + defaultXslBase + " does not exist.");
- } else {
- xslBase = defaultXslBase;
- }
- }
- String xsl = xslBase + "/html/docbook.xsl";
-
- documentBuilderFactory = DocumentBuilderFactory.newInstance();
- documentBuilderFactory.setXIncludeAware(true);
- documentBuilderFactory.setNamespaceAware(true);
-
- // We must explicitly use the non-XSLTC transformer, as XSLTC is not working
- // with DocBook stylesheets
- transformerFactory = new TransformerFactoryImpl();
-
- Source xslSource = new StreamSource(xsl);
- try {
- docBoookTemplates = transformerFactory.newTemplates(xslSource);
- if (docBoookTemplates == null)
- throw new ServletException("Could not instantiate XSL " + xsl);
- } catch (TransformerConfigurationException e) {
- throw new ServletException("Cannot instantiate XSL " + xsl, e);
- }
- }
-
- public void setRepository(Repository repository) {
- this.repository = repository;
- }
-
- public void addTheme(CmsTheme theme, Map<String, String> properties) {
- themes.put(theme.getThemeId(), theme);
- }
-
- public void removeTheme(CmsTheme theme, Map<String, String> properties) {
- themes.remove(theme.getThemeId());
- }
-
-}
+++ /dev/null
-package org.argeo.publishing.servlet;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.commons.io.IOUtils;
-import org.argeo.api.cms.CmsTheme;
-
-/** Serves fonts locally. */
-public class FontsServlet extends HttpServlet {
- private static final long serialVersionUID = 6009572962850708537L;
- private Map<String, CmsTheme> themes = Collections.synchronizedMap(new HashMap<>());
-
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- String font = req.getPathInfo();
- font = font.substring(1, font.length());
- for (CmsTheme theme : themes.values()) {
- for (String fontPath : theme.getFontsPaths()) {
- if (fontPath.endsWith(font)) {
- if (font.endsWith(".woff"))
- resp.setContentType("font/woff");
- else if (font.endsWith(".woff2"))
- resp.setContentType("font/woff2");
- try (InputStream in = theme.loadPath(fontPath)) {
- IOUtils.copy(in, resp.getOutputStream());
- return;
- }
- }
- }
- }
- resp.setStatus(404);
- }
-
- public void addTheme(CmsTheme theme, Map<String, String> properties) {
- themes.put(theme.getThemeId(), theme);
- }
-
- public void removeTheme(CmsTheme theme, Map<String, String> properties) {
- themes.remove(theme.getThemeId());
- }
-
-}
+++ /dev/null
-package org.argeo.publishing.ui;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.jcr.nodetype.NodeType;
-
-import org.argeo.api.cms.CmsEditable;
-import org.argeo.api.cms.CmsView;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.ui.CmsUiProvider;
-import org.argeo.cms.ui.util.CmsLink;
-import org.argeo.cms.ui.util.CmsUiUtils;
-import org.argeo.cms.ui.viewers.JcrVersionCmsEditable;
-import org.argeo.cms.ui.widgets.ScrolledPage;
-import org.argeo.docbook.DbkType;
-import org.argeo.docbook.ui.AbstractDbkViewer;
-import org.argeo.docbook.ui.DocumentTextEditor;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.browser.Browser;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-
-public class DocumentUiProvider implements CmsUiProvider {
-
- @Override
- public Control createUi(Composite parent, Node context) throws RepositoryException {
- CmsView cmsView = CmsSwtUtils.getCmsView(parent);
- CmsEditable cmsEditable = new JcrVersionCmsEditable(context);
- if (context.hasNode(DbkType.article.get())) {
- Node textNode = context.getNode(DbkType.article.get());
- // Title
- parent.setLayout(CmsSwtUtils.noSpaceGridLayout());
-
- CmsLink toHtml = new CmsLink("To HTML", "/html/dbk" + context.getPath()+"/index.html");
- toHtml.createUiPart(parent, context);
-
- ScrolledPage page = new ScrolledPage(parent, SWT.NONE);
- page.setLayoutData(CmsSwtUtils.fillAll());
- page.setLayout(CmsSwtUtils.noSpaceGridLayout());
-
- cmsView.runAs(() -> {
- AbstractDbkViewer dbkEditor = new DocumentTextEditor(page, SWT.NONE, textNode, cmsEditable);
- dbkEditor.refresh();
- });
- return page;
-
- } else if (context.isNodeType(NodeType.NT_FILE)) {
- String fileName = context.getName();
- if (fileName.endsWith(".pdf")) {
- Browser browser = new Browser(parent, SWT.NONE);
- String dataPath = CmsUiUtils.getDataPath(context);
- browser.setUrl(dataPath);
- browser.setLayoutData(CmsSwtUtils.fillAll());
- return browser;
- }
- }
- return null;
- }
-
-}
+++ /dev/null
-package org.argeo.publishing.ui;
-
-import static org.argeo.suite.ui.SuiteApp.DEFAULT_THEME_ID_PROPERTY;
-import static org.argeo.suite.ui.SuiteApp.DEFAULT_UI_NAME_PROPERTY;
-
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import javax.jcr.Node;
-import javax.jcr.Repository;
-import javax.jcr.Session;
-
-import org.argeo.api.cms.CmsApp;
-import org.argeo.api.cms.CmsUi;
-import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.AbstractCmsApp;
-import org.argeo.cms.ui.CmsUiProvider;
-import org.argeo.jcr.Jcr;
-import org.argeo.suite.ui.SuiteApp;
-import org.argeo.util.LangUtils;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.osgi.framework.Constants;
-import org.osgi.service.event.Event;
-import org.osgi.service.event.EventHandler;
-
-/**
- * A {@link CmsApp} dedicated to publishing, typically a public or internal web
- * site.
- */
-public class PublishingApp extends AbstractCmsApp implements EventHandler {
- private final static CmsLog log = CmsLog.getLog(PublishingApp.class);
-
- private String pid;
- private String defaultThemeId;
- private String defaultUiName = "";
-
- private String publicBasePath = null;
-
- private CmsUiProvider landingPage;
- private CmsUiProvider defaultProvider = new DocumentUiProvider();
-
- private Repository repository;
-
- public void init(Map<String, String> properties) {
- 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);
- publicBasePath = LangUtils.get(properties, SuiteApp.PUBLIC_BASE_PATH_PROPERTY);
- pid = properties.get(Constants.SERVICE_PID);
-
- if (log.isDebugEnabled())
- log.info("Publishing App " + pid + " started");
- }
-
- public void destroy(Map<String, String> properties) {
- if (log.isDebugEnabled())
- log.info("Publishing App " + pid + " stopped");
-
- }
-
- @Override
- public Set<String> getUiNames() {
- Set<String> uiNames = new HashSet<>();
- uiNames.add(defaultUiName);
- return uiNames;
- }
-
- @Override
- public CmsUi initUi(Object uiParent) {
- Composite parent = (Composite) uiParent;
-// Session adminSession = NodeUtils.openDataAdminSession(getRepository(), null);
- Session session = Jcr.login(getRepository(), null);
- parent.setLayout(new GridLayout());
- Node indexNode = Jcr.getNode(session, publicBasePath + "/index");
-// try {
-// indexNode = JcrUtils.getOrAdd(Jcr.getRootNode(adminSession), DocumentPage.WWW, DbkType.article.get());
-// adminSession.save();
-// } catch (RepositoryException e) {
-// throw new IllegalStateException(e);
-// }
-
- Control page;
- if (landingPage != null) {
- page = landingPage.createUiPart(parent, indexNode);
- } else {
- page = defaultProvider.createUiPart(parent, indexNode);
- }
- return (CmsUi) page;
- }
-
- @Override
- public void refreshUi(CmsUi cmsUi, String state) {
- Composite parent = (Composite) cmsUi;
- parent.setLayout(new GridLayout());
- if (landingPage != null)
- landingPage.createUiPart(parent, null);
- else
- defaultProvider.createUiPart(parent, null);
- }
-
- @Override
- public void setState(CmsUi cmsUi, String state) {
-
- }
-
- @Override
- protected String getThemeId(String uiName) {
- return defaultThemeId;
- }
-
- public void setLandingPage(CmsUiProvider landingPage) {
- this.landingPage = landingPage;
- }
-
- @Override
- public void handleEvent(Event event) {
- // TODO listen to some events
-
- }
-
- public Repository getRepository() {
- return repository;
- }
-
- public void setRepository(Repository repository) {
- this.repository = repository;
- }
-
-}
+++ /dev/null
-package org.argeo.publishing.ui;
-
-import org.argeo.api.cms.CmsStyle;
-
-/** Publishing styles. */
-public enum PublishingStyle implements CmsStyle {
- // general
- page, coverTitle, coverSubTitle, coverTagline, bannerLine1, bannerLine2,
- // meta data
- tag, menu,
- // text style
- title, subTitle, chapo, para, sectionTitle, subSectionTitle,
- // links
- internalLink,
- // composite style
- framed, line;
-
- @Override
- public String getClassPrefix() {
- return "argeo-publishing";
- }
-
-}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
- <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
- <classpathentry kind="src" path="src"/>
- <classpathentry kind="output" path="bin"/>
-</classpath>
+++ /dev/null
-/bin/
-/target/
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>org.argeo.suite.core</name>
- <comment></comment>
- <projects>
- </projects>
- <buildSpec>
- <buildCommand>
- <name>org.eclipse.jdt.core.javabuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.ManifestBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.SchemaBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.ds.core.builder</name>
- <arguments>
- </arguments>
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>org.eclipse.pde.PluginNature</nature>
- <nature>org.eclipse.jdt.core.javanature</nature>
- </natures>
-</projectDescription>
+++ /dev/null
-/MANIFEST.MF
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy" name="Suite Maintenance Service">
- <implementation class="org.argeo.suite.core.SuiteMaintenanceService"/>
- <reference bind="setRepository" cardinality="1..1" interface="javax.jcr.Repository" name="Repository" policy="static" target="(cn=entity)"/>
- <reference bind="setUserTransaction" cardinality="1..1" interface="javax.transaction.UserTransaction" name="UserTransaction" policy="static"/>
- <reference bind="setUserAdmin" cardinality="1..1" interface="org.osgi.service.useradmin.UserAdmin" name="UserAdmin" policy="static"/>
-</scr:component>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy" name="Suite Terms Manager">
- <implementation class="org.argeo.suite.core.SuiteTermsManager"/>
- <reference bind="setRepository" cardinality="1..1" interface="javax.jcr.Repository" name="Repository" policy="static" target="(cn=entity)"/>
- <service>
- <provide interface="org.argeo.entity.TermsManager"/>
- </service>
-</scr:component>
+++ /dev/null
-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.entity,\
-*
\ No newline at end of file
+++ /dev/null
-output.. = bin/
-bin.includes = META-INF/,\
- .,\
- OSGI-INF/
-source.. = src/
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.argeo.suite</groupId>
- <artifactId>argeo-suite</artifactId>
- <version>2.3-SNAPSHOT</version>
- <relativePath>..</relativePath>
- </parent>
- <artifactId>org.argeo.suite.core</artifactId>
- <name>Suite Core</name>
- <packaging>jar</packaging>
- <dependencies>
- <dependency>
- <groupId>org.argeo.suite</groupId>
- <artifactId>org.argeo.entity.core</artifactId>
- <version>2.3-SNAPSHOT</version>
- </dependency>
-
- <!-- Argeo Commons -->
- <dependency>
- <groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.cms</artifactId>
- <version>${version.argeo-commons}</version>
- </dependency>
- <dependency>
- <groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.cms.jcr</artifactId>
- <version>${version.argeo-commons}</version>
- </dependency>
- </dependencies>
-</project>
+++ /dev/null
-package org.argeo.suite;
-
-import java.util.Map;
-
-import org.argeo.api.cms.CmsLog;
-
-/**
- * A container for an object whose relevance can be ranked. Typically used in an
- * OSGi context with the service.ranking property.
- */
-public class RankedObject<T> {
- private final static CmsLog log = CmsLog.getLog(RankedObject.class);
-
- private final static String SERVICE_RANKING = "service.ranking";
-// private final static String SERVICE_ID = "service.id";
-
- private T object;
- private Map<String, Object> properties;
- private final Long rank;
-
- public RankedObject(T object, Map<String, Object> properties) {
- this(object, properties, extractRanking(properties));
- }
-
- public RankedObject(T object, Map<String, Object> properties, Long rank) {
- super();
- this.object = object;
- this.properties = properties;
- this.rank = rank;
- }
-
- private static Long extractRanking(Map<String, Object> 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<String, Object> 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 <K, T> RankedObject<T> putIfHigherRank(Map<K, RankedObject<T>> map, K key, T object,
- Map<String, Object> properties) {
- RankedObject<T> rankedObject = new RankedObject<>(object, properties);
- if (!map.containsKey(key)) {
- map.put(key, rankedObject);
- if (log.isTraceEnabled())
- log.trace(
- "Added " + key + " as " + object.getClass().getName() + " with rank " + rankedObject.getRank());
- return rankedObject;
- } else {
- RankedObject<T> current = map.get(key);
- if (current.getRank() <= rankedObject.getRank()) {
- map.put(key, rankedObject);
- if (log.isTraceEnabled())
- log.trace("Replaced " + key + " by " + object.getClass().getName() + " with rank "
- + rankedObject.getRank());
- return rankedObject;
- } else {
- return current;
- }
- }
-
- }
-
-}
+++ /dev/null
-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<RankingKey> {
- 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<String, Object> 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);
- }
-}
+++ /dev/null
-package org.argeo.suite;
-
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.util.naming.Distinguished;
-import org.argeo.util.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(CmsConstants.ROLES_BASEDN).toString();
- }
-}
+++ /dev/null
-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.cms.CmsSession;
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.entity.EntityType;
-import org.argeo.jackrabbit.security.JackrabbitSecurityUtils;
-import org.argeo.jcr.JcrException;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.util.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(), CmsConstants.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<String> extractRoles(String[] semiColArr) {
- Set<String> 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;
- }
-
-}
+++ /dev/null
-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.argeo.api.cms.CmsLog;
-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 CmsLog log = CmsLog.getLog(AbstractMaintenanceService.class);
-
- protected List<String> getTypologies() {
- return new ArrayList<>();
- }
-
- protected String getTypologiesLoadBase() {
- return "/sys/terms";
- }
-
- protected void loadTypologies(Node customBaseNode) throws RepositoryException, IOException {
- List<String> 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;
- }
- }
-
-}
+++ /dev/null
-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.cms.CmsConstants;
-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(), CmsConstants.ROLE_USER_ADMIN,
- Privilege.JCR_ALL);
- //JcrUtils.addPrivilege(adminSession, "/", SuiteRole.coworker.dn(), Privilege.JCR_READ);
- }
-
-}
+++ /dev/null
-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<SuiteTerm> 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<SuiteTerm> getSubTerms() {
- return subTerms;
- }
-
- @Override
- public SuiteTerm getParentTerm() {
- return parentTerm;
- }
-
-}
+++ /dev/null
-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.cms.CmsConstants;
-import org.argeo.cms.jcr.CmsJcrUtils;
-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<String, SuiteTerm> terms = new HashMap<>();
- private final Map<String, SuiteTypology> typologies = new HashMap<>();
-
- // JCR
- private Repository repository;
- private Session adminSession;
-
- public void init() {
- adminSession = CmsJcrUtils.openDataAdminSession(repository, CmsConstants.SYS_WORKSPACE);
- }
-
- @Override
- public List<Term> listAllTerms(String typology) {
- List<Term> 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;
- }
-
-}
+++ /dev/null
-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<SuiteTerm> 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<SuiteTerm> getSubTerms() {
- return subTerms;
- }
-
- public List<SuiteTerm> getAllTerms() {
- if (isFlat)
- return subTerms;
- else {
- List<SuiteTerm> terms = new ArrayList<>();
- for (SuiteTerm subTerm : subTerms) {
- terms.add(subTerm);
- collectSubTerms(terms, subTerm);
- }
- return terms;
- }
- }
-
- public Term findTermByName(String name) {
- List<SuiteTerm> 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<SuiteTerm> collected) {
- if (term.getName().equals(name)) {
- collected.add(term);
- }
- for (SuiteTerm subTerm : term.getSubTerms()) {
- collectTermsByName(subTerm, name, collected);
- }
- }
-
- private void collectSubTerms(List<SuiteTerm> terms, SuiteTerm term) {
- for (SuiteTerm subTerm : term.getSubTerms()) {
- terms.add(subTerm);
- collectSubTerms(terms, subTerm);
- }
- }
-
-}
+++ /dev/null
-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<Tbl> tables = new ArrayList<>();
- protected List<String> text = new ArrayList<>();
- protected Map<String, byte[]> media = new TreeMap<>();
- private Set<String> mediaDigests = new HashSet<>();
-
- protected void processTextItem(List<String> 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<Tr> 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<Tr> 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<Tc> 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<Tc> 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<String> getText() {
- return text;
- }
-
- public List<Tbl> getTables() {
- return tables;
- }
-
- public Map<String, byte[]> 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");
- }
- }
-
-}
+++ /dev/null
-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.jackrabbit.util.ISO9075;
-import org.argeo.api.cms.CmsLog;
-
-/** Ease XPath generation for JCR requests */
-public class XPathUtils {
- private final static CmsLog log = CmsLog.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() {
-
- }
-}
+++ /dev/null
-/bin/
-/target/
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>org.argeo.suite.theme.default</name>
- <comment></comment>
- <projects>
- </projects>
- <buildSpec>
- <buildCommand>
- <name>org.eclipse.pde.ManifestBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.SchemaBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.ds.core.builder</name>
- <arguments>
- </arguments>
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>org.eclipse.pde.PluginNature</nature>
- </natures>
-</projectDescription>
+++ /dev/null
-/MANIFEST.MF
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy" name="Argeo Suite Default Theme">
- <implementation class="org.argeo.cms.swt.osgi.BundleCmsSwtTheme"/>
- <service>
- <provide interface="org.argeo.api.cms.CmsTheme"/>
- </service>
-</scr:component>
+++ /dev/null
-Service-Component:\
-OSGI-INF/cmsTheme.xml
-
-Import-Package:\
-org.argeo.cms.swt.osgi,\
-*
\ No newline at end of file
+++ /dev/null
-bin.includes = META-INF/,\
- OSGI-INF/
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.argeo.suite</groupId>
- <artifactId>argeo-suite</artifactId>
- <version>2.3-SNAPSHOT</version>
- <relativePath>..</relativePath>
- </parent>
- <artifactId>org.argeo.suite.theme.default</artifactId>
- <name>Suite Default Theme</name>
- <packaging>jar</packaging>
- <dependencies>
- </dependencies>
-</project>
+++ /dev/null
-.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;
-}
+++ /dev/null
-.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
+++ /dev/null
-/bin/
-/target/
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>org.argeo.suite.ui.rap</name>
- <comment></comment>
- <projects>
- </projects>
- <buildSpec>
- <buildCommand>
- <name>org.eclipse.pde.ManifestBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.SchemaBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.ds.core.builder</name>
- <arguments>
- </arguments>
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>org.eclipse.pde.PluginNature</nature>
- </natures>
-</projectDescription>
+++ /dev/null
-/MANIFEST.MF
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy" name="Argeo Suite Web App">
- <implementation class="org.argeo.cms.web.CmsWebApp"/>
- <property name="contextName" type="String" value="argeo"/>
- <reference bind="setCmsApp" cardinality="1..1" interface="org.argeo.api.cms.CmsApp" name="CmsApp" policy="dynamic" target="(service.pid=argeo.suite.ui.app)" unbind="unsetCmsApp"/>
- <reference bind="setEventAdmin" cardinality="1..1" interface="org.osgi.service.event.EventAdmin" name="EventAdmin" policy="static"/>
-</scr:component>
+++ /dev/null
-Service-Component: OSGI-INF/cmsWebApp.xml
-
-Import-Package:\
-org.argeo.cms.web;resolution:=optional,\
-org.eclipse.rap.rwt.application;resolution:=optional,\
-*;resolution:=optional
+++ /dev/null
-output.. = bin/
-bin.includes = META-INF/,\
- .,\
- OSGI-INF/
-source.. = src/
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.argeo.suite</groupId>
- <artifactId>argeo-suite</artifactId>
- <version>2.3-SNAPSHOT</version>
- <relativePath>..</relativePath>
- </parent>
- <artifactId>org.argeo.suite.ui.rap</artifactId>
- <name>Suite UI RAP</name>
- <packaging>jar</packaging>
- <dependencies>
- <dependency>
- <groupId>org.argeo.suite</groupId>
- <artifactId>org.argeo.suite.ui</artifactId>
- <version>2.3-SNAPSHOT</version>
- </dependency>
-
- <!-- Eclipse E4 -->
- <dependency>
- <groupId>org.argeo.tp</groupId>
- <artifactId>argeo-tp-rap-e4</artifactId>
- <version>${version.argeo-tp}</version>
- <type>pom</type>
- <scope>provided</scope>
- </dependency>
- </dependencies>
-</project>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
- <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
- <classpathentry kind="src" path="src"/>
- <classpathentry kind="output" path="bin"/>
-</classpath>
+++ /dev/null
-/bin/
-/target/
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>org.argeo.suite.ui</name>
- <comment></comment>
- <projects>
- </projects>
- <buildSpec>
- <buildCommand>
- <name>org.eclipse.jdt.core.javabuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.ManifestBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.SchemaBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.ds.core.builder</name>
- <arguments>
- </arguments>
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>org.eclipse.pde.PluginNature</nature>
- <nature>org.eclipse.jdt.core.javanature</nature>
- </natures>
-</projectDescription>
+++ /dev/null
-/MANIFEST.MF
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy" immediate="false" name="Admin Lead Pane">
- <implementation class="org.argeo.suite.ui.DefaultLeadPane"/>
- <service>
- <provide interface="org.argeo.cms.ui.CmsUiProvider"/>
- </service>
- <properties entry="config/adminLeadPane.properties"/>
- <property name="defaultLayers" type="String">argeo.suite.ui.termsLayer
- </property>
- <reference bind="addLayer" cardinality="1..n" interface="org.argeo.suite.ui.SuiteLayer" name="SuiteLayer" policy="dynamic" unbind="removeLayer"/>
-</scr:component>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy" name="Argeo Suite App">
- <implementation class="org.argeo.suite.ui.SuiteApp"/>
- <service>
- <provide interface="org.argeo.api.cms.CmsApp"/>
- <provide interface="org.osgi.service.event.EventHandler"/>
- </service>
- <properties entry="config/cmsApp.properties"/>
- <reference bind="addUiProvider" cardinality="0..n" interface="org.argeo.cms.ui.CmsUiProvider" name="CmsUiProvider" policy="dynamic" unbind="removeUiProvider"/>
- <reference bind="addTheme" cardinality="1..n" interface="org.argeo.api.cms.CmsTheme" name="CmsTheme" policy="dynamic" unbind="removeTheme"/>
- <reference bind="setRepository" cardinality="1..1" interface="javax.jcr.Repository" name="Repository" policy="dynamic" target="(cn=ego)"/>
- <reference bind="addLayer" cardinality="1..n" interface="org.argeo.suite.ui.SuiteLayer" name="SuiteLayer" policy="dynamic" unbind="removeLayer"/>
- <reference bind="setCmsUserManager" cardinality="1..1" interface="org.argeo.cms.CmsUserManager" name="CmsUserManager" policy="static"/>
-</scr:component>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="Default Dashboard">
- <implementation class="org.argeo.suite.ui.DefaultDashboard"/>
- <service>
- <provide interface="org.argeo.cms.ui.CmsUiProvider"/>
- </service>
- <properties entry="config/dashboard.properties"/>
-</scr:component>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="Dashboard Layer">
- <implementation class="org.argeo.suite.ui.DefaultEditionLayer"/>
- <service>
- <provide interface="org.argeo.suite.ui.SuiteLayer"/>
- </service>
- <properties entry="config/dashboardLayer.properties"/>
- <reference bind="setEntryArea" cardinality="1..1" interface="org.argeo.cms.ui.CmsUiProvider" name="CmsUiProvider" policy="dynamic" target="(service.pid=argeo.suite.ui.recentItems)"/>
-</scr:component>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy" name="Event Recorder">
- <implementation class="org.argeo.suite.ui.EventRecorder"/>
- <service>
- <provide interface="org.osgi.service.event.EventHandler"/>
- </service>
- <properties entry="config/eventRecorder.properties"/>
-</scr:component>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy" immediate="false" name="Default Suite Footer">
- <implementation class="org.argeo.suite.ui.DefaultFooter"/>
- <service>
- <provide interface="org.argeo.cms.ui.CmsUiProvider"/>
- </service>
- <properties entry="config/footer.properties"/>
-</scr:component>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy" immediate="false" name="Default Suite Header">
- <implementation class="org.argeo.suite.ui.DefaultHeader"/>
- <service>
- <provide interface="org.argeo.cms.ui.CmsUiProvider"/>
- </service>
- <properties entry="config/header.properties"/>
-</scr:component>
+++ /dev/null
-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.
+++ /dev/null
-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.
+++ /dev/null
-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.
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy" immediate="false" name="Default Lead Pane">
- <implementation class="org.argeo.suite.ui.DefaultLeadPane"/>
- <service>
- <provide interface="org.argeo.cms.ui.CmsUiProvider"/>
- </service>
- <properties entry="config/leadPane.properties"/>
- <property name="defaultLayers" type="String">argeo.suite.ui.dashboardLayer
-argeo.library.ui.contentLayer
-argeo.people.ui.peopleLayer
-argeo.geo.ui.mapLayer
- </property>
- <reference bind="addLayer" cardinality="1..n" interface="org.argeo.suite.ui.SuiteLayer" name="SuiteLayer" policy="dynamic" unbind="removeLayer"/>
-</scr:component>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="Default Login Screen">
- <implementation class="org.argeo.suite.ui.DefaultLoginScreen"/>
- <properties entry="config/loginScreen.properties"/>
- <service>
- <provide interface="org.argeo.cms.ui.CmsUiProvider"/>
- </service>
-</scr:component>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" name="Default Recent Items">
- <implementation class="org.argeo.suite.ui.RecentItems"/>
- <service>
- <provide interface="org.argeo.cms.ui.CmsUiProvider"/>
- </service>
- <properties entry="config/recentItems.properties"/>
-</scr:component>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="Terms Entry Area">
- <implementation class="org.argeo.suite.ui.TermsEntryArea"/>
- <service>
- <provide interface="org.argeo.cms.ui.CmsUiProvider"/>
- </service>
- <properties entry="config/termsEntryArea.properties"/>
-</scr:component>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="Terms Layer">
- <implementation class="org.argeo.suite.ui.DefaultEditionLayer"/>
- <service>
- <provide interface="org.argeo.suite.ui.SuiteLayer"/>
- </service>
- <properties entry="config/termsLayer.properties"/>
- <reference bind="setEntryArea" cardinality="1..1" interface="org.argeo.cms.ui.CmsUiProvider" name="CmsUiProvider" policy="dynamic" target="(service.pid=argeo.suite.ui.termsEntryArea)"/>
-</scr:component>
+++ /dev/null
-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.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,\
-*
+++ /dev/null
-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/
+++ /dev/null
-service.pid=argeo.suite.ui.adminLeadPane
+++ /dev/null
-service.pid=argeo.suite.ui.app
-
-event.topics=argeo/suite/*
\ No newline at end of file
+++ /dev/null
-service.pid=argeo.suite.ui.dashboard
+++ /dev/null
-service.pid=argeo.suite.ui.dashboardLayer
-
-title=Dashboard
-icon=dashboard
\ No newline at end of file
+++ /dev/null
-service.pid=argeo.suite.ui.eventRecorder
-
-event.topics=argeo/suite/*
\ No newline at end of file
+++ /dev/null
-service.pid=argeo.suite.ui.footer
+++ /dev/null
-service.pid=argeo.suite.ui.header
-argeo.suite.ui=true
-
-argeo.suite.ui.header.title=%appTitle
\ No newline at end of file
+++ /dev/null
-service.pid=argeo.suite.ui.leadPane
+++ /dev/null
-service.pid=argeo.suite.ui.loginScreen
+++ /dev/null
-service.pid=argeo.suite.ui.recentItems
+++ /dev/null
-service.pid=argeo.suite.ui.termsEntryArea
+++ /dev/null
-service.pid=argeo.suite.ui.termsLayer
-title=Terms
-icon=dashboard
-
-entity.type=entity:terms,entity:term
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.argeo.suite</groupId>
- <artifactId>argeo-suite</artifactId>
- <version>2.3-SNAPSHOT</version>
- <relativePath>..</relativePath>
- </parent>
- <artifactId>org.argeo.suite.ui</artifactId>
- <name>Suite UI</name>
- <packaging>jar</packaging>
- <dependencies>
- <dependency>
- <groupId>org.argeo.suite</groupId>
- <artifactId>org.argeo.suite.core</artifactId>
- <version>2.3-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.argeo.suite</groupId>
- <artifactId>org.argeo.entity.ui</artifactId>
- <version>2.3-SNAPSHOT</version>
- </dependency>
-
- <!-- Argeo Commons -->
- <dependency>
- <groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.cms.ui</artifactId>
- <version>${version.argeo-commons}</version>
- </dependency>
- <!-- Specific -->
- <dependency>
- <groupId>org.argeo.commons.rap</groupId>
- <artifactId>org.argeo.swt.specific.rap</artifactId>
- <version>${version.argeo-commons}</version>
- <scope>provided</scope>
- </dependency>
-
- <!-- Eclipse E4 -->
- <dependency>
- <groupId>org.argeo.tp</groupId>
- <artifactId>argeo-tp-rap-e4</artifactId>
- <version>${version.argeo-tp}</version>
- <type>pom</type>
- <scope>provided</scope>
- </dependency>
- </dependencies>
-</project>
+++ /dev/null
-package org.argeo.suite.ui;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.api.cms.CmsView;
-import org.argeo.cms.auth.CurrentUser;
-import org.argeo.cms.swt.CmsSwtUtils;
-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;
-
-/** Provides a dashboard. */
-public class DefaultDashboard implements CmsUiProvider {
-
- @Override
- public Control createUi(Composite parent, Node context) throws RepositoryException {
- parent.setLayout(new GridLayout());
- CmsView cmsView = CmsSwtUtils.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;
- }
-
-}
+++ /dev/null
-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.api.cms.CmsTheme;
-import org.argeo.cms.Localized;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.ui.CmsUiProvider;
-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<String> 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);
- CmsSwtUtils.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 = CmsSwtUtils.getCmsTheme(parent);
- TabbedArea tabbedArea = createTabbedArea(parent, theme);
- return tabbedArea;
- }
- }
-
- @Override
- public void view(CmsUiProvider uiProvider, Composite workAreaC, Node context) {
- if (workArea != null) {
- try {
- CmsSwtUtils.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<String, Object> 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<String, String> 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(CmsSwtUtils.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 = CmsSwtUtils.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 = CmsSwtUtils.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 = CmsSwtUtils.getCmsTheme(parent);
-
- setLayout(CmsSwtUtils.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(CmsSwtUtils.fillHeight());
-
- GridLayout editorAreaLayout = CmsSwtUtils.noSpaceGridLayout();
-// editorAreaLayout.verticalSpacing = 0;
-// editorAreaLayout.marginBottom = 0;
-// editorAreaLayout.marginHeight = 0;
-// editorAreaLayout.marginLeft = 0;
-// editorAreaLayout.marginRight = 0;
- editorC.setLayout(editorAreaLayout);
- editorC.setLayoutData(CmsSwtUtils.fillAll());
-
- tabbedArea = createTabbedArea(editorC, theme);
- }
-
- TabbedArea getTabbedArea() {
- return tabbedArea;
- }
-
- Composite getEntryArea() {
- return entryC;
- }
- }
-
-}
\ No newline at end of file
+++ /dev/null
-package org.argeo.suite.ui;
-
-import java.util.Map;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.ui.CmsUiProvider;
-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(CmsSwtUtils.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<String, String> properties) {
- }
-
- public void destroy(BundleContext bundleContext, Map<String, String> properties) {
-
- }
-}
+++ /dev/null
-package org.argeo.suite.ui;
-
-import java.util.Map;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.api.cms.CmsTheme;
-import org.argeo.api.cms.CmsView;
-import org.argeo.cms.Localized;
-import org.argeo.cms.auth.CurrentUser;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.ui.CmsUiProvider;
-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 = CmsSwtUtils.getCmsView(parent);
- CmsTheme theme = CmsSwtUtils.getCmsTheme(parent);
-
- parent.setLayout(CmsSwtUtils.noSpaceGridLayout(new GridLayout(3, true)));
-
- // TODO right to left
- Composite lead = new Composite(parent, SWT.NONE);
- CmsSwtUtils.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());
- CmsSwtUtils.style(lbl, SuiteStyle.headerTitle);
- lbl.setLayoutData(CmsSwtUtils.fillWidth());
-
- Composite middle = new Composite(parent, SWT.NONE);
- CmsSwtUtils.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);
- CmsSwtUtils.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);
- CmsSwtUtils.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<String, String> 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<String, String> properties) {
-
- }
-
- public Localized getTitle() {
- return title;
- }
-
-}
+++ /dev/null
-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.argeo.api.cms.CmsView;
-import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.Localized;
-import org.argeo.cms.auth.CurrentUser;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.ui.CmsUiProvider;
-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 CmsLog log = CmsLog.getLog(DefaultLeadPane.class);
-
- public static enum Property {
- defaultLayers, adminLayers;
- }
-
- private Map<String, RankedObject<SuiteLayer>> layers = Collections.synchronizedSortedMap(new TreeMap<>());
- private List<String> defaultLayers;
- private List<String> adminLayers = new ArrayList<>();
-
- private ClassLoader l10nClassLoader;
-
- @Override
- public Control createUi(Composite parent, Node node) throws RepositoryException {
- CmsView cmsView = CmsSwtUtils.getCmsView(parent);
- parent.setLayout(CmsSwtUtils.noSpaceGridLayout());
- Composite appLayersC = new Composite(parent, SWT.NONE);
- CmsSwtUtils.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);
- CmsSwtUtils.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<String> 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<String> layerRoles = SuiteUtils.extractRoles(semiColArr);
- if (layers.containsKey(layerId)) {
- if (!layerRoles.isEmpty()) {
- Set<String> intersection = new HashSet<String>(layerRoles);
- intersection.retainAll(userRoles);
- if (intersection.isEmpty())
- continue layers;// skip unauthorized layer
- }
- RankedObject<SuiteLayer> 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<String, Object> 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<String, String> properties) {
-
- }
-
- public void addLayer(SuiteLayer layer, Map<String, Object> 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<String, Object> 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<SuiteLayer>(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;
-// }
-}
+++ /dev/null
-package org.argeo.suite.ui;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.api.cms.CmsView;
-import org.argeo.cms.auth.CurrentUser;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.swt.auth.CmsLogin;
-import org.argeo.cms.ui.CmsUiProvider;
-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 = CmsSwtUtils.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();
- }
-
-}
+++ /dev/null
-package org.argeo.suite.ui;
-
-import org.argeo.api.cms.CmsLog;
-import org.osgi.service.event.Event;
-import org.osgi.service.event.EventHandler;
-
-/** Record UI events. */
-public class EventRecorder implements EventHandler {
- private final static CmsLog log = CmsLog.getLog(EventRecorder.class);
-
- public void init() {
-
- }
-
- public void destroy() {
-
- }
-
- @Override
- public void handleEvent(Event event) {
- if (log.isTraceEnabled())
- log.trace(event);
-
- }
-
-}
+++ /dev/null
-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.api.cms.CmsTheme;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.ui.CmsUiProvider;
-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 = CmsSwtUtils.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(CmsSwtUtils.fillAll());
-
- Composite bottom = new Composite(parent, SWT.NONE);
- bottom.setLayoutData(CmsSwtUtils.fillWidth());
- bottom.setLayout(CmsSwtUtils.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)
- CmsSwtUtils.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) {
- CmsSwtUtils.getCmsView(parent).sendEvent(SuiteEvent.refreshPart.topic(),
- SuiteEvent.eventProperties(node));
- deleteItem.setEnabled(true);
- } else {
- deleteItem.setEnabled(false);
- }
- }
- });
-
- return entityViewer.filterTxt;
-
- }
-
- public void init(Map<String, String> 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<Node> 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<Node>) newInput;
- }
-
- public Object[] getElements(Object arg0) {
- return nodes.toArray();
- }
- }
- }
-}
+++ /dev/null
-package org.argeo.suite.ui;
-
-import static org.argeo.api.cms.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.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.nodetype.NodeType;
-import javax.naming.InvalidNameException;
-import javax.naming.ldap.LdapName;
-
-import org.argeo.api.cms.CmsSession;
-import org.argeo.api.cms.CmsTheme;
-import org.argeo.api.cms.CmsUi;
-import org.argeo.api.cms.CmsView;
-import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.AbstractCmsApp;
-import org.argeo.cms.CmsUserManager;
-import org.argeo.cms.LocaleUtils;
-import org.argeo.cms.Localized;
-import org.argeo.cms.jcr.CmsJcrUtils;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.swt.dialogs.CmsFeedback;
-import org.argeo.cms.ui.CmsUiProvider;
-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 CmsLog log = CmsLog.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<String, RankedObject<CmsUiProvider>> uiProvidersByPid = Collections.synchronizedMap(new HashMap<>());
- private Map<String, RankedObject<CmsUiProvider>> uiProvidersByType = Collections.synchronizedMap(new HashMap<>());
- private Map<String, RankedObject<SuiteLayer>> layersByPid = Collections.synchronizedSortedMap(new TreeMap<>());
- private Map<String, RankedObject<SuiteLayer>> layersByType = Collections.synchronizedSortedMap(new TreeMap<>());
-
- private CmsUserManager cmsUserManager;
-
- // TODO make more optimal or via CmsSession/CmsView
- private Map<String, SuiteUi> managedUis = new HashMap<>();
-
- private Repository repository;
-
-
- public void init(Map<String, Object> 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<String, Object> properties) {
- for (SuiteUi ui : managedUis.values())
- if (!ui.isDisposed())
- ui.dispose();
- if (log.isDebugEnabled())
- log.info("Argeo Suite App stopped");
-
- }
-
- @Override
- public Set<String> getUiNames() {
- HashSet<String> uiNames = new HashSet<>();
- uiNames.add(defaultUiName);
- uiNames.add(adminUiName);
- return uiNames;
- }
-
- @Override
- public CmsUi initUi(Object parent) {
- Composite uiParent =(Composite) parent;
- String uiName = uiParent.getData(UI_NAME_PROPERTY) != null ? uiParent.getData(UI_NAME_PROPERTY).toString() : null;
- CmsView cmsView = CmsSwtUtils.getCmsView(uiParent);
- if (cmsView == null)
- throw new IllegalStateException("No CMS view is registered.");
- CmsTheme theme = getTheme(uiName);
- if (theme != null)
- CmsSwtUtils.registerCmsTheme(uiParent.getShell(), theme);
- SuiteUi argeoSuiteUi = new SuiteUi(uiParent, 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(CmsUi cmsUi, String state) {
- try {
- Node context = null;
- SuiteUi ui = (SuiteUi) cmsUi;
-
- 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 = CmsSwtUtils.getCmsView(ui);
- 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 = CmsJcrUtils.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(ui, 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) {
- CmsSwtUtils.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> T findByType(Map<String, RankedObject<T>> byType, Node context) {
- if (context == null)
- throw new IllegalArgumentException("A node should be provided");
- try {
- // mixins
- Set<String> types = new TreeSet<>();
- for (NodeType mixinType : context.getMixinNodeTypes()) {
- String mixinTypeName = mixinType.getName();
- if (byType.containsKey(mixinTypeName)) {
- types.add(mixinTypeName);
- }
- for (NodeType superType : mixinType.getDeclaredSupertypes()) {
- if (byType.containsKey(superType.getName())) {
- types.add(superType.getName());
- }
- }
- }
- // primary node type
- NodeType primaryType = context.getPrimaryNodeType();
- String primaryTypeName = primaryType.getName();
- if (byType.containsKey(primaryTypeName)) {
- types.add(primaryTypeName);
- }
- for (NodeType superType : primaryType.getDeclaredSupertypes()) {
- if (byType.containsKey(superType.getName())) {
- types.add(superType.getName());
- }
- }
- // entity type
- if (context.isNodeType(EntityType.entity.get())) {
- if (context.hasProperty(EntityNames.ENTITY_TYPE)) {
- String entityTypeName = context.getProperty(EntityNames.ENTITY_TYPE).getString();
- if (byType.containsKey(entityTypeName)) {
- types.add(entityTypeName);
- }
- }
- }
-
-// if (context.getPath().equals("/")) {// root node
-// types.add("nt:folder");
-// }
- if (CmsJcrUtils.isUserHome(context) && byType.containsKey("nt:folder")) {// home node
- types.add("nt:folder");
- }
-
- if (types.size() == 0)
- throw new IllegalArgumentException("No type found for " + context + " (" + listTypes(context) + ")");
- String type = types.iterator().next();
- if (!byType.containsKey(type))
- throw new IllegalArgumentException("No component found for " + context + " with type " + type);
- return byType.get(type).get();
- } catch (RepositoryException e) {
- throw new IllegalStateException(e);
- }
- }
-
- 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(CmsUi cmsUi, String state) {
- if (state == null)
- return;
- if (!state.startsWith("/")) {
- if (cmsUi instanceof SuiteUi) {
- SuiteUi ui = (SuiteUi) cmsUi;
- if (LOGIN.equals(state)) {
- String appTitle = "";
- if (ui.getTitle() != null)
- appTitle = ui.getTitle().lead();
- ui.getCmsView().stateChanged(state, appTitle);
- return;
- }
- Map<String, Object> 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) cmsUi;
- 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 = CmsJcrUtils.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<String, Object> 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<String> types = LangUtils.toStringList(properties.get(EntityConstants.TYPE));
- for (String type : types)
- RankedObject.putIfHigherRank(uiProvidersByType, type, uiProvider, properties);
- }
- }
-
- public void removeUiProvider(CmsUiProvider uiProvider, Map<String, Object> 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<CmsUiProvider>(uiProvider, properties))) {
- uiProvidersByPid.remove(pid);
- }
- }
- }
- if (properties.containsKey(EntityConstants.TYPE)) {
- List<String> types = LangUtils.toStringList(properties.get(EntityConstants.TYPE));
- for (String type : types) {
- if (uiProvidersByType.containsKey(type)) {
- if (uiProvidersByType.get(type).equals(new RankedObject<CmsUiProvider>(uiProvider, properties))) {
- uiProvidersByType.remove(type);
- }
- }
- }
- }
- }
-
- public void addLayer(SuiteLayer layer, Map<String, Object> 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<String> types = LangUtils.toStringList(properties.get(EntityConstants.TYPE));
- for (String type : types)
- RankedObject.putIfHigherRank(layersByType, type, layer, properties);
- }
- }
-
- public void removeLayer(SuiteLayer layer, Map<String, Object> 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<SuiteLayer>(layer, properties))) {
- layersByPid.remove(pid);
- }
- }
- }
- if (properties.containsKey(EntityConstants.TYPE)) {
- List<String> types = LangUtils.toStringList(properties.get(EntityConstants.TYPE));
- for (String type : types) {
- if (layersByType.containsKey(type)) {
- if (layersByType.get(type).equals(new RankedObject<CmsUiProvider>(layer, properties))) {
- layersByType.remove(type);
- }
- }
- }
- }
- }
-
- public void setCmsUserManager(CmsUserManager cmsUserManager) {
- this.cmsUserManager = cmsUserManager;
- }
-
- public Repository getRepository() {
- return repository;
- }
-
- public void setRepository(Repository repository) {
- this.repository = repository;
- }
-
-
-}
+++ /dev/null
-package org.argeo.suite.ui;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.jcr.Node;
-
-import org.argeo.api.cms.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<String, Object> eventProperties(Node node) {
- Map<String, Object> properties = new HashMap<>();
- properties.put(NODE_PATH, Jcr.getPath(node));
- properties.put(WORKSPACE, Jcr.getWorkspaceName(node));
- return properties;
- }
-
- public static Map<String, Object> eventProperties(User user) {
- Map<String, Object> properties = new HashMap<>();
- properties.put(USERNAME, user.getName());
- return properties;
- }
-}
+++ /dev/null
-package org.argeo.suite.ui;
-
-import org.argeo.cms.swt.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;
-}
+++ /dev/null
-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;
- }
-}
+++ /dev/null
-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;
-}
+++ /dev/null
-package org.argeo.suite.ui;
-
-import org.argeo.api.cms.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";
- }
-
-}
+++ /dev/null
-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.argeo.api.cms.CmsUi;
-import org.argeo.api.cms.CmsView;
-import org.argeo.api.cms.CmsLog;
-import org.argeo.api.cms.CmsConstants;
-import org.argeo.cms.Localized;
-import org.argeo.cms.swt.CmsSwtUtils;
-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 implements CmsUi {
- private static final long serialVersionUID = 6207018859086689108L;
- private final static CmsLog log = CmsLog.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<String, SuiteLayer> layers = new HashMap<>();
- private Map<String, Composite> workAreas = new HashMap<>();
- private String currentLayerId = null;
-
- private CmsView cmsView;
-
- public SuiteUi(Composite parent, int style) {
- super(parent, style);
- cmsView = CmsSwtUtils.getCmsView(parent);
- this.setLayout(CmsSwtUtils.noSpaceGridLayout());
-
- header = new Composite(this, SWT.NONE);
- header.setLayout(CmsSwtUtils.noSpaceGridLayout());
- CmsSwtUtils.style(header, SuiteStyle.header);
- header.setLayoutData(CmsSwtUtils.fillWidth());
-
- belowHeader = new Composite(this, SWT.NONE);
- belowHeader.setLayoutData(CmsSwtUtils.fillAll());
-
- footer = new Composite(this, SWT.NONE);
- footer.setLayout(CmsSwtUtils.noSpaceGridLayout());
- CmsSwtUtils.style(footer, SuiteStyle.footer);
- footer.setLayoutData(CmsSwtUtils.fillWidth());
- }
-
- public void refreshBelowHeader(boolean initApp) {
- CmsSwtUtils.clear(belowHeader);
- int style = getStyle();
- if (initApp) {
- belowHeader.setLayout(CmsSwtUtils.noSpaceGridLayout(3));
-
- if (SWT.RIGHT_TO_LEFT == (style & SWT.RIGHT_TO_LEFT)) {// arabic, hebrew, etc.
- sidePane = new Composite(belowHeader, SWT.NONE);
- sidePane.setLayout(CmsSwtUtils.noSpaceGridLayout());
- sidePane.setLayoutData(CmsSwtUtils.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(CmsSwtUtils.noSpaceGridLayout());
- sidePane.setLayoutData(CmsSwtUtils.fillHeight());
- }
- leadPane.setLayoutData(CmsSwtUtils.fillHeight());
- leadPane.setLayout(CmsSwtUtils.noSpaceGridLayout());
- CmsSwtUtils.style(leadPane, SuiteStyle.leadPane);
-
- dynamicArea.setLayoutData(CmsSwtUtils.fillAll());
- dynamicArea.setLayout(new FormLayout());
-
- } else {
- belowHeader.setLayout(CmsSwtUtils.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));
- CmsSwtUtils.style(workArea, SuiteStyle.workArea);
- workArea.setLayoutData(CmsSwtUtils.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(CmsConstants.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 (CmsConstants.SYS_WORKSPACE.equals(workspaceName))
- return sysSession;
- else if (CmsConstants.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;
- }
-
-}
+++ /dev/null
-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.api.cms.CmsEditable;
-import org.argeo.api.cms.CmsEvent;
-import org.argeo.api.cms.CmsStyle;
-import org.argeo.api.cms.CmsTheme;
-import org.argeo.api.cms.CmsView;
-import org.argeo.cms.LocaleUtils;
-import org.argeo.cms.Localized;
-import org.argeo.cms.auth.CurrentUser;
-import org.argeo.cms.swt.CmsIcon;
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.swt.dialogs.LightweightDialog;
-import org.argeo.cms.ui.util.CmsLink;
-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(CmsSwtUtils.fillWidth());
- CmsSwtUtils.style(titleBar, SuiteStyle.titleContainer);
-
- titleBar.setLayout(CmsSwtUtils.noSpaceGridLayout(new GridLayout(2, false)));
- Label titleLbl = new Label(titleBar, SWT.NONE);
- titleLbl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
- CmsSwtUtils.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));
- CmsSwtUtils.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));
- CmsSwtUtils.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));
- CmsSwtUtils.style(txt, SuiteStyle.simpleText);
- return txt;
- }
-
- public static Text addFormInputField(Composite parent, String placeholder) {
- Text txt = new Text(parent, SWT.BORDER);
-
- GridData gridData = CmsSwtUtils.fillWidth();
- txt.setLayoutData(gridData);
-
- if (placeholder != null)
- txt.setText(placeholder);
-
- CmsSwtUtils.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));
- CmsSwtUtils.style(lineComposite, SuiteStyle.formLine);
- addFormLabel(lineComposite, label);
- Text txt = addFormTextField(lineComposite, text, null);
- txt.setEditable(false);
- txt.setLayoutData(CmsSwtUtils.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));
- CmsSwtUtils.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(CmsSwtUtils.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));
- CmsSwtUtils.style(lineComposite, SuiteStyle.formLine);
- addFormLabel(lineComposite, label);
- Text txt = addFormInputField(lineComposite, placeholder);
- txt.setLayoutData(CmsSwtUtils.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));
- CmsSwtUtils.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(CmsSwtUtils.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(CmsSwtUtils.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(CmsSwtUtils.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));
- CmsSwtUtils.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);
- CmsSwtUtils.markup(img);
- StringBuffer txt = new StringBuffer();
- String target = toLink(link);
- if (target != null)
- txt.append("<a href='").append(target).append("'>");
- txt.append(CmsUiUtils.img(fileNode, width.toString(), height.toString()));
- if (target != null)
- txt.append("</a>");
- 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(CmsSwtUtils.fillAll());
- scroll.setLayout(CmsSwtUtils.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(CmsSwtUtils.fillAll());
- Label bigImg = new Label(c, SWT.NONE);
- CmsSwtUtils.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) {
- return node != null ? "#" + CmsUiUtils.cleanPathForUrl(SuiteApp.nodeToState(node)) : null;
- }
-
- 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);
- CmsSwtUtils.markup(lbl);
- StringBuilder txt = new StringBuilder();
- txt.append("<a class='" + plainCssAnchorClass + "'");
- txt.append(" href='").append(url).append("'");
- if (newWindow) {
- txt.append(" target='blank_'");
- }
- txt.append(">");
- txt.append(label);
- txt.append("</a>");
- 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 = CmsSwtUtils.getCmsTheme(parent);
- Button button = new Button(parent, SWT.PUSH);
- CmsSwtUtils.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);
- CmsSwtUtils.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));
- }
- CmsSwtUtils.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);
-// }
-// }
-
-}
+++ /dev/null
-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;
- }
-
-}
+++ /dev/null
-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);
-// }
-}
+++ /dev/null
-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();
- }
- }
-}
+++ /dev/null
-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();
- }
- }
-}
+++ /dev/null
-package org.argeo.suite.ui.widgets;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.argeo.cms.swt.CmsSwtUtils;
-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<String, Button> actionButtons = new HashMap<String, Button>();
-
- 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());
- CmsSwtUtils.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);
-}
+++ /dev/null
-package org.argeo.suite.ui.widgets;
-
-import java.util.Arrays;
-import java.util.List;
-
-import org.argeo.cms.swt.CmsSwtUtils;
-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)
- CmsSwtUtils.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<String> getFilteredValues(String filter);
-
- protected void refreshValues() {
- List<String> 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);
- }
- }
- });
- }
-}
+++ /dev/null
-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();
- };
-
-}
+++ /dev/null
-package org.argeo.suite.ui.widgets;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.jcr.Node;
-
-import org.argeo.cms.swt.CmsSwtUtils;
-import org.argeo.cms.swt.Selected;
-import org.argeo.cms.ui.CmsUiProvider;
-import org.argeo.cms.ui.viewers.Section;
-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<Section> 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);
- CmsSwtUtils.style(parent, bodyStyle);
-
- setLayout(CmsSwtUtils.noSpaceGridLayout());
-
- // TODO manage tabs at bottom or sides
- headers = new Composite(this, SWT.NONE);
- headers.setLayoutData(CmsSwtUtils.fillWidth());
- body = new Composite(this, SWT.NONE);
- body.setLayoutData(CmsSwtUtils.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(CmsSwtUtils.noSpaceGridLayout(new GridLayout(tabCount, true)));
-
- if (sections.size() == 0) {
- Composite emptyHeader = new Composite(headers, SWT.NONE);
- emptyHeader.setLayoutData(CmsSwtUtils.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);
- CmsSwtUtils.style(sectionHeader, selected ? tabSelectedStyle : tabStyle);
- int headerColumns = singleTab ? 1 : 2;
- sectionHeader.setLayout(new GridLayout(headerColumns, false));
- sectionHeader.setLayout(CmsSwtUtils.noSpaceGridLayout(headerColumns));
- Button title = new Button(sectionHeader, SWT.FLAT);
- CmsSwtUtils.style(title, selected ? tabSelectedStyle : tabStyle);
- title.setLayoutData(CmsSwtUtils.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");
- CmsSwtUtils.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)
- CmsSwtUtils.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();
- CmsSwtUtils.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;
- }
-
-}
+++ /dev/null
-package org.argeo.suite.ui.widgets;
-
-import org.argeo.cms.swt.CmsSwtUtils;
-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(CmsSwtUtils.fillWidth());
- createSearchUi(searchC);
-
- Composite bodyC = new Composite(parent, SWT.NONE);
- bodyC.setLayoutData(CmsSwtUtils.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(CmsSwtUtils.noSpaceGridLayout());
- searchT = new Text(parent, SWT.MULTI | SWT.BORDER);
- searchT.setLayoutData(CmsSwtUtils.fillWidth());
- }
-
- protected void createTreeUi(Composite parent) {
- parent.setLayout(CmsSwtUtils.noSpaceGridLayout());
- treeViewer = new TreeViewer(parent);
- treeViewer.getTree().setLayoutData(CmsSwtUtils.fillAll());
- }
-
- protected void createSearchResultsUi(Composite parent) {
- parent.setLayout(CmsSwtUtils.noSpaceGridLayout());
- searchResultsViewer = new TreeViewer(parent);
- searchResultsViewer.getTree().setLayoutData(CmsSwtUtils.fillAll());
- }
-
- public TreeViewer getTreeViewer() {
- return treeViewer;
- }
-
- public TreeViewer getSearchResultsViewer() {
- return searchResultsViewer;
- }
-
-}
+++ /dev/null
-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<String> 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<GeonamesAdm> upperLevels = new ArrayList<>();
-
- private List<String> row;
-
- /** Initialise from a row in the main Geonames table. */
- public GeonamesAdm(List<String> 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<Long, GeonamesAdm> 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<String, String> transform) {
- if (transform != null)
- return transform.apply(name);
- else
- return name;
-
- }
-
- public String getAsciiName() {
- return asciiName;
- }
-
- public List<String> 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<String> 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<GeonamesAdm> 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 + ")";
- }
-
-}
+++ /dev/null
-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<Long, GeonamesAdm> geonamesAdms = new HashMap<>();
-
- /** Loads the data. */
- public void parse(InputStream in) {
- Map<String, Long> countryGeonameIds = new HashMap<>();
- Map<String, Long> admin1GeonameIds = new HashMap<>();
- CsvParser csvParser = new CsvParser() {
-
- @Override
- protected void processLine(Integer lineNumber, List<String> header, List<String> 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<Long, GeonamesAdm> 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<String> header, List<String> 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);
- }
- }
-
-}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
- <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
- <classpathentry kind="src" path="src"/>
- <classpathentry kind="output" path="bin"/>
-</classpath>
+++ /dev/null
-/bin/
-/target/
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>org.argeo.support.odk</name>
- <comment></comment>
- <projects>
- </projects>
- <buildSpec>
- <buildCommand>
- <name>org.eclipse.jdt.core.javabuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.ManifestBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.SchemaBuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.ds.core.builder</name>
- <arguments>
- </arguments>
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>org.eclipse.pde.PluginNature</nature>
- <nature>org.eclipse.jdt.core.javanature</nature>
- </natures>
-</projectDescription>
+++ /dev/null
-/MANIFEST.MF
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="ODK Form List Servlet">
- <implementation class="org.argeo.support.odk.servlet.OdkFormListServlet"/>
- <service>
- <provide interface="javax.servlet.Servlet"/>
- </service>
- <property name="osgi.http.whiteboard.servlet.pattern" type="String" value="/formList/*"/>
- <property name="osgi.http.whiteboard.context.select" type="String" value="(osgi.http.whiteboard.context.name=odkServletContext)"/>
- <reference bind="addForm" cardinality="0..n" interface="org.argeo.support.odk.OdkForm" name="OdkForm" policy="dynamic" unbind="removeForm"/>
- <reference bind="setRepository" cardinality="1..1" interface="javax.jcr.Repository" name="Repository" policy="static" target="(cn=odk)"/>
-</scr:component>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="ODK Form Servlet">
- <implementation class="org.argeo.support.odk.servlet.OdkFormServlet"/>
- <service>
- <provide interface="javax.servlet.Servlet"/>
- </service>
- <property name="osgi.http.whiteboard.servlet.pattern" type="String" value="/form/*"/>
- <property name="osgi.http.whiteboard.context.select" type="String" value="(osgi.http.whiteboard.context.name=odkServletContext)"/>
- <reference bind="addForm" cardinality="0..n" interface="org.argeo.support.odk.OdkForm" name="OdkForm" policy="dynamic" unbind="removeForm"/>
- <reference bind="setRepository" cardinality="1..1" interface="javax.jcr.Repository" name="Repository" policy="static" target="(cn=odk)"/>
-</scr:component>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="ODK Manifest Servlet">
- <implementation class="org.argeo.support.odk.servlet.OdkManifestServlet"/>
- <service>
- <provide interface="javax.servlet.Servlet"/>
- </service>
- <property name="osgi.http.whiteboard.servlet.pattern" type="String" value="/formManifest/*"/>
- <property name="osgi.http.whiteboard.context.select" type="String" value="(osgi.http.whiteboard.context.name=odkServletContext)"/>
- <reference bind="setRepository" cardinality="1..1" interface="javax.jcr.Repository" name="Repository" policy="static" target="(cn=odk)"/>
-</scr:component>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy" name="ODK Servlet Context">
- <implementation class="org.argeo.support.odk.servlet.OdkServletContext"/>
- <service>
- <provide interface="org.osgi.service.http.context.ServletContextHelper"/>
- </service>
- <property name="osgi.http.whiteboard.context.name" type="String" value="odkServletContext"/>
- <property name="osgi.http.whiteboard.context.path" type="String" value="/api/odk"/>
-</scr:component>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="ODK Submission Servlet">
- <implementation class="org.argeo.support.odk.servlet.OdkSubmissionServlet"/>
- <service>
- <provide interface="javax.servlet.Servlet"/>
- </service>
- <property name="osgi.http.whiteboard.servlet.pattern" type="String" value="/submission"/>
- <property name="osgi.http.whiteboard.context.select" type="String" value="(osgi.http.whiteboard.context.name=odkServletContext)"/>
- <property name="osgi.http.whiteboard.servlet.multipart.enabled" type="String" value="true"/>
- <reference bind="setRepository" cardinality="1..1" interface="javax.jcr.Repository" name="Repository" policy="static" target="(cn=odk)"/>
- <reference bind="addSubmissionListener" cardinality="0..n" interface="org.argeo.support.xforms.FormSubmissionListener" name="FormSubmissionListener" policy="dynamic" unbind="removeSubmissionListener"/>
-</scr:component>
+++ /dev/null
-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,\
-javax.jcr.nodetype,\
-*
+++ /dev/null
-output.. = bin/
-bin.includes = META-INF/,\
- .,\
- OSGI-INF/,\
- OSGI-INF/odkServletContext.xml
-source.. = src/
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.argeo.suite</groupId>
- <artifactId>argeo-suite</artifactId>
- <version>2.3-SNAPSHOT</version>
- <relativePath>..</relativePath>
- </parent>
- <artifactId>org.argeo.support.odk</artifactId>
- <name>ODK support</name>
- <packaging>jar</packaging>
- <dependencies>
- <dependency>
- <groupId>org.argeo.suite</groupId>
- <artifactId>org.argeo.suite.core</artifactId>
- <version>2.3-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.argeo.suite</groupId>
- <artifactId>org.argeo.support.xforms</artifactId>
- <version>2.3-SNAPSHOT</version>
- </dependency>
-
- <dependency>
- <groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.cms.servlet</artifactId>
- <version>${version.argeo-commons}</version>
- </dependency>
-
- </dependencies>
-</project>
+++ /dev/null
-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<String, String> 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;
- }
-
-}
+++ /dev/null
-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();
-}
+++ /dev/null
-package org.argeo.support.odk;
-
-/** Names related to ODK. */
-public interface OdkNames {
-
- public final static String H_HTML = "h:html";
-}
+++ /dev/null
-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.argeo.api.cms.CmsLog;
-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 CmsLog log = CmsLog.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() {
-
- }
-
-}
+++ /dev/null
-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";
- }
-
-}
+++ /dev/null
-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";
- }
-
-}
+++ /dev/null
-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";
- }
-
-}
+++ /dev/null
-<jr = "http://openrosa.org/javarosa">
-<orx = "http://openrosa.org/xforms">
-<orxList = "http://openrosa.org/xforms/xformsList">
-<orxManifest = "http://openrosa.org/xforms/xformsManifest">
-<odk = "http://www.opendatakit.org/xforms">
-
-
-[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) *
-
-
+++ /dev/null
-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.argeo.api.cms.CmsConstants;
-import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.auth.RemoteAuthUtils;
-import org.argeo.cms.servlet.ServletHttpRequest;
-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 CmsLog log = CmsLog.getLog(OdkFormListServlet.class);
-
- private Set<OdkForm> 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 = RemoteAuthUtils.doAs(() -> Jcr.login(repository, CmsConstants.SYS_WORKSPACE),
- new ServletHttpRequest(req));
-// session = NodeUtils.openDataAdminSession(repository, NodeConstants.SYS_WORKSPACE);
- Writer writer = resp.getWriter();
- writer.append("<?xml version='1.0' encoding='UTF-8' ?>");
- writer.append("<xforms xmlns=\"http://openrosa.org/xforms/xformsList\">");
- 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("<xform>");
- sb.append("<formID>" + node.getProperty(OrxListName.formID.get()).getString() + "</formID>");
- sb.append("<name>" + Jcr.getTitle(node) + "</name>");
- sb.append("<version>" + node.getProperty(OrxListName.version.get()).getString() + "</version>");
- sb.append("<hash>md5:" + JcrxApi.getChecksum(node, JcrxApi.MD5) + "</hash>");
- if (node.hasProperty(Property.JCR_DESCRIPTION))
- sb.append("<name>" + node.getProperty(Property.JCR_DESCRIPTION).getString() + "</name>");
- sb.append("<downloadUrl>" + protocol + "://" + serverName
- + (serverPort == 80 || serverPort == 443 ? "" : ":" + serverPort) + "/api/odk/form"
- + node.getPath() + "</downloadUrl>");
- if (node.hasNode(OrxManifestName.manifest.name())) {
- sb.append("<manifestUrl>" + protocol + "://" + serverName
- + (serverPort == 80 || serverPort == 443 ? "" : ":" + serverPort)
- + "/api/odk/formManifest" + node.getNode(OrxManifestName.manifest.name()).getPath()
- + "</manifestUrl>");
- }
- sb.append("</xform>");
- } else if (node.isNodeType(EntityType.formSet.get())) {
- sb.append("<xforms-group>");
- sb.append("<groupId>" + node.getPath() + "</groupId>");
- sb.append("<name>" + node.getProperty(Property.JCR_TITLE).getString() + "</name>");
- sb.append("<listUrl>" + protocol + "://" + serverName
- + (serverPort == 80 || serverPort == 443 ? "" : ":" + serverPort) + "/api/odk/formList"
- + node.getPath() + "</listUrl>");
- sb.append("</xforms-group>");
- }
- 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("<xform>");
- sb.append("<formID>" + form.getFormId() + "</formID>");
- sb.append("<name>" + form.getName() + "</name>");
- sb.append("<version>" + form.getVersion() + "</version>");
- sb.append("<hash>" + form.getHash(null) + "</hash>");
- sb.append("<descriptionText>" + form.getDescription() + "</descriptionText>");
- sb.append("<downloadUrl>" + protocol + "://" + serverName
- + (serverPort == 80 || serverPort == 443 ? "" : ":" + serverPort) + "/api/odk/form/"
- + form.getFileName() + "</downloadUrl>");
- sb.append("</xform>");
- String str = sb.toString();
- if (log.isDebugEnabled())
- log.debug(str);
- writer.append(str);
- }
- }
- writer.append("</xforms>");
- }
-
- public void addForm(OdkForm odkForm) {
- odkForms.add(odkForm);
- }
-
- public void removeForm(OdkForm odkForm) {
- odkForms.remove(odkForm);
- }
-
- public void setRepository(Repository repository) {
- this.repository = repository;
- }
-
-}
+++ /dev/null
-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.auth.RemoteAuthUtils;
-import org.argeo.cms.servlet.ServletHttpRequest;
-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<String, OdkForm> 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 = RemoteAuthUtils.doAs(() -> Jcr.login(repository, null), new ServletHttpRequest(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;
- }
-
-}
+++ /dev/null
-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.auth.RemoteAuthUtils;
-import org.argeo.cms.servlet.ServletHttpRequest;
-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 = RemoteAuthUtils.doAs(() -> Jcr.login(repository, null), new ServletHttpRequest(req));
-
- try {
- Node node = session.getNode(pathInfo);
- if (node.isNodeType(OrxManifestName.manifest.get())) {
- resp.setContentType(EntityMimeType.XML.toHttpContentType());
- Writer writer = resp.getWriter();
- writer.append("<?xml version='1.0' encoding='UTF-8' ?>");
- writer.append("<manifest xmlns=\"http://openrosa.org/xforms/xformsManifest\">");
- 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("<mediaFile>");
- writer.append("<filename>");
- // Work around bug in ODK Collect not supporting paths
- // writer.append(target.getPath().substring(1) + ".xml");
- writer.append(target.getIdentifier() + "." + mimeType.getDefaultExtension());
- writer.append("</filename>");
-
- 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("<hash>");
- writer.append("md5sum:" + DigestUtils.encodeHexString(out.getMessageDigest().digest()));
- writer.append("</hash>");
- }
-
-// try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
-// session.exportDocumentView(target.getPath(), out, true, false);
-// String fileCsum = DigestUtils.digest(DigestUtils.MD5, out.toByteArray());
-// writer.append("<hash>");
-// writer.append("md5sum:" + fileCsum);
-// writer.append("</hash>");
-// }
- writer.append("<downloadUrl>" + protocol + "://" + serverName
- + (serverPort == 80 || serverPort == 443 ? "" : ":" + serverPort)
- + "/api/odk/formManifest" + file.getPath() + "</downloadUrl>");
- }
- writer.append("</mediaFile>");
- }
- }
-
- writer.append("</manifest>");
- } 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<String> 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;
- }
-
-}
+++ /dev/null
-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());
-
- }
-
-}
+++ /dev/null
-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.argeo.api.cms.CmsSession;
-import org.argeo.api.cms.CmsLog;
-import org.argeo.cms.auth.RemoteAuthRequest;
-import org.argeo.cms.auth.RemoteAuthUtils;
-import org.argeo.cms.jcr.CmsJcrUtils;
-import org.argeo.cms.servlet.ServletHttpRequest;
-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 CmsLog log = CmsLog.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<FormSubmissionListener> 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);
-
- RemoteAuthRequest request = new ServletHttpRequest(req);
- Session session = RemoteAuthUtils.doAs(() -> Jcr.login(repository, null), request);
-
- try {
-// Node submissions = JcrUtils.mkdirs(session,
-// "/" + EntityType.form.get() + "/" + EntityNames.SUBMISSIONS_BASE);
- CmsSession cmsSession = RemoteAuthUtils.getCmsSession(request);
-
- ClassLoader currentContextCl = Thread.currentThread().getContextClassLoader();
- Thread.currentThread().setContextClassLoader(RemoteAuthUtils.class.getClassLoader());
- Session adminSession = null;
- try {
- // TODO centralise at a deeper level
- adminSession = CmsJcrUtils.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("<OpenRosaResponse xmlns=\"http://openrosa.org/http/response\">"
- + "<message>Form Received!</message>" + "</OpenRosaResponse>");
-
- }
-
- 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);
- }
-}
+++ /dev/null
-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;
-}
+++ /dev/null
-<xforms = "http://www.w3.org/2002/xforms">
-
-[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 *
</properties>
<modules>
<!-- Entity Framework -->
- <module>org.argeo.entity.api</module>
- <module>org.argeo.entity.core</module>
- <module>org.argeo.entity.ui</module>
+ <module>org.argeo.app.api</module>
+<!-- <module>org.argeo.entity.core</module> -->
+<!-- <module>org.argeo.entity.ui</module> -->
<!-- Argeo Suite -->
- <module>org.argeo.suite.core</module>
- <module>org.argeo.suite.ui</module>
- <module>org.argeo.suite.ui.rap</module>
- <module>org.argeo.suite.theme.default</module>
+ <module>org.argeo.app.core</module>
+ <module>org.argeo.app.ui</module>
+ <module>org.argeo.app.ui.rap</module>
+ <module>org.argeo.app.theme.default</module>
<!-- Functional areas -->
- <module>org.argeo.people.ui</module>
- <module>org.argeo.library.ui</module>
- <module>org.argeo.geo.ui</module>
- <module>org.argeo.publishing.ui</module>
- <module>org.argeo.support.xforms</module>
- <module>org.argeo.support.odk</module>
- <module>org.argeo.support.geonames</module>
+<!-- <module>org.argeo.people.ui</module> -->
+<!-- <module>org.argeo.library.ui</module> -->
+<!-- <module>org.argeo.geo.ui</module> -->
+ <module>org.argeo.app.servlet.publish</module>
+<!-- <module>org.argeo.support.xforms</module> -->
+ <module>org.argeo.app.servlet.odk</module>
+<!-- <module>org.argeo.support.geonames</module> -->
<!-- Packaging -->
<module>dep</module>