+++ /dev/null
-bin.includes = feature.xml,\
- modularDistribution.csv
+++ /dev/null
-properties.1.name=org.eclipse.equinox.p2.type.category
-properties.1.value=true
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<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.commons</groupId>
- <version>2.3-SNAPSHOT</version>
- <artifactId>dep</artifactId>
- <relativePath>..</relativePath>
- </parent>
- <artifactId>org.argeo.dep.cms.client</artifactId>
- <name>CMS Client</name>
- <dependencies>
-
- <!-- Argeo Commons -->
- <dependency>
- <groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.enterprise</artifactId>
- <version>2.3-SNAPSHOT</version>
- </dependency>
-<!-- <dependency> -->
-<!-- <groupId>org.argeo.commons</groupId> -->
-<!-- <artifactId>org.argeo.jcr</artifactId> -->
-<!-- <version>2.3-SNAPSHOT</version> -->
-<!-- </dependency> -->
- <dependency>
- <groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.core</artifactId>
- <version>2.3-SNAPSHOT</version>
- </dependency>
-
- <!-- Third Parties -->
- <dependency>
- <groupId>org.argeo.tp.javax</groupId>
- <artifactId>javax.jcr</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.javax</groupId>
- <artifactId>javax.el-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.javax</groupId>
- <artifactId>javax.interceptor-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.javax</groupId>
- <artifactId>javax.enterprise.cdi-api</artifactId>
- </dependency>
-
- <!-- JTA is still indirectly required by Jackrabbit -->
- <dependency>
- <groupId>org.argeo.tp.javax</groupId>
- <artifactId>javax.transaction-api</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.argeo.tp.apache</groupId>
- <artifactId>org.apache.log4j</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.misc</groupId>
- <artifactId>org.slf4j.log4j12</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.misc</groupId>
- <artifactId>org.slf4j.api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.misc</groupId>
- <artifactId>org.slf4j.commons.logging</artifactId>
- </dependency>
-
- <!-- OSGi annotations -->
-<!-- <dependency> -->
-<!-- <groupId>org.argeo.tp.sdk</groupId> -->
-<!-- <artifactId>osgi.annotation</artifactId> -->
-<!-- </dependency> -->
-<!-- <dependency> -->
-<!-- <groupId>org.argeo.tp.sdk</groupId> -->
-<!-- <artifactId>org.osgi.service.metatype.annotations</artifactId> -->
-<!-- </dependency> -->
-<!-- <dependency> -->
-<!-- <groupId>org.argeo.tp.sdk</groupId> -->
-<!-- <artifactId>org.osgi.service.component.annotations</artifactId> -->
-<!-- </dependency> -->
-
-
- <dependency>
- <groupId>org.argeo.tp.bouncycastle</groupId>
- <artifactId>bcpkix</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.bouncycastle</groupId>
- <artifactId>bcpg</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.argeo.tp.apache</groupId>
- <artifactId>org.apache.httpcomponents.httpcore</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.apache</groupId>
- <artifactId>org.apache.httpcomponents.httpclient</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.apache.commons</groupId>
- <artifactId>org.apache.commons.io</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.apache.commons</groupId>
- <artifactId>org.apache.commons.codec</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.apache.commons</groupId>
- <artifactId>org.apache.commons.exec</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.apache.commons</groupId>
- <artifactId>org.apache.commons.cli</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.apache.commons</groupId>
- <artifactId>org.apache.commons.httpclient</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.apache.commons</groupId>
- <artifactId>org.apache.commons.net</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.apache.commons</groupId>
- <artifactId>org.apache.commons.collections</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.apache.commons</groupId>
- <artifactId>org.apache.commons.compress</artifactId>
- </dependency>
-
- <!-- Equinox -->
- <dependency>
- <groupId>org.argeo.tp.equinox</groupId>
- <artifactId>org.eclipse.osgi.util</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.equinox</groupId>
- <artifactId>org.eclipse.equinox.util</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.equinox</groupId>
- <artifactId>org.eclipse.equinox.cm</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.equinox</groupId>
- <artifactId>org.eclipse.osgi.services</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.equinox</groupId>
- <artifactId>org.eclipse.equinox.registry</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.equinox</groupId>
- <artifactId>org.eclipse.equinox.preferences</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.equinox</groupId>
- <artifactId>org.eclipse.equinox.common</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.equinox</groupId>
- <artifactId>org.eclipse.equinox.event</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.equinox</groupId>
- <artifactId>org.eclipse.equinox.app</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.equinox</groupId>
- <artifactId>org.eclipse.equinox.ds</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.equinox</groupId>
- <artifactId>org.eclipse.equinox.metatype</artifactId>
- </dependency>
-
- <!-- Console -->
- <dependency>
- <groupId>org.argeo.tp.apache.felix</groupId>
- <artifactId>org.apache.felix.scr</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.apache.felix</groupId>
- <artifactId>org.apache.felix.gogo.runtime</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.apache.felix</groupId>
- <artifactId>org.apache.felix.gogo.shell</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.equinox</groupId>
- <artifactId>org.eclipse.equinox.console</artifactId>
- </dependency>
-
- <!-- Jackrabbit client -->
- <dependency>
- <groupId>org.argeo.tp.apache.jackrabbit</groupId>
- <artifactId>org.apache.jackrabbit.api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.apache.jackrabbit</groupId>
- <artifactId>org.apache.jackrabbit.jcr.commons</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.apache.jackrabbit</groupId>
- <artifactId>org.apache.jackrabbit.spi</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.apache.jackrabbit</groupId>
- <artifactId>org.apache.jackrabbit.spi.commons</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.apache.jackrabbit</groupId>
- <artifactId>org.apache.jackrabbit.webdav</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.apache.jackrabbit</groupId>
- <artifactId>org.apache.jackrabbit.spi2dav</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.apache.jackrabbit</groupId>
- <artifactId>org.apache.jackrabbit.jcr2dav</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.apache.jackrabbit</groupId>
- <artifactId>org.apache.jackrabbit.jcr2spi</artifactId>
- </dependency>
-
- <!-- Test only -->
- <dependency>
- <groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.osgi.boot</artifactId>
- <version>2.3-SNAPSHOT</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <profiles>
- <profile>
- <id>rpmbuild</id>
- <build>
- <plugins>
- <plugin>
- <artifactId>maven-assembly-plugin</artifactId>
- <executions>
- <execution>
- <id>prepare-source</id>
- <phase>package</phase>
- <goals>
- <goal>single</goal>
- </goals>
- <configuration>
- <descriptorRefs>
- <descriptorRef>a2-source</descriptorRef>
- </descriptorRefs>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>rpm-maven-plugin</artifactId>
- <executions>
- <execution>
- <id>rpm-argeo</id>
- <phase>package</phase>
- <goals>
- <goal>rpm</goal>
- </goals>
- <configuration>
- <name>argeo-cms-client${argeo.rpm.suffix}</name>
- <mappings>
- <mapping>
- <directory>/usr/share/osgi</directory>
- <username>root</username>
- <groupname>root</groupname>
- <filemode>644</filemode>
- <directoryIncluded>false</directoryIncluded>
- <sources>
- <source>
- <location>${project.build.directory}/${project.artifactId}-${project.version}-a2-source</location>
- <includes>
- <include>**/*.jar</include>
- </includes>
- </source>
- </sources>
- </mapping>
- </mappings>
- <requires>
- <require>argeo-cms-client-tp${argeo.rpm.suffix}</require>
- <require>argeo-osgi-boot${argeo.rpm.suffix}</require>
- </requires>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- </profile>
- <profile>
- <id>rpmbuild-tp</id>
- <build>
- <plugins>
- <plugin>
- <artifactId>maven-assembly-plugin</artifactId>
- <executions>
- <execution>
- <id>prepare-source-tp</id>
- <phase>package</phase>
- <goals>
- <goal>single</goal>
- </goals>
- <configuration>
- <descriptorRefs>
- <descriptorRef>a2-source-tp</descriptorRef>
- </descriptorRefs>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>rpm-maven-plugin</artifactId>
- <executions>
- <execution>
- <id>rpm-tp</id>
- <phase>package</phase>
- <goals>
- <goal>rpm</goal>
- </goals>
- <configuration>
- <name>argeo-cms-client-tp${argeo.rpm.suffix}</name>
- <projversion>${version.argeo-tp}</projversion>
- <release>${argeo.rpm.release.tp}</release>
- <mappings>
- <mapping>
- <directory>/usr/share/osgi</directory>
- <username>root</username>
- <groupname>root</groupname>
- <filemode>644</filemode>
- <directoryIncluded>false</directoryIncluded>
- <sources>
- <source>
- <location>${project.build.directory}/${project.artifactId}-${project.version}-a2-source-tp</location>
- <includes>
- <include>**/*.jar</include>
- </includes>
- </source>
- </sources>
- </mapping>
- </mappings>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- </profile>
- </profiles>
-</project>
\ No newline at end of file
--- /dev/null
+bin.includes = feature.xml,\
+ modularDistribution.csv
--- /dev/null
+properties.1.name=org.eclipse.equinox.p2.type.category
+properties.1.value=true
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<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.commons</groupId>
+ <version>2.3-SNAPSHOT</version>
+ <artifactId>dep</artifactId>
+ <relativePath>..</relativePath>
+ </parent>
+ <artifactId>org.argeo.dep.cms.minimal</artifactId>
+ <name>CMS Minimal</name>
+ <dependencies>
+
+ <!-- Argeo Commons -->
+ <dependency>
+ <groupId>org.argeo.commons</groupId>
+ <artifactId>org.argeo.enterprise</artifactId>
+ <version>2.3-SNAPSHOT</version>
+ </dependency>
+ <!-- <dependency> -->
+ <!-- <groupId>org.argeo.commons</groupId> -->
+ <!-- <artifactId>org.argeo.jcr</artifactId> -->
+ <!-- <version>2.3-SNAPSHOT</version> -->
+ <!-- </dependency> -->
+ <!-- <dependency> -->
+ <!-- <groupId>org.argeo.commons</groupId> -->
+ <!-- <artifactId>org.argeo.core</artifactId> -->
+ <!-- <version>2.3-SNAPSHOT</version> -->
+ <!-- </dependency> -->
+
+ <dependency>
+ <groupId>org.argeo.commons</groupId>
+ <artifactId>org.argeo.api</artifactId>
+ <version>2.3-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.commons</groupId>
+ <artifactId>org.argeo.cms</artifactId>
+ <version>2.3-SNAPSHOT</version>
+ </dependency>
+
+ <!-- Third Parties -->
+
+ <dependency>
+ <groupId>org.argeo.tp.apache</groupId>
+ <artifactId>org.apache.log4j</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.misc</groupId>
+ <artifactId>org.slf4j.log4j12</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.misc</groupId>
+ <artifactId>org.slf4j.api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.misc</groupId>
+ <artifactId>org.slf4j.commons.logging</artifactId>
+ </dependency>
+
+ <!-- OSGi annotations -->
+ <!-- <dependency> -->
+ <!-- <groupId>org.argeo.tp.sdk</groupId> -->
+ <!-- <artifactId>osgi.annotation</artifactId> -->
+ <!-- </dependency> -->
+ <!-- <dependency> -->
+ <!-- <groupId>org.argeo.tp.sdk</groupId> -->
+ <!-- <artifactId>org.osgi.service.metatype.annotations</artifactId> -->
+ <!-- </dependency> -->
+ <!-- <dependency> -->
+ <!-- <groupId>org.argeo.tp.sdk</groupId> -->
+ <!-- <artifactId>org.osgi.service.component.annotations</artifactId> -->
+ <!-- </dependency> -->
+
+ <!-- Bouncycastle -->
+ <dependency>
+ <groupId>org.argeo.tp.bouncycastle</groupId>
+ <artifactId>bcprov</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.bouncycastle</groupId>
+ <artifactId>bcpkix</artifactId>
+ </dependency>
+<!-- <dependency> -->
+<!-- <groupId>org.argeo.tp.bouncycastle</groupId> -->
+<!-- <artifactId>bcpg</artifactId> -->
+<!-- </dependency> -->
+
+ <!-- Apache Commons -->
+ <dependency>
+ <groupId>org.argeo.tp.apache.commons</groupId>
+ <artifactId>org.apache.commons.io</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.apache.commons</groupId>
+ <artifactId>org.apache.commons.codec</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.apache.commons</groupId>
+ <artifactId>org.apache.commons.httpclient</artifactId>
+ </dependency>
+
+ <!-- Equinox -->
+ <dependency>
+ <groupId>org.argeo.tp.equinox</groupId>
+ <artifactId>org.eclipse.osgi.util</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.equinox</groupId>
+ <artifactId>org.eclipse.equinox.util</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.equinox</groupId>
+ <artifactId>org.eclipse.equinox.cm</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.equinox</groupId>
+ <artifactId>org.eclipse.osgi.services</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.equinox</groupId>
+ <artifactId>org.eclipse.equinox.registry</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.equinox</groupId>
+ <artifactId>org.eclipse.equinox.preferences</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.equinox</groupId>
+ <artifactId>org.eclipse.equinox.common</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.equinox</groupId>
+ <artifactId>org.eclipse.equinox.event</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.equinox</groupId>
+ <artifactId>org.eclipse.equinox.app</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.equinox</groupId>
+ <artifactId>org.eclipse.equinox.ds</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.equinox</groupId>
+ <artifactId>org.eclipse.equinox.metatype</artifactId>
+ </dependency>
+
+ <!-- Equinox Console -->
+ <dependency>
+ <groupId>org.argeo.tp.apache.felix</groupId>
+ <artifactId>org.apache.felix.scr</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.apache.felix</groupId>
+ <artifactId>org.apache.felix.gogo.runtime</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.apache.felix</groupId>
+ <artifactId>org.apache.felix.gogo.shell</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.equinox</groupId>
+ <artifactId>org.eclipse.equinox.console</artifactId>
+ </dependency>
+
+ <!-- Servlet -->
+ <dependency>
+ <groupId>org.argeo.tp.javax</groupId>
+ <artifactId>javax.servlet</artifactId>
+ </dependency>
+
+ <!-- HTTP Server -->
+ <dependency>
+ <groupId>org.argeo.tp.equinox</groupId>
+ <artifactId>org.eclipse.equinox.http.servlet</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.equinox</groupId>
+ <artifactId>org.eclipse.equinox.http.jetty</artifactId>
+ </dependency>
+
+ <!-- Jetty -->
+ <dependency>
+ <groupId>org.argeo.tp.jetty</groupId>
+ <artifactId>org.eclipse.jetty.client</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.jetty</groupId>
+ <artifactId>org.eclipse.jetty.continuation</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.jetty</groupId>
+ <artifactId>org.eclipse.jetty.http</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.jetty</groupId>
+ <artifactId>org.eclipse.jetty.io</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.jetty</groupId>
+ <artifactId>org.eclipse.jetty.jmx</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.jetty</groupId>
+ <artifactId>org.eclipse.jetty.security</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.jetty</groupId>
+ <artifactId>org.eclipse.jetty.server</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.jetty</groupId>
+ <artifactId>org.eclipse.jetty.servlet</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.jetty</groupId>
+ <artifactId>org.eclipse.jetty.servlets</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.jetty</groupId>
+ <artifactId>org.eclipse.jetty.util</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.jetty</groupId>
+ <artifactId>org.eclipse.jetty.xml</artifactId>
+ </dependency>
+
+ <!-- Database drivers -->
+ <dependency>
+ <groupId>org.argeo.tp.misc</groupId>
+ <artifactId>org.postgresql.jdbc42</artifactId>
+ </dependency>
+
+ <!-- Test only -->
+ <dependency>
+ <groupId>org.argeo.commons</groupId>
+ <artifactId>org.argeo.osgi.boot</artifactId>
+ <version>2.3-SNAPSHOT</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <profiles>
+ <profile>
+ <id>rpmbuild</id>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>prepare-source</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <configuration>
+ <descriptorRefs>
+ <descriptorRef>a2-source</descriptorRef>
+ </descriptorRefs>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>rpm-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>rpm-argeo</id>
+ <phase>package</phase>
+ <goals>
+ <goal>rpm</goal>
+ </goals>
+ <configuration>
+ <name>argeo-cms-minimal${argeo.rpm.suffix}</name>
+ <mappings>
+ <mapping>
+ <directory>/usr/share/osgi</directory>
+ <username>root</username>
+ <groupname>root</groupname>
+ <filemode>644</filemode>
+ <directoryIncluded>false</directoryIncluded>
+ <sources>
+ <source>
+ <location>${project.build.directory}/${project.artifactId}-${project.version}-a2-source</location>
+ <includes>
+ <include>**/*.jar</include>
+ </includes>
+ </source>
+ </sources>
+ </mapping>
+ </mappings>
+ <requires>
+ <require>argeo-cms-minimal-tp${argeo.rpm.suffix}</require>
+ <require>argeo-osgi-boot${argeo.rpm.suffix}</require>
+ </requires>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>rpmbuild-tp</id>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>prepare-source-tp</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <configuration>
+ <descriptorRefs>
+ <descriptorRef>a2-source-tp</descriptorRef>
+ </descriptorRefs>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>rpm-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>rpm-tp</id>
+ <phase>package</phase>
+ <goals>
+ <goal>rpm</goal>
+ </goals>
+ <configuration>
+ <name>argeo-cms-minimal-tp${argeo.rpm.suffix}</name>
+ <projversion>${version.argeo-tp}</projversion>
+ <release>${argeo.rpm.release.tp}</release>
+ <mappings>
+ <mapping>
+ <directory>/usr/share/osgi</directory>
+ <username>root</username>
+ <groupname>root</groupname>
+ <filemode>644</filemode>
+ <directoryIncluded>false</directoryIncluded>
+ <sources>
+ <source>
+ <location>${project.build.directory}/${project.artifactId}-${project.version}-a2-source-tp</location>
+ <includes>
+ <include>**/*.jar</include>
+ </includes>
+ </source>
+ </sources>
+ </mapping>
+ </mappings>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<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">
+<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.commons</groupId>
</parent>
<artifactId>org.argeo.dep.cms.node</artifactId>
<name>CMS Node</name>
-
+
<dependencies>
<!-- Parent dependencies -->
<dependency>
<groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.dep.cms.client</artifactId>
+ <artifactId>org.argeo.dep.cms.minimal</artifactId>
<version>2.3-SNAPSHOT</version>
<type>pom</type>
</dependency>
<!-- Argeo Commons -->
- <dependency>
- <groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.api</artifactId>
- <version>2.3-SNAPSHOT</version>
- </dependency>
- <dependency>
-
- <groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.cms</artifactId>
- <version>2.3-SNAPSHOT</version>
- </dependency>
<dependency>
<groupId>org.argeo.commons</groupId>
<artifactId>org.argeo.cms.jcr</artifactId>
<version>2.3-SNAPSHOT</version>
</dependency>
-<!-- <dependency> -->
-<!-- <groupId>org.argeo.commons</groupId> -->
-<!-- <artifactId>org.argeo.maintenance</artifactId> -->
-<!-- <version>2.3-SNAPSHOT</version> -->
-<!-- </dependency> -->
+ <!-- <dependency> -->
+ <!-- <groupId>org.argeo.commons</groupId> -->
+ <!-- <artifactId>org.argeo.maintenance</artifactId> -->
+ <!-- <version>2.3-SNAPSHOT</version> -->
+ <!-- </dependency> -->
<!-- CMS Dependencies -->
<!-- <dependency> -->
<!-- <artifactId>org.joda.time</artifactId> -->
<!-- </dependency> -->
- <!-- Misc -->
- <dependency>
- <groupId>org.argeo.tp.bouncycastle</groupId>
- <artifactId>bcprov</artifactId>
- </dependency>
-
<!-- Apache Commons -->
<dependency>
<groupId>org.argeo.tp.apache.commons</groupId>
</dependency>
<!-- Javax -->
+ <dependency>
+ <groupId>org.argeo.tp.javax</groupId>
+ <artifactId>javax.jcr</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.javax</groupId>
+ <artifactId>javax.el-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.javax</groupId>
+ <artifactId>javax.interceptor-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.javax</groupId>
+ <artifactId>javax.enterprise.cdi-api</artifactId>
+ </dependency>
+ <!-- JTA is still indirectly required by Jackrabbit -->
+ <dependency>
+ <groupId>org.argeo.tp.javax</groupId>
+ <artifactId>javax.transaction-api</artifactId>
+ </dependency>
<dependency>
<groupId>org.argeo.tp.javax</groupId>
<artifactId>javax.annotation</artifactId>
<groupId>org.argeo.tp.javax</groupId>
<artifactId>javax.inject</artifactId>
</dependency>
+
+ <dependency>
+ <groupId>org.argeo.tp.apache.commons</groupId>
+ <artifactId>org.apache.commons.net</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.apache.commons</groupId>
+ <artifactId>org.apache.commons.collections</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.apache.commons</groupId>
+ <artifactId>org.apache.commons.compress</artifactId>
+ </dependency>
+
+ <!-- Jackrabbit Dependencies -->
+ <dependency>
+ <groupId>org.argeo.tp.apache</groupId>
+ <artifactId>org.apache.httpcomponents.httpcore</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.apache</groupId>
+ <artifactId>org.apache.httpcomponents.httpclient</artifactId>
+ </dependency>
+
+ <!-- Jackrabbit client -->
+ <dependency>
+ <groupId>org.argeo.tp.apache.jackrabbit</groupId>
+ <artifactId>org.apache.jackrabbit.api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.apache.jackrabbit</groupId>
+ <artifactId>org.apache.jackrabbit.jcr.commons</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.apache.jackrabbit</groupId>
+ <artifactId>org.apache.jackrabbit.spi</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.apache.jackrabbit</groupId>
+ <artifactId>org.apache.jackrabbit.spi.commons</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.apache.jackrabbit</groupId>
+ <artifactId>org.apache.jackrabbit.webdav</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.apache.jackrabbit</groupId>
+ <artifactId>org.apache.jackrabbit.spi2dav</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.apache.jackrabbit</groupId>
+ <artifactId>org.apache.jackrabbit.jcr2dav</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.apache.jackrabbit</groupId>
+ <artifactId>org.apache.jackrabbit.jcr2spi</artifactId>
+ </dependency>
<!-- Jackrabbit Repository -->
<dependency>
<groupId>org.argeo.tp.misc</groupId>
<artifactId>org.h2</artifactId>
</dependency>
- <dependency>
- <groupId>org.argeo.tp.misc</groupId>
- <artifactId>org.postgresql.jdbc42</artifactId>
- </dependency>
<!-- Third Parties -->
<dependency>
<!-- <artifactId>org.apache.aries.spifly.dynamic.bundle</artifactId> -->
<!-- </dependency> -->
- <!-- Servlet -->
- <dependency>
- <groupId>org.argeo.tp.javax</groupId>
- <artifactId>javax.servlet</artifactId>
- </dependency>
-
- <!-- HTTP Server -->
- <dependency>
- <groupId>org.argeo.tp.equinox</groupId>
- <artifactId>org.eclipse.equinox.http.servlet</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.equinox</groupId>
- <artifactId>org.eclipse.equinox.http.jetty</artifactId>
- </dependency>
-
- <!-- Jetty -->
- <dependency>
- <groupId>org.argeo.tp.jetty</groupId>
- <artifactId>org.eclipse.jetty.client</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.jetty</groupId>
- <artifactId>org.eclipse.jetty.continuation</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.jetty</groupId>
- <artifactId>org.eclipse.jetty.http</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.jetty</groupId>
- <artifactId>org.eclipse.jetty.io</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.jetty</groupId>
- <artifactId>org.eclipse.jetty.jmx</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.jetty</groupId>
- <artifactId>org.eclipse.jetty.security</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.jetty</groupId>
- <artifactId>org.eclipse.jetty.server</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.jetty</groupId>
- <artifactId>org.eclipse.jetty.servlet</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.jetty</groupId>
- <artifactId>org.eclipse.jetty.servlets</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.jetty</groupId>
- <artifactId>org.eclipse.jetty.util</artifactId>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.jetty</groupId>
- <artifactId>org.eclipse.jetty.xml</artifactId>
- </dependency>
-
-
</dependencies>
<profiles>
</mapping>
</mappings>
<requires>
- <require>argeo-cms-client${argeo.rpm.suffix}</require>
+ <require>argeo-cms-minimal{argeo.rpm.suffix}</require>
<require>argeo-cms-node-tp${argeo.rpm.suffix}</require>
</requires>
</configuration>
</mapping>
</mappings>
<requires>
- <require>argeo-cms-client-tp${argeo.rpm.suffix}</require>
+ <require>argeo-cms-minimal-tp${argeo.rpm.suffix}</require>
</requires>
</configuration>
</execution>
<type>pom</type>
</dependency>
+ <!-- Argeo Commons UI -->
+<!-- <dependency> -->
+<!-- <groupId>org.argeo.commons</groupId> -->
+<!-- <artifactId>org.argeo.eclipse.ui</artifactId> -->
+<!-- <version>2.3-SNAPSHOT</version> -->
+<!-- </dependency> -->
+ <dependency>
+ <groupId>org.argeo.commons</groupId>
+ <artifactId>org.argeo.swt.specific.rap</artifactId>
+ <version>2.3-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.commons</groupId>
+ <artifactId>org.argeo.cms.swt</artifactId>
+ <version>2.3-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.commons</groupId>
+ <artifactId>org.argeo.cms.ui</artifactId>
+ <version>2.3-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.commons</groupId>
+ <artifactId>org.argeo.cms.ui.rap</artifactId>
+ <version>2.3-SNAPSHOT</version>
+ </dependency>
+
+
<!-- RWT -->
<dependency>
<groupId>org.argeo.tp.rap.e4</groupId>
<artifactId>org.eclipse.rap.fileupload</artifactId>
</dependency>
- <!-- Argeo Commons UI -->
- <dependency>
- <groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.eclipse.ui</artifactId>
- <version>2.3-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.eclipse.ui.rap</artifactId>
- <version>2.3-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.cms.ui</artifactId>
- <version>2.3-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.cms.ui.rap</artifactId>
- <version>2.3-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.cms.ui.theme</artifactId>
- <version>2.3-SNAPSHOT</version>
- </dependency>
-
<!-- SDK -->
<dependency>
<groupId>org.argeo.tp.sdk</groupId>
<name>Commons Modular Distributions</name>
<packaging>pom</packaging>
<modules>
- <module>org.argeo.dep.cms.client</module>
+ <module>org.argeo.dep.cms.minimal</module>
<module>org.argeo.dep.cms.node</module>
<module>org.argeo.dep.cms.ui.rap</module>
<module>org.argeo.dep.cms.e4.rap</module>
<relativePath>..</relativePath>
</parent>
<artifactId>org.argeo.api</artifactId>
- <name>Argeo Node API</name>
+ <name>CMS API</name>
<packaging>jar</packaging>
<dependencies>
</dependencies>
<!-- Specific -->
<dependency>
<groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.eclipse.ui.rap</artifactId>
+ <artifactId>org.argeo.swt.specific.rap</artifactId>
<version>2.3-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<!-- UI -->
<dependency>
<groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.eclipse.ui.rap</artifactId>
+ <artifactId>org.argeo.swt.specific.rap</artifactId>
<version>2.3-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<relativePath>..</relativePath>
</parent>
<artifactId>org.argeo.cms.jcr</artifactId>
- <name>Commons CMS JCR</name>
+ <name>CMS JCR</name>
<dependencies>
- <dependency>
- <groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.api</artifactId>
- <version>2.3-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.enterprise</artifactId>
- <version>2.3-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.core</artifactId>
- <version>2.3-SNAPSHOT</version>
- </dependency>
<dependency>
<groupId>org.argeo.commons</groupId>
<artifactId>org.argeo.cms</artifactId>
+++ /dev/null
-package org.argeo.cli.jcr;
-
-import org.argeo.cli.CommandsCli;
-
-/** File utilities. */
-public class JcrCommands extends CommandsCli {
-
- public JcrCommands(String commandName) {
- super(commandName);
- addCommand("sync", new JcrSync());
- }
-
- @Override
- public String getDescription() {
- return "Utilities around remote and local JCR repositories";
- }
-
-}
+++ /dev/null
-package org.argeo.cli.jcr;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.nio.file.Paths;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.jcr.Credentials;
-import javax.jcr.Node;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.RepositoryFactory;
-import javax.jcr.Session;
-import javax.jcr.SimpleCredentials;
-
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.apache.jackrabbit.core.RepositoryImpl;
-import org.apache.jackrabbit.core.config.RepositoryConfig;
-import org.argeo.cli.CommandArgsException;
-import org.argeo.cli.CommandRuntimeException;
-import org.argeo.cli.DescribedCommand;
-import org.argeo.jackrabbit.client.ClientDavexRepositoryFactory;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.sync.SyncResult;
-
-public class JcrSync implements DescribedCommand<SyncResult<Node>> {
- public final static String DEFAULT_LOCALFS_CONFIG = "repository-localfs.xml";
-
- final static Option deleteOption = Option.builder().longOpt("delete").desc("delete from target").build();
- final static Option recursiveOption = Option.builder("r").longOpt("recursive").desc("recurse into directories")
- .build();
- final static Option progressOption = Option.builder().longOpt("progress").hasArg(false).desc("show progress")
- .build();
-
- @Override
- public SyncResult<Node> apply(List<String> t) {
- try {
- CommandLine line = toCommandLine(t);
- List<String> remaining = line.getArgList();
- if (remaining.size() == 0) {
- throw new CommandArgsException("There must be at least one argument");
- }
- URI sourceUri = new URI(remaining.get(0));
- URI targetUri;
- if (remaining.size() == 1) {
- targetUri = Paths.get(System.getProperty("user.dir")).toUri();
- } else {
- targetUri = new URI(remaining.get(1));
- }
- boolean delete = line.hasOption(deleteOption.getLongOpt());
- boolean recursive = line.hasOption(recursiveOption.getLongOpt());
-
- // TODO make it configurable
- String sourceWorkspace = "home";
- String targetWorkspace = sourceWorkspace;
-
- final Repository sourceRepository;
- final Session sourceSession;
- Credentials sourceCredentials = null;
- final Repository targetRepository;
- final Session targetSession;
- Credentials targetCredentials = null;
-
- if ("http".equals(sourceUri.getScheme()) || "https".equals(sourceUri.getScheme())) {
- sourceRepository = createRemoteRepository(sourceUri);
- } else if (null == sourceUri.getScheme() || "file".equals(sourceUri.getScheme())) {
- RepositoryConfig repositoryConfig = RepositoryConfig.create(
- JcrSync.class.getResourceAsStream(DEFAULT_LOCALFS_CONFIG), sourceUri.getPath().toString());
- sourceRepository = RepositoryImpl.create(repositoryConfig);
- sourceCredentials = new SimpleCredentials("admin", "admin".toCharArray());
- } else {
- throw new IllegalArgumentException("Unsupported scheme " + sourceUri.getScheme());
- }
- sourceSession = JcrUtils.loginOrCreateWorkspace(sourceRepository, sourceWorkspace, sourceCredentials);
-
- if ("http".equals(targetUri.getScheme()) || "https".equals(targetUri.getScheme())) {
- targetRepository = createRemoteRepository(targetUri);
- } else if (null == targetUri.getScheme() || "file".equals(targetUri.getScheme())) {
- RepositoryConfig repositoryConfig = RepositoryConfig.create(
- JcrSync.class.getResourceAsStream(DEFAULT_LOCALFS_CONFIG), targetUri.getPath().toString());
- targetRepository = RepositoryImpl.create(repositoryConfig);
- targetCredentials = new SimpleCredentials("admin", "admin".toCharArray());
- } else {
- throw new IllegalArgumentException("Unsupported scheme " + targetUri.getScheme());
- }
- targetSession = JcrUtils.loginOrCreateWorkspace(targetRepository, targetWorkspace, targetCredentials);
-
- JcrUtils.copy(sourceSession.getRootNode(), targetSession.getRootNode());
- return new SyncResult<Node>();
- } catch (URISyntaxException e) {
- throw new CommandArgsException(e);
- } catch (Exception e) {
- throw new CommandRuntimeException(e, this, t);
- }
- }
-
- protected Repository createRemoteRepository(URI uri) throws RepositoryException {
- RepositoryFactory repositoryFactory = new ClientDavexRepositoryFactory();
- Map<String, String> params = new HashMap<String, String>();
- params.put(ClientDavexRepositoryFactory.JACKRABBIT_DAVEX_URI, uri.toString());
- // FIXME make it configurable
- params.put(ClientDavexRepositoryFactory.JACKRABBIT_REMOTE_DEFAULT_WORKSPACE, "sys");
- return repositoryFactory.getRepository(params);
- }
-
- @Override
- public Options getOptions() {
- Options options = new Options();
- options.addOption(recursiveOption);
- options.addOption(deleteOption);
- options.addOption(progressOption);
- return options;
- }
-
- @Override
- public String getUsage() {
- return "[source URI] [target URI]";
- }
-
- public static void main(String[] args) {
- DescribedCommand.mainImpl(new JcrSync(), args);
- }
-
- @Override
- public String getDescription() {
- return "Synchronises JCR repositories";
- }
-
-}
+++ /dev/null
-/** JCR CLI commands. */
-package org.argeo.cli.jcr;
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0"?>
-<!--
-
- Copyright (C) 2007-2012 Argeo GmbH
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
--->
-<!DOCTYPE Repository PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit 1.6//EN"
- "http://jackrabbit.apache.org/dtd/repository-2.0.dtd">
-<Repository>
- <!-- File system and datastore -->
- <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
- <param name="path" value="${rep.home}/repository" />
- </FileSystem>
- <DataStore class="org.apache.jackrabbit.core.data.FileDataStore">
- <param name="path" value="${rep.home}/datastore" />
- </DataStore>
-
- <!-- Workspace templates -->
- <Workspaces rootPath="${rep.home}/workspaces"
- defaultWorkspace="main" configRootPath="/workspaces" />
- <Workspace name="${wsp.name}">
- <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
- <param name="path" value="${wsp.home}" />
- </FileSystem>
- <PersistenceManager
- class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager">
- <param name="blobFSBlockSize" value="1" />
- </PersistenceManager>
- <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
- <param name="path" value="${rep.home}/repository/index" />
- </SearchIndex>
- </Workspace>
-
- <!-- Versioning -->
- <Versioning rootPath="${rep.home}/version">
- <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
- <param name="path" value="${rep.home}/version" />
- </FileSystem>
- <PersistenceManager
- class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager">
- <param name="blobFSBlockSize" value="1" />
- </PersistenceManager>
- </Versioning>
-
- <!-- Indexing -->
- <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
- <param name="path" value="${rep.home}/repository/index" />
- <param name="tikaConfigPath" value="tika-config.xml"/>
- </SearchIndex>
-
- <!-- Security -->
- <Security appName="Jackrabbit">
- <SecurityManager
- class="org.apache.jackrabbit.core.security.simple.SimpleSecurityManager"
- workspaceName="security" />
- <AccessManager
- class="org.apache.jackrabbit.core.security.simple.SimpleAccessManager" />
- <LoginModule
- class="org.apache.jackrabbit.core.security.simple.SimpleLoginModule">
- <param name="anonymousId" value="anonymous" />
- <param name="adminId" value="admin" />
- </LoginModule>
- </Security>
-</Repository>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src" />
+ <classpathentry kind="con"
+ path="org.eclipse.pde.core.requiredPlugins" />
+ <classpathentry kind="con"
+ path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11" />
+ <classpathentry kind="output" path="bin" />
+</classpath>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.argeo.cms.swt</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
+Import-Package: org.eclipse.swt,\
+ org.eclipse.jface.window,\
+ org.eclipse.core.commands.common,\
+ *
--- /dev/null
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
+
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<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.commons</groupId>
+ <version>2.3-SNAPSHOT</version>
+ <artifactId>argeo-commons</artifactId>
+ <relativePath>..</relativePath>
+ </parent>
+ <artifactId>org.argeo.cms.swt</artifactId>
+ <name>CMS SWT</name>
+ <dependencies>
+<!-- <dependency> -->
+<!-- <groupId>org.argeo.commons</groupId> -->
+<!-- <artifactId>org.argeo.util</artifactId> -->
+<!-- <version>2.1.89-SNAPSHOT</version> -->
+<!-- </dependency> -->
+ <dependency>
+ <groupId>org.argeo.commons</groupId>
+ <artifactId>org.argeo.cms</artifactId>
+ <version>2.3-SNAPSHOT</version>
+ </dependency>
+
+ <!-- UI -->
+ <dependency>
+ <groupId>org.argeo.tp.rap.e4</groupId>
+ <artifactId>org.eclipse.rap.rwt</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.rap.e4</groupId>
+ <artifactId>org.eclipse.core.commands</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.rap.e4</groupId>
+ <artifactId>org.eclipse.rap.jface</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
--- /dev/null
+package org.argeo.cms.ui.theme;
+
+import java.net.URL;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+
+public class CmsImages {
+ private static BundleContext themeBc = FrameworkUtil.getBundle(CmsImages.class).getBundleContext();
+
+ final public static String ICONS_BASE = "icons/";
+ final public static String TYPES_BASE = ICONS_BASE + "types/";
+ final public static String ACTIONS_BASE = ICONS_BASE + "actions/";
+
+ public static Image createIcon(String name) {
+ return createImg(CmsImages.ICONS_BASE + name);
+ }
+
+ public static Image createAction(String name) {
+ return createImg(CmsImages.ACTIONS_BASE + name);
+ }
+
+ public static Image createType(String name) {
+ return createImg(CmsImages.TYPES_BASE + name);
+ }
+
+ public static Image createImg(String name) {
+ return CmsImages.createDesc(name).createImage(Display.getDefault());
+ }
+
+ public static ImageDescriptor createDesc(String name) {
+ return createDesc(themeBc, name);
+ }
+
+ public static ImageDescriptor createDesc(BundleContext bc, String name) {
+ URL url = bc.getBundle().getResource(name);
+ if (url == null)
+ return ImageDescriptor.getMissingImageDescriptor();
+ return ImageDescriptor.createFromURL(url);
+ }
+
+ public static Image createImg(BundleContext bc, String name) {
+ return createDesc(bc, name).createImage(Display.getDefault());
+ }
+
+}
--- /dev/null
+/** Argeo CMS core theme images. */
+package org.argeo.cms.ui.theme;
\ No newline at end of file
--- /dev/null
+package org.argeo.eclipse.ui;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Tree content provider dealing with tree objects and providing reasonable
+ * defaults.
+ */
+public abstract class AbstractTreeContentProvider implements
+ ITreeContentProvider {
+ private static final long serialVersionUID = 8246126401957763868L;
+
+ /** Does nothing */
+ public void dispose() {
+ }
+
+ /** Does nothing */
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+
+ public Object[] getChildren(Object element) {
+ if (element instanceof TreeParent) {
+ return ((TreeParent) element).getChildren();
+ }
+ return new Object[0];
+ }
+
+ public Object getParent(Object element) {
+ if (element instanceof TreeParent) {
+ return ((TreeParent) element).getParent();
+ }
+ return null;
+ }
+
+ public boolean hasChildren(Object element) {
+ if (element instanceof TreeParent) {
+ return ((TreeParent) element).hasChildren();
+ }
+ return false;
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.argeo.eclipse.ui;
+
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+
+/**
+ * Wraps the definition of a column to be used in the various JFace viewers
+ * (typically tree and table). It enables definition of generic viewers which
+ * column can be then defined externally. Also used to generate export.
+ */
+public class ColumnDefinition {
+ private ColumnLabelProvider labelProvider;
+ private String label;
+ private int weight = 0;
+ private int minWidth = 120;
+
+ public ColumnDefinition(ColumnLabelProvider labelProvider, String label) {
+ this.labelProvider = labelProvider;
+ this.label = label;
+ }
+
+ public ColumnDefinition(ColumnLabelProvider labelProvider, String label,
+ int weight) {
+ this.labelProvider = labelProvider;
+ this.label = label;
+ this.weight = weight;
+ this.minWidth = weight;
+ }
+
+ public ColumnDefinition(ColumnLabelProvider labelProvider, String label,
+ int weight, int minimumWidth) {
+ this.labelProvider = labelProvider;
+ this.label = label;
+ this.weight = weight;
+ this.minWidth = minimumWidth;
+ }
+
+ public ColumnLabelProvider getLabelProvider() {
+ return labelProvider;
+ }
+
+ public void setLabelProvider(ColumnLabelProvider labelProvider) {
+ this.labelProvider = labelProvider;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ public int getWeight() {
+ return weight;
+ }
+
+ public void setWeight(int weight) {
+ this.weight = weight;
+ }
+
+ public int getMinWidth() {
+ return minWidth;
+ }
+
+ public void setMinWidth(int minWidth) {
+ this.minWidth = minWidth;
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.argeo.eclipse.ui;
+
+import org.eclipse.jface.viewers.ColumnViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+
+/** Generic column viewer sorter */
+public class ColumnViewerComparator extends ViewerComparator {
+ private static final long serialVersionUID = -2266218906355859909L;
+
+ public static final int ASC = 1;
+
+ public static final int NONE = 0;
+
+ public static final int DESC = -1;
+
+ private int direction = 0;
+
+ private TableViewerColumn column;
+
+ private ColumnViewer viewer;
+
+ public ColumnViewerComparator(TableViewerColumn column) {
+ super(null);
+ this.column = column;
+ this.viewer = column.getViewer();
+ this.column.getColumn().addSelectionListener(new SelectionAdapter() {
+ private static final long serialVersionUID = 7586796298965472189L;
+
+ public void widgetSelected(SelectionEvent e) {
+ if (ColumnViewerComparator.this.viewer.getComparator() != null) {
+ if (ColumnViewerComparator.this.viewer.getComparator() == ColumnViewerComparator.this) {
+ int tdirection = ColumnViewerComparator.this.direction;
+
+ if (tdirection == ASC) {
+ setSortDirection(DESC);
+ } else if (tdirection == DESC) {
+ setSortDirection(NONE);
+ }
+ } else {
+ setSortDirection(ASC);
+ }
+ } else {
+ setSortDirection(ASC);
+ }
+ }
+ });
+ }
+
+ private void setSortDirection(int direction) {
+ if (direction == NONE) {
+ column.getColumn().getParent().setSortColumn(null);
+ column.getColumn().getParent().setSortDirection(SWT.NONE);
+ viewer.setComparator(null);
+ } else {
+ column.getColumn().getParent().setSortColumn(column.getColumn());
+ this.direction = direction;
+
+ if (direction == ASC) {
+ column.getColumn().getParent().setSortDirection(SWT.DOWN);
+ } else {
+ column.getColumn().getParent().setSortDirection(SWT.UP);
+ }
+
+ if (viewer.getComparator() == this) {
+ viewer.refresh();
+ } else {
+ viewer.setComparator(this);
+ }
+
+ }
+ }
+
+ public int compare(Viewer viewer, Object e1, Object e2) {
+ return direction * super.compare(viewer, e1, e2);
+ }
+}
--- /dev/null
+package org.argeo.eclipse.ui;
+
+/** CMS specific exceptions. */
+public class EclipseUiException extends RuntimeException {
+ private static final long serialVersionUID = -5341764743356771313L;
+
+ public EclipseUiException(String message) {
+ super(message);
+ }
+
+ public EclipseUiException(String message, Throwable e) {
+ super(message, e);
+ }
+
+}
--- /dev/null
+package org.argeo.eclipse.ui;
+
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+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.Label;
+import org.eclipse.swt.widgets.Text;
+
+/** Utilities to simplify UI development. */
+public class EclipseUiUtils {
+
+ /** Dispose all children of a Composite */
+ public static void clear(Composite composite) {
+ for (Control child : composite.getChildren())
+ child.dispose();
+ }
+
+ /**
+ * Enables efficient call to the layout method of a composite, refreshing only
+ * some of the children controls.
+ */
+ public static void layout(Composite parent, Control... toUpdateControls) {
+ parent.layout(toUpdateControls);
+ }
+
+ //
+ // FONTS
+ //
+ /** Shortcut to retrieve default italic font from display */
+ public static Font getItalicFont(Composite parent) {
+ return JFaceResources.getFontRegistry().defaultFontDescriptor().setStyle(SWT.ITALIC)
+ .createFont(parent.getDisplay());
+ }
+
+ /** Shortcut to retrieve default bold font from display */
+ public static Font getBoldFont(Composite parent) {
+ return JFaceResources.getFontRegistry().defaultFontDescriptor().setStyle(SWT.BOLD)
+ .createFont(parent.getDisplay());
+ }
+
+ /** Shortcut to retrieve default bold italic font from display */
+ public static Font getBoldItalicFont(Composite parent) {
+ return JFaceResources.getFontRegistry().defaultFontDescriptor().setStyle(SWT.BOLD | SWT.ITALIC)
+ .createFont(parent.getDisplay());
+ }
+
+ //
+ // Simplify grid layouts management
+ //
+ public static GridLayout noSpaceGridLayout() {
+ return noSpaceGridLayout(new GridLayout());
+ }
+
+ public static GridLayout noSpaceGridLayout(int columns) {
+ return noSpaceGridLayout(new GridLayout(columns, false));
+ }
+
+ public static GridLayout noSpaceGridLayout(GridLayout layout) {
+ layout.horizontalSpacing = 0;
+ layout.verticalSpacing = 0;
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ return layout;
+ }
+
+ public static GridData fillWidth() {
+ return grabWidth(SWT.FILL, SWT.FILL);
+ }
+
+ public static GridData fillWidth(int colSpan) {
+ GridData gd = grabWidth(SWT.FILL, SWT.FILL);
+ gd.horizontalSpan = colSpan;
+ return gd;
+ }
+
+ public static GridData fillAll() {
+ return new GridData(SWT.FILL, SWT.FILL, true, true);
+ }
+
+ public static GridData fillAll(int colSpan, int rowSpan) {
+ return new GridData(SWT.FILL, SWT.FILL, true, true, colSpan, rowSpan);
+ }
+
+ public static GridData grabWidth(int horizontalAlignment, int verticalAlignment) {
+ return new GridData(horizontalAlignment, horizontalAlignment, true, false);
+ }
+
+ //
+ // Simplify Form layout management
+ //
+
+ /**
+ * Creates a basic form data that is attached to the 4 corners of the parent
+ * composite
+ */
+ public static FormData fillFormData() {
+ FormData formData = new FormData();
+ formData.top = new FormAttachment(0, 0);
+ formData.left = new FormAttachment(0, 0);
+ formData.right = new FormAttachment(100, 0);
+ formData.bottom = new FormAttachment(100, 0);
+ return formData;
+ }
+
+ /**
+ * Create a label and a text field for a grid layout, the text field grabbing
+ * excess horizontal
+ *
+ * @param parent
+ * the parent composite
+ * @param label
+ * the label to display
+ * @param modifyListener
+ * a {@link ModifyListener} to listen on events on the text, can be
+ * null
+ * @return the created text
+ *
+ */
+ // FIXME why was this deprecated.
+ // * @ deprecated use { @ link #createGridLT(Composite, String)} instead
+ // @ Deprecated
+ public static Text createGridLT(Composite parent, String label, ModifyListener modifyListener) {
+ Label lbl = new Label(parent, SWT.LEAD);
+ lbl.setText(label);
+ lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
+ Text txt = new Text(parent, SWT.LEAD | SWT.BORDER);
+ txt.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+ if (modifyListener != null)
+ txt.addModifyListener(modifyListener);
+ return txt;
+ }
+
+ /**
+ * Create a label and a text field for a grid layout, the text field grabbing
+ * excess horizontal
+ */
+ public static Text createGridLT(Composite parent, String label) {
+ return createGridLT(parent, label, null);
+ }
+
+ /**
+ * Creates one label and a text field not editable with background colour of the
+ * parent (like a label but with selectable text)
+ */
+ public static Text createGridLL(Composite parent, String label, String text) {
+ Text txt = createGridLT(parent, label);
+ txt.setText(text);
+ txt.setEditable(false);
+ txt.setBackground(parent.getBackground());
+ return txt;
+ }
+
+ /**
+ * Create a label and a text field with password display for a grid layout, the
+ * text field grabbing excess horizontal
+ */
+ public static Text createGridLP(Composite parent, String label) {
+ return createGridLP(parent, label, null);
+ }
+
+ /**
+ * Create a label and a text field with password display for a grid layout, the
+ * text field grabbing excess horizontal. The given modify listener will be
+ * added to the newly created text field if not null.
+ */
+ public static Text createGridLP(Composite parent, String label, ModifyListener modifyListener) {
+ Label lbl = new Label(parent, SWT.LEAD);
+ lbl.setText(label);
+ lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
+ Text txt = new Text(parent, SWT.LEAD | SWT.BORDER | SWT.PASSWORD);
+ txt.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+ if (modifyListener != null)
+ txt.addModifyListener(modifyListener);
+ return txt;
+ }
+
+ // MISCELLANEOUS
+
+ /** Simply checks if a string is not null nor empty */
+ public static boolean notEmpty(String stringToTest) {
+ return !(stringToTest == null || "".equals(stringToTest.trim()));
+ }
+
+ /** Simply checks if a string is null or empty */
+ public static boolean isEmpty(String stringToTest) {
+ return stringToTest == null || "".equals(stringToTest.trim());
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.argeo.eclipse.ui;
+
+import java.io.InputStream;
+
+/**
+ * Used for file download : subclasses must implement model specific methods to
+ * get a byte array representing a file given is ID.
+ */
+@Deprecated
+public interface FileProvider {
+
+ public byte[] getByteArrayFileFromId(String fileId);
+
+ public InputStream getInputStreamFromFileId(String fileId);
+
+}
--- /dev/null
+package org.argeo.eclipse.ui;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+
+public abstract class GenericTableComparator extends ViewerComparator {
+ private static final long serialVersionUID = -1175894935075325810L;
+ protected int propertyIndex;
+ public static final int ASCENDING = 0, DESCENDING = 1;
+ protected int direction = DESCENDING;
+
+ /**
+ * Creates an instance of a sorter for TableViewer.
+ *
+ * @param defaultColumnIndex
+ * the default sorter column
+ */
+
+ public GenericTableComparator(int defaultColumnIndex, int direction) {
+ propertyIndex = defaultColumnIndex;
+ this.direction = direction;
+ }
+
+ public void setColumn(int column) {
+ if (column == this.propertyIndex) {
+ // Same column as last sort; toggle the direction
+ direction = 1 - direction;
+ } else {
+ // New column; do a descending sort
+ this.propertyIndex = column;
+ direction = DESCENDING;
+ }
+ }
+
+ /**
+ * Must be Overriden in each view.
+ */
+ public abstract int compare(Viewer viewer, Object e1, Object e2);
+}
--- /dev/null
+package org.argeo.eclipse.ui;
+
+import java.util.List;
+
+/**
+ * Views and editors can implement this interface so that one of the list that
+ * is displayed in the part (For instance in a Table or a Tree Viewer) can be
+ * rebuilt externally. Typically to generate csv or calc extract.
+ */
+public interface IListProvider {
+ /**
+ * Returns an array of current and relevant elements
+ */
+ public Object[] getElements(String extractId);
+
+ /**
+ * Returns the column definition for passed ID
+ */
+ public List<ColumnDefinition> getColumnDefinition(String extractId);
+}
--- /dev/null
+package org.argeo.eclipse.ui;
+
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+
+/**
+ * {@link MouseListener#mouseDoubleClick(MouseEvent)} as a functional interface
+ * in order to use as a short lambda expression in UI code.
+ * {@link MouseListener#mouseDownouseEvent)} and
+ * {@link MouseListener#mouseUp(MouseEvent)} do nothing by default.
+ */
+@FunctionalInterface
+public interface MouseDoubleClick extends MouseListener {
+ @Override
+ void mouseDoubleClick(MouseEvent e);
+
+ @Override
+ default void mouseDown(MouseEvent e) {
+ // does nothing
+ }
+
+ @Override
+ default void mouseUp(MouseEvent e) {
+ // does nothing
+ }
+}
--- /dev/null
+package org.argeo.eclipse.ui;
+
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+
+/**
+ * {@link MouseListener#mouseDown(MouseEvent)} as a functional interface in
+ * order to use as a short lambda expression in UI code.
+ * {@link MouseListener#mouseDoubleClick(MouseEvent)} and
+ * {@link MouseListener#mouseUp(MouseEvent)} do nothing by default.
+ */
+@FunctionalInterface
+public interface MouseDown extends MouseListener {
+ @Override
+ void mouseDown(MouseEvent e);
+
+ @Override
+ default void mouseDoubleClick(MouseEvent e) {
+ // does nothing
+ }
+
+ @Override
+ default void mouseUp(MouseEvent e) {
+ // does nothing
+ }
+}
--- /dev/null
+package org.argeo.eclipse.ui;
+
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+
+/**
+ * {@link SelectionListener} as a functional interface in order to use as a
+ * short lambda expression in UI code.
+ * {@link SelectionListener#widgetDefaultSelected(SelectionEvent)} does nothing
+ * by default.
+ */
+@FunctionalInterface
+public interface Selected extends SelectionListener {
+ @Override
+ public void widgetSelected(SelectionEvent e);
+
+ default public void widgetDefaultSelected(SelectionEvent e) {
+ // does nothing
+ }
+
+}
--- /dev/null
+package org.argeo.eclipse.ui;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/** Parent / children semantic to be used for simple UI Tree structure */
+public class TreeParent {
+ private String name;
+ private TreeParent parent;
+
+ private List<Object> children;
+
+ /**
+ * Unique id within the context of a tree display. If set, equals() and
+ * hashCode() methods will be based on it
+ */
+ private String path = null;
+
+ /** False until at least one child has been added, then true until cleared */
+ private boolean loaded = false;
+
+ public TreeParent(String name) {
+ this.name = name;
+ children = new ArrayList<Object>();
+ }
+
+ public synchronized void addChild(Object child) {
+ loaded = true;
+ children.add(child);
+ if (child instanceof TreeParent)
+ ((TreeParent) child).setParent(this);
+ }
+
+ /**
+ * Remove this child. The child is disposed.
+ */
+ public synchronized void removeChild(Object child) {
+ children.remove(child);
+ if (child instanceof TreeParent) {
+ ((TreeParent) child).dispose();
+ }
+ }
+
+ public synchronized void clearChildren() {
+ for (Object obj : children) {
+ if (obj instanceof TreeParent)
+ ((TreeParent) obj).dispose();
+ }
+ loaded = false;
+ children.clear();
+ }
+
+ /**
+ * If overridden, <code>super.dispose()</code> must be called, typically
+ * after custom cleaning.
+ */
+ public synchronized void dispose() {
+ clearChildren();
+ parent = null;
+ children = null;
+ }
+
+ public synchronized Object[] getChildren() {
+ return children.toArray(new Object[children.size()]);
+ }
+
+ @SuppressWarnings("unchecked")
+ public synchronized <T> List<T> getChildrenOfType(Class<T> clss) {
+ List<T> lst = new ArrayList<T>();
+ for (Object obj : children) {
+ if (clss.isAssignableFrom(obj.getClass()))
+ lst.add((T) obj);
+ }
+ return lst;
+ }
+
+ public synchronized boolean hasChildren() {
+ return children.size() > 0;
+ }
+
+ public Object getChildByName(String name) {
+ for (Object child : children) {
+ if (child.toString().equals(name))
+ return child;
+ }
+ return null;
+ }
+
+ public synchronized Boolean isLoaded() {
+ return loaded;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setParent(TreeParent parent) {
+ this.parent = parent;
+ if (parent != null && parent.path != null)
+ this.path = parent.path + '/' + name;
+ else
+ this.path = '/' + name;
+ }
+
+ public TreeParent getParent() {
+ return parent;
+ }
+
+ public String toString() {
+ return getName();
+ }
+
+ public int compareTo(TreeParent o) {
+ return name.compareTo(o.name);
+ }
+
+ @Override
+ public int hashCode() {
+ if (path != null)
+ return path.hashCode();
+ else
+ return name.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (path != null && obj instanceof TreeParent)
+ return path.equals(((TreeParent) obj).path);
+ else
+ return name.equals(obj.toString());
+ }
+
+}
--- /dev/null
+package org.argeo.eclipse.ui.dialogs;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+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.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Generic error dialog to be used in try/catch blocks.
+ *
+ * @deprecated Use CMS dialogs instead.
+ */
+@Deprecated
+public class ErrorFeedback extends TitleAreaDialog {
+ private static final long serialVersionUID = -8918084784628179044L;
+
+ private final static Log log = LogFactory.getLog(ErrorFeedback.class);
+
+ private final String message;
+ private final Throwable exception;
+
+ public static void show(String message, Throwable e) {
+ // rethrow ThreaDeath in order to make sure that RAP will properly clean
+ // up the UI thread
+ if (e instanceof ThreadDeath)
+ throw (ThreadDeath) e;
+
+ new ErrorFeedback(newShell(), message, e).open();
+ }
+
+ public static void show(String message) {
+ new ErrorFeedback(newShell(), message, null).open();
+ }
+
+ private static Shell newShell() {
+ return new Shell(getDisplay(), SWT.NO_TRIM);
+ }
+
+ /** Tries to find a display */
+ private static Display getDisplay() {
+ try {
+ Display display = Display.getCurrent();
+ if (display != null)
+ return display;
+ else
+ return Display.getDefault();
+ } catch (Exception e) {
+ return Display.getCurrent();
+ }
+ }
+
+ public ErrorFeedback(Shell parentShell, String message, Throwable e) {
+ super(parentShell);
+ setShellStyle(SWT.NO_TRIM);
+ this.message = message;
+ this.exception = e;
+ log.error(message, e);
+ }
+
+ protected Point getInitialSize() {
+ if (exception != null)
+ return new Point(800, 600);
+ else
+ return new Point(400, 300);
+ }
+
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ Composite dialogarea = (Composite) super.createDialogArea(parent);
+ dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ Composite composite = new Composite(dialogarea, SWT.NONE);
+ composite.setLayout(new GridLayout(2, false));
+ composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ setMessage(message != null ? message + (exception != null ? ": " + exception.getMessage() : "")
+ : exception != null ? exception.getMessage() : "Unkown Error", IMessageProvider.ERROR);
+
+ if (exception != null) {
+ Text stack = new Text(composite, SWT.MULTI | SWT.LEAD | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
+ stack.setEditable(false);
+ stack.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ StringWriter sw = new StringWriter();
+ exception.printStackTrace(new PrintWriter(sw));
+ stack.setText(sw.toString());
+ }
+
+ parent.pack();
+ return composite;
+ }
+
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+ shell.setText("Error");
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.argeo.eclipse.ui.dialogs;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.eclipse.ui.EclipseUiException;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ShellAdapter;
+import org.eclipse.swt.events.ShellEvent;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+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.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Generic lightweight dialog, not based on JFace.
+ *
+ * @deprecated Use CMS dialogs instead.
+ */
+@Deprecated
+public class FeedbackDialog extends LightweightDialog {
+ private final static Log log = LogFactory.getLog(FeedbackDialog.class);
+
+ private String message;
+ private Throwable exception;
+
+// private Shell parentShell;
+ private Shell shell;
+
+ public static void show(String message, Throwable e) {
+ // rethrow ThreaDeath in order to make sure that RAP will properly clean
+ // up the UI thread
+ if (e instanceof ThreadDeath)
+ throw (ThreadDeath) e;
+
+ new FeedbackDialog(getDisplay().getActiveShell(), message, e).open();
+ }
+
+ public static void show(String message) {
+ new FeedbackDialog(getDisplay().getActiveShell(), message, null).open();
+ }
+
+ /** Tries to find a display */
+ private static Display getDisplay() {
+ try {
+ Display display = Display.getCurrent();
+ if (display != null)
+ return display;
+ else
+ return Display.getDefault();
+ } catch (Exception e) {
+ return Display.getCurrent();
+ }
+ }
+
+ public FeedbackDialog(Shell parentShell, String message, Throwable e) {
+ super(parentShell);
+ this.message = message;
+ this.exception = e;
+ log.error(message, e);
+ }
+
+ public int open() {
+ if (shell != null)
+ throw new EclipseUiException("There is already a shell");
+ shell = new Shell(getDisplay(), SWT.NO_TRIM | SWT.BORDER | SWT.ON_TOP);
+ shell.setLayout(new GridLayout());
+ // shell.setText("Error");
+ shell.setSize(getInitialSize());
+ createDialogArea(shell);
+ // shell.pack();
+ // shell.layout();
+
+ Rectangle shellBounds = Display.getCurrent().getBounds();// RAP
+ Point dialogSize = shell.getSize();
+ int x = shellBounds.x + (shellBounds.width - dialogSize.x) / 2;
+ int y = shellBounds.y + (shellBounds.height - dialogSize.y) / 2;
+ shell.setLocation(x, y);
+
+ shell.addShellListener(new ShellAdapter() {
+ private static final long serialVersionUID = -2701270481953688763L;
+
+ @Override
+ public void shellDeactivated(ShellEvent e) {
+ closeShell();
+ }
+ });
+
+ shell.open();
+ return OK;
+ }
+
+ protected void closeShell() {
+ shell.close();
+ shell.dispose();
+ shell = null;
+ }
+
+ protected Point getInitialSize() {
+ // if (exception != null)
+ // return new Point(800, 600);
+ // else
+ return new Point(400, 300);
+ }
+
+ protected Control createDialogArea(Composite parent) {
+ Composite dialogarea = new Composite(parent, SWT.NONE);
+ dialogarea.setLayout(new GridLayout());
+ // Composite dialogarea = (Composite) super.createDialogArea(parent);
+ dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ Label messageLbl = new Label(dialogarea, SWT.NONE);
+ if (message != null)
+ messageLbl.setText(message);
+ else if (exception != null)
+ messageLbl.setText(exception.getLocalizedMessage());
+
+ Composite composite = new Composite(dialogarea, SWT.NONE);
+ composite.setLayout(new GridLayout(2, false));
+ composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ if (exception != null) {
+ Text stack = new Text(composite, SWT.MULTI | SWT.LEAD | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
+ stack.setEditable(false);
+ stack.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ StringWriter sw = new StringWriter();
+ exception.printStackTrace(new PrintWriter(sw));
+ stack.setText(sw.toString());
+ }
+
+ // parent.pack();
+ return composite;
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.argeo.eclipse.ui.dialogs;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.eclipse.ui.EclipseUiException;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.ShellAdapter;
+import org.eclipse.swt.events.ShellEvent;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+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.Display;
+import org.eclipse.swt.widgets.Shell;
+
+/** Generic lightweight dialog, not based on JFace. */
+@Deprecated
+public class LightweightDialog {
+ private final static Log log = LogFactory.getLog(LightweightDialog.class);
+
+ // must be the same value as org.eclipse.jface.window.Window#OK
+ public final static int OK = 0;
+ // must be the same value as org.eclipse.jface.window.Window#CANCEL
+ public final static int CANCEL = 1;
+
+ private Shell parentShell;
+ private Shell backgroundShell;
+ private Shell foregoundShell;
+
+ private Integer returnCode = null;
+ private boolean block = true;
+
+ private String title;
+
+ /** Tries to find a display */
+ private static Display getDisplay() {
+ try {
+ Display display = Display.getCurrent();
+ if (display != null)
+ return display;
+ else
+ return Display.getDefault();
+ } catch (Exception e) {
+ return Display.getCurrent();
+ }
+ }
+
+ public LightweightDialog(Shell parentShell) {
+ this.parentShell = parentShell;
+ }
+
+ public int open() {
+ if (foregoundShell != null)
+ throw new EclipseUiException("There is already a shell");
+ backgroundShell = new Shell(parentShell, SWT.ON_TOP);
+ backgroundShell.setFullScreen(true);
+ // if (parentShell != null) {
+ // backgroundShell.setBounds(parentShell.getBounds());
+ // } else
+ // backgroundShell.setMaximized(true);
+ backgroundShell.setAlpha(128);
+ backgroundShell.setBackground(getDisplay().getSystemColor(SWT.COLOR_BLACK));
+ foregoundShell = new Shell(backgroundShell, SWT.NO_TRIM | SWT.ON_TOP);
+ if (title != null)
+ setTitle(title);
+ foregoundShell.setLayout(new GridLayout());
+ foregoundShell.setSize(getInitialSize());
+ createDialogArea(foregoundShell);
+ // shell.pack();
+ // shell.layout();
+
+ Rectangle shellBounds = parentShell != null ? parentShell.getBounds() : Display.getCurrent().getBounds();// RAP
+ Point dialogSize = foregoundShell.getSize();
+ int x = shellBounds.x + (shellBounds.width - dialogSize.x) / 2;
+ int y = shellBounds.y + (shellBounds.height - dialogSize.y) / 2;
+ foregoundShell.setLocation(x, y);
+
+ foregoundShell.addShellListener(new ShellAdapter() {
+ private static final long serialVersionUID = -2701270481953688763L;
+
+ @Override
+ public void shellDeactivated(ShellEvent e) {
+ if (hasChildShells())
+ return;
+ if (returnCode == null)// not yet closed
+ closeShell(CANCEL);
+ }
+
+ @Override
+ public void shellClosed(ShellEvent e) {
+ notifyClose();
+ }
+
+ });
+
+ backgroundShell.open();
+ foregoundShell.open();
+ // after the foreground shell has been opened
+ backgroundShell.addFocusListener(new FocusListener() {
+ private static final long serialVersionUID = 3137408447474661070L;
+
+ @Override
+ public void focusLost(FocusEvent event) {
+ }
+
+ @Override
+ public void focusGained(FocusEvent event) {
+ if (hasChildShells())
+ return;
+ if (returnCode == null)// not yet closed
+ closeShell(CANCEL);
+ }
+ });
+
+ if (block) {
+ block();
+ }
+ if (returnCode == null)
+ returnCode = OK;
+ return returnCode;
+ }
+
+ public void block() {
+ try {
+ runEventLoop(foregoundShell);
+ } catch (ThreadDeath t) {
+ returnCode = CANCEL;
+ if (log.isTraceEnabled())
+ log.error("Thread death, canceling dialog", t);
+ } catch (Throwable t) {
+ returnCode = CANCEL;
+ log.error("Cannot open blocking lightweight dialog", t);
+ }
+ }
+
+ private boolean hasChildShells() {
+ if (foregoundShell == null)
+ return false;
+ return foregoundShell.getShells().length != 0;
+ }
+
+ // public synchronized int openAndWait() {
+ // open();
+ // while (returnCode == null)
+ // try {
+ // wait(100);
+ // } catch (InterruptedException e) {
+ // // silent
+ // }
+ // return returnCode;
+ // }
+
+ private synchronized void notifyClose() {
+ if (returnCode == null)
+ returnCode = CANCEL;
+ notifyAll();
+ }
+
+ protected void closeShell(int returnCode) {
+ this.returnCode = returnCode;
+ if (CANCEL == returnCode)
+ onCancel();
+ if (foregoundShell != null && !foregoundShell.isDisposed()) {
+ foregoundShell.close();
+ foregoundShell.dispose();
+ foregoundShell = null;
+ }
+
+ if (backgroundShell != null && !backgroundShell.isDisposed()) {
+ backgroundShell.close();
+ backgroundShell.dispose();
+ }
+ }
+
+ protected Point getInitialSize() {
+ // if (exception != null)
+ // return new Point(800, 600);
+ // else
+ return new Point(600, 400);
+ }
+
+ protected Control createDialogArea(Composite parent) {
+ Composite dialogarea = new Composite(parent, SWT.NONE);
+ dialogarea.setLayout(new GridLayout());
+ dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ return dialogarea;
+ }
+
+ protected Shell getBackgroundShell() {
+ return backgroundShell;
+ }
+
+ protected Shell getForegoundShell() {
+ return foregoundShell;
+ }
+
+ public void setBlockOnOpen(boolean shouldBlock) {
+ block = shouldBlock;
+ }
+
+ public void pack() {
+ foregoundShell.pack();
+ }
+
+ private void runEventLoop(Shell loopShell) {
+ Display display;
+ if (foregoundShell == null) {
+ display = Display.getCurrent();
+ } else {
+ display = loopShell.getDisplay();
+ }
+
+ while (loopShell != null && !loopShell.isDisposed()) {
+ try {
+ if (!display.readAndDispatch()) {
+ display.sleep();
+ }
+ } catch (UnsupportedOperationException e) {
+ throw e;
+ } catch (Throwable e) {
+ handleException(e);
+ }
+ }
+ if (!display.isDisposed())
+ display.update();
+ }
+
+ protected void handleException(Throwable t) {
+ if (t instanceof ThreadDeath) {
+ // Don't catch ThreadDeath as this is a normal occurrence when
+ // the thread dies
+ throw (ThreadDeath) t;
+ }
+ // Try to keep running.
+ t.printStackTrace();
+ }
+
+ /** @return false, if the dialog should not be closed. */
+ protected boolean onCancel() {
+ return true;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ if (title != null && getForegoundShell() != null)
+ getForegoundShell().setText(title);
+ }
+
+ public Integer getReturnCode() {
+ return returnCode;
+ }
+
+}
\ No newline at end of file
--- /dev/null
+package org.argeo.eclipse.ui.dialogs;
+
+import org.argeo.eclipse.ui.EclipseUiUtils;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+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.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Dialog to retrieve a single value.
+ *
+ * @deprecated Use CMS dialogs instead.
+ */
+@Deprecated
+public class SingleValue extends TitleAreaDialog {
+ private static final long serialVersionUID = 2843538207460082349L;
+
+ private Text valueT;
+ private String value;
+ private final String title, message, label;
+ private final Boolean multiline;
+
+ public static String ask(String label, String message) {
+ SingleValue svd = new SingleValue(label, message);
+ if (svd.open() == Window.OK)
+ return svd.getString();
+ else
+ return null;
+ }
+
+ public static Long askLong(String label, String message) {
+ SingleValue svd = new SingleValue(label, message);
+ if (svd.open() == Window.OK)
+ return svd.getLong();
+ else
+ return null;
+ }
+
+ public static Double askDouble(String label, String message) {
+ SingleValue svd = new SingleValue(label, message);
+ if (svd.open() == Window.OK)
+ return svd.getDouble();
+ else
+ return null;
+ }
+
+ public SingleValue(String label, String message) {
+ this(Display.getDefault().getActiveShell(), label, message, label, false);
+ }
+
+ public SingleValue(Shell parentShell, String title, String message, String label, Boolean multiline) {
+ super(parentShell);
+ this.title = title;
+ this.message = message;
+ this.label = label;
+ this.multiline = multiline;
+ }
+
+ protected Point getInitialSize() {
+ if (multiline)
+ return new Point(450, 350);
+
+ else
+ return new Point(400, 270);
+ }
+
+ protected Control createDialogArea(Composite parent) {
+ Composite dialogarea = (Composite) super.createDialogArea(parent);
+ dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ Composite composite = new Composite(dialogarea, SWT.NONE);
+ composite.setLayoutData(EclipseUiUtils.fillAll());
+ GridLayout layout = new GridLayout(2, false);
+ layout.marginWidth = layout.marginHeight = 20;
+ composite.setLayout(layout);
+
+ valueT = createLT(composite, label);
+
+ setMessage(message, IMessageProvider.NONE);
+
+ parent.pack();
+ valueT.setFocus();
+ return composite;
+ }
+
+ @Override
+ protected void okPressed() {
+ value = valueT.getText();
+ super.okPressed();
+ }
+
+ /** Creates label and text. */
+ protected Text createLT(Composite parent, String label) {
+ new Label(parent, SWT.NONE).setText(label);
+ Text text;
+ if (multiline) {
+ text = new Text(parent, SWT.LEAD | SWT.BORDER | SWT.MULTI);
+ text.setLayoutData(EclipseUiUtils.fillAll());
+ } else {
+ text = new Text(parent, SWT.LEAD | SWT.BORDER | SWT.SINGLE);
+ text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
+ }
+ return text;
+ }
+
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+ shell.setText(title);
+ }
+
+ public String getString() {
+ return value;
+ }
+
+ public Long getLong() {
+ return Long.valueOf(getString());
+ }
+
+ public Double getDouble() {
+ return Double.valueOf(getString());
+ }
+}
--- /dev/null
+/** Generic SWT/JFace dialogs. */
+package org.argeo.eclipse.ui.dialogs;
\ No newline at end of file
--- /dev/null
+package org.argeo.eclipse.ui.fs;
+
+import java.io.IOException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.LinkedHashMap;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.eclipse.ui.EclipseUiUtils;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.custom.ScrolledComposite;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+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.graphics.Rectangle;
+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.Label;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.Text;
+
+/** Simple UI provider that populates a composite parent given a NIO path */
+public class AdvancedFsBrowser {
+ private final static Log log = LogFactory.getLog(AdvancedFsBrowser.class);
+
+ // Some local constants to experiment. should be cleaned
+ // private final static int THUMBNAIL_WIDTH = 400;
+ // private Point imageWidth = new Point(250, 0);
+ private final static int COLUMN_WIDTH = 160;
+
+ private Path initialPath;
+ private Path currEdited;
+ // Filter
+ private Composite displayBoxCmp;
+ private Text parentPathTxt;
+ private Text filterTxt;
+ // Browser columns
+ private ScrolledComposite scrolledCmp;
+ // Keep a cache of the opened directories
+ private LinkedHashMap<Path, FilterEntitiesVirtualTable> browserCols = new LinkedHashMap<>();
+ private Composite scrolledCmpBody;
+
+ public Control createUi(Composite parent, Path basePath) {
+ if (basePath == null)
+ throw new IllegalArgumentException("Context cannot be null");
+ parent.setLayout(new GridLayout());
+
+ // top filter
+ Composite filterCmp = new Composite(parent, SWT.NO_FOCUS);
+ filterCmp.setLayoutData(EclipseUiUtils.fillWidth());
+ addFilterPanel(filterCmp);
+
+ // Bottom part a sash with browser on the left
+ SashForm form = new SashForm(parent, SWT.HORIZONTAL);
+ // form.setLayout(new FillLayout());
+ form.setLayoutData(EclipseUiUtils.fillAll());
+ Composite leftCmp = new Composite(form, SWT.NO_FOCUS);
+ displayBoxCmp = new Composite(form, SWT.NONE);
+ form.setWeights(new int[] { 3, 1 });
+
+ createBrowserPart(leftCmp, basePath);
+ // leftCmp.addControlListener(new ControlAdapter() {
+ // @Override
+ // public void controlResized(ControlEvent e) {
+ // Rectangle r = leftCmp.getClientArea();
+ // log.warn("Browser resized: " + r.toString());
+ // scrolledCmp.setMinSize(browserCols.size() * (COLUMN_WIDTH + 2),
+ // SWT.DEFAULT);
+ // // scrolledCmp.setMinSize(scrolledCmpBody.computeSize(SWT.DEFAULT,
+ // // r.height));
+ // }
+ // });
+
+ populateCurrEditedDisplay(displayBoxCmp, basePath);
+
+ // INIT
+ setEdited(basePath);
+ initialPath = basePath;
+ // form.layout(true, true);
+ return parent;
+ }
+
+ private void createBrowserPart(Composite parent, Path context) {
+ parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
+
+ // scrolled composite
+ scrolledCmp = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.BORDER | SWT.NO_FOCUS);
+ scrolledCmp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ scrolledCmp.setExpandVertical(true);
+ scrolledCmp.setExpandHorizontal(true);
+ scrolledCmp.setShowFocusedControl(true);
+
+ scrolledCmpBody = new Composite(scrolledCmp, SWT.NO_FOCUS);
+ scrolledCmp.setContent(scrolledCmpBody);
+ scrolledCmpBody.addControlListener(new ControlAdapter() {
+ private static final long serialVersionUID = 183238447102854553L;
+
+ @Override
+ public void controlResized(ControlEvent e) {
+ Rectangle r = scrolledCmp.getClientArea();
+ scrolledCmp.setMinSize(scrolledCmpBody.computeSize(SWT.DEFAULT, r.height));
+ }
+ });
+ initExplorer(scrolledCmpBody, context);
+ scrolledCmpBody.layout(true, true);
+ scrolledCmp.layout();
+
+ }
+
+ private Control initExplorer(Composite parent, Path context) {
+ parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
+ return createBrowserColumn(parent, context);
+ }
+
+ private Control createBrowserColumn(Composite parent, Path context) {
+ // TODO style is not correctly managed.
+ FilterEntitiesVirtualTable table = new FilterEntitiesVirtualTable(parent, SWT.BORDER | SWT.NO_FOCUS, context);
+ // CmsUtils.style(table, ArgeoOrgStyle.browserColumn.style());
+ table.filterList("*");
+ table.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, true));
+ browserCols.put(context, table);
+ parent.layout(true, true);
+ return table;
+ }
+
+ public void addFilterPanel(Composite parent) {
+ parent.setLayout(EclipseUiUtils.noSpaceGridLayout(new GridLayout(2, false)));
+
+ parentPathTxt = new Text(parent, SWT.NO_FOCUS);
+ parentPathTxt.setEditable(false);
+
+ filterTxt = new Text(parent, SWT.SEARCH | SWT.ICON_CANCEL);
+ filterTxt.setMessage("Filter current list");
+ filterTxt.setLayoutData(EclipseUiUtils.fillWidth());
+ 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(currEdited, 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 FsUiException(
+ "Unable to determine unique child existence and get it under " + parent + " with filter " + filter,
+ ioe);
+ }
+ }
+
+ private void setEdited(Path path) {
+ currEdited = path;
+ EclipseUiUtils.clear(displayBoxCmp);
+ populateCurrEditedDisplay(displayBoxCmp, currEdited);
+ refreshFilters(path);
+ refreshBrowser(path);
+ }
+
+ private void refreshFilters(Path path) {
+ parentPathTxt.setText(path.toUri().toString());
+ filterTxt.setText("");
+ filterTxt.getParent().layout();
+ }
+
+ private void refreshBrowser(Path currPath) {
+ Path currParPath = currPath.getParent();
+ Object[][] colMatrix = new Object[browserCols.size()][2];
+
+ int i = 0, currPathIndex = -1, lastLeftOpenedIndex = -1;
+ for (Path path : browserCols.keySet()) {
+ colMatrix[i][0] = path;
+ colMatrix[i][1] = browserCols.get(path);
+ if (currPathIndex >= 0 && lastLeftOpenedIndex < 0 && currParPath != null) {
+ boolean leaveOpened = path.startsWith(currPath);
+ if (!leaveOpened)
+ lastLeftOpenedIndex = i;
+ }
+ if (currParPath.equals(path))
+ currPathIndex = i;
+ i++;
+ }
+
+ if (currPathIndex >= 0 && lastLeftOpenedIndex >= 0) {
+ // dispose and remove useless cols
+ for (int l = i - 1; l >= lastLeftOpenedIndex; l--) {
+ ((FilterEntitiesVirtualTable) colMatrix[l][1]).dispose();
+ browserCols.remove(colMatrix[l][0]);
+ }
+ }
+
+ if (browserCols.containsKey(currPath)) {
+ FilterEntitiesVirtualTable currCol = browserCols.get(currPath);
+ if (currCol.isDisposed()) {
+ // Does it still happen ?
+ log.warn(currPath + " browser column was disposed and still listed");
+ browserCols.remove(currPath);
+ }
+ }
+
+ if (!browserCols.containsKey(currPath) && Files.isDirectory(currPath))
+ createBrowserColumn(scrolledCmpBody, currPath);
+
+ scrolledCmpBody.setLayout(EclipseUiUtils.noSpaceGridLayout(new GridLayout(browserCols.size(), false)));
+ scrolledCmpBody.layout(true, true);
+ // also resize the scrolled composite
+ scrolledCmp.layout();
+ }
+
+ private void modifyFilter(boolean fromOutside) {
+ if (!fromOutside)
+ if (currEdited != null) {
+ String filter = filterTxt.getText() + "*";
+ FilterEntitiesVirtualTable table = browserCols.get(currEdited);
+ if (table != null && !table.isDisposed())
+ table.filterList(filter);
+ }
+ }
+
+ /**
+ * Recreates the content of the box that displays information about the current
+ * selected node.
+ */
+ private void populateCurrEditedDisplay(Composite parent, Path context) {
+ parent.setLayout(new GridLayout());
+
+ // if (isImg(context)) {
+ // EditableImage image = new Img(parent, RIGHT, context, imageWidth);
+ // image.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false,
+ // 2, 1));
+ // }
+
+ try {
+ Label contextL = new Label(parent, SWT.NONE);
+ contextL.setText(context.getFileName().toString());
+ contextL.setFont(EclipseUiUtils.getBoldFont(parent));
+ addProperty(parent, "Last modified", Files.getLastModifiedTime(context).toString());
+ addProperty(parent, "Owner", Files.getOwner(context).getName());
+ if (Files.isDirectory(context)) {
+ addProperty(parent, "Type", "Folder");
+ } else {
+ String mimeType = Files.probeContentType(context);
+ if (EclipseUiUtils.isEmpty(mimeType))
+ mimeType = "<i>Unknown</i>";
+ addProperty(parent, "Type", mimeType);
+ addProperty(parent, "Size", FsUiUtils.humanReadableByteCount(Files.size(context), false));
+ }
+ parent.layout(true, true);
+ } catch (IOException e) {
+ throw new FsUiException("Cannot display details for " + context, e);
+ }
+ }
+
+ private void addProperty(Composite parent, String propName, String value) {
+ Label contextL = new Label(parent, SWT.NONE);
+ contextL.setText(propName + ": " + value);
+ }
+
+ /**
+ * Almost canonical implementation of a table that displays the content of a
+ * directory
+ */
+ private class FilterEntitiesVirtualTable extends Composite {
+ private static final long serialVersionUID = 2223410043691844875L;
+
+ // Context
+ private Path context;
+ private Path currSelected = null;
+
+ // UI Objects
+ private FsTableViewer viewer;
+
+ @Override
+ public boolean setFocus() {
+ if (viewer.getTable().isDisposed())
+ return false;
+ if (currSelected != null)
+ viewer.setSelection(new StructuredSelection(currSelected), true);
+ else if (viewer.getSelection().isEmpty()) {
+ Object first = viewer.getElementAt(0);
+ if (first != null)
+ viewer.setSelection(new StructuredSelection(first), true);
+ }
+ return viewer.getTable().setFocus();
+ }
+
+ /**
+ * Enable highlighting the correct element in the table when externally browsing
+ * (typically via the command-line-like Text field)
+ */
+ void setSelected(Path selected) {
+ // to prevent change selection event to be thrown
+ currSelected = selected;
+ viewer.setSelection(new StructuredSelection(currSelected), true);
+ }
+
+ void filterList(String filter) {
+ viewer.setInput(context, filter);
+ }
+
+ public FilterEntitiesVirtualTable(Composite parent, int style, Path context) {
+ super(parent, SWT.NO_FOCUS);
+ this.context = context;
+ createTableViewer(this);
+ }
+
+ private void createTableViewer(final Composite parent) {
+ parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
+
+ // We must limit the size of the table otherwise the full list is
+ // loaded before the layout happens
+ // Composite listCmp = new Composite(parent, SWT.NO_FOCUS);
+ // GridData gd = new GridData(SWT.LEFT, SWT.FILL, false, true);
+ // gd.widthHint = COLUMN_WIDTH;
+ // listCmp.setLayoutData(gd);
+ // listCmp.setLayout(EclipseUiUtils.noSpaceGridLayout());
+ // viewer = new TableViewer(listCmp, SWT.VIRTUAL | SWT.MULTI |
+ // SWT.V_SCROLL);
+ // Table table = viewer.getTable();
+ // table.setLayoutData(EclipseUiUtils.fillAll());
+
+ viewer = new FsTableViewer(parent, SWT.MULTI);
+ Table table = viewer.configureDefaultSingleColumnTable(COLUMN_WIDTH);
+
+ viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+
+ @Override
+ public void selectionChanged(SelectionChangedEvent event) {
+ IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
+ if (selection.isEmpty())
+ return;
+ Object obj = selection.getFirstElement();
+ Path newSelected;
+ if (obj instanceof Path)
+ newSelected = (Path) obj;
+ else if (obj instanceof ParentDir)
+ newSelected = ((ParentDir) obj).getPath();
+ else
+ return;
+ if (newSelected.equals(currSelected))
+ return;
+ currSelected = newSelected;
+ setEdited(newSelected);
+
+ }
+ });
+
+ table.addKeyListener(new KeyListener() {
+ private static final long serialVersionUID = -8083424284436715709L;
+
+ @Override
+ public void keyReleased(KeyEvent e) {
+ }
+
+ @Override
+ public void keyPressed(KeyEvent e) {
+ IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
+ Path selected = null;
+ if (!selection.isEmpty())
+ selected = ((Path) selection.getFirstElement());
+ if (e.keyCode == SWT.ARROW_RIGHT) {
+ if (!Files.isDirectory(selected))
+ return;
+ if (selected != null) {
+ setEdited(selected);
+ browserCols.get(selected).setFocus();
+ }
+ } else if (e.keyCode == SWT.ARROW_LEFT) {
+ if (context.equals(initialPath))
+ return;
+ Path parent = context.getParent();
+ if (parent == null)
+ return;
+
+ setEdited(parent);
+ browserCols.get(parent).setFocus();
+ }
+ }
+ });
+ }
+ }
+}
--- /dev/null
+package org.argeo.eclipse.ui.fs;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.swt.graphics.Image;
+
+/** Basic label provider with icon for NIO file viewers */
+public class FileIconNameLabelProvider extends ColumnLabelProvider {
+ private static final long serialVersionUID = 8187902187946523148L;
+
+ private Image folderIcon;
+ private Image fileIcon;
+
+ public FileIconNameLabelProvider() {
+ // if (!PlatformUI.isWorkbenchRunning()) {
+ folderIcon = ImageDescriptor.createFromFile(getClass(), "folder.png").createImage();
+ fileIcon = ImageDescriptor.createFromFile(getClass(), "file.png").createImage();
+ // }
+ }
+
+ @Override
+ public void dispose() {
+ if (folderIcon != null)
+ folderIcon.dispose();
+ if (fileIcon != null)
+ fileIcon.dispose();
+ super.dispose();
+ }
+
+ @Override
+ public String getText(Object element) {
+ if (element instanceof Path) {
+ Path curr = ((Path) element);
+ Path name = curr.getFileName();
+ if (name == null)
+ return "[No name]";
+ else
+ return name.toString();
+ } else if (element instanceof ParentDir) {
+ return "..";
+ }
+ return null;
+ }
+
+ @Override
+ public Image getImage(Object element) {
+ if (element instanceof Path) {
+ Path curr = ((Path) element);
+ if (Files.isDirectory(curr))
+ // if (folderIcon != null)
+ return folderIcon;
+ // else
+ // return
+ // PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER);
+ // else if (fileIcon != null)
+ return fileIcon;
+ // else
+ // return
+ // PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FILE);
+ } else if (element instanceof ParentDir) {
+ return folderIcon;
+ }
+ return null;
+ }
+
+ @Override
+ public String getToolTipText(Object element) {
+ if (element instanceof Path) {
+ Path curr = ((Path) element);
+ Path name = curr.getFileName();
+ if (name == null)
+ return "[No name]";
+ else
+ return name.toAbsolutePath().toString();
+ } else if (element instanceof ParentDir) {
+ return ((ParentDir) element).getPath().toAbsolutePath().toString();
+ }
+ return null;
+ }
+
+}
\ No newline at end of file
--- /dev/null
+package org.argeo.eclipse.ui.fs;
+
+import java.nio.file.Path;
+import java.util.List;
+
+import org.argeo.eclipse.ui.ColumnDefinition;
+import org.eclipse.jface.viewers.CellLabelProvider;
+import org.eclipse.jface.viewers.ILazyContentProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+
+/**
+ * Canonical implementation of a JFace table viewer to display the content of a
+ * file folder
+ */
+public class FsTableViewer extends TableViewer {
+ private static final long serialVersionUID = -5632407542678477234L;
+
+ private boolean showHiddenItems = false;
+ private boolean folderFirst = true;
+ private boolean reverseOrder = false;
+ private String orderProperty = FsUiConstants.PROPERTY_NAME;
+
+ private Path initialPath = null;
+
+ public FsTableViewer(Composite parent, int style) {
+ super(parent, style | SWT.VIRTUAL);
+ }
+
+ public Table configureDefaultSingleColumnTable(int tableWidthHint) {
+
+ return configureDefaultSingleColumnTable(tableWidthHint, new FileIconNameLabelProvider());
+ }
+
+ public Table configureDefaultSingleColumnTable(int tableWidthHint, CellLabelProvider labelProvider) {
+ Table table = this.getTable();
+ table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
+ table.setLinesVisible(false);
+ table.setHeaderVisible(false);
+ // CmsUtils.markup(table);
+ // CmsUtils.style(table, MaintenanceStyles.BROWSER_COLUMN);
+
+ TableViewerColumn column = new TableViewerColumn(this, SWT.NONE);
+ TableColumn tcol = column.getColumn();
+ tcol.setWidth(tableWidthHint);
+ column.setLabelProvider(labelProvider);
+ this.setContentProvider(new MyLazyCP());
+ return table;
+ }
+
+ public Table configureDefaultTable(List<ColumnDefinition> columns) {
+ this.setContentProvider(new MyLazyCP());
+ Table table = this.getTable();
+ table.setLinesVisible(true);
+ table.setHeaderVisible(true);
+ // CmsUtils.markup(table);
+ // CmsUtils.style(table, MaintenanceStyles.BROWSER_COLUMN);
+ for (ColumnDefinition colDef : columns) {
+ TableViewerColumn column = new TableViewerColumn(this, SWT.NONE);
+ column.setLabelProvider(colDef.getLabelProvider());
+ TableColumn tcol = column.getColumn();
+ tcol.setResizable(true);
+ tcol.setText(colDef.getLabel());
+ tcol.setWidth(colDef.getMinWidth());
+ }
+ return table;
+ }
+
+ public void setInput(Path dir, String filter) {
+ Path[] rows = FsUiUtils.getChildren(dir, filter, showHiddenItems, folderFirst, orderProperty, reverseOrder);
+ if (rows == null) {
+ this.setInput(null);
+ this.setItemCount(0);
+ return;
+ }
+ boolean isRoot;
+ try {
+ isRoot = dir.getRoot().equals(dir);
+ } catch (Exception e) {
+ // FIXME Workaround for JCR root node access
+ isRoot = dir.toString().equals("/");
+ }
+ final Object[] res;
+ if (isRoot)
+ res = rows;
+ else if (initialPath != null && initialPath.equals(dir))
+ res = rows;
+ else {
+ res = new Object[rows.length + 1];
+ res[0] = new ParentDir(dir.getParent());
+ for (int i = 1; i < res.length; i++) {
+ res[i] = rows[i - 1];
+ }
+ }
+ this.setInput(res);
+ int length = res.length;
+ this.setItemCount(length);
+ this.refresh();
+ }
+
+ /** Directly displays bookmarks **/
+ public void setPathsInput(Path... paths) {
+ this.setInput((Object[]) paths);
+ this.setItemCount(paths.length);
+ this.refresh();
+ }
+
+ /**
+ * A path which is to be considered as root (and thus provide no link to a
+ * parent directory)
+ */
+ public void setInitialPath(Path initialPath) {
+ this.initialPath = initialPath;
+ }
+
+ private class MyLazyCP implements ILazyContentProvider {
+ private static final long serialVersionUID = 9096550041395433128L;
+ private Object[] elements;
+
+ public void dispose() {
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ // IMPORTANT: don't forget this: an exception will be thrown if
+ // a selected object is not part of the results anymore.
+ viewer.setSelection(null);
+ this.elements = (Object[]) newInput;
+ }
+
+ public void updateElement(int index) {
+ if (index < elements.length)
+ FsTableViewer.this.replace(elements[index], index);
+ }
+ }
+}
--- /dev/null
+package org.argeo.eclipse.ui.fs;
+
+import java.io.IOException;
+import java.nio.file.DirectoryIteratorException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.argeo.eclipse.ui.ColumnDefinition;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.TreeViewerColumn;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeColumn;
+
+/**
+ * Canonical implementation of a JFace TreeViewer to display the content of a
+ * repository
+ */
+public class FsTreeViewer extends TreeViewer {
+ private static final long serialVersionUID = -5632407542678477234L;
+
+ private boolean showHiddenItems = false;
+ private boolean showDirectoryFirst = true;
+ private String orderingProperty = FsUiConstants.PROPERTY_NAME;
+
+ public FsTreeViewer(Composite parent, int style) {
+ super(parent, style | SWT.VIRTUAL);
+ }
+
+ public Tree configureDefaultSingleColumnTable(int tableWidthHint) {
+ Tree tree = this.getTree();
+ tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
+ tree.setLinesVisible(true);
+ tree.setHeaderVisible(false);
+// CmsUtils.markup(tree);
+
+ TreeViewerColumn column = new TreeViewerColumn(this, SWT.NONE);
+ TreeColumn tcol = column.getColumn();
+ tcol.setWidth(tableWidthHint);
+ column.setLabelProvider(new FileIconNameLabelProvider());
+
+ this.setContentProvider(new MyCP());
+ return tree;
+ }
+
+ public Tree configureDefaultTable(List<ColumnDefinition> columns) {
+ this.setContentProvider(new MyCP());
+ Tree tree = this.getTree();
+ tree.setLinesVisible(true);
+ tree.setHeaderVisible(true);
+// CmsUtils.markup(tree);
+// CmsUtils.style(tree, MaintenanceStyles.BROWSER_COLUMN);
+ for (ColumnDefinition colDef : columns) {
+ TreeViewerColumn column = new TreeViewerColumn(this, SWT.NONE);
+ column.setLabelProvider(colDef.getLabelProvider());
+ TreeColumn tcol = column.getColumn();
+ tcol.setResizable(true);
+ tcol.setText(colDef.getLabel());
+ tcol.setWidth(colDef.getMinWidth());
+ }
+ return tree;
+ }
+
+ public void setInput(Path dir, String filter) {
+ try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, filter)) {
+ // TODO make this lazy
+ List<Path> paths = new ArrayList<>();
+ for (Path entry : stream) {
+ paths.add(entry);
+ }
+ Object[] rows = paths.toArray(new Object[0]);
+ this.setInput(rows);
+ // this.setItemCount(rows.length);
+ this.refresh();
+ } catch (IOException | DirectoryIteratorException e) {
+ throw new FsUiException("Unable to filter " + dir + " children with filter " + filter, e);
+ }
+ }
+
+ /** Directly displays bookmarks **/
+ public void setPathsInput(Path... paths) {
+ this.setInput((Object[]) paths);
+ // this.setItemCount(paths.length);
+ this.refresh();
+ }
+
+ private class MyCP implements ITreeContentProvider {
+ private static final long serialVersionUID = 9096550041395433128L;
+ private Object[] elements;
+
+ public void dispose() {
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ // IMPORTANT: don't forget this: an exception will be thrown if
+ // a selected object is not part of the results anymore.
+ viewer.setSelection(null);
+ this.elements = (Object[]) newInput;
+ }
+
+ @Override
+ public Object[] getElements(Object inputElement) {
+ return elements;
+ }
+
+ @Override
+ public Object[] getChildren(Object parentElement) {
+ Path path = (Path) parentElement;
+ if (!Files.isDirectory(path))
+ return null;
+ else
+ return FsUiUtils.getChildren(path, "*", showHiddenItems, showDirectoryFirst, orderingProperty, false);
+ }
+
+ @Override
+ public Object getParent(Object element) {
+ Path path = (Path) element;
+ return path.getParent();
+ }
+
+ @Override
+ public boolean hasChildren(Object element) {
+ Path path = (Path) element;
+ try {
+ if (!Files.isDirectory(path))
+ return false;
+ else
+ try (DirectoryStream<Path> children = Files.newDirectoryStream(path, "*")) {
+ return children.iterator().hasNext();
+ }
+ } catch (IOException e) {
+ throw new FsUiException("Unable to check child existence on " + path, e);
+ }
+ }
+
+ }
+}
--- /dev/null
+package org.argeo.eclipse.ui.fs;
+
+/** Centralize constants used by the Nio FS UI parts */
+public interface FsUiConstants {
+
+ // TODO use standard properties
+ String PROPERTY_NAME = "name";
+ String PROPERTY_SIZE = "size";
+ String PROPERTY_LAST_MODIFIED = "last-modified";
+ String PROPERTY_TYPE = "type";
+}
--- /dev/null
+package org.argeo.eclipse.ui.fs;
+
+/** Files specific exception */
+public class FsUiException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+
+ public FsUiException(String message) {
+ super(message);
+ }
+
+ public FsUiException(String message, Throwable e) {
+ super(message, e);
+ }
+}
--- /dev/null
+package org.argeo.eclipse.ui.fs;
+
+import java.io.IOException;
+import java.nio.file.DirectoryIteratorException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/** Centralise additional utilitary methods to manage Java7 NIO files */
+public class FsUiUtils {
+
+ /**
+ * thanks to
+ * http://programming.guide/java/formatting-byte-size-to-human-readable-format.html
+ */
+ public static String humanReadableByteCount(long bytes, boolean si) {
+ int unit = si ? 1000 : 1024;
+ if (bytes < unit)
+ return bytes + " B";
+ int exp = (int) (Math.log(bytes) / Math.log(unit));
+ String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i");
+ return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
+ }
+
+ public static Path[] getChildren(Path parent, String filter, boolean showHiddenItems, boolean folderFirst,
+ String orderProperty, boolean reverseOrder) {
+ if (!Files.isDirectory(parent))
+ return null;
+ List<Pair> pairs = new ArrayList<>();
+ try (DirectoryStream<Path> stream = Files.newDirectoryStream(parent, filter)) {
+ loop: for (Path entry : stream) {
+ if (!showHiddenItems)
+ if (Files.isHidden(entry))
+ continue loop;
+ switch (orderProperty) {
+ case FsUiConstants.PROPERTY_SIZE:
+ if (folderFirst)
+ pairs.add(new LPair(entry, Files.size(entry), Files.isDirectory(entry)));
+ else
+ pairs.add(new LPair(entry, Files.size(entry)));
+ break;
+ case FsUiConstants.PROPERTY_LAST_MODIFIED:
+ if (folderFirst)
+ pairs.add(new LPair(entry, Files.getLastModifiedTime(entry).toMillis(),
+ Files.isDirectory(entry)));
+ else
+ pairs.add(new LPair(entry, Files.getLastModifiedTime(entry).toMillis()));
+ break;
+ case FsUiConstants.PROPERTY_NAME:
+ if (folderFirst)
+ pairs.add(new SPair(entry, entry.getFileName().toString(), Files.isDirectory(entry)));
+ else
+ pairs.add(new SPair(entry, entry.getFileName().toString()));
+ break;
+ default:
+ throw new FsUiException("Unable to prepare sort for property " + orderProperty);
+ }
+ }
+ Pair[] rows = pairs.toArray(new Pair[0]);
+ Arrays.sort(rows);
+ Path[] results = new Path[rows.length];
+ if (reverseOrder) {
+ int j = rows.length - 1;
+ for (int i = 0; i < rows.length; i++)
+ results[i] = rows[j - i].p;
+ } else
+ for (int i = 0; i < rows.length; i++)
+ results[i] = rows[i].p;
+ return results;
+ } catch (IOException | DirectoryIteratorException e) {
+ throw new FsUiException("Unable to filter " + parent + " children with filter " + filter, e);
+ }
+ }
+
+ static abstract class Pair implements Comparable<Object> {
+ Path p;
+ Boolean i;
+ };
+
+ static class LPair extends Pair {
+ long v;
+
+ public LPair(Path path, long propValue) {
+ p = path;
+ v = propValue;
+ }
+
+ public LPair(Path path, long propValue, boolean isDir) {
+ p = path;
+ v = propValue;
+ i = isDir;
+ }
+
+ public int compareTo(Object o) {
+ if (i != null) {
+ Boolean j = ((LPair) o).i;
+ if (i.booleanValue() != j.booleanValue())
+ return i.booleanValue() ? -1 : 1;
+ }
+ long u = ((LPair) o).v;
+ return v < u ? -1 : v == u ? 0 : 1;
+ }
+ };
+
+ static class SPair extends Pair {
+ String v;
+
+ public SPair(Path path, String propValue) {
+ p = path;
+ v = propValue;
+ }
+
+ public SPair(Path path, String propValue, boolean isDir) {
+ p = path;
+ v = propValue;
+ i = isDir;
+ }
+
+ public int compareTo(Object o) {
+ if (i != null) {
+ Boolean j = ((SPair) o).i;
+ if (i.booleanValue() != j.booleanValue())
+ return i.booleanValue() ? -1 : 1;
+ }
+ String u = ((SPair) o).v;
+ return v.compareTo(u);
+ }
+ };
+}
--- /dev/null
+package org.argeo.eclipse.ui.fs;
+
+import java.io.IOException;
+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.Date;
+
+import org.argeo.eclipse.ui.EclipseUiUtils;
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+
+/** Expect a {@link Path} as input element */
+public class NioFileLabelProvider extends ColumnLabelProvider {
+ private final static FileTime EPOCH = FileTime.fromMillis(0);
+ private static final long serialVersionUID = 2160026425187796930L;
+ private final String propName;
+ private DateFormat dateFormat = new SimpleDateFormat("YYYY-MM-dd HH:mm");
+
+ // TODO use new formatting
+ // DateTimeFormatter formatter =
+ // DateTimeFormatter.ofLocalizedDateTime( FormatStyle.SHORT )
+ // .withLocale( Locale.UK )
+ // .withZone( ZoneId.systemDefault() );
+ public NioFileLabelProvider(String propName) {
+ this.propName = propName;
+ }
+
+ @Override
+ public String getText(Object element) {
+ try {
+ Path path;
+ if (element instanceof ParentDir) {
+// switch (propName) {
+// case FsUiConstants.PROPERTY_SIZE:
+// return "-";
+// case FsUiConstants.PROPERTY_LAST_MODIFIED:
+// return "-";
+// // return Files.getLastModifiedTime(((ParentDir) element).getPath()).toString();
+// case FsUiConstants.PROPERTY_TYPE:
+// return "Folder";
+// }
+ path = ((ParentDir) element).getPath();
+ } else
+ path = (Path) element;
+ switch (propName) {
+ case FsUiConstants.PROPERTY_SIZE:
+ if (Files.isDirectory(path))
+ return "-";
+ else
+ return FsUiUtils.humanReadableByteCount(Files.size(path), false);
+ case FsUiConstants.PROPERTY_LAST_MODIFIED:
+ if (Files.isDirectory(path))
+ return "-";
+ FileTime time = Files.getLastModifiedTime(path);
+ if (time.equals(EPOCH))
+ return "-";
+ else
+ return dateFormat.format(new Date(time.toMillis()));
+ case FsUiConstants.PROPERTY_TYPE:
+ if (Files.isDirectory(path))
+ return "Folder";
+ else {
+ String mimeType = Files.probeContentType(path);
+ if (EclipseUiUtils.isEmpty(mimeType))
+ return "Unknown";
+ else
+ return mimeType;
+ }
+ default:
+ throw new IllegalArgumentException("Unsupported property " + propName);
+ }
+ } catch (IOException ioe) {
+ throw new FsUiException("Cannot get property " + propName + " on " + element);
+ }
+ }
+}
--- /dev/null
+package org.argeo.eclipse.ui.fs;
+
+import java.nio.file.Path;
+
+/** A parent directory (..) reference. */
+public class ParentDir {
+ Path path;
+
+ public ParentDir(Path path) {
+ super();
+ this.path = path;
+ }
+
+ public Path getPath() {
+ return path;
+ }
+
+ @Override
+ public int hashCode() {
+ return path.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return "Parent dir " + path;
+ }
+
+}
--- /dev/null
+package org.argeo.eclipse.ui.fs;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.eclipse.ui.ColumnDefinition;
+import org.argeo.eclipse.ui.EclipseUiUtils;
+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.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Table;
+
+/**
+ * Experimental UI upon Java 7 nio files api: SashForm layout with bookmarks on
+ * the left hand side and a simple table on the right hand side.
+ */
+public class SimpleFsBrowser extends Composite {
+ private final static Log log = LogFactory.getLog(SimpleFsBrowser.class);
+ private static final long serialVersionUID = -40347919096946585L;
+
+ private Path currSelected;
+ private FsTableViewer bookmarksViewer;
+ private FsTableViewer directoryDisplayViewer;
+
+ public SimpleFsBrowser(Composite parent, int style) {
+ super(parent, style);
+ createContent(this);
+ // parent.layout(true, true);
+ }
+
+ public Viewer getViewer() {
+ return directoryDisplayViewer;
+ }
+
+ private void createContent(Composite parent) {
+ parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
+
+ SashForm form = new SashForm(parent, SWT.HORIZONTAL);
+ Composite leftCmp = new Composite(form, SWT.NONE);
+ populateBookmarks(leftCmp);
+
+ Composite rightCmp = new Composite(form, SWT.BORDER);
+ populateDisplay(rightCmp);
+ form.setLayoutData(EclipseUiUtils.fillAll());
+ form.setWeights(new int[] { 1, 3 });
+ }
+
+ public void setInput(Path... paths) {
+ bookmarksViewer.setPathsInput(paths);
+ bookmarksViewer.getTable().getParent().layout(true, true);
+ }
+
+ private void populateBookmarks(final Composite parent) {
+ // GridLayout layout = EclipseUiUtils.noSpaceGridLayout();
+ // layout.verticalSpacing = 5;
+ parent.setLayout(new GridLayout());
+
+ ISelectionChangedListener selList = new MySelectionChangedListener();
+
+ appendTitle(parent, "My bookmarks");
+ bookmarksViewer = new FsTableViewer(parent, SWT.MULTI | SWT.NO_SCROLL);
+ Table table = bookmarksViewer.configureDefaultSingleColumnTable(500);
+ GridData gd = EclipseUiUtils.fillWidth();
+ gd.horizontalIndent = 10;
+ table.setLayoutData(gd);
+ bookmarksViewer.addSelectionChangedListener(selList);
+
+ appendTitle(parent, "Jcr + File");
+
+ FsTableViewer jcrFilesViewers = new FsTableViewer(parent, SWT.MULTI | SWT.NO_SCROLL);
+ table = jcrFilesViewers.configureDefaultSingleColumnTable(500);
+ gd = EclipseUiUtils.fillWidth();
+ gd.horizontalIndent = 10;
+ table.setLayoutData(gd);
+ jcrFilesViewers.addSelectionChangedListener(selList);
+
+ // FileSystemProvider fsProvider = new JackrabbitMemoryFsProvider();
+ // try {
+ // Path testPath = fsProvider.getPath(new URI("jcr+memory:/"));
+ // jcrFilesViewers.setPathsInput(testPath);
+ // } catch (URISyntaxException e) {
+ // // TODO Auto-generated catch block
+ // e.printStackTrace();
+ // }
+ }
+
+ private Label appendTitle(Composite parent, String value) {
+ Label titleLbl = new Label(parent, SWT.NONE);
+ titleLbl.setText(value);
+ titleLbl.setFont(EclipseUiUtils.getBoldFont(parent));
+ GridData gd = EclipseUiUtils.fillWidth();
+ gd.horizontalIndent = 5;
+ gd.verticalIndent = 5;
+ titleLbl.setLayoutData(gd);
+ return titleLbl;
+ }
+
+ private class MySelectionChangedListener implements ISelectionChangedListener {
+ @Override
+ public void selectionChanged(SelectionChangedEvent event) {
+ IStructuredSelection selection = (IStructuredSelection) bookmarksViewer.getSelection();
+ if (selection.isEmpty())
+ return;
+ else {
+ Path newSelected = (Path) selection.getFirstElement();
+ if (newSelected.equals(currSelected))
+ return;
+ currSelected = newSelected;
+ directoryDisplayViewer.setInput(currSelected, "*");
+ }
+ }
+ }
+
+ private void populateDisplay(final Composite parent) {
+ parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
+ directoryDisplayViewer = new FsTableViewer(parent, SWT.MULTI);
+ List<ColumnDefinition> colDefs = new ArrayList<>();
+ colDefs.add(new ColumnDefinition(new FileIconNameLabelProvider(), "Name", 200));
+ colDefs.add(new ColumnDefinition(new NioFileLabelProvider(FsUiConstants.PROPERTY_SIZE), "Size", 100));
+ colDefs.add(new ColumnDefinition(new NioFileLabelProvider(FsUiConstants.PROPERTY_TYPE), "Type", 250));
+ colDefs.add(new ColumnDefinition(new NioFileLabelProvider(FsUiConstants.PROPERTY_LAST_MODIFIED),
+ "Last modified", 200));
+ Table table = directoryDisplayViewer.configureDefaultTable(colDefs);
+ table.setLayoutData(EclipseUiUtils.fillAll());
+
+ table.addKeyListener(new KeyListener() {
+ private static final long serialVersionUID = -8083424284436715709L;
+
+ @Override
+ public void keyReleased(KeyEvent e) {
+ }
+
+ @Override
+ public void keyPressed(KeyEvent e) {
+ log.debug("Key event received: " + e.keyCode);
+ IStructuredSelection selection = (IStructuredSelection) directoryDisplayViewer.getSelection();
+ Path selected = null;
+ if (!selection.isEmpty())
+ selected = ((Path) selection.getFirstElement());
+ if (e.keyCode == SWT.CR) {
+ if (!Files.isDirectory(selected))
+ return;
+ if (selected != null) {
+ currSelected = selected;
+ directoryDisplayViewer.setInput(currSelected, "*");
+ }
+ } else if (e.keyCode == SWT.BS) {
+ currSelected = currSelected.getParent();
+ directoryDisplayViewer.setInput(currSelected, "*");
+ directoryDisplayViewer.getTable().setFocus();
+ }
+ }
+ });
+
+// directoryDisplayViewer.addDoubleClickListener(new IDoubleClickListener() {
+// @Override
+// public void doubleClick(DoubleClickEvent event) {
+// IStructuredSelection selection = (IStructuredSelection) directoryDisplayViewer.getSelection();
+// Path selected = null;
+// if (!selection.isEmpty()) {
+// Object obj = selection.getFirstElement();
+// if (obj instanceof Path)
+// selected = (Path) obj;
+// else if (obj instanceof ParentDir)
+// selected = ((ParentDir) obj).getPath();
+// }
+// if (selected != null) {
+// if (!Files.isDirectory(selected))
+// return;
+// currSelected = selected;
+// directoryDisplayViewer.setInput(currSelected, "*");
+// }
+// }
+// });
+
+ directoryDisplayViewer.addDoubleClickListener(new IDoubleClickListener() {
+ @Override
+ public void doubleClick(DoubleClickEvent event) {
+ IStructuredSelection selection = (IStructuredSelection) directoryDisplayViewer.getSelection();
+ Path selected = null;
+ if (!selection.isEmpty()) {
+ Object obj = selection.getFirstElement();
+ if (obj instanceof Path)
+ selected = (Path) obj;
+ else if (obj instanceof ParentDir)
+ selected = ((ParentDir) obj).getPath();
+ }
+ if (selected != null) {
+ if (!Files.isDirectory(selected))
+ return;
+ currSelected = selected;
+ directoryDisplayViewer.setInput(currSelected, "*");
+ }
+ }
+ });
+ }
+}
--- /dev/null
+package org.argeo.eclipse.ui.fs;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.eclipse.ui.ColumnDefinition;
+import org.argeo.eclipse.ui.EclipseUiUtils;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+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.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.Tree;
+
+/** A simple Java 7 nio files browser with a tree */
+public class SimpleFsTreeBrowser extends Composite {
+ private final static Log log = LogFactory.getLog(SimpleFsTreeBrowser.class);
+ private static final long serialVersionUID = -40347919096946585L;
+
+ private Path currSelected;
+ private FsTreeViewer treeViewer;
+ private FsTableViewer directoryDisplayViewer;
+
+ public SimpleFsTreeBrowser(Composite parent, int style) {
+ super(parent, style);
+ createContent(this);
+ // parent.layout(true, true);
+ }
+
+ private void createContent(Composite parent) {
+ parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
+ SashForm form = new SashForm(parent, SWT.HORIZONTAL);
+ Composite child1 = new Composite(form, SWT.NONE);
+ populateTree(child1);
+ Composite child2 = new Composite(form, SWT.BORDER);
+ populateDisplay(child2);
+ form.setLayoutData(EclipseUiUtils.fillAll());
+ form.setWeights(new int[] { 1, 3 });
+ }
+
+ public void setInput(Path... paths) {
+ treeViewer.setPathsInput(paths);
+ treeViewer.getControl().getParent().layout(true, true);
+ }
+
+ private void populateTree(final Composite parent) {
+ // GridLayout layout = EclipseUiUtils.noSpaceGridLayout();
+ // layout.verticalSpacing = 5;
+ parent.setLayout(new GridLayout());
+
+ ISelectionChangedListener selList = new MySelectionChangedListener();
+
+ treeViewer = new FsTreeViewer(parent, SWT.MULTI);
+ Tree tree = treeViewer.configureDefaultSingleColumnTable(500);
+ GridData gd = EclipseUiUtils.fillAll();
+ // gd.horizontalIndent = 10;
+ tree.setLayoutData(gd);
+ treeViewer.addSelectionChangedListener(selList);
+ }
+
+ private class MySelectionChangedListener implements ISelectionChangedListener {
+ @Override
+ public void selectionChanged(SelectionChangedEvent event) {
+ IStructuredSelection selection = (IStructuredSelection) treeViewer.getSelection();
+ if (selection.isEmpty())
+ return;
+ else {
+ Path newSelected = (Path) selection.getFirstElement();
+ if (newSelected.equals(currSelected))
+ return;
+ currSelected = newSelected;
+ if (Files.isDirectory(currSelected))
+ directoryDisplayViewer.setInput(currSelected, "*");
+ }
+ }
+ }
+
+ private void populateDisplay(final Composite parent) {
+ parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
+ directoryDisplayViewer = new FsTableViewer(parent, SWT.MULTI);
+ List<ColumnDefinition> colDefs = new ArrayList<>();
+ colDefs.add(new ColumnDefinition(new FileIconNameLabelProvider(), "Name", 200, 200));
+ colDefs.add(new ColumnDefinition(new NioFileLabelProvider(FsUiConstants.PROPERTY_SIZE), "Size", 100, 100));
+ colDefs.add(new ColumnDefinition(new NioFileLabelProvider(FsUiConstants.PROPERTY_TYPE), "Type", 300, 300));
+ colDefs.add(new ColumnDefinition(new NioFileLabelProvider(FsUiConstants.PROPERTY_LAST_MODIFIED),
+ "Last modified", 100, 100));
+ Table table = directoryDisplayViewer.configureDefaultTable(colDefs);
+ table.setLayoutData(EclipseUiUtils.fillAll());
+
+ table.addKeyListener(new KeyListener() {
+ private static final long serialVersionUID = -8083424284436715709L;
+
+ @Override
+ public void keyReleased(KeyEvent e) {
+ }
+
+ @Override
+ public void keyPressed(KeyEvent e) {
+ log.debug("Key event received: " + e.keyCode);
+ IStructuredSelection selection = (IStructuredSelection) directoryDisplayViewer.getSelection();
+ Path selected = null;
+ if (!selection.isEmpty())
+ selected = ((Path) selection.getFirstElement());
+ if (e.keyCode == SWT.CR) {
+ if (!Files.isDirectory(selected))
+ return;
+ if (selected != null) {
+ currSelected = selected;
+ directoryDisplayViewer.setInput(currSelected, "*");
+ }
+ } else if (e.keyCode == SWT.BS) {
+ currSelected = currSelected.getParent();
+ directoryDisplayViewer.setInput(currSelected, "*");
+ directoryDisplayViewer.getTable().setFocus();
+ }
+ }
+ });
+ }
+}
--- /dev/null
+/** Generic SWT/JFace file system utilities. */
+package org.argeo.eclipse.ui.fs;
\ No newline at end of file
--- /dev/null
+/** Generic SWT/JFace utilities. */
+package org.argeo.eclipse.ui;
\ No newline at end of file
--- /dev/null
+package org.argeo.eclipse.ui.parts;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.argeo.eclipse.ui.ColumnDefinition;
+import org.argeo.eclipse.ui.EclipseUiException;
+import org.argeo.eclipse.ui.EclipseUiUtils;
+import org.argeo.eclipse.ui.util.ViewerUtils;
+import org.eclipse.jface.layout.TableColumnLayout;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+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.Composite;
+import org.eclipse.swt.widgets.Link;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.Text;
+import org.osgi.service.useradmin.User;
+
+/**
+ * Generic composite that display a filter and a table viewer to display users
+ * (can also be groups)
+ *
+ * Warning: this class does not extends <code>TableViewer</code>. Use the
+ * getTableViewer method to access it.
+ *
+ */
+public abstract class LdifUsersTable extends Composite {
+ private static final long serialVersionUID = -7385959046279360420L;
+
+ // Context
+ // private UserAdmin userAdmin;
+
+ // Configuration
+ private List<ColumnDefinition> columnDefs = new ArrayList<ColumnDefinition>();
+ private boolean hasFilter;
+ private boolean preventTableLayout = false;
+ private boolean hasSelectionColumn;
+ private int tableStyle;
+
+ // Local UI Objects
+ private TableViewer usersViewer;
+ private Text filterTxt;
+
+ /* EXPOSED METHODS */
+
+ /**
+ * @param parent
+ * @param style
+ */
+ public LdifUsersTable(Composite parent, int style) {
+ super(parent, SWT.NO_FOCUS);
+ this.tableStyle = style;
+ }
+
+ // TODO workaround the bug of the table layout in the Form
+ public LdifUsersTable(Composite parent, int style, boolean preventTableLayout) {
+ super(parent, SWT.NO_FOCUS);
+ this.tableStyle = style;
+ this.preventTableLayout = preventTableLayout;
+ }
+
+ /** This must be called before the call to populate method */
+ public void setColumnDefinitions(List<ColumnDefinition> columnDefinitions) {
+ this.columnDefs = columnDefinitions;
+ }
+
+ /**
+ *
+ * @param addFilter
+ * choose to add a field to filter results or not
+ * @param addSelection
+ * choose to add a column to select some of the displayed results or
+ * not
+ */
+ public void populate(boolean addFilter, boolean addSelection) {
+ // initialization
+ Composite parent = this;
+ hasFilter = addFilter;
+ hasSelectionColumn = addSelection;
+
+ // Main Layout
+ GridLayout layout = EclipseUiUtils.noSpaceGridLayout();
+ layout.verticalSpacing = 5;
+ this.setLayout(layout);
+ if (hasFilter)
+ createFilterPart(parent);
+
+ Composite tableComp = new Composite(parent, SWT.NO_FOCUS);
+ tableComp.setLayoutData(EclipseUiUtils.fillAll());
+ usersViewer = createTableViewer(tableComp);
+ usersViewer.setContentProvider(new UsersContentProvider());
+ }
+
+ /**
+ *
+ * @param showMore
+ * display static filters on creation
+ * @param addSelection
+ * choose to add a column to select some of the displayed results or
+ * not
+ */
+ public void populateWithStaticFilters(boolean showMore, boolean addSelection) {
+ // initialization
+ Composite parent = this;
+ hasFilter = true;
+ hasSelectionColumn = addSelection;
+
+ // Main Layout
+ GridLayout layout = EclipseUiUtils.noSpaceGridLayout();
+ layout.verticalSpacing = 5;
+ this.setLayout(layout);
+ createStaticFilterPart(parent, showMore);
+
+ Composite tableComp = new Composite(parent, SWT.NO_FOCUS);
+ tableComp.setLayoutData(EclipseUiUtils.fillAll());
+ usersViewer = createTableViewer(tableComp);
+ usersViewer.setContentProvider(new UsersContentProvider());
+ }
+
+ /** Enable access to the selected users or groups */
+ public List<User> getSelectedUsers() {
+ if (hasSelectionColumn) {
+ Object[] elements = ((CheckboxTableViewer) usersViewer).getCheckedElements();
+
+ List<User> result = new ArrayList<User>();
+ for (Object obj : elements) {
+ result.add((User) obj);
+ }
+ return result;
+ } else
+ throw new EclipseUiException(
+ "Unvalid request: no selection column " + "has been created for the current table");
+ }
+
+ /** Returns the User table viewer, typically to add doubleclick listener */
+ public TableViewer getTableViewer() {
+ return usersViewer;
+ }
+
+ /**
+ * Force the refresh of the underlying table using the current filter string if
+ * relevant
+ */
+ public void refresh() {
+ String filter = hasFilter ? filterTxt.getText().trim() : null;
+ if ("".equals(filter))
+ filter = null;
+ refreshFilteredList(filter);
+ }
+
+ /** Effective repository request: caller must implement this method */
+ abstract protected List<User> listFilteredElements(String filter);
+
+ // protected List<User> listFilteredElements(String filter) {
+ // List<User> users = new ArrayList<User>();
+ // try {
+ // Role[] roles = userAdmin.getRoles(filter);
+ // // Display all users and groups
+ // for (Role role : roles)
+ // users.add((User) role);
+ // } catch (InvalidSyntaxException e) {
+ // throw new EclipseUiException("Unable to get roles with filter: "
+ // + filter, e);
+ // }
+ // return users;
+ // }
+
+ /* GENERIC COMPOSITE METHODS */
+ @Override
+ public boolean setFocus() {
+ if (hasFilter)
+ return filterTxt.setFocus();
+ else
+ return usersViewer.getTable().setFocus();
+ }
+
+ @Override
+ public void dispose() {
+ super.dispose();
+ }
+
+ /* LOCAL CLASSES AND METHODS */
+ // Will be usefull to rather use a virtual table viewer
+ private void refreshFilteredList(String filter) {
+ List<User> users = listFilteredElements(filter);
+ usersViewer.setInput(users.toArray());
+ }
+
+ private class UsersContentProvider implements IStructuredContentProvider {
+ private static final long serialVersionUID = 1L;
+
+ public Object[] getElements(Object inputElement) {
+ return (Object[]) inputElement;
+ }
+
+ public void dispose() {
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+ }
+
+ /* MANAGE FILTER */
+ private void createFilterPart(Composite parent) {
+ // Text Area for the filter
+ filterTxt = new Text(parent, SWT.BORDER | SWT.SEARCH | SWT.ICON_SEARCH | SWT.ICON_CANCEL);
+ filterTxt.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));
+ filterTxt.addModifyListener(new ModifyListener() {
+ private static final long serialVersionUID = 1L;
+
+ public void modifyText(ModifyEvent event) {
+ refreshFilteredList(filterTxt.getText());
+ }
+ });
+ }
+
+ private void createStaticFilterPart(Composite parent, boolean showMore) {
+ Composite filterComp = new Composite(parent, SWT.NO_FOCUS);
+ filterComp.setLayout(new GridLayout(2, false));
+ filterComp.setLayoutData(EclipseUiUtils.fillWidth());
+ // generic search
+ filterTxt = new Text(filterComp, SWT.BORDER | SWT.SEARCH | SWT.ICON_SEARCH | SWT.ICON_CANCEL);
+ filterTxt.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));
+ // filterTxt.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL |
+ // GridData.HORIZONTAL_ALIGN_FILL));
+ filterTxt.addModifyListener(new ModifyListener() {
+ private static final long serialVersionUID = 1L;
+
+ public void modifyText(ModifyEvent event) {
+ refreshFilteredList(filterTxt.getText());
+ }
+ });
+
+ // add static filter abilities
+ Link moreLk = new Link(filterComp, SWT.NONE);
+ Composite staticFilterCmp = new Composite(filterComp, SWT.NO_FOCUS);
+ staticFilterCmp.setLayoutData(EclipseUiUtils.fillWidth(2));
+ populateStaticFilters(staticFilterCmp);
+
+ MoreLinkListener listener = new MoreLinkListener(moreLk, staticFilterCmp, showMore);
+ // initialise the layout
+ listener.refresh();
+ moreLk.addSelectionListener(listener);
+ }
+
+ /** Overwrite to add static filters */
+ protected void populateStaticFilters(Composite staticFilterCmp) {
+ }
+
+ // private void addMoreSL(final Link more) {
+ // more.addSelectionListener( }
+
+ private class MoreLinkListener extends SelectionAdapter {
+ private static final long serialVersionUID = -524987616510893463L;
+ private boolean isShown;
+ private final Composite staticFilterCmp;
+ private final Link moreLk;
+
+ public MoreLinkListener(Link moreLk, Composite staticFilterCmp, boolean isShown) {
+ this.moreLk = moreLk;
+ this.staticFilterCmp = staticFilterCmp;
+ this.isShown = isShown;
+ }
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ isShown = !isShown;
+ refresh();
+ }
+
+ public void refresh() {
+ GridData gd = (GridData) staticFilterCmp.getLayoutData();
+ if (isShown) {
+ moreLk.setText("<a> Less... </a>");
+ gd.heightHint = SWT.DEFAULT;
+ } else {
+ moreLk.setText("<a> More... </a>");
+ gd.heightHint = 0;
+ }
+ forceLayout();
+ }
+ }
+
+ private void forceLayout() {
+ LdifUsersTable.this.getParent().layout(true, true);
+ }
+
+ private TableViewer createTableViewer(final Composite parent) {
+
+ int style = tableStyle | SWT.H_SCROLL | SWT.V_SCROLL;
+ if (hasSelectionColumn)
+ style = style | SWT.CHECK;
+ Table table = new Table(parent, style);
+ TableColumnLayout layout = new TableColumnLayout();
+
+ // TODO the table layout does not works with the scrolled form
+
+ if (preventTableLayout) {
+ parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
+ table.setLayoutData(EclipseUiUtils.fillAll());
+ } else
+ parent.setLayout(layout);
+
+ TableViewer viewer;
+ if (hasSelectionColumn)
+ viewer = new CheckboxTableViewer(table);
+ else
+ viewer = new TableViewer(table);
+ table.setLinesVisible(true);
+ table.setHeaderVisible(true);
+
+ TableViewerColumn column;
+ // int offset = 0;
+ if (hasSelectionColumn) {
+ // offset = 1;
+ column = ViewerUtils.createTableViewerColumn(viewer, "", SWT.NONE, 25);
+ column.setLabelProvider(new ColumnLabelProvider() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public String getText(Object element) {
+ return null;
+ }
+ });
+ layout.setColumnData(column.getColumn(), new ColumnWeightData(25, 25, false));
+
+ SelectionAdapter selectionAdapter = new SelectionAdapter() {
+ private static final long serialVersionUID = 1L;
+
+ boolean allSelected = false;
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ allSelected = !allSelected;
+ ((CheckboxTableViewer) usersViewer).setAllChecked(allSelected);
+ }
+ };
+ column.getColumn().addSelectionListener(selectionAdapter);
+ }
+
+ // NodeViewerComparator comparator = new NodeViewerComparator();
+ // TODO enable the sort by click on the header
+ // int i = offset;
+ for (ColumnDefinition colDef : columnDefs)
+ createTableColumn(viewer, layout, colDef);
+
+ // column = ViewerUtils.createTableViewerColumn(viewer,
+ // colDef.getHeaderLabel(), SWT.NONE, colDef.getColumnSize());
+ // column.setLabelProvider(new CLProvider(colDef.getPropertyName()));
+ // column.getColumn().addSelectionListener(
+ // JcrUiUtils.getNodeSelectionAdapter(i,
+ // colDef.getPropertyType(), colDef.getPropertyName(),
+ // comparator, viewer));
+ // i++;
+ // }
+
+ // IMPORTANT: initialize comparator before setting it
+ // JcrColumnDefinition firstCol = colDefs.get(0);
+ // comparator.setColumn(firstCol.getPropertyType(),
+ // firstCol.getPropertyName());
+ // viewer.setComparator(comparator);
+
+ return viewer;
+ }
+
+ /** Default creation of a column for a user table */
+ private TableViewerColumn createTableColumn(TableViewer tableViewer, TableColumnLayout layout,
+ ColumnDefinition columnDef) {
+
+ boolean resizable = true;
+ TableViewerColumn tvc = new TableViewerColumn(tableViewer, SWT.NONE);
+ TableColumn column = tvc.getColumn();
+
+ column.setText(columnDef.getLabel());
+ column.setWidth(columnDef.getMinWidth());
+ column.setResizable(resizable);
+
+ ColumnLabelProvider lp = columnDef.getLabelProvider();
+ // add a reference to the display to enable font management
+ // if (lp instanceof UserAdminAbstractLP)
+ // ((UserAdminAbstractLP) lp).setDisplay(tableViewer.getTable()
+ // .getDisplay());
+ tvc.setLabelProvider(lp);
+
+ layout.setColumnData(column, new ColumnWeightData(columnDef.getWeight(), columnDef.getMinWidth(), resizable));
+
+ return tvc;
+ }
+}
--- /dev/null
+/** Generic SWT/JFace composites. */
+package org.argeo.eclipse.ui.parts;
\ No newline at end of file
--- /dev/null
+package org.argeo.eclipse.ui.util;
+
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.TreeViewerColumn;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TreeColumn;
+
+/**
+ * Centralise useful methods to manage JFace Table, Tree and TreeColumn viewers.
+ */
+public class ViewerUtils {
+
+ /**
+ * Creates a basic column for the given table. For the time being, we do not
+ * support movable columns.
+ */
+ public static TableColumn createColumn(Table parent, String name, int style, int width) {
+ TableColumn result = new TableColumn(parent, style);
+ result.setText(name);
+ result.setWidth(width);
+ result.setResizable(true);
+ return result;
+ }
+
+ /**
+ * Creates a TableViewerColumn for the given viewer. For the time being, we do
+ * not support movable columns.
+ */
+ public static TableViewerColumn createTableViewerColumn(TableViewer parent, String name, int style, int width) {
+ TableViewerColumn tvc = new TableViewerColumn(parent, style);
+ TableColumn column = tvc.getColumn();
+ column.setText(name);
+ column.setWidth(width);
+ column.setResizable(true);
+ return tvc;
+ }
+
+ // public static TableViewerColumn createTableViewerColumn(TableViewer parent,
+ // Localized name, int style, int width) {
+ // return createTableViewerColumn(parent, name.lead(), style, width);
+ // }
+
+ /**
+ * Creates a TreeViewerColumn for the given viewer. For the time being, we do
+ * not support movable columns.
+ */
+ public static TreeViewerColumn createTreeViewerColumn(TreeViewer parent, String name, int style, int width) {
+ TreeViewerColumn tvc = new TreeViewerColumn(parent, style);
+ TreeColumn column = tvc.getColumn();
+ column.setText(name);
+ column.setWidth(width);
+ column.setResizable(true);
+ return tvc;
+ }
+}
--- /dev/null
+/** Generic SWT/JFace JCR helpers. */
+package org.argeo.eclipse.ui.util;
\ No newline at end of file
javax.jcr.nodetype,\
javax.jcr.security,\
org.eclipse.swt.graphics,\
+org.eclipse.jetty.util.component;resolution:=optional,\
+org.eclipse.jetty.http;resolution:=optional,\
+org.eclipse.jetty.io;resolution:=optional,\
+org.eclipse.jetty.security;resolution:=optional,\
+org.eclipse.jetty.server.handler;resolution:=optional,\
+org.eclipse.jetty.*;resolution:=optional,\
*
+
<!-- Specific -->
<dependency>
<groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.eclipse.ui.rap</artifactId>
+ <artifactId>org.argeo.swt.specific.rap</artifactId>
<version>2.3-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
- <!-- Theme -->
- <dependency>
- <groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.cms.ui.theme</artifactId>
- <version>2.3-SNAPSHOT</version>
- </dependency>
-
<!-- UI -->
<dependency>
<groupId>org.argeo.tp.rap.e4</groupId>
--- /dev/null
+package org.argeo.eclipse.ui.jetty;
+
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.servlet.DefaultServlet;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.util.thread.QueuedThreadPool;
+import org.eclipse.rap.rwt.application.AbstractEntryPoint;
+import org.eclipse.rap.rwt.application.ApplicationRunner;
+import org.eclipse.rap.rwt.engine.RWTServlet;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+
+/** A minimal RWT runner based on embedded Jetty. */
+public class RwtRunner {
+
+ private final Server server;
+ private final ServerConnector serverConnector;
+ private Path tempDir;
+
+ public RwtRunner() {
+ server = new Server(new QueuedThreadPool(10, 1));
+ serverConnector = new ServerConnector(server);
+ serverConnector.setPort(0);
+ server.setConnectors(new Connector[] { serverConnector });
+ }
+
+ protected Control createUi(Composite parent, Object context) {
+ return new Label(parent, SWT.NONE);
+ }
+
+ public void init() {
+ ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
+ context.setContextPath("/");
+ server.setHandler(context);
+
+ String entryPoint = "app";
+
+ // rwt-resources requires a file system
+ try {
+ tempDir = Files.createTempDirectory("argeo-rwtRunner");
+ context.setBaseResource(Resource.newResource(tempDir.resolve("www").toString()));
+ } catch (IOException e) {
+ throw new IllegalStateException("Cannot create temporary directory", e);
+ }
+ context.addEventListener(new ServletContextListener() {
+ ApplicationRunner applicationRunner;
+
+ @Override
+ public void contextInitialized(ServletContextEvent sce) {
+ applicationRunner = new ApplicationRunner(
+ (application) -> application.addEntryPoint("/" + entryPoint, () -> new AbstractEntryPoint() {
+ private static final long serialVersionUID = 5678385921969090733L;
+
+ @Override
+ protected void createContents(Composite parent) {
+ createUi(parent, null);
+ }
+ }, null), sce.getServletContext());
+ applicationRunner.start();
+ }
+
+ @Override
+ public void contextDestroyed(ServletContextEvent sce) {
+ applicationRunner.stop();
+ }
+ });
+
+ context.addServlet(new ServletHolder(new RWTServlet()), "/" + entryPoint);
+
+ // Required to serve rwt-resources. It is important that this is last.
+ ServletHolder holderPwd = new ServletHolder("default", DefaultServlet.class);
+ context.addServlet(holderPwd, "/");
+
+ try {
+ server.start();
+ } catch (Exception e) {
+ throw new IllegalStateException("Cannot start Jetty server", e);
+ }
+ }
+
+ public void destroy() {
+ try {
+ serverConnector.close();
+ server.stop();
+ // TODO delete temp dir
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public Integer getEffectivePort() {
+ return serverConnector.getLocalPort();
+ }
+
+ public void waitFor() throws InterruptedException {
+ server.join();
+ }
+
+ public static void main(String[] args) throws Exception {
+ RwtRunner rwtRunner = new RwtRunner() {
+
+ @Override
+ protected Control createUi(Composite parent, Object context) {
+ Label label = new Label(parent, SWT.NONE);
+ label.setText("Hello world!");
+ return label;
+ }
+ };
+ rwtRunner.init();
+ Runtime.getRuntime().addShutdownHook(new Thread(() -> rwtRunner.destroy(), "Jetty shutdown"));
+
+ long jvmUptime = ManagementFactory.getRuntimeMXBean().getUptime();
+ System.out.println("App available in " + jvmUptime + " ms, on port " + rwtRunner.getEffectivePort());
+
+ // open browser in app mode
+ Thread.sleep(2000);// wait for RWT to be ready
+ Runtime.getRuntime().exec("google-chrome --app=http://localhost:" + rwtRunner.getEffectivePort() + "/app");
+
+ rwtRunner.waitFor();
+ }
+}
+++ /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
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>org.argeo.cms.ui.theme</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
-Bundle-ActivationPolicy: lazy
+++ /dev/null
-source.. = src/
-output.. = bin/
-bin.includes = META-INF/,\
- .
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<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.commons</groupId>
- <artifactId>argeo-commons</artifactId>
- <version>2.3-SNAPSHOT</version>
- <relativePath>..</relativePath>
- </parent>
- <artifactId>org.argeo.cms.ui.theme</artifactId>
- <name>CMS UI Theme</name>
- <packaging>jar</packaging>
- <dependencies>
- <!-- UI -->
- <dependency>
- <groupId>org.argeo.tp.rap.e4</groupId>
- <artifactId>org.eclipse.rap.rwt</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.rap.e4</groupId>
- <artifactId>org.eclipse.rap.jface</artifactId>
- <scope>provided</scope>
- </dependency>
-
- </dependencies>
-</project>
\ No newline at end of file
+++ /dev/null
-Composite.qa {
- background-color: gray;
- color: white;
-}
-
-Button[PUSH].qa {
- color: white;
- background-color: gray;
- padding: 0px;
- spacing: 0px;
- border: none;
-}
-
-Composite.support {
- background-color: red;
-}
-
-Label.support {
- background-color: red;
- color: white;
-}
+++ /dev/null
-package org.argeo.cms.ui.theme;
-
-import java.net.URL;
-
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Display;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkUtil;
-
-public class CmsImages {
- private static BundleContext themeBc = FrameworkUtil.getBundle(CmsImages.class).getBundleContext();
-
- final public static String ICONS_BASE = "icons/";
- final public static String TYPES_BASE = ICONS_BASE + "types/";
- final public static String ACTIONS_BASE = ICONS_BASE + "actions/";
-
- public static Image createIcon(String name) {
- return createImg(CmsImages.ICONS_BASE + name);
- }
-
- public static Image createAction(String name) {
- return createImg(CmsImages.ACTIONS_BASE + name);
- }
-
- public static Image createType(String name) {
- return createImg(CmsImages.TYPES_BASE + name);
- }
-
- public static Image createImg(String name) {
- return CmsImages.createDesc(name).createImage(Display.getDefault());
- }
-
- public static ImageDescriptor createDesc(String name) {
- return createDesc(themeBc, name);
- }
-
- public static ImageDescriptor createDesc(BundleContext bc, String name) {
- URL url = bc.getBundle().getResource(name);
- if (url == null)
- return ImageDescriptor.getMissingImageDescriptor();
- return ImageDescriptor.createFromURL(url);
- }
-
- public static Image createImg(BundleContext bc, String name) {
- return createDesc(bc, name).createImage(Display.getDefault());
- }
-
-}
+++ /dev/null
-/** Argeo CMS core theme images. */
-package org.argeo.cms.ui.theme;
\ No newline at end of file
</dependency>
<dependency>
<groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.cms.jcr</artifactId>
+ <artifactId>org.argeo.cms.swt</artifactId>
<version>2.3-SNAPSHOT</version>
</dependency>
- <!-- Specific -->
<dependency>
<groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.eclipse.ui.rap</artifactId>
+ <artifactId>org.argeo.cms.jcr</artifactId>
<version>2.3-SNAPSHOT</version>
- <scope>provided</scope>
</dependency>
-
- <!-- Theme -->
+ <!-- Specific -->
<dependency>
<groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.cms.ui.theme</artifactId>
+ <artifactId>org.argeo.swt.specific.rap</artifactId>
<version>2.3-SNAPSHOT</version>
+ <scope>provided</scope>
</dependency>
<!-- UI -->
<artifactId>org.argeo.enterprise</artifactId>
<version>2.3-SNAPSHOT</version>
</dependency>
- <dependency>
- <groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.core</artifactId>
- <version>2.3-SNAPSHOT</version>
- </dependency>
+<!-- <dependency> -->
+<!-- <groupId>org.argeo.commons</groupId> -->
+<!-- <artifactId>org.argeo.core</artifactId> -->
+<!-- <version>2.3-SNAPSHOT</version> -->
+<!-- </dependency> -->
<!-- <dependency> -->
<!-- <groupId>org.argeo.commons</groupId> -->
<!-- <artifactId>org.argeo.maintenance</artifactId> -->
+++ /dev/null
-package org.argeo.cms.cli;
-
-import org.apache.commons.cli.Option;
-import org.argeo.cli.CommandsCli;
-import org.argeo.cli.fs.FsCommands;
-import org.argeo.cli.posix.PosixCommands;
-
-/** Argeo command line tools. */
-public class ArgeoCli extends CommandsCli {
-
- public ArgeoCli(String commandName) {
- super(commandName);
- // Common options
- options.addOption(Option.builder("v").hasArg().argName("verbose").desc("verbosity").build());
- options.addOption(
- Option.builder("D").hasArgs().argName("property=value").desc("use value for given property").build());
-
- addCommandsCli(new PosixCommands("posix"));
- addCommandsCli(new FsCommands("fs"));
-// addCommandsCli(new JcrCommands("jcr"));
- }
-
- @Override
- public String getDescription() {
- return "Argeo command line utilities";
- }
-
- public static void main(String[] args) {
- mainImpl(new ArgeoCli("argeo"), args);
- }
-
-}
+++ /dev/null
-/** Argeo command line interface. */
-package org.argeo.cms.cli;
\ 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="src" path="ext/test"/>
- <classpathentry kind="output" path="bin"/>
-</classpath>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>org.argeo.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>
- </buildSpec>
- <natures>
- <nature>org.eclipse.pde.PluginNature</nature>
- <nature>org.eclipse.jdt.core.javanature</nature>
- </natures>
-</projectDescription>
+++ /dev/null
-/MANIFEST.MF
+++ /dev/null
-source.. = src/,\
- ext/test/
-output.. = bin/
-bin.includes = META-INF/,\
- .
-
\ No newline at end of file
+++ /dev/null
-log4j.rootLogger=WARN, console
-
-## Levels
-log4j.logger.org.argeo=DEBUG
-log4j.logger.org.apache.jackrabbit=OFF
-
-## Appenders
-# console is set to be a ConsoleAppender.
-log4j.appender.console=org.apache.log4j.ConsoleAppender
-
-# console uses PatternLayout.
-log4j.appender.console.layout=org.apache.log4j.PatternLayout
-#log4j.appender.console.layout.ConversionPattern= %-5p %d{ISO8601} %m - %c%n
-log4j.appender.console.layout.ConversionPattern=%m%n
+++ /dev/null
-package org.argeo.fs;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-
-/** {@link FsUtils} tests. */
-public class FsUtilsTest {
- final static String FILE00 = "file00";
- final static String FILE01 = "file01";
- final static String SUB_DIR = "subDir";
-
- public void testDelete() throws IOException {
- Path dir = createDir00();
- assert Files.exists(dir);
- FsUtils.delete(dir);
- assert !Files.exists(dir);
- }
-
- public void testSync() throws IOException {
- Path source = createDir00();
- Path target = Files.createTempDirectory(getClass().getName());
- FsUtils.sync(source, target);
- assert Files.exists(target.resolve(FILE00));
- assert Files.exists(target.resolve(SUB_DIR));
- assert Files.exists(target.resolve(SUB_DIR + File.separator + FILE01));
- FsUtils.delete(source.resolve(SUB_DIR));
- FsUtils.sync(source, target, true);
- assert Files.exists(target.resolve(FILE00));
- assert !Files.exists(target.resolve(SUB_DIR));
- assert !Files.exists(target.resolve(SUB_DIR + File.separator + FILE01));
-
- // clean up
- FsUtils.delete(source);
- FsUtils.delete(target);
-
- }
-
- Path createDir00() throws IOException {
- Path base = Files.createTempDirectory(getClass().getName());
- base.toFile().deleteOnExit();
- Files.createFile(base.resolve(FILE00)).toFile().deleteOnExit();
- Path subDir = Files.createDirectories(base.resolve(SUB_DIR));
- subDir.toFile().deleteOnExit();
- Files.createFile(subDir.resolve(FILE01)).toFile().deleteOnExit();
- return base;
- }
-}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<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.commons</groupId>
- <artifactId>argeo-commons</artifactId>
- <version>2.3-SNAPSHOT</version>
- <relativePath>..</relativePath>
- </parent>
- <artifactId>org.argeo.core</artifactId>
- <name>Commons Third Parties Utilities</name>
- <dependencies>
- <dependency>
- <groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.enterprise</artifactId>
- <version>2.3-SNAPSHOT</version>
- </dependency>
-<!-- <dependency> -->
-<!-- <groupId>org.argeo.commons</groupId> -->
-<!-- <artifactId>org.argeo.jcr</artifactId> -->
-<!-- <version>2.3-SNAPSHOT</version> -->
-<!-- </dependency> -->
- </dependencies>
-</project>
\ No newline at end of file
+++ /dev/null
-package org.argeo.cli;
-
-public class CommandArgsException extends IllegalArgumentException {
- private static final long serialVersionUID = -7271050747105253935L;
- private String commandName;
- private volatile CommandsCli commandsCli;
-
- public CommandArgsException(Exception cause) {
- super(cause.getMessage(), cause);
- }
-
- public CommandArgsException(String message) {
- super(message);
- }
-
- public String getCommandName() {
- return commandName;
- }
-
- public void setCommandName(String commandName) {
- this.commandName = commandName;
- }
-
- public CommandsCli getCommandsCli() {
- return commandsCli;
- }
-
- public void setCommandsCli(CommandsCli commandsCli) {
- this.commandsCli = commandsCli;
- }
-
-}
+++ /dev/null
-package org.argeo.cli;
-
-import java.util.List;
-
-/** {@link RuntimeException} referring during a command run. */
-public class CommandRuntimeException extends RuntimeException {
- private static final long serialVersionUID = 5595999301269377128L;
-
- private final DescribedCommand<?> command;
- private final List<String> arguments;
-
- public CommandRuntimeException(Throwable e, DescribedCommand<?> command, List<String> arguments) {
- this(null, e, command, arguments);
- }
-
- public CommandRuntimeException(String message, DescribedCommand<?> command, List<String> arguments) {
- this(message, null, command, arguments);
- }
-
- public CommandRuntimeException(String message, Throwable e, DescribedCommand<?> command, List<String> arguments) {
- super(message == null ? "(" + command.getClass().getName() + " " + arguments.toString() + ")"
- : message + " (" + command.getClass().getName() + " " + arguments.toString() + ")", e);
- this.command = command;
- this.arguments = arguments;
- }
-
- public DescribedCommand<?> getCommand() {
- return command;
- }
-
- public List<String> getArguments() {
- return arguments;
- }
-
-}
+++ /dev/null
-package org.argeo.cli;
-
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.function.Function;
-
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.CommandLineParser;
-import org.apache.commons.cli.DefaultParser;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-
-/** Base class for a CLI managing sub commands. */
-public abstract class CommandsCli implements DescribedCommand<Object> {
- public final static String HELP = "help";
-
- private final String commandName;
- private Map<String, Function<List<String>, ?>> commands = new TreeMap<>();
-
- protected final Options options = new Options();
-
- public CommandsCli(String commandName) {
- this.commandName = commandName;
- }
-
- @Override
- public Object apply(List<String> args) {
- String cmd = null;
- List<String> newArgs = new ArrayList<>();
- try {
- CommandLineParser clParser = new DefaultParser();
- CommandLine commonCl = clParser.parse(getOptions(), args.toArray(new String[args.size()]), true);
- List<String> leftOvers = commonCl.getArgList();
- for (String arg : leftOvers) {
- if (!arg.startsWith("-") && cmd == null) {
- cmd = arg;
- } else {
- newArgs.add(arg);
- }
- }
- } catch (ParseException e) {
- CommandArgsException cae = new CommandArgsException(e);
- throw cae;
- }
-
- Function<List<String>, ?> function = cmd != null ? getCommand(cmd) : getDefaultCommand();
- if (function == null)
- throw new IllegalArgumentException("Uknown command " + cmd);
- try {
- return function.apply(newArgs).toString();
- } catch (CommandArgsException e) {
- if (e.getCommandName() == null) {
- e.setCommandName(cmd);
- e.setCommandsCli(this);
- }
- throw e;
- } catch (IllegalArgumentException e) {
- CommandArgsException cae = new CommandArgsException(e);
- cae.setCommandName(cmd);
- throw cae;
- }
- }
-
- @Override
- public Options getOptions() {
- return options;
- }
-
- protected void addCommand(String cmd, Function<List<String>, ?> function) {
- commands.put(cmd, function);
-
- }
-
- @Override
- public String getUsage() {
- return "[command]";
- }
-
- protected void addCommandsCli(CommandsCli commandsCli) {
- addCommand(commandsCli.getCommandName(), commandsCli);
- commandsCli.addCommand(HELP, new HelpCommand(this, commandsCli));
- }
-
- public String getCommandName() {
- return commandName;
- }
-
- public Set<String> getSubCommands() {
- return commands.keySet();
- }
-
- public Function<List<String>, ?> getCommand(String command) {
- return commands.get(command);
- }
-
- public HelpCommand getHelpCommand() {
- return (HelpCommand) getCommand(HELP);
- }
-
- public Function<List<String>, String> getDefaultCommand() {
- return getHelpCommand();
- }
-
- /** In order to implement quickly a main method. */
- public static void mainImpl(CommandsCli cli, String[] args) {
- try {
- cli.addCommand(CommandsCli.HELP, new HelpCommand(null, cli));
- Object output = cli.apply(Arrays.asList(args));
- System.out.println(output);
- System.exit(0);
- } catch (CommandArgsException e) {
- System.err.println("Wrong arguments " + Arrays.toString(args) + ": " + e.getMessage());
- if (e.getCommandName() != null) {
- StringWriter out = new StringWriter();
- HelpCommand.printHelp(e.getCommandsCli(), e.getCommandName(), out);
- System.err.println(out.toString());
- } else {
- e.printStackTrace();
- }
- System.exit(1);
- } catch (Exception e) {
- e.printStackTrace();
- System.exit(1);
- }
- }
-}
+++ /dev/null
-package org.argeo.cli;
-
-import java.io.StringWriter;
-import java.util.Arrays;
-import java.util.List;
-import java.util.function.Function;
-
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.DefaultParser;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-
-/** A command that can be described. */
-public interface DescribedCommand<T> extends Function<List<String>, T> {
- default Options getOptions() {
- return new Options();
- }
-
- String getDescription();
-
- default String getUsage() {
- return null;
- }
-
- default String getExamples() {
- return null;
- }
-
- default CommandLine toCommandLine(List<String> args) {
- try {
- DefaultParser parser = new DefaultParser();
- return parser.parse(getOptions(), args.toArray(new String[args.size()]));
- } catch (ParseException e) {
- throw new CommandArgsException(e);
- }
- }
-
- /** In order to implement quickly a main method. */
- public static void mainImpl(DescribedCommand<?> command, String[] args) {
- try {
- Object output = command.apply(Arrays.asList(args));
- System.out.println(output);
- System.exit(0);
- } catch (IllegalArgumentException e) {
- StringWriter out = new StringWriter();
- HelpCommand.printHelp(command, out);
- System.err.println(out.toString());
- System.exit(1);
- } catch (Exception e) {
- e.printStackTrace();
- System.exit(1);
- }
- }
-
-}
+++ /dev/null
-package org.argeo.cli;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.List;
-import java.util.function.Function;
-
-import org.apache.commons.cli.HelpFormatter;
-import org.apache.commons.cli.Options;
-
-/** A special command that can describe {@link DescribedCommand}. */
-public class HelpCommand implements DescribedCommand<String> {
- private CommandsCli commandsCli;
- private CommandsCli parentCommandsCli;
-
- // Help formatting
- private static int helpWidth = 80;
- private static int helpLeftPad = 4;
- private static int helpDescPad = 20;
-
- public HelpCommand(CommandsCli parentCommandsCli, CommandsCli commandsCli) {
- super();
- this.parentCommandsCli = parentCommandsCli;
- this.commandsCli = commandsCli;
- }
-
- @Override
- public String apply(List<String> args) {
- StringWriter out = new StringWriter();
-
- if (args.size() == 0) {// overview
- printHelp(commandsCli, out);
- } else {
- String cmd = args.get(0);
- Function<List<String>, ?> function = commandsCli.getCommand(cmd);
- if (function == null)
- return "Command " + cmd + " not found.";
- Options options;
- String examples;
- DescribedCommand<?> command = null;
- if (function instanceof DescribedCommand) {
- command = (DescribedCommand<?>) function;
- options = command.getOptions();
- examples = command.getExamples();
- } else {
- options = new Options();
- examples = null;
- }
- String description = getShortDescription(function);
- String commandCall = getCommandUsage(cmd, command);
- HelpFormatter formatter = new HelpFormatter();
- formatter.printHelp(new PrintWriter(out), helpWidth, commandCall, description, options, helpLeftPad,
- helpDescPad, examples, false);
- }
- return out.toString();
- }
-
- private static String getShortDescription(Function<List<String>, ?> function) {
- if (function instanceof DescribedCommand) {
- return ((DescribedCommand<?>) function).getDescription();
- } else {
- return function.toString();
- }
- }
-
- public String getCommandUsage(String cmd, DescribedCommand<?> command) {
- String commandCall = getCommandCall(commandsCli) + " " + cmd;
- assert command != null;
- if (command != null && command.getUsage() != null) {
- commandCall = commandCall + " " + command.getUsage();
- }
- return commandCall;
- }
-
- @Override
- public String getDescription() {
- return "Shows this help or describes a command";
- }
-
- @Override
- public String getUsage() {
- return "[command]";
- }
-
- public CommandsCli getParentCommandsCli() {
- return parentCommandsCli;
- }
-
- protected String getCommandCall(CommandsCli commandsCli) {
- HelpCommand hc = commandsCli.getHelpCommand();
- if (hc.getParentCommandsCli() != null) {
- return getCommandCall(hc.getParentCommandsCli()) + " " + commandsCli.getCommandName();
- } else {
- return commandsCli.getCommandName();
- }
- }
-
- public static void printHelp(DescribedCommand<?> command, StringWriter out) {
- String usage = "java " + command.getClass().getName()
- + (command.getUsage() != null ? " " + command.getUsage() : "");
- HelpFormatter formatter = new HelpFormatter();
- formatter.printHelp(new PrintWriter(out), helpWidth, usage, command.getDescription(), command.getOptions(),
- helpLeftPad, helpDescPad, command.getExamples(), false);
-
- }
-
- public static void printHelp(CommandsCli commandsCli, String commandName, StringWriter out) {
- DescribedCommand<?> command = (DescribedCommand<?>) commandsCli.getCommand(commandName);
- String usage = commandsCli.getHelpCommand().getCommandUsage(commandName, command);
- HelpFormatter formatter = new HelpFormatter();
- formatter.printHelp(new PrintWriter(out), helpWidth, usage, command.getDescription(), command.getOptions(),
- helpLeftPad, helpDescPad, command.getExamples(), false);
-
- }
-
- public static void printHelp(CommandsCli commandsCli, StringWriter out) {
- out.append(commandsCli.getDescription()).append('\n');
- String leftPad = spaces(helpLeftPad);
- for (String cmd : commandsCli.getSubCommands()) {
- Function<List<String>, ?> function = commandsCli.getCommand(cmd);
- assert function != null;
- out.append(leftPad);
- out.append(cmd);
- // TODO deal with long commands
- out.append(spaces(helpDescPad - cmd.length()));
- out.append(getShortDescription(function));
- out.append('\n');
- }
- }
-
- private static String spaces(int count) {
- // Java 11
- // return " ".repeat(count);
- if (count <= 0)
- return "";
- else {
- StringBuilder sb = new StringBuilder(count);
- for (int i = 0; i < count; i++)
- sb.append(' ');
- return sb.toString();
- }
- }
-}
+++ /dev/null
-package org.argeo.cli.fs;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.List;
-
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.argeo.cli.CommandArgsException;
-import org.argeo.cli.DescribedCommand;
-import org.argeo.sync.SyncResult;
-
-public class FileSync implements DescribedCommand<SyncResult<Path>> {
- final static Option deleteOption = Option.builder().longOpt("delete").desc("delete from target").build();
- final static Option recursiveOption = Option.builder("r").longOpt("recursive").desc("recurse into directories")
- .build();
- final static Option progressOption = Option.builder().longOpt("progress").hasArg(false).desc("show progress")
- .build();
-
- @Override
- public SyncResult<Path> apply(List<String> t) {
- try {
- CommandLine line = toCommandLine(t);
- List<String> remaining = line.getArgList();
- if (remaining.size() == 0) {
- throw new CommandArgsException("There must be at least one argument");
- }
- URI sourceUri = new URI(remaining.get(0));
- URI targetUri;
- if (remaining.size() == 1) {
- targetUri = Paths.get(System.getProperty("user.dir")).toUri();
- } else {
- targetUri = new URI(remaining.get(1));
- }
- boolean delete = line.hasOption(deleteOption.getLongOpt());
- boolean recursive = line.hasOption(recursiveOption.getLongOpt());
- PathSync pathSync = new PathSync(sourceUri, targetUri, delete, recursive);
- return pathSync.call();
- } catch (URISyntaxException e) {
- throw new CommandArgsException(e);
- }
- }
-
- @Override
- public Options getOptions() {
- Options options = new Options();
- options.addOption(recursiveOption);
- options.addOption(deleteOption);
- options.addOption(progressOption);
- return options;
- }
-
- @Override
- public String getUsage() {
- return "[source URI] [target URI]";
- }
-
- public static void main(String[] args) {
- DescribedCommand.mainImpl(new FileSync(), args);
-// Options options = new Options();
-// options.addOption("r", "recursive", false, "recurse into directories");
-// options.addOption(Option.builder().longOpt("progress").hasArg(false).desc("show progress").build());
-//
-// CommandLineParser parser = new DefaultParser();
-// try {
-// CommandLine line = parser.parse(options, args);
-// List<String> remaining = line.getArgList();
-// if (remaining.size() == 0) {
-// System.err.println("There must be at least one argument");
-// printHelp(options);
-// System.exit(1);
-// }
-// URI sourceUri = new URI(remaining.get(0));
-// URI targetUri;
-// if (remaining.size() == 1) {
-// targetUri = Paths.get(System.getProperty("user.dir")).toUri();
-// } else {
-// targetUri = new URI(remaining.get(1));
-// }
-// PathSync pathSync = new PathSync(sourceUri, targetUri);
-// pathSync.run();
-// } catch (Exception exp) {
-// exp.printStackTrace();
-// printHelp(options);
-// System.exit(1);
-// }
- }
-
-// public static void printHelp(Options options) {
-// HelpFormatter formatter = new HelpFormatter();
-// formatter.printHelp("sync SRC [DEST]", options, true);
-// }
-
- @Override
- public String getDescription() {
- return "Synchronises files";
- }
-
-}
+++ /dev/null
-package org.argeo.cli.fs;
-
-import org.argeo.cli.CommandsCli;
-
-/** File utilities. */
-public class FsCommands extends CommandsCli {
-
- public FsCommands(String commandName) {
- super(commandName);
- addCommand("sync", new FileSync());
- }
-
- @Override
- public String getDescription() {
- return "Utilities around files and file systems";
- }
-
-}
+++ /dev/null
-package org.argeo.cli.fs;
-
-import java.net.URI;
-import java.nio.file.FileSystems;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.spi.FileSystemProvider;
-import java.util.concurrent.Callable;
-
-import org.argeo.sync.SyncResult;
-
-/** Synchronises two paths. */
-public class PathSync implements Callable<SyncResult<Path>> {
- private final URI sourceUri, targetUri;
- private final boolean delete;
- private final boolean recursive;
-
- public PathSync(URI sourceUri, URI targetUri) {
- this(sourceUri, targetUri, false, false);
- }
-
- public PathSync(URI sourceUri, URI targetUri, boolean delete, boolean recursive) {
- this.sourceUri = sourceUri;
- this.targetUri = targetUri;
- this.delete = delete;
- this.recursive = recursive;
- }
-
- @Override
- public SyncResult<Path> call() {
- try {
- Path sourceBasePath = createPath(sourceUri);
- Path targetBasePath = createPath(targetUri);
- SyncFileVisitor syncFileVisitor = new SyncFileVisitor(sourceBasePath, targetBasePath, delete, recursive);
- Files.walkFileTree(sourceBasePath, syncFileVisitor);
- return syncFileVisitor.getSyncResult();
- } catch (Exception e) {
- throw new IllegalStateException("Cannot sync " + sourceUri + " to " + targetUri, e);
- }
- }
-
- private Path createPath(URI uri) {
- Path path;
- if (uri.getScheme() == null) {
- path = Paths.get(uri.getPath());
- } else if (uri.getScheme().equals("file")) {
- FileSystemProvider fsProvider = FileSystems.getDefault().provider();
- path = fsProvider.getPath(uri);
- } else if (uri.getScheme().equals("davex")) {
- throw new UnsupportedOperationException();
-// FileSystemProvider fsProvider = new DavexFsProvider();
-// path = fsProvider.getPath(uri);
-// } else if (uri.getScheme().equals("sftp")) {
-// Sftp sftp = new Sftp(uri);
-// path = sftp.getBasePath();
- } else
- throw new IllegalArgumentException("URI scheme not supported for " + uri);
- return path;
- }
-}
+++ /dev/null
-package org.argeo.cli.fs;
-
-import java.nio.file.Path;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.fs.BasicSyncFileVisitor;
-
-/** Synchronises two directory structures. */
-public class SyncFileVisitor extends BasicSyncFileVisitor {
- private final static Log log = LogFactory.getLog(SyncFileVisitor.class);
-
- public SyncFileVisitor(Path sourceBasePath, Path targetBasePath, boolean delete, boolean recursive) {
- super(sourceBasePath, targetBasePath, delete, recursive);
- }
-
- @Override
- protected void error(Object obj, Throwable e) {
- log.error(obj, e);
- }
-
- @Override
- protected boolean isTraceEnabled() {
- return log.isTraceEnabled();
- }
-
- @Override
- protected void trace(Object obj) {
- log.trace(obj);
- }
-}
+++ /dev/null
-/** File system CLI commands. */
-package org.argeo.cli.fs;
\ No newline at end of file
+++ /dev/null
-/** Command line API. */
-package org.argeo.cli;
\ No newline at end of file
+++ /dev/null
-package org.argeo.cli.posix;
-
-import java.util.List;
-
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.argeo.cli.DescribedCommand;
-
-public class Echo implements DescribedCommand<String> {
-
- @Override
- public Options getOptions() {
- Options options = new Options();
- options.addOption(Option.builder("n").desc("do not output the trailing newline").build());
- return options;
- }
-
- @Override
- public String getDescription() {
- return "Display a line of text";
- }
-
- @Override
- public String getUsage() {
- return "[STRING]...";
- }
-
- @Override
- public String apply(List<String> args) {
- CommandLine cl = toCommandLine(args);
-
- StringBuffer sb = new StringBuffer();
- for (String s : cl.getArgList()) {
- sb.append(s).append(' ');
- }
-
- if (cl.hasOption('n')) {
- sb.deleteCharAt(sb.length() - 1);
- } else {
- sb.setCharAt(sb.length() - 1, '\n');
- }
- return sb.toString();
- }
-
-}
+++ /dev/null
-package org.argeo.cli.posix;
-
-import org.argeo.cli.CommandsCli;
-
-/** POSIX commands. */
-public class PosixCommands extends CommandsCli {
-
- public PosixCommands(String commandName) {
- super(commandName);
- addCommand("echo", new Echo());
- }
-
- @Override
- public String getDescription() {
- return "Reimplementation of some POSIX commands in plain Java";
- }
-
- public static void main(String[] args) {
- mainImpl(new PosixCommands("argeo-posix"), args);
- }
-}
+++ /dev/null
-/** Posix CLI commands. */
-package org.argeo.cli.posix;
\ No newline at end of file
+++ /dev/null
-package org.argeo.fs;
-
-import java.io.IOException;
-import java.nio.file.FileVisitResult;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.SimpleFileVisitor;
-import java.nio.file.StandardCopyOption;
-import java.nio.file.attribute.BasicFileAttributes;
-import java.nio.file.attribute.FileTime;
-
-import org.argeo.sync.SyncResult;
-
-/** Synchronises two directory structures. */
-public class BasicSyncFileVisitor extends SimpleFileVisitor<Path> {
- // TODO make it configurable
- private boolean trace = false;
-
- private final Path sourceBasePath;
- private final Path targetBasePath;
- private final boolean delete;
- private final boolean recursive;
-
- private SyncResult<Path> syncResult = new SyncResult<>();
-
- public BasicSyncFileVisitor(Path sourceBasePath, Path targetBasePath, boolean delete, boolean recursive) {
- this.sourceBasePath = sourceBasePath;
- this.targetBasePath = targetBasePath;
- this.delete = delete;
- this.recursive = recursive;
- }
-
- @Override
- public FileVisitResult preVisitDirectory(Path sourceDir, BasicFileAttributes attrs) throws IOException {
- if (!recursive && !sourceDir.equals(sourceBasePath))
- return FileVisitResult.SKIP_SUBTREE;
- Path targetDir = toTargetPath(sourceDir);
- Files.createDirectories(targetDir);
- return FileVisitResult.CONTINUE;
- }
-
- @Override
- public FileVisitResult postVisitDirectory(Path sourceDir, IOException exc) throws IOException {
- if (delete) {
- Path targetDir = toTargetPath(sourceDir);
- for (Path targetPath : Files.newDirectoryStream(targetDir)) {
- Path sourcePath = sourceDir.resolve(targetPath.getFileName());
- if (!Files.exists(sourcePath)) {
- try {
- FsUtils.delete(targetPath);
- deleted(targetPath);
- } catch (Exception e) {
- deleteFailed(targetPath, exc);
- }
- }
- }
- }
- return FileVisitResult.CONTINUE;
- }
-
- @Override
- public FileVisitResult visitFile(Path sourceFile, BasicFileAttributes attrs) throws IOException {
- Path targetFile = toTargetPath(sourceFile);
- try {
- if (!Files.exists(targetFile)) {
- Files.copy(sourceFile, targetFile);
- added(sourceFile, targetFile);
- } else {
- if (shouldOverwrite(sourceFile, targetFile)) {
- Files.copy(sourceFile, targetFile, StandardCopyOption.REPLACE_EXISTING);
- }
- }
- } catch (Exception e) {
- copyFailed(sourceFile, targetFile, e);
- }
- return FileVisitResult.CONTINUE;
- }
-
- protected boolean shouldOverwrite(Path sourceFile, Path targetFile) throws IOException {
- long sourceSize = Files.size(sourceFile);
- long targetSize = Files.size(targetFile);
- if (sourceSize != targetSize) {
- return true;
- }
- FileTime sourceLastModif = Files.getLastModifiedTime(sourceFile);
- FileTime targetLastModif = Files.getLastModifiedTime(targetFile);
- if (sourceLastModif.compareTo(targetLastModif) > 0)
- return true;
- return shouldOverwriteLaterSameSize(sourceFile, targetFile);
- }
-
- protected boolean shouldOverwriteLaterSameSize(Path sourceFile, Path targetFile) {
- return false;
- }
-
-// @Override
-// public FileVisitResult visitFileFailed(Path sourceFile, IOException exc) throws IOException {
-// error("Cannot sync " + sourceFile, exc);
-// return FileVisitResult.CONTINUE;
-// }
-
- private Path toTargetPath(Path sourcePath) {
- Path relativePath = sourceBasePath.relativize(sourcePath);
- Path targetPath = targetBasePath.resolve(relativePath.toString());
- return targetPath;
- }
-
- public Path getSourceBasePath() {
- return sourceBasePath;
- }
-
- public Path getTargetBasePath() {
- return targetBasePath;
- }
-
- protected void added(Path sourcePath, Path targetPath) {
- syncResult.getAdded().add(targetPath);
- if (isTraceEnabled())
- trace("Added " + sourcePath + " as " + targetPath);
- }
-
- protected void modified(Path sourcePath, Path targetPath) {
- syncResult.getModified().add(targetPath);
- if (isTraceEnabled())
- trace("Overwritten from " + sourcePath + " to " + targetPath);
- }
-
- protected void copyFailed(Path sourcePath, Path targetPath, Exception e) {
- syncResult.addError(sourcePath, targetPath, e);
- if (isTraceEnabled())
- error("Cannot copy " + sourcePath + " to " + targetPath, e);
- }
-
- protected void deleted(Path targetPath) {
- syncResult.getDeleted().add(targetPath);
- if (isTraceEnabled())
- trace("Deleted " + targetPath);
- }
-
- protected void deleteFailed(Path targetPath, Exception e) {
- syncResult.addError(null, targetPath, e);
- if (isTraceEnabled())
- error("Cannot delete " + targetPath, e);
- }
-
- /** Log error. */
- protected void error(Object obj, Throwable e) {
- System.err.println(obj);
- e.printStackTrace();
- }
-
- protected boolean isTraceEnabled() {
- return trace;
- }
-
- protected void trace(Object obj) {
- System.out.println(obj);
- }
-
- public SyncResult<Path> getSyncResult() {
- return syncResult;
- }
-
-}
+++ /dev/null
-package org.argeo.fs;
-
-import java.io.IOException;
-import java.nio.file.FileVisitResult;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.SimpleFileVisitor;
-import java.nio.file.attribute.BasicFileAttributes;
-
-/** Utilities around the standard Java file abstractions. */
-public class FsUtils {
- /** Sync a source path with a target path. */
- public static void sync(Path sourceBasePath, Path targetBasePath) {
- sync(sourceBasePath, targetBasePath, false);
- }
-
- /** Sync a source path with a target path. */
- public static void sync(Path sourceBasePath, Path targetBasePath, boolean delete) {
- sync(new BasicSyncFileVisitor(sourceBasePath, targetBasePath, delete, true));
- }
-
- public static void sync(BasicSyncFileVisitor syncFileVisitor) {
- try {
- Files.walkFileTree(syncFileVisitor.getSourceBasePath(), syncFileVisitor);
- } catch (Exception e) {
- throw new RuntimeException("Cannot sync " + syncFileVisitor.getSourceBasePath() + " with "
- + syncFileVisitor.getTargetBasePath(), e);
- }
- }
-
- /** Deletes this path, recursively if needed. */
- public static void delete(Path path) {
- try {
- Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
- @Override
- public FileVisitResult postVisitDirectory(Path directory, IOException e) throws IOException {
- if (e != null)
- throw e;
- Files.delete(directory);
- return FileVisitResult.CONTINUE;
- }
-
- @Override
- public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
- Files.delete(file);
- return FileVisitResult.CONTINUE;
- }
- });
- } catch (IOException e) {
- throw new RuntimeException("Cannot delete " + path, e);
- }
- }
-
- /** Singleton. */
- private FsUtils() {
- }
-
-}
+++ /dev/null
-/** Generic file system utilities. */
-package org.argeo.fs;
\ No newline at end of file
+++ /dev/null
-package org.argeo.sync;
-
-/** Commons exception for sync */
-public class SyncException extends RuntimeException {
- private static final long serialVersionUID = -3371314343580218538L;
-
- public SyncException(String message) {
- super(message);
- }
-
- public SyncException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public SyncException(Object source, Object target, Throwable cause) {
- super("Cannot sync from " + source + " to " + target, cause);
- }
-}
+++ /dev/null
-package org.argeo.sync;
-
-import java.time.Instant;
-import java.util.Set;
-import java.util.TreeSet;
-
-/** Describes what happendend during a sync operation. */
-public class SyncResult<T> {
- private final Set<T> added = new TreeSet<>();
- private final Set<T> modified = new TreeSet<>();
- private final Set<T> deleted = new TreeSet<>();
- private final Set<Error> errors = new TreeSet<>();
-
- public Set<T> getAdded() {
- return added;
- }
-
- public Set<T> getModified() {
- return modified;
- }
-
- public Set<T> getDeleted() {
- return deleted;
- }
-
- public Set<Error> getErrors() {
- return errors;
- }
-
- public void addError(T sourcePath, T targetPath, Exception e) {
- Error error = new Error(sourcePath, targetPath, e);
- errors.add(error);
- }
-
- public boolean noModification() {
- return modified.isEmpty() && deleted.isEmpty() && added.isEmpty();
- }
-
- @Override
- public String toString() {
- if (noModification())
- return "No modification.";
- StringBuffer sb = new StringBuffer();
- for (T p : modified)
- sb.append("MOD ").append(p).append('\n');
- for (T p : deleted)
- sb.append("DEL ").append(p).append('\n');
- for (T p : added)
- sb.append("ADD ").append(p).append('\n');
- for (Error error : errors)
- sb.append(error).append('\n');
- return sb.toString();
- }
-
- public class Error implements Comparable<Error> {
- private final T sourcePath;// if null this is a failed delete
- private final T targetPath;
- private final Exception exception;
- private final Instant timestamp = Instant.now();
-
- public Error(T sourcePath, T targetPath, Exception e) {
- super();
- this.sourcePath = sourcePath;
- this.targetPath = targetPath;
- this.exception = e;
- }
-
- public T getSourcePath() {
- return sourcePath;
- }
-
- public T getTargetPath() {
- return targetPath;
- }
-
- public Exception getException() {
- return exception;
- }
-
- public Instant getTimestamp() {
- return timestamp;
- }
-
- @Override
- public int compareTo(Error o) {
- return timestamp.compareTo(o.timestamp);
- }
-
- @Override
- public int hashCode() {
- return timestamp.hashCode();
- }
-
- @Override
- public String toString() {
- return "ERR " + timestamp + (sourcePath == null ? "Deletion failed" : "Copy failed " + sourcePath) + " "
- + targetPath + " " + exception.getMessage();
- }
-
- }
-}
+++ /dev/null
-/** Synchrnoisation related utilities. */
-package org.argeo.sync;
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
- <classpathentry kind="src" path="src" />
- <classpathentry kind="con"
- path="org.eclipse.pde.core.requiredPlugins" />
- <classpathentry kind="con"
- path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11" />
- <classpathentry kind="output" path="bin" />
-</classpath>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>org.argeo.eclipse.ui.rap</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
-Import-Package: org.eclipse.swt,\
-org.eclipse.jface.dialogs,\
-org.argeo.eclipse.ui.util,\
-org.eclipse.swt.events,\
-org.eclipse.jetty.util.component;resolution:=optional,\
-org.eclipse.jetty.http;resolution:=optional,\
-org.eclipse.jetty.io;resolution:=optional,\
-org.eclipse.jetty.security;resolution:=optional,\
-org.eclipse.jetty.server.handler;resolution:=optional,\
-org.eclipse.jetty.*;resolution:=optional,\
-*
+++ /dev/null
-source.. = src/
-output.. = bin/
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<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.commons</groupId>
- <version>2.3-SNAPSHOT</version>
- <artifactId>argeo-commons</artifactId>
- <relativePath>..</relativePath>
- </parent>
- <artifactId>org.argeo.eclipse.ui.rap</artifactId>
- <name>Commons Eclipse UI RAP</name>
- <dependencies>
- <dependency>
- <groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.eclipse.ui</artifactId>
- <version>2.3-SNAPSHOT</version>
- </dependency>
-
- <!-- UI -->
- <dependency>
- <groupId>org.argeo.tp.rap.e4</groupId>
- <artifactId>org.eclipse.rap.rwt</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.rap.e4</groupId>
- <artifactId>org.eclipse.core.commands</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.rap.e4</groupId>
- <artifactId>org.eclipse.rap.jface</artifactId>
- <scope>provided</scope>
- </dependency>
-
- <!-- File upload -->
- <dependency>
- <groupId>org.argeo.tp.rap.e4</groupId>
- <artifactId>org.eclipse.rap.filedialog</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.rap.e4</groupId>
- <artifactId>org.eclipse.rap.fileupload</artifactId>
- <scope>provided</scope>
- </dependency>
-
- </dependencies>
-</project>
\ No newline at end of file
+++ /dev/null
-package org.argeo.eclipse.ui.jetty;
-
-import java.io.IOException;
-import java.lang.management.ManagementFactory;
-import java.nio.file.Files;
-import java.nio.file.Path;
-
-import javax.servlet.ServletContextEvent;
-import javax.servlet.ServletContextListener;
-
-import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.servlet.DefaultServlet;
-import org.eclipse.jetty.servlet.ServletContextHandler;
-import org.eclipse.jetty.servlet.ServletHolder;
-import org.eclipse.jetty.util.resource.Resource;
-import org.eclipse.jetty.util.thread.QueuedThreadPool;
-import org.eclipse.rap.rwt.application.AbstractEntryPoint;
-import org.eclipse.rap.rwt.application.ApplicationRunner;
-import org.eclipse.rap.rwt.engine.RWTServlet;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-
-/** A minimal RWT runner based on embedded Jetty. */
-public class RwtRunner {
-
- private final Server server;
- private final ServerConnector serverConnector;
- private Path tempDir;
-
- public RwtRunner() {
- server = new Server(new QueuedThreadPool(10, 1));
- serverConnector = new ServerConnector(server);
- serverConnector.setPort(0);
- server.setConnectors(new Connector[] { serverConnector });
- }
-
- protected Control createUi(Composite parent, Object context) {
- return new Label(parent, SWT.NONE);
- }
-
- public void init() {
- ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
- context.setContextPath("/");
- server.setHandler(context);
-
- String entryPoint = "app";
-
- // rwt-resources requires a file system
- try {
- tempDir = Files.createTempDirectory("argeo-rwtRunner");
- context.setBaseResource(Resource.newResource(tempDir.resolve("www").toString()));
- } catch (IOException e) {
- throw new IllegalStateException("Cannot create temporary directory", e);
- }
- context.addEventListener(new ServletContextListener() {
- ApplicationRunner applicationRunner;
-
- @Override
- public void contextInitialized(ServletContextEvent sce) {
- applicationRunner = new ApplicationRunner(
- (application) -> application.addEntryPoint("/" + entryPoint, () -> new AbstractEntryPoint() {
- private static final long serialVersionUID = 5678385921969090733L;
-
- @Override
- protected void createContents(Composite parent) {
- createUi(parent, null);
- }
- }, null), sce.getServletContext());
- applicationRunner.start();
- }
-
- @Override
- public void contextDestroyed(ServletContextEvent sce) {
- applicationRunner.stop();
- }
- });
-
- context.addServlet(new ServletHolder(new RWTServlet()), "/" + entryPoint);
-
- // Required to serve rwt-resources. It is important that this is last.
- ServletHolder holderPwd = new ServletHolder("default", DefaultServlet.class);
- context.addServlet(holderPwd, "/");
-
- try {
- server.start();
- } catch (Exception e) {
- throw new IllegalStateException("Cannot start Jetty server", e);
- }
- }
-
- public void destroy() {
- try {
- serverConnector.close();
- server.stop();
- // TODO delete temp dir
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- public Integer getEffectivePort() {
- return serverConnector.getLocalPort();
- }
-
- public void waitFor() throws InterruptedException {
- server.join();
- }
-
- public static void main(String[] args) throws Exception {
- RwtRunner rwtRunner = new RwtRunner() {
-
- @Override
- protected Control createUi(Composite parent, Object context) {
- Label label = new Label(parent, SWT.NONE);
- label.setText("Hello world!");
- return label;
- }
- };
- rwtRunner.init();
- Runtime.getRuntime().addShutdownHook(new Thread(() -> rwtRunner.destroy(), "Jetty shutdown"));
-
- long jvmUptime = ManagementFactory.getRuntimeMXBean().getUptime();
- System.out.println("App available in " + jvmUptime + " ms, on port " + rwtRunner.getEffectivePort());
-
- // open browser in app mode
- Thread.sleep(2000);// wait for RWT to be ready
- Runtime.getRuntime().exec("google-chrome --app=http://localhost:" + rwtRunner.getEffectivePort() + "/app");
-
- rwtRunner.waitFor();
- }
-}
+++ /dev/null
-package org.argeo.eclipse.ui.specific;
-
-import org.eclipse.swt.widgets.FileDialog;
-import org.eclipse.swt.widgets.Shell;
-
-public class CmsFileDialog extends FileDialog {
- private static final long serialVersionUID = -7540791204102318801L;
-
- public CmsFileDialog(Shell parent, int style) {
- super(parent, style);
- }
-
- public CmsFileDialog(Shell parent) {
- super(parent);
- }
-
-}
+++ /dev/null
-package org.argeo.eclipse.ui.specific;
-
-import org.eclipse.rap.rwt.widgets.FileUpload;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.widgets.Composite;
-
-public class CmsFileUpload extends FileUpload {
- private static final long serialVersionUID = 8027963992680980549L;
-
- public CmsFileUpload(Composite parent, int style) {
- super(parent, style);
- }
-
- @Override
- public void setText(String text) {
- super.setText(text);
- }
-
- @Override
- public String getFileName() {
- return super.getFileName();
- }
-
- @Override
- public String[] getFileNames() {
- return super.getFileNames();
- }
-
- @Override
- public void addSelectionListener(SelectionListener listener) {
- super.addSelectionListener(listener);
- }
-
-}
+++ /dev/null
-package org.argeo.eclipse.ui.specific;
-
-import org.eclipse.jface.viewers.AbstractTableViewer;
-import org.eclipse.jface.viewers.ColumnViewer;
-import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.rap.rwt.RWT;
-import org.eclipse.swt.widgets.Widget;
-
-/** Static utilities to bridge differences between RCP and RAP */
-public class EclipseUiSpecificUtils {
-
- public static void setStyleData(Widget widget, Object data) {
- widget.setData(RWT.CUSTOM_VARIANT, data);
- }
-
- public static Object getStyleData(Widget widget) {
- return widget.getData(RWT.CUSTOM_VARIANT);
- }
-
- public static void setMarkupData(Widget widget) {
- widget.setData(RWT.MARKUP_ENABLED, true);
- }
-
- public static void setMarkupValidationDisabledData(Widget widget) {
- widget.setData("org.eclipse.rap.rwt.markupValidationDisabled", Boolean.TRUE);
- }
-
- /**
- * TootlTip support is supported only for {@link AbstractTableViewer} in RAP
- */
- public static void enableToolTipSupport(Viewer viewer) {
- if (viewer instanceof ColumnViewer)
- ColumnViewerToolTipSupport.enableFor((ColumnViewer) viewer);
- }
-
- private EclipseUiSpecificUtils() {
- }
-}
+++ /dev/null
-package org.argeo.eclipse.ui.specific;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.eclipse.rap.fileupload.FileDetails;
-import org.eclipse.rap.fileupload.FileUploadHandler;
-import org.eclipse.rap.fileupload.FileUploadReceiver;
-import org.eclipse.rap.rwt.RWT;
-import org.eclipse.rap.rwt.client.ClientFile;
-import org.eclipse.rap.rwt.client.service.ClientFileUploader;
-import org.eclipse.rap.rwt.dnd.ClientFileTransfer;
-import org.eclipse.swt.dnd.DND;
-import org.eclipse.swt.dnd.DropTarget;
-import org.eclipse.swt.dnd.DropTargetAdapter;
-import org.eclipse.swt.dnd.DropTargetEvent;
-import org.eclipse.swt.dnd.Transfer;
-import org.eclipse.swt.widgets.Control;
-
-/** Configures a {@link Control} to receive files drop from the client OS. */
-public class FileDropAdapter {
-
- public void prepareDropTarget(Control control, DropTarget dropTarget) {
- dropTarget.setTransfer(new Transfer[] { ClientFileTransfer.getInstance() });
- dropTarget.addDropListener(new DropTargetAdapter() {
- private static final long serialVersionUID = 5361645765549463168L;
-
- @Override
- public void dropAccept(DropTargetEvent event) {
- if (!ClientFileTransfer.getInstance().isSupportedType(event.currentDataType)) {
- event.detail = DND.DROP_NONE;
- }
- }
-
- @Override
- public void drop(DropTargetEvent event) {
- handleFileDrop(control, event);
- }
- });
- }
-
- public void handleFileDrop(Control control, DropTargetEvent event) {
- ClientFile[] clientFiles = (ClientFile[]) event.data;
- ClientFileUploader service = RWT.getClient().getService(ClientFileUploader.class);
-// DiskFileUploadReceiver receiver = new DiskFileUploadReceiver();
- FileUploadReceiver receiver = new FileUploadReceiver() {
-
- @Override
- public void receive(InputStream stream, FileDetails details) throws IOException {
- control.getDisplay().syncExec(() -> {
- try {
- processUpload(stream, details.getFileName(), details.getContentType());
- } catch (IOException e) {
- throw new IllegalStateException("Cannot process upload of " + details.getFileName(), e);
- }
- });
- }
- };
- FileUploadHandler handler = new FileUploadHandler(receiver);
-// handler.setMaxFileSize( sizeLimit );
-// handler.setUploadTimeLimit( timeLimit );
- service.submit(handler.getUploadUrl(), clientFiles);
-// for (File file : receiver.getTargetFiles()) {
-// paths.add(file.toPath());
-// }
- }
-
- /** Executed in UI thread */
- protected void processUpload(InputStream in, String fileName, String contentType) throws IOException {
-
- }
-
-}
+++ /dev/null
-package org.argeo.eclipse.ui.specific;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.argeo.eclipse.ui.util.SingleSourcingConstants;
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.rap.rwt.RWT;
-import org.eclipse.rap.rwt.client.service.UrlLauncher;
-
-/**
- * RWT specific object to open a file retrieved from the server. It forwards the
- * request to the correct service after encoding file name and path in the
- * request URI.
- *
- * <p>
- * The parameter "URI" is used to determine the correct file service, the path
- * and the file name. An optional file name can be added to present the end user
- * with a different file name as the one used to retrieve it.
- * </p>
- *
- *
- * <p>
- * The instance specific service is called by its ID and must have been
- * externally created
- * </p>
- */
-public class OpenFile extends AbstractHandler {
- private final static Log log = LogFactory.getLog(OpenFile.class);
-
- public final static String ID = SingleSourcingConstants.OPEN_FILE_CMD_ID;
- public final static String PARAM_FILE_NAME = SingleSourcingConstants.PARAM_FILE_NAME;
- public final static String PARAM_FILE_URI = SingleSourcingConstants.PARAM_FILE_URI;;
-
- /* DEPENDENCY INJECTION */
- private String openFileServiceId;
-
- public Object execute(ExecutionEvent event) {
- String fileName = event.getParameter(PARAM_FILE_NAME);
- String fileUri = event.getParameter(PARAM_FILE_URI);
- // Sanity check
- if (fileUri == null || "".equals(fileUri.trim()) || openFileServiceId == null
- || "".equals(openFileServiceId.trim()))
- return null;
-
- org.argeo.eclipse.ui.specific.OpenFile openFileClient = new org.argeo.eclipse.ui.specific.OpenFile();
- openFileClient.execute(openFileServiceId, fileUri, fileName);
- return null;
- }
-
- public Object execute(String openFileServiceId, String fileUri, String fileName) {
- StringBuilder url = new StringBuilder();
- url.append(RWT.getServiceManager().getServiceHandlerUrl(openFileServiceId));
-
- if (EclipseUiUtils.notEmpty(fileName))
- url.append("&").append(SingleSourcingConstants.PARAM_FILE_NAME).append("=").append(fileName);
- url.append("&").append(SingleSourcingConstants.PARAM_FILE_URI).append("=").append(fileUri);
-
- String downloadUrl = url.toString();
- if (log.isTraceEnabled())
- log.trace("Calling OpenFileService with ID: " + openFileServiceId + " , with download URL: " + downloadUrl);
-
- UrlLauncher launcher = RWT.getClient().getService(UrlLauncher.class);
- launcher.openURL(downloadUrl);
- return null;
- }
-
- /* DEPENDENCY INJECTION */
- public void setOpenFileServiceId(String openFileServiceId) {
- this.openFileServiceId = openFileServiceId;
- }
-}
+++ /dev/null
-package org.argeo.eclipse.ui.specific;
-
-import static org.argeo.eclipse.ui.util.SingleSourcingConstants.FILE_SCHEME;
-import static org.argeo.eclipse.ui.util.SingleSourcingConstants.SCHEME_HOST_SEPARATOR;
-
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.argeo.eclipse.ui.util.SingleSourcingConstants;
-import org.eclipse.rap.rwt.service.ServiceHandler;
-
-/**
- * RWT specific Basic Default service handler that retrieves a file on the
- * server file system using its absolute path and forwards it to the end user
- * browser.
- *
- * Clients might extend to provide context specific services
- */
-public class OpenFileService implements ServiceHandler {
- public OpenFileService() {
- }
-
- public void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
- String fileName = request.getParameter(SingleSourcingConstants.PARAM_FILE_NAME);
- String uri = request.getParameter(SingleSourcingConstants.PARAM_FILE_URI);
-
- // Use buffered array to directly write the stream?
- if (!uri.startsWith(SingleSourcingConstants.FILE_SCHEME))
- throw new IllegalArgumentException(
- "Open file service can only handle files that are on the server file system");
-
- // Set the Metadata
- response.setContentLength((int) getFileSize(uri));
- if (EclipseUiUtils.isEmpty(fileName))
- fileName = getFileName(uri);
- response.setContentType(getMimeType(uri, fileName));
- String contentDisposition = "attachment; filename=\"" + fileName + "\"";
- response.setHeader("Content-Disposition", contentDisposition);
-
- // Useless for current use
- // response.setHeader("Content-Transfer-Encoding", "binary");
- // response.setHeader("Pragma", "no-cache");
- // response.setHeader("Cache-Control", "no-cache, must-revalidate");
-
- Path path = Paths.get(getAbsPathFromUri(uri));
- Files.copy(path, response.getOutputStream());
-
- // FIXME we always use temporary files for the time being.
- // the deleteOnClose file only works when the JVM is closed so we
- // explicitly delete to avoid overloading the server
- if (path.startsWith("/tmp"))
- path.toFile().delete();
- }
-
- protected long getFileSize(String uri) throws IOException {
- if (uri.startsWith(SingleSourcingConstants.FILE_SCHEME)) {
- Path path = Paths.get(getAbsPathFromUri(uri));
- return Files.size(path);
- }
- return -1l;
- }
-
- protected String getFileName(String uri) {
- if (uri.startsWith(SingleSourcingConstants.FILE_SCHEME)) {
- Path path = Paths.get(getAbsPathFromUri(uri));
- return path.getFileName().toString();
- }
- return null;
- }
-
- private String getAbsPathFromUri(String uri) {
- if (uri.startsWith(FILE_SCHEME))
- return uri.substring((FILE_SCHEME + SCHEME_HOST_SEPARATOR).length());
- // else if (uri.startsWith(JCR_SCHEME))
- // return uri.substring((JCR_SCHEME + SCHEME_HOST_SEPARATOR).length());
- else
- throw new IllegalArgumentException("Unknown URI prefix for" + uri);
- }
-
- protected String getMimeType(String uri, String fileName) throws IOException {
- if (uri.startsWith(FILE_SCHEME)) {
- Path path = Paths.get(getAbsPathFromUri(uri));
- String mimeType = Files.probeContentType(path);
- if (EclipseUiUtils.notEmpty(mimeType))
- return mimeType;
- }
- return "application/octet-stream";
- }
-}
+++ /dev/null
-package org.argeo.eclipse.ui.specific;
-
-/** Exception related to SWT/RWT single sourcing. */
-public class SingleSourcingException extends RuntimeException {
- private static final long serialVersionUID = -727700418055348468L;
-
- public SingleSourcingException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public SingleSourcingException(String message) {
- super(message);
- }
-
-}
+++ /dev/null
-package org.argeo.eclipse.ui.specific;
-
-import java.util.Locale;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.eclipse.rap.rwt.RWT;
-import org.eclipse.swt.widgets.Display;
-
-/** Singleton class providing single sources infos about the UI context. */
-public class UiContext {
- /** Can be null, thus indicating that we are not in a web context. */
- public static HttpServletRequest getHttpRequest() {
- return RWT.getRequest();
- }
-
- public static HttpServletResponse getHttpResponse() {
- return RWT.getResponse();
- }
-
- public static Locale getLocale() {
- if (Display.getCurrent() != null)
- return RWT.getUISession().getLocale();
- else
- return Locale.getDefault();
- }
-
- public static void setLocale(Locale locale) {
- if (Display.getCurrent() != null)
- RWT.getUISession().setLocale(locale);
- else
- Locale.setDefault(locale);
- }
-
- /** Can always be null */
- @SuppressWarnings("unchecked")
- public static <T> T getData(String key) {
- Display display = getDisplay();
- if (display == null)
- return null;
- return (T) display.getData(key);
- }
-
- public static void setData(String key, Object value) {
- Display display = getDisplay();
- if (display == null)
- throw new SingleSourcingException("Not display available in RAP context");
- display.setData(key, value);
- }
-
- private static Display getDisplay() {
- return Display.getCurrent();
- }
-
- private UiContext() {
- }
-
-}
+++ /dev/null
-/** Eclipse RAP-specific SWT/JFace utilities, to simplify single-sourcing. */
-package org.argeo.eclipse.ui.specific;
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
- <classpathentry kind="src" path="src" />
- <classpathentry kind="con"
- path="org.eclipse.pde.core.requiredPlugins" />
- <classpathentry kind="con"
- path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11" />
- <classpathentry kind="output" path="bin" />
-</classpath>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>org.argeo.eclipse.ui</name>
- <comment></comment>
- <projects></projects>
- <buildSpec>
- <buildCommand>
- <name>org.eclipse.jdt.core.javabuilder</name>
- <arguments />
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.ManifestBuilder</name>
- <arguments />
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.pde.SchemaBuilder</name>
- <arguments />
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>org.eclipse.pde.PluginNature</nature>
- <nature>org.eclipse.jdt.core.javanature</nature>
- </natures>
-</projectDescription>
\ No newline at end of file
+++ /dev/null
-/MANIFEST.MF
+++ /dev/null
-Import-Package: org.eclipse.swt,\
- org.eclipse.jface.window,\
- org.eclipse.core.commands.common,\
- *
+++ /dev/null
-source.. = src/
-output.. = bin/
-bin.includes = META-INF/,\
- .
-
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<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.commons</groupId>
- <version>2.3-SNAPSHOT</version>
- <artifactId>argeo-commons</artifactId>
- <relativePath>..</relativePath>
- </parent>
- <artifactId>org.argeo.eclipse.ui</artifactId>
- <name>Commons Eclipse UI</name>
- <dependencies>
-<!-- <dependency> -->
-<!-- <groupId>org.argeo.commons</groupId> -->
-<!-- <artifactId>org.argeo.util</artifactId> -->
-<!-- <version>2.1.89-SNAPSHOT</version> -->
-<!-- </dependency> -->
- <dependency>
- <groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.cms.jcr</artifactId>
- <version>2.3-SNAPSHOT</version>
- </dependency>
-
- <!-- UI -->
- <dependency>
- <groupId>org.argeo.tp.rap.e4</groupId>
- <artifactId>org.eclipse.rap.rwt</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.rap.e4</groupId>
- <artifactId>org.eclipse.core.commands</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.argeo.tp.rap.e4</groupId>
- <artifactId>org.eclipse.rap.jface</artifactId>
- <scope>provided</scope>
- </dependency>
- </dependencies>
-</project>
\ No newline at end of file
+++ /dev/null
-package org.argeo.eclipse.ui;
-
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.Viewer;
-
-/**
- * Tree content provider dealing with tree objects and providing reasonable
- * defaults.
- */
-public abstract class AbstractTreeContentProvider implements
- ITreeContentProvider {
- private static final long serialVersionUID = 8246126401957763868L;
-
- /** Does nothing */
- public void dispose() {
- }
-
- /** Does nothing */
- public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
- }
-
- public Object[] getChildren(Object element) {
- if (element instanceof TreeParent) {
- return ((TreeParent) element).getChildren();
- }
- return new Object[0];
- }
-
- public Object getParent(Object element) {
- if (element instanceof TreeParent) {
- return ((TreeParent) element).getParent();
- }
- return null;
- }
-
- public boolean hasChildren(Object element) {
- if (element instanceof TreeParent) {
- return ((TreeParent) element).hasChildren();
- }
- return false;
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.argeo.eclipse.ui;
-
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-
-/**
- * Wraps the definition of a column to be used in the various JFace viewers
- * (typically tree and table). It enables definition of generic viewers which
- * column can be then defined externally. Also used to generate export.
- */
-public class ColumnDefinition {
- private ColumnLabelProvider labelProvider;
- private String label;
- private int weight = 0;
- private int minWidth = 120;
-
- public ColumnDefinition(ColumnLabelProvider labelProvider, String label) {
- this.labelProvider = labelProvider;
- this.label = label;
- }
-
- public ColumnDefinition(ColumnLabelProvider labelProvider, String label,
- int weight) {
- this.labelProvider = labelProvider;
- this.label = label;
- this.weight = weight;
- this.minWidth = weight;
- }
-
- public ColumnDefinition(ColumnLabelProvider labelProvider, String label,
- int weight, int minimumWidth) {
- this.labelProvider = labelProvider;
- this.label = label;
- this.weight = weight;
- this.minWidth = minimumWidth;
- }
-
- public ColumnLabelProvider getLabelProvider() {
- return labelProvider;
- }
-
- public void setLabelProvider(ColumnLabelProvider labelProvider) {
- this.labelProvider = labelProvider;
- }
-
- public String getLabel() {
- return label;
- }
-
- public void setLabel(String label) {
- this.label = label;
- }
-
- public int getWeight() {
- return weight;
- }
-
- public void setWeight(int weight) {
- this.weight = weight;
- }
-
- public int getMinWidth() {
- return minWidth;
- }
-
- public void setMinWidth(int minWidth) {
- this.minWidth = minWidth;
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.argeo.eclipse.ui;
-
-import org.eclipse.jface.viewers.ColumnViewer;
-import org.eclipse.jface.viewers.TableViewerColumn;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.jface.viewers.ViewerComparator;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-
-/** Generic column viewer sorter */
-public class ColumnViewerComparator extends ViewerComparator {
- private static final long serialVersionUID = -2266218906355859909L;
-
- public static final int ASC = 1;
-
- public static final int NONE = 0;
-
- public static final int DESC = -1;
-
- private int direction = 0;
-
- private TableViewerColumn column;
-
- private ColumnViewer viewer;
-
- public ColumnViewerComparator(TableViewerColumn column) {
- super(null);
- this.column = column;
- this.viewer = column.getViewer();
- this.column.getColumn().addSelectionListener(new SelectionAdapter() {
- private static final long serialVersionUID = 7586796298965472189L;
-
- public void widgetSelected(SelectionEvent e) {
- if (ColumnViewerComparator.this.viewer.getComparator() != null) {
- if (ColumnViewerComparator.this.viewer.getComparator() == ColumnViewerComparator.this) {
- int tdirection = ColumnViewerComparator.this.direction;
-
- if (tdirection == ASC) {
- setSortDirection(DESC);
- } else if (tdirection == DESC) {
- setSortDirection(NONE);
- }
- } else {
- setSortDirection(ASC);
- }
- } else {
- setSortDirection(ASC);
- }
- }
- });
- }
-
- private void setSortDirection(int direction) {
- if (direction == NONE) {
- column.getColumn().getParent().setSortColumn(null);
- column.getColumn().getParent().setSortDirection(SWT.NONE);
- viewer.setComparator(null);
- } else {
- column.getColumn().getParent().setSortColumn(column.getColumn());
- this.direction = direction;
-
- if (direction == ASC) {
- column.getColumn().getParent().setSortDirection(SWT.DOWN);
- } else {
- column.getColumn().getParent().setSortDirection(SWT.UP);
- }
-
- if (viewer.getComparator() == this) {
- viewer.refresh();
- } else {
- viewer.setComparator(this);
- }
-
- }
- }
-
- public int compare(Viewer viewer, Object e1, Object e2) {
- return direction * super.compare(viewer, e1, e2);
- }
-}
+++ /dev/null
-package org.argeo.eclipse.ui;
-
-/** CMS specific exceptions. */
-public class EclipseUiException extends RuntimeException {
- private static final long serialVersionUID = -5341764743356771313L;
-
- public EclipseUiException(String message) {
- super(message);
- }
-
- public EclipseUiException(String message, Throwable e) {
- super(message, e);
- }
-
-}
+++ /dev/null
-package org.argeo.eclipse.ui;
-
-import org.eclipse.jface.resource.JFaceResources;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.layout.FormAttachment;
-import org.eclipse.swt.layout.FormData;
-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.Label;
-import org.eclipse.swt.widgets.Text;
-
-/** Utilities to simplify UI development. */
-public class EclipseUiUtils {
-
- /** Dispose all children of a Composite */
- public static void clear(Composite composite) {
- for (Control child : composite.getChildren())
- child.dispose();
- }
-
- /**
- * Enables efficient call to the layout method of a composite, refreshing only
- * some of the children controls.
- */
- public static void layout(Composite parent, Control... toUpdateControls) {
- parent.layout(toUpdateControls);
- }
-
- //
- // FONTS
- //
- /** Shortcut to retrieve default italic font from display */
- public static Font getItalicFont(Composite parent) {
- return JFaceResources.getFontRegistry().defaultFontDescriptor().setStyle(SWT.ITALIC)
- .createFont(parent.getDisplay());
- }
-
- /** Shortcut to retrieve default bold font from display */
- public static Font getBoldFont(Composite parent) {
- return JFaceResources.getFontRegistry().defaultFontDescriptor().setStyle(SWT.BOLD)
- .createFont(parent.getDisplay());
- }
-
- /** Shortcut to retrieve default bold italic font from display */
- public static Font getBoldItalicFont(Composite parent) {
- return JFaceResources.getFontRegistry().defaultFontDescriptor().setStyle(SWT.BOLD | SWT.ITALIC)
- .createFont(parent.getDisplay());
- }
-
- //
- // Simplify grid layouts management
- //
- public static GridLayout noSpaceGridLayout() {
- return noSpaceGridLayout(new GridLayout());
- }
-
- public static GridLayout noSpaceGridLayout(int columns) {
- return noSpaceGridLayout(new GridLayout(columns, false));
- }
-
- public static GridLayout noSpaceGridLayout(GridLayout layout) {
- layout.horizontalSpacing = 0;
- layout.verticalSpacing = 0;
- layout.marginWidth = 0;
- layout.marginHeight = 0;
- return layout;
- }
-
- public static GridData fillWidth() {
- return grabWidth(SWT.FILL, SWT.FILL);
- }
-
- public static GridData fillWidth(int colSpan) {
- GridData gd = grabWidth(SWT.FILL, SWT.FILL);
- gd.horizontalSpan = colSpan;
- return gd;
- }
-
- public static GridData fillAll() {
- return new GridData(SWT.FILL, SWT.FILL, true, true);
- }
-
- public static GridData fillAll(int colSpan, int rowSpan) {
- return new GridData(SWT.FILL, SWT.FILL, true, true, colSpan, rowSpan);
- }
-
- public static GridData grabWidth(int horizontalAlignment, int verticalAlignment) {
- return new GridData(horizontalAlignment, horizontalAlignment, true, false);
- }
-
- //
- // Simplify Form layout management
- //
-
- /**
- * Creates a basic form data that is attached to the 4 corners of the parent
- * composite
- */
- public static FormData fillFormData() {
- FormData formData = new FormData();
- formData.top = new FormAttachment(0, 0);
- formData.left = new FormAttachment(0, 0);
- formData.right = new FormAttachment(100, 0);
- formData.bottom = new FormAttachment(100, 0);
- return formData;
- }
-
- /**
- * Create a label and a text field for a grid layout, the text field grabbing
- * excess horizontal
- *
- * @param parent
- * the parent composite
- * @param label
- * the label to display
- * @param modifyListener
- * a {@link ModifyListener} to listen on events on the text, can be
- * null
- * @return the created text
- *
- */
- // FIXME why was this deprecated.
- // * @ deprecated use { @ link #createGridLT(Composite, String)} instead
- // @ Deprecated
- public static Text createGridLT(Composite parent, String label, ModifyListener modifyListener) {
- Label lbl = new Label(parent, SWT.LEAD);
- lbl.setText(label);
- lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
- Text txt = new Text(parent, SWT.LEAD | SWT.BORDER);
- txt.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
- if (modifyListener != null)
- txt.addModifyListener(modifyListener);
- return txt;
- }
-
- /**
- * Create a label and a text field for a grid layout, the text field grabbing
- * excess horizontal
- */
- public static Text createGridLT(Composite parent, String label) {
- return createGridLT(parent, label, null);
- }
-
- /**
- * Creates one label and a text field not editable with background colour of the
- * parent (like a label but with selectable text)
- */
- public static Text createGridLL(Composite parent, String label, String text) {
- Text txt = createGridLT(parent, label);
- txt.setText(text);
- txt.setEditable(false);
- txt.setBackground(parent.getBackground());
- return txt;
- }
-
- /**
- * Create a label and a text field with password display for a grid layout, the
- * text field grabbing excess horizontal
- */
- public static Text createGridLP(Composite parent, String label) {
- return createGridLP(parent, label, null);
- }
-
- /**
- * Create a label and a text field with password display for a grid layout, the
- * text field grabbing excess horizontal. The given modify listener will be
- * added to the newly created text field if not null.
- */
- public static Text createGridLP(Composite parent, String label, ModifyListener modifyListener) {
- Label lbl = new Label(parent, SWT.LEAD);
- lbl.setText(label);
- lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
- Text txt = new Text(parent, SWT.LEAD | SWT.BORDER | SWT.PASSWORD);
- txt.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
- if (modifyListener != null)
- txt.addModifyListener(modifyListener);
- return txt;
- }
-
- // MISCELLANEOUS
-
- /** Simply checks if a string is not null nor empty */
- public static boolean notEmpty(String stringToTest) {
- return !(stringToTest == null || "".equals(stringToTest.trim()));
- }
-
- /** Simply checks if a string is null or empty */
- public static boolean isEmpty(String stringToTest) {
- return stringToTest == null || "".equals(stringToTest.trim());
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.argeo.eclipse.ui;
-
-import java.io.InputStream;
-
-/**
- * Used for file download : subclasses must implement model specific methods to
- * get a byte array representing a file given is ID.
- */
-@Deprecated
-public interface FileProvider {
-
- public byte[] getByteArrayFileFromId(String fileId);
-
- public InputStream getInputStreamFromFileId(String fileId);
-
-}
+++ /dev/null
-package org.argeo.eclipse.ui;
-
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.jface.viewers.ViewerComparator;
-
-public abstract class GenericTableComparator extends ViewerComparator {
- private static final long serialVersionUID = -1175894935075325810L;
- protected int propertyIndex;
- public static final int ASCENDING = 0, DESCENDING = 1;
- protected int direction = DESCENDING;
-
- /**
- * Creates an instance of a sorter for TableViewer.
- *
- * @param defaultColumnIndex
- * the default sorter column
- */
-
- public GenericTableComparator(int defaultColumnIndex, int direction) {
- propertyIndex = defaultColumnIndex;
- this.direction = direction;
- }
-
- public void setColumn(int column) {
- if (column == this.propertyIndex) {
- // Same column as last sort; toggle the direction
- direction = 1 - direction;
- } else {
- // New column; do a descending sort
- this.propertyIndex = column;
- direction = DESCENDING;
- }
- }
-
- /**
- * Must be Overriden in each view.
- */
- public abstract int compare(Viewer viewer, Object e1, Object e2);
-}
+++ /dev/null
-package org.argeo.eclipse.ui;
-
-import java.util.List;
-
-/**
- * Views and editors can implement this interface so that one of the list that
- * is displayed in the part (For instance in a Table or a Tree Viewer) can be
- * rebuilt externally. Typically to generate csv or calc extract.
- */
-public interface IListProvider {
- /**
- * Returns an array of current and relevant elements
- */
- public Object[] getElements(String extractId);
-
- /**
- * Returns the column definition for passed ID
- */
- public List<ColumnDefinition> getColumnDefinition(String extractId);
-}
+++ /dev/null
-package org.argeo.eclipse.ui;
-
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseListener;
-
-/**
- * {@link MouseListener#mouseDoubleClick(MouseEvent)} as a functional interface
- * in order to use as a short lambda expression in UI code.
- * {@link MouseListener#mouseDownouseEvent)} and
- * {@link MouseListener#mouseUp(MouseEvent)} do nothing by default.
- */
-@FunctionalInterface
-public interface MouseDoubleClick extends MouseListener {
- @Override
- void mouseDoubleClick(MouseEvent e);
-
- @Override
- default void mouseDown(MouseEvent e) {
- // does nothing
- }
-
- @Override
- default void mouseUp(MouseEvent e) {
- // does nothing
- }
-}
+++ /dev/null
-package org.argeo.eclipse.ui;
-
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseListener;
-
-/**
- * {@link MouseListener#mouseDown(MouseEvent)} as a functional interface in
- * order to use as a short lambda expression in UI code.
- * {@link MouseListener#mouseDoubleClick(MouseEvent)} and
- * {@link MouseListener#mouseUp(MouseEvent)} do nothing by default.
- */
-@FunctionalInterface
-public interface MouseDown extends MouseListener {
- @Override
- void mouseDown(MouseEvent e);
-
- @Override
- default void mouseDoubleClick(MouseEvent e) {
- // does nothing
- }
-
- @Override
- default void mouseUp(MouseEvent e) {
- // does nothing
- }
-}
+++ /dev/null
-package org.argeo.eclipse.ui;
-
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-
-/**
- * {@link SelectionListener} as a functional interface in order to use as a
- * short lambda expression in UI code.
- * {@link SelectionListener#widgetDefaultSelected(SelectionEvent)} does nothing
- * by default.
- */
-@FunctionalInterface
-public interface Selected extends SelectionListener {
- @Override
- public void widgetSelected(SelectionEvent e);
-
- default public void widgetDefaultSelected(SelectionEvent e) {
- // does nothing
- }
-
-}
+++ /dev/null
-package org.argeo.eclipse.ui;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** Parent / children semantic to be used for simple UI Tree structure */
-public class TreeParent {
- private String name;
- private TreeParent parent;
-
- private List<Object> children;
-
- /**
- * Unique id within the context of a tree display. If set, equals() and
- * hashCode() methods will be based on it
- */
- private String path = null;
-
- /** False until at least one child has been added, then true until cleared */
- private boolean loaded = false;
-
- public TreeParent(String name) {
- this.name = name;
- children = new ArrayList<Object>();
- }
-
- public synchronized void addChild(Object child) {
- loaded = true;
- children.add(child);
- if (child instanceof TreeParent)
- ((TreeParent) child).setParent(this);
- }
-
- /**
- * Remove this child. The child is disposed.
- */
- public synchronized void removeChild(Object child) {
- children.remove(child);
- if (child instanceof TreeParent) {
- ((TreeParent) child).dispose();
- }
- }
-
- public synchronized void clearChildren() {
- for (Object obj : children) {
- if (obj instanceof TreeParent)
- ((TreeParent) obj).dispose();
- }
- loaded = false;
- children.clear();
- }
-
- /**
- * If overridden, <code>super.dispose()</code> must be called, typically
- * after custom cleaning.
- */
- public synchronized void dispose() {
- clearChildren();
- parent = null;
- children = null;
- }
-
- public synchronized Object[] getChildren() {
- return children.toArray(new Object[children.size()]);
- }
-
- @SuppressWarnings("unchecked")
- public synchronized <T> List<T> getChildrenOfType(Class<T> clss) {
- List<T> lst = new ArrayList<T>();
- for (Object obj : children) {
- if (clss.isAssignableFrom(obj.getClass()))
- lst.add((T) obj);
- }
- return lst;
- }
-
- public synchronized boolean hasChildren() {
- return children.size() > 0;
- }
-
- public Object getChildByName(String name) {
- for (Object child : children) {
- if (child.toString().equals(name))
- return child;
- }
- return null;
- }
-
- public synchronized Boolean isLoaded() {
- return loaded;
- }
-
- public String getName() {
- return name;
- }
-
- public void setParent(TreeParent parent) {
- this.parent = parent;
- if (parent != null && parent.path != null)
- this.path = parent.path + '/' + name;
- else
- this.path = '/' + name;
- }
-
- public TreeParent getParent() {
- return parent;
- }
-
- public String toString() {
- return getName();
- }
-
- public int compareTo(TreeParent o) {
- return name.compareTo(o.name);
- }
-
- @Override
- public int hashCode() {
- if (path != null)
- return path.hashCode();
- else
- return name.hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (path != null && obj instanceof TreeParent)
- return path.equals(((TreeParent) obj).path);
- else
- return name.equals(obj.toString());
- }
-
-}
+++ /dev/null
-package org.argeo.eclipse.ui.dialogs;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.eclipse.jface.dialogs.IMessageProvider;
-import org.eclipse.jface.dialogs.TitleAreaDialog;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Point;
-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.Display;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-
-/**
- * Generic error dialog to be used in try/catch blocks.
- *
- * @deprecated Use CMS dialogs instead.
- */
-@Deprecated
-public class ErrorFeedback extends TitleAreaDialog {
- private static final long serialVersionUID = -8918084784628179044L;
-
- private final static Log log = LogFactory.getLog(ErrorFeedback.class);
-
- private final String message;
- private final Throwable exception;
-
- public static void show(String message, Throwable e) {
- // rethrow ThreaDeath in order to make sure that RAP will properly clean
- // up the UI thread
- if (e instanceof ThreadDeath)
- throw (ThreadDeath) e;
-
- new ErrorFeedback(newShell(), message, e).open();
- }
-
- public static void show(String message) {
- new ErrorFeedback(newShell(), message, null).open();
- }
-
- private static Shell newShell() {
- return new Shell(getDisplay(), SWT.NO_TRIM);
- }
-
- /** Tries to find a display */
- private static Display getDisplay() {
- try {
- Display display = Display.getCurrent();
- if (display != null)
- return display;
- else
- return Display.getDefault();
- } catch (Exception e) {
- return Display.getCurrent();
- }
- }
-
- public ErrorFeedback(Shell parentShell, String message, Throwable e) {
- super(parentShell);
- setShellStyle(SWT.NO_TRIM);
- this.message = message;
- this.exception = e;
- log.error(message, e);
- }
-
- protected Point getInitialSize() {
- if (exception != null)
- return new Point(800, 600);
- else
- return new Point(400, 300);
- }
-
- @Override
- protected Control createDialogArea(Composite parent) {
- Composite dialogarea = (Composite) super.createDialogArea(parent);
- dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- Composite composite = new Composite(dialogarea, SWT.NONE);
- composite.setLayout(new GridLayout(2, false));
- composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-
- setMessage(message != null ? message + (exception != null ? ": " + exception.getMessage() : "")
- : exception != null ? exception.getMessage() : "Unkown Error", IMessageProvider.ERROR);
-
- if (exception != null) {
- Text stack = new Text(composite, SWT.MULTI | SWT.LEAD | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
- stack.setEditable(false);
- stack.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- StringWriter sw = new StringWriter();
- exception.printStackTrace(new PrintWriter(sw));
- stack.setText(sw.toString());
- }
-
- parent.pack();
- return composite;
- }
-
- protected void configureShell(Shell shell) {
- super.configureShell(shell);
- shell.setText("Error");
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.argeo.eclipse.ui.dialogs;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.eclipse.ui.EclipseUiException;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ShellAdapter;
-import org.eclipse.swt.events.ShellEvent;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-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.Display;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-
-/**
- * Generic lightweight dialog, not based on JFace.
- *
- * @deprecated Use CMS dialogs instead.
- */
-@Deprecated
-public class FeedbackDialog extends LightweightDialog {
- private final static Log log = LogFactory.getLog(FeedbackDialog.class);
-
- private String message;
- private Throwable exception;
-
-// private Shell parentShell;
- private Shell shell;
-
- public static void show(String message, Throwable e) {
- // rethrow ThreaDeath in order to make sure that RAP will properly clean
- // up the UI thread
- if (e instanceof ThreadDeath)
- throw (ThreadDeath) e;
-
- new FeedbackDialog(getDisplay().getActiveShell(), message, e).open();
- }
-
- public static void show(String message) {
- new FeedbackDialog(getDisplay().getActiveShell(), message, null).open();
- }
-
- /** Tries to find a display */
- private static Display getDisplay() {
- try {
- Display display = Display.getCurrent();
- if (display != null)
- return display;
- else
- return Display.getDefault();
- } catch (Exception e) {
- return Display.getCurrent();
- }
- }
-
- public FeedbackDialog(Shell parentShell, String message, Throwable e) {
- super(parentShell);
- this.message = message;
- this.exception = e;
- log.error(message, e);
- }
-
- public int open() {
- if (shell != null)
- throw new EclipseUiException("There is already a shell");
- shell = new Shell(getDisplay(), SWT.NO_TRIM | SWT.BORDER | SWT.ON_TOP);
- shell.setLayout(new GridLayout());
- // shell.setText("Error");
- shell.setSize(getInitialSize());
- createDialogArea(shell);
- // shell.pack();
- // shell.layout();
-
- Rectangle shellBounds = Display.getCurrent().getBounds();// RAP
- Point dialogSize = shell.getSize();
- int x = shellBounds.x + (shellBounds.width - dialogSize.x) / 2;
- int y = shellBounds.y + (shellBounds.height - dialogSize.y) / 2;
- shell.setLocation(x, y);
-
- shell.addShellListener(new ShellAdapter() {
- private static final long serialVersionUID = -2701270481953688763L;
-
- @Override
- public void shellDeactivated(ShellEvent e) {
- closeShell();
- }
- });
-
- shell.open();
- return OK;
- }
-
- protected void closeShell() {
- shell.close();
- shell.dispose();
- shell = null;
- }
-
- protected Point getInitialSize() {
- // if (exception != null)
- // return new Point(800, 600);
- // else
- return new Point(400, 300);
- }
-
- protected Control createDialogArea(Composite parent) {
- Composite dialogarea = new Composite(parent, SWT.NONE);
- dialogarea.setLayout(new GridLayout());
- // Composite dialogarea = (Composite) super.createDialogArea(parent);
- dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-
- Label messageLbl = new Label(dialogarea, SWT.NONE);
- if (message != null)
- messageLbl.setText(message);
- else if (exception != null)
- messageLbl.setText(exception.getLocalizedMessage());
-
- Composite composite = new Composite(dialogarea, SWT.NONE);
- composite.setLayout(new GridLayout(2, false));
- composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-
- if (exception != null) {
- Text stack = new Text(composite, SWT.MULTI | SWT.LEAD | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
- stack.setEditable(false);
- stack.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- StringWriter sw = new StringWriter();
- exception.printStackTrace(new PrintWriter(sw));
- stack.setText(sw.toString());
- }
-
- // parent.pack();
- return composite;
- }
-}
\ No newline at end of file
+++ /dev/null
-package org.argeo.eclipse.ui.dialogs;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.eclipse.ui.EclipseUiException;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.FocusEvent;
-import org.eclipse.swt.events.FocusListener;
-import org.eclipse.swt.events.ShellAdapter;
-import org.eclipse.swt.events.ShellEvent;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-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.Display;
-import org.eclipse.swt.widgets.Shell;
-
-/** Generic lightweight dialog, not based on JFace. */
-@Deprecated
-public class LightweightDialog {
- private final static Log log = LogFactory.getLog(LightweightDialog.class);
-
- // must be the same value as org.eclipse.jface.window.Window#OK
- public final static int OK = 0;
- // must be the same value as org.eclipse.jface.window.Window#CANCEL
- public final static int CANCEL = 1;
-
- private Shell parentShell;
- private Shell backgroundShell;
- private Shell foregoundShell;
-
- private Integer returnCode = null;
- private boolean block = true;
-
- private String title;
-
- /** Tries to find a display */
- private static Display getDisplay() {
- try {
- Display display = Display.getCurrent();
- if (display != null)
- return display;
- else
- return Display.getDefault();
- } catch (Exception e) {
- return Display.getCurrent();
- }
- }
-
- public LightweightDialog(Shell parentShell) {
- this.parentShell = parentShell;
- }
-
- public int open() {
- if (foregoundShell != null)
- throw new EclipseUiException("There is already a shell");
- backgroundShell = new Shell(parentShell, SWT.ON_TOP);
- backgroundShell.setFullScreen(true);
- // if (parentShell != null) {
- // backgroundShell.setBounds(parentShell.getBounds());
- // } else
- // backgroundShell.setMaximized(true);
- backgroundShell.setAlpha(128);
- backgroundShell.setBackground(getDisplay().getSystemColor(SWT.COLOR_BLACK));
- foregoundShell = new Shell(backgroundShell, SWT.NO_TRIM | SWT.ON_TOP);
- if (title != null)
- setTitle(title);
- foregoundShell.setLayout(new GridLayout());
- foregoundShell.setSize(getInitialSize());
- createDialogArea(foregoundShell);
- // shell.pack();
- // shell.layout();
-
- Rectangle shellBounds = parentShell != null ? parentShell.getBounds() : Display.getCurrent().getBounds();// RAP
- Point dialogSize = foregoundShell.getSize();
- int x = shellBounds.x + (shellBounds.width - dialogSize.x) / 2;
- int y = shellBounds.y + (shellBounds.height - dialogSize.y) / 2;
- foregoundShell.setLocation(x, y);
-
- foregoundShell.addShellListener(new ShellAdapter() {
- private static final long serialVersionUID = -2701270481953688763L;
-
- @Override
- public void shellDeactivated(ShellEvent e) {
- if (hasChildShells())
- return;
- if (returnCode == null)// not yet closed
- closeShell(CANCEL);
- }
-
- @Override
- public void shellClosed(ShellEvent e) {
- notifyClose();
- }
-
- });
-
- backgroundShell.open();
- foregoundShell.open();
- // after the foreground shell has been opened
- backgroundShell.addFocusListener(new FocusListener() {
- private static final long serialVersionUID = 3137408447474661070L;
-
- @Override
- public void focusLost(FocusEvent event) {
- }
-
- @Override
- public void focusGained(FocusEvent event) {
- if (hasChildShells())
- return;
- if (returnCode == null)// not yet closed
- closeShell(CANCEL);
- }
- });
-
- if (block) {
- block();
- }
- if (returnCode == null)
- returnCode = OK;
- return returnCode;
- }
-
- public void block() {
- try {
- runEventLoop(foregoundShell);
- } catch (ThreadDeath t) {
- returnCode = CANCEL;
- if (log.isTraceEnabled())
- log.error("Thread death, canceling dialog", t);
- } catch (Throwable t) {
- returnCode = CANCEL;
- log.error("Cannot open blocking lightweight dialog", t);
- }
- }
-
- private boolean hasChildShells() {
- if (foregoundShell == null)
- return false;
- return foregoundShell.getShells().length != 0;
- }
-
- // public synchronized int openAndWait() {
- // open();
- // while (returnCode == null)
- // try {
- // wait(100);
- // } catch (InterruptedException e) {
- // // silent
- // }
- // return returnCode;
- // }
-
- private synchronized void notifyClose() {
- if (returnCode == null)
- returnCode = CANCEL;
- notifyAll();
- }
-
- protected void closeShell(int returnCode) {
- this.returnCode = returnCode;
- if (CANCEL == returnCode)
- onCancel();
- if (foregoundShell != null && !foregoundShell.isDisposed()) {
- foregoundShell.close();
- foregoundShell.dispose();
- foregoundShell = null;
- }
-
- if (backgroundShell != null && !backgroundShell.isDisposed()) {
- backgroundShell.close();
- backgroundShell.dispose();
- }
- }
-
- protected Point getInitialSize() {
- // if (exception != null)
- // return new Point(800, 600);
- // else
- return new Point(600, 400);
- }
-
- protected Control createDialogArea(Composite parent) {
- Composite dialogarea = new Composite(parent, SWT.NONE);
- dialogarea.setLayout(new GridLayout());
- dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- return dialogarea;
- }
-
- protected Shell getBackgroundShell() {
- return backgroundShell;
- }
-
- protected Shell getForegoundShell() {
- return foregoundShell;
- }
-
- public void setBlockOnOpen(boolean shouldBlock) {
- block = shouldBlock;
- }
-
- public void pack() {
- foregoundShell.pack();
- }
-
- private void runEventLoop(Shell loopShell) {
- Display display;
- if (foregoundShell == null) {
- display = Display.getCurrent();
- } else {
- display = loopShell.getDisplay();
- }
-
- while (loopShell != null && !loopShell.isDisposed()) {
- try {
- if (!display.readAndDispatch()) {
- display.sleep();
- }
- } catch (UnsupportedOperationException e) {
- throw e;
- } catch (Throwable e) {
- handleException(e);
- }
- }
- if (!display.isDisposed())
- display.update();
- }
-
- protected void handleException(Throwable t) {
- if (t instanceof ThreadDeath) {
- // Don't catch ThreadDeath as this is a normal occurrence when
- // the thread dies
- throw (ThreadDeath) t;
- }
- // Try to keep running.
- t.printStackTrace();
- }
-
- /** @return false, if the dialog should not be closed. */
- protected boolean onCancel() {
- return true;
- }
-
- public void setTitle(String title) {
- this.title = title;
- if (title != null && getForegoundShell() != null)
- getForegoundShell().setText(title);
- }
-
- public Integer getReturnCode() {
- return returnCode;
- }
-
-}
\ No newline at end of file
+++ /dev/null
-package org.argeo.eclipse.ui.dialogs;
-
-import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.eclipse.jface.dialogs.IMessageProvider;
-import org.eclipse.jface.dialogs.TitleAreaDialog;
-import org.eclipse.jface.window.Window;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Point;
-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.Display;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-
-/**
- * Dialog to retrieve a single value.
- *
- * @deprecated Use CMS dialogs instead.
- */
-@Deprecated
-public class SingleValue extends TitleAreaDialog {
- private static final long serialVersionUID = 2843538207460082349L;
-
- private Text valueT;
- private String value;
- private final String title, message, label;
- private final Boolean multiline;
-
- public static String ask(String label, String message) {
- SingleValue svd = new SingleValue(label, message);
- if (svd.open() == Window.OK)
- return svd.getString();
- else
- return null;
- }
-
- public static Long askLong(String label, String message) {
- SingleValue svd = new SingleValue(label, message);
- if (svd.open() == Window.OK)
- return svd.getLong();
- else
- return null;
- }
-
- public static Double askDouble(String label, String message) {
- SingleValue svd = new SingleValue(label, message);
- if (svd.open() == Window.OK)
- return svd.getDouble();
- else
- return null;
- }
-
- public SingleValue(String label, String message) {
- this(Display.getDefault().getActiveShell(), label, message, label, false);
- }
-
- public SingleValue(Shell parentShell, String title, String message, String label, Boolean multiline) {
- super(parentShell);
- this.title = title;
- this.message = message;
- this.label = label;
- this.multiline = multiline;
- }
-
- protected Point getInitialSize() {
- if (multiline)
- return new Point(450, 350);
-
- else
- return new Point(400, 270);
- }
-
- protected Control createDialogArea(Composite parent) {
- Composite dialogarea = (Composite) super.createDialogArea(parent);
- dialogarea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- Composite composite = new Composite(dialogarea, SWT.NONE);
- composite.setLayoutData(EclipseUiUtils.fillAll());
- GridLayout layout = new GridLayout(2, false);
- layout.marginWidth = layout.marginHeight = 20;
- composite.setLayout(layout);
-
- valueT = createLT(composite, label);
-
- setMessage(message, IMessageProvider.NONE);
-
- parent.pack();
- valueT.setFocus();
- return composite;
- }
-
- @Override
- protected void okPressed() {
- value = valueT.getText();
- super.okPressed();
- }
-
- /** Creates label and text. */
- protected Text createLT(Composite parent, String label) {
- new Label(parent, SWT.NONE).setText(label);
- Text text;
- if (multiline) {
- text = new Text(parent, SWT.LEAD | SWT.BORDER | SWT.MULTI);
- text.setLayoutData(EclipseUiUtils.fillAll());
- } else {
- text = new Text(parent, SWT.LEAD | SWT.BORDER | SWT.SINGLE);
- text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
- }
- return text;
- }
-
- protected void configureShell(Shell shell) {
- super.configureShell(shell);
- shell.setText(title);
- }
-
- public String getString() {
- return value;
- }
-
- public Long getLong() {
- return Long.valueOf(getString());
- }
-
- public Double getDouble() {
- return Double.valueOf(getString());
- }
-}
+++ /dev/null
-/** Generic SWT/JFace dialogs. */
-package org.argeo.eclipse.ui.dialogs;
\ No newline at end of file
+++ /dev/null
-package org.argeo.eclipse.ui.fs;
-
-import java.io.IOException;
-import java.nio.file.DirectoryStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.LinkedHashMap;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.SashForm;
-import org.eclipse.swt.custom.ScrolledComposite;
-import org.eclipse.swt.events.ControlAdapter;
-import org.eclipse.swt.events.ControlEvent;
-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.graphics.Rectangle;
-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.Label;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.Text;
-
-/** Simple UI provider that populates a composite parent given a NIO path */
-public class AdvancedFsBrowser {
- private final static Log log = LogFactory.getLog(AdvancedFsBrowser.class);
-
- // Some local constants to experiment. should be cleaned
- // private final static int THUMBNAIL_WIDTH = 400;
- // private Point imageWidth = new Point(250, 0);
- private final static int COLUMN_WIDTH = 160;
-
- private Path initialPath;
- private Path currEdited;
- // Filter
- private Composite displayBoxCmp;
- private Text parentPathTxt;
- private Text filterTxt;
- // Browser columns
- private ScrolledComposite scrolledCmp;
- // Keep a cache of the opened directories
- private LinkedHashMap<Path, FilterEntitiesVirtualTable> browserCols = new LinkedHashMap<>();
- private Composite scrolledCmpBody;
-
- public Control createUi(Composite parent, Path basePath) {
- if (basePath == null)
- throw new IllegalArgumentException("Context cannot be null");
- parent.setLayout(new GridLayout());
-
- // top filter
- Composite filterCmp = new Composite(parent, SWT.NO_FOCUS);
- filterCmp.setLayoutData(EclipseUiUtils.fillWidth());
- addFilterPanel(filterCmp);
-
- // Bottom part a sash with browser on the left
- SashForm form = new SashForm(parent, SWT.HORIZONTAL);
- // form.setLayout(new FillLayout());
- form.setLayoutData(EclipseUiUtils.fillAll());
- Composite leftCmp = new Composite(form, SWT.NO_FOCUS);
- displayBoxCmp = new Composite(form, SWT.NONE);
- form.setWeights(new int[] { 3, 1 });
-
- createBrowserPart(leftCmp, basePath);
- // leftCmp.addControlListener(new ControlAdapter() {
- // @Override
- // public void controlResized(ControlEvent e) {
- // Rectangle r = leftCmp.getClientArea();
- // log.warn("Browser resized: " + r.toString());
- // scrolledCmp.setMinSize(browserCols.size() * (COLUMN_WIDTH + 2),
- // SWT.DEFAULT);
- // // scrolledCmp.setMinSize(scrolledCmpBody.computeSize(SWT.DEFAULT,
- // // r.height));
- // }
- // });
-
- populateCurrEditedDisplay(displayBoxCmp, basePath);
-
- // INIT
- setEdited(basePath);
- initialPath = basePath;
- // form.layout(true, true);
- return parent;
- }
-
- private void createBrowserPart(Composite parent, Path context) {
- parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
-
- // scrolled composite
- scrolledCmp = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.BORDER | SWT.NO_FOCUS);
- scrolledCmp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- scrolledCmp.setExpandVertical(true);
- scrolledCmp.setExpandHorizontal(true);
- scrolledCmp.setShowFocusedControl(true);
-
- scrolledCmpBody = new Composite(scrolledCmp, SWT.NO_FOCUS);
- scrolledCmp.setContent(scrolledCmpBody);
- scrolledCmpBody.addControlListener(new ControlAdapter() {
- private static final long serialVersionUID = 183238447102854553L;
-
- @Override
- public void controlResized(ControlEvent e) {
- Rectangle r = scrolledCmp.getClientArea();
- scrolledCmp.setMinSize(scrolledCmpBody.computeSize(SWT.DEFAULT, r.height));
- }
- });
- initExplorer(scrolledCmpBody, context);
- scrolledCmpBody.layout(true, true);
- scrolledCmp.layout();
-
- }
-
- private Control initExplorer(Composite parent, Path context) {
- parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
- return createBrowserColumn(parent, context);
- }
-
- private Control createBrowserColumn(Composite parent, Path context) {
- // TODO style is not correctly managed.
- FilterEntitiesVirtualTable table = new FilterEntitiesVirtualTable(parent, SWT.BORDER | SWT.NO_FOCUS, context);
- // CmsUtils.style(table, ArgeoOrgStyle.browserColumn.style());
- table.filterList("*");
- table.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, true));
- browserCols.put(context, table);
- parent.layout(true, true);
- return table;
- }
-
- public void addFilterPanel(Composite parent) {
- parent.setLayout(EclipseUiUtils.noSpaceGridLayout(new GridLayout(2, false)));
-
- parentPathTxt = new Text(parent, SWT.NO_FOCUS);
- parentPathTxt.setEditable(false);
-
- filterTxt = new Text(parent, SWT.SEARCH | SWT.ICON_CANCEL);
- filterTxt.setMessage("Filter current list");
- filterTxt.setLayoutData(EclipseUiUtils.fillWidth());
- 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(currEdited, 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 FsUiException(
- "Unable to determine unique child existence and get it under " + parent + " with filter " + filter,
- ioe);
- }
- }
-
- private void setEdited(Path path) {
- currEdited = path;
- EclipseUiUtils.clear(displayBoxCmp);
- populateCurrEditedDisplay(displayBoxCmp, currEdited);
- refreshFilters(path);
- refreshBrowser(path);
- }
-
- private void refreshFilters(Path path) {
- parentPathTxt.setText(path.toUri().toString());
- filterTxt.setText("");
- filterTxt.getParent().layout();
- }
-
- private void refreshBrowser(Path currPath) {
- Path currParPath = currPath.getParent();
- Object[][] colMatrix = new Object[browserCols.size()][2];
-
- int i = 0, currPathIndex = -1, lastLeftOpenedIndex = -1;
- for (Path path : browserCols.keySet()) {
- colMatrix[i][0] = path;
- colMatrix[i][1] = browserCols.get(path);
- if (currPathIndex >= 0 && lastLeftOpenedIndex < 0 && currParPath != null) {
- boolean leaveOpened = path.startsWith(currPath);
- if (!leaveOpened)
- lastLeftOpenedIndex = i;
- }
- if (currParPath.equals(path))
- currPathIndex = i;
- i++;
- }
-
- if (currPathIndex >= 0 && lastLeftOpenedIndex >= 0) {
- // dispose and remove useless cols
- for (int l = i - 1; l >= lastLeftOpenedIndex; l--) {
- ((FilterEntitiesVirtualTable) colMatrix[l][1]).dispose();
- browserCols.remove(colMatrix[l][0]);
- }
- }
-
- if (browserCols.containsKey(currPath)) {
- FilterEntitiesVirtualTable currCol = browserCols.get(currPath);
- if (currCol.isDisposed()) {
- // Does it still happen ?
- log.warn(currPath + " browser column was disposed and still listed");
- browserCols.remove(currPath);
- }
- }
-
- if (!browserCols.containsKey(currPath) && Files.isDirectory(currPath))
- createBrowserColumn(scrolledCmpBody, currPath);
-
- scrolledCmpBody.setLayout(EclipseUiUtils.noSpaceGridLayout(new GridLayout(browserCols.size(), false)));
- scrolledCmpBody.layout(true, true);
- // also resize the scrolled composite
- scrolledCmp.layout();
- }
-
- private void modifyFilter(boolean fromOutside) {
- if (!fromOutside)
- if (currEdited != null) {
- String filter = filterTxt.getText() + "*";
- FilterEntitiesVirtualTable table = browserCols.get(currEdited);
- if (table != null && !table.isDisposed())
- table.filterList(filter);
- }
- }
-
- /**
- * Recreates the content of the box that displays information about the current
- * selected node.
- */
- private void populateCurrEditedDisplay(Composite parent, Path context) {
- parent.setLayout(new GridLayout());
-
- // if (isImg(context)) {
- // EditableImage image = new Img(parent, RIGHT, context, imageWidth);
- // image.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false,
- // 2, 1));
- // }
-
- try {
- Label contextL = new Label(parent, SWT.NONE);
- contextL.setText(context.getFileName().toString());
- contextL.setFont(EclipseUiUtils.getBoldFont(parent));
- addProperty(parent, "Last modified", Files.getLastModifiedTime(context).toString());
- addProperty(parent, "Owner", Files.getOwner(context).getName());
- if (Files.isDirectory(context)) {
- addProperty(parent, "Type", "Folder");
- } else {
- String mimeType = Files.probeContentType(context);
- if (EclipseUiUtils.isEmpty(mimeType))
- mimeType = "<i>Unknown</i>";
- addProperty(parent, "Type", mimeType);
- addProperty(parent, "Size", FsUiUtils.humanReadableByteCount(Files.size(context), false));
- }
- parent.layout(true, true);
- } catch (IOException e) {
- throw new FsUiException("Cannot display details for " + context, e);
- }
- }
-
- private void addProperty(Composite parent, String propName, String value) {
- Label contextL = new Label(parent, SWT.NONE);
- contextL.setText(propName + ": " + value);
- }
-
- /**
- * Almost canonical implementation of a table that displays the content of a
- * directory
- */
- private class FilterEntitiesVirtualTable extends Composite {
- private static final long serialVersionUID = 2223410043691844875L;
-
- // Context
- private Path context;
- private Path currSelected = null;
-
- // UI Objects
- private FsTableViewer viewer;
-
- @Override
- public boolean setFocus() {
- if (viewer.getTable().isDisposed())
- return false;
- if (currSelected != null)
- viewer.setSelection(new StructuredSelection(currSelected), true);
- else if (viewer.getSelection().isEmpty()) {
- Object first = viewer.getElementAt(0);
- if (first != null)
- viewer.setSelection(new StructuredSelection(first), true);
- }
- return viewer.getTable().setFocus();
- }
-
- /**
- * Enable highlighting the correct element in the table when externally browsing
- * (typically via the command-line-like Text field)
- */
- void setSelected(Path selected) {
- // to prevent change selection event to be thrown
- currSelected = selected;
- viewer.setSelection(new StructuredSelection(currSelected), true);
- }
-
- void filterList(String filter) {
- viewer.setInput(context, filter);
- }
-
- public FilterEntitiesVirtualTable(Composite parent, int style, Path context) {
- super(parent, SWT.NO_FOCUS);
- this.context = context;
- createTableViewer(this);
- }
-
- private void createTableViewer(final Composite parent) {
- parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
-
- // We must limit the size of the table otherwise the full list is
- // loaded before the layout happens
- // Composite listCmp = new Composite(parent, SWT.NO_FOCUS);
- // GridData gd = new GridData(SWT.LEFT, SWT.FILL, false, true);
- // gd.widthHint = COLUMN_WIDTH;
- // listCmp.setLayoutData(gd);
- // listCmp.setLayout(EclipseUiUtils.noSpaceGridLayout());
- // viewer = new TableViewer(listCmp, SWT.VIRTUAL | SWT.MULTI |
- // SWT.V_SCROLL);
- // Table table = viewer.getTable();
- // table.setLayoutData(EclipseUiUtils.fillAll());
-
- viewer = new FsTableViewer(parent, SWT.MULTI);
- Table table = viewer.configureDefaultSingleColumnTable(COLUMN_WIDTH);
-
- viewer.addSelectionChangedListener(new ISelectionChangedListener() {
-
- @Override
- public void selectionChanged(SelectionChangedEvent event) {
- IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
- if (selection.isEmpty())
- return;
- Object obj = selection.getFirstElement();
- Path newSelected;
- if (obj instanceof Path)
- newSelected = (Path) obj;
- else if (obj instanceof ParentDir)
- newSelected = ((ParentDir) obj).getPath();
- else
- return;
- if (newSelected.equals(currSelected))
- return;
- currSelected = newSelected;
- setEdited(newSelected);
-
- }
- });
-
- table.addKeyListener(new KeyListener() {
- private static final long serialVersionUID = -8083424284436715709L;
-
- @Override
- public void keyReleased(KeyEvent e) {
- }
-
- @Override
- public void keyPressed(KeyEvent e) {
- IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
- Path selected = null;
- if (!selection.isEmpty())
- selected = ((Path) selection.getFirstElement());
- if (e.keyCode == SWT.ARROW_RIGHT) {
- if (!Files.isDirectory(selected))
- return;
- if (selected != null) {
- setEdited(selected);
- browserCols.get(selected).setFocus();
- }
- } else if (e.keyCode == SWT.ARROW_LEFT) {
- if (context.equals(initialPath))
- return;
- Path parent = context.getParent();
- if (parent == null)
- return;
-
- setEdited(parent);
- browserCols.get(parent).setFocus();
- }
- }
- });
- }
- }
-}
+++ /dev/null
-package org.argeo.eclipse.ui.fs;
-
-import java.nio.file.Files;
-import java.nio.file.Path;
-
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-import org.eclipse.swt.graphics.Image;
-
-/** Basic label provider with icon for NIO file viewers */
-public class FileIconNameLabelProvider extends ColumnLabelProvider {
- private static final long serialVersionUID = 8187902187946523148L;
-
- private Image folderIcon;
- private Image fileIcon;
-
- public FileIconNameLabelProvider() {
- // if (!PlatformUI.isWorkbenchRunning()) {
- folderIcon = ImageDescriptor.createFromFile(getClass(), "folder.png").createImage();
- fileIcon = ImageDescriptor.createFromFile(getClass(), "file.png").createImage();
- // }
- }
-
- @Override
- public void dispose() {
- if (folderIcon != null)
- folderIcon.dispose();
- if (fileIcon != null)
- fileIcon.dispose();
- super.dispose();
- }
-
- @Override
- public String getText(Object element) {
- if (element instanceof Path) {
- Path curr = ((Path) element);
- Path name = curr.getFileName();
- if (name == null)
- return "[No name]";
- else
- return name.toString();
- } else if (element instanceof ParentDir) {
- return "..";
- }
- return null;
- }
-
- @Override
- public Image getImage(Object element) {
- if (element instanceof Path) {
- Path curr = ((Path) element);
- if (Files.isDirectory(curr))
- // if (folderIcon != null)
- return folderIcon;
- // else
- // return
- // PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER);
- // else if (fileIcon != null)
- return fileIcon;
- // else
- // return
- // PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FILE);
- } else if (element instanceof ParentDir) {
- return folderIcon;
- }
- return null;
- }
-
- @Override
- public String getToolTipText(Object element) {
- if (element instanceof Path) {
- Path curr = ((Path) element);
- Path name = curr.getFileName();
- if (name == null)
- return "[No name]";
- else
- return name.toAbsolutePath().toString();
- } else if (element instanceof ParentDir) {
- return ((ParentDir) element).getPath().toAbsolutePath().toString();
- }
- return null;
- }
-
-}
\ No newline at end of file
+++ /dev/null
-package org.argeo.eclipse.ui.fs;
-
-import java.nio.file.Path;
-import java.util.List;
-
-import org.argeo.eclipse.ui.ColumnDefinition;
-import org.eclipse.jface.viewers.CellLabelProvider;
-import org.eclipse.jface.viewers.ILazyContentProvider;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.TableViewerColumn;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-
-/**
- * Canonical implementation of a JFace table viewer to display the content of a
- * file folder
- */
-public class FsTableViewer extends TableViewer {
- private static final long serialVersionUID = -5632407542678477234L;
-
- private boolean showHiddenItems = false;
- private boolean folderFirst = true;
- private boolean reverseOrder = false;
- private String orderProperty = FsUiConstants.PROPERTY_NAME;
-
- private Path initialPath = null;
-
- public FsTableViewer(Composite parent, int style) {
- super(parent, style | SWT.VIRTUAL);
- }
-
- public Table configureDefaultSingleColumnTable(int tableWidthHint) {
-
- return configureDefaultSingleColumnTable(tableWidthHint, new FileIconNameLabelProvider());
- }
-
- public Table configureDefaultSingleColumnTable(int tableWidthHint, CellLabelProvider labelProvider) {
- Table table = this.getTable();
- table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
- table.setLinesVisible(false);
- table.setHeaderVisible(false);
- // CmsUtils.markup(table);
- // CmsUtils.style(table, MaintenanceStyles.BROWSER_COLUMN);
-
- TableViewerColumn column = new TableViewerColumn(this, SWT.NONE);
- TableColumn tcol = column.getColumn();
- tcol.setWidth(tableWidthHint);
- column.setLabelProvider(labelProvider);
- this.setContentProvider(new MyLazyCP());
- return table;
- }
-
- public Table configureDefaultTable(List<ColumnDefinition> columns) {
- this.setContentProvider(new MyLazyCP());
- Table table = this.getTable();
- table.setLinesVisible(true);
- table.setHeaderVisible(true);
- // CmsUtils.markup(table);
- // CmsUtils.style(table, MaintenanceStyles.BROWSER_COLUMN);
- for (ColumnDefinition colDef : columns) {
- TableViewerColumn column = new TableViewerColumn(this, SWT.NONE);
- column.setLabelProvider(colDef.getLabelProvider());
- TableColumn tcol = column.getColumn();
- tcol.setResizable(true);
- tcol.setText(colDef.getLabel());
- tcol.setWidth(colDef.getMinWidth());
- }
- return table;
- }
-
- public void setInput(Path dir, String filter) {
- Path[] rows = FsUiUtils.getChildren(dir, filter, showHiddenItems, folderFirst, orderProperty, reverseOrder);
- if (rows == null) {
- this.setInput(null);
- this.setItemCount(0);
- return;
- }
- boolean isRoot;
- try {
- isRoot = dir.getRoot().equals(dir);
- } catch (Exception e) {
- // FIXME Workaround for JCR root node access
- isRoot = dir.toString().equals("/");
- }
- final Object[] res;
- if (isRoot)
- res = rows;
- else if (initialPath != null && initialPath.equals(dir))
- res = rows;
- else {
- res = new Object[rows.length + 1];
- res[0] = new ParentDir(dir.getParent());
- for (int i = 1; i < res.length; i++) {
- res[i] = rows[i - 1];
- }
- }
- this.setInput(res);
- int length = res.length;
- this.setItemCount(length);
- this.refresh();
- }
-
- /** Directly displays bookmarks **/
- public void setPathsInput(Path... paths) {
- this.setInput((Object[]) paths);
- this.setItemCount(paths.length);
- this.refresh();
- }
-
- /**
- * A path which is to be considered as root (and thus provide no link to a
- * parent directory)
- */
- public void setInitialPath(Path initialPath) {
- this.initialPath = initialPath;
- }
-
- private class MyLazyCP implements ILazyContentProvider {
- private static final long serialVersionUID = 9096550041395433128L;
- private Object[] elements;
-
- public void dispose() {
- }
-
- public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
- // IMPORTANT: don't forget this: an exception will be thrown if
- // a selected object is not part of the results anymore.
- viewer.setSelection(null);
- this.elements = (Object[]) newInput;
- }
-
- public void updateElement(int index) {
- if (index < elements.length)
- FsTableViewer.this.replace(elements[index], index);
- }
- }
-}
+++ /dev/null
-package org.argeo.eclipse.ui.fs;
-
-import java.io.IOException;
-import java.nio.file.DirectoryIteratorException;
-import java.nio.file.DirectoryStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.argeo.eclipse.ui.ColumnDefinition;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.jface.viewers.TreeViewerColumn;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Tree;
-import org.eclipse.swt.widgets.TreeColumn;
-
-/**
- * Canonical implementation of a JFace TreeViewer to display the content of a
- * repository
- */
-public class FsTreeViewer extends TreeViewer {
- private static final long serialVersionUID = -5632407542678477234L;
-
- private boolean showHiddenItems = false;
- private boolean showDirectoryFirst = true;
- private String orderingProperty = FsUiConstants.PROPERTY_NAME;
-
- public FsTreeViewer(Composite parent, int style) {
- super(parent, style | SWT.VIRTUAL);
- }
-
- public Tree configureDefaultSingleColumnTable(int tableWidthHint) {
- Tree tree = this.getTree();
- tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
- tree.setLinesVisible(true);
- tree.setHeaderVisible(false);
-// CmsUtils.markup(tree);
-
- TreeViewerColumn column = new TreeViewerColumn(this, SWT.NONE);
- TreeColumn tcol = column.getColumn();
- tcol.setWidth(tableWidthHint);
- column.setLabelProvider(new FileIconNameLabelProvider());
-
- this.setContentProvider(new MyCP());
- return tree;
- }
-
- public Tree configureDefaultTable(List<ColumnDefinition> columns) {
- this.setContentProvider(new MyCP());
- Tree tree = this.getTree();
- tree.setLinesVisible(true);
- tree.setHeaderVisible(true);
-// CmsUtils.markup(tree);
-// CmsUtils.style(tree, MaintenanceStyles.BROWSER_COLUMN);
- for (ColumnDefinition colDef : columns) {
- TreeViewerColumn column = new TreeViewerColumn(this, SWT.NONE);
- column.setLabelProvider(colDef.getLabelProvider());
- TreeColumn tcol = column.getColumn();
- tcol.setResizable(true);
- tcol.setText(colDef.getLabel());
- tcol.setWidth(colDef.getMinWidth());
- }
- return tree;
- }
-
- public void setInput(Path dir, String filter) {
- try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, filter)) {
- // TODO make this lazy
- List<Path> paths = new ArrayList<>();
- for (Path entry : stream) {
- paths.add(entry);
- }
- Object[] rows = paths.toArray(new Object[0]);
- this.setInput(rows);
- // this.setItemCount(rows.length);
- this.refresh();
- } catch (IOException | DirectoryIteratorException e) {
- throw new FsUiException("Unable to filter " + dir + " children with filter " + filter, e);
- }
- }
-
- /** Directly displays bookmarks **/
- public void setPathsInput(Path... paths) {
- this.setInput((Object[]) paths);
- // this.setItemCount(paths.length);
- this.refresh();
- }
-
- private class MyCP implements ITreeContentProvider {
- private static final long serialVersionUID = 9096550041395433128L;
- private Object[] elements;
-
- public void dispose() {
- }
-
- public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
- // IMPORTANT: don't forget this: an exception will be thrown if
- // a selected object is not part of the results anymore.
- viewer.setSelection(null);
- this.elements = (Object[]) newInput;
- }
-
- @Override
- public Object[] getElements(Object inputElement) {
- return elements;
- }
-
- @Override
- public Object[] getChildren(Object parentElement) {
- Path path = (Path) parentElement;
- if (!Files.isDirectory(path))
- return null;
- else
- return FsUiUtils.getChildren(path, "*", showHiddenItems, showDirectoryFirst, orderingProperty, false);
- }
-
- @Override
- public Object getParent(Object element) {
- Path path = (Path) element;
- return path.getParent();
- }
-
- @Override
- public boolean hasChildren(Object element) {
- Path path = (Path) element;
- try {
- if (!Files.isDirectory(path))
- return false;
- else
- try (DirectoryStream<Path> children = Files.newDirectoryStream(path, "*")) {
- return children.iterator().hasNext();
- }
- } catch (IOException e) {
- throw new FsUiException("Unable to check child existence on " + path, e);
- }
- }
-
- }
-}
+++ /dev/null
-package org.argeo.eclipse.ui.fs;
-
-/** Centralize constants used by the Nio FS UI parts */
-public interface FsUiConstants {
-
- // TODO use standard properties
- String PROPERTY_NAME = "name";
- String PROPERTY_SIZE = "size";
- String PROPERTY_LAST_MODIFIED = "last-modified";
- String PROPERTY_TYPE = "type";
-}
+++ /dev/null
-package org.argeo.eclipse.ui.fs;
-
-/** Files specific exception */
-public class FsUiException extends RuntimeException {
- private static final long serialVersionUID = 1L;
-
- public FsUiException(String message) {
- super(message);
- }
-
- public FsUiException(String message, Throwable e) {
- super(message, e);
- }
-}
+++ /dev/null
-package org.argeo.eclipse.ui.fs;
-
-import java.io.IOException;
-import java.nio.file.DirectoryIteratorException;
-import java.nio.file.DirectoryStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/** Centralise additional utilitary methods to manage Java7 NIO files */
-public class FsUiUtils {
-
- /**
- * thanks to
- * http://programming.guide/java/formatting-byte-size-to-human-readable-format.html
- */
- public static String humanReadableByteCount(long bytes, boolean si) {
- int unit = si ? 1000 : 1024;
- if (bytes < unit)
- return bytes + " B";
- int exp = (int) (Math.log(bytes) / Math.log(unit));
- String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i");
- return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
- }
-
- public static Path[] getChildren(Path parent, String filter, boolean showHiddenItems, boolean folderFirst,
- String orderProperty, boolean reverseOrder) {
- if (!Files.isDirectory(parent))
- return null;
- List<Pair> pairs = new ArrayList<>();
- try (DirectoryStream<Path> stream = Files.newDirectoryStream(parent, filter)) {
- loop: for (Path entry : stream) {
- if (!showHiddenItems)
- if (Files.isHidden(entry))
- continue loop;
- switch (orderProperty) {
- case FsUiConstants.PROPERTY_SIZE:
- if (folderFirst)
- pairs.add(new LPair(entry, Files.size(entry), Files.isDirectory(entry)));
- else
- pairs.add(new LPair(entry, Files.size(entry)));
- break;
- case FsUiConstants.PROPERTY_LAST_MODIFIED:
- if (folderFirst)
- pairs.add(new LPair(entry, Files.getLastModifiedTime(entry).toMillis(),
- Files.isDirectory(entry)));
- else
- pairs.add(new LPair(entry, Files.getLastModifiedTime(entry).toMillis()));
- break;
- case FsUiConstants.PROPERTY_NAME:
- if (folderFirst)
- pairs.add(new SPair(entry, entry.getFileName().toString(), Files.isDirectory(entry)));
- else
- pairs.add(new SPair(entry, entry.getFileName().toString()));
- break;
- default:
- throw new FsUiException("Unable to prepare sort for property " + orderProperty);
- }
- }
- Pair[] rows = pairs.toArray(new Pair[0]);
- Arrays.sort(rows);
- Path[] results = new Path[rows.length];
- if (reverseOrder) {
- int j = rows.length - 1;
- for (int i = 0; i < rows.length; i++)
- results[i] = rows[j - i].p;
- } else
- for (int i = 0; i < rows.length; i++)
- results[i] = rows[i].p;
- return results;
- } catch (IOException | DirectoryIteratorException e) {
- throw new FsUiException("Unable to filter " + parent + " children with filter " + filter, e);
- }
- }
-
- static abstract class Pair implements Comparable<Object> {
- Path p;
- Boolean i;
- };
-
- static class LPair extends Pair {
- long v;
-
- public LPair(Path path, long propValue) {
- p = path;
- v = propValue;
- }
-
- public LPair(Path path, long propValue, boolean isDir) {
- p = path;
- v = propValue;
- i = isDir;
- }
-
- public int compareTo(Object o) {
- if (i != null) {
- Boolean j = ((LPair) o).i;
- if (i.booleanValue() != j.booleanValue())
- return i.booleanValue() ? -1 : 1;
- }
- long u = ((LPair) o).v;
- return v < u ? -1 : v == u ? 0 : 1;
- }
- };
-
- static class SPair extends Pair {
- String v;
-
- public SPair(Path path, String propValue) {
- p = path;
- v = propValue;
- }
-
- public SPair(Path path, String propValue, boolean isDir) {
- p = path;
- v = propValue;
- i = isDir;
- }
-
- public int compareTo(Object o) {
- if (i != null) {
- Boolean j = ((SPair) o).i;
- if (i.booleanValue() != j.booleanValue())
- return i.booleanValue() ? -1 : 1;
- }
- String u = ((SPair) o).v;
- return v.compareTo(u);
- }
- };
-}
+++ /dev/null
-package org.argeo.eclipse.ui.fs;
-
-import java.io.IOException;
-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.Date;
-
-import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-
-/** Expect a {@link Path} as input element */
-public class NioFileLabelProvider extends ColumnLabelProvider {
- private final static FileTime EPOCH = FileTime.fromMillis(0);
- private static final long serialVersionUID = 2160026425187796930L;
- private final String propName;
- private DateFormat dateFormat = new SimpleDateFormat("YYYY-MM-dd HH:mm");
-
- // TODO use new formatting
- // DateTimeFormatter formatter =
- // DateTimeFormatter.ofLocalizedDateTime( FormatStyle.SHORT )
- // .withLocale( Locale.UK )
- // .withZone( ZoneId.systemDefault() );
- public NioFileLabelProvider(String propName) {
- this.propName = propName;
- }
-
- @Override
- public String getText(Object element) {
- try {
- Path path;
- if (element instanceof ParentDir) {
-// switch (propName) {
-// case FsUiConstants.PROPERTY_SIZE:
-// return "-";
-// case FsUiConstants.PROPERTY_LAST_MODIFIED:
-// return "-";
-// // return Files.getLastModifiedTime(((ParentDir) element).getPath()).toString();
-// case FsUiConstants.PROPERTY_TYPE:
-// return "Folder";
-// }
- path = ((ParentDir) element).getPath();
- } else
- path = (Path) element;
- switch (propName) {
- case FsUiConstants.PROPERTY_SIZE:
- if (Files.isDirectory(path))
- return "-";
- else
- return FsUiUtils.humanReadableByteCount(Files.size(path), false);
- case FsUiConstants.PROPERTY_LAST_MODIFIED:
- if (Files.isDirectory(path))
- return "-";
- FileTime time = Files.getLastModifiedTime(path);
- if (time.equals(EPOCH))
- return "-";
- else
- return dateFormat.format(new Date(time.toMillis()));
- case FsUiConstants.PROPERTY_TYPE:
- if (Files.isDirectory(path))
- return "Folder";
- else {
- String mimeType = Files.probeContentType(path);
- if (EclipseUiUtils.isEmpty(mimeType))
- return "Unknown";
- else
- return mimeType;
- }
- default:
- throw new IllegalArgumentException("Unsupported property " + propName);
- }
- } catch (IOException ioe) {
- throw new FsUiException("Cannot get property " + propName + " on " + element);
- }
- }
-}
+++ /dev/null
-package org.argeo.eclipse.ui.fs;
-
-import java.nio.file.Path;
-
-/** A parent directory (..) reference. */
-public class ParentDir {
- Path path;
-
- public ParentDir(Path path) {
- super();
- this.path = path;
- }
-
- public Path getPath() {
- return path;
- }
-
- @Override
- public int hashCode() {
- return path.hashCode();
- }
-
- @Override
- public String toString() {
- return "Parent dir " + path;
- }
-
-}
+++ /dev/null
-package org.argeo.eclipse.ui.fs;
-
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.eclipse.ui.ColumnDefinition;
-import org.argeo.eclipse.ui.EclipseUiUtils;
-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.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Table;
-
-/**
- * Experimental UI upon Java 7 nio files api: SashForm layout with bookmarks on
- * the left hand side and a simple table on the right hand side.
- */
-public class SimpleFsBrowser extends Composite {
- private final static Log log = LogFactory.getLog(SimpleFsBrowser.class);
- private static final long serialVersionUID = -40347919096946585L;
-
- private Path currSelected;
- private FsTableViewer bookmarksViewer;
- private FsTableViewer directoryDisplayViewer;
-
- public SimpleFsBrowser(Composite parent, int style) {
- super(parent, style);
- createContent(this);
- // parent.layout(true, true);
- }
-
- public Viewer getViewer() {
- return directoryDisplayViewer;
- }
-
- private void createContent(Composite parent) {
- parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
-
- SashForm form = new SashForm(parent, SWT.HORIZONTAL);
- Composite leftCmp = new Composite(form, SWT.NONE);
- populateBookmarks(leftCmp);
-
- Composite rightCmp = new Composite(form, SWT.BORDER);
- populateDisplay(rightCmp);
- form.setLayoutData(EclipseUiUtils.fillAll());
- form.setWeights(new int[] { 1, 3 });
- }
-
- public void setInput(Path... paths) {
- bookmarksViewer.setPathsInput(paths);
- bookmarksViewer.getTable().getParent().layout(true, true);
- }
-
- private void populateBookmarks(final Composite parent) {
- // GridLayout layout = EclipseUiUtils.noSpaceGridLayout();
- // layout.verticalSpacing = 5;
- parent.setLayout(new GridLayout());
-
- ISelectionChangedListener selList = new MySelectionChangedListener();
-
- appendTitle(parent, "My bookmarks");
- bookmarksViewer = new FsTableViewer(parent, SWT.MULTI | SWT.NO_SCROLL);
- Table table = bookmarksViewer.configureDefaultSingleColumnTable(500);
- GridData gd = EclipseUiUtils.fillWidth();
- gd.horizontalIndent = 10;
- table.setLayoutData(gd);
- bookmarksViewer.addSelectionChangedListener(selList);
-
- appendTitle(parent, "Jcr + File");
-
- FsTableViewer jcrFilesViewers = new FsTableViewer(parent, SWT.MULTI | SWT.NO_SCROLL);
- table = jcrFilesViewers.configureDefaultSingleColumnTable(500);
- gd = EclipseUiUtils.fillWidth();
- gd.horizontalIndent = 10;
- table.setLayoutData(gd);
- jcrFilesViewers.addSelectionChangedListener(selList);
-
- // FileSystemProvider fsProvider = new JackrabbitMemoryFsProvider();
- // try {
- // Path testPath = fsProvider.getPath(new URI("jcr+memory:/"));
- // jcrFilesViewers.setPathsInput(testPath);
- // } catch (URISyntaxException e) {
- // // TODO Auto-generated catch block
- // e.printStackTrace();
- // }
- }
-
- private Label appendTitle(Composite parent, String value) {
- Label titleLbl = new Label(parent, SWT.NONE);
- titleLbl.setText(value);
- titleLbl.setFont(EclipseUiUtils.getBoldFont(parent));
- GridData gd = EclipseUiUtils.fillWidth();
- gd.horizontalIndent = 5;
- gd.verticalIndent = 5;
- titleLbl.setLayoutData(gd);
- return titleLbl;
- }
-
- private class MySelectionChangedListener implements ISelectionChangedListener {
- @Override
- public void selectionChanged(SelectionChangedEvent event) {
- IStructuredSelection selection = (IStructuredSelection) bookmarksViewer.getSelection();
- if (selection.isEmpty())
- return;
- else {
- Path newSelected = (Path) selection.getFirstElement();
- if (newSelected.equals(currSelected))
- return;
- currSelected = newSelected;
- directoryDisplayViewer.setInput(currSelected, "*");
- }
- }
- }
-
- private void populateDisplay(final Composite parent) {
- parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
- directoryDisplayViewer = new FsTableViewer(parent, SWT.MULTI);
- List<ColumnDefinition> colDefs = new ArrayList<>();
- colDefs.add(new ColumnDefinition(new FileIconNameLabelProvider(), "Name", 200));
- colDefs.add(new ColumnDefinition(new NioFileLabelProvider(FsUiConstants.PROPERTY_SIZE), "Size", 100));
- colDefs.add(new ColumnDefinition(new NioFileLabelProvider(FsUiConstants.PROPERTY_TYPE), "Type", 250));
- colDefs.add(new ColumnDefinition(new NioFileLabelProvider(FsUiConstants.PROPERTY_LAST_MODIFIED),
- "Last modified", 200));
- Table table = directoryDisplayViewer.configureDefaultTable(colDefs);
- table.setLayoutData(EclipseUiUtils.fillAll());
-
- table.addKeyListener(new KeyListener() {
- private static final long serialVersionUID = -8083424284436715709L;
-
- @Override
- public void keyReleased(KeyEvent e) {
- }
-
- @Override
- public void keyPressed(KeyEvent e) {
- log.debug("Key event received: " + e.keyCode);
- IStructuredSelection selection = (IStructuredSelection) directoryDisplayViewer.getSelection();
- Path selected = null;
- if (!selection.isEmpty())
- selected = ((Path) selection.getFirstElement());
- if (e.keyCode == SWT.CR) {
- if (!Files.isDirectory(selected))
- return;
- if (selected != null) {
- currSelected = selected;
- directoryDisplayViewer.setInput(currSelected, "*");
- }
- } else if (e.keyCode == SWT.BS) {
- currSelected = currSelected.getParent();
- directoryDisplayViewer.setInput(currSelected, "*");
- directoryDisplayViewer.getTable().setFocus();
- }
- }
- });
-
-// directoryDisplayViewer.addDoubleClickListener(new IDoubleClickListener() {
-// @Override
-// public void doubleClick(DoubleClickEvent event) {
-// IStructuredSelection selection = (IStructuredSelection) directoryDisplayViewer.getSelection();
-// Path selected = null;
-// if (!selection.isEmpty()) {
-// Object obj = selection.getFirstElement();
-// if (obj instanceof Path)
-// selected = (Path) obj;
-// else if (obj instanceof ParentDir)
-// selected = ((ParentDir) obj).getPath();
-// }
-// if (selected != null) {
-// if (!Files.isDirectory(selected))
-// return;
-// currSelected = selected;
-// directoryDisplayViewer.setInput(currSelected, "*");
-// }
-// }
-// });
-
- directoryDisplayViewer.addDoubleClickListener(new IDoubleClickListener() {
- @Override
- public void doubleClick(DoubleClickEvent event) {
- IStructuredSelection selection = (IStructuredSelection) directoryDisplayViewer.getSelection();
- Path selected = null;
- if (!selection.isEmpty()) {
- Object obj = selection.getFirstElement();
- if (obj instanceof Path)
- selected = (Path) obj;
- else if (obj instanceof ParentDir)
- selected = ((ParentDir) obj).getPath();
- }
- if (selected != null) {
- if (!Files.isDirectory(selected))
- return;
- currSelected = selected;
- directoryDisplayViewer.setInput(currSelected, "*");
- }
- }
- });
- }
-}
+++ /dev/null
-package org.argeo.eclipse.ui.fs;
-
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.eclipse.ui.ColumnDefinition;
-import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-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.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.Tree;
-
-/** A simple Java 7 nio files browser with a tree */
-public class SimpleFsTreeBrowser extends Composite {
- private final static Log log = LogFactory.getLog(SimpleFsTreeBrowser.class);
- private static final long serialVersionUID = -40347919096946585L;
-
- private Path currSelected;
- private FsTreeViewer treeViewer;
- private FsTableViewer directoryDisplayViewer;
-
- public SimpleFsTreeBrowser(Composite parent, int style) {
- super(parent, style);
- createContent(this);
- // parent.layout(true, true);
- }
-
- private void createContent(Composite parent) {
- parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
- SashForm form = new SashForm(parent, SWT.HORIZONTAL);
- Composite child1 = new Composite(form, SWT.NONE);
- populateTree(child1);
- Composite child2 = new Composite(form, SWT.BORDER);
- populateDisplay(child2);
- form.setLayoutData(EclipseUiUtils.fillAll());
- form.setWeights(new int[] { 1, 3 });
- }
-
- public void setInput(Path... paths) {
- treeViewer.setPathsInput(paths);
- treeViewer.getControl().getParent().layout(true, true);
- }
-
- private void populateTree(final Composite parent) {
- // GridLayout layout = EclipseUiUtils.noSpaceGridLayout();
- // layout.verticalSpacing = 5;
- parent.setLayout(new GridLayout());
-
- ISelectionChangedListener selList = new MySelectionChangedListener();
-
- treeViewer = new FsTreeViewer(parent, SWT.MULTI);
- Tree tree = treeViewer.configureDefaultSingleColumnTable(500);
- GridData gd = EclipseUiUtils.fillAll();
- // gd.horizontalIndent = 10;
- tree.setLayoutData(gd);
- treeViewer.addSelectionChangedListener(selList);
- }
-
- private class MySelectionChangedListener implements ISelectionChangedListener {
- @Override
- public void selectionChanged(SelectionChangedEvent event) {
- IStructuredSelection selection = (IStructuredSelection) treeViewer.getSelection();
- if (selection.isEmpty())
- return;
- else {
- Path newSelected = (Path) selection.getFirstElement();
- if (newSelected.equals(currSelected))
- return;
- currSelected = newSelected;
- if (Files.isDirectory(currSelected))
- directoryDisplayViewer.setInput(currSelected, "*");
- }
- }
- }
-
- private void populateDisplay(final Composite parent) {
- parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
- directoryDisplayViewer = new FsTableViewer(parent, SWT.MULTI);
- List<ColumnDefinition> colDefs = new ArrayList<>();
- colDefs.add(new ColumnDefinition(new FileIconNameLabelProvider(), "Name", 200, 200));
- colDefs.add(new ColumnDefinition(new NioFileLabelProvider(FsUiConstants.PROPERTY_SIZE), "Size", 100, 100));
- colDefs.add(new ColumnDefinition(new NioFileLabelProvider(FsUiConstants.PROPERTY_TYPE), "Type", 300, 300));
- colDefs.add(new ColumnDefinition(new NioFileLabelProvider(FsUiConstants.PROPERTY_LAST_MODIFIED),
- "Last modified", 100, 100));
- Table table = directoryDisplayViewer.configureDefaultTable(colDefs);
- table.setLayoutData(EclipseUiUtils.fillAll());
-
- table.addKeyListener(new KeyListener() {
- private static final long serialVersionUID = -8083424284436715709L;
-
- @Override
- public void keyReleased(KeyEvent e) {
- }
-
- @Override
- public void keyPressed(KeyEvent e) {
- log.debug("Key event received: " + e.keyCode);
- IStructuredSelection selection = (IStructuredSelection) directoryDisplayViewer.getSelection();
- Path selected = null;
- if (!selection.isEmpty())
- selected = ((Path) selection.getFirstElement());
- if (e.keyCode == SWT.CR) {
- if (!Files.isDirectory(selected))
- return;
- if (selected != null) {
- currSelected = selected;
- directoryDisplayViewer.setInput(currSelected, "*");
- }
- } else if (e.keyCode == SWT.BS) {
- currSelected = currSelected.getParent();
- directoryDisplayViewer.setInput(currSelected, "*");
- directoryDisplayViewer.getTable().setFocus();
- }
- }
- });
- }
-}
+++ /dev/null
-/** Generic SWT/JFace file system utilities. */
-package org.argeo.eclipse.ui.fs;
\ No newline at end of file
+++ /dev/null
-/** Generic SWT/JFace utilities. */
-package org.argeo.eclipse.ui;
\ No newline at end of file
+++ /dev/null
-package org.argeo.eclipse.ui.parts;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.argeo.eclipse.ui.ColumnDefinition;
-import org.argeo.eclipse.ui.EclipseUiException;
-import org.argeo.eclipse.ui.EclipseUiUtils;
-import org.argeo.eclipse.ui.util.ViewerUtils;
-import org.eclipse.jface.layout.TableColumnLayout;
-import org.eclipse.jface.viewers.CheckboxTableViewer;
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-import org.eclipse.jface.viewers.ColumnWeightData;
-import org.eclipse.jface.viewers.IStructuredContentProvider;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.TableViewerColumn;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-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.Composite;
-import org.eclipse.swt.widgets.Link;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-import org.eclipse.swt.widgets.Text;
-import org.osgi.service.useradmin.User;
-
-/**
- * Generic composite that display a filter and a table viewer to display users
- * (can also be groups)
- *
- * Warning: this class does not extends <code>TableViewer</code>. Use the
- * getTableViewer method to access it.
- *
- */
-public abstract class LdifUsersTable extends Composite {
- private static final long serialVersionUID = -7385959046279360420L;
-
- // Context
- // private UserAdmin userAdmin;
-
- // Configuration
- private List<ColumnDefinition> columnDefs = new ArrayList<ColumnDefinition>();
- private boolean hasFilter;
- private boolean preventTableLayout = false;
- private boolean hasSelectionColumn;
- private int tableStyle;
-
- // Local UI Objects
- private TableViewer usersViewer;
- private Text filterTxt;
-
- /* EXPOSED METHODS */
-
- /**
- * @param parent
- * @param style
- */
- public LdifUsersTable(Composite parent, int style) {
- super(parent, SWT.NO_FOCUS);
- this.tableStyle = style;
- }
-
- // TODO workaround the bug of the table layout in the Form
- public LdifUsersTable(Composite parent, int style, boolean preventTableLayout) {
- super(parent, SWT.NO_FOCUS);
- this.tableStyle = style;
- this.preventTableLayout = preventTableLayout;
- }
-
- /** This must be called before the call to populate method */
- public void setColumnDefinitions(List<ColumnDefinition> columnDefinitions) {
- this.columnDefs = columnDefinitions;
- }
-
- /**
- *
- * @param addFilter
- * choose to add a field to filter results or not
- * @param addSelection
- * choose to add a column to select some of the displayed results or
- * not
- */
- public void populate(boolean addFilter, boolean addSelection) {
- // initialization
- Composite parent = this;
- hasFilter = addFilter;
- hasSelectionColumn = addSelection;
-
- // Main Layout
- GridLayout layout = EclipseUiUtils.noSpaceGridLayout();
- layout.verticalSpacing = 5;
- this.setLayout(layout);
- if (hasFilter)
- createFilterPart(parent);
-
- Composite tableComp = new Composite(parent, SWT.NO_FOCUS);
- tableComp.setLayoutData(EclipseUiUtils.fillAll());
- usersViewer = createTableViewer(tableComp);
- usersViewer.setContentProvider(new UsersContentProvider());
- }
-
- /**
- *
- * @param showMore
- * display static filters on creation
- * @param addSelection
- * choose to add a column to select some of the displayed results or
- * not
- */
- public void populateWithStaticFilters(boolean showMore, boolean addSelection) {
- // initialization
- Composite parent = this;
- hasFilter = true;
- hasSelectionColumn = addSelection;
-
- // Main Layout
- GridLayout layout = EclipseUiUtils.noSpaceGridLayout();
- layout.verticalSpacing = 5;
- this.setLayout(layout);
- createStaticFilterPart(parent, showMore);
-
- Composite tableComp = new Composite(parent, SWT.NO_FOCUS);
- tableComp.setLayoutData(EclipseUiUtils.fillAll());
- usersViewer = createTableViewer(tableComp);
- usersViewer.setContentProvider(new UsersContentProvider());
- }
-
- /** Enable access to the selected users or groups */
- public List<User> getSelectedUsers() {
- if (hasSelectionColumn) {
- Object[] elements = ((CheckboxTableViewer) usersViewer).getCheckedElements();
-
- List<User> result = new ArrayList<User>();
- for (Object obj : elements) {
- result.add((User) obj);
- }
- return result;
- } else
- throw new EclipseUiException(
- "Unvalid request: no selection column " + "has been created for the current table");
- }
-
- /** Returns the User table viewer, typically to add doubleclick listener */
- public TableViewer getTableViewer() {
- return usersViewer;
- }
-
- /**
- * Force the refresh of the underlying table using the current filter string if
- * relevant
- */
- public void refresh() {
- String filter = hasFilter ? filterTxt.getText().trim() : null;
- if ("".equals(filter))
- filter = null;
- refreshFilteredList(filter);
- }
-
- /** Effective repository request: caller must implement this method */
- abstract protected List<User> listFilteredElements(String filter);
-
- // protected List<User> listFilteredElements(String filter) {
- // List<User> users = new ArrayList<User>();
- // try {
- // Role[] roles = userAdmin.getRoles(filter);
- // // Display all users and groups
- // for (Role role : roles)
- // users.add((User) role);
- // } catch (InvalidSyntaxException e) {
- // throw new EclipseUiException("Unable to get roles with filter: "
- // + filter, e);
- // }
- // return users;
- // }
-
- /* GENERIC COMPOSITE METHODS */
- @Override
- public boolean setFocus() {
- if (hasFilter)
- return filterTxt.setFocus();
- else
- return usersViewer.getTable().setFocus();
- }
-
- @Override
- public void dispose() {
- super.dispose();
- }
-
- /* LOCAL CLASSES AND METHODS */
- // Will be usefull to rather use a virtual table viewer
- private void refreshFilteredList(String filter) {
- List<User> users = listFilteredElements(filter);
- usersViewer.setInput(users.toArray());
- }
-
- private class UsersContentProvider implements IStructuredContentProvider {
- private static final long serialVersionUID = 1L;
-
- public Object[] getElements(Object inputElement) {
- return (Object[]) inputElement;
- }
-
- public void dispose() {
- }
-
- public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
- }
- }
-
- /* MANAGE FILTER */
- private void createFilterPart(Composite parent) {
- // Text Area for the filter
- filterTxt = new Text(parent, SWT.BORDER | SWT.SEARCH | SWT.ICON_SEARCH | SWT.ICON_CANCEL);
- filterTxt.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));
- filterTxt.addModifyListener(new ModifyListener() {
- private static final long serialVersionUID = 1L;
-
- public void modifyText(ModifyEvent event) {
- refreshFilteredList(filterTxt.getText());
- }
- });
- }
-
- private void createStaticFilterPart(Composite parent, boolean showMore) {
- Composite filterComp = new Composite(parent, SWT.NO_FOCUS);
- filterComp.setLayout(new GridLayout(2, false));
- filterComp.setLayoutData(EclipseUiUtils.fillWidth());
- // generic search
- filterTxt = new Text(filterComp, SWT.BORDER | SWT.SEARCH | SWT.ICON_SEARCH | SWT.ICON_CANCEL);
- filterTxt.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));
- // filterTxt.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL |
- // GridData.HORIZONTAL_ALIGN_FILL));
- filterTxt.addModifyListener(new ModifyListener() {
- private static final long serialVersionUID = 1L;
-
- public void modifyText(ModifyEvent event) {
- refreshFilteredList(filterTxt.getText());
- }
- });
-
- // add static filter abilities
- Link moreLk = new Link(filterComp, SWT.NONE);
- Composite staticFilterCmp = new Composite(filterComp, SWT.NO_FOCUS);
- staticFilterCmp.setLayoutData(EclipseUiUtils.fillWidth(2));
- populateStaticFilters(staticFilterCmp);
-
- MoreLinkListener listener = new MoreLinkListener(moreLk, staticFilterCmp, showMore);
- // initialise the layout
- listener.refresh();
- moreLk.addSelectionListener(listener);
- }
-
- /** Overwrite to add static filters */
- protected void populateStaticFilters(Composite staticFilterCmp) {
- }
-
- // private void addMoreSL(final Link more) {
- // more.addSelectionListener( }
-
- private class MoreLinkListener extends SelectionAdapter {
- private static final long serialVersionUID = -524987616510893463L;
- private boolean isShown;
- private final Composite staticFilterCmp;
- private final Link moreLk;
-
- public MoreLinkListener(Link moreLk, Composite staticFilterCmp, boolean isShown) {
- this.moreLk = moreLk;
- this.staticFilterCmp = staticFilterCmp;
- this.isShown = isShown;
- }
-
- @Override
- public void widgetSelected(SelectionEvent e) {
- isShown = !isShown;
- refresh();
- }
-
- public void refresh() {
- GridData gd = (GridData) staticFilterCmp.getLayoutData();
- if (isShown) {
- moreLk.setText("<a> Less... </a>");
- gd.heightHint = SWT.DEFAULT;
- } else {
- moreLk.setText("<a> More... </a>");
- gd.heightHint = 0;
- }
- forceLayout();
- }
- }
-
- private void forceLayout() {
- LdifUsersTable.this.getParent().layout(true, true);
- }
-
- private TableViewer createTableViewer(final Composite parent) {
-
- int style = tableStyle | SWT.H_SCROLL | SWT.V_SCROLL;
- if (hasSelectionColumn)
- style = style | SWT.CHECK;
- Table table = new Table(parent, style);
- TableColumnLayout layout = new TableColumnLayout();
-
- // TODO the table layout does not works with the scrolled form
-
- if (preventTableLayout) {
- parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
- table.setLayoutData(EclipseUiUtils.fillAll());
- } else
- parent.setLayout(layout);
-
- TableViewer viewer;
- if (hasSelectionColumn)
- viewer = new CheckboxTableViewer(table);
- else
- viewer = new TableViewer(table);
- table.setLinesVisible(true);
- table.setHeaderVisible(true);
-
- TableViewerColumn column;
- // int offset = 0;
- if (hasSelectionColumn) {
- // offset = 1;
- column = ViewerUtils.createTableViewerColumn(viewer, "", SWT.NONE, 25);
- column.setLabelProvider(new ColumnLabelProvider() {
- private static final long serialVersionUID = 1L;
-
- @Override
- public String getText(Object element) {
- return null;
- }
- });
- layout.setColumnData(column.getColumn(), new ColumnWeightData(25, 25, false));
-
- SelectionAdapter selectionAdapter = new SelectionAdapter() {
- private static final long serialVersionUID = 1L;
-
- boolean allSelected = false;
-
- @Override
- public void widgetSelected(SelectionEvent e) {
- allSelected = !allSelected;
- ((CheckboxTableViewer) usersViewer).setAllChecked(allSelected);
- }
- };
- column.getColumn().addSelectionListener(selectionAdapter);
- }
-
- // NodeViewerComparator comparator = new NodeViewerComparator();
- // TODO enable the sort by click on the header
- // int i = offset;
- for (ColumnDefinition colDef : columnDefs)
- createTableColumn(viewer, layout, colDef);
-
- // column = ViewerUtils.createTableViewerColumn(viewer,
- // colDef.getHeaderLabel(), SWT.NONE, colDef.getColumnSize());
- // column.setLabelProvider(new CLProvider(colDef.getPropertyName()));
- // column.getColumn().addSelectionListener(
- // JcrUiUtils.getNodeSelectionAdapter(i,
- // colDef.getPropertyType(), colDef.getPropertyName(),
- // comparator, viewer));
- // i++;
- // }
-
- // IMPORTANT: initialize comparator before setting it
- // JcrColumnDefinition firstCol = colDefs.get(0);
- // comparator.setColumn(firstCol.getPropertyType(),
- // firstCol.getPropertyName());
- // viewer.setComparator(comparator);
-
- return viewer;
- }
-
- /** Default creation of a column for a user table */
- private TableViewerColumn createTableColumn(TableViewer tableViewer, TableColumnLayout layout,
- ColumnDefinition columnDef) {
-
- boolean resizable = true;
- TableViewerColumn tvc = new TableViewerColumn(tableViewer, SWT.NONE);
- TableColumn column = tvc.getColumn();
-
- column.setText(columnDef.getLabel());
- column.setWidth(columnDef.getMinWidth());
- column.setResizable(resizable);
-
- ColumnLabelProvider lp = columnDef.getLabelProvider();
- // add a reference to the display to enable font management
- // if (lp instanceof UserAdminAbstractLP)
- // ((UserAdminAbstractLP) lp).setDisplay(tableViewer.getTable()
- // .getDisplay());
- tvc.setLabelProvider(lp);
-
- layout.setColumnData(column, new ColumnWeightData(columnDef.getWeight(), columnDef.getMinWidth(), resizable));
-
- return tvc;
- }
-}
+++ /dev/null
-/** Generic SWT/JFace composites. */
-package org.argeo.eclipse.ui.parts;
\ No newline at end of file
+++ /dev/null
-package org.argeo.eclipse.ui.util;
-
-/**
- * Centralise constants that are used in both RAP and RCP specific code to avoid
- * duplicated declaration
- */
-public interface SingleSourcingConstants {
-
- // Single sourced open file command
- String OPEN_FILE_CMD_ID = "org.argeo.cms.ui.workbench.openFile";
- String PARAM_FILE_NAME = "param.fileName";
- String PARAM_FILE_URI = "param.fileURI";
-
- String SCHEME_HOST_SEPARATOR = "://";
- String FILE_SCHEME = "file";
- String JCR_SCHEME = "jcr";
-}
+++ /dev/null
-package org.argeo.eclipse.ui.util;
-
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.TableViewerColumn;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.jface.viewers.TreeViewerColumn;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-import org.eclipse.swt.widgets.TreeColumn;
-
-/**
- * Centralise useful methods to manage JFace Table, Tree and TreeColumn viewers.
- */
-public class ViewerUtils {
-
- /**
- * Creates a basic column for the given table. For the time being, we do not
- * support movable columns.
- */
- public static TableColumn createColumn(Table parent, String name, int style, int width) {
- TableColumn result = new TableColumn(parent, style);
- result.setText(name);
- result.setWidth(width);
- result.setResizable(true);
- return result;
- }
-
- /**
- * Creates a TableViewerColumn for the given viewer. For the time being, we do
- * not support movable columns.
- */
- public static TableViewerColumn createTableViewerColumn(TableViewer parent, String name, int style, int width) {
- TableViewerColumn tvc = new TableViewerColumn(parent, style);
- TableColumn column = tvc.getColumn();
- column.setText(name);
- column.setWidth(width);
- column.setResizable(true);
- return tvc;
- }
-
- // public static TableViewerColumn createTableViewerColumn(TableViewer parent,
- // Localized name, int style, int width) {
- // return createTableViewerColumn(parent, name.lead(), style, width);
- // }
-
- /**
- * Creates a TreeViewerColumn for the given viewer. For the time being, we do
- * not support movable columns.
- */
- public static TreeViewerColumn createTreeViewerColumn(TreeViewer parent, String name, int style, int width) {
- TreeViewerColumn tvc = new TreeViewerColumn(parent, style);
- TreeColumn column = tvc.getColumn();
- column.setText(name);
- column.setWidth(width);
- column.setResizable(true);
- return tvc;
- }
-}
+++ /dev/null
-/** Generic SWT/JFace JCR helpers. */
-package org.argeo.eclipse.ui.util;
\ No newline at end of file
<relativePath>..</relativePath>
</parent>
<artifactId>org.argeo.enterprise</artifactId>
- <name>Commons Enterprise</name>
+ <name>Argeo Enterprise</name>
</project>
\ No newline at end of file
</parent>
<artifactId>org.argeo.osgi.boot</artifactId>
<packaging>jar</packaging>
- <name>Commons OSGi Boot</name>
+ <name>OSGi Boot</name>
<build>
<plugins>
<plugin>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src" />
+ <classpathentry kind="con"
+ path="org.eclipse.pde.core.requiredPlugins" />
+ <classpathentry kind="con"
+ path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11" />
+ <classpathentry kind="output" path="bin" />
+</classpath>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.argeo.swt.specific.rap</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
+Import-Package: org.eclipse.swt,\
+org.eclipse.jface.dialogs,\
+javax.servlet.http,\
+org.eclipse.swt.events,\
+*
--- /dev/null
+source.. = src/
+output.. = bin/
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<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.commons</groupId>
+ <version>2.3-SNAPSHOT</version>
+ <artifactId>argeo-commons</artifactId>
+ <relativePath>..</relativePath>
+ </parent>
+ <artifactId>org.argeo.swt.specific.rap</artifactId>
+ <name>SWT RAP Specific</name>
+ <dependencies>
+ <!-- UI -->
+ <dependency>
+ <groupId>org.argeo.tp.rap.e4</groupId>
+ <artifactId>org.eclipse.rap.rwt</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.rap.e4</groupId>
+ <artifactId>org.eclipse.core.commands</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.rap.e4</groupId>
+ <artifactId>org.eclipse.rap.jface</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <!-- File upload -->
+ <dependency>
+ <groupId>org.argeo.tp.rap.e4</groupId>
+ <artifactId>org.eclipse.rap.filedialog</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.argeo.tp.rap.e4</groupId>
+ <artifactId>org.eclipse.rap.fileupload</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ </dependencies>
+</project>
\ No newline at end of file
--- /dev/null
+package org.argeo.eclipse.ui.specific;
+
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Shell;
+
+public class CmsFileDialog extends FileDialog {
+ private static final long serialVersionUID = -7540791204102318801L;
+
+ public CmsFileDialog(Shell parent, int style) {
+ super(parent, style);
+ }
+
+ public CmsFileDialog(Shell parent) {
+ super(parent);
+ }
+
+}
--- /dev/null
+package org.argeo.eclipse.ui.specific;
+
+import org.eclipse.rap.rwt.widgets.FileUpload;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Composite;
+
+public class CmsFileUpload extends FileUpload {
+ private static final long serialVersionUID = 8027963992680980549L;
+
+ public CmsFileUpload(Composite parent, int style) {
+ super(parent, style);
+ }
+
+ @Override
+ public void setText(String text) {
+ super.setText(text);
+ }
+
+ @Override
+ public String getFileName() {
+ return super.getFileName();
+ }
+
+ @Override
+ public String[] getFileNames() {
+ return super.getFileNames();
+ }
+
+ @Override
+ public void addSelectionListener(SelectionListener listener) {
+ super.addSelectionListener(listener);
+ }
+
+}
--- /dev/null
+package org.argeo.eclipse.ui.specific;
+
+import org.eclipse.jface.viewers.AbstractTableViewer;
+import org.eclipse.jface.viewers.ColumnViewer;
+import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.rap.rwt.RWT;
+import org.eclipse.swt.widgets.Widget;
+
+/** Static utilities to bridge differences between RCP and RAP */
+public class EclipseUiSpecificUtils {
+
+ public static void setStyleData(Widget widget, Object data) {
+ widget.setData(RWT.CUSTOM_VARIANT, data);
+ }
+
+ public static Object getStyleData(Widget widget) {
+ return widget.getData(RWT.CUSTOM_VARIANT);
+ }
+
+ public static void setMarkupData(Widget widget) {
+ widget.setData(RWT.MARKUP_ENABLED, true);
+ }
+
+ public static void setMarkupValidationDisabledData(Widget widget) {
+ widget.setData("org.eclipse.rap.rwt.markupValidationDisabled", Boolean.TRUE);
+ }
+
+ /**
+ * TootlTip support is supported only for {@link AbstractTableViewer} in RAP
+ */
+ public static void enableToolTipSupport(Viewer viewer) {
+ if (viewer instanceof ColumnViewer)
+ ColumnViewerToolTipSupport.enableFor((ColumnViewer) viewer);
+ }
+
+ private EclipseUiSpecificUtils() {
+ }
+}
--- /dev/null
+package org.argeo.eclipse.ui.specific;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.eclipse.rap.fileupload.FileDetails;
+import org.eclipse.rap.fileupload.FileUploadHandler;
+import org.eclipse.rap.fileupload.FileUploadReceiver;
+import org.eclipse.rap.rwt.RWT;
+import org.eclipse.rap.rwt.client.ClientFile;
+import org.eclipse.rap.rwt.client.service.ClientFileUploader;
+import org.eclipse.rap.rwt.dnd.ClientFileTransfer;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DropTarget;
+import org.eclipse.swt.dnd.DropTargetAdapter;
+import org.eclipse.swt.dnd.DropTargetEvent;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.widgets.Control;
+
+/** Configures a {@link Control} to receive files drop from the client OS. */
+public class FileDropAdapter {
+
+ public void prepareDropTarget(Control control, DropTarget dropTarget) {
+ dropTarget.setTransfer(new Transfer[] { ClientFileTransfer.getInstance() });
+ dropTarget.addDropListener(new DropTargetAdapter() {
+ private static final long serialVersionUID = 5361645765549463168L;
+
+ @Override
+ public void dropAccept(DropTargetEvent event) {
+ if (!ClientFileTransfer.getInstance().isSupportedType(event.currentDataType)) {
+ event.detail = DND.DROP_NONE;
+ }
+ }
+
+ @Override
+ public void drop(DropTargetEvent event) {
+ handleFileDrop(control, event);
+ }
+ });
+ }
+
+ public void handleFileDrop(Control control, DropTargetEvent event) {
+ ClientFile[] clientFiles = (ClientFile[]) event.data;
+ ClientFileUploader service = RWT.getClient().getService(ClientFileUploader.class);
+// DiskFileUploadReceiver receiver = new DiskFileUploadReceiver();
+ FileUploadReceiver receiver = new FileUploadReceiver() {
+
+ @Override
+ public void receive(InputStream stream, FileDetails details) throws IOException {
+ control.getDisplay().syncExec(() -> {
+ try {
+ processUpload(stream, details.getFileName(), details.getContentType());
+ } catch (IOException e) {
+ throw new IllegalStateException("Cannot process upload of " + details.getFileName(), e);
+ }
+ });
+ }
+ };
+ FileUploadHandler handler = new FileUploadHandler(receiver);
+// handler.setMaxFileSize( sizeLimit );
+// handler.setUploadTimeLimit( timeLimit );
+ service.submit(handler.getUploadUrl(), clientFiles);
+// for (File file : receiver.getTargetFiles()) {
+// paths.add(file.toPath());
+// }
+ }
+
+ /** Executed in UI thread */
+ protected void processUpload(InputStream in, String fileName, String contentType) throws IOException {
+
+ }
+
+}
--- /dev/null
+package org.argeo.eclipse.ui.specific;
+
+import java.util.Locale;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.rap.rwt.RWT;
+import org.eclipse.swt.widgets.Display;
+
+/** Singleton class providing single sources infos about the UI context. */
+public class UiContext {
+ /** Can be null, thus indicating that we are not in a web context. */
+ public static HttpServletRequest getHttpRequest() {
+ return RWT.getRequest();
+ }
+
+ public static HttpServletResponse getHttpResponse() {
+ return RWT.getResponse();
+ }
+
+ public static Locale getLocale() {
+ if (Display.getCurrent() != null)
+ return RWT.getUISession().getLocale();
+ else
+ return Locale.getDefault();
+ }
+
+ public static void setLocale(Locale locale) {
+ if (Display.getCurrent() != null)
+ RWT.getUISession().setLocale(locale);
+ else
+ Locale.setDefault(locale);
+ }
+
+ /** Can always be null */
+ @SuppressWarnings("unchecked")
+ public static <T> T getData(String key) {
+ Display display = getDisplay();
+ if (display == null)
+ return null;
+ return (T) display.getData(key);
+ }
+
+ public static void setData(String key, Object value) {
+ Display display = getDisplay();
+ if (display == null)
+ throw new IllegalStateException("Not display available");
+ display.setData(key, value);
+ }
+
+ private static Display getDisplay() {
+ return Display.getCurrent();
+ }
+
+ private UiContext() {
+ }
+
+}
--- /dev/null
+/** Eclipse RAP-specific SWT/JFace utilities, to simplify single-sourcing. */
+package org.argeo.eclipse.ui.specific;
\ No newline at end of file
</properties>
<modules>
<!-- Base -->
+ <module>org.argeo.osgi.boot</module>
<module>org.argeo.enterprise</module>
<!-- <module>org.argeo.jcr</module> -->
- <module>org.argeo.osgi.boot</module>
- <module>org.argeo.core</module>
+<!-- <module>org.argeo.core</module> -->
<!-- Eclipse -->
- <module>org.argeo.eclipse.ui</module>
- <module>org.argeo.eclipse.ui.rap</module>
+ <module>org.argeo.swt.specific.rap</module>
<!-- CMS -->
<module>org.argeo.api</module>
<!-- <module>org.argeo.maintenance</module> -->
<module>org.argeo.cms</module>
+ <module>org.argeo.cms.swt</module>
<module>org.argeo.cms.jcr</module>
- <module>org.argeo.cms.ui.theme</module>
+<!-- <module>org.argeo.cms.ui.theme</module> -->
<module>org.argeo.cms.ui</module>
<module>org.argeo.cms.ui.rap</module>
<!-- CMS E4 -->