Remove or merge bundles
authorMathieu Baudier <mbaudier@argeo.org>
Tue, 10 Feb 2015 10:40:11 +0000 (10:40 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Tue, 10 Feb 2015 10:40:11 +0000 (10:40 +0000)
Clean up POMs

git-svn-id: https://svn.argeo.org/commons/trunk@7775 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

125 files changed:
dep/org.argeo.dep.cms/pom.xml
dep/org.argeo.security.dep.node.rap/pom.xml
dep/org.argeo.security.dep.node/pom.xml
dep/pom.xml
dist/osgi-boot/pom.xml
dist/pom.xml
org.argeo.cms/bnd.bnd
org.argeo.cms/pom.xml
org.argeo.cms/src/org/argeo/cms/CmsApplication.java
org.argeo.cms/src/org/argeo/cms/internal/backup/AbstractAtomicBackup.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/internal/backup/AtomicBackup.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/internal/backup/BackupContext.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/internal/backup/BackupFileSystemManager.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/internal/backup/BackupPurge.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/internal/backup/BackupUtils.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/internal/backup/MySqlBackup.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/internal/backup/OpenLdapBackup.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/internal/backup/OsCallBackup.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/internal/backup/PostgreSqlBackup.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/internal/backup/SimpleBackupContext.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/internal/backup/SimpleBackupPurge.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/internal/backup/SvnBackup.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/internal/backup/SystemBackup.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeHttp.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeSecurity.java
org.argeo.cms/src/org/argeo/cms/viewers/AbstractPageViewer.java
org.argeo.eclipse.ui.rap/pom.xml
org.argeo.eclipse.ui.workbench.rap/pom.xml
org.argeo.eclipse.ui.workbench/pom.xml
org.argeo.eclipse.ui/bnd.bnd
org.argeo.eclipse.ui/pom.xml
org.argeo.security.core/bnd.bnd
org.argeo.security.core/pom.xml
org.argeo.security.core/src/org/argeo/security/core/AuthorizationPrincipal.java [new file with mode: 0644]
org.argeo.security.core/src/org/argeo/security/core/UserAdminLoginModule.java [new file with mode: 0644]
org.argeo.security.core/src/org/argeo/security/ldap/ArgeoLdapShaPasswordEncoder.java [new file with mode: 0644]
org.argeo.security.core/src/org/argeo/security/ldap/ArgeoLdapUserDetailsManager.java [new file with mode: 0644]
org.argeo.security.core/src/org/argeo/security/ldap/ArgeoUserAdminDaoLdap.java [new file with mode: 0644]
org.argeo.security.core/src/org/argeo/security/ldap/jcr/JcrLdapSynchronizer.java [new file with mode: 0644]
org.argeo.security.core/src/org/argeo/security/ldap/jcr/JcrUserDetailsContextMapper.java [new file with mode: 0644]
org.argeo.security.jackrabbit/pom.xml
org.argeo.security.ldap/.classpath [deleted file]
org.argeo.security.ldap/.project [deleted file]
org.argeo.security.ldap/bnd.bnd [deleted file]
org.argeo.security.ldap/build.properties [deleted file]
org.argeo.security.ldap/pom.xml [deleted file]
org.argeo.security.ldap/src/org/argeo/security/ldap/ArgeoLdapShaPasswordEncoder.java [deleted file]
org.argeo.security.ldap/src/org/argeo/security/ldap/ArgeoLdapUserDetailsManager.java [deleted file]
org.argeo.security.ldap/src/org/argeo/security/ldap/ArgeoUserAdminDaoLdap.java [deleted file]
org.argeo.security.ldap/src/org/argeo/security/ldap/jcr/JcrLdapSynchronizer.java [deleted file]
org.argeo.security.ldap/src/org/argeo/security/ldap/jcr/JcrUserDetailsContextMapper.java [deleted file]
org.argeo.security.ui.admin/pom.xml
org.argeo.security.ui.rap/pom.xml
org.argeo.security.ui/pom.xml
org.argeo.server.core/.classpath [deleted file]
org.argeo.server.core/.project [deleted file]
org.argeo.server.core/bnd.bnd [deleted file]
org.argeo.server.core/build.properties [deleted file]
org.argeo.server.core/pom.xml [deleted file]
org.argeo.server.core/src/org/argeo/server/BooleanAnswer.java [deleted file]
org.argeo.server.core/src/org/argeo/server/Deserializer.java [deleted file]
org.argeo.server.core/src/org/argeo/server/DeserializingEditor.java [deleted file]
org.argeo.server.core/src/org/argeo/server/PrimitiveAnswer.java [deleted file]
org.argeo.server.core/src/org/argeo/server/Serializer.java [deleted file]
org.argeo.server.core/src/org/argeo/server/ServerAnswer.java [deleted file]
org.argeo.server.core/src/org/argeo/server/ServerSerializer.java [deleted file]
org.argeo.server.core/src/org/argeo/server/backup/AbstractAtomicBackup.java [deleted file]
org.argeo.server.core/src/org/argeo/server/backup/AtomicBackup.java [deleted file]
org.argeo.server.core/src/org/argeo/server/backup/BackupContext.java [deleted file]
org.argeo.server.core/src/org/argeo/server/backup/BackupFileSystemManager.java [deleted file]
org.argeo.server.core/src/org/argeo/server/backup/BackupPurge.java [deleted file]
org.argeo.server.core/src/org/argeo/server/backup/BackupUtils.java [deleted file]
org.argeo.server.core/src/org/argeo/server/backup/MySqlBackup.java [deleted file]
org.argeo.server.core/src/org/argeo/server/backup/OpenLdapBackup.java [deleted file]
org.argeo.server.core/src/org/argeo/server/backup/OsCallBackup.java [deleted file]
org.argeo.server.core/src/org/argeo/server/backup/PostgreSqlBackup.java [deleted file]
org.argeo.server.core/src/org/argeo/server/backup/SimpleBackupContext.java [deleted file]
org.argeo.server.core/src/org/argeo/server/backup/SimpleBackupPurge.java [deleted file]
org.argeo.server.core/src/org/argeo/server/backup/SvnBackup.java [deleted file]
org.argeo.server.core/src/org/argeo/server/backup/SystemBackup.java [deleted file]
org.argeo.server.core/src/org/argeo/server/dao/AbstractMemoryDaoSupport.java [deleted file]
org.argeo.server.core/src/org/argeo/server/dao/AbstractTabularDaoSupport.java [deleted file]
org.argeo.server.core/src/org/argeo/server/dao/LightDaoAware.java [deleted file]
org.argeo.server.core/src/org/argeo/server/dao/LightDaoPropertyEditor.java [deleted file]
org.argeo.server.core/src/org/argeo/server/dao/LightDaoSupport.java [deleted file]
org.argeo.server.core/src/org/argeo/server/mvc/DefaultHandlerExceptionResolver.java [deleted file]
org.argeo.server.core/src/org/argeo/server/mvc/EmptyViewController.java [deleted file]
org.argeo.server.core/src/org/argeo/server/mvc/MvcConstants.java [deleted file]
org.argeo.server.core/src/org/argeo/server/mvc/SerializingView.java [deleted file]
org.argeo.server.core/src/org/argeo/server/mvc/SerializingViewResolver.java [deleted file]
org.argeo.server.jackrabbit/.classpath [deleted file]
org.argeo.server.jackrabbit/.project [deleted file]
org.argeo.server.jackrabbit/.settings/org.eclipse.jdt.core.prefs [deleted file]
org.argeo.server.jackrabbit/bnd.bnd [deleted file]
org.argeo.server.jackrabbit/build.properties [deleted file]
org.argeo.server.jackrabbit/pom.xml [deleted file]
org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/JackrabbitAuthorizations.java [deleted file]
org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/JackrabbitContainer.java [deleted file]
org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/JackrabbitDataModelMigration.java [deleted file]
org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/JackrabbitRepositoryFactory.java [deleted file]
org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/JackrabbitWrapper.java [deleted file]
org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/OsgiJackrabbitRepositoryFactory.java [deleted file]
org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/repository-fs.xml [deleted file]
org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/repository-h2.xml [deleted file]
org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/repository-memory.xml [deleted file]
org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/servlet/OpenInViewSessionProvider.java [deleted file]
org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/servlet/RemotingServlet.java [deleted file]
org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/servlet/WebdavServlet.java [deleted file]
org.argeo.server.jcr/bnd.bnd
org.argeo.server.jcr/build.properties
org.argeo.server.jcr/pom.xml
org.argeo.server.jcr/src/org/argeo/jackrabbit/JackrabbitAuthorizations.java [new file with mode: 0644]
org.argeo.server.jcr/src/org/argeo/jackrabbit/JackrabbitContainer.java [new file with mode: 0644]
org.argeo.server.jcr/src/org/argeo/jackrabbit/JackrabbitDataModelMigration.java [new file with mode: 0644]
org.argeo.server.jcr/src/org/argeo/jackrabbit/JackrabbitRepositoryFactory.java [new file with mode: 0644]
org.argeo.server.jcr/src/org/argeo/jackrabbit/JackrabbitWrapper.java [new file with mode: 0644]
org.argeo.server.jcr/src/org/argeo/jackrabbit/OsgiJackrabbitRepositoryFactory.java [new file with mode: 0644]
org.argeo.server.jcr/src/org/argeo/jackrabbit/repository-fs.xml [new file with mode: 0644]
org.argeo.server.jcr/src/org/argeo/jackrabbit/repository-h2.xml [new file with mode: 0644]
org.argeo.server.jcr/src/org/argeo/jackrabbit/repository-memory.xml [new file with mode: 0644]
org.argeo.server.jcr/src/org/argeo/jackrabbit/servlet/OpenInViewSessionProvider.java [new file with mode: 0644]
org.argeo.server.jcr/src/org/argeo/jackrabbit/servlet/RemotingServlet.java [new file with mode: 0644]
org.argeo.server.jcr/src/org/argeo/jackrabbit/servlet/WebdavServlet.java [new file with mode: 0644]
org.argeo.util/pom.xml
pom.xml

index ca9bde2185ddf0da367702233425ee76166f38da..6bba46fd6ab30056746be2b0afb469118bdcb7ee 100644 (file)
@@ -1,5 +1,6 @@
 <?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>
@@ -8,33 +9,7 @@
                <relativePath>..</relativePath>
        </parent>
        <artifactId>org.argeo.dep.cms</artifactId>
-       <name>Commons CMS Dependencies</name>
-       <build>
-               <plugins>
-                       <plugin>
-                               <groupId>org.apache.felix</groupId>
-                               <artifactId>maven-bundle-plugin</artifactId>
-                               <configuration>
-                                       <instructions>
-                                               <SLC-ModularDistribution>default</SLC-ModularDistribution>
-                                       </instructions>
-                               </configuration>
-                       </plugin>
-                       <plugin>
-                               <groupId>org.argeo.maven.plugins</groupId>
-                               <artifactId>maven-argeo-osgi-plugin</artifactId>
-                               <executions>
-                                       <execution>
-                                               <id>generate-descriptors</id>
-                                               <goals>
-                                                       <goal>descriptors</goal>
-                                               </goals>
-                                               <phase>generate-resources</phase>
-                                       </execution>
-                               </executions>
-                       </plugin>
-               </plugins>
-       </build>
+       <name>Commons CMS Light</name>
        <dependencies>
                <dependency>
                        <groupId>org.argeo.commons</groupId>
                                </exclusion>
 
                                <!-- Workbench -->
-                               <exclusion>
-                                       <groupId>org.argeo.tp.rap.platform</groupId>
-                                       <artifactId>javax.xml</artifactId>
-                               </exclusion>
                                <exclusion>
                                        <groupId>org.argeo.tp.rap.platform</groupId>
                                        <artifactId>org.eclipse.rap.ui.workbench</artifactId>
                                <!-- <groupId>org.argeo.tp</groupId> -->
                                <!-- <artifactId>org.aspectj.weaver</artifactId> -->
                                <!-- </exclusion> -->
-                               <!-- <exclusion> -->
-                               <!-- <groupId>org.argeo.tp.apache.ant</groupId> -->
-                               <!-- <artifactId>org.apache.ant</artifactId> -->
-                               <!-- </exclusion> -->
-                               <!-- <exclusion> -->
-                               <!-- <groupId>org.argeo.tp.apache.ant</groupId> -->
-                               <!-- <artifactId>org.apache.ant.launch</artifactId> -->
-                               <!-- </exclusion> -->
+                               <exclusion>
+                                       <groupId>org.argeo.tp.apache.ant</groupId>
+                                       <artifactId>org.apache.ant</artifactId>
+                               </exclusion>
+                               <exclusion>
+                                       <groupId>org.argeo.tp.apache.ant</groupId>
+                                       <artifactId>org.apache.ant.launch</artifactId>
+                               </exclusion>
                        </exclusions>
                </dependency>
 
        </dependencies>
-       <profiles>
-               <profile>
-                       <id>check-osgi</id>
-                       <build>
-                               <plugins>
-                                       <plugin>
-                                               <groupId>org.argeo.maven.plugins</groupId>
-                                               <artifactId>maven-argeo-osgi-plugin</artifactId>
-                                               <executions>
-                                                       <execution>
-                                                               <id>check-osgi</id>
-                                                               <phase>test</phase>
-                                                               <goals>
-                                                                       <goal>equinox</goal>
-                                                               </goals>
-                                                               <configuration>
-                                                                       <onlyCheck>true</onlyCheck>
-                                                               </configuration>
-                                                       </execution>
-                                               </executions>
-                                       </plugin>
-                               </plugins>
-                       </build>
-               </profile>
-       </profiles>
 </project>
\ No newline at end of file
index 14bd5b919b390c394dbe00c4b9409724cd0d6de8..002365fa7e7f70656c167afb110f1d49c25aa570 100644 (file)
@@ -7,35 +7,9 @@
                <relativePath>..</relativePath>
        </parent>
        <artifactId>org.argeo.security.dep.node.rap</artifactId>
-       <name>Node Eclipse RAP</name>
-       <build>
-               <plugins>
-                       <plugin>
-                               <groupId>org.apache.felix</groupId>
-                               <artifactId>maven-bundle-plugin</artifactId>
-                               <configuration>
-                                       <instructions>
-                                               <SLC-ModularDistribution>default</SLC-ModularDistribution>
-                                       </instructions>
-                               </configuration>
-                       </plugin>
-                       <plugin>
-                               <groupId>org.argeo.maven.plugins</groupId>
-                               <artifactId>maven-argeo-osgi-plugin</artifactId>
-                               <executions>
-                                       <execution>
-                                               <id>generate-descriptors</id>
-                                               <goals>
-                                                       <goal>descriptors</goal>
-                                               </goals>
-                                               <phase>generate-resources</phase>
-                                       </execution>
-                               </executions>
-                       </plugin>
-               </plugins>
-       </build>
+       <name>Commons CMS Full</name>
        <dependencies>
-               <!-- CMS kernel -->
+               <!-- CMS -->
                <dependency>
                        <groupId>org.argeo.commons</groupId>
                        <artifactId>org.argeo.cms</artifactId>
                        <artifactId>org.argeo.security.ui.admin</artifactId>
                        <version>2.1.14-SNAPSHOT</version>
                </dependency>
-               <!-- <dependency> -->
-               <!-- <groupId>org.argeo.commons</groupId> -->
-               <!-- <artifactId>org.argeo.security.mvc</artifactId> -->
-               <!-- <version>2.1.12-SNAPSHOT</version> -->
-               <!-- </dependency> -->
 
                <!-- Basis -->
                <dependency>
                        <artifactId>org.argeo.security.dep.node</artifactId>
                        <version>2.1.14-SNAPSHOT</version>
                        <type>pom</type>
-                       <exclusions>
-                               <!-- <exclusion> <groupId>org.argeo.commons</groupId> <artifactId>org.argeo.security.dao.jackrabbit</artifactId> 
-                                       </exclusion> -->
-                               <!-- <exclusion> <groupId>org.argeo.commons</groupId> <artifactId>org.argeo.security.dao.os</artifactId> 
-                                       </exclusion> -->
-                       </exclusions>
                </dependency>
                <dependency>
                        <groupId>org.argeo.commons</groupId>
                        <artifactId>argeo-tp</artifactId>
                        <version>${version.argeo-distribution}</version>
                </dependency>
-
-               <!-- RAP -->
-               <!-- <dependency> <groupId>org.argeo.commons</groupId> <artifactId>org.argeo.eclipse.dep.rap</artifactId> 
-                       <version>2.1.12-SNAPSHOT</version> <type>pom</type> </dependency> -->
-               <!-- For Tomcat deployment <dependency> <groupId>org.argeo.commons</groupId> 
-                       <artifactId>org.argeo.server.rap.webapp</artifactId> <version>2.1.1.tp-SNAPSHOT</version> 
-                       </dependency> -->
        </dependencies>
-       <profiles>
-               <profile>
-                       <id>check-osgi</id>
-                       <build>
-                               <plugins>
-                                       <plugin>
-                                               <groupId>org.argeo.maven.plugins</groupId>
-                                               <artifactId>maven-argeo-osgi-plugin</artifactId>
-                                               <executions>
-                                                       <execution>
-                                                               <id>check-osgi</id>
-                                                               <phase>test</phase>
-                                                               <goals>
-                                                                       <goal>equinox</goal>
-                                                               </goals>
-                                                               <configuration>
-                                                                       <onlyCheck>true</onlyCheck>
-                                                               </configuration>
-                                                       </execution>
-                                               </executions>
-                                       </plugin>
-                               </plugins>
-                       </build>
-               </profile>
-       </profiles>
 </project>
index 507bb9353423af4c60d85d30b2e5c160e79c8467..9c6440fd097e84092f6ec3da00eceea43c8ebfb7 100644 (file)
@@ -1,5 +1,6 @@
 <?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>
@@ -8,33 +9,7 @@
                <relativePath>..</relativePath>
        </parent>
        <artifactId>org.argeo.security.dep.node</artifactId>
-       <name>Node Backend</name>
-       <build>
-               <plugins>
-                       <plugin>
-                               <groupId>org.apache.felix</groupId>
-                               <artifactId>maven-bundle-plugin</artifactId>
-                               <configuration>
-                                       <instructions>
-                                               <SLC-ModularDistribution>default</SLC-ModularDistribution>
-                                       </instructions>
-                               </configuration>
-                       </plugin>
-                       <plugin>
-                               <groupId>org.argeo.maven.plugins</groupId>
-                               <artifactId>maven-argeo-osgi-plugin</artifactId>
-                               <executions>
-                                       <execution>
-                                               <id>generate-descriptors</id>
-                                               <goals>
-                                                       <goal>descriptors</goal>
-                                               </goals>
-                                               <phase>generate-resources</phase>
-                                       </execution>
-                               </executions>
-                       </plugin>
-               </plugins>
-       </build>
+       <name>Commons Backend</name>
        <dependencies>
                <!-- Third Parties -->
                <dependency>
                        <version>${version.argeo-distribution}</version>
                </dependency>
 
-               <!-- Default JCR repositories configurations -->
-               <!-- <dependency> -->
-               <!-- <groupId>org.argeo.commons</groupId> -->
-               <!-- <artifactId>org.argeo.node.repo.jackrabbit</artifactId> -->
-               <!-- <version>2.1.13-SNAPSHOT</version> -->
-               <!-- </dependency> -->
-
                <!-- OSGi Boot (and Equinox) -->
                <dependency>
                        <groupId>org.argeo.commons</groupId>
                        <version>2.1.14-SNAPSHOT</version>
                </dependency>
 
-               <!-- Jackrabbit -->
+               <!-- JCR / Jackrabbit -->
                <dependency>
                        <groupId>org.argeo.commons</groupId>
-                       <artifactId>org.argeo.server.jackrabbit</artifactId>
+                       <artifactId>org.argeo.server.jcr</artifactId>
                        <version>2.1.14-SNAPSHOT</version>
                </dependency>
                <dependency>
                        <artifactId>org.argeo.security.jackrabbit</artifactId>
                        <version>2.1.14-SNAPSHOT</version>
                </dependency>
-
-               <!-- Security (Jackrabbit) -->
-               <!-- <dependency> -->
-               <!-- <groupId>org.argeo.commons</groupId> -->
-               <!-- <artifactId>org.argeo.security.dao.jackrabbit</artifactId> -->
-               <!-- <version>2.1.13-SNAPSHOT</version> -->
-               <!-- </dependency> -->
        </dependencies>
-       <profiles>
-               <profile>
-                       <id>check-osgi</id>
-                       <build>
-                               <plugins>
-                                       <plugin>
-                                               <groupId>org.argeo.maven.plugins</groupId>
-                                               <artifactId>maven-argeo-osgi-plugin</artifactId>
-                                               <executions>
-                                                       <execution>
-                                                               <id>check-osgi</id>
-                                                               <phase>test</phase>
-                                                               <goals>
-                                                                       <goal>equinox</goal>
-                                                               </goals>
-                                                               <configuration>
-                                                                       <onlyCheck>true</onlyCheck>
-                                                               </configuration>
-                                                       </execution>
-                                               </executions>
-                                       </plugin>
-                               </plugins>
-                       </build>
-               </profile>
-       </profiles>
 </project>
\ No newline at end of file
index 5702442abd9072a1bc46c793854d6becb241900e..200cf2ce697069a604bb3aa0470271d9a34a8f1a 100644 (file)
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<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>
@@ -8,16 +9,62 @@
                <relativePath>..</relativePath>
        </parent>
        <artifactId>dep</artifactId>
-       <name>Commons Base Dependencies</name>
+       <name>Commons Modular Distributions</name>
        <packaging>pom</packaging>
        <modules>
                <module>org.argeo.security.dep.node</module>
                <module>org.argeo.dep.cms</module>
                <module>org.argeo.security.dep.node.rap</module>
        </modules>
+       <build>
+               <plugins>
+                       <plugin>
+                               <groupId>org.apache.felix</groupId>
+                               <artifactId>maven-bundle-plugin</artifactId>
+                               <configuration>
+                                       <instructions>
+                                               <SLC-ModularDistribution>default</SLC-ModularDistribution>
+                                       </instructions>
+                               </configuration>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.argeo.maven.plugins</groupId>
+                               <artifactId>maven-argeo-osgi-plugin</artifactId>
+                               <executions>
+                                       <execution>
+                                               <id>generate-descriptors</id>
+                                               <goals>
+                                                       <goal>descriptors</goal>
+                                               </goals>
+                                               <phase>generate-resources</phase>
+                                       </execution>
+                               </executions>
+                       </plugin>
+               </plugins>
+       </build>
        <profiles>
                <profile>
                        <id>check-osgi</id>
+                       <build>
+                               <plugins>
+                                       <plugin>
+                                               <groupId>org.argeo.maven.plugins</groupId>
+                                               <artifactId>maven-argeo-osgi-plugin</artifactId>
+                                               <executions>
+                                                       <execution>
+                                                               <id>check-osgi</id>
+                                                               <phase>test</phase>
+                                                               <goals>
+                                                                       <goal>equinox</goal>
+                                                               </goals>
+                                                               <configuration>
+                                                                       <onlyCheck>true</onlyCheck>
+                                                               </configuration>
+                                                       </execution>
+                                               </executions>
+                                       </plugin>
+                               </plugins>
+                       </build>
                        <dependencies>
                                <dependency>
                                        <groupId>org.argeo.commons</groupId>
index 06eefe9e3d3e56f19c914e4cc3df72ad55c72163..9a81e9b1cf995f3731ac1c0430b99b8790e0f712 100644 (file)
@@ -8,9 +8,9 @@
        </parent>
        <artifactId>osgi-boot</artifactId>
        <packaging>pom</packaging>
-       <name>Commons OSGi Boot Distribution</name>
+       <name>Commons Deployable OSGi Boot</name>
        <properties>
-               <version.equinox>3.9.1.v20140110-1610</version.equinox>
+               <version.equinox>3.10.1.v20140909-1633</version.equinox>
        </properties>
        <profiles>
                <profile>
index adcc087dfb1a088ea38cea0bf4f8bea34304d89d..da75c3bea34893386111b7be519f9134c8a8a6c8 100644 (file)
@@ -8,7 +8,7 @@
                <relativePath>..</relativePath>
        </parent>
        <artifactId>dist</artifactId>
-       <name>Commons Distributions</name>
+       <name>Commons Deployable Distributions</name>
        <packaging>pom</packaging>
        <modules>
                <module>osgi-boot</module>
index 4772234852f4765e885efd5ca3f39a22301b9c6d..bdcfd61d0b589e0d9097737a59400826d42487d2 100644 (file)
@@ -8,9 +8,10 @@ javax.jcr.security,\
 org.xml.sax;version="0.0.0",\
 org.eclipse.swt.widgets;version="0.0.0",\
 org.argeo.jcr,\
-org.h2;resolution:=optional,\
 org.springframework.context,\
 org.apache.jackrabbit.api,\
 org.apache.jackrabbit.commons,\
 org.eclipse.rap.rwt.osgi,\
+org.h2;resolution:=optional,\
+org.apache.commons.vfs2.*;resolution:=optional,\
 *
index b2a398d2a1330df37373f7700f1d6da696e25fa1..660a263fc82feee99587f2b41344f4b5841493a6 100644 (file)
@@ -8,7 +8,7 @@
                <relativePath>..</relativePath>
        </parent>
        <artifactId>org.argeo.cms</artifactId>
-       <name>Commons Content Management System</name>
+       <name>Commons CMS</name>
        <packaging>jar</packaging>
        <dependencies>
                <dependency>
                        <artifactId>org.argeo.server.jcr</artifactId>
                        <version>2.1.14-SNAPSHOT</version>
                </dependency>
-               <dependency>
-                       <groupId>org.argeo.commons</groupId>
-                       <artifactId>org.argeo.server.jackrabbit</artifactId>
-                       <version>2.1.14-SNAPSHOT</version>
-               </dependency>
-
                <dependency>
                        <groupId>org.argeo.commons</groupId>
                        <artifactId>org.argeo.security.core</artifactId>
                        <version>2.1.14-SNAPSHOT</version>
                </dependency>
-
-               <!-- Files -->
-               <!--  <dependency>
-                       <groupId>org.argeo.tp.rap.addons</groupId>
-                       <artifactId>org.eclipse.rap.addons.fileupload</artifactId>
-               </dependency>
-               <dependency>
-                       <groupId>org.argeo.tp.rap.addons</groupId>
-                       <artifactId>org.eclipse.rap.addons.filedialog</artifactId>
-               </dependency> -->
-
-               <!-- RAP -->
-               <!--  <dependency>
-                       <groupId>org.argeo.tp.rap.platform</groupId>
-                       <artifactId>org.eclipse.rap.rwt</artifactId>
-               </dependency>
-               <dependency>
-                       <groupId>org.argeo.tp.rap.platform</groupId>
-                       <artifactId>org.eclipse.rap.jface</artifactId>
-               </dependency>
-               <dependency>
-                       <groupId>org.argeo.tp.rap.platform</groupId>
-                       <artifactId>org.eclipse.core.commands</artifactId>
-               </dependency>  -->
-               <!--  Argeo base Eclipse utilities. -->
                <dependency>
                        <groupId>org.argeo.commons</groupId>
                        <artifactId>org.argeo.eclipse.ui</artifactId>
                        <version>2.1.14-SNAPSHOT</version>
                </dependency>
-
-
-               <!-- OSGi -->
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.tp</groupId> -->
-<!--                   <artifactId>org.springframework.osgi.core</artifactId> -->
-<!--           </dependency> -->
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.tp.rap.platform</groupId> -->
-<!--                   <artifactId>org.eclipse.osgi</artifactId> -->
-<!--                   <scope>provided</scope> -->
-<!--           </dependency> -->
        </dependencies>
 </project>
\ No newline at end of file
index af8fa1c99fc25963aa302535afe16d34d7a0c6e0..7871ee0861e4373b38bda2dc61af56c60b92be24 100644 (file)
@@ -23,6 +23,7 @@ import org.eclipse.rap.rwt.service.ResourceLoader;
 import org.osgi.framework.BundleContext;
 
 /** Configures an Argeo CMS RWT application. */
+@SuppressWarnings("deprecation")
 public class CmsApplication implements CmsConstants, ApplicationConfiguration,
                BundleContextAware {
        final static Log log = LogFactory.getLog(CmsApplication.class);
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/backup/AbstractAtomicBackup.java b/org.argeo.cms/src/org/argeo/cms/internal/backup/AbstractAtomicBackup.java
new file mode 100644 (file)
index 0000000..88fbb5a
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * 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.
+ */
+package org.argeo.cms.internal.backup;
+
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.FileSystemOptions;
+import org.apache.commons.vfs2.provider.sftp.SftpFileSystemConfigBuilder;
+import org.argeo.ArgeoException;
+
+/**
+ * Simplify atomic backups implementation, especially by managing VFS.
+ */
+public abstract class AbstractAtomicBackup implements AtomicBackup {
+       private String name;
+       private String compression = "bz2";
+
+       protected abstract void writeBackup(FileObject targetFo);
+
+       public AbstractAtomicBackup() {
+       }
+
+       public AbstractAtomicBackup(String name) {
+               this.name = name;
+       }
+
+       public void init() {
+               if (name == null)
+                       throw new ArgeoException("Atomic backup name must be set");
+       }
+
+       public void destroy() {
+
+       }
+
+       @Override
+       public String backup(FileSystemManager fileSystemManager,
+                       String backupsBase, BackupContext backupContext,
+                       FileSystemOptions opts) {
+               if (name == null)
+                       throw new ArgeoException("Atomic backup name must be set");
+
+               FileObject targetFo = null;
+               try {
+                       if (backupsBase.startsWith("sftp:"))
+                               SftpFileSystemConfigBuilder.getInstance()
+                                               .setStrictHostKeyChecking(opts, "no");
+                       if (compression == null || compression.equals("none"))
+                               targetFo = fileSystemManager.resolveFile(backupsBase + '/'
+                                               + backupContext.getRelativeFolder() + '/' + name, opts);
+                       else if (compression.equals("bz2"))
+                               targetFo = fileSystemManager.resolveFile("bz2:" + backupsBase
+                                               + '/' + backupContext.getRelativeFolder() + '/' + name
+                                               + ".bz2" + "!" + name, opts);
+                       else if (compression.equals("gz"))
+                               targetFo = fileSystemManager.resolveFile("gz:" + backupsBase
+                                               + '/' + backupContext.getRelativeFolder() + '/' + name
+                                               + ".gz" + "!" + name, opts);
+                       else
+                               throw new ArgeoException("Unsupported compression "
+                                               + compression);
+
+                       writeBackup(targetFo);
+
+                       return targetFo.toString();
+               } catch (Exception e) {
+                       throw new ArgeoException("Cannot backup " + name + " to "
+                                       + targetFo, e);
+               } finally {
+                       BackupUtils.closeFOQuietly(targetFo);
+               }
+       }
+
+       public void setName(String name) {
+               this.name = name;
+       }
+
+       public String getName() {
+               return name;
+       }
+
+       public void setCompression(String compression) {
+               this.compression = compression;
+       }
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/backup/AtomicBackup.java b/org.argeo.cms/src/org/argeo/cms/internal/backup/AtomicBackup.java
new file mode 100644 (file)
index 0000000..e14344c
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+package org.argeo.cms.internal.backup;
+
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.FileSystemOptions;
+
+/** Performs the backup of a single component, typically a database dump */
+public interface AtomicBackup {
+       /** Name identifiying this backup */
+       public String getName();
+
+       /**
+        * Retrieves the data of the component in a format that allows to restore
+        * the component
+        * 
+        * @param backupContext
+        *            the context of this backup
+        * @return the VFS URI of the generated file or directory
+        */
+       public String backup(FileSystemManager fileSystemManager,
+                       String backupsBase, BackupContext backupContext,
+                       FileSystemOptions opts);
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/backup/BackupContext.java b/org.argeo.cms/src/org/argeo/cms/internal/backup/BackupContext.java
new file mode 100644 (file)
index 0000000..14e7eb4
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+package org.argeo.cms.internal.backup;
+
+import java.text.DateFormat;
+import java.util.Date;
+
+/**
+ * Transient information of a given backup, centralizing common information such
+ * as timestamp and location.
+ */
+public interface BackupContext {
+       /** Backup date */
+       public Date getTimestamp();
+
+       /** Formatted backup date */
+       public String getTimestampAsString();
+
+       /** System name */
+       public String getSystemName();
+
+       /** Local base */
+       public String getRelativeFolder();
+
+       /** Date format */
+       public DateFormat getDateFormat();
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/backup/BackupFileSystemManager.java b/org.argeo.cms/src/org/argeo/cms/internal/backup/BackupFileSystemManager.java
new file mode 100644 (file)
index 0000000..2883e05
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+package org.argeo.cms.internal.backup;
+
+import org.apache.commons.vfs2.FileSystemException;
+import org.apache.commons.vfs2.impl.DefaultFileSystemManager;
+import org.apache.commons.vfs2.provider.bzip2.Bzip2FileProvider;
+import org.apache.commons.vfs2.provider.ftp.FtpFileProvider;
+import org.apache.commons.vfs2.provider.gzip.GzipFileProvider;
+import org.apache.commons.vfs2.provider.local.DefaultLocalFileProvider;
+import org.apache.commons.vfs2.provider.ram.RamFileProvider;
+import org.apache.commons.vfs2.provider.sftp.SftpFileProvider;
+import org.apache.commons.vfs2.provider.url.UrlFileProvider;
+import org.argeo.ArgeoException;
+
+/**
+ * Programatically configured VFS file system manager which can be declared as a
+ * bean and associated with a life cycle (methods
+ * {@link DefaultFileSystemManager#init()} and
+ * {@link DefaultFileSystemManager#closet()}). Supports bz2, file, ram, gzip,
+ * ftp, sftp
+ */
+public class BackupFileSystemManager extends DefaultFileSystemManager {
+
+       public BackupFileSystemManager() {
+               super();
+               try {
+                       addProvider("file", new DefaultLocalFileProvider());
+                       addProvider("bz2", new Bzip2FileProvider());
+                       addProvider("ftp", new FtpFileProvider());
+                       addProvider("sftp", new SftpFileProvider());
+                       addProvider("gzip", new GzipFileProvider());
+                       addProvider("ram", new RamFileProvider());
+                       setDefaultProvider(new UrlFileProvider());
+               } catch (FileSystemException e) {
+                       throw new ArgeoException("Cannot configure backup file provider", e);
+               }
+       }
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/backup/BackupPurge.java b/org.argeo.cms/src/org/argeo/cms/internal/backup/BackupPurge.java
new file mode 100644 (file)
index 0000000..75a6b16
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+package org.argeo.cms.internal.backup;
+
+import java.text.DateFormat;
+
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.FileSystemOptions;
+
+/** Purges previous backups */
+public interface BackupPurge {
+       /**
+        * Purge the backups identified by these arguments. Although these are the
+        * same fields as a {@link BackupContext} we don't pass it as argument since
+        * we want to use this interface to purge remote backups as well (that is,
+        * with a different base), or outside the scope of a running backup.
+        */
+       public void purge(FileSystemManager fileSystemManager, String base,
+                       String name, DateFormat dateFormat, FileSystemOptions opts);
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/backup/BackupUtils.java b/org.argeo.cms/src/org/argeo/cms/internal/backup/BackupUtils.java
new file mode 100644 (file)
index 0000000..9a4e91c
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+package org.argeo.cms.internal.backup;
+
+import org.apache.commons.vfs2.FileObject;
+
+/** Backup utilities */
+public class BackupUtils {
+       /** Close a file object quietly even if it is null or throws an exception. */
+       public static void closeFOQuietly(FileObject fo) {
+               if (fo != null) {
+                       try {
+                               fo.close();
+                       } catch (Exception e) {
+                               // silent
+                       }
+               }
+       }
+       
+       /** Prevents instantiation */
+       private BackupUtils() {
+       }
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/backup/MySqlBackup.java b/org.argeo.cms/src/org/argeo/cms/internal/backup/MySqlBackup.java
new file mode 100644 (file)
index 0000000..765c564
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+package org.argeo.cms.internal.backup;
+
+import org.apache.commons.vfs2.FileObject;
+
+/** Backups a MySQL database using mysqldump. */
+public class MySqlBackup extends OsCallBackup {
+       private String mysqldumpLocation = "/usr/bin/mysqldump";
+
+       private String dbUser;
+       private String dbPassword;
+       private String dbName;
+
+       public MySqlBackup() {
+       }
+
+       public MySqlBackup(String dbUser, String dbPassword, String dbName) {
+               this.dbUser = dbUser;
+               this.dbPassword = dbPassword;
+               this.dbName = dbName;
+               init();
+       }
+
+       @Override
+       public void init() {
+               if (getName() == null)
+                       setName(dbName + ".mysql");
+               super.init();
+       }
+
+       @Override
+       public void writeBackup(FileObject targetFo) {
+               if (getCommand() == null)
+                       setCommand(mysqldumpLocation
+                                       + " --lock-tables --add-locks --add-drop-table"
+                                       + " -u ${dbUser} --password=${dbPassword} --databases ${dbName}");
+               getVariables().put("dbUser", dbUser);
+               getVariables().put("dbPassword", dbPassword);
+               getVariables().put("dbName", dbName);
+
+               super.writeBackup(targetFo);
+       }
+
+       public void setDbUser(String dbUser) {
+               this.dbUser = dbUser;
+       }
+
+       public void setDbPassword(String dbPassword) {
+               this.dbPassword = dbPassword;
+       }
+
+       public void setDbName(String dbName) {
+               this.dbName = dbName;
+       }
+
+       public void setMysqldumpLocation(String mysqldumpLocation) {
+               this.mysqldumpLocation = mysqldumpLocation;
+       }
+
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/backup/OpenLdapBackup.java b/org.argeo.cms/src/org/argeo/cms/internal/backup/OpenLdapBackup.java
new file mode 100644 (file)
index 0000000..278e362
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+package org.argeo.cms.internal.backup;
+
+import org.apache.commons.vfs2.FileObject;
+import org.argeo.ArgeoException;
+
+/** Backups an OpenLDAP server using slapcat */
+public class OpenLdapBackup extends OsCallBackup {
+       private String slapcatLocation = "/usr/sbin/slapcat";
+       private String slapdConfLocation = "/etc/openldap/slapd.conf";
+       private String baseDn;
+
+       public OpenLdapBackup() {
+               super();
+       }
+
+       public OpenLdapBackup(String baseDn) {
+               super();
+               this.baseDn = baseDn;
+       }
+
+       @Override
+       public void writeBackup(FileObject targetFo) {
+               if (baseDn == null)
+                       throw new ArgeoException("Base DN must be set");
+
+               if (getCommand() == null)
+                       setCommand(slapcatLocation
+                                       + " -f ${slapdConfLocation} -b '${baseDn}'");
+               getVariables().put("slapdConfLocation", slapdConfLocation);
+               getVariables().put("baseDn", baseDn);
+
+               super.writeBackup(targetFo);
+       }
+
+       public void setSlapcatLocation(String slapcatLocation) {
+               this.slapcatLocation = slapcatLocation;
+       }
+
+       public void setSlapdConfLocation(String slapdConfLocation) {
+               this.slapdConfLocation = slapdConfLocation;
+       }
+
+       public void setBaseDn(String baseDn) {
+               this.baseDn = baseDn;
+       }
+
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/backup/OsCallBackup.java b/org.argeo.cms/src/org/argeo/cms/internal/backup/OsCallBackup.java
new file mode 100644 (file)
index 0000000..e588a0b
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * 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.
+ */
+package org.argeo.cms.internal.backup;
+
+import java.io.ByteArrayOutputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.exec.CommandLine;
+import org.apache.commons.exec.DefaultExecutor;
+import org.apache.commons.exec.ExecuteException;
+import org.apache.commons.exec.ExecuteStreamHandler;
+import org.apache.commons.exec.Executor;
+import org.apache.commons.exec.PumpStreamHandler;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.vfs2.FileContent;
+import org.apache.commons.vfs2.FileObject;
+import org.argeo.ArgeoException;
+
+/**
+ * Runs an OS command and save its standard output as a file. Typically used for
+ * MySQL or OpenLDAP dumps.
+ */
+public class OsCallBackup extends AbstractAtomicBackup {
+       private final static Log log = LogFactory.getLog(OsCallBackup.class);
+
+       private String command;
+       private Map<String, String> variables = new HashMap<String, String>();
+       private Executor executor = new DefaultExecutor();
+
+       private Map<String, String> environment = new HashMap<String, String>();
+
+       /** Name of the sudo user, root if "", not sudo if null */
+       private String sudo = null;
+
+       public OsCallBackup() {
+       }
+
+       public OsCallBackup(String name) {
+               super(name);
+       }
+
+       public OsCallBackup(String name, String command) {
+               super(name);
+               this.command = command;
+       }
+
+       @Override
+       public void writeBackup(FileObject targetFo) {
+               String commandToUse = command;
+
+               // sudo
+               if (sudo != null) {
+                       if (sudo.equals(""))
+                               commandToUse = "sudo " + commandToUse;
+                       else
+                               commandToUse = "sudo -u " + sudo + " " + commandToUse;
+               }
+
+               CommandLine commandLine = CommandLine.parse(commandToUse, variables);
+               ByteArrayOutputStream errBos = new ByteArrayOutputStream();
+               if (log.isTraceEnabled())
+                       log.trace(commandLine.toString());
+
+               try {
+                       // stdout
+                       FileContent targetContent = targetFo.getContent();
+                       // stderr
+                       ExecuteStreamHandler streamHandler = new PumpStreamHandler(
+                                       targetContent.getOutputStream(), errBos);
+                       executor.setStreamHandler(streamHandler);
+                       executor.execute(commandLine, environment);
+               } catch (ExecuteException e) {
+                       byte[] err = errBos.toByteArray();
+                       String errStr = new String(err);
+                       throw new ArgeoException("Process " + commandLine + " failed ("
+                                       + e.getExitValue() + "): " + errStr, e);
+               } catch (Exception e) {
+                       byte[] err = errBos.toByteArray();
+                       String errStr = new String(err);
+                       throw new ArgeoException("Process " + commandLine + " failed: "
+                                       + errStr, e);
+               } finally {
+                       IOUtils.closeQuietly(errBos);
+               }
+       }
+
+       public void setCommand(String command) {
+               this.command = command;
+       }
+
+       protected String getCommand() {
+               return command;
+       }
+
+       /**
+        * A reference to the environment variables that will be passed to the
+        * process. Empty by default.
+        */
+       protected Map<String, String> getEnvironment() {
+               return environment;
+       }
+
+       protected Map<String, String> getVariables() {
+               return variables;
+       }
+
+       public void setVariables(Map<String, String> variables) {
+               this.variables = variables;
+       }
+
+       public void setExecutor(Executor executor) {
+               this.executor = executor;
+       }
+
+       public void setSudo(String sudo) {
+               this.sudo = sudo;
+       }
+
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/backup/PostgreSqlBackup.java b/org.argeo.cms/src/org/argeo/cms/internal/backup/PostgreSqlBackup.java
new file mode 100644 (file)
index 0000000..dbc3624
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+package org.argeo.cms.internal.backup;
+
+import org.apache.commons.vfs2.FileObject;
+
+/** Backups a PostgreSQL database using pg_dump. */
+public class PostgreSqlBackup extends OsCallBackup {
+       /**
+        * PostgreSQL password environment variable (see
+        * http://stackoverflow.com/questions
+        * /2893954/how-to-pass-in-password-to-pg-dump)
+        */
+       protected final static String PGPASSWORD = "PGPASSWORD";
+
+       private String pgDumpLocation = "/usr/bin/pg_dump";
+
+       private String dbUser;
+       private String dbPassword;
+       private String dbName;
+
+       public PostgreSqlBackup() {
+               super();
+       }
+
+       public PostgreSqlBackup(String dbUser, String dbPassword, String dbName) {
+               this.dbUser = dbUser;
+               this.dbPassword = dbPassword;
+               this.dbName = dbName;
+               init();
+       }
+
+       @Override
+       public void init() {
+               // disable compression since pg_dump is used with -Fc option
+               setCompression(null);
+
+               if (getName() == null)
+                       setName(dbName + ".pgdump");
+               super.init();
+       }
+
+       @Override
+       public void writeBackup(FileObject targetFo) {
+               if (getCommand() == null) {
+                       getEnvironment().put(PGPASSWORD, dbPassword);
+                       setCommand(pgDumpLocation + " -Fc" + " -U ${dbUser} ${dbName}");
+               }
+               getVariables().put("dbUser", dbUser);
+               getVariables().put("dbPassword", dbPassword);
+               getVariables().put("dbName", dbName);
+
+               super.writeBackup(targetFo);
+       }
+
+       public void setDbUser(String dbUser) {
+               this.dbUser = dbUser;
+       }
+
+       public void setDbPassword(String dbPassword) {
+               this.dbPassword = dbPassword;
+       }
+
+       public void setDbName(String dbName) {
+               this.dbName = dbName;
+       }
+
+       public void setPgDumpLocation(String mysqldumpLocation) {
+               this.pgDumpLocation = mysqldumpLocation;
+       }
+
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/backup/SimpleBackupContext.java b/org.argeo.cms/src/org/argeo/cms/internal/backup/SimpleBackupContext.java
new file mode 100644 (file)
index 0000000..8e9e418
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+package org.argeo.cms.internal.backup;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.apache.commons.vfs2.FileSystemManager;
+
+/** Simple implementation of a backup context */
+public class SimpleBackupContext implements BackupContext {
+       private DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmm");
+       private final Date timestamp;
+       private final String name;
+
+       private final FileSystemManager fileSystemManager;
+
+       public SimpleBackupContext(FileSystemManager fileSystemManager,
+                       String backupsBase, String name) {
+               this.name = name;
+               this.timestamp = new Date();
+               this.fileSystemManager = fileSystemManager;
+       }
+
+       public Date getTimestamp() {
+               return timestamp;
+       }
+
+       public String getTimestampAsString() {
+               return dateFormat.format(timestamp);
+       }
+
+       public String getSystemName() {
+               return name;
+       }
+
+       public String getRelativeFolder() {
+               return name + '/' + getTimestampAsString();
+       }
+
+       public DateFormat getDateFormat() {
+               return dateFormat;
+       }
+
+       public FileSystemManager getFileSystemManager() {
+               return fileSystemManager;
+       }
+
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/backup/SimpleBackupPurge.java b/org.argeo.cms/src/org/argeo/cms/internal/backup/SimpleBackupPurge.java
new file mode 100644 (file)
index 0000000..64d749b
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+package org.argeo.cms.internal.backup;
+
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.FileSystemOptions;
+import org.apache.commons.vfs2.Selectors;
+import org.argeo.ArgeoException;
+import org.joda.time.DateTime;
+import org.joda.time.Period;
+
+/** Simple backup purge which keeps backups only for a given number of days */
+public class SimpleBackupPurge implements BackupPurge {
+       private final static Log log = LogFactory.getLog(SimpleBackupPurge.class);
+
+       private Integer daysKept = 30;
+
+       @Override
+       public void purge(FileSystemManager fileSystemManager, String base,
+                       String name, DateFormat dateFormat, FileSystemOptions opts) {
+               try {
+                       DateTime nowDt = new DateTime();
+                       FileObject baseFo = fileSystemManager.resolveFile(
+                                       base + '/' + name, opts);
+
+                       SortedMap<DateTime, FileObject> toDelete = new TreeMap<DateTime, FileObject>();
+                       int backupCount = 0;
+
+                       // make sure base dir exists
+                       baseFo.createFolder();
+
+                       // scan backups and list those which should be deleted
+                       for (FileObject backupFo : baseFo.getChildren()) {
+                               String backupName = backupFo.getName().getBaseName();
+                               Date backupDate = dateFormat.parse(backupName);
+                               backupCount++;
+
+                               DateTime backupDt = new DateTime(backupDate.getTime());
+                               Period sinceThen = new Period(backupDt, nowDt);
+                               int days = sinceThen.getDays();
+                               // int days = sinceThen.getMinutes();
+                               if (days > daysKept) {
+                                       toDelete.put(backupDt, backupFo);
+                               }
+                       }
+
+                       if (toDelete.size() != 0 && toDelete.size() == backupCount) {
+                               // all backups would be deleted
+                               // but we want to keep at least one
+                               DateTime lastBackupDt = toDelete.firstKey();
+                               FileObject keptFo = toDelete.remove(lastBackupDt);
+                               log.warn("Backup " + keptFo
+                                               + " kept although it is older than " + daysKept
+                                               + " days.");
+                       }
+
+                       // delete old backups
+                       for (FileObject backupFo : toDelete.values()) {
+                               backupFo.delete(Selectors.SELECT_ALL);
+                               if (log.isDebugEnabled())
+                                       log.debug("Deleted backup " + backupFo);
+                       }
+               } catch (Exception e) {
+                       throw new ArgeoException("Could not purge previous backups", e);
+               }
+
+       }
+
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/backup/SvnBackup.java b/org.argeo.cms/src/org/argeo/cms/internal/backup/SvnBackup.java
new file mode 100644 (file)
index 0000000..7367c04
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+package org.argeo.cms.internal.backup;
+
+import java.io.File;
+
+import org.apache.commons.vfs2.FileObject;
+
+/** Backups a Subversion repository using svnadmin. */
+public class SvnBackup extends OsCallBackup {
+       private String svnadminLocation = "/usr/bin/svnadmin";
+
+       private String repoLocation;
+       private String repoName;
+
+       public SvnBackup() {
+       }
+
+       public SvnBackup(String repoLocation) {
+               this.repoLocation = repoLocation;
+               init();
+       }
+
+       @Override
+       public void init() {
+               // use directory as repo name
+               if (repoName == null)
+                       repoName = new File(repoLocation).getName();
+
+               if (getName() == null)
+                       setName(repoName + ".svndump");
+               super.init();
+       }
+
+       @Override
+       public void writeBackup(FileObject targetFo) {
+               if (getCommand() == null) {
+                       setCommand(svnadminLocation + " dump " + " ${repoLocation}");
+               }
+               getVariables().put("repoLocation", repoLocation);
+
+               super.writeBackup(targetFo);
+       }
+
+       public void setRepoLocation(String repoLocation) {
+               this.repoLocation = repoLocation;
+       }
+
+       public void setRepoName(String repoName) {
+               this.repoName = repoName;
+       }
+
+       public void setSvnadminLocation(String mysqldumpLocation) {
+               this.svnadminLocation = mysqldumpLocation;
+       }
+
+}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/backup/SystemBackup.java b/org.argeo.cms/src/org/argeo/cms/internal/backup/SystemBackup.java
new file mode 100644 (file)
index 0000000..5036cc4
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * 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.
+ */
+package org.argeo.cms.internal.backup;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemException;
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.FileSystemOptions;
+import org.apache.commons.vfs2.Selectors;
+import org.apache.commons.vfs2.UserAuthenticator;
+import org.apache.commons.vfs2.impl.DefaultFileSystemConfigBuilder;
+import org.argeo.ArgeoException;
+
+/**
+ * Combines multiple backups and transfer them to a remote location. Purges
+ * remote and local data based on certain criteria.
+ */
+public class SystemBackup implements Runnable {
+       private final static Log log = LogFactory.getLog(SystemBackup.class);
+
+       private FileSystemManager fileSystemManager;
+       private UserAuthenticator userAuthenticator = null;
+
+       private String backupsBase;
+       private String systemName;
+
+       private List<AtomicBackup> atomicBackups = new ArrayList<AtomicBackup>();
+       private BackupPurge backupPurge = new SimpleBackupPurge();
+
+       private Map<String, UserAuthenticator> remoteBases = new HashMap<String, UserAuthenticator>();
+
+       @Override
+       public void run() {
+               if (atomicBackups.size() == 0)
+                       throw new ArgeoException("No atomic backup listed");
+               List<String> failures = new ArrayList<String>();
+
+               SimpleBackupContext backupContext = new SimpleBackupContext(
+                               fileSystemManager, backupsBase, systemName);
+
+               // purge older backups
+               FileSystemOptions opts = new FileSystemOptions();
+               try {
+                       DefaultFileSystemConfigBuilder.getInstance().setUserAuthenticator(
+                                       opts, userAuthenticator);
+               } catch (FileSystemException e) {
+                       throw new ArgeoException("Cannot create authentication", e);
+               }
+
+               try {
+
+                       backupPurge.purge(fileSystemManager, backupsBase, systemName,
+                                       backupContext.getDateFormat(), opts);
+               } catch (Exception e) {
+                       failures.add("Purge " + backupsBase + " failed: " + e.getMessage());
+                       log.error("Purge of " + backupsBase + " failed", e);
+               }
+
+               // perform backup
+               for (AtomicBackup atomickBackup : atomicBackups) {
+                       try {
+                               String target = atomickBackup.backup(fileSystemManager,
+                                               backupsBase, backupContext, opts);
+                               if (log.isDebugEnabled())
+                                       log.debug("Performed backup " + target);
+                       } catch (Exception e) {
+                               String msg = "Atomic backup " + atomickBackup.getName()
+                                               + " failed: " + ArgeoException.chainCausesMessages(e);
+                               failures.add(msg);
+                               log.error(msg);
+                               if (log.isTraceEnabled())
+                                       log.trace(
+                                                       "Stacktrace of atomic backup "
+                                                                       + atomickBackup.getName() + " failure.", e);
+                       }
+               }
+
+               // dispatch to remote
+               for (String remoteBase : remoteBases.keySet()) {
+                       FileObject localBaseFo = null;
+                       FileObject remoteBaseFo = null;
+                       UserAuthenticator auth = remoteBases.get(remoteBase);
+
+                       // authentication
+                       FileSystemOptions remoteOpts = new FileSystemOptions();
+                       try {
+                               DefaultFileSystemConfigBuilder.getInstance()
+                                               .setUserAuthenticator(remoteOpts, auth);
+                               backupPurge.purge(fileSystemManager, remoteBase, systemName,
+                                               backupContext.getDateFormat(), remoteOpts);
+                       } catch (Exception e) {
+                               failures.add("Purge " + remoteBase + " failed: "
+                                               + e.getMessage());
+                               log.error("Cannot purge " + remoteBase, e);
+                       }
+
+                       try {
+                               localBaseFo = fileSystemManager.resolveFile(backupsBase + '/'
+                                               + backupContext.getRelativeFolder(), opts);
+                               remoteBaseFo = fileSystemManager.resolveFile(remoteBase + '/'
+                                               + backupContext.getRelativeFolder(), remoteOpts);
+                               remoteBaseFo.copyFrom(localBaseFo, Selectors.SELECT_ALL);
+                               if (log.isDebugEnabled())
+                                       log.debug("Copied backup to " + remoteBaseFo + " from "
+                                                       + localBaseFo);
+                               // }
+                       } catch (Exception e) {
+                               failures.add("Dispatch to " + remoteBase + " failed: "
+                                               + e.getMessage());
+                               log.error(
+                                               "Cannot dispatch backups from "
+                                                               + backupContext.getRelativeFolder() + " to "
+                                                               + remoteBase, e);
+                       }
+                       BackupUtils.closeFOQuietly(localBaseFo);
+                       BackupUtils.closeFOQuietly(remoteBaseFo);
+               }
+
+               int failureCount = 0;
+               if (failures.size() > 0) {
+                       StringBuffer buf = new StringBuffer();
+                       for (String failure : failures) {
+                               buf.append('\n').append(failureCount).append(" - ")
+                                               .append(failure);
+                               failureCount++;
+                       }
+                       throw new ArgeoException(failureCount
+                                       + " error(s) when running the backup,"
+                                       + " check the logs and the backups as soon as possible."
+                                       + buf);
+               }
+       }
+
+       public void setFileSystemManager(FileSystemManager fileSystemManager) {
+               this.fileSystemManager = fileSystemManager;
+       }
+
+       public void setBackupsBase(String backupsBase) {
+               this.backupsBase = backupsBase;
+       }
+
+       public void setSystemName(String name) {
+               this.systemName = name;
+       }
+
+       public void setAtomicBackups(List<AtomicBackup> atomicBackups) {
+               this.atomicBackups = atomicBackups;
+       }
+
+       public void setBackupPurge(BackupPurge backupPurge) {
+               this.backupPurge = backupPurge;
+       }
+
+       public void setUserAuthenticator(UserAuthenticator userAuthenticator) {
+               this.userAuthenticator = userAuthenticator;
+       }
+
+       public void setRemoteBases(Map<String, UserAuthenticator> remoteBases) {
+               this.remoteBases = remoteBases;
+       }
+
+//     public static void main(String args[]) {
+//             while (true) {
+//                     try {
+//                             StandardFileSystemManager fsm = new StandardFileSystemManager();
+//                             fsm.init();
+//
+//                             SystemBackup systemBackup = new SystemBackup();
+//                             systemBackup.setSystemName("mySystem");
+//                             systemBackup
+//                                             .setBackupsBase("/home/mbaudier/dev/src/commons/server/runtime/org.argeo.server.core/target");
+//                             systemBackup.setFileSystemManager(fsm);
+//
+//                             List<AtomicBackup> atomicBackups = new ArrayList<AtomicBackup>();
+//
+//                             MySqlBackup mySqlBackup = new MySqlBackup("root", "", "test");
+//                             atomicBackups.add(mySqlBackup);
+//                             PostgreSqlBackup postgreSqlBackup = new PostgreSqlBackup(
+//                                             "argeo", "argeo", "gis_template");
+//                             atomicBackups.add(postgreSqlBackup);
+//                             SvnBackup svnBackup = new SvnBackup(
+//                                             "/home/mbaudier/tmp/testsvnrepo");
+//                             atomicBackups.add(svnBackup);
+//
+//                             systemBackup.setAtomicBackups(atomicBackups);
+//
+//                             Map<String, UserAuthenticator> remoteBases = new HashMap<String, UserAuthenticator>();
+//                             StaticUserAuthenticator userAuthenticator = new StaticUserAuthenticator(
+//                                             null, "demo", "demo");
+//                             remoteBases.put("sftp://localhost/home/mbaudier/test",
+//                                             userAuthenticator);
+//                             systemBackup.setRemoteBases(remoteBases);
+//
+//                             systemBackup.run();
+//
+//                             fsm.close();
+//                     } catch (FileSystemException e) {
+//                             // TODO Auto-generated catch block
+//                             e.printStackTrace();
+//                             System.exit(1);
+//                     }
+//
+//                     // wait
+//                     try {
+//                             Thread.sleep(120 * 1000);
+//                     } catch (InterruptedException e) {
+//                             e.printStackTrace();
+//                     }
+//             }
+//     }
+}
index c0383f5439b897dfaaf4e51ba11f670211969e04..db66de2eaa989e75a8bf809635c1c29a4a89e0fc 100644 (file)
@@ -15,8 +15,6 @@ import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.argeo.cms.CmsException;
-import org.argeo.cms.internal.kernel.NodeHttp.AnonymousFilter;
-import org.argeo.cms.internal.kernel.NodeHttp.DavFilter;
 import org.argeo.jackrabbit.servlet.OpenInViewSessionProvider;
 import org.argeo.jackrabbit.servlet.RemotingServlet;
 import org.argeo.jackrabbit.servlet.WebdavServlet;
@@ -52,7 +50,7 @@ class NodeHttp implements KernelConstants, ArgeoJcrConstants {
        private String httpAuthRealm = "Argeo";
 
        // Filters
-       private final RootFilter rootFilter;
+       // private final RootFilter rootFilter;
 
        // remoting
        private OpenInViewSessionProvider sessionProvider;
@@ -81,7 +79,7 @@ class NodeHttp implements KernelConstants, ArgeoJcrConstants {
                                        + ExtendedHttpService.class + " service.");
 
                // Filters
-               rootFilter = new RootFilter();
+               // rootFilter = new RootFilter();
 
                // DAV
                sessionProvider = new OpenInViewSessionProvider();
index b5d2eb412365b6f01b78313ac681761b7b0b2976..be94cd5df7f3f6a716e68962ae38ff2ce75461e6 100644 (file)
@@ -30,12 +30,15 @@ class NodeSecurity implements AuthenticationManager {
 
        private final InternalAuthenticationProvider internalAuth;
        private final AnonymousAuthenticationProvider anonymousAuth;
-       private final JackrabbitUserAdminService jackrabbitUserAdmin;
+       private final JackrabbitUserAdminService userAdminService;
+       // private final JcrUserAdmin userAdmin;
 
        private ServiceRegistration<AuthenticationManager> authenticationManagerReg;
-       private ServiceRegistration<UserAdminService> userAdminReg;
+       private ServiceRegistration<UserAdminService> userAdminServiceReg;
        private ServiceRegistration<UserDetailsManager> userDetailsManagerReg;
 
+       // private ServiceRegistration<UserAdmin> userAdminReg;
+
        public NodeSecurity(BundleContext bundleContext, JackrabbitNode node)
                        throws RepositoryException {
                URL url = getClass().getClassLoader().getResource(
@@ -51,33 +54,36 @@ class NodeSecurity implements AuthenticationManager {
                                KernelConstants.DEFAULT_SECURITY_KEY);
 
                // user admin
-               jackrabbitUserAdmin = new JackrabbitUserAdminService();
-               jackrabbitUserAdmin.setRepository(node);
-               jackrabbitUserAdmin.setSecurityModel(new SimpleJcrSecurityModel());
-               jackrabbitUserAdmin.init();
+               userAdminService = new JackrabbitUserAdminService();
+               userAdminService.setRepository(node);
+               userAdminService.setSecurityModel(new SimpleJcrSecurityModel());
+               userAdminService.init();
+
+               // userAdmin = new JcrUserAdmin(bundleContext);
+               // userAdmin.setUserAdminService(userAdminService);
        }
 
        public void publish() {
                authenticationManagerReg = bundleContext.registerService(
                                AuthenticationManager.class, this, null);
-               userAdminReg = bundleContext.registerService(UserAdminService.class,
-                               jackrabbitUserAdmin, null);
+               userAdminServiceReg = bundleContext.registerService(
+                               UserAdminService.class, userAdminService, null);
                userDetailsManagerReg = bundleContext.registerService(
-                               UserDetailsManager.class, jackrabbitUserAdmin, null);
-               // userAdminReg =
-               // bundleContext.registerService(UserDetailsService.class,
-               // jackrabbitUserAdmin, null);
+                               UserDetailsManager.class, userAdminService, null);
+               // userAdminReg = bundleContext.registerService(UserAdmin.class,
+               // userAdmin, null);
        }
 
        void destroy() {
                try {
-                       jackrabbitUserAdmin.destroy();
+                       userAdminService.destroy();
                } catch (RepositoryException e) {
                        log.error("Error while destroying Jackrabbit useradmin");
                }
                userDetailsManagerReg.unregister();
-               userAdminReg.unregister();
+               userAdminServiceReg.unregister();
                authenticationManagerReg.unregister();
+               // userAdminReg.unregister();
        }
 
        @Override
@@ -89,7 +95,7 @@ class NodeSecurity implements AuthenticationManager {
                else if (authentication instanceof AnonymousAuthenticationToken)
                        auth = anonymousAuth.authenticate(authentication);
                else if (authentication instanceof UsernamePasswordAuthenticationToken)
-                       auth = jackrabbitUserAdmin.authenticate(authentication);
+                       auth = userAdminService.authenticate(authentication);
                if (auth == null)
                        throw new CmsException("Could not authenticate " + authentication);
                return auth;
index e779a79931c393a18c2ee8c6982a2502e5664e7a..331275c44dd3484dbd8e0bd071bfc7e08109fa58 100644 (file)
@@ -10,7 +10,6 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.argeo.cms.CmsEditable;
 import org.argeo.cms.CmsException;
-import org.argeo.cms.widgets.JcrComposite;
 import org.argeo.cms.widgets.ScrolledPage;
 import org.eclipse.jface.viewers.ContentViewer;
 import org.eclipse.jface.viewers.ISelection;
index 167f2d3e366e5d7ce7f7fd8c5b745e4428ae4384..d164dbc96e32eeed6d94a82cdb1baef399b8d32f 100644 (file)
@@ -9,33 +9,16 @@
        </parent>
        <artifactId>org.argeo.eclipse.ui.rap</artifactId>
        <name>Commons Eclipse UI RAP</name>
-       <description>Provide rap specific classes and behaviour in order to provide single sourcing abilities</description>
-       <packaging>jar</packaging>
        <dependencies>
-               <!-- Generic base UI classes. -->
                <dependency>
                        <groupId>org.argeo.commons</groupId>
                        <artifactId>org.argeo.eclipse.ui</artifactId>
                        <version>2.1.14-SNAPSHOT</version>
                </dependency>
-
-               <!-- Base distribution for RAP projects -->
-               <!--  <dependency>
-                       <groupId>org.argeo.commons</groupId>
-                       <artifactId>org.argeo.eclipse.dep.rap</artifactId>
-                       <type>pom</type>
-                       <version>2.1.12-SNAPSHOT</version>
-               </dependency>  -->
-
-               <!-- Utils and logging -->
                <dependency>
                        <groupId>org.argeo.commons</groupId>
                        <artifactId>org.argeo.util</artifactId>
                        <version>2.1.14-SNAPSHOT</version>
                </dependency>
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.tp</groupId> -->
-<!--                   <artifactId>slf4j.org.apache.commons.logging</artifactId> -->
-<!--           </dependency> -->
        </dependencies>
 </project>
\ No newline at end of file
index a1f59ea9e2821bcd821b82218a7424456674007c..3977949dc95741489d62662c39d9df765007c8d6 100644 (file)
@@ -7,5 +7,5 @@
                <relativePath>..</relativePath>
        </parent>
        <artifactId>org.argeo.eclipse.ui.workbench.rap</artifactId>
-       <name>Commons Eclipse UI Workbench RAP</name>
+       <name>Commons Eclipse Workbench RAP</name>
 </project>
index 360054f331a671b1a4e1d0cfa62776f9ffa91a8a..bde063db04cdd3cddebd8c8ea398529bd4e225d1 100644 (file)
@@ -7,44 +7,23 @@
                <relativePath>..</relativePath>
        </parent>
        <artifactId>org.argeo.eclipse.ui.workbench</artifactId>
-       <name>Commons Eclipse UI Workbench</name>
+       <name>Commons Eclipse Workbench</name>
        <dependencies>
-               <!-- Generic Eclipse UI Dependencies -->
                <dependency>
                        <groupId>org.argeo.commons</groupId>
-                       <artifactId>org.argeo.eclipse.ui</artifactId>
+                       <artifactId>org.argeo.util</artifactId>
                        <version>2.1.14-SNAPSHOT</version>
-                       <exclusions>
-                               <!-- version of the org.osgi.framework package provided in this bundle 
-                                       is too old -->
-                               <!--  <exclusion>
-                                       <groupId>org.argeo.tp</groupId>
-                                       <artifactId>org.osgi.core</artifactId>
-                               </exclusion>  -->
-                       </exclusions>
                </dependency>
-
-               <!-- We build against RAP -->
                <dependency>
                        <groupId>org.argeo.commons</groupId>
-                       <artifactId>org.argeo.eclipse.ui.rap</artifactId>
+                       <artifactId>org.argeo.eclipse.ui</artifactId>
                        <version>2.1.14-SNAPSHOT</version>
-                       <scope>provided</scope>
                </dependency>
-
-               <!--  <dependency>
-                       <groupId>org.argeo.commons</groupId>
-                       <artifactId>org.argeo.eclipse.dep.rap</artifactId>
-                       <type>pom</type>
-                       <version>2.1.12-SNAPSHOT</version>
-                       <scope>provided</scope>
-               </dependency> -->
-
-               <!-- Business dependencies -->
                <dependency>
                        <groupId>org.argeo.commons</groupId>
-                       <artifactId>org.argeo.util</artifactId>
+                       <artifactId>org.argeo.eclipse.ui.rap</artifactId>
                        <version>2.1.14-SNAPSHOT</version>
+                       <scope>provided</scope>
                </dependency>
        </dependencies>
-</project>
+</project>
\ No newline at end of file
index 32bfbc1ade358b5ec61d7a6a49249eeaa260fb7f..bf8d37a8f1f2eee91054c24e234470d72389ef8e 100644 (file)
@@ -1,4 +1,3 @@
-Require-Bundle: org.eclipse.core.runtime
 Import-Package: org.eclipse.core.commands,\
                                org.eclipse.jface.window,\
                                org.eclipse.swt,\
@@ -11,12 +10,3 @@ Import-Package: org.eclipse.core.commands,\
                                javax.jcr.nodetype,\
                                org.springframework.security.core,\
                                *
-
-# Was: 
-#Bundle-ActivationPolicy: lazy
-#Bundle-SymbolicName: org.argeo.eclipse.ui;singleton:=true
-#Bundle-Activator: org.argeo.eclipse.ui.ArgeoUiPlugin 
-
-#!org.eclipse.core.commands,\ 
-# !org.eclipse.core.runtime,\
-# !org.eclipse.ui.plugin,\
index d352a32ec3ff9407164fbe490362a61914407190..7a6d535050d901765ec14c25396144d03df76425 100644 (file)
@@ -9,16 +9,7 @@
        </parent>
        <artifactId>org.argeo.eclipse.ui</artifactId>
        <name>Commons Eclipse UI</name>
-       <packaging>jar</packaging>
-       <!-- <build> <plugins> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> 
-               <configuration> <instructions> <Bundle-SymbolicName>${project.artifactId};singleton:=true</Bundle-SymbolicName> 
-               </instructions> </configuration> </plugin> </plugins> </build> -->
        <dependencies>
-               <!-- We build against RAP -->
-               <!-- <dependency> <groupId>org.argeo.commons</groupId> <artifactId>org.argeo.eclipse.dep.rap</artifactId> 
-                       <type>pom</type> <version>2.1.12-SNAPSHOT</version> <scope>provided</scope> 
-                       </dependency> -->
-               <!-- Commons -->
                <dependency>
                        <groupId>org.argeo.commons</groupId>
                        <artifactId>org.argeo.util</artifactId>
                        <artifactId>org.argeo.security.core</artifactId>
                        <version>2.1.14-SNAPSHOT</version>
                </dependency>
-
-               <!-- Bridge Spring and OSGi -->
-               <!-- <dependency> -->
-               <!-- <groupId>org.argeo.tp</groupId> -->
-               <!-- <artifactId>org.springframework.osgi.extender</artifactId> -->
-               <!-- </dependency> -->
-
-               <!-- Spring -->
-               <!-- <dependency> -->
-               <!-- <groupId>org.argeo.tp</groupId> -->
-               <!-- <artifactId>org.springframework.context</artifactId> -->
-               <!-- </dependency> -->
-
-
-               <!-- Others -->
-               <!-- <dependency> -->
-               <!-- <groupId>org.argeo.tp</groupId> -->
-               <!-- <artifactId>slf4j.org.apache.commons.logging</artifactId> -->
-               <!-- </dependency> -->
        </dependencies>
 </project>
\ No newline at end of file
index ef3d1aa2e6db9d908de5b3ed5f8c55542b390d84..fa20c3d9e1534e11053fcd2efc14ffe99ec31e27 100644 (file)
@@ -3,4 +3,6 @@ Import-Package:org.bouncycastle.*;resolution:=optional,\
 org.springframework.util,\
 javax.jcr.security,\
 org.apache.jackrabbit.*;resolution:=optional,\
+org.springframework.ldap.*;resolution:=optional,\
+org.springframework.security.ldap.*;resolution:=optional,\
 *
index b677bb860d9d11f28d92896a86e829b7df097ef5..426fc9ff1b3cad9ed97031b9bec19043a3f3308e 100644 (file)
@@ -8,7 +8,7 @@
                <relativePath>..</relativePath>
        </parent>
        <artifactId>org.argeo.security.core</artifactId>
-       <name>Commons Security Core</name>
+       <name>Commons Security</name>
        <dependencies>
                <dependency>
                        <groupId>org.argeo.commons</groupId>
                        <artifactId>org.argeo.server.jcr</artifactId>
                        <version>2.1.14-SNAPSHOT</version>
                </dependency>
-               <dependency>
-                       <groupId>org.argeo.commons</groupId>
-                       <artifactId>org.argeo.server.jackrabbit</artifactId>
-                       <version>2.1.14-SNAPSHOT</version>
-               </dependency>
-
-               <!-- SDK -->
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.tp</groupId> -->
-<!--                   <artifactId>argeo-tp</artifactId> -->
-<!--                   <version>${version.argeo-distribution}</version> -->
-<!--                   <scope>provided</scope> -->
-<!--           </dependency> -->
-
-               <!-- Crypto -->
-               <!-- <dependency> -->
-               <!-- <groupId>org.argeo.tp</groupId> -->
-               <!-- <artifactId>bcprov</artifactId> -->
-               <!-- <optional>true</optional> -->
-               <!-- </dependency> -->
-               <!-- <dependency> -->
-               <!-- <groupId>org.argeo.tp</groupId> -->
-               <!-- <artifactId>org.apache.commons.codec</artifactId> -->
-               <!-- </dependency> -->
-
-               <!-- Spring -->
-               <!-- <dependency> -->
-               <!-- <groupId>org.argeo.tp</groupId> -->
-               <!-- <artifactId>org.springframework.core</artifactId> -->
-               <!-- </dependency> -->
-               <!-- <dependency> -->
-               <!-- <groupId>org.argeo.tp</groupId> -->
-               <!-- <artifactId>org.springframework.beans</artifactId> -->
-               <!-- </dependency> -->
-               <!-- <dependency> -->
-               <!-- <groupId>org.argeo.tp</groupId> -->
-               <!-- <artifactId>org.springframework.context</artifactId> -->
-               <!-- </dependency> -->
-               <!-- <dependency> -->
-               <!-- <groupId>org.argeo.tp</groupId> -->
-               <!-- <artifactId>org.springframework.security.core</artifactId> -->
-               <!-- </dependency> -->
-               <!-- <dependency> -->
-               <!-- <groupId>org.argeo.tp</groupId> -->
-               <!-- <artifactId>org.springframework.transaction</artifactId> -->
-               <!-- </dependency> -->
-
-               <!-- OSGi -->
-               <!-- <dependency> -->
-               <!-- <groupId>org.argeo.tp</groupId> -->
-               <!-- <artifactId>org.eclipse.osgi</artifactId> -->
-               <!-- <scope>provided</scope> -->
-               <!-- </dependency> -->
-
-               <!-- Logging -->
-               <!-- <dependency> -->
-               <!-- <groupId>org.argeo.tp</groupId> -->
-               <!-- <artifactId>slf4j.org.apache.commons.logging</artifactId> -->
-               <!-- </dependency> -->
-
-               <!-- <dependency> -->
-               <!-- <groupId>org.argeo.tp</groupId> -->
-               <!-- <artifactId>org.apache.log4j</artifactId> -->
-               <!-- <optional>true</optional> -->
-               <!-- </dependency> -->
-
-               <!-- TEST -->
-               <!-- <dependency> -->
-               <!-- <groupId>org.argeo.tp</groupId> -->
-               <!-- <artifactId>junit</artifactId> -->
-               <!-- <scope>test</scope> -->
-               <!-- </dependency> -->
-               <!-- <dependency> -->
-               <!-- <groupId>org.argeo.commons</groupId> -->
-               <!-- <artifactId>org.argeo.dep.log4j</artifactId> -->
-               <!-- <version>2.1.12-SNAPSHOT</version> -->
-               <!-- <type>pom</type> -->
-               <!-- <scope>test</scope> -->
-               <!-- </dependency> -->
-               <!-- <dependency> -->
-               <!-- <groupId>org.argeo.commons</groupId> -->
-               <!-- <artifactId>org.argeo.server.json</artifactId> -->
-               <!-- <version>2.1.12-SNAPSHOT</version> -->
-               <!-- <scope>test</scope> -->
-               <!-- </dependency> -->
-               <!-- <dependency> -->
-               <!-- <groupId>org.argeo.tp</groupId> -->
-               <!-- <artifactId>com.springsource.json</artifactId> -->
-               <!-- <scope>test</scope> -->
-               <!-- </dependency> -->
-
        </dependencies>
 </project>
\ No newline at end of file
diff --git a/org.argeo.security.core/src/org/argeo/security/core/AuthorizationPrincipal.java b/org.argeo.security.core/src/org/argeo/security/core/AuthorizationPrincipal.java
new file mode 100644 (file)
index 0000000..ac3b233
--- /dev/null
@@ -0,0 +1,24 @@
+package org.argeo.security.core;
+
+import java.security.Principal;
+
+import org.osgi.service.useradmin.Authorization;
+
+/** Wraps an OSGi {@link Authorization} as a JAAS {@link Principal} */
+public final class AuthorizationPrincipal implements Principal {
+       private Authorization authorization;
+
+       public AuthorizationPrincipal(Authorization authorization) {
+               this.authorization = authorization;
+       }
+
+       @Override
+       public String getName() {
+               return authorization.getName();
+       }
+
+       public Authorization getAuthorization() {
+               return authorization;
+       }
+
+}
diff --git a/org.argeo.security.core/src/org/argeo/security/core/UserAdminLoginModule.java b/org.argeo.security.core/src/org/argeo/security/core/UserAdminLoginModule.java
new file mode 100644 (file)
index 0000000..16bc623
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * 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.
+ */
+package org.argeo.security.core;
+
+import java.util.Locale;
+import java.util.Map;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+
+import org.argeo.jcr.ArgeoNames;
+import org.argeo.util.LocaleCallback;
+import org.argeo.util.LocaleUtils;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.useradmin.Authorization;
+import org.osgi.service.useradmin.User;
+import org.osgi.service.useradmin.UserAdmin;
+import org.springframework.security.authentication.encoding.LdapShaPasswordEncoder;
+
+/** Login module which caches one subject per thread. */
+public class UserAdminLoginModule implements LoginModule {
+       // private final static Log log = LogFactory
+       // .getLog(UserAdminLoginModule.class);
+
+       private CallbackHandler callbackHandler;
+
+       private Subject subject;
+
+       private Long waitBetweenFailedLoginAttempts = 5 * 1000l;
+
+       /** Comma separated list of locales */
+       private String availableLocales = "";
+
+       private AuthorizationPrincipal auth = null;
+       private Locale selectedLocale = null;
+
+       private LdapShaPasswordEncoder shaPasswordEncoder = new LdapShaPasswordEncoder();
+
+       public UserAdminLoginModule() {
+
+       }
+
+       @SuppressWarnings("rawtypes")
+       public void initialize(Subject subject, CallbackHandler callbackHandler,
+                       Map sharedState, Map options) {
+               this.callbackHandler = callbackHandler;
+               this.subject = subject;
+       }
+
+       public boolean login() throws LoginException {
+               try {
+                       // TODO thread already logged in
+                       // AuthorizationPrincipal principal = subject
+                       // .getPrincipals(AuthorizationPrincipal.class).iterator();
+
+                       if (callbackHandler == null)
+                               throw new LoginException("No call back handler available");
+
+                       // ask for username and password
+                       NameCallback nameCallback = new NameCallback("User");
+                       PasswordCallback passwordCallback = new PasswordCallback(
+                                       "Password", false);
+                       LocaleCallback localeCallback = new LocaleCallback(availableLocales);
+                       BundleContextCallback bundleContextCallback = new BundleContextCallback();
+
+                       callbackHandler.handle(new Callback[] { nameCallback,
+                                       passwordCallback, localeCallback, bundleContextCallback });
+
+                       selectedLocale = localeCallback.getSelectedLocale();
+
+                       // create credentials
+                       final String username = nameCallback.getName();
+                       if (username == null || username.trim().equals(""))
+                               return false;
+
+                       char[] password = {};
+                       if (passwordCallback.getPassword() != null)
+                               password = passwordCallback.getPassword();
+
+                       BundleContext bc = bundleContextCallback.getBundleContext();
+                       UserAdmin userAdmin = bc.getService(bc
+                                       .getServiceReference(UserAdmin.class));
+
+                       User user = (User) userAdmin.getRole(username);
+                       // TODO use hash
+                       boolean authenticated = user.hasCredential(
+                                       ArgeoNames.ARGEO_PASSWORD, new String(password));
+
+                       if (!authenticated) {
+                               // wait between failed login attempts
+                               Thread.sleep(waitBetweenFailedLoginAttempts);
+                               return false;
+                       }
+
+                       Authorization authorization = userAdmin.getAuthorization(user);
+                       auth = new AuthorizationPrincipal(authorization);
+                       return true;
+               } catch (LoginException e) {
+                       throw e;
+               } catch (ThreadDeath e) {
+                       LoginException le = new LoginException(
+                                       "Spring Security login thread died");
+                       le.initCause(e);
+                       throw le;
+               } catch (Exception e) {
+                       LoginException le = new LoginException(
+                                       "Spring Security login failed");
+                       le.initCause(e);
+                       throw le;
+               }
+       }
+
+       @Override
+       public boolean logout() throws LoginException {
+               subject.getPrincipals(AuthorizationPrincipal.class).remove(auth);
+               return true;
+       }
+
+       @Override
+       public boolean commit() throws LoginException {
+               subject.getPrincipals().add(auth);
+               if (selectedLocale != null)
+                       LocaleUtils.threadLocale.set(selectedLocale);
+               return true;
+       }
+
+       @Override
+       public boolean abort() throws LoginException {
+               auth = null;
+               selectedLocale = null;
+               return true;
+       }
+
+       public void setAvailableLocales(String locales) {
+               this.availableLocales = locales;
+       }
+}
\ No newline at end of file
diff --git a/org.argeo.security.core/src/org/argeo/security/ldap/ArgeoLdapShaPasswordEncoder.java b/org.argeo.security.core/src/org/argeo/security/ldap/ArgeoLdapShaPasswordEncoder.java
new file mode 100644 (file)
index 0000000..a2c43a5
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+package org.argeo.security.ldap;
+
+import org.springframework.security.authentication.encoding.LdapShaPasswordEncoder;
+
+/**
+ * {@link LdapShaPasswordEncoder} allowing to configure the usage of salt (APache
+ * Directory Server 1.0 does not support bind with SSHA)
+ */
+public class ArgeoLdapShaPasswordEncoder extends LdapShaPasswordEncoder {
+       private Boolean useSalt = true;
+
+       @Override
+       public String encodePassword(String rawPass, Object salt) {
+               return super.encodePassword(rawPass, useSalt ? salt : null);
+       }
+
+       public void setUseSalt(Boolean useSalt) {
+               this.useSalt = useSalt;
+       }
+
+}
diff --git a/org.argeo.security.core/src/org/argeo/security/ldap/ArgeoLdapUserDetailsManager.java b/org.argeo.security.core/src/org/argeo/security/ldap/ArgeoLdapUserDetailsManager.java
new file mode 100644 (file)
index 0000000..89b5aa9
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * 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.
+ */
+package org.argeo.security.ldap;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.argeo.ArgeoException;
+import org.argeo.security.UserAdminService;
+import org.springframework.ldap.core.ContextSource;
+import org.springframework.security.authentication.encoding.PasswordEncoder;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.ldap.userdetails.LdapUserDetailsManager;
+
+/** Extends {@link LdapUserDetailsManager} by adding password encoding support. */
+public class ArgeoLdapUserDetailsManager extends LdapUserDetailsManager
+               implements UserAdminService {
+       private String superUsername = "root";
+       private ArgeoUserAdminDaoLdap userAdminDao;
+       private PasswordEncoder passwordEncoder;
+       private final Random random;
+
+       public ArgeoLdapUserDetailsManager(ContextSource contextSource) {
+               super(contextSource);
+               this.random = createRandom();
+       }
+
+       private static Random createRandom() {
+               try {
+                       return SecureRandom.getInstance("SHA1PRNG");
+               } catch (NoSuchAlgorithmException e) {
+                       return new Random(System.currentTimeMillis());
+               }
+       }
+
+       @Override
+       public void changePassword(String oldPassword, String newPassword) {
+               Authentication authentication = SecurityContextHolder.getContext()
+                               .getAuthentication();
+               if (authentication == null)
+                       throw new ArgeoException(
+                                       "Cannot change password without authentication");
+               String username = authentication.getName();
+               UserDetails userDetails = loadUserByUsername(username);
+               String currentPassword = userDetails.getPassword();
+               if (currentPassword == null)
+                       throw new ArgeoException("Cannot access current password");
+               if (!passwordEncoder
+                               .isPasswordValid(currentPassword, oldPassword, null))
+                       throw new ArgeoException("Old password invalid");
+               // Spring Security LDAP 2.0 is buggy when used with OpenLDAP and called
+               // with oldPassword argument
+               super.changePassword(null, encodePassword(newPassword));
+       }
+
+       public void newRole(String role) {
+               userAdminDao.createRole(role, superUsername);
+       }
+
+       public void synchronize() {
+               for (String username : userAdminDao.listUsers())
+                       loadUserByUsername(username);
+               // TODO: find a way to remove from JCR
+       }
+
+       public void deleteRole(String role) {
+               userAdminDao.deleteRole(role);
+       }
+
+       public Set<String> listUsers() {
+               return userAdminDao.listUsers();
+       }
+
+       public Set<String> listUsersInRole(String role) {
+               Set<String> lst = new TreeSet<String>(
+                               userAdminDao.listUsersInRole(role));
+               Iterator<String> it = lst.iterator();
+               while (it.hasNext()) {
+                       if (it.next().equals(superUsername)) {
+                               it.remove();
+                               break;
+                       }
+               }
+               return lst;
+       }
+
+       public List<String> listUserRoles(String username) {
+               UserDetails userDetails = loadUserByUsername(username);
+               List<String> roles = new ArrayList<String>();
+               for (GrantedAuthority ga : userDetails.getAuthorities()) {
+                       roles.add(ga.getAuthority());
+               }
+               return Collections.unmodifiableList(roles);
+       }
+
+       public Set<String> listEditableRoles() {
+               return userAdminDao.listEditableRoles();
+       }
+
+       protected String encodePassword(String password) {
+               if (!password.startsWith("{")) {
+                       byte[] salt = new byte[16];
+                       random.nextBytes(salt);
+                       return passwordEncoder.encodePassword(password, salt);
+               } else {
+                       return password;
+               }
+       }
+
+       public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
+               this.passwordEncoder = passwordEncoder;
+       }
+
+       public void setSuperUsername(String superUsername) {
+               this.superUsername = superUsername;
+       }
+
+       public void setUserAdminDao(ArgeoUserAdminDaoLdap userAdminDao) {
+               this.userAdminDao = userAdminDao;
+       }
+
+}
diff --git a/org.argeo.security.core/src/org/argeo/security/ldap/ArgeoUserAdminDaoLdap.java b/org.argeo.security.core/src/org/argeo/security/ldap/ArgeoUserAdminDaoLdap.java
new file mode 100644 (file)
index 0000000..37d2a06
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * 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.
+ */
+package org.argeo.security.ldap;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.naming.Name;
+import javax.naming.NamingException;
+import javax.naming.directory.DirContext;
+
+import org.springframework.ldap.core.ContextExecutor;
+import org.springframework.ldap.core.ContextMapper;
+import org.springframework.ldap.core.DirContextAdapter;
+import org.springframework.ldap.core.DistinguishedName;
+import org.springframework.ldap.core.LdapTemplate;
+import org.springframework.ldap.core.support.BaseLdapPathContextSource;
+import org.springframework.security.ldap.LdapUsernameToDnMapper;
+import org.springframework.security.ldap.LdapUtils;
+
+/**
+ * Wraps low-level LDAP operation on user and roles, used by
+ * {@link ArgeoLdapUserDetailsManager}
+ */
+public class ArgeoUserAdminDaoLdap {
+       private String userBase;
+       private String usernameAttribute;
+       private String groupBase;
+       private String[] groupClasses;
+
+       private String groupRoleAttribute;
+       private String groupMemberAttribute;
+       private String defaultRole;
+       private String rolePrefix;
+
+       private final LdapTemplate ldapTemplate;
+       private LdapUsernameToDnMapper usernameMapper;
+
+       /**
+        * Standard constructor, using the LDAP context source shared with Spring
+        * Security components.
+        */
+       public ArgeoUserAdminDaoLdap(BaseLdapPathContextSource contextSource) {
+               this.ldapTemplate = new LdapTemplate(contextSource);
+       }
+
+       @SuppressWarnings("unchecked")
+       public synchronized Set<String> listUsers() {
+               List<String> usernames = (List<String>) ldapTemplate.listBindings(
+                               new DistinguishedName(userBase), new ContextMapper() {
+                                       public Object mapFromContext(Object ctxArg) {
+                                               DirContextAdapter ctx = (DirContextAdapter) ctxArg;
+                                               return ctx.getStringAttribute(usernameAttribute);
+                                       }
+                               });
+
+               return Collections
+                               .unmodifiableSortedSet(new TreeSet<String>(usernames));
+       }
+
+       @SuppressWarnings("unchecked")
+       public Set<String> listEditableRoles() {
+               return Collections.unmodifiableSortedSet(new TreeSet<String>(
+                               ldapTemplate.listBindings(groupBase, new ContextMapper() {
+                                       public Object mapFromContext(Object ctxArg) {
+                                               String groupName = ((DirContextAdapter) ctxArg)
+                                                               .getStringAttribute(groupRoleAttribute);
+                                               String roleName = convertGroupToRole(groupName);
+                                               return roleName;
+                                       }
+                               })));
+       }
+
+       @SuppressWarnings("unchecked")
+       public Set<String> listUsersInRole(String role) {
+               return (Set<String>) ldapTemplate.lookup(
+                               buildGroupDn(convertRoleToGroup(role)), new ContextMapper() {
+                                       public Object mapFromContext(Object ctxArg) {
+                                               DirContextAdapter ctx = (DirContextAdapter) ctxArg;
+                                               String[] userDns = ctx
+                                                               .getStringAttributes(groupMemberAttribute);
+                                               TreeSet<String> set = new TreeSet<String>();
+                                               for (String userDn : userDns) {
+                                                       DistinguishedName dn = new DistinguishedName(userDn);
+                                                       String username = dn.getValue(usernameAttribute);
+                                                       set.add(username);
+                                               }
+                                               return Collections.unmodifiableSortedSet(set);
+                                       }
+                               });
+       }
+
+       public void createRole(String role, final String superuserName) {
+               String group = convertRoleToGroup(role);
+               DistinguishedName superuserDn = (DistinguishedName) ldapTemplate
+                               .executeReadWrite(new ContextExecutor() {
+                                       public Object executeWithContext(DirContext ctx)
+                                                       throws NamingException {
+                                               return LdapUtils.getFullDn(
+                                                               usernameMapper.buildDn(superuserName), ctx);
+                                       }
+                               });
+
+               Name groupDn = buildGroupDn(group);
+               DirContextAdapter context = new DirContextAdapter();
+               context.setAttributeValues("objectClass", groupClasses);
+               context.setAttributeValue("cn", group);
+               // Add superuser because cannot create empty group
+               context.setAttributeValue(groupMemberAttribute, superuserDn.toString());
+               ldapTemplate.bind(groupDn, context, null);
+       }
+
+       public void deleteRole(String role) {
+               String group = convertRoleToGroup(role);
+               Name dn = buildGroupDn(group);
+               ldapTemplate.unbind(dn);
+       }
+
+       /** Maps a role (ROLE_XXX) to the related LDAP group (xxx) */
+       protected String convertRoleToGroup(String role) {
+               String group = role;
+               if (group.startsWith(rolePrefix)) {
+                       group = group.substring(rolePrefix.length());
+                       group = group.toLowerCase();
+               }
+               return group;
+       }
+
+       /** Maps anLDAP group (xxx) to the related role (ROLE_XXX) */
+       protected String convertGroupToRole(String groupName) {
+               groupName = groupName.toUpperCase();
+
+               return rolePrefix + groupName;
+       }
+
+       protected Name buildGroupDn(String name) {
+               return new DistinguishedName(groupRoleAttribute + "=" + name + ","
+                               + groupBase);
+       }
+
+       public void setUserBase(String userBase) {
+               this.userBase = userBase;
+       }
+
+       public void setUsernameAttribute(String usernameAttribute) {
+               this.usernameAttribute = usernameAttribute;
+       }
+
+       public void setGroupBase(String groupBase) {
+               this.groupBase = groupBase;
+       }
+
+       public void setGroupRoleAttribute(String groupRoleAttributeName) {
+               this.groupRoleAttribute = groupRoleAttributeName;
+       }
+
+       public void setGroupMemberAttribute(String groupMemberAttributeName) {
+               this.groupMemberAttribute = groupMemberAttributeName;
+       }
+
+       public void setDefaultRole(String defaultRole) {
+               this.defaultRole = defaultRole;
+       }
+
+       public void setRolePrefix(String rolePrefix) {
+               this.rolePrefix = rolePrefix;
+       }
+
+       public void setUsernameMapper(LdapUsernameToDnMapper usernameMapper) {
+               this.usernameMapper = usernameMapper;
+       }
+
+       public String getDefaultRole() {
+               return defaultRole;
+       }
+
+       public void setGroupClasses(String[] groupClasses) {
+               this.groupClasses = groupClasses;
+       }
+}
diff --git a/org.argeo.security.core/src/org/argeo/security/ldap/jcr/JcrLdapSynchronizer.java b/org.argeo.security.core/src/org/argeo/security/ldap/jcr/JcrLdapSynchronizer.java
new file mode 100644 (file)
index 0000000..e0519c3
--- /dev/null
@@ -0,0 +1,622 @@
+/*
+ * 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.
+ */
+package org.argeo.security.ldap.jcr;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.SortedSet;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.query.Query;
+import javax.jcr.version.VersionManager;
+import javax.naming.Name;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.ModificationItem;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.ArgeoException;
+import org.argeo.jcr.ArgeoNames;
+import org.argeo.jcr.ArgeoTypes;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.security.SecurityUtils;
+import org.argeo.security.jcr.JcrSecurityModel;
+import org.argeo.security.jcr.JcrUserDetails;
+import org.argeo.security.jcr.SimpleJcrSecurityModel;
+import org.springframework.ldap.core.ContextMapper;
+import org.springframework.ldap.core.DirContextAdapter;
+import org.springframework.ldap.core.DirContextOperations;
+import org.springframework.ldap.core.DistinguishedName;
+import org.springframework.ldap.core.LdapTemplate;
+import org.springframework.security.authentication.encoding.PasswordEncoder;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.ldap.LdapUsernameToDnMapper;
+import org.springframework.security.ldap.userdetails.UserDetailsContextMapper;
+
+/** Makes sure that LDAP and JCR are in line. */
+public class JcrLdapSynchronizer implements UserDetailsContextMapper,
+               ArgeoNames {
+       private final static Log log = LogFactory.getLog(JcrLdapSynchronizer.class);
+
+       // LDAP
+       private LdapTemplate ldapTemplate;
+       /**
+        * LDAP template whose context source has an object factory set to null. see
+        * <a href=
+        * "http://forum.springsource.org/showthread.php?55955-Persistent-search-with-spring-ldap"
+        * >this</a>
+        */
+       // private LdapTemplate rawLdapTemplate;
+
+       private String userBase;
+       private String usernameAttribute;
+       private String passwordAttribute;
+       private String[] userClasses;
+       // private String defaultUserRole ="ROLE_USER";
+
+       // private NamingListener ldapUserListener;
+       // private SearchControls subTreeSearchControls;
+       private LdapUsernameToDnMapper usernameMapper;
+
+       private PasswordEncoder passwordEncoder;
+       private final Random random;
+
+       // JCR
+       /** Admin session on the main workspace */
+       private Session nodeSession;
+       private Repository repository;
+
+       // private JcrProfileListener jcrProfileListener;
+       private JcrSecurityModel jcrSecurityModel = new SimpleJcrSecurityModel();
+
+       // Mapping
+       private Map<String, String> propertyToAttributes = new HashMap<String, String>();
+
+       public JcrLdapSynchronizer() {
+               random = createRandom();
+       }
+
+       public void init() {
+               try {
+                       nodeSession = repository.login();
+
+                       // TODO put this in a different thread, and poll the LDAP server
+                       // until it is up
+                       try {
+                               synchronize();
+
+                               // LDAP
+                               // subTreeSearchControls = new SearchControls();
+                               // subTreeSearchControls
+                               // .setSearchScope(SearchControls.SUBTREE_SCOPE);
+                               // LDAP listener
+                               // ldapUserListener = new LdapUserListener();
+                               // rawLdapTemplate.executeReadOnly(new ContextExecutor() {
+                               // public Object executeWithContext(DirContext ctx)
+                               // throws NamingException {
+                               // EventDirContext ectx = (EventDirContext) ctx.lookup("");
+                               // ectx.addNamingListener(userBase, "("
+                               // + usernameAttribute + "=*)",
+                               // subTreeSearchControls, ldapUserListener);
+                               // return null;
+                               // }
+                               // });
+                       } catch (Exception e) {
+                               log.error("Could not synchronize and listen to LDAP,"
+                                               + " probably because the LDAP server is not available."
+                                               + " Restart the system as soon as possible.", e);
+                       }
+
+                       // JCR
+                       // String[] nodeTypes = { ArgeoTypes.ARGEO_USER_PROFILE };
+                       // jcrProfileListener = new JcrProfileListener();
+                       // noLocal is used so that we are not notified when we modify JCR
+                       // from LDAP
+                       // nodeSession
+                       // .getWorkspace()
+                       // .getObservationManager()
+                       // .addEventListener(jcrProfileListener,
+                       // Event.PROPERTY_CHANGED | Event.NODE_ADDED, "/",
+                       // true, null, nodeTypes, true);
+               } catch (Exception e) {
+                       JcrUtils.logoutQuietly(nodeSession);
+                       throw new ArgeoException("Cannot initialize LDAP/JCR synchronizer",
+                                       e);
+               }
+       }
+
+       public void destroy() {
+               // JcrUtils.removeListenerQuietly(nodeSession, jcrProfileListener);
+               JcrUtils.logoutQuietly(nodeSession);
+               // try {
+               // rawLdapTemplate.executeReadOnly(new ContextExecutor() {
+               // public Object executeWithContext(DirContext ctx)
+               // throws NamingException {
+               // EventDirContext ectx = (EventDirContext) ctx.lookup("");
+               // ectx.removeNamingListener(ldapUserListener);
+               // return null;
+               // }
+               // });
+               // } catch (Exception e) {
+               // // silent (LDAP server may have been shutdown already)
+               // if (log.isTraceEnabled())
+               // log.trace("Cannot remove LDAP listener", e);
+               // }
+       }
+
+       /*
+        * LDAP TO JCR
+        */
+       /** Full synchronization between LDAP and JCR. LDAP has priority. */
+       protected void synchronize() {
+               try {
+                       Name userBaseName = new DistinguishedName(userBase);
+                       // TODO subtree search?
+                       @SuppressWarnings("unchecked")
+                       List<String> userPaths = (List<String>) ldapTemplate.listBindings(
+                                       userBaseName, new ContextMapper() {
+                                               public Object mapFromContext(Object ctxObj) {
+                                                       try {
+                                                               return mapLdapToJcr((DirContextAdapter) ctxObj);
+                                                       } catch (Exception e) {
+                                                               // do not break process because of error
+                                                               log.error(
+                                                                               "Could not LDAP->JCR synchronize user "
+                                                                                               + ctxObj, e);
+                                                               return null;
+                                                       }
+                                               }
+                                       });
+
+                       // create accounts which are not in LDAP
+                       Query query = nodeSession
+                                       .getWorkspace()
+                                       .getQueryManager()
+                                       .createQuery(
+                                                       "select * from [" + ArgeoTypes.ARGEO_USER_PROFILE
+                                                                       + "]", Query.JCR_SQL2);
+                       NodeIterator it = query.execute().getNodes();
+                       while (it.hasNext()) {
+                               Node userProfile = it.nextNode();
+                               String path = userProfile.getPath();
+                               try {
+                                       if (!userPaths.contains(path)) {
+                                               String username = userProfile
+                                                               .getProperty(ARGEO_USER_ID).getString();
+                                               // GrantedAuthority[] authorities = {new
+                                               // GrantedAuthorityImpl(defaultUserRole)};
+                                               List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
+                                               JcrUserDetails userDetails = new JcrUserDetails(
+                                                               userProfile, username, authorities);
+                                               String dn = createLdapUser(userDetails);
+                                               log.warn("Created ldap entry '" + dn + "' for user '"
+                                                               + username + "'");
+
+                                               // if(!userProfile.getProperty(ARGEO_ENABLED).getBoolean()){
+                                               // continue profiles;
+                                               // }
+                                               //
+                                               // log.warn("Path "
+                                               // + path
+                                               // + " not found in LDAP, disabling user "
+                                               // + userProfile.getProperty(ArgeoNames.ARGEO_USER_ID)
+                                               // .getString());
+
+                                               // Temporary hack to repair previous behaviour
+                                               if (!userProfile.getProperty(ARGEO_ENABLED)
+                                                               .getBoolean()) {
+                                                       VersionManager versionManager = nodeSession
+                                                                       .getWorkspace().getVersionManager();
+                                                       versionManager.checkout(userProfile.getPath());
+                                                       userProfile.setProperty(ArgeoNames.ARGEO_ENABLED,
+                                                                       true);
+                                                       nodeSession.save();
+                                                       versionManager.checkin(userProfile.getPath());
+                                               }
+                                       }
+                               } catch (Exception e) {
+                                       log.error("Cannot process " + path, e);
+                               }
+                       }
+               } catch (Exception e) {
+                       JcrUtils.discardQuietly(nodeSession);
+                       log.error("Cannot synchronize LDAP and JCR", e);
+                       // throw new ArgeoException("Cannot synchronize LDAP and JCR", e);
+               }
+       }
+
+       private String createLdapUser(UserDetails user) {
+               DirContextAdapter ctx = new DirContextAdapter();
+               mapUserToContext(user, ctx);
+               DistinguishedName dn = usernameMapper.buildDn(user.getUsername());
+               ldapTemplate.bind(dn, ctx, null);
+               return dn.toString();
+       }
+
+       /** Called during authentication in order to retrieve user details */
+       public UserDetails mapUserFromContext(final DirContextOperations ctx,
+                       final String username,
+                       Collection<? extends GrantedAuthority> authorities) {
+               if (ctx == null)
+                       throw new ArgeoException("No LDAP information for user " + username);
+
+               String ldapUsername = ctx.getStringAttribute(usernameAttribute);
+               if (!ldapUsername.equals(username))
+                       throw new ArgeoException("Logged in with username " + username
+                                       + " but LDAP user is " + ldapUsername);
+
+               Node userProfile = jcrSecurityModel.sync(nodeSession, username,
+                               SecurityUtils.authoritiesToStringList(authorities));
+               // JcrUserDetails.checkAccountStatus(userProfile);
+
+               // password
+               SortedSet<?> passwordAttributes = ctx
+                               .getAttributeSortedStringSet(passwordAttribute);
+               String password;
+               if (passwordAttributes == null || passwordAttributes.size() == 0) {
+                       // throw new ArgeoException("No password found for user " +
+                       // username);
+                       password = "NULL";
+               } else {
+                       byte[] arr = (byte[]) passwordAttributes.first();
+                       password = new String(arr);
+                       // erase password
+                       Arrays.fill(arr, (byte) 0);
+               }
+
+               try {
+                       return new JcrUserDetails(userProfile, password, authorities);
+               } catch (RepositoryException e) {
+                       throw new ArgeoException("Cannot retrieve user details for "
+                                       + username, e);
+               }
+       }
+
+       /**
+        * Writes an LDAP context to the JCR user profile.
+        * 
+        * @return path to user profile
+        */
+       protected synchronized String mapLdapToJcr(DirContextAdapter ctx) {
+               Session session = nodeSession;
+               try {
+                       // process
+                       String username = ctx.getStringAttribute(usernameAttribute);
+
+                       Node userProfile = jcrSecurityModel.sync(session, username, null);
+                       Map<String, String> modifications = new HashMap<String, String>();
+                       for (String jcrProperty : propertyToAttributes.keySet())
+                               ldapToJcr(userProfile, jcrProperty, ctx, modifications);
+
+                       int modifCount = modifications.size();
+                       if (modifCount > 0) {
+                               session.getWorkspace().getVersionManager()
+                                               .checkout(userProfile.getPath());
+                               for (String prop : modifications.keySet())
+                                       userProfile.setProperty(prop, modifications.get(prop));
+                               JcrUtils.updateLastModified(userProfile);
+                               session.save();
+                               session.getWorkspace().getVersionManager()
+                                               .checkin(userProfile.getPath());
+                               if (log.isDebugEnabled())
+                                       log.debug("Mapped " + modifCount + " LDAP modification"
+                                                       + (modifCount == 1 ? "" : "s") + " from "
+                                                       + ctx.getDn() + " to " + userProfile);
+                       }
+                       return userProfile.getPath();
+               } catch (Exception e) {
+                       JcrUtils.discardQuietly(session);
+                       throw new ArgeoException("Cannot synchronize JCR and LDAP", e);
+               }
+       }
+
+       /** Maps an LDAP property to a JCR property */
+       protected void ldapToJcr(Node userProfile, String jcrProperty,
+                       DirContextOperations ctx, Map<String, String> modifications) {
+               // TODO do we really need DirContextOperations?
+               try {
+                       String ldapAttribute;
+                       if (propertyToAttributes.containsKey(jcrProperty))
+                               ldapAttribute = propertyToAttributes.get(jcrProperty);
+                       else
+                               throw new ArgeoException(
+                                               "No LDAP attribute mapped for JCR proprty "
+                                                               + jcrProperty);
+
+                       String value = ctx.getStringAttribute(ldapAttribute);
+                       String jcrValue = userProfile.hasProperty(jcrProperty) ? userProfile
+                                       .getProperty(jcrProperty).getString() : null;
+                       if (value != null && jcrValue != null) {
+                               if (!value.equals(jcrValue))
+                                       modifications.put(jcrProperty, value);
+                       } else if (value != null && jcrValue == null) {
+                               modifications.put(jcrProperty, value);
+                       } else if (value == null && jcrValue != null) {
+                               modifications.put(jcrProperty, value);
+                       }
+               } catch (Exception e) {
+                       throw new ArgeoException("Cannot map JCR property " + jcrProperty
+                                       + " from LDAP", e);
+               }
+       }
+
+       /*
+        * JCR to LDAP
+        */
+
+       public void mapUserToContext(UserDetails user, final DirContextAdapter ctx) {
+               if (!(user instanceof JcrUserDetails))
+                       throw new ArgeoException("Unsupported user details: "
+                                       + user.getClass());
+
+               ctx.setAttributeValues("objectClass", userClasses);
+               ctx.setAttributeValue(usernameAttribute, user.getUsername());
+               ctx.setAttributeValue(passwordAttribute,
+                               encodePassword(user.getPassword()));
+
+               final JcrUserDetails jcrUserDetails = (JcrUserDetails) user;
+               try {
+                       Node userProfile = nodeSession
+                                       .getNode(jcrUserDetails.getHomePath()).getNode(
+                                                       ARGEO_PROFILE);
+                       for (String jcrProperty : propertyToAttributes.keySet()) {
+                               if (userProfile.hasProperty(jcrProperty)) {
+                                       ModificationItem mi = jcrToLdap(jcrProperty, userProfile
+                                                       .getProperty(jcrProperty).getString());
+                                       if (mi != null)
+                                               ctx.setAttribute(mi.getAttribute());
+                               }
+                       }
+                       if (log.isTraceEnabled())
+                               log.trace("Mapped " + userProfile + " to " + ctx.getDn());
+               } catch (RepositoryException e) {
+                       throw new ArgeoException("Cannot synchronize JCR and LDAP", e);
+               }
+
+       }
+
+       /** Maps a JCR property to an LDAP property */
+       protected ModificationItem jcrToLdap(String jcrProperty, String value) {
+               // TODO do we really need DirContextOperations?
+               try {
+                       String ldapAttribute;
+                       if (propertyToAttributes.containsKey(jcrProperty))
+                               ldapAttribute = propertyToAttributes.get(jcrProperty);
+                       else
+                               return null;
+
+                       // fix issue with empty 'sn' in LDAP
+                       if (ldapAttribute.equals("sn") && (value.trim().equals("")))
+                               return null;
+                       // fix issue with empty 'description' in LDAP
+                       if (ldapAttribute.equals("description") && value.trim().equals(""))
+                               return null;
+                       BasicAttribute attr = new BasicAttribute(
+                                       propertyToAttributes.get(jcrProperty), value);
+                       ModificationItem mi = new ModificationItem(
+                                       DirContext.REPLACE_ATTRIBUTE, attr);
+                       return mi;
+               } catch (Exception e) {
+                       throw new ArgeoException("Cannot map JCR property " + jcrProperty
+                                       + " from LDAP", e);
+               }
+       }
+
+       /*
+        * UTILITIES
+        */
+       protected String encodePassword(String password) {
+               if (!password.startsWith("{")) {
+                       byte[] salt = new byte[16];
+                       random.nextBytes(salt);
+                       return passwordEncoder.encodePassword(password, salt);
+               } else {
+                       return password;
+               }
+       }
+
+       private static Random createRandom() {
+               try {
+                       return SecureRandom.getInstance("SHA1PRNG");
+               } catch (NoSuchAlgorithmException e) {
+                       return new Random(System.currentTimeMillis());
+               }
+       }
+
+       /*
+        * DEPENDENCY INJECTION
+        */
+
+       public void setLdapTemplate(LdapTemplate ldapTemplate) {
+               this.ldapTemplate = ldapTemplate;
+       }
+
+       public void setRawLdapTemplate(LdapTemplate rawLdapTemplate) {
+               // this.rawLdapTemplate = rawLdapTemplate;
+       }
+
+       public void setRepository(Repository repository) {
+               this.repository = repository;
+       }
+
+       public void setUserBase(String userBase) {
+               this.userBase = userBase;
+       }
+
+       public void setUsernameAttribute(String usernameAttribute) {
+               this.usernameAttribute = usernameAttribute;
+       }
+
+       public void setPropertyToAttributes(Map<String, String> propertyToAttributes) {
+               this.propertyToAttributes = propertyToAttributes;
+       }
+
+       public void setUsernameMapper(LdapUsernameToDnMapper usernameMapper) {
+               this.usernameMapper = usernameMapper;
+       }
+
+       public void setPasswordAttribute(String passwordAttribute) {
+               this.passwordAttribute = passwordAttribute;
+       }
+
+       public void setUserClasses(String[] userClasses) {
+               this.userClasses = userClasses;
+       }
+
+       public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
+               this.passwordEncoder = passwordEncoder;
+       }
+
+       public void setJcrSecurityModel(JcrSecurityModel jcrSecurityModel) {
+               this.jcrSecurityModel = jcrSecurityModel;
+       }
+
+       /** Listen to LDAP */
+       // class LdapUserListener implements ObjectChangeListener,
+       // NamespaceChangeListener, UnsolicitedNotificationListener {
+       //
+       // public void namingExceptionThrown(NamingExceptionEvent evt) {
+       // evt.getException().printStackTrace();
+       // }
+       //
+       // public void objectChanged(NamingEvent evt) {
+       // Binding user = evt.getNewBinding();
+       // // TODO find a way not to be called when JCR is the source of the
+       // // modification
+       // DirContextAdapter ctx = (DirContextAdapter) ldapTemplate
+       // .lookup(user.getName());
+       // mapLdapToJcr(ctx);
+       // }
+       //
+       // public void objectAdded(NamingEvent evt) {
+       // Binding user = evt.getNewBinding();
+       // DirContextAdapter ctx = (DirContextAdapter) ldapTemplate
+       // .lookup(user.getName());
+       // mapLdapToJcr(ctx);
+       // }
+       //
+       // public void objectRemoved(NamingEvent evt) {
+       // if (log.isDebugEnabled())
+       // log.debug(evt);
+       // }
+       //
+       // public void objectRenamed(NamingEvent evt) {
+       // if (log.isDebugEnabled())
+       // log.debug(evt);
+       // }
+       //
+       // public void notificationReceived(UnsolicitedNotificationEvent evt) {
+       // UnsolicitedNotification notification = evt.getNotification();
+       // NamingException ne = notification.getException();
+       // String msg = "LDAP notification " + "ID=" + notification.getID()
+       // + ", referrals=" + notification.getReferrals();
+       // if (ne != null) {
+       // if (log.isTraceEnabled())
+       // log.trace(msg + ", exception= " + ne, ne);
+       // else
+       // log.warn(msg + ", exception= " + ne);
+       // } else if (log.isDebugEnabled()) {
+       // log.debug("Unsollicited LDAP notification " + msg);
+       // }
+       // }
+       //
+       // }
+
+       /** Listen to JCR */
+       // class JcrProfileListener implements EventListener {
+       //
+       // public void onEvent(EventIterator events) {
+       // try {
+       // final Map<Name, List<ModificationItem>> modifications = new HashMap<Name,
+       // List<ModificationItem>>();
+       // while (events.hasNext()) {
+       // Event event = events.nextEvent();
+       // try {
+       // if (Event.PROPERTY_CHANGED == event.getType()) {
+       // Property property = (Property) nodeSession
+       // .getItem(event.getPath());
+       // String propertyName = property.getName();
+       // Node userProfile = property.getParent();
+       // String username = userProfile.getProperty(
+       // ARGEO_USER_ID).getString();
+       // if (propertyToAttributes.containsKey(propertyName)) {
+       // Name name = usernameMapper.buildDn(username);
+       // if (!modifications.containsKey(name))
+       // modifications.put(name,
+       // new ArrayList<ModificationItem>());
+       // String value = property.getString();
+       // ModificationItem mi = jcrToLdap(propertyName,
+       // value);
+       // if (mi != null)
+       // modifications.get(name).add(mi);
+       // }
+       // } else if (Event.NODE_ADDED == event.getType()) {
+       // Node userProfile = nodeSession.getNode(event
+       // .getPath());
+       // String username = userProfile.getProperty(
+       // ARGEO_USER_ID).getString();
+       // Name name = usernameMapper.buildDn(username);
+       // for (String propertyName : propertyToAttributes
+       // .keySet()) {
+       // if (!modifications.containsKey(name))
+       // modifications.put(name,
+       // new ArrayList<ModificationItem>());
+       // String value = userProfile.getProperty(
+       // propertyName).getString();
+       // ModificationItem mi = jcrToLdap(propertyName,
+       // value);
+       // if (mi != null)
+       // modifications.get(name).add(mi);
+       // }
+       // }
+       // } catch (RepositoryException e) {
+       // throw new ArgeoException("Cannot process event "
+       // + event, e);
+       // }
+       // }
+       //
+       // for (Name name : modifications.keySet()) {
+       // List<ModificationItem> userModifs = modifications.get(name);
+       // int modifCount = userModifs.size();
+       // ldapTemplate.modifyAttributes(name, userModifs
+       // .toArray(new ModificationItem[modifCount]));
+       // if (log.isDebugEnabled())
+       // log.debug("Mapped " + modifCount + " JCR modification"
+       // + (modifCount == 1 ? "" : "s") + " to " + name);
+       // }
+       // } catch (Exception e) {
+       // // if (log.isDebugEnabled())
+       // // e.printStackTrace();
+       // throw new ArgeoException("Cannot process JCR events ("
+       // + e.getMessage() + ")", e);
+       // }
+       // }
+       //
+       // }
+}
diff --git a/org.argeo.security.core/src/org/argeo/security/ldap/jcr/JcrUserDetailsContextMapper.java b/org.argeo.security.core/src/org/argeo/security/ldap/jcr/JcrUserDetailsContextMapper.java
new file mode 100644 (file)
index 0000000..f63250c
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * 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.
+ */
+package org.argeo.security.ldap.jcr;
+
+import java.util.Collection;
+import java.util.UUID;
+
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.argeo.ArgeoException;
+import org.argeo.jcr.ArgeoNames;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.UserJcrUtils;
+import org.argeo.security.jcr.JcrUserDetails;
+import org.springframework.ldap.core.DirContextAdapter;
+import org.springframework.ldap.core.DirContextOperations;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.ldap.userdetails.UserDetailsContextMapper;
+
+/** @deprecated Read only mapping from LDAP to user details */
+@Deprecated
+public class JcrUserDetailsContextMapper implements UserDetailsContextMapper,
+               ArgeoNames {
+       /** Admin session on the security workspace */
+       private Session securitySession;
+       private Repository repository;
+       private String securityWorkspace = "security";
+
+       public void init() {
+               try {
+                       securitySession = repository.login(securityWorkspace);
+               } catch (RepositoryException e) {
+                       JcrUtils.logoutQuietly(securitySession);
+                       throw new ArgeoException(
+                                       "Cannot initialize LDAP/JCR user details context mapper", e);
+               }
+       }
+
+       public void destroy() {
+               JcrUtils.logoutQuietly(securitySession);
+       }
+
+       /** Called during authentication in order to retrieve user details */
+       public UserDetails mapUserFromContext(final DirContextOperations ctx,
+                       final String username,
+                       Collection<? extends GrantedAuthority> authorities) {
+               if (ctx == null)
+                       throw new ArgeoException("No LDAP information for user " + username);
+               Node userHome = UserJcrUtils.getUserHome(securitySession, username);
+               if (userHome == null)
+                       throw new ArgeoException("No JCR information for user " + username);
+
+               // password
+               // SortedSet<?> passwordAttributes = ctx
+               // .getAttributeSortedStringSet(passwordAttribute);
+               // String password;
+               // if (passwordAttributes == null || passwordAttributes.size() == 0) {
+               // throw new ArgeoException("No password found for user " + username);
+               // } else {
+               // byte[] arr = (byte[]) passwordAttributes.first();
+               // password = new String(arr);
+               // // erase password
+               // Arrays.fill(arr, (byte) 0);
+               // }
+
+               try {
+                       // we don't have access to password, so let's not pretend
+                       String password = UUID.randomUUID().toString();
+                       return new JcrUserDetails(userHome.getNode(ARGEO_PROFILE),
+                                       password, authorities);
+               } catch (RepositoryException e) {
+                       throw new ArgeoException("Cannot retrieve user details for "
+                                       + username, e);
+               }
+       }
+
+       public void mapUserToContext(UserDetails user, final DirContextAdapter ctx) {
+               throw new UnsupportedOperationException("LDAP access is read-only");
+       }
+
+}
index bb8138ff2a33a793df2ac39ccc4db90060357f32..282c3f954d6b5c5e8ae7d5fcc68c419a77a5c317 100644 (file)
@@ -8,24 +8,12 @@
                <relativePath>..</relativePath>
        </parent>
        <artifactId>org.argeo.security.jackrabbit</artifactId>
-       <name>Commons Security Jackrabbit</name>
+       <name>Commons Jackrabbit Extensions</name>
        <dependencies>
                <dependency>
                        <groupId>org.argeo.commons</groupId>
                        <artifactId>org.argeo.security.core</artifactId>
                        <version>2.1.14-SNAPSHOT</version>
                </dependency>
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.tp</groupId> -->
-<!--                   <artifactId>javax.jcr</artifactId> -->
-<!--           </dependency> -->
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.tp</groupId> -->
-<!--                   <artifactId>org.apache.jackrabbit</artifactId> -->
-<!--           </dependency> -->
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.tp</groupId> -->
-<!--                   <artifactId>org.springframework.security.core</artifactId> -->
-<!--           </dependency> -->
        </dependencies>
 </project>
\ No newline at end of file
diff --git a/org.argeo.security.ldap/.classpath b/org.argeo.security.ldap/.classpath
deleted file mode 100644 (file)
index d2953a6..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-<?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-1.6" />
-       <classpathentry kind="output" path="bin" />
-</classpath>
diff --git a/org.argeo.security.ldap/.project b/org.argeo.security.ldap/.project
deleted file mode 100644 (file)
index 942f140..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-       <name>org.argeo.security.ldap</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>
diff --git a/org.argeo.security.ldap/bnd.bnd b/org.argeo.security.ldap/bnd.bnd
deleted file mode 100644 (file)
index 12f35fa..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-Import-Package: org.springframework.core,\
-org.springframework.dao,\
-javax.jcr.nodetype,\
-*
\ No newline at end of file
diff --git a/org.argeo.security.ldap/build.properties b/org.argeo.security.ldap/build.properties
deleted file mode 100644 (file)
index 30f7153..0000000
+++ /dev/null
@@ -1 +0,0 @@
-source.. = src/
diff --git a/org.argeo.security.ldap/pom.xml b/org.argeo.security.ldap/pom.xml
deleted file mode 100644 (file)
index 295f743..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-<?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.1.14-SNAPSHOT</version>
-               <relativePath>..</relativePath>
-       </parent>
-       <artifactId>org.argeo.security.ldap</artifactId>
-       <name>Commons Security LDAP</name>
-       <build>
-               <plugins>
-                       <plugin>
-                               <groupId>org.apache.maven.plugins</groupId>
-                               <artifactId>maven-compiler-plugin</artifactId>
-                       </plugin>
-                       <plugin>
-                               <groupId>org.apache.maven.plugins</groupId>
-                               <artifactId>maven-source-plugin</artifactId>
-                       </plugin>
-                       <plugin>
-                               <groupId>org.apache.maven.plugins</groupId>
-                               <artifactId>maven-jar-plugin</artifactId>
-                       </plugin>
-                       <plugin>
-                               <groupId>org.apache.felix</groupId>
-                               <artifactId>maven-bundle-plugin</artifactId>
-
-                               <configuration>
-                                       <instructions>
-                                               <Export-Package>
-                                                       org.argeo.security.ldap.*
-                                               </Export-Package>
-                                               <Import-Package>
-                                                       org.springframework.core,
-                                                       org.springframework.dao,
-                                                       javax.jcr.nodetype,
-                                                       *
-                                               </Import-Package>
-                                       </instructions>
-                               </configuration>
-                       </plugin>
-               </plugins>
-       </build>
-       <dependencies>
-               <dependency>
-                       <groupId>org.argeo.commons</groupId>
-                       <artifactId>org.argeo.util</artifactId>
-                       <version>2.1.14-SNAPSHOT</version>
-               </dependency>
-               <dependency>
-                       <groupId>org.argeo.commons</groupId>
-                       <artifactId>org.argeo.security.core</artifactId>
-                       <version>2.1.14-SNAPSHOT</version>
-               </dependency>
-
-               <!-- JCR -->
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.tp</groupId> -->
-<!--                   <artifactId>javax.jcr</artifactId> -->
-<!--           </dependency> -->
-
-               <!-- Spring -->
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.tp</groupId> -->
-<!--                   <artifactId>org.springframework.ldap</artifactId> -->
-<!--           </dependency> -->
-
-               <!-- Logging -->
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.tp</groupId> -->
-<!--                   <artifactId>slf4j.org.apache.commons.logging</artifactId> -->
-<!--           </dependency> -->
-
-       </dependencies>
-</project>
\ No newline at end of file
diff --git a/org.argeo.security.ldap/src/org/argeo/security/ldap/ArgeoLdapShaPasswordEncoder.java b/org.argeo.security.ldap/src/org/argeo/security/ldap/ArgeoLdapShaPasswordEncoder.java
deleted file mode 100644 (file)
index a2c43a5..0000000
+++ /dev/null
@@ -1,36 +0,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.
- */
-package org.argeo.security.ldap;
-
-import org.springframework.security.authentication.encoding.LdapShaPasswordEncoder;
-
-/**
- * {@link LdapShaPasswordEncoder} allowing to configure the usage of salt (APache
- * Directory Server 1.0 does not support bind with SSHA)
- */
-public class ArgeoLdapShaPasswordEncoder extends LdapShaPasswordEncoder {
-       private Boolean useSalt = true;
-
-       @Override
-       public String encodePassword(String rawPass, Object salt) {
-               return super.encodePassword(rawPass, useSalt ? salt : null);
-       }
-
-       public void setUseSalt(Boolean useSalt) {
-               this.useSalt = useSalt;
-       }
-
-}
diff --git a/org.argeo.security.ldap/src/org/argeo/security/ldap/ArgeoLdapUserDetailsManager.java b/org.argeo.security.ldap/src/org/argeo/security/ldap/ArgeoLdapUserDetailsManager.java
deleted file mode 100644 (file)
index 89b5aa9..0000000
+++ /dev/null
@@ -1,145 +0,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.
- */
-package org.argeo.security.ldap;
-
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Random;
-import java.util.Set;
-import java.util.TreeSet;
-
-import org.argeo.ArgeoException;
-import org.argeo.security.UserAdminService;
-import org.springframework.ldap.core.ContextSource;
-import org.springframework.security.authentication.encoding.PasswordEncoder;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.security.ldap.userdetails.LdapUserDetailsManager;
-
-/** Extends {@link LdapUserDetailsManager} by adding password encoding support. */
-public class ArgeoLdapUserDetailsManager extends LdapUserDetailsManager
-               implements UserAdminService {
-       private String superUsername = "root";
-       private ArgeoUserAdminDaoLdap userAdminDao;
-       private PasswordEncoder passwordEncoder;
-       private final Random random;
-
-       public ArgeoLdapUserDetailsManager(ContextSource contextSource) {
-               super(contextSource);
-               this.random = createRandom();
-       }
-
-       private static Random createRandom() {
-               try {
-                       return SecureRandom.getInstance("SHA1PRNG");
-               } catch (NoSuchAlgorithmException e) {
-                       return new Random(System.currentTimeMillis());
-               }
-       }
-
-       @Override
-       public void changePassword(String oldPassword, String newPassword) {
-               Authentication authentication = SecurityContextHolder.getContext()
-                               .getAuthentication();
-               if (authentication == null)
-                       throw new ArgeoException(
-                                       "Cannot change password without authentication");
-               String username = authentication.getName();
-               UserDetails userDetails = loadUserByUsername(username);
-               String currentPassword = userDetails.getPassword();
-               if (currentPassword == null)
-                       throw new ArgeoException("Cannot access current password");
-               if (!passwordEncoder
-                               .isPasswordValid(currentPassword, oldPassword, null))
-                       throw new ArgeoException("Old password invalid");
-               // Spring Security LDAP 2.0 is buggy when used with OpenLDAP and called
-               // with oldPassword argument
-               super.changePassword(null, encodePassword(newPassword));
-       }
-
-       public void newRole(String role) {
-               userAdminDao.createRole(role, superUsername);
-       }
-
-       public void synchronize() {
-               for (String username : userAdminDao.listUsers())
-                       loadUserByUsername(username);
-               // TODO: find a way to remove from JCR
-       }
-
-       public void deleteRole(String role) {
-               userAdminDao.deleteRole(role);
-       }
-
-       public Set<String> listUsers() {
-               return userAdminDao.listUsers();
-       }
-
-       public Set<String> listUsersInRole(String role) {
-               Set<String> lst = new TreeSet<String>(
-                               userAdminDao.listUsersInRole(role));
-               Iterator<String> it = lst.iterator();
-               while (it.hasNext()) {
-                       if (it.next().equals(superUsername)) {
-                               it.remove();
-                               break;
-                       }
-               }
-               return lst;
-       }
-
-       public List<String> listUserRoles(String username) {
-               UserDetails userDetails = loadUserByUsername(username);
-               List<String> roles = new ArrayList<String>();
-               for (GrantedAuthority ga : userDetails.getAuthorities()) {
-                       roles.add(ga.getAuthority());
-               }
-               return Collections.unmodifiableList(roles);
-       }
-
-       public Set<String> listEditableRoles() {
-               return userAdminDao.listEditableRoles();
-       }
-
-       protected String encodePassword(String password) {
-               if (!password.startsWith("{")) {
-                       byte[] salt = new byte[16];
-                       random.nextBytes(salt);
-                       return passwordEncoder.encodePassword(password, salt);
-               } else {
-                       return password;
-               }
-       }
-
-       public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
-               this.passwordEncoder = passwordEncoder;
-       }
-
-       public void setSuperUsername(String superUsername) {
-               this.superUsername = superUsername;
-       }
-
-       public void setUserAdminDao(ArgeoUserAdminDaoLdap userAdminDao) {
-               this.userAdminDao = userAdminDao;
-       }
-
-}
diff --git a/org.argeo.security.ldap/src/org/argeo/security/ldap/ArgeoUserAdminDaoLdap.java b/org.argeo.security.ldap/src/org/argeo/security/ldap/ArgeoUserAdminDaoLdap.java
deleted file mode 100644 (file)
index 37d2a06..0000000
+++ /dev/null
@@ -1,195 +0,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.
- */
-package org.argeo.security.ldap;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
-
-import javax.naming.Name;
-import javax.naming.NamingException;
-import javax.naming.directory.DirContext;
-
-import org.springframework.ldap.core.ContextExecutor;
-import org.springframework.ldap.core.ContextMapper;
-import org.springframework.ldap.core.DirContextAdapter;
-import org.springframework.ldap.core.DistinguishedName;
-import org.springframework.ldap.core.LdapTemplate;
-import org.springframework.ldap.core.support.BaseLdapPathContextSource;
-import org.springframework.security.ldap.LdapUsernameToDnMapper;
-import org.springframework.security.ldap.LdapUtils;
-
-/**
- * Wraps low-level LDAP operation on user and roles, used by
- * {@link ArgeoLdapUserDetailsManager}
- */
-public class ArgeoUserAdminDaoLdap {
-       private String userBase;
-       private String usernameAttribute;
-       private String groupBase;
-       private String[] groupClasses;
-
-       private String groupRoleAttribute;
-       private String groupMemberAttribute;
-       private String defaultRole;
-       private String rolePrefix;
-
-       private final LdapTemplate ldapTemplate;
-       private LdapUsernameToDnMapper usernameMapper;
-
-       /**
-        * Standard constructor, using the LDAP context source shared with Spring
-        * Security components.
-        */
-       public ArgeoUserAdminDaoLdap(BaseLdapPathContextSource contextSource) {
-               this.ldapTemplate = new LdapTemplate(contextSource);
-       }
-
-       @SuppressWarnings("unchecked")
-       public synchronized Set<String> listUsers() {
-               List<String> usernames = (List<String>) ldapTemplate.listBindings(
-                               new DistinguishedName(userBase), new ContextMapper() {
-                                       public Object mapFromContext(Object ctxArg) {
-                                               DirContextAdapter ctx = (DirContextAdapter) ctxArg;
-                                               return ctx.getStringAttribute(usernameAttribute);
-                                       }
-                               });
-
-               return Collections
-                               .unmodifiableSortedSet(new TreeSet<String>(usernames));
-       }
-
-       @SuppressWarnings("unchecked")
-       public Set<String> listEditableRoles() {
-               return Collections.unmodifiableSortedSet(new TreeSet<String>(
-                               ldapTemplate.listBindings(groupBase, new ContextMapper() {
-                                       public Object mapFromContext(Object ctxArg) {
-                                               String groupName = ((DirContextAdapter) ctxArg)
-                                                               .getStringAttribute(groupRoleAttribute);
-                                               String roleName = convertGroupToRole(groupName);
-                                               return roleName;
-                                       }
-                               })));
-       }
-
-       @SuppressWarnings("unchecked")
-       public Set<String> listUsersInRole(String role) {
-               return (Set<String>) ldapTemplate.lookup(
-                               buildGroupDn(convertRoleToGroup(role)), new ContextMapper() {
-                                       public Object mapFromContext(Object ctxArg) {
-                                               DirContextAdapter ctx = (DirContextAdapter) ctxArg;
-                                               String[] userDns = ctx
-                                                               .getStringAttributes(groupMemberAttribute);
-                                               TreeSet<String> set = new TreeSet<String>();
-                                               for (String userDn : userDns) {
-                                                       DistinguishedName dn = new DistinguishedName(userDn);
-                                                       String username = dn.getValue(usernameAttribute);
-                                                       set.add(username);
-                                               }
-                                               return Collections.unmodifiableSortedSet(set);
-                                       }
-                               });
-       }
-
-       public void createRole(String role, final String superuserName) {
-               String group = convertRoleToGroup(role);
-               DistinguishedName superuserDn = (DistinguishedName) ldapTemplate
-                               .executeReadWrite(new ContextExecutor() {
-                                       public Object executeWithContext(DirContext ctx)
-                                                       throws NamingException {
-                                               return LdapUtils.getFullDn(
-                                                               usernameMapper.buildDn(superuserName), ctx);
-                                       }
-                               });
-
-               Name groupDn = buildGroupDn(group);
-               DirContextAdapter context = new DirContextAdapter();
-               context.setAttributeValues("objectClass", groupClasses);
-               context.setAttributeValue("cn", group);
-               // Add superuser because cannot create empty group
-               context.setAttributeValue(groupMemberAttribute, superuserDn.toString());
-               ldapTemplate.bind(groupDn, context, null);
-       }
-
-       public void deleteRole(String role) {
-               String group = convertRoleToGroup(role);
-               Name dn = buildGroupDn(group);
-               ldapTemplate.unbind(dn);
-       }
-
-       /** Maps a role (ROLE_XXX) to the related LDAP group (xxx) */
-       protected String convertRoleToGroup(String role) {
-               String group = role;
-               if (group.startsWith(rolePrefix)) {
-                       group = group.substring(rolePrefix.length());
-                       group = group.toLowerCase();
-               }
-               return group;
-       }
-
-       /** Maps anLDAP group (xxx) to the related role (ROLE_XXX) */
-       protected String convertGroupToRole(String groupName) {
-               groupName = groupName.toUpperCase();
-
-               return rolePrefix + groupName;
-       }
-
-       protected Name buildGroupDn(String name) {
-               return new DistinguishedName(groupRoleAttribute + "=" + name + ","
-                               + groupBase);
-       }
-
-       public void setUserBase(String userBase) {
-               this.userBase = userBase;
-       }
-
-       public void setUsernameAttribute(String usernameAttribute) {
-               this.usernameAttribute = usernameAttribute;
-       }
-
-       public void setGroupBase(String groupBase) {
-               this.groupBase = groupBase;
-       }
-
-       public void setGroupRoleAttribute(String groupRoleAttributeName) {
-               this.groupRoleAttribute = groupRoleAttributeName;
-       }
-
-       public void setGroupMemberAttribute(String groupMemberAttributeName) {
-               this.groupMemberAttribute = groupMemberAttributeName;
-       }
-
-       public void setDefaultRole(String defaultRole) {
-               this.defaultRole = defaultRole;
-       }
-
-       public void setRolePrefix(String rolePrefix) {
-               this.rolePrefix = rolePrefix;
-       }
-
-       public void setUsernameMapper(LdapUsernameToDnMapper usernameMapper) {
-               this.usernameMapper = usernameMapper;
-       }
-
-       public String getDefaultRole() {
-               return defaultRole;
-       }
-
-       public void setGroupClasses(String[] groupClasses) {
-               this.groupClasses = groupClasses;
-       }
-}
diff --git a/org.argeo.security.ldap/src/org/argeo/security/ldap/jcr/JcrLdapSynchronizer.java b/org.argeo.security.ldap/src/org/argeo/security/ldap/jcr/JcrLdapSynchronizer.java
deleted file mode 100644 (file)
index e0519c3..0000000
+++ /dev/null
@@ -1,622 +0,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.
- */
-package org.argeo.security.ldap.jcr;
-
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.SortedSet;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.query.Query;
-import javax.jcr.version.VersionManager;
-import javax.naming.Name;
-import javax.naming.directory.BasicAttribute;
-import javax.naming.directory.DirContext;
-import javax.naming.directory.ModificationItem;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.ArgeoException;
-import org.argeo.jcr.ArgeoNames;
-import org.argeo.jcr.ArgeoTypes;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.security.SecurityUtils;
-import org.argeo.security.jcr.JcrSecurityModel;
-import org.argeo.security.jcr.JcrUserDetails;
-import org.argeo.security.jcr.SimpleJcrSecurityModel;
-import org.springframework.ldap.core.ContextMapper;
-import org.springframework.ldap.core.DirContextAdapter;
-import org.springframework.ldap.core.DirContextOperations;
-import org.springframework.ldap.core.DistinguishedName;
-import org.springframework.ldap.core.LdapTemplate;
-import org.springframework.security.authentication.encoding.PasswordEncoder;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.security.ldap.LdapUsernameToDnMapper;
-import org.springframework.security.ldap.userdetails.UserDetailsContextMapper;
-
-/** Makes sure that LDAP and JCR are in line. */
-public class JcrLdapSynchronizer implements UserDetailsContextMapper,
-               ArgeoNames {
-       private final static Log log = LogFactory.getLog(JcrLdapSynchronizer.class);
-
-       // LDAP
-       private LdapTemplate ldapTemplate;
-       /**
-        * LDAP template whose context source has an object factory set to null. see
-        * <a href=
-        * "http://forum.springsource.org/showthread.php?55955-Persistent-search-with-spring-ldap"
-        * >this</a>
-        */
-       // private LdapTemplate rawLdapTemplate;
-
-       private String userBase;
-       private String usernameAttribute;
-       private String passwordAttribute;
-       private String[] userClasses;
-       // private String defaultUserRole ="ROLE_USER";
-
-       // private NamingListener ldapUserListener;
-       // private SearchControls subTreeSearchControls;
-       private LdapUsernameToDnMapper usernameMapper;
-
-       private PasswordEncoder passwordEncoder;
-       private final Random random;
-
-       // JCR
-       /** Admin session on the main workspace */
-       private Session nodeSession;
-       private Repository repository;
-
-       // private JcrProfileListener jcrProfileListener;
-       private JcrSecurityModel jcrSecurityModel = new SimpleJcrSecurityModel();
-
-       // Mapping
-       private Map<String, String> propertyToAttributes = new HashMap<String, String>();
-
-       public JcrLdapSynchronizer() {
-               random = createRandom();
-       }
-
-       public void init() {
-               try {
-                       nodeSession = repository.login();
-
-                       // TODO put this in a different thread, and poll the LDAP server
-                       // until it is up
-                       try {
-                               synchronize();
-
-                               // LDAP
-                               // subTreeSearchControls = new SearchControls();
-                               // subTreeSearchControls
-                               // .setSearchScope(SearchControls.SUBTREE_SCOPE);
-                               // LDAP listener
-                               // ldapUserListener = new LdapUserListener();
-                               // rawLdapTemplate.executeReadOnly(new ContextExecutor() {
-                               // public Object executeWithContext(DirContext ctx)
-                               // throws NamingException {
-                               // EventDirContext ectx = (EventDirContext) ctx.lookup("");
-                               // ectx.addNamingListener(userBase, "("
-                               // + usernameAttribute + "=*)",
-                               // subTreeSearchControls, ldapUserListener);
-                               // return null;
-                               // }
-                               // });
-                       } catch (Exception e) {
-                               log.error("Could not synchronize and listen to LDAP,"
-                                               + " probably because the LDAP server is not available."
-                                               + " Restart the system as soon as possible.", e);
-                       }
-
-                       // JCR
-                       // String[] nodeTypes = { ArgeoTypes.ARGEO_USER_PROFILE };
-                       // jcrProfileListener = new JcrProfileListener();
-                       // noLocal is used so that we are not notified when we modify JCR
-                       // from LDAP
-                       // nodeSession
-                       // .getWorkspace()
-                       // .getObservationManager()
-                       // .addEventListener(jcrProfileListener,
-                       // Event.PROPERTY_CHANGED | Event.NODE_ADDED, "/",
-                       // true, null, nodeTypes, true);
-               } catch (Exception e) {
-                       JcrUtils.logoutQuietly(nodeSession);
-                       throw new ArgeoException("Cannot initialize LDAP/JCR synchronizer",
-                                       e);
-               }
-       }
-
-       public void destroy() {
-               // JcrUtils.removeListenerQuietly(nodeSession, jcrProfileListener);
-               JcrUtils.logoutQuietly(nodeSession);
-               // try {
-               // rawLdapTemplate.executeReadOnly(new ContextExecutor() {
-               // public Object executeWithContext(DirContext ctx)
-               // throws NamingException {
-               // EventDirContext ectx = (EventDirContext) ctx.lookup("");
-               // ectx.removeNamingListener(ldapUserListener);
-               // return null;
-               // }
-               // });
-               // } catch (Exception e) {
-               // // silent (LDAP server may have been shutdown already)
-               // if (log.isTraceEnabled())
-               // log.trace("Cannot remove LDAP listener", e);
-               // }
-       }
-
-       /*
-        * LDAP TO JCR
-        */
-       /** Full synchronization between LDAP and JCR. LDAP has priority. */
-       protected void synchronize() {
-               try {
-                       Name userBaseName = new DistinguishedName(userBase);
-                       // TODO subtree search?
-                       @SuppressWarnings("unchecked")
-                       List<String> userPaths = (List<String>) ldapTemplate.listBindings(
-                                       userBaseName, new ContextMapper() {
-                                               public Object mapFromContext(Object ctxObj) {
-                                                       try {
-                                                               return mapLdapToJcr((DirContextAdapter) ctxObj);
-                                                       } catch (Exception e) {
-                                                               // do not break process because of error
-                                                               log.error(
-                                                                               "Could not LDAP->JCR synchronize user "
-                                                                                               + ctxObj, e);
-                                                               return null;
-                                                       }
-                                               }
-                                       });
-
-                       // create accounts which are not in LDAP
-                       Query query = nodeSession
-                                       .getWorkspace()
-                                       .getQueryManager()
-                                       .createQuery(
-                                                       "select * from [" + ArgeoTypes.ARGEO_USER_PROFILE
-                                                                       + "]", Query.JCR_SQL2);
-                       NodeIterator it = query.execute().getNodes();
-                       while (it.hasNext()) {
-                               Node userProfile = it.nextNode();
-                               String path = userProfile.getPath();
-                               try {
-                                       if (!userPaths.contains(path)) {
-                                               String username = userProfile
-                                                               .getProperty(ARGEO_USER_ID).getString();
-                                               // GrantedAuthority[] authorities = {new
-                                               // GrantedAuthorityImpl(defaultUserRole)};
-                                               List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
-                                               JcrUserDetails userDetails = new JcrUserDetails(
-                                                               userProfile, username, authorities);
-                                               String dn = createLdapUser(userDetails);
-                                               log.warn("Created ldap entry '" + dn + "' for user '"
-                                                               + username + "'");
-
-                                               // if(!userProfile.getProperty(ARGEO_ENABLED).getBoolean()){
-                                               // continue profiles;
-                                               // }
-                                               //
-                                               // log.warn("Path "
-                                               // + path
-                                               // + " not found in LDAP, disabling user "
-                                               // + userProfile.getProperty(ArgeoNames.ARGEO_USER_ID)
-                                               // .getString());
-
-                                               // Temporary hack to repair previous behaviour
-                                               if (!userProfile.getProperty(ARGEO_ENABLED)
-                                                               .getBoolean()) {
-                                                       VersionManager versionManager = nodeSession
-                                                                       .getWorkspace().getVersionManager();
-                                                       versionManager.checkout(userProfile.getPath());
-                                                       userProfile.setProperty(ArgeoNames.ARGEO_ENABLED,
-                                                                       true);
-                                                       nodeSession.save();
-                                                       versionManager.checkin(userProfile.getPath());
-                                               }
-                                       }
-                               } catch (Exception e) {
-                                       log.error("Cannot process " + path, e);
-                               }
-                       }
-               } catch (Exception e) {
-                       JcrUtils.discardQuietly(nodeSession);
-                       log.error("Cannot synchronize LDAP and JCR", e);
-                       // throw new ArgeoException("Cannot synchronize LDAP and JCR", e);
-               }
-       }
-
-       private String createLdapUser(UserDetails user) {
-               DirContextAdapter ctx = new DirContextAdapter();
-               mapUserToContext(user, ctx);
-               DistinguishedName dn = usernameMapper.buildDn(user.getUsername());
-               ldapTemplate.bind(dn, ctx, null);
-               return dn.toString();
-       }
-
-       /** Called during authentication in order to retrieve user details */
-       public UserDetails mapUserFromContext(final DirContextOperations ctx,
-                       final String username,
-                       Collection<? extends GrantedAuthority> authorities) {
-               if (ctx == null)
-                       throw new ArgeoException("No LDAP information for user " + username);
-
-               String ldapUsername = ctx.getStringAttribute(usernameAttribute);
-               if (!ldapUsername.equals(username))
-                       throw new ArgeoException("Logged in with username " + username
-                                       + " but LDAP user is " + ldapUsername);
-
-               Node userProfile = jcrSecurityModel.sync(nodeSession, username,
-                               SecurityUtils.authoritiesToStringList(authorities));
-               // JcrUserDetails.checkAccountStatus(userProfile);
-
-               // password
-               SortedSet<?> passwordAttributes = ctx
-                               .getAttributeSortedStringSet(passwordAttribute);
-               String password;
-               if (passwordAttributes == null || passwordAttributes.size() == 0) {
-                       // throw new ArgeoException("No password found for user " +
-                       // username);
-                       password = "NULL";
-               } else {
-                       byte[] arr = (byte[]) passwordAttributes.first();
-                       password = new String(arr);
-                       // erase password
-                       Arrays.fill(arr, (byte) 0);
-               }
-
-               try {
-                       return new JcrUserDetails(userProfile, password, authorities);
-               } catch (RepositoryException e) {
-                       throw new ArgeoException("Cannot retrieve user details for "
-                                       + username, e);
-               }
-       }
-
-       /**
-        * Writes an LDAP context to the JCR user profile.
-        * 
-        * @return path to user profile
-        */
-       protected synchronized String mapLdapToJcr(DirContextAdapter ctx) {
-               Session session = nodeSession;
-               try {
-                       // process
-                       String username = ctx.getStringAttribute(usernameAttribute);
-
-                       Node userProfile = jcrSecurityModel.sync(session, username, null);
-                       Map<String, String> modifications = new HashMap<String, String>();
-                       for (String jcrProperty : propertyToAttributes.keySet())
-                               ldapToJcr(userProfile, jcrProperty, ctx, modifications);
-
-                       int modifCount = modifications.size();
-                       if (modifCount > 0) {
-                               session.getWorkspace().getVersionManager()
-                                               .checkout(userProfile.getPath());
-                               for (String prop : modifications.keySet())
-                                       userProfile.setProperty(prop, modifications.get(prop));
-                               JcrUtils.updateLastModified(userProfile);
-                               session.save();
-                               session.getWorkspace().getVersionManager()
-                                               .checkin(userProfile.getPath());
-                               if (log.isDebugEnabled())
-                                       log.debug("Mapped " + modifCount + " LDAP modification"
-                                                       + (modifCount == 1 ? "" : "s") + " from "
-                                                       + ctx.getDn() + " to " + userProfile);
-                       }
-                       return userProfile.getPath();
-               } catch (Exception e) {
-                       JcrUtils.discardQuietly(session);
-                       throw new ArgeoException("Cannot synchronize JCR and LDAP", e);
-               }
-       }
-
-       /** Maps an LDAP property to a JCR property */
-       protected void ldapToJcr(Node userProfile, String jcrProperty,
-                       DirContextOperations ctx, Map<String, String> modifications) {
-               // TODO do we really need DirContextOperations?
-               try {
-                       String ldapAttribute;
-                       if (propertyToAttributes.containsKey(jcrProperty))
-                               ldapAttribute = propertyToAttributes.get(jcrProperty);
-                       else
-                               throw new ArgeoException(
-                                               "No LDAP attribute mapped for JCR proprty "
-                                                               + jcrProperty);
-
-                       String value = ctx.getStringAttribute(ldapAttribute);
-                       String jcrValue = userProfile.hasProperty(jcrProperty) ? userProfile
-                                       .getProperty(jcrProperty).getString() : null;
-                       if (value != null && jcrValue != null) {
-                               if (!value.equals(jcrValue))
-                                       modifications.put(jcrProperty, value);
-                       } else if (value != null && jcrValue == null) {
-                               modifications.put(jcrProperty, value);
-                       } else if (value == null && jcrValue != null) {
-                               modifications.put(jcrProperty, value);
-                       }
-               } catch (Exception e) {
-                       throw new ArgeoException("Cannot map JCR property " + jcrProperty
-                                       + " from LDAP", e);
-               }
-       }
-
-       /*
-        * JCR to LDAP
-        */
-
-       public void mapUserToContext(UserDetails user, final DirContextAdapter ctx) {
-               if (!(user instanceof JcrUserDetails))
-                       throw new ArgeoException("Unsupported user details: "
-                                       + user.getClass());
-
-               ctx.setAttributeValues("objectClass", userClasses);
-               ctx.setAttributeValue(usernameAttribute, user.getUsername());
-               ctx.setAttributeValue(passwordAttribute,
-                               encodePassword(user.getPassword()));
-
-               final JcrUserDetails jcrUserDetails = (JcrUserDetails) user;
-               try {
-                       Node userProfile = nodeSession
-                                       .getNode(jcrUserDetails.getHomePath()).getNode(
-                                                       ARGEO_PROFILE);
-                       for (String jcrProperty : propertyToAttributes.keySet()) {
-                               if (userProfile.hasProperty(jcrProperty)) {
-                                       ModificationItem mi = jcrToLdap(jcrProperty, userProfile
-                                                       .getProperty(jcrProperty).getString());
-                                       if (mi != null)
-                                               ctx.setAttribute(mi.getAttribute());
-                               }
-                       }
-                       if (log.isTraceEnabled())
-                               log.trace("Mapped " + userProfile + " to " + ctx.getDn());
-               } catch (RepositoryException e) {
-                       throw new ArgeoException("Cannot synchronize JCR and LDAP", e);
-               }
-
-       }
-
-       /** Maps a JCR property to an LDAP property */
-       protected ModificationItem jcrToLdap(String jcrProperty, String value) {
-               // TODO do we really need DirContextOperations?
-               try {
-                       String ldapAttribute;
-                       if (propertyToAttributes.containsKey(jcrProperty))
-                               ldapAttribute = propertyToAttributes.get(jcrProperty);
-                       else
-                               return null;
-
-                       // fix issue with empty 'sn' in LDAP
-                       if (ldapAttribute.equals("sn") && (value.trim().equals("")))
-                               return null;
-                       // fix issue with empty 'description' in LDAP
-                       if (ldapAttribute.equals("description") && value.trim().equals(""))
-                               return null;
-                       BasicAttribute attr = new BasicAttribute(
-                                       propertyToAttributes.get(jcrProperty), value);
-                       ModificationItem mi = new ModificationItem(
-                                       DirContext.REPLACE_ATTRIBUTE, attr);
-                       return mi;
-               } catch (Exception e) {
-                       throw new ArgeoException("Cannot map JCR property " + jcrProperty
-                                       + " from LDAP", e);
-               }
-       }
-
-       /*
-        * UTILITIES
-        */
-       protected String encodePassword(String password) {
-               if (!password.startsWith("{")) {
-                       byte[] salt = new byte[16];
-                       random.nextBytes(salt);
-                       return passwordEncoder.encodePassword(password, salt);
-               } else {
-                       return password;
-               }
-       }
-
-       private static Random createRandom() {
-               try {
-                       return SecureRandom.getInstance("SHA1PRNG");
-               } catch (NoSuchAlgorithmException e) {
-                       return new Random(System.currentTimeMillis());
-               }
-       }
-
-       /*
-        * DEPENDENCY INJECTION
-        */
-
-       public void setLdapTemplate(LdapTemplate ldapTemplate) {
-               this.ldapTemplate = ldapTemplate;
-       }
-
-       public void setRawLdapTemplate(LdapTemplate rawLdapTemplate) {
-               // this.rawLdapTemplate = rawLdapTemplate;
-       }
-
-       public void setRepository(Repository repository) {
-               this.repository = repository;
-       }
-
-       public void setUserBase(String userBase) {
-               this.userBase = userBase;
-       }
-
-       public void setUsernameAttribute(String usernameAttribute) {
-               this.usernameAttribute = usernameAttribute;
-       }
-
-       public void setPropertyToAttributes(Map<String, String> propertyToAttributes) {
-               this.propertyToAttributes = propertyToAttributes;
-       }
-
-       public void setUsernameMapper(LdapUsernameToDnMapper usernameMapper) {
-               this.usernameMapper = usernameMapper;
-       }
-
-       public void setPasswordAttribute(String passwordAttribute) {
-               this.passwordAttribute = passwordAttribute;
-       }
-
-       public void setUserClasses(String[] userClasses) {
-               this.userClasses = userClasses;
-       }
-
-       public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
-               this.passwordEncoder = passwordEncoder;
-       }
-
-       public void setJcrSecurityModel(JcrSecurityModel jcrSecurityModel) {
-               this.jcrSecurityModel = jcrSecurityModel;
-       }
-
-       /** Listen to LDAP */
-       // class LdapUserListener implements ObjectChangeListener,
-       // NamespaceChangeListener, UnsolicitedNotificationListener {
-       //
-       // public void namingExceptionThrown(NamingExceptionEvent evt) {
-       // evt.getException().printStackTrace();
-       // }
-       //
-       // public void objectChanged(NamingEvent evt) {
-       // Binding user = evt.getNewBinding();
-       // // TODO find a way not to be called when JCR is the source of the
-       // // modification
-       // DirContextAdapter ctx = (DirContextAdapter) ldapTemplate
-       // .lookup(user.getName());
-       // mapLdapToJcr(ctx);
-       // }
-       //
-       // public void objectAdded(NamingEvent evt) {
-       // Binding user = evt.getNewBinding();
-       // DirContextAdapter ctx = (DirContextAdapter) ldapTemplate
-       // .lookup(user.getName());
-       // mapLdapToJcr(ctx);
-       // }
-       //
-       // public void objectRemoved(NamingEvent evt) {
-       // if (log.isDebugEnabled())
-       // log.debug(evt);
-       // }
-       //
-       // public void objectRenamed(NamingEvent evt) {
-       // if (log.isDebugEnabled())
-       // log.debug(evt);
-       // }
-       //
-       // public void notificationReceived(UnsolicitedNotificationEvent evt) {
-       // UnsolicitedNotification notification = evt.getNotification();
-       // NamingException ne = notification.getException();
-       // String msg = "LDAP notification " + "ID=" + notification.getID()
-       // + ", referrals=" + notification.getReferrals();
-       // if (ne != null) {
-       // if (log.isTraceEnabled())
-       // log.trace(msg + ", exception= " + ne, ne);
-       // else
-       // log.warn(msg + ", exception= " + ne);
-       // } else if (log.isDebugEnabled()) {
-       // log.debug("Unsollicited LDAP notification " + msg);
-       // }
-       // }
-       //
-       // }
-
-       /** Listen to JCR */
-       // class JcrProfileListener implements EventListener {
-       //
-       // public void onEvent(EventIterator events) {
-       // try {
-       // final Map<Name, List<ModificationItem>> modifications = new HashMap<Name,
-       // List<ModificationItem>>();
-       // while (events.hasNext()) {
-       // Event event = events.nextEvent();
-       // try {
-       // if (Event.PROPERTY_CHANGED == event.getType()) {
-       // Property property = (Property) nodeSession
-       // .getItem(event.getPath());
-       // String propertyName = property.getName();
-       // Node userProfile = property.getParent();
-       // String username = userProfile.getProperty(
-       // ARGEO_USER_ID).getString();
-       // if (propertyToAttributes.containsKey(propertyName)) {
-       // Name name = usernameMapper.buildDn(username);
-       // if (!modifications.containsKey(name))
-       // modifications.put(name,
-       // new ArrayList<ModificationItem>());
-       // String value = property.getString();
-       // ModificationItem mi = jcrToLdap(propertyName,
-       // value);
-       // if (mi != null)
-       // modifications.get(name).add(mi);
-       // }
-       // } else if (Event.NODE_ADDED == event.getType()) {
-       // Node userProfile = nodeSession.getNode(event
-       // .getPath());
-       // String username = userProfile.getProperty(
-       // ARGEO_USER_ID).getString();
-       // Name name = usernameMapper.buildDn(username);
-       // for (String propertyName : propertyToAttributes
-       // .keySet()) {
-       // if (!modifications.containsKey(name))
-       // modifications.put(name,
-       // new ArrayList<ModificationItem>());
-       // String value = userProfile.getProperty(
-       // propertyName).getString();
-       // ModificationItem mi = jcrToLdap(propertyName,
-       // value);
-       // if (mi != null)
-       // modifications.get(name).add(mi);
-       // }
-       // }
-       // } catch (RepositoryException e) {
-       // throw new ArgeoException("Cannot process event "
-       // + event, e);
-       // }
-       // }
-       //
-       // for (Name name : modifications.keySet()) {
-       // List<ModificationItem> userModifs = modifications.get(name);
-       // int modifCount = userModifs.size();
-       // ldapTemplate.modifyAttributes(name, userModifs
-       // .toArray(new ModificationItem[modifCount]));
-       // if (log.isDebugEnabled())
-       // log.debug("Mapped " + modifCount + " JCR modification"
-       // + (modifCount == 1 ? "" : "s") + " to " + name);
-       // }
-       // } catch (Exception e) {
-       // // if (log.isDebugEnabled())
-       // // e.printStackTrace();
-       // throw new ArgeoException("Cannot process JCR events ("
-       // + e.getMessage() + ")", e);
-       // }
-       // }
-       //
-       // }
-}
diff --git a/org.argeo.security.ldap/src/org/argeo/security/ldap/jcr/JcrUserDetailsContextMapper.java b/org.argeo.security.ldap/src/org/argeo/security/ldap/jcr/JcrUserDetailsContextMapper.java
deleted file mode 100644 (file)
index f63250c..0000000
+++ /dev/null
@@ -1,98 +0,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.
- */
-package org.argeo.security.ldap.jcr;
-
-import java.util.Collection;
-import java.util.UUID;
-
-import javax.jcr.Node;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.argeo.ArgeoException;
-import org.argeo.jcr.ArgeoNames;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.jcr.UserJcrUtils;
-import org.argeo.security.jcr.JcrUserDetails;
-import org.springframework.ldap.core.DirContextAdapter;
-import org.springframework.ldap.core.DirContextOperations;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.security.ldap.userdetails.UserDetailsContextMapper;
-
-/** @deprecated Read only mapping from LDAP to user details */
-@Deprecated
-public class JcrUserDetailsContextMapper implements UserDetailsContextMapper,
-               ArgeoNames {
-       /** Admin session on the security workspace */
-       private Session securitySession;
-       private Repository repository;
-       private String securityWorkspace = "security";
-
-       public void init() {
-               try {
-                       securitySession = repository.login(securityWorkspace);
-               } catch (RepositoryException e) {
-                       JcrUtils.logoutQuietly(securitySession);
-                       throw new ArgeoException(
-                                       "Cannot initialize LDAP/JCR user details context mapper", e);
-               }
-       }
-
-       public void destroy() {
-               JcrUtils.logoutQuietly(securitySession);
-       }
-
-       /** Called during authentication in order to retrieve user details */
-       public UserDetails mapUserFromContext(final DirContextOperations ctx,
-                       final String username,
-                       Collection<? extends GrantedAuthority> authorities) {
-               if (ctx == null)
-                       throw new ArgeoException("No LDAP information for user " + username);
-               Node userHome = UserJcrUtils.getUserHome(securitySession, username);
-               if (userHome == null)
-                       throw new ArgeoException("No JCR information for user " + username);
-
-               // password
-               // SortedSet<?> passwordAttributes = ctx
-               // .getAttributeSortedStringSet(passwordAttribute);
-               // String password;
-               // if (passwordAttributes == null || passwordAttributes.size() == 0) {
-               // throw new ArgeoException("No password found for user " + username);
-               // } else {
-               // byte[] arr = (byte[]) passwordAttributes.first();
-               // password = new String(arr);
-               // // erase password
-               // Arrays.fill(arr, (byte) 0);
-               // }
-
-               try {
-                       // we don't have access to password, so let's not pretend
-                       String password = UUID.randomUUID().toString();
-                       return new JcrUserDetails(userHome.getNode(ARGEO_PROFILE),
-                                       password, authorities);
-               } catch (RepositoryException e) {
-                       throw new ArgeoException("Cannot retrieve user details for "
-                                       + username, e);
-               }
-       }
-
-       public void mapUserToContext(UserDetails user, final DirContextAdapter ctx) {
-               throw new UnsupportedOperationException("LDAP access is read-only");
-       }
-
-}
index e11b5b4a3319a90439e097927b0d5d7c7e9af7b4..cd153c903123dae259edd65965a634f0b485a1ad 100644 (file)
@@ -8,59 +8,34 @@
                <relativePath>..</relativePath>
        </parent>
        <artifactId>org.argeo.security.ui.admin</artifactId>
-       <name>Commons Security Admin UI</name>
+       <name>Commons CMS Workbench Admin</name>
        <packaging>jar</packaging>
        <dependencies>
-               <!-- Argeo Security -->
                <dependency>
                        <groupId>org.argeo.commons</groupId>
-                       <artifactId>org.argeo.security.ui</artifactId>
+                       <artifactId>org.argeo.util</artifactId>
                        <version>2.1.14-SNAPSHOT</version>
                </dependency>
                <dependency>
                        <groupId>org.argeo.commons</groupId>
-                       <artifactId>org.argeo.security.core</artifactId>
+                       <artifactId>org.argeo.security.ui</artifactId>
                        <version>2.1.14-SNAPSHOT</version>
                </dependency>
-
-               <!-- Argeo Eclipse, we build agaist RAP -->
                <dependency>
                        <groupId>org.argeo.commons</groupId>
-                       <artifactId>org.argeo.eclipse.ui.rap</artifactId>
+                       <artifactId>org.argeo.security.core</artifactId>
                        <version>2.1.14-SNAPSHOT</version>
-                       <scope>provided</scope>
                </dependency>
-               <!--  <dependency>
-                       <groupId>org.argeo.commons</groupId>
-                       <artifactId>org.argeo.eclipse.dep.rap</artifactId>
-                       <type>pom</type>
-                       <version>2.1.12-SNAPSHOT</version>
-                       <scope>provided</scope>
-               </dependency>  -->
                <dependency>
                        <groupId>org.argeo.commons</groupId>
                        <artifactId>org.argeo.eclipse.ui</artifactId>
                        <version>2.1.14-SNAPSHOT</version>
                </dependency>
-
-               <!-- Commons -->
                <dependency>
                        <groupId>org.argeo.commons</groupId>
-                       <artifactId>org.argeo.util</artifactId>
+                       <artifactId>org.argeo.eclipse.ui.rap</artifactId>
                        <version>2.1.14-SNAPSHOT</version>
+                       <scope>provided</scope>
                </dependency>
-
-               <!-- Spring -->
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.tp</groupId> -->
-<!--                   <artifactId>org.springframework.security.core</artifactId> -->
-<!--           </dependency> -->
-
-               <!-- Others -->
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.tp</groupId> -->
-<!--                   <artifactId>slf4j.org.apache.commons.logging -->
-<!--                   </artifactId> -->
-<!--           </dependency> -->
        </dependencies>
 </project>
\ No newline at end of file
index 6aa33e8711fe230ea447cea0f8e1454554ba0f0f..208cd173e6d0a0a43e8089b64e5fe8f9ca1562b2 100644 (file)
@@ -8,37 +8,19 @@
                <relativePath>..</relativePath>
        </parent>
        <artifactId>org.argeo.security.ui.rap</artifactId>
-       <name>Commons Security UI RAP</name>
+       <name>Commons CMS Workbench RAP</name>
        <packaging>jar</packaging>
        <dependencies>
-               <!-- Commons -->
                <dependency>
                        <groupId>org.argeo.commons</groupId>
                        <artifactId>org.argeo.util</artifactId>
                        <version>2.1.14-SNAPSHOT</version>
                </dependency>
-
-               <!-- Logging -->
-               <!-- <dependency> -->
-               <!-- <groupId>org.argeo.tp</groupId> -->
-               <!-- <artifactId>slf4j.org.apache.commons.logging</artifactId> -->
-               <!-- </dependency> -->
-
-               <!-- Argeo Security -->
                <dependency>
                        <groupId>org.argeo.commons</groupId>
                        <artifactId>org.argeo.security.ui</artifactId>
                        <version>2.1.14-SNAPSHOT</version>
                </dependency>
-               <!-- <dependency> -->
-               <!-- <groupId>org.argeo.commons</groupId> -->
-               <!-- <artifactId>org.argeo.security.equinox</artifactId> -->
-               <!-- <version>2.1.13-SNAPSHOT</version> -->
-               <!-- </dependency> -->
-
-               <!-- RAP specific -->
-               <!-- <dependency> <groupId>org.argeo.commons</groupId> <artifactId>org.argeo.eclipse.dep.rap</artifactId> 
-                       <type>pom</type> <version>2.1.12-SNAPSHOT</version> </dependency> -->
                <dependency>
                        <groupId>org.argeo.commons</groupId>
                        <artifactId>org.argeo.eclipse.ui.rap</artifactId>
index 5634891ab8cef5d16de2c16da54061c8f70d1bf4..14b2401656f5439b532a36c2a4a824adf2e18ec4 100644 (file)
@@ -8,45 +8,23 @@
                <relativePath>..</relativePath>
        </parent>
        <artifactId>org.argeo.security.ui</artifactId>
-       <name>Commons Security UI</name>
+       <name>Commons CMS Workbench</name>
        <packaging>jar</packaging>
        <dependencies>
-               <!-- Argeo Security -->
                <dependency>
                        <groupId>org.argeo.commons</groupId>
                        <artifactId>org.argeo.security.core</artifactId>
                        <version>2.1.14-SNAPSHOT</version>
                </dependency>
-
-               <!-- Generic Eclipse Utilities -->
                <dependency>
                        <groupId>org.argeo.commons</groupId>
                        <artifactId>org.argeo.eclipse.ui.workbench</artifactId>
                        <version>2.1.14-SNAPSHOT</version>
                </dependency>
-
-               <!-- We build against RAP -->
-               <!--  <dependency>
-                       <groupId>org.argeo.commons</groupId>
-                       <artifactId>org.argeo.eclipse.dep.rap</artifactId>
-                       <type>pom</type>
-                       <version>2.1.12-SNAPSHOT</version>
-                       <scope>provided</scope>
-               </dependency>  -->
-
-               <!-- Others: Commons utils, Spring, Logging -->
                <dependency>
                        <groupId>org.argeo.commons</groupId>
                        <artifactId>org.argeo.util</artifactId>
                        <version>2.1.14-SNAPSHOT</version>
                </dependency>
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.tp</groupId> -->
-<!--                   <artifactId>org.springframework.security.core</artifactId> -->
-<!--           </dependency> -->
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.tp</groupId> -->
-<!--                   <artifactId>slf4j.org.apache.commons.logging</artifactId> -->
-<!--           </dependency> -->
        </dependencies>
 </project>
\ No newline at end of file
diff --git a/org.argeo.server.core/.classpath b/org.argeo.server.core/.classpath
deleted file mode 100644 (file)
index d2953a6..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-<?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-1.6" />
-       <classpathentry kind="output" path="bin" />
-</classpath>
diff --git a/org.argeo.server.core/.project b/org.argeo.server.core/.project
deleted file mode 100644 (file)
index b28214b..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-       <name>org.argeo.server.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.jdt.core.javanature</nature>
-               <nature>org.eclipse.pde.PluginNature</nature>
-       </natures>
-</projectDescription>
diff --git a/org.argeo.server.core/bnd.bnd b/org.argeo.server.core/bnd.bnd
deleted file mode 100644 (file)
index 8a56d16..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-Import-Package: javax.servlet,\
-org.springframework.web.context,\
-*
\ No newline at end of file
diff --git a/org.argeo.server.core/build.properties b/org.argeo.server.core/build.properties
deleted file mode 100644 (file)
index 63f6b33..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-source.. = src/
-additional.bundles = org.apache.log4j,\
-                     com.jcraft.jsch
-                     
\ No newline at end of file
diff --git a/org.argeo.server.core/pom.xml b/org.argeo.server.core/pom.xml
deleted file mode 100644 (file)
index 9d81e2e..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-<?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.1.14-SNAPSHOT</version>
-               <relativePath>..</relativePath>
-       </parent>
-       <artifactId>org.argeo.server.core</artifactId>
-       <name>Commons Server Core</name>
-       <dependencies>
-               <dependency>
-                       <groupId>org.argeo.commons</groupId>
-                       <artifactId>org.argeo.util</artifactId>
-                       <version>2.1.14-SNAPSHOT</version>
-               </dependency>
-
-               <!-- Apache Commons -->
-<!--   <dependency>
-                       <groupId>org.argeo.tp</groupId>
-                       <artifactId>org.apache.commons.io</artifactId>
-               </dependency>
-               <dependency>
-                       <groupId>org.argeo.tp</groupId>
-                       <artifactId>org.apache.commons.vfs2</artifactId>
-               </dependency>
-               <dependency>
-                       <groupId>org.argeo.tp</groupId>
-                       <artifactId>org.apache.commons.exec</artifactId>
-               </dependency>
-               <dependency>
-                       <groupId>org.argeo.tp</groupId>
-                       <artifactId>com.jcraft.jsch</artifactId>
-               </dependency>
-
-               <dependency>
-                       <groupId>org.argeo.tp</groupId>
-                       <artifactId>org.joda.time</artifactId>
-               </dependency>
- -->   
-               <!-- Spring -->
-<!-- <dependency>
-                       <groupId>org.argeo.tp</groupId>
-                       <artifactId>org.springframework.web</artifactId>
-               </dependency>
-               <dependency>
-                       <groupId>org.argeo.tp</groupId>
-                       <artifactId>org.springframework.beans</artifactId>
-               </dependency>
-               <dependency>
-                       <groupId>org.argeo.tp</groupId>
-                       <artifactId>org.springframework.context</artifactId>
-               </dependency>
-               <dependency>
-                       <groupId>org.argeo.tp</groupId>
-                       <artifactId>org.springframework.core</artifactId>
-               </dependency>
-               <dependency>
-                       <groupId>org.argeo.tp</groupId>
-                       <artifactId>org.springframework.web.servlet</artifactId>
-               </dependency>
- -->
-               <!-- J2EE -->
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.tp</groupId> -->
-<!--                   <artifactId>javax.servlet</artifactId> -->
-<!--           </dependency> -->
-
-       <!-- Logging -->
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.tp</groupId> -->
-<!--                   <artifactId>slf4j.org.apache.commons.logging</artifactId> -->
-<!--           </dependency> -->
-
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.tp</groupId> -->
-<!--                   <artifactId>org.apache.commons.fileupload</artifactId> -->
-<!--           </dependency> -->
-       </dependencies>
-</project>
\ No newline at end of file
diff --git a/org.argeo.server.core/src/org/argeo/server/BooleanAnswer.java b/org.argeo.server.core/src/org/argeo/server/BooleanAnswer.java
deleted file mode 100644 (file)
index 2b7ffb2..0000000
+++ /dev/null
@@ -1,36 +0,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.
- */
-package org.argeo.server;
-
-
-/** Answer to an execution of a remote service which performed changes. */
-public class BooleanAnswer {
-       private Boolean value = Boolean.TRUE;
-
-       /** Canonical constructor */
-       public BooleanAnswer(Boolean status) {
-               this.value = status;
-       }
-
-       /** Empty constructor */
-       public BooleanAnswer() {
-       }
-
-       public Boolean getValue() {
-               return value;
-       }
-
-}
diff --git a/org.argeo.server.core/src/org/argeo/server/Deserializer.java b/org.argeo.server.core/src/org/argeo/server/Deserializer.java
deleted file mode 100644 (file)
index 4d7faf9..0000000
+++ /dev/null
@@ -1,22 +0,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.
- */
-package org.argeo.server;
-
-import java.io.Reader;
-
-public interface Deserializer {
-       public <T> T deserialize(Reader reader, Class<T> clss);
-}
diff --git a/org.argeo.server.core/src/org/argeo/server/DeserializingEditor.java b/org.argeo.server.core/src/org/argeo/server/DeserializingEditor.java
deleted file mode 100644 (file)
index 915b71c..0000000
+++ /dev/null
@@ -1,43 +0,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.
- */
-package org.argeo.server;
-
-import java.beans.PropertyEditorSupport;
-import java.io.StringReader;
-
-import org.apache.commons.io.IOUtils;
-
-public class DeserializingEditor extends PropertyEditorSupport {
-       private final Deserializer deserializer;
-       private final Class<?> targetClass;
-
-       public DeserializingEditor(Deserializer deserializer, Class<?> targetClass) {
-               super();
-               this.deserializer = deserializer;
-               this.targetClass = targetClass;
-       }
-
-       @Override
-       public void setAsText(String text) throws IllegalArgumentException {
-               StringReader reader = new StringReader(text);
-               try {
-                       setValue(deserializer.deserialize(reader, targetClass));
-               } finally {
-                       IOUtils.closeQuietly(reader);
-               }
-       }
-
-}
diff --git a/org.argeo.server.core/src/org/argeo/server/PrimitiveAnswer.java b/org.argeo.server.core/src/org/argeo/server/PrimitiveAnswer.java
deleted file mode 100644 (file)
index c69ffed..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *         http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.server;\r
-\r
-/**\r
- * Answer to a request to a remote service that sends back only one primitive\r
- */\r
-public class PrimitiveAnswer {\r
-\r
-       private Object primitive;\r
-\r
-       /** Canonical constructor */\r
-       public PrimitiveAnswer(Object primitive) {\r
-               this.primitive = primitive;\r
-       }\r
-\r
-       public Object getValue() {\r
-               return primitive;\r
-       }\r
-\r
-}\r
diff --git a/org.argeo.server.core/src/org/argeo/server/Serializer.java b/org.argeo.server.core/src/org/argeo/server/Serializer.java
deleted file mode 100644 (file)
index 890b17c..0000000
+++ /dev/null
@@ -1,26 +0,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.
- */
-package org.argeo.server;
-
-import java.io.Writer;
-
-public interface Serializer {
-       /** Will be removed soon. Use {@link #serialize(Object, Writer)} instead. */
-       @Deprecated
-       public void serialize(Writer writer, Object obj);
-
-       public void serialize(Object obj, Writer writer);
-}
diff --git a/org.argeo.server.core/src/org/argeo/server/ServerAnswer.java b/org.argeo.server.core/src/org/argeo/server/ServerAnswer.java
deleted file mode 100644 (file)
index 2f9cbee..0000000
+++ /dev/null
@@ -1,95 +0,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.
- */
-package org.argeo.server;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
-import org.apache.commons.io.IOUtils;
-import org.argeo.ArgeoException;
-
-/** Answer to an execution of a remote service which performed changes. */
-public class ServerAnswer {
-       public final static String OK = "OK";
-       public final static String ERROR = "ERROR";
-
-       private String status = OK;
-       private String message = "";
-
-       // TODO: add an exception field
-
-       /** Canonical constructor */
-       public ServerAnswer(String status, String message) {
-               setStatus(status);
-               if (message == null)
-                       throw new ArgeoException("Message cannot be null");
-               this.message = message;
-       }
-
-       /** Empty constructor */
-       public ServerAnswer() {
-       }
-
-       public String getStatus() {
-               return status;
-       }
-
-       public void setStatus(String status) {
-               if (status == null || (!status.equals(OK) && !status.equals(ERROR)))
-                       throw new ArgeoException("Bad status format: " + status);
-               this.status = status;
-       }
-
-       public String getMessage() {
-               return message;
-       }
-
-       public void setMessage(String message) {
-               this.message = message;
-       }
-
-       public Boolean isOk() {
-               return status.equals(OK);
-       }
-
-       public Boolean isError() {
-               return status.equals(ERROR);
-       }
-
-       public static ServerAnswer error(String message) {
-               return new ServerAnswer(ERROR, message);
-       }
-
-       public static ServerAnswer error(Throwable e) {
-               StringWriter writer = new StringWriter();
-               try {
-                       e.printStackTrace(new PrintWriter(writer));
-                       return new ServerAnswer(ERROR, writer.toString());
-               } finally {
-                       IOUtils.closeQuietly(writer);
-               }
-       }
-
-       public static ServerAnswer ok(String message) {
-               return new ServerAnswer(OK, message);
-       }
-
-       @Override
-       public String toString() {
-               return "ServerAnswer{status:" + status + ", message:" + message + "}";
-       }
-
-}
diff --git a/org.argeo.server.core/src/org/argeo/server/ServerSerializer.java b/org.argeo.server.core/src/org/argeo/server/ServerSerializer.java
deleted file mode 100644 (file)
index cdb1632..0000000
+++ /dev/null
@@ -1,24 +0,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.
- */
-package org.argeo.server;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-public interface ServerSerializer {
-       public void serialize(Object obj, HttpServletRequest request,
-                       HttpServletResponse response);
-}
diff --git a/org.argeo.server.core/src/org/argeo/server/backup/AbstractAtomicBackup.java b/org.argeo.server.core/src/org/argeo/server/backup/AbstractAtomicBackup.java
deleted file mode 100644 (file)
index 89c53e6..0000000
+++ /dev/null
@@ -1,98 +0,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.
- */
-package org.argeo.server.backup;
-
-import org.apache.commons.vfs2.FileObject;
-import org.apache.commons.vfs2.FileSystemManager;
-import org.apache.commons.vfs2.FileSystemOptions;
-import org.apache.commons.vfs2.provider.sftp.SftpFileSystemConfigBuilder;
-import org.argeo.ArgeoException;
-
-/**
- * Simplify atomic backups implementation, especially by managing VFS.
- */
-public abstract class AbstractAtomicBackup implements AtomicBackup {
-       private String name;
-       private String compression = "bz2";
-
-       protected abstract void writeBackup(FileObject targetFo);
-
-       public AbstractAtomicBackup() {
-       }
-
-       public AbstractAtomicBackup(String name) {
-               this.name = name;
-       }
-
-       public void init() {
-               if (name == null)
-                       throw new ArgeoException("Atomic backup name must be set");
-       }
-
-       public void destroy() {
-
-       }
-
-       @Override
-       public String backup(FileSystemManager fileSystemManager,
-                       String backupsBase, BackupContext backupContext,
-                       FileSystemOptions opts) {
-               if (name == null)
-                       throw new ArgeoException("Atomic backup name must be set");
-
-               FileObject targetFo = null;
-               try {
-                       if (backupsBase.startsWith("sftp:"))
-                               SftpFileSystemConfigBuilder.getInstance()
-                                               .setStrictHostKeyChecking(opts, "no");
-                       if (compression == null || compression.equals("none"))
-                               targetFo = fileSystemManager.resolveFile(backupsBase + '/'
-                                               + backupContext.getRelativeFolder() + '/' + name, opts);
-                       else if (compression.equals("bz2"))
-                               targetFo = fileSystemManager.resolveFile("bz2:" + backupsBase
-                                               + '/' + backupContext.getRelativeFolder() + '/' + name
-                                               + ".bz2" + "!" + name, opts);
-                       else if (compression.equals("gz"))
-                               targetFo = fileSystemManager.resolveFile("gz:" + backupsBase
-                                               + '/' + backupContext.getRelativeFolder() + '/' + name
-                                               + ".gz" + "!" + name, opts);
-                       else
-                               throw new ArgeoException("Unsupported compression "
-                                               + compression);
-
-                       writeBackup(targetFo);
-
-                       return targetFo.toString();
-               } catch (Exception e) {
-                       throw new ArgeoException("Cannot backup " + name + " to "
-                                       + targetFo, e);
-               } finally {
-                       BackupUtils.closeFOQuietly(targetFo);
-               }
-       }
-
-       public void setName(String name) {
-               this.name = name;
-       }
-
-       public String getName() {
-               return name;
-       }
-
-       public void setCompression(String compression) {
-               this.compression = compression;
-       }
-}
diff --git a/org.argeo.server.core/src/org/argeo/server/backup/AtomicBackup.java b/org.argeo.server.core/src/org/argeo/server/backup/AtomicBackup.java
deleted file mode 100644 (file)
index 1f3eb94..0000000
+++ /dev/null
@@ -1,37 +0,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.
- */
-package org.argeo.server.backup;
-
-import org.apache.commons.vfs2.FileSystemManager;
-import org.apache.commons.vfs2.FileSystemOptions;
-
-/** Performs the backup of a single component, typically a database dump */
-public interface AtomicBackup {
-       /** Name identifiying this backup */
-       public String getName();
-
-       /**
-        * Retrieves the data of the component in a format that allows to restore
-        * the component
-        * 
-        * @param backupContext
-        *            the context of this backup
-        * @return the VFS URI of the generated file or directory
-        */
-       public String backup(FileSystemManager fileSystemManager,
-                       String backupsBase, BackupContext backupContext,
-                       FileSystemOptions opts);
-}
diff --git a/org.argeo.server.core/src/org/argeo/server/backup/BackupContext.java b/org.argeo.server.core/src/org/argeo/server/backup/BackupContext.java
deleted file mode 100644 (file)
index 5f6442f..0000000
+++ /dev/null
@@ -1,40 +0,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.
- */
-package org.argeo.server.backup;
-
-import java.text.DateFormat;
-import java.util.Date;
-
-/**
- * Transient information of a given backup, centralizing common information such
- * as timestamp and location.
- */
-public interface BackupContext {
-       /** Backup date */
-       public Date getTimestamp();
-
-       /** Formatted backup date */
-       public String getTimestampAsString();
-
-       /** System name */
-       public String getSystemName();
-
-       /** Local base */
-       public String getRelativeFolder();
-
-       /** Date format */
-       public DateFormat getDateFormat();
-}
diff --git a/org.argeo.server.core/src/org/argeo/server/backup/BackupFileSystemManager.java b/org.argeo.server.core/src/org/argeo/server/backup/BackupFileSystemManager.java
deleted file mode 100644 (file)
index c963c30..0000000
+++ /dev/null
@@ -1,52 +0,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.
- */
-package org.argeo.server.backup;
-
-import org.apache.commons.vfs2.FileSystemException;
-import org.apache.commons.vfs2.impl.DefaultFileSystemManager;
-import org.apache.commons.vfs2.provider.bzip2.Bzip2FileProvider;
-import org.apache.commons.vfs2.provider.ftp.FtpFileProvider;
-import org.apache.commons.vfs2.provider.gzip.GzipFileProvider;
-import org.apache.commons.vfs2.provider.local.DefaultLocalFileProvider;
-import org.apache.commons.vfs2.provider.ram.RamFileProvider;
-import org.apache.commons.vfs2.provider.sftp.SftpFileProvider;
-import org.apache.commons.vfs2.provider.url.UrlFileProvider;
-import org.argeo.ArgeoException;
-
-/**
- * Programatically configured VFS file system manager which can be declared as a
- * bean and associated with a life cycle (methods
- * {@link DefaultFileSystemManager#init()} and
- * {@link DefaultFileSystemManager#closet()}). Supports bz2, file, ram, gzip,
- * ftp, sftp
- */
-public class BackupFileSystemManager extends DefaultFileSystemManager {
-
-       public BackupFileSystemManager() {
-               super();
-               try {
-                       addProvider("file", new DefaultLocalFileProvider());
-                       addProvider("bz2", new Bzip2FileProvider());
-                       addProvider("ftp", new FtpFileProvider());
-                       addProvider("sftp", new SftpFileProvider());
-                       addProvider("gzip", new GzipFileProvider());
-                       addProvider("ram", new RamFileProvider());
-                       setDefaultProvider(new UrlFileProvider());
-               } catch (FileSystemException e) {
-                       throw new ArgeoException("Cannot configure backup file provider", e);
-               }
-       }
-}
diff --git a/org.argeo.server.core/src/org/argeo/server/backup/BackupPurge.java b/org.argeo.server.core/src/org/argeo/server/backup/BackupPurge.java
deleted file mode 100644 (file)
index 4937b8e..0000000
+++ /dev/null
@@ -1,33 +0,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.
- */
-package org.argeo.server.backup;
-
-import java.text.DateFormat;
-
-import org.apache.commons.vfs2.FileSystemManager;
-import org.apache.commons.vfs2.FileSystemOptions;
-
-/** Purges previous backups */
-public interface BackupPurge {
-       /**
-        * Purge the backups identified by these arguments. Although these are the
-        * same fields as a {@link BackupContext} we don't pass it as argument since
-        * we want to use this interface to purge remote backups as well (that is,
-        * with a different base), or outside the scope of a running backup.
-        */
-       public void purge(FileSystemManager fileSystemManager, String base,
-                       String name, DateFormat dateFormat, FileSystemOptions opts);
-}
diff --git a/org.argeo.server.core/src/org/argeo/server/backup/BackupUtils.java b/org.argeo.server.core/src/org/argeo/server/backup/BackupUtils.java
deleted file mode 100644 (file)
index 4eb3830..0000000
+++ /dev/null
@@ -1,36 +0,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.
- */
-package org.argeo.server.backup;
-
-import org.apache.commons.vfs2.FileObject;
-
-/** Backup utilities */
-public class BackupUtils {
-       /** Close a file object quietly even if it is null or throws an exception. */
-       public static void closeFOQuietly(FileObject fo) {
-               if (fo != null) {
-                       try {
-                               fo.close();
-                       } catch (Exception e) {
-                               // silent
-                       }
-               }
-       }
-       
-       /** Prevents instantiation */
-       private BackupUtils() {
-       }
-}
diff --git a/org.argeo.server.core/src/org/argeo/server/backup/MySqlBackup.java b/org.argeo.server.core/src/org/argeo/server/backup/MySqlBackup.java
deleted file mode 100644 (file)
index 4eb662c..0000000
+++ /dev/null
@@ -1,74 +0,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.
- */
-package org.argeo.server.backup;
-
-import org.apache.commons.vfs2.FileObject;
-
-/** Backups a MySQL database using mysqldump. */
-public class MySqlBackup extends OsCallBackup {
-       private String mysqldumpLocation = "/usr/bin/mysqldump";
-
-       private String dbUser;
-       private String dbPassword;
-       private String dbName;
-
-       public MySqlBackup() {
-       }
-
-       public MySqlBackup(String dbUser, String dbPassword, String dbName) {
-               this.dbUser = dbUser;
-               this.dbPassword = dbPassword;
-               this.dbName = dbName;
-               init();
-       }
-
-       @Override
-       public void init() {
-               if (getName() == null)
-                       setName(dbName + ".mysql");
-               super.init();
-       }
-
-       @Override
-       public void writeBackup(FileObject targetFo) {
-               if (getCommand() == null)
-                       setCommand(mysqldumpLocation
-                                       + " --lock-tables --add-locks --add-drop-table"
-                                       + " -u ${dbUser} --password=${dbPassword} --databases ${dbName}");
-               getVariables().put("dbUser", dbUser);
-               getVariables().put("dbPassword", dbPassword);
-               getVariables().put("dbName", dbName);
-
-               super.writeBackup(targetFo);
-       }
-
-       public void setDbUser(String dbUser) {
-               this.dbUser = dbUser;
-       }
-
-       public void setDbPassword(String dbPassword) {
-               this.dbPassword = dbPassword;
-       }
-
-       public void setDbName(String dbName) {
-               this.dbName = dbName;
-       }
-
-       public void setMysqldumpLocation(String mysqldumpLocation) {
-               this.mysqldumpLocation = mysqldumpLocation;
-       }
-
-}
diff --git a/org.argeo.server.core/src/org/argeo/server/backup/OpenLdapBackup.java b/org.argeo.server.core/src/org/argeo/server/backup/OpenLdapBackup.java
deleted file mode 100644 (file)
index bfebe26..0000000
+++ /dev/null
@@ -1,62 +0,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.
- */
-package org.argeo.server.backup;
-
-import org.apache.commons.vfs2.FileObject;
-import org.argeo.ArgeoException;
-
-/** Backups an OpenLDAP server using slapcat */
-public class OpenLdapBackup extends OsCallBackup {
-       private String slapcatLocation = "/usr/sbin/slapcat";
-       private String slapdConfLocation = "/etc/openldap/slapd.conf";
-       private String baseDn;
-
-       public OpenLdapBackup() {
-               super();
-       }
-
-       public OpenLdapBackup(String baseDn) {
-               super();
-               this.baseDn = baseDn;
-       }
-
-       @Override
-       public void writeBackup(FileObject targetFo) {
-               if (baseDn == null)
-                       throw new ArgeoException("Base DN must be set");
-
-               if (getCommand() == null)
-                       setCommand(slapcatLocation
-                                       + " -f ${slapdConfLocation} -b '${baseDn}'");
-               getVariables().put("slapdConfLocation", slapdConfLocation);
-               getVariables().put("baseDn", baseDn);
-
-               super.writeBackup(targetFo);
-       }
-
-       public void setSlapcatLocation(String slapcatLocation) {
-               this.slapcatLocation = slapcatLocation;
-       }
-
-       public void setSlapdConfLocation(String slapdConfLocation) {
-               this.slapdConfLocation = slapdConfLocation;
-       }
-
-       public void setBaseDn(String baseDn) {
-               this.baseDn = baseDn;
-       }
-
-}
diff --git a/org.argeo.server.core/src/org/argeo/server/backup/OsCallBackup.java b/org.argeo.server.core/src/org/argeo/server/backup/OsCallBackup.java
deleted file mode 100644 (file)
index 788ba52..0000000
+++ /dev/null
@@ -1,135 +0,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.
- */
-package org.argeo.server.backup;
-
-import java.io.ByteArrayOutputStream;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.commons.exec.CommandLine;
-import org.apache.commons.exec.DefaultExecutor;
-import org.apache.commons.exec.ExecuteException;
-import org.apache.commons.exec.ExecuteStreamHandler;
-import org.apache.commons.exec.Executor;
-import org.apache.commons.exec.PumpStreamHandler;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.commons.vfs2.FileContent;
-import org.apache.commons.vfs2.FileObject;
-import org.argeo.ArgeoException;
-
-/**
- * Runs an OS command and save its standard output as a file. Typically used for
- * MySQL or OpenLDAP dumps.
- */
-public class OsCallBackup extends AbstractAtomicBackup {
-       private final static Log log = LogFactory.getLog(OsCallBackup.class);
-
-       private String command;
-       private Map<String, String> variables = new HashMap<String, String>();
-       private Executor executor = new DefaultExecutor();
-
-       private Map<String, String> environment = new HashMap<String, String>();
-
-       /** Name of the sudo user, root if "", not sudo if null */
-       private String sudo = null;
-
-       public OsCallBackup() {
-       }
-
-       public OsCallBackup(String name) {
-               super(name);
-       }
-
-       public OsCallBackup(String name, String command) {
-               super(name);
-               this.command = command;
-       }
-
-       @Override
-       public void writeBackup(FileObject targetFo) {
-               String commandToUse = command;
-
-               // sudo
-               if (sudo != null) {
-                       if (sudo.equals(""))
-                               commandToUse = "sudo " + commandToUse;
-                       else
-                               commandToUse = "sudo -u " + sudo + " " + commandToUse;
-               }
-
-               CommandLine commandLine = CommandLine.parse(commandToUse, variables);
-               ByteArrayOutputStream errBos = new ByteArrayOutputStream();
-               if (log.isTraceEnabled())
-                       log.trace(commandLine.toString());
-
-               try {
-                       // stdout
-                       FileContent targetContent = targetFo.getContent();
-                       // stderr
-                       ExecuteStreamHandler streamHandler = new PumpStreamHandler(
-                                       targetContent.getOutputStream(), errBos);
-                       executor.setStreamHandler(streamHandler);
-                       executor.execute(commandLine, environment);
-               } catch (ExecuteException e) {
-                       byte[] err = errBos.toByteArray();
-                       String errStr = new String(err);
-                       throw new ArgeoException("Process " + commandLine + " failed ("
-                                       + e.getExitValue() + "): " + errStr, e);
-               } catch (Exception e) {
-                       byte[] err = errBos.toByteArray();
-                       String errStr = new String(err);
-                       throw new ArgeoException("Process " + commandLine + " failed: "
-                                       + errStr, e);
-               } finally {
-                       IOUtils.closeQuietly(errBos);
-               }
-       }
-
-       public void setCommand(String command) {
-               this.command = command;
-       }
-
-       protected String getCommand() {
-               return command;
-       }
-
-       /**
-        * A reference to the environment variables that will be passed to the
-        * process. Empty by default.
-        */
-       protected Map<String, String> getEnvironment() {
-               return environment;
-       }
-
-       protected Map<String, String> getVariables() {
-               return variables;
-       }
-
-       public void setVariables(Map<String, String> variables) {
-               this.variables = variables;
-       }
-
-       public void setExecutor(Executor executor) {
-               this.executor = executor;
-       }
-
-       public void setSudo(String sudo) {
-               this.sudo = sudo;
-       }
-
-}
diff --git a/org.argeo.server.core/src/org/argeo/server/backup/PostgreSqlBackup.java b/org.argeo.server.core/src/org/argeo/server/backup/PostgreSqlBackup.java
deleted file mode 100644 (file)
index 805954b..0000000
+++ /dev/null
@@ -1,85 +0,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.
- */
-package org.argeo.server.backup;
-
-import org.apache.commons.vfs2.FileObject;
-
-/** Backups a PostgreSQL database using pg_dump. */
-public class PostgreSqlBackup extends OsCallBackup {
-       /**
-        * PostgreSQL password environment variable (see
-        * http://stackoverflow.com/questions
-        * /2893954/how-to-pass-in-password-to-pg-dump)
-        */
-       protected final static String PGPASSWORD = "PGPASSWORD";
-
-       private String pgDumpLocation = "/usr/bin/pg_dump";
-
-       private String dbUser;
-       private String dbPassword;
-       private String dbName;
-
-       public PostgreSqlBackup() {
-               super();
-       }
-
-       public PostgreSqlBackup(String dbUser, String dbPassword, String dbName) {
-               this.dbUser = dbUser;
-               this.dbPassword = dbPassword;
-               this.dbName = dbName;
-               init();
-       }
-
-       @Override
-       public void init() {
-               // disable compression since pg_dump is used with -Fc option
-               setCompression(null);
-
-               if (getName() == null)
-                       setName(dbName + ".pgdump");
-               super.init();
-       }
-
-       @Override
-       public void writeBackup(FileObject targetFo) {
-               if (getCommand() == null) {
-                       getEnvironment().put(PGPASSWORD, dbPassword);
-                       setCommand(pgDumpLocation + " -Fc" + " -U ${dbUser} ${dbName}");
-               }
-               getVariables().put("dbUser", dbUser);
-               getVariables().put("dbPassword", dbPassword);
-               getVariables().put("dbName", dbName);
-
-               super.writeBackup(targetFo);
-       }
-
-       public void setDbUser(String dbUser) {
-               this.dbUser = dbUser;
-       }
-
-       public void setDbPassword(String dbPassword) {
-               this.dbPassword = dbPassword;
-       }
-
-       public void setDbName(String dbName) {
-               this.dbName = dbName;
-       }
-
-       public void setPgDumpLocation(String mysqldumpLocation) {
-               this.pgDumpLocation = mysqldumpLocation;
-       }
-
-}
diff --git a/org.argeo.server.core/src/org/argeo/server/backup/SimpleBackupContext.java b/org.argeo.server.core/src/org/argeo/server/backup/SimpleBackupContext.java
deleted file mode 100644 (file)
index 33e45e6..0000000
+++ /dev/null
@@ -1,63 +0,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.
- */
-package org.argeo.server.backup;
-
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-import org.apache.commons.vfs2.FileSystemManager;
-
-/** Simple implementation of a backup context */
-public class SimpleBackupContext implements BackupContext {
-       private DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmm");
-       private final Date timestamp;
-       private final String name;
-
-       private final FileSystemManager fileSystemManager;
-
-       public SimpleBackupContext(FileSystemManager fileSystemManager,
-                       String backupsBase, String name) {
-               this.name = name;
-               this.timestamp = new Date();
-               this.fileSystemManager = fileSystemManager;
-       }
-
-       public Date getTimestamp() {
-               return timestamp;
-       }
-
-       public String getTimestampAsString() {
-               return dateFormat.format(timestamp);
-       }
-
-       public String getSystemName() {
-               return name;
-       }
-
-       public String getRelativeFolder() {
-               return name + '/' + getTimestampAsString();
-       }
-
-       public DateFormat getDateFormat() {
-               return dateFormat;
-       }
-
-       public FileSystemManager getFileSystemManager() {
-               return fileSystemManager;
-       }
-
-}
diff --git a/org.argeo.server.core/src/org/argeo/server/backup/SimpleBackupPurge.java b/org.argeo.server.core/src/org/argeo/server/backup/SimpleBackupPurge.java
deleted file mode 100644 (file)
index ad269f7..0000000
+++ /dev/null
@@ -1,90 +0,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.
- */
-package org.argeo.server.backup;
-
-import java.text.DateFormat;
-import java.util.Date;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.commons.vfs2.FileObject;
-import org.apache.commons.vfs2.FileSystemManager;
-import org.apache.commons.vfs2.FileSystemOptions;
-import org.apache.commons.vfs2.Selectors;
-import org.argeo.ArgeoException;
-import org.joda.time.DateTime;
-import org.joda.time.Period;
-
-/** Simple backup purge which keeps backups only for a given number of days */
-public class SimpleBackupPurge implements BackupPurge {
-       private final static Log log = LogFactory.getLog(SimpleBackupPurge.class);
-
-       private Integer daysKept = 30;
-
-       @Override
-       public void purge(FileSystemManager fileSystemManager, String base,
-                       String name, DateFormat dateFormat, FileSystemOptions opts) {
-               try {
-                       DateTime nowDt = new DateTime();
-                       FileObject baseFo = fileSystemManager.resolveFile(
-                                       base + '/' + name, opts);
-
-                       SortedMap<DateTime, FileObject> toDelete = new TreeMap<DateTime, FileObject>();
-                       int backupCount = 0;
-
-                       // make sure base dir exists
-                       baseFo.createFolder();
-
-                       // scan backups and list those which should be deleted
-                       for (FileObject backupFo : baseFo.getChildren()) {
-                               String backupName = backupFo.getName().getBaseName();
-                               Date backupDate = dateFormat.parse(backupName);
-                               backupCount++;
-
-                               DateTime backupDt = new DateTime(backupDate.getTime());
-                               Period sinceThen = new Period(backupDt, nowDt);
-                               int days = sinceThen.getDays();
-                               // int days = sinceThen.getMinutes();
-                               if (days > daysKept) {
-                                       toDelete.put(backupDt, backupFo);
-                               }
-                       }
-
-                       if (toDelete.size() != 0 && toDelete.size() == backupCount) {
-                               // all backups would be deleted
-                               // but we want to keep at least one
-                               DateTime lastBackupDt = toDelete.firstKey();
-                               FileObject keptFo = toDelete.remove(lastBackupDt);
-                               log.warn("Backup " + keptFo
-                                               + " kept although it is older than " + daysKept
-                                               + " days.");
-                       }
-
-                       // delete old backups
-                       for (FileObject backupFo : toDelete.values()) {
-                               backupFo.delete(Selectors.SELECT_ALL);
-                               if (log.isDebugEnabled())
-                                       log.debug("Deleted backup " + backupFo);
-                       }
-               } catch (Exception e) {
-                       throw new ArgeoException("Could not purge previous backups", e);
-               }
-
-       }
-
-}
diff --git a/org.argeo.server.core/src/org/argeo/server/backup/SvnBackup.java b/org.argeo.server.core/src/org/argeo/server/backup/SvnBackup.java
deleted file mode 100644 (file)
index d157ecf..0000000
+++ /dev/null
@@ -1,70 +0,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.
- */
-package org.argeo.server.backup;
-
-import java.io.File;
-
-import org.apache.commons.vfs2.FileObject;
-
-/** Backups a Subversion repository using svnadmin. */
-public class SvnBackup extends OsCallBackup {
-       private String svnadminLocation = "/usr/bin/svnadmin";
-
-       private String repoLocation;
-       private String repoName;
-
-       public SvnBackup() {
-       }
-
-       public SvnBackup(String repoLocation) {
-               this.repoLocation = repoLocation;
-               init();
-       }
-
-       @Override
-       public void init() {
-               // use directory as repo name
-               if (repoName == null)
-                       repoName = new File(repoLocation).getName();
-
-               if (getName() == null)
-                       setName(repoName + ".svndump");
-               super.init();
-       }
-
-       @Override
-       public void writeBackup(FileObject targetFo) {
-               if (getCommand() == null) {
-                       setCommand(svnadminLocation + " dump " + " ${repoLocation}");
-               }
-               getVariables().put("repoLocation", repoLocation);
-
-               super.writeBackup(targetFo);
-       }
-
-       public void setRepoLocation(String repoLocation) {
-               this.repoLocation = repoLocation;
-       }
-
-       public void setRepoName(String repoName) {
-               this.repoName = repoName;
-       }
-
-       public void setSvnadminLocation(String mysqldumpLocation) {
-               this.svnadminLocation = mysqldumpLocation;
-       }
-
-}
diff --git a/org.argeo.server.core/src/org/argeo/server/backup/SystemBackup.java b/org.argeo.server.core/src/org/argeo/server/backup/SystemBackup.java
deleted file mode 100644 (file)
index b7ce029..0000000
+++ /dev/null
@@ -1,233 +0,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.
- */
-package org.argeo.server.backup;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.commons.vfs2.FileObject;
-import org.apache.commons.vfs2.FileSystemException;
-import org.apache.commons.vfs2.FileSystemManager;
-import org.apache.commons.vfs2.FileSystemOptions;
-import org.apache.commons.vfs2.Selectors;
-import org.apache.commons.vfs2.UserAuthenticator;
-import org.apache.commons.vfs2.auth.StaticUserAuthenticator;
-import org.apache.commons.vfs2.impl.DefaultFileSystemConfigBuilder;
-import org.apache.commons.vfs2.impl.StandardFileSystemManager;
-import org.argeo.ArgeoException;
-
-/**
- * Combines multiple backups and transfer them to a remote location. Purges
- * remote and local data based on certain criteria.
- */
-public class SystemBackup implements Runnable {
-       private final static Log log = LogFactory.getLog(SystemBackup.class);
-
-       private FileSystemManager fileSystemManager;
-       private UserAuthenticator userAuthenticator = null;
-
-       private String backupsBase;
-       private String systemName;
-
-       private List<AtomicBackup> atomicBackups = new ArrayList<AtomicBackup>();
-       private BackupPurge backupPurge = new SimpleBackupPurge();
-
-       private Map<String, UserAuthenticator> remoteBases = new HashMap<String, UserAuthenticator>();
-
-       @Override
-       public void run() {
-               if (atomicBackups.size() == 0)
-                       throw new ArgeoException("No atomic backup listed");
-               List<String> failures = new ArrayList<String>();
-
-               SimpleBackupContext backupContext = new SimpleBackupContext(
-                               fileSystemManager, backupsBase, systemName);
-
-               // purge older backups
-               FileSystemOptions opts = new FileSystemOptions();
-               try {
-                       DefaultFileSystemConfigBuilder.getInstance().setUserAuthenticator(
-                                       opts, userAuthenticator);
-               } catch (FileSystemException e) {
-                       throw new ArgeoException("Cannot create authentication", e);
-               }
-
-               try {
-
-                       backupPurge.purge(fileSystemManager, backupsBase, systemName,
-                                       backupContext.getDateFormat(), opts);
-               } catch (Exception e) {
-                       failures.add("Purge " + backupsBase + " failed: " + e.getMessage());
-                       log.error("Purge of " + backupsBase + " failed", e);
-               }
-
-               // perform backup
-               for (AtomicBackup atomickBackup : atomicBackups) {
-                       try {
-                               String target = atomickBackup.backup(fileSystemManager,
-                                               backupsBase, backupContext, opts);
-                               if (log.isDebugEnabled())
-                                       log.debug("Performed backup " + target);
-                       } catch (Exception e) {
-                               String msg = "Atomic backup " + atomickBackup.getName()
-                                               + " failed: " + ArgeoException.chainCausesMessages(e);
-                               failures.add(msg);
-                               log.error(msg);
-                               if (log.isTraceEnabled())
-                                       log.trace(
-                                                       "Stacktrace of atomic backup "
-                                                                       + atomickBackup.getName() + " failure.", e);
-                       }
-               }
-
-               // dispatch to remote
-               for (String remoteBase : remoteBases.keySet()) {
-                       FileObject localBaseFo = null;
-                       FileObject remoteBaseFo = null;
-                       UserAuthenticator auth = remoteBases.get(remoteBase);
-
-                       // authentication
-                       FileSystemOptions remoteOpts = new FileSystemOptions();
-                       try {
-                               DefaultFileSystemConfigBuilder.getInstance()
-                                               .setUserAuthenticator(remoteOpts, auth);
-                               backupPurge.purge(fileSystemManager, remoteBase, systemName,
-                                               backupContext.getDateFormat(), remoteOpts);
-                       } catch (Exception e) {
-                               failures.add("Purge " + remoteBase + " failed: "
-                                               + e.getMessage());
-                               log.error("Cannot purge " + remoteBase, e);
-                       }
-
-                       try {
-                               localBaseFo = fileSystemManager.resolveFile(backupsBase + '/'
-                                               + backupContext.getRelativeFolder(), opts);
-                               remoteBaseFo = fileSystemManager.resolveFile(remoteBase + '/'
-                                               + backupContext.getRelativeFolder(), remoteOpts);
-                               remoteBaseFo.copyFrom(localBaseFo, Selectors.SELECT_ALL);
-                               if (log.isDebugEnabled())
-                                       log.debug("Copied backup to " + remoteBaseFo + " from "
-                                                       + localBaseFo);
-                               // }
-                       } catch (Exception e) {
-                               failures.add("Dispatch to " + remoteBase + " failed: "
-                                               + e.getMessage());
-                               log.error(
-                                               "Cannot dispatch backups from "
-                                                               + backupContext.getRelativeFolder() + " to "
-                                                               + remoteBase, e);
-                       }
-                       BackupUtils.closeFOQuietly(localBaseFo);
-                       BackupUtils.closeFOQuietly(remoteBaseFo);
-               }
-
-               int failureCount = 0;
-               if (failures.size() > 0) {
-                       StringBuffer buf = new StringBuffer();
-                       for (String failure : failures) {
-                               buf.append('\n').append(failureCount).append(" - ")
-                                               .append(failure);
-                               failureCount++;
-                       }
-                       throw new ArgeoException(failureCount
-                                       + " error(s) when running the backup,"
-                                       + " check the logs and the backups as soon as possible."
-                                       + buf);
-               }
-       }
-
-       public void setFileSystemManager(FileSystemManager fileSystemManager) {
-               this.fileSystemManager = fileSystemManager;
-       }
-
-       public void setBackupsBase(String backupsBase) {
-               this.backupsBase = backupsBase;
-       }
-
-       public void setSystemName(String name) {
-               this.systemName = name;
-       }
-
-       public void setAtomicBackups(List<AtomicBackup> atomicBackups) {
-               this.atomicBackups = atomicBackups;
-       }
-
-       public void setBackupPurge(BackupPurge backupPurge) {
-               this.backupPurge = backupPurge;
-       }
-
-       public void setUserAuthenticator(UserAuthenticator userAuthenticator) {
-               this.userAuthenticator = userAuthenticator;
-       }
-
-       public void setRemoteBases(Map<String, UserAuthenticator> remoteBases) {
-               this.remoteBases = remoteBases;
-       }
-
-       public static void main(String args[]) {
-               while (true) {
-                       try {
-                               StandardFileSystemManager fsm = new StandardFileSystemManager();
-                               fsm.init();
-
-                               SystemBackup systemBackup = new SystemBackup();
-                               systemBackup.setSystemName("mySystem");
-                               systemBackup
-                                               .setBackupsBase("/home/mbaudier/dev/src/commons/server/runtime/org.argeo.server.core/target");
-                               systemBackup.setFileSystemManager(fsm);
-
-                               List<AtomicBackup> atomicBackups = new ArrayList<AtomicBackup>();
-
-                               MySqlBackup mySqlBackup = new MySqlBackup("root", "", "test");
-                               atomicBackups.add(mySqlBackup);
-                               PostgreSqlBackup postgreSqlBackup = new PostgreSqlBackup(
-                                               "argeo", "argeo", "gis_template");
-                               atomicBackups.add(postgreSqlBackup);
-                               SvnBackup svnBackup = new SvnBackup(
-                                               "/home/mbaudier/tmp/testsvnrepo");
-                               atomicBackups.add(svnBackup);
-
-                               systemBackup.setAtomicBackups(atomicBackups);
-
-                               Map<String, UserAuthenticator> remoteBases = new HashMap<String, UserAuthenticator>();
-                               StaticUserAuthenticator userAuthenticator = new StaticUserAuthenticator(
-                                               null, "demo", "demo");
-                               remoteBases.put("sftp://localhost/home/mbaudier/test",
-                                               userAuthenticator);
-                               systemBackup.setRemoteBases(remoteBases);
-
-                               systemBackup.run();
-
-                               fsm.close();
-                       } catch (FileSystemException e) {
-                               // TODO Auto-generated catch block
-                               e.printStackTrace();
-                               System.exit(1);
-                       }
-
-                       // wait
-                       try {
-                               Thread.sleep(120 * 1000);
-                       } catch (InterruptedException e) {
-                               e.printStackTrace();
-                       }
-               }
-       }
-}
diff --git a/org.argeo.server.core/src/org/argeo/server/dao/AbstractMemoryDaoSupport.java b/org.argeo.server.core/src/org/argeo/server/dao/AbstractMemoryDaoSupport.java
deleted file mode 100644 (file)
index f9af51b..0000000
+++ /dev/null
@@ -1,264 +0,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.
- */
-package org.argeo.server.dao;
-
-import java.beans.PropertyEditor;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.ArgeoException;
-import org.springframework.beans.BeanWrapper;
-import org.springframework.beans.BeanWrapperImpl;
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-import org.springframework.core.io.Resource;
-
-public abstract class AbstractMemoryDaoSupport implements LightDaoSupport,
-               ApplicationContextAware, InitializingBean {
-       private final static Log log = LogFactory
-                       .getLog(AbstractMemoryDaoSupport.class);
-
-       private ClassLoader classLoader = getClass().getClassLoader();
-       private ApplicationContext applicationContext;
-       private List<Class<?>> additionalClasses = new ArrayList<Class<?>>();
-
-       private Map<Class<?>, Map<Object, Object>> model = new HashMap<Class<?>, Map<Object, Object>>();
-
-       private Map<String, Object> externalRefs = new HashMap<String, Object>();
-
-       private List<String> scannedPackages = new ArrayList<String>();
-
-       private List<Resource> resources = new ArrayList<Resource>();
-
-       private Map<Class<?>, PropertyEditor> customEditors = new HashMap<Class<?>, PropertyEditor>();;
-
-       protected abstract void load(InputStream in, List<Reference> references);
-
-       protected abstract Object findInternalRef(Reference reference);
-
-       public void afterPropertiesSet() throws Exception {
-               init();
-       }
-
-       public void init() {
-               for (PropertyEditor propertyEditor : customEditors.values())
-                       if (propertyEditor instanceof LightDaoAware) {
-                               ((LightDaoAware) propertyEditor).setLightDaoSupport(this);
-                       }
-
-               // Load data
-               List<Reference> references = new ArrayList<Reference>();
-
-               for (Resource res : resources) {
-                       InputStream in = null;
-                       try {
-                               in = res.getInputStream();
-                               load(in, references);
-                       } catch (Exception e) {
-                               throw new ArgeoException("Cannot load stream", e);
-                       } finally {
-                               IOUtils.closeQuietly(in);
-                       }
-               }
-
-               // Inject references
-               for (Reference ref : references) {
-                       injectReference(ref);
-               }
-               if (log.isDebugEnabled())
-                       log.debug(references.size() + " references linked");
-       }
-
-       public List<Class<?>> getSupportedClasses() {
-               List<Class<?>> res = new ArrayList<Class<?>>();
-               res.addAll(additionalClasses);
-               res.addAll(model.keySet());
-               return res;
-       }
-
-       protected void injectReference(Reference reference) {
-               BeanWrapper bw = new BeanWrapperImpl(reference.object);
-               Object targetObject;
-               if (reference.getExternalRef() != null) {
-                       String ref = reference.getExternalRef();
-                       if (externalRefs.containsKey(ref))
-                               targetObject = externalRefs.get(ref);
-                       else if (applicationContext != null)
-                               targetObject = applicationContext.getBean(ref);
-                       else {
-                               targetObject = null;
-                               log.warn("Ref " + ref + " not found");
-                       }
-               } else {
-                       targetObject = findInternalRef(reference);
-               }
-               bw.setPropertyValue(reference.property, targetObject);
-
-       }
-
-       protected BeanWrapper newBeanWrapper(Class<?> targetClass) {
-               BeanWrapperImpl bw = new BeanWrapperImpl(targetClass);
-               for (Class<?> clss : customEditors.keySet())
-                       bw.registerCustomEditor(clss, customEditors.get(clss));
-               return bw;
-       }
-
-       @SuppressWarnings("unchecked")
-       public <T> T getByKey(Class<T> clss, Object key) {
-               if (key == null)
-                       throw new ArgeoException("Key is null for " + clss);
-               return (T) model.get(findClass(clss)).get(key);
-       }
-
-       /**
-        * Slow.
-        * 
-        * @return the first found
-        */
-       public <T> T getByField(Class<T> clss, String field, Object value) {
-               List<T> all = list(clss, null);
-               T res = null;
-               for (T obj : all) {
-                       if (new BeanWrapperImpl(obj).getPropertyValue(field).equals(value)) {
-                               res = obj;
-                               break;
-                       }
-               }
-               return res;
-       }
-
-       @SuppressWarnings({ "unchecked", "rawtypes" })
-       public <T> List<T> list(Class<T> clss, Object filter) {
-               List<T> res = new ArrayList<T>();
-
-               Class classToUse = findClass(clss);
-               if (classToUse != null)
-                       res.addAll((Collection<T>) model.get(classToUse).values());
-
-               if (applicationContext != null)
-                       res.addAll(applicationContext.getBeansOfType(clss).values());
-
-               return res;
-       }
-
-       @SuppressWarnings({ "unchecked", "rawtypes" })
-       protected Class findClass(Class parent) {
-               if (model.containsKey(parent))
-                       return parent;
-
-               for (Class clss : model.keySet()) {
-                       if (parent.isAssignableFrom(clss))
-                               return clss;// return the first found
-               }
-               if (log.isDebugEnabled())
-                       log.warn("No class found for " + parent.getName());
-               return null;
-       }
-
-       public void setApplicationContext(ApplicationContext applicationContext)
-                       throws BeansException {
-               this.applicationContext = applicationContext;
-       }
-
-       /**
-        * When it should be stored under a different class (e.g. super class or
-        * interface)
-        */
-       public void saveOrUpdate(Object key, Object value, Class<?> clss) {
-               if (!model.containsKey(clss))
-                       model.put(clss, new TreeMap<Object, Object>());
-               model.get(clss).put(key, value);
-       }
-
-       protected ClassLoader getClassLoader() {
-               return classLoader;
-       }
-
-       public void setExternalRefs(Map<String, Object> externalRefs) {
-               this.externalRefs = externalRefs;
-       }
-
-       public Map<String, Object> getExternalRefs() {
-               return externalRefs;
-       }
-
-       public void setScannedPackages(List<String> scannedPackages) {
-               this.scannedPackages = scannedPackages;
-       }
-
-       public List<String> getScannedPackages() {
-               return scannedPackages;
-       }
-
-       public void setResources(List<Resource> workbooks) {
-               this.resources = workbooks;
-       }
-
-       public List<Resource> getResources() {
-               return resources;
-       }
-
-       public void setClassLoader(ClassLoader classLoader) {
-               this.classLoader = classLoader;
-       }
-
-       public List<Class<?>> getAdditionalClasses() {
-               return additionalClasses;
-       }
-
-       public void setAdditionalClasses(List<Class<?>> additionalClasses) {
-               this.additionalClasses = additionalClasses;
-       }
-
-       public void setCustomEditors(Map<Class<?>, PropertyEditor> propertyEditors) {
-               this.customEditors = propertyEditors;
-       }
-
-       protected static class Reference {
-               private Object object;
-               private String property;
-               private String externalRef;
-
-               public Reference(Object object, String property, String externalRef) {
-                       this.object = object;
-                       this.property = property;
-                       this.externalRef = externalRef;
-               }
-
-               public Object getObject() {
-                       return object;
-               }
-
-               public String getProperty() {
-                       return property;
-               }
-
-               public String getExternalRef() {
-                       return externalRef;
-               }
-
-       }
-}
diff --git a/org.argeo.server.core/src/org/argeo/server/dao/AbstractTabularDaoSupport.java b/org.argeo.server.core/src/org/argeo/server/dao/AbstractTabularDaoSupport.java
deleted file mode 100644 (file)
index 1ca5a10..0000000
+++ /dev/null
@@ -1,100 +0,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.
- */
-package org.argeo.server.dao;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.ArgeoException;
-
-public abstract class AbstractTabularDaoSupport extends
-               AbstractMemoryDaoSupport {
-       private final static Log log = LogFactory
-                       .getLog(AbstractTabularDaoSupport.class);
-       
-       private Map<String, List<Object>> tabularView = new HashMap<String, List<Object>>();
-
-       @Override
-       protected Object findInternalRef(Reference reference) {
-               TabularInternalReference tabReference = (TabularInternalReference) reference;
-               return getFromTabularView(tabReference.getTargetTableName(),
-                               tabReference.getTargetRow());
-       }
-
-       protected Object getFromTabularView(String tableName, Integer row) {
-               return tabularView.get(tableName).get(row - 2);
-       }
-
-       protected void registerInTabularView(String tableName, Object object) {
-               if (!tabularView.containsKey(tableName))
-                       tabularView.put(tableName, new ArrayList<Object>());
-               tabularView.get(tableName).add(object);
-       }
-
-       protected Class<?> findClassToInstantiate(String tableName) {
-               // TODO: ability to map sheet names and class names
-               String className = tableName;
-               Class<?> clss = null;
-               try {
-                       clss = getClassLoader().loadClass(className);
-                       return clss;
-               } catch (ClassNotFoundException e) {
-                       // silent
-               }
-
-               scannedPkgs: for (String pkg : getScannedPackages()) {
-                       try {
-                               clss = getClassLoader().loadClass(pkg.trim() + "." + className);
-                               break scannedPkgs;
-                       } catch (ClassNotFoundException e) {
-                               // silent
-                               if (log.isTraceEnabled())
-                                       log.trace(e.getMessage());
-                       }
-               }
-
-               if (clss == null)
-                       throw new ArgeoException("Cannot find a class for table "
-                                       + tableName);
-
-               return clss;
-       }
-
-       protected static class TabularInternalReference extends Reference {
-               private String targetTableName;
-               private Integer targetRow;
-
-               public TabularInternalReference(Object object, String property,
-                               String targetSheet, Integer targetRow) {
-                       super(object, property, null);
-                       this.targetTableName = targetSheet;
-                       this.targetRow = targetRow;
-               }
-
-               public String getTargetTableName() {
-                       return targetTableName;
-               }
-
-               public Integer getTargetRow() {
-                       return targetRow;
-               }
-
-       }
-}
diff --git a/org.argeo.server.core/src/org/argeo/server/dao/LightDaoAware.java b/org.argeo.server.core/src/org/argeo/server/dao/LightDaoAware.java
deleted file mode 100644 (file)
index 5ae7bea..0000000
+++ /dev/null
@@ -1,20 +0,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.
- */
-package org.argeo.server.dao;
-
-public interface LightDaoAware {
-       public void setLightDaoSupport(LightDaoSupport lightDaoSupport);
-}
diff --git a/org.argeo.server.core/src/org/argeo/server/dao/LightDaoPropertyEditor.java b/org.argeo.server.core/src/org/argeo/server/dao/LightDaoPropertyEditor.java
deleted file mode 100644 (file)
index de6ba70..0000000
+++ /dev/null
@@ -1,59 +0,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.
- */
-package org.argeo.server.dao;
-
-import java.beans.PropertyEditorSupport;
-
-import org.argeo.ArgeoException;
-
-public class LightDaoPropertyEditor extends PropertyEditorSupport implements
-               LightDaoAware {
-       private LightDaoSupport lightDaoSupport;
-
-       private Class<?> targetClass;
-       /** Can be null */
-       private String businessIdField;
-
-       @Override
-       public String getAsText() {
-               return getValue().toString();
-       }
-
-       @Override
-       public void setAsText(String text) throws IllegalArgumentException {
-               if (targetClass == null)
-                       throw new ArgeoException("Target class cannot be null");
-
-               if (businessIdField != null)
-                       setValue(lightDaoSupport.getByField(targetClass, businessIdField,
-                                       text));
-               else
-                       setValue(lightDaoSupport.getByKey(targetClass, text));
-       }
-
-       public void setLightDaoSupport(LightDaoSupport lightDaoSupport) {
-               this.lightDaoSupport = lightDaoSupport;
-       }
-
-       public void setTargetClass(Class<?> targetClass) {
-               this.targetClass = targetClass;
-       }
-
-       public void setBusinessIdField(String businessIdField) {
-               this.businessIdField = businessIdField;
-       }
-
-}
diff --git a/org.argeo.server.core/src/org/argeo/server/dao/LightDaoSupport.java b/org.argeo.server.core/src/org/argeo/server/dao/LightDaoSupport.java
deleted file mode 100644 (file)
index 6ea1b75..0000000
+++ /dev/null
@@ -1,36 +0,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.
- */
-package org.argeo.server.dao;
-
-import java.util.List;
-
-/** Minimal generic DAO for easy to implements objects <-> storage mapping. */
-public interface LightDaoSupport {
-       /** Retrieve an object of a given type by its unique key. */
-       public <T> T getByKey(Class<T> clss, Object key);
-
-       /** Retrieve an object of a given type by the value of one of its fields. */
-       public <T> T getByField(Class<T> clss, String field, Object value);
-
-       /** List all objects, optionally filtering them (implementation dependent) */
-       public <T> List<T> list(Class<T> clss, Object filter);
-
-       /** Lis all supported object types. */
-       public List<Class<?>> getSupportedClasses();
-
-       /** Save or update an object */
-       public void saveOrUpdate(Object key, Object value, Class<?> clss);
-}
diff --git a/org.argeo.server.core/src/org/argeo/server/mvc/DefaultHandlerExceptionResolver.java b/org.argeo.server.core/src/org/argeo/server/mvc/DefaultHandlerExceptionResolver.java
deleted file mode 100644 (file)
index 6269bd0..0000000
+++ /dev/null
@@ -1,46 +0,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.
- */
-package org.argeo.server.mvc;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.server.ServerAnswer;
-import org.springframework.web.servlet.HandlerExceptionResolver;
-import org.springframework.web.servlet.ModelAndView;
-
-public class DefaultHandlerExceptionResolver implements
-               HandlerExceptionResolver {
-       private final static Log log = LogFactory
-                       .getLog(DefaultHandlerExceptionResolver.class);
-
-       public ModelAndView resolveException(HttpServletRequest request,
-                       HttpServletResponse response, Object handler, Exception ex) {
-               ModelAndView mv = new ModelAndView();
-               ServerAnswer serverAnswer = ServerAnswer.error(ex);
-               mv.addObject(serverAnswer);
-
-               if (log.isDebugEnabled())
-                       log.error(serverAnswer);
-
-               mv.setViewName("500");
-               // response.setStatus(500);
-               return mv;
-       }
-
-}
diff --git a/org.argeo.server.core/src/org/argeo/server/mvc/EmptyViewController.java b/org.argeo.server.core/src/org/argeo/server/mvc/EmptyViewController.java
deleted file mode 100644 (file)
index c83d4ae..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*\r
- * Copyright (C) 2007-2012 Argeo GmbH\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *         http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.argeo.server.mvc;\r
-\r
-import javax.servlet.http.HttpServletRequest;\r
-import javax.servlet.http.HttpServletResponse;\r
-\r
-import org.springframework.web.servlet.ModelAndView;\r
-import org.springframework.web.servlet.mvc.ParameterizableViewController;\r
-\r
-/** Dummy controller which simply redirects to a view (typically a JSP)*/\r
-public class EmptyViewController extends ParameterizableViewController {\r
-\r
-       protected ModelAndView handleRequestInternal(HttpServletRequest request,\r
-                       HttpServletResponse response) throws Exception {\r
-               ModelAndView modelAndView = new ModelAndView();\r
-               modelAndView.setViewName(getViewName());\r
-               return modelAndView;\r
-\r
-       }\r
-}\r
diff --git a/org.argeo.server.core/src/org/argeo/server/mvc/MvcConstants.java b/org.argeo.server.core/src/org/argeo/server/mvc/MvcConstants.java
deleted file mode 100644 (file)
index d5c32dc..0000000
+++ /dev/null
@@ -1,21 +0,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.
- */
-package org.argeo.server.mvc;
-
-public interface MvcConstants {
-       public final static String ANSWER_MODEL_KEY = "org.argeo.server.mvc.ANSWER";
-       public final static String ANSWER_MODEL_KEY_AS_HTML = "org.argeo.server.mvc.ANSWER_AS_HTML";
-}
diff --git a/org.argeo.server.core/src/org/argeo/server/mvc/SerializingView.java b/org.argeo.server.core/src/org/argeo/server/mvc/SerializingView.java
deleted file mode 100644 (file)
index b42a9a0..0000000
+++ /dev/null
@@ -1,119 +0,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.
- */
-package org.argeo.server.mvc;
-
-import java.util.Locale;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.argeo.ArgeoException;
-import org.argeo.server.ServerAnswer;
-import org.argeo.server.ServerSerializer;
-import org.springframework.validation.BindingResult;
-import org.springframework.web.servlet.View;
-import org.springframework.web.servlet.view.AbstractView;
-
-/**
- * Can be used as a standalone {@link View} or using
- * {@link SerializingViewResolver}
- */
-public class SerializingView extends AbstractView implements MvcConstants {
-       private final String viewName;
-       private final Locale locale;
-
-       private ServerSerializer serializer;
-
-       public SerializingView() {
-               this.viewName = null;
-               this.locale = Locale.getDefault();
-       }
-
-       public SerializingView(String viewName, Locale locale,
-                       ServerSerializer serializer) {
-               this.viewName = viewName;
-               this.locale = locale;
-               this.serializer = serializer;
-       }
-
-       @SuppressWarnings({ "rawtypes" })
-       @Override
-       protected void renderMergedOutputModel(Map model,
-                       HttpServletRequest request, HttpServletResponse response)
-                       throws Exception {
-               Boolean serverAnswersAsHtml = model
-                               .containsKey(ANSWER_MODEL_KEY_AS_HTML);
-
-               final Object answer = findAnswerInModel(model);
-
-               if ((answer instanceof ServerAnswer) && serverAnswersAsHtml) {
-                       response.setContentType("text/html");
-                       ServerAnswer serverAnswer = (ServerAnswer) answer;
-                       response.getWriter().append("<pre>");
-                       response.getWriter().append(serverAnswer.getMessage());
-                       response.getWriter().append("</pre>");
-               } else {
-                       serializer.serialize(answer, request, response);
-               }
-       }
-
-       @SuppressWarnings("rawtypes")
-       protected Object findAnswerInModel(Map model) {
-               if (model.size() == 1) {
-                       return model.values().iterator().next();
-               } else if (model.size() == 2) {
-                       boolean otherIsBindingResult = false;
-                       Object answerValue = null;
-                       for (Object value : model.values()) {
-                               if (value instanceof BindingResult)
-                                       otherIsBindingResult = true;
-                               else
-                                       answerValue = value;
-                       }
-
-                       if (otherIsBindingResult)
-                               return answerValue;
-               }
-
-               if (model.containsKey(ANSWER_MODEL_KEY)) {
-                       return model.get(ANSWER_MODEL_KEY);
-               } else if (model.containsKey(ANSWER_MODEL_KEY_AS_HTML)) {
-                       return model.get(ANSWER_MODEL_KEY_AS_HTML);
-               } else if (viewName != null && model.containsKey(viewName)) {
-                       return model.get(viewName);
-               } else {
-                       if (model.size() == 0)
-                               throw new ArgeoException("Model is empty.");
-                       else
-                               throw new ArgeoException(
-                                               "Model has a size different from 1. Specify a modelKey.");
-               }
-       }
-
-       public String getViewName() {
-               return viewName;
-       }
-
-       public Locale getLocale() {
-               return locale;
-       }
-
-       public void setSerializer(ServerSerializer serializer) {
-               this.serializer = serializer;
-       }
-
-}
diff --git a/org.argeo.server.core/src/org/argeo/server/mvc/SerializingViewResolver.java b/org.argeo.server.core/src/org/argeo/server/mvc/SerializingViewResolver.java
deleted file mode 100644 (file)
index 9331543..0000000
+++ /dev/null
@@ -1,46 +0,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.
- */
-package org.argeo.server.mvc;
-
-import java.util.Locale;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.server.ServerSerializer;
-import org.springframework.web.servlet.View;
-import org.springframework.web.servlet.view.AbstractCachingViewResolver;
-
-/**
- * Returns a {@link SerializingView} based on the underlying.
- */
-public class SerializingViewResolver extends AbstractCachingViewResolver {
-       private final static Log log = LogFactory
-                       .getLog(SerializingViewResolver.class);
-
-       private ServerSerializer serializer;
-
-       @Override
-       protected View loadView(String viewName, Locale locale) throws Exception {
-               if (log.isTraceEnabled())
-                       log.trace("viewName=" + viewName);
-               return new SerializingView(viewName, locale, serializer);
-       }
-
-       public void setSerializer(ServerSerializer serializer) {
-               this.serializer = serializer;
-       }
-
-}
diff --git a/org.argeo.server.jackrabbit/.classpath b/org.argeo.server.jackrabbit/.classpath
deleted file mode 100644 (file)
index d2953a6..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-<?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-1.6" />
-       <classpathentry kind="output" path="bin" />
-</classpath>
diff --git a/org.argeo.server.jackrabbit/.project b/org.argeo.server.jackrabbit/.project
deleted file mode 100644 (file)
index a381d35..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-       <name>org.argeo.server.jackrabbit</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.jdt.core.javanature</nature>
-               <nature>org.eclipse.pde.PluginNature</nature>
-       </natures>
-</projectDescription>
diff --git a/org.argeo.server.jackrabbit/.settings/org.eclipse.jdt.core.prefs b/org.argeo.server.jackrabbit/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644 (file)
index 51880a3..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
-org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
-org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
-org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
-org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
-org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
-org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
-org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
-org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
-org.eclipse.jdt.core.compiler.problem.deadCode=warning
-org.eclipse.jdt.core.compiler.problem.deprecation=warning
-org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
-org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
-org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
-org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
-org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
-org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
-org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
-org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
-org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
-org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
-org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
-org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
-org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
-org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
-org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
-org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
-org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
-org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
-org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
-org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
-org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
-org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
-org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
-org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
-org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
-org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
-org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
-org.eclipse.jdt.core.compiler.problem.nullReference=warning
-org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
-org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
-org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
-org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
-org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
-org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
-org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
-org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
-org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
-org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
-org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
-org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
-org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
-org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
-org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
-org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
-org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
-org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
-org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
-org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
-org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
-org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
-org.eclipse.jdt.core.compiler.problem.unusedImport=warning
-org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
-org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
-org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
-org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
-org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
-org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
diff --git a/org.argeo.server.jackrabbit/bnd.bnd b/org.argeo.server.jackrabbit/bnd.bnd
deleted file mode 100644 (file)
index 785086f..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-Import-Package: javax.servlet,\
-org.apache.jackrabbit.webdav.server,\
-org.osgi.framework;version="0.0.0",\
-org.xml.sax;version="0.0.0",\
-org.apache.jackrabbit.webdav.jcr,\
-org.springframework.beans,\
-*
diff --git a/org.argeo.server.jackrabbit/build.properties b/org.argeo.server.jackrabbit/build.properties
deleted file mode 100644 (file)
index 93e080c..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-source.. = src/
-additional.bundles = org.apache.jackrabbit.data
diff --git a/org.argeo.server.jackrabbit/pom.xml b/org.argeo.server.jackrabbit/pom.xml
deleted file mode 100644 (file)
index 4ea6c71..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-<?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.1.14-SNAPSHOT</version>
-               <relativePath>..</relativePath>
-       </parent>
-       <artifactId>org.argeo.server.jackrabbit</artifactId>
-       <name>Commons Server Jackrabbit</name>
-       <dependencies>
-               <dependency>
-                       <groupId>org.argeo.commons</groupId>
-                       <artifactId>org.argeo.util</artifactId>
-                       <version>2.1.14-SNAPSHOT</version>
-               </dependency>
-               <dependency>
-                       <groupId>org.argeo.commons</groupId>
-                       <artifactId>org.argeo.server.jcr</artifactId>
-                       <version>2.1.14-SNAPSHOT</version>
-               </dependency>
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.commons</groupId> -->
-<!--                   <artifactId>org.argeo.server.jcr.mvc</artifactId> -->
-<!--                   <version>2.1.13-SNAPSHOT</version> -->
-<!--                   <scope>compile</scope> -->
-<!--           </dependency> -->
-
-               <!-- Jackrabbit -->
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.commons</groupId> -->
-<!--                   <artifactId>org.argeo.dep.jackrabbit</artifactId> -->
-<!--                   <type>pom</type> -->
-<!--                   <version>2.1.12-SNAPSHOT</version> -->
-<!--           </dependency> -->
-
-               <!-- OSGi -->
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.tp.rap.platform</groupId> -->
-<!--                   <artifactId>org.eclipse.osgi</artifactId> -->
-<!--                   <scope>provided</scope> -->
-<!--           </dependency> -->
-
-               <!-- Spring -->
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.tp</groupId> -->
-<!--                   <artifactId>org.springframework.beans</artifactId> -->
-<!--           </dependency> -->
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.tp</groupId> -->
-<!--                   <artifactId>org.springframework.web.servlet</artifactId> -->
-<!--           </dependency> -->
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.tp</groupId> -->
-<!--                   <artifactId>org.springframework.security.core</artifactId> -->
-<!--           </dependency> -->
-
-               <!-- TEST -->
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.commons</groupId> -->
-<!--                   <artifactId>org.argeo.dep.log4j</artifactId> -->
-<!--                   <version>2.1.12-SNAPSHOT</version> -->
-<!--                   <type>pom</type> -->
-<!--                   <scope>test</scope> -->
-<!--           </dependency> -->
-       </dependencies>
-</project>
\ No newline at end of file
diff --git a/org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/JackrabbitAuthorizations.java b/org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/JackrabbitAuthorizations.java
deleted file mode 100644 (file)
index e880b67..0000000
+++ /dev/null
@@ -1,66 +0,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.
- */
-package org.argeo.jackrabbit;
-
-import java.security.Principal;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.jackrabbit.api.JackrabbitSession;
-import org.apache.jackrabbit.api.security.user.Authorizable;
-import org.apache.jackrabbit.api.security.user.UserManager;
-import org.argeo.ArgeoException;
-import org.argeo.jcr.security.JcrAuthorizations;
-
-/** Apply authorizations to a Jackrabbit repository. */
-public class JackrabbitAuthorizations extends JcrAuthorizations {
-       private final static Log log = LogFactory
-                       .getLog(JackrabbitAuthorizations.class);
-
-       private List<String> groupPrefixes = Arrays
-                       .asList(new String[] { "ROLE_" });// new ArrayList<String>();
-
-       @Override
-       protected Principal getOrCreatePrincipal(Session session,
-                       String principalName) throws RepositoryException {
-               UserManager um = ((JackrabbitSession) session).getUserManager();
-               synchronized (um) {
-                       Authorizable authorizable = um.getAuthorizable(principalName);
-                       if (authorizable == null) {
-                               groupPrefixes: for (String groupPrefix : groupPrefixes) {
-                                       if (principalName.startsWith(groupPrefix)) {
-                                               authorizable = um.createGroup(principalName);
-                                               log.info("Created group " + principalName);
-                                               break groupPrefixes;
-                                       }
-                               }
-                               if (authorizable == null)
-                                       throw new ArgeoException("Authorizable " + principalName
-                                                       + " not found");
-                       }
-                       return authorizable.getPrincipal();
-               }
-       }
-
-       public void setGroupPrefixes(List<String> groupsToCreate) {
-               this.groupPrefixes = groupsToCreate;
-       }
-}
diff --git a/org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/JackrabbitContainer.java b/org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/JackrabbitContainer.java
deleted file mode 100644 (file)
index 82d58fb..0000000
+++ /dev/null
@@ -1,374 +0,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.
- */
-package org.argeo.jackrabbit;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.UUID;
-
-import javax.jcr.Node;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.jackrabbit.api.JackrabbitRepository;
-import org.apache.jackrabbit.core.RepositoryImpl;
-import org.apache.jackrabbit.core.config.RepositoryConfig;
-import org.apache.jackrabbit.core.config.RepositoryConfigurationParser;
-import org.argeo.ArgeoException;
-import org.argeo.jcr.ArgeoNames;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.jcr.MaintainedRepository;
-import org.springframework.core.io.Resource;
-import org.springframework.util.SystemPropertyUtils;
-import org.xml.sax.InputSource;
-
-/**
- * Wrapper around a Jackrabbit repository which allows to configure it in Spring
- * and expose it as a {@link Repository}.
- */
-public class JackrabbitContainer extends JackrabbitWrapper implements
-               MaintainedRepository {
-       private final static Log log = LogFactory.getLog(JackrabbitContainer.class);
-
-       // local
-       private Resource configuration;
-
-       private Resource variables;
-
-       private RepositoryConfig repositoryConfig;
-       private File homeDirectory;
-       private Boolean inMemory = false;
-
-       /** Migrations to execute (if not already done) */
-       private Set<JackrabbitDataModelMigration> dataModelMigrations = new HashSet<JackrabbitDataModelMigration>();
-
-       /** Straight (non spring) values */
-       private Properties configurationProperties;
-       private InputSource configurationXml;
-
-       /**
-        * Empty constructor, {@link #init()} should be called after properties have
-        * been set
-        */
-       public JackrabbitContainer() {
-       }
-
-       public void init() {
-               long begin = System.currentTimeMillis();
-
-               if (getRepository() != null)
-                       throw new ArgeoException(
-                                       "Cannot be used to wrap another repository");
-               Repository repository = createJackrabbitRepository();
-               super.setRepository(repository);
-
-               // migrate if needed
-               migrate();
-
-               // apply new CND files after migration
-               prepareDataModel();
-
-               double duration = ((double) (System.currentTimeMillis() - begin)) / 1000;
-               if (log.isDebugEnabled())
-                       log.debug("Initialized JCR repository wrapper in " + duration
-                                       + " s");
-       }
-
-       /** Actually creates the new repository. */
-       protected Repository createJackrabbitRepository() {
-               long begin = System.currentTimeMillis();
-               InputStream configurationIn = null;
-               Repository repository;
-               try {
-                       // temporary
-                       if (inMemory && getHomeDirectory().exists()) {
-                               FileUtils.deleteDirectory(getHomeDirectory());
-                               log.warn("Deleted Jackrabbit home directory "
-                                               + getHomeDirectory());
-                       }
-
-                       // process configuration file
-                       Properties vars = getConfigurationProperties();
-                       vars.put(RepositoryConfigurationParser.REPOSITORY_HOME_VARIABLE,
-                                       getHomeDirectory().getCanonicalPath());
-                       InputSource is;
-                       if (configurationXml != null)
-                               is = configurationXml;
-                       else {
-                               configurationIn = readConfiguration();
-                               is = new InputSource(configurationIn);
-                       }
-                       repositoryConfig = RepositoryConfig.create(is, vars);
-
-                       //
-                       // Actual repository creation
-                       //
-                       repository = RepositoryImpl.create(repositoryConfig);
-
-                       double duration = ((double) (System.currentTimeMillis() - begin)) / 1000;
-                       if (log.isTraceEnabled())
-                               log.trace("Created Jackrabbit repository in " + duration
-                                               + " s, home: " + getHomeDirectory());
-
-                       return repository;
-               } catch (Exception e) {
-                       throw new ArgeoException("Cannot create Jackrabbit repository "
-                                       + getHomeDirectory(), e);
-               } finally {
-                       IOUtils.closeQuietly(configurationIn);
-               }
-       }
-
-       /** Lazy init. */
-       protected File getHomeDirectory() {
-               try {
-                       if (homeDirectory == null) {
-                               if (inMemory) {
-                                       homeDirectory = new File(
-                                                       System.getProperty("java.io.tmpdir")
-                                                                       + File.separator
-                                                                       + System.getProperty("user.name")
-                                                                       + File.separator + "jackrabbit-"
-                                                                       + UUID.randomUUID());
-                                       homeDirectory.mkdirs();
-                                       // will it work if directory is not empty??
-                                       homeDirectory.deleteOnExit();
-                               }
-                       }
-
-                       return homeDirectory.getCanonicalFile();
-               } catch (IOException e) {
-                       throw new ArgeoException("Cannot get canonical file for "
-                                       + homeDirectory, e);
-               }
-       }
-
-       /** Executes migrations, if needed. */
-       protected void migrate() {
-               // No migration to perform
-               if (dataModelMigrations.size() == 0)
-                       return;
-
-               Boolean restartAndClearCaches = false;
-
-               // migrate data
-               Session session = null;
-               try {
-                       session = login();
-                       for (JackrabbitDataModelMigration dataModelMigration : new TreeSet<JackrabbitDataModelMigration>(
-                                       dataModelMigrations)) {
-                               if (dataModelMigration.migrate(session)) {
-                                       restartAndClearCaches = true;
-                               }
-                       }
-               } catch (ArgeoException e) {
-                       throw e;
-               } catch (Exception e) {
-                       throw new ArgeoException("Cannot migrate", e);
-               } finally {
-                       JcrUtils.logoutQuietly(session);
-               }
-
-               // restart repository
-               if (restartAndClearCaches) {
-                       Repository repository = getRepository();
-                       if (repository instanceof RepositoryImpl) {
-                               JackrabbitDataModelMigration
-                                               .clearRepositoryCaches(((RepositoryImpl) repository)
-                                                               .getConfig());
-                       }
-                       ((JackrabbitRepository) repository).shutdown();
-                       createJackrabbitRepository();
-               }
-
-               // set data model version
-               try {
-                       session = login();
-               } catch (RepositoryException e) {
-                       throw new ArgeoException("Cannot login to migrated repository", e);
-               }
-
-               for (JackrabbitDataModelMigration dataModelMigration : new TreeSet<JackrabbitDataModelMigration>(
-                               dataModelMigrations)) {
-                       try {
-                               if (session.itemExists(dataModelMigration
-                                               .getDataModelNodePath())) {
-                                       Node dataModelNode = session.getNode(dataModelMigration
-                                                       .getDataModelNodePath());
-                                       dataModelNode.setProperty(
-                                                       ArgeoNames.ARGEO_DATA_MODEL_VERSION,
-                                                       dataModelMigration.getTargetVersion());
-                                       session.save();
-                               }
-                       } catch (Exception e) {
-                               log.error("Cannot set model version", e);
-                       }
-               }
-               JcrUtils.logoutQuietly(session);
-
-       }
-
-       /** Shutdown the repository */
-       public void destroy() throws Exception {
-               Repository repository = getRepository();
-               if (repository != null && repository instanceof RepositoryImpl) {
-                       long begin = System.currentTimeMillis();
-                       ((RepositoryImpl) repository).shutdown();
-                       if (inMemory)
-                               if (getHomeDirectory().exists()) {
-                                       FileUtils.deleteDirectory(getHomeDirectory());
-                                       if (log.isDebugEnabled())
-                                               log.debug("Deleted Jackrabbit home directory "
-                                                               + getHomeDirectory());
-                               }
-                       double duration = ((double) (System.currentTimeMillis() - begin)) / 1000;
-                       log.info("Destroyed Jackrabbit repository in " + duration
-                                       + " s, home: " + getHomeDirectory());
-               }
-               repository = null;
-       }
-
-       public void dispose() {
-               throw new IllegalArgumentException(
-                               "Call destroy() method instead of dispose()");
-       }
-
-       /*
-        * UTILITIES
-        */
-       /**
-        * Reads the configuration which will initialize a {@link RepositoryConfig}.
-        */
-       protected InputStream readConfiguration() {
-               try {
-                       return configuration != null ? configuration.getInputStream()
-                                       : null;
-               } catch (IOException e) {
-                       throw new ArgeoException("Cannot read Jackrabbit configuration "
-                                       + configuration, e);
-               }
-       }
-
-       /**
-        * Reads the variables which will initialize a {@link Properties}. Returns
-        * null by default, to be overridden.
-        * 
-        * @return a new stream or null if no variables available
-        */
-       protected InputStream readVariables() {
-               try {
-                       return variables != null ? variables.getInputStream() : null;
-               } catch (IOException e) {
-                       throw new ArgeoException("Cannot read Jackrabbit variables "
-                                       + variables, e);
-               }
-       }
-
-       /**
-        * Resolves ${} placeholders in the provided string. Based on system
-        * properties if no map is provided.
-        */
-       protected String resolvePlaceholders(String string,
-                       Map<String, String> variables) {
-               return SystemPropertyUtils.resolvePlaceholders(string);
-       }
-
-       /** Generates the properties to use in the configuration. */
-       protected Properties getConfigurationProperties() {
-               if (configurationProperties != null)
-                       return configurationProperties;
-
-               InputStream propsIn = null;
-               Properties vars;
-               try {
-                       vars = new Properties();
-                       propsIn = readVariables();
-                       if (propsIn != null) {
-                               vars.load(propsIn);
-                       }
-                       // resolve system properties
-                       for (Object key : vars.keySet()) {
-                               // TODO: implement a smarter mechanism to resolve nested ${}
-                               String newValue = resolvePlaceholders(
-                                               vars.getProperty(key.toString()), null);
-                               vars.put(key, newValue);
-                       }
-                       // override with system properties
-                       vars.putAll(System.getProperties());
-
-                       if (log.isTraceEnabled()) {
-                               log.trace("Jackrabbit config variables:");
-                               for (Object key : new TreeSet<Object>(vars.keySet()))
-                                       log.trace(key + "=" + vars.getProperty(key.toString()));
-                       }
-
-               } catch (IOException e) {
-                       throw new ArgeoException("Cannot read configuration properties", e);
-               } finally {
-                       IOUtils.closeQuietly(propsIn);
-               }
-               return vars;
-       }
-
-       /*
-        * FIELDS ACCESS
-        */
-
-       public void setHomeDirectory(File homeDirectory) {
-               this.homeDirectory = homeDirectory;
-       }
-
-       public void setInMemory(Boolean inMemory) {
-               this.inMemory = inMemory;
-       }
-
-       public void setRepository(Repository repository) {
-               throw new ArgeoException("Cannot be used to wrap another repository");
-       }
-
-       public void setDataModelMigrations(
-                       Set<JackrabbitDataModelMigration> dataModelMigrations) {
-               this.dataModelMigrations = dataModelMigrations;
-       }
-
-       public void setVariables(Resource variables) {
-               this.variables = variables;
-       }
-
-       public void setConfiguration(Resource configuration) {
-               this.configuration = configuration;
-       }
-
-       public void setConfigurationProperties(Properties configurationProperties) {
-               this.configurationProperties = configurationProperties;
-       }
-
-       public void setConfigurationXml(InputSource configurationXml) {
-               this.configurationXml = configurationXml;
-       }
-
-}
diff --git a/org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/JackrabbitDataModelMigration.java b/org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/JackrabbitDataModelMigration.java
deleted file mode 100644 (file)
index 401b34d..0000000
+++ /dev/null
@@ -1,182 +0,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.
- */
-package org.argeo.jackrabbit;
-
-import java.io.InputStreamReader;
-import java.io.Reader;
-
-import javax.jcr.Node;
-import javax.jcr.Session;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.jackrabbit.commons.cnd.CndImporter;
-import org.apache.jackrabbit.core.config.RepositoryConfig;
-import org.argeo.ArgeoException;
-import org.argeo.jcr.ArgeoNames;
-import org.argeo.jcr.JcrCallback;
-import org.argeo.jcr.JcrUtils;
-import org.springframework.core.io.Resource;
-
-/** Migrate the data in a Jackrabbit repository. */
-public class JackrabbitDataModelMigration implements
-               Comparable<JackrabbitDataModelMigration> {
-       private final static Log log = LogFactory
-                       .getLog(JackrabbitDataModelMigration.class);
-
-       private String dataModelNodePath;
-       private String targetVersion;
-       private Resource migrationCnd;
-       private JcrCallback dataModification;
-
-       /**
-        * Expects an already started repository with the old data model to migrate.
-        * Expects to be run with admin rights (Repository.login() will be used).
-        * 
-        * @return true if a migration was performed and the repository needs to be
-        *         restarted and its caches cleared.
-        */
-       public Boolean migrate(Session session) {
-               long begin = System.currentTimeMillis();
-               Reader reader = null;
-               try {
-                       // check if already migrated
-                       if (!session.itemExists(dataModelNodePath)) {
-                               log.warn("Node " + dataModelNodePath
-                                               + " does not exist: nothing to migrate.");
-                               return false;
-                       }
-                       Node dataModelNode = session.getNode(dataModelNodePath);
-                       if (dataModelNode.hasProperty(ArgeoNames.ARGEO_DATA_MODEL_VERSION)) {
-                               String currentVersion = dataModelNode.getProperty(
-                                               ArgeoNames.ARGEO_DATA_MODEL_VERSION).getString();
-                               if (compareVersions(currentVersion, targetVersion) >= 0) {
-                                       log.info("Data model at version " + currentVersion
-                                                       + ", no need to migrate.");
-                                       return false;
-                               }
-                       }
-
-                       // apply transitional CND
-                       if (migrationCnd != null) {
-                               reader = new InputStreamReader(migrationCnd.getInputStream());
-                               CndImporter.registerNodeTypes(reader, session, true);
-                               session.save();
-                               log.info("Registered migration node types from " + migrationCnd);
-                       }
-
-                       // modify data
-                       dataModification.execute(session);
-
-                       // apply changes
-                       session.save();
-
-                       long duration = System.currentTimeMillis() - begin;
-                       log.info("Migration of data model " + dataModelNodePath + " to "
-                                       + targetVersion + " performed in " + duration + "ms");
-                       return true;
-               } catch (Exception e) {
-                       JcrUtils.discardQuietly(session);
-                       throw new ArgeoException("Migration of data model "
-                                       + dataModelNodePath + " to " + targetVersion + " failed.",
-                                       e);
-               } finally {
-                       JcrUtils.logoutQuietly(session);
-                       IOUtils.closeQuietly(reader);
-               }
-       }
-
-       protected static int compareVersions(String version1, String version2) {
-               // TODO do a proper version analysis and comparison
-               return version1.compareTo(version2);
-       }
-
-       /** To be called on a stopped repository. */
-       public static void clearRepositoryCaches(RepositoryConfig repositoryConfig) {
-               try {
-                       String customeNodeTypesPath = "/nodetypes/custom_nodetypes.xml";
-                       repositoryConfig.getFileSystem().deleteFile(customeNodeTypesPath);
-                       if (log.isDebugEnabled())
-                               log.debug("Cleared " + customeNodeTypesPath);
-               } catch (Exception e) {
-                       throw new ArgeoException("Cannot clear caches", e);
-               }
-
-               // File customNodeTypes = new File(home.getPath()
-               // + "/repository/nodetypes/custom_nodetypes.xml");
-               // if (customNodeTypes.exists()) {
-               // customNodeTypes.delete();
-               // if (log.isDebugEnabled())
-               // log.debug("Cleared " + customNodeTypes);
-               // } else {
-               // log.warn("File " + customNodeTypes + " not found.");
-               // }
-       }
-
-       /*
-        * FOR USE IN (SORTED) SETS
-        */
-
-       public int compareTo(JackrabbitDataModelMigration dataModelMigration) {
-               // TODO make ordering smarter
-               if (dataModelNodePath.equals(dataModelMigration.dataModelNodePath))
-                       return compareVersions(targetVersion,
-                                       dataModelMigration.targetVersion);
-               else
-                       return dataModelNodePath
-                                       .compareTo(dataModelMigration.dataModelNodePath);
-       }
-
-       @Override
-       public boolean equals(Object obj) {
-               if (!(obj instanceof JackrabbitDataModelMigration))
-                       return false;
-               JackrabbitDataModelMigration dataModelMigration = (JackrabbitDataModelMigration) obj;
-               return dataModelNodePath.equals(dataModelMigration.dataModelNodePath)
-                               && targetVersion.equals(dataModelMigration.targetVersion);
-       }
-
-       @Override
-       public int hashCode() {
-               return targetVersion.hashCode();
-       }
-
-       public void setDataModelNodePath(String dataModelNodePath) {
-               this.dataModelNodePath = dataModelNodePath;
-       }
-
-       public void setTargetVersion(String targetVersion) {
-               this.targetVersion = targetVersion;
-       }
-
-       public void setMigrationCnd(Resource migrationCnd) {
-               this.migrationCnd = migrationCnd;
-       }
-
-       public void setDataModification(JcrCallback dataModification) {
-               this.dataModification = dataModification;
-       }
-
-       public String getDataModelNodePath() {
-               return dataModelNodePath;
-       }
-
-       public String getTargetVersion() {
-               return targetVersion;
-       }
-
-}
diff --git a/org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/JackrabbitRepositoryFactory.java b/org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/JackrabbitRepositoryFactory.java
deleted file mode 100644 (file)
index d64bb5e..0000000
+++ /dev/null
@@ -1,169 +0,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.
- */
-package org.argeo.jackrabbit;
-
-import java.io.File;
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.RepositoryFactory;
-import javax.jcr.Session;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.jackrabbit.commons.JcrUtils;
-import org.apache.jackrabbit.core.RepositoryImpl;
-import org.apache.jackrabbit.core.config.RepositoryConfig;
-import org.apache.jackrabbit.core.config.RepositoryConfigurationParser;
-import org.apache.jackrabbit.jcr2dav.Jcr2davRepositoryFactory;
-import org.argeo.ArgeoException;
-import org.argeo.jcr.ArgeoJcrConstants;
-import org.argeo.jcr.DefaultRepositoryFactory;
-import org.springframework.core.io.ClassPathResource;
-import org.springframework.core.io.Resource;
-import org.xml.sax.InputSource;
-
-/**
- * Repository factory which can create new repositories and access remote
- * Jackrabbit repositories
- */
-public class JackrabbitRepositoryFactory extends DefaultRepositoryFactory
-               implements RepositoryFactory, ArgeoJcrConstants {
-
-       private final static Log log = LogFactory
-                       .getLog(JackrabbitRepositoryFactory.class);
-
-       private Resource fileRepositoryConfiguration = new ClassPathResource(
-                       "/org/argeo/jackrabbit/repository-h2.xml");
-
-       @SuppressWarnings({ "rawtypes", "unchecked" })
-       public Repository getRepository(Map parameters) throws RepositoryException {
-               // check if can be found by alias
-               Repository repository = super.getRepository(parameters);
-               if (repository != null)
-                       return repository;
-
-               // check if remote
-               String uri = null;
-               if (parameters.containsKey(JCR_REPOSITORY_URI))
-                       uri = parameters.get(JCR_REPOSITORY_URI).toString();
-               else if (parameters.containsKey(JcrUtils.REPOSITORY_URI))
-                       uri = parameters.get(JcrUtils.REPOSITORY_URI).toString();
-
-               if (uri != null) {
-                       if (uri.startsWith("http"))// http, https
-                               repository = createRemoteRepository(uri);
-                       else if (uri.startsWith("file"))// http, https
-                               repository = createFileRepository(uri, parameters);
-                       else if (uri.startsWith("vm")) {
-                               log.warn("URI "
-                                               + uri
-                                               + " should have been managed by generic JCR repository factory");
-                               repository = getRepositoryByAlias(getAliasFromURI(uri));
-                       }
-               }
-
-               // publish under alias
-               if (parameters.containsKey(JCR_REPOSITORY_ALIAS)) {
-                       Properties properties = new Properties();
-                       properties.putAll(parameters);
-                       String alias = parameters.get(JCR_REPOSITORY_ALIAS).toString();
-                       publish(alias, repository, properties);
-                       log.info("Registered JCR repository under alias '" + alias
-                                       + "' with properties " + properties);
-               }
-
-               return repository;
-       }
-
-       protected Repository createRemoteRepository(String uri)
-                       throws RepositoryException {
-               Map<String, String> params = new HashMap<String, String>();
-               params.put(JcrUtils.REPOSITORY_URI, uri);
-               Repository repository = new Jcr2davRepositoryFactory()
-                               .getRepository(params);
-               if (repository == null)
-                       throw new ArgeoException("Remote Davex repository " + uri
-                                       + " not found");
-               log.info("Initialized remote Jackrabbit repository from uri " + uri);
-               return repository;
-       }
-
-       @SuppressWarnings({ "rawtypes", "unchecked" })
-       protected Repository createFileRepository(final String uri, Map parameters)
-                       throws RepositoryException {
-               InputStream configurationIn = null;
-               try {
-                       Properties vars = new Properties();
-                       vars.putAll(parameters);
-                       String dirPath = uri.substring("file:".length());
-                       File homeDir = new File(dirPath);
-                       if (homeDir.exists() && !homeDir.isDirectory())
-                               throw new ArgeoException("Repository home " + dirPath
-                                               + " is not a directory");
-                       if (!homeDir.exists())
-                               homeDir.mkdirs();
-                       configurationIn = fileRepositoryConfiguration.getInputStream();
-                       vars.put(RepositoryConfigurationParser.REPOSITORY_HOME_VARIABLE,
-                                       homeDir.getCanonicalPath());
-                       RepositoryConfig repositoryConfig = RepositoryConfig.create(
-                                       new InputSource(configurationIn), vars);
-
-                       // TransientRepository repository = new
-                       // TransientRepository(repositoryConfig);
-                       final RepositoryImpl repository = RepositoryImpl
-                                       .create(repositoryConfig);
-                       Session session = repository.login();
-                       // FIXME make it generic
-                       org.argeo.jcr.JcrUtils.addPrivilege(session, "/", "ROLE_ADMIN",
-                                       "jcr:all");
-                       org.argeo.jcr.JcrUtils.logoutQuietly(session);
-                       Runtime.getRuntime().addShutdownHook(
-                                       new Thread("Clean JCR repository " + uri) {
-                                               public void run() {
-                                                       repository.shutdown();
-                                                       log.info("Destroyed repository " + uri);
-                                               }
-                                       });
-                       log.info("Initialized file Jackrabbit repository from uri " + uri);
-                       return repository;
-               } catch (Exception e) {
-                       throw new ArgeoException("Cannot create repository " + uri, e);
-               } finally {
-                       IOUtils.closeQuietly(configurationIn);
-               }
-       }
-
-       /**
-        * Called after the repository has been initialised. Does nothing by
-        * default.
-        */
-       @SuppressWarnings("rawtypes")
-       protected void postInitialization(Repository repository, Map parameters) {
-
-       }
-
-       public void setFileRepositoryConfiguration(
-                       Resource fileRepositoryConfiguration) {
-               this.fileRepositoryConfiguration = fileRepositoryConfiguration;
-       }
-
-}
diff --git a/org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/JackrabbitWrapper.java b/org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/JackrabbitWrapper.java
deleted file mode 100644 (file)
index 53a9ff1..0000000
+++ /dev/null
@@ -1,379 +0,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.
- */
-package org.argeo.jackrabbit;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.jcr.Credentials;
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.Repository;
-import javax.jcr.Session;
-import javax.jcr.nodetype.NodeType;
-
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.jackrabbit.commons.NamespaceHelper;
-import org.apache.jackrabbit.commons.cnd.CndImporter;
-import org.argeo.ArgeoException;
-import org.argeo.jcr.ArgeoJcrConstants;
-import org.argeo.jcr.ArgeoNames;
-import org.argeo.jcr.ArgeoTypes;
-import org.argeo.jcr.JcrRepositoryWrapper;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.util.security.DigestUtils;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.packageadmin.ExportedPackage;
-import org.osgi.service.packageadmin.PackageAdmin;
-import org.springframework.context.ResourceLoaderAware;
-import org.springframework.core.io.Resource;
-import org.springframework.core.io.ResourceLoader;
-
-/**
- * Wrapper around a Jackrabbit repository which allows to simplify configuration
- * and intercept some actions. It exposes itself as a {@link Repository}.
- */
-public class JackrabbitWrapper extends JcrRepositoryWrapper implements
-               ResourceLoaderAware {
-       private final static Log log = LogFactory.getLog(JackrabbitWrapper.class);
-       private final static String DIGEST_ALGORITHM = "MD5";
-
-       // local
-       private ResourceLoader resourceLoader;
-
-       // data model
-       /** Node type definitions in CND format */
-       private List<String> cndFiles = new ArrayList<String>();
-       /**
-        * Always import CNDs. Useful during development of new data models. In
-        * production, explicit migration processes should be used.
-        */
-       private Boolean forceCndImport = true;
-
-       /** Namespaces to register: key is prefix, value namespace */
-       private Map<String, String> namespaces = new HashMap<String, String>();
-
-       private BundleContext bundleContext;
-
-       /**
-        * Explicitly set admin credentials used in initialization. Useful for
-        * testing, in real applications authentication is rather dealt with
-        * externally
-        */
-       private Credentials adminCredentials = null;
-
-       /**
-        * Empty constructor, {@link #init()} should be called after properties have
-        * been set
-        */
-       public JackrabbitWrapper() {
-       }
-
-       @Override
-       public void init() {
-               prepareDataModel();
-       }
-
-       /*
-        * DATA MODEL
-        */
-
-       /**
-        * Import declared node type definitions and register namespaces. Tries to
-        * update the node definitions if they have changed. In case of failures an
-        * error will be logged but no exception will be thrown.
-        */
-       protected void prepareDataModel() {
-               if ((cndFiles == null || cndFiles.size() == 0)
-                               && (namespaces == null || namespaces.size() == 0))
-                       return;
-
-               Session session = null;
-               try {
-                       session = login(adminCredentials);
-                       // register namespaces
-                       if (namespaces.size() > 0) {
-                               NamespaceHelper namespaceHelper = new NamespaceHelper(session);
-                               namespaceHelper.registerNamespaces(namespaces);
-                       }
-
-                       // load CND files from classpath or as URL
-                       for (String resUrl : cndFiles) {
-                               processCndFile(session, resUrl);
-                       }
-               } catch (Exception e) {
-                       JcrUtils.discardQuietly(session);
-                       throw new ArgeoException("Cannot import node type definitions "
-                                       + cndFiles, e);
-               } finally {
-                       JcrUtils.logoutQuietly(session);
-               }
-
-       }
-
-       protected void processCndFile(Session session, String resUrl) {
-               Reader reader = null;
-               try {
-                       // check existing data model nodes
-                       new NamespaceHelper(session).registerNamespace(ArgeoNames.ARGEO,
-                                       ArgeoNames.ARGEO_NAMESPACE);
-                       if (!session.itemExists(ArgeoJcrConstants.DATA_MODELS_BASE_PATH))
-                               JcrUtils.mkdirs(session,
-                                               ArgeoJcrConstants.DATA_MODELS_BASE_PATH);
-                       Node dataModels = session
-                                       .getNode(ArgeoJcrConstants.DATA_MODELS_BASE_PATH);
-                       NodeIterator it = dataModels.getNodes();
-                       Node dataModel = null;
-                       while (it.hasNext()) {
-                               Node node = it.nextNode();
-                               if (node.getProperty(ArgeoNames.ARGEO_URI).getString()
-                                               .equals(resUrl)) {
-                                       dataModel = node;
-                                       break;
-                               }
-                       }
-
-                       byte[] cndContent = readCndContent(resUrl);
-                       String newDigest = DigestUtils.digest(DIGEST_ALGORITHM, cndContent);
-                       Bundle bundle = findDataModelBundle(resUrl);
-
-                       String currentVersion = null;
-                       if (dataModel != null) {
-                               currentVersion = dataModel.getProperty(
-                                               ArgeoNames.ARGEO_DATA_MODEL_VERSION).getString();
-                               if (dataModel.hasNode(Node.JCR_CONTENT)) {
-                                       String oldDigest = JcrUtils.checksumFile(dataModel,
-                                                       DIGEST_ALGORITHM);
-                                       if (oldDigest.equals(newDigest)) {
-                                               if (log.isDebugEnabled())
-                                                       log.debug("Data model " + resUrl
-                                                                       + " hasn't changed, keeping version "
-                                                                       + currentVersion);
-                                               return;
-                                       }
-                               }
-                       }
-
-                       if (dataModel != null && !forceCndImport) {
-                               log.info("Data model "
-                                               + resUrl
-                                               + " has changed since version "
-                                               + currentVersion
-                                               + (bundle != null ? ": version " + bundle.getVersion()
-                                                               + ", bundle " + bundle.getSymbolicName() : ""));
-                               return;
-                       }
-
-                       reader = new InputStreamReader(new ByteArrayInputStream(cndContent));
-                       // actually imports the CND
-                       try {
-                               CndImporter.registerNodeTypes(reader, session, true);
-                       } catch (Exception e) {
-                               log.error("Cannot import data model " + resUrl, e);
-                               return;
-                       }
-
-                       if (dataModel != null && !dataModel.isNodeType(NodeType.NT_FILE)) {
-                               dataModel.remove();
-                               dataModel = null;
-                       }
-
-                       // FIXME: what if argeo.cnd would not be the first called on
-                       // a new repo? argeo:dataModel would not be found
-                       String fileName = FilenameUtils.getName(resUrl);
-                       if (dataModel == null) {
-                               dataModel = dataModels.addNode(fileName, NodeType.NT_FILE);
-                               dataModel.addNode(Node.JCR_CONTENT, NodeType.NT_RESOURCE);
-                               dataModel.addMixin(ArgeoTypes.ARGEO_DATA_MODEL);
-                               dataModel.setProperty(ArgeoNames.ARGEO_URI, resUrl);
-                       } else {
-                               session.getWorkspace().getVersionManager()
-                                               .checkout(dataModel.getPath());
-                       }
-                       if (bundle != null)
-                               dataModel.setProperty(ArgeoNames.ARGEO_DATA_MODEL_VERSION,
-                                               bundle.getVersion().toString());
-                       else
-                               dataModel.setProperty(ArgeoNames.ARGEO_DATA_MODEL_VERSION,
-                                               "0.0.0");
-                       JcrUtils.copyBytesAsFile(dataModel.getParent(), fileName,
-                                       cndContent);
-                       JcrUtils.updateLastModified(dataModel);
-                       session.save();
-                       session.getWorkspace().getVersionManager()
-                                       .checkin(dataModel.getPath());
-
-                       if (currentVersion == null)
-                               log.info("Data model "
-                                               + resUrl
-                                               + (bundle != null ? ", version " + bundle.getVersion()
-                                                               + ", bundle " + bundle.getSymbolicName() : ""));
-                       else
-                               log.info("Data model "
-                                               + resUrl
-                                               + " updated from version "
-                                               + currentVersion
-                                               + (bundle != null ? ", version " + bundle.getVersion()
-                                                               + ", bundle " + bundle.getSymbolicName() : ""));
-               } catch (Exception e) {
-                       throw new ArgeoException("Cannot process data model " + resUrl, e);
-               } finally {
-                       IOUtils.closeQuietly(reader);
-               }
-       }
-
-       protected byte[] readCndContent(String resUrl) {
-               InputStream in = null;
-               try {
-                       boolean classpath;
-                       // normalize URL
-                       if (bundleContext != null && resUrl.startsWith("classpath:")) {
-                               resUrl = resUrl.substring("classpath:".length());
-                               classpath = true;
-                       } else if (resUrl.indexOf(':') < 0) {
-                               if (!resUrl.startsWith("/")) {
-                                       resUrl = "/" + resUrl;
-                                       log.warn("Classpath should start with '/'");
-                               }
-                               classpath = true;
-                       } else {
-                               classpath = false;
-                       }
-
-                       URL url = null;
-                       if (classpath) {
-                               if (bundleContext != null) {
-                                       Bundle currentBundle = bundleContext.getBundle();
-                                       url = currentBundle.getResource(resUrl);
-                               } else {
-                                       resUrl = "classpath:" + resUrl;
-                                       url = null;
-                               }
-                       } else if (!resUrl.startsWith("classpath:")) {
-                               url = new URL(resUrl);
-                       }
-
-                       if (url != null) {
-                               in = url.openStream();
-                       } else if (resourceLoader != null) {
-                               Resource res = resourceLoader.getResource(resUrl);
-                               in = res.getInputStream();
-                               url = res.getURL();
-                       } else {
-                               throw new ArgeoException("No " + resUrl + " in the classpath,"
-                                               + " make sure the containing" + " package is visible.");
-                       }
-
-                       return IOUtils.toByteArray(in);
-               } catch (Exception e) {
-                       throw new ArgeoException("Cannot read CND from " + resUrl, e);
-               } finally {
-                       IOUtils.closeQuietly(in);
-               }
-       }
-
-       /*
-        * REPOSITORY INTERCEPTOR
-        */
-
-       /*
-        * UTILITIES
-        */
-       /** Find which OSGi bundle provided the data model resource */
-       protected Bundle findDataModelBundle(String resUrl) {
-               if (bundleContext == null)
-                       return null;
-
-               if (resUrl.startsWith("/"))
-                       resUrl = resUrl.substring(1);
-               String pkg = resUrl.substring(0, resUrl.lastIndexOf('/')).replace('/',
-                               '.');
-               ServiceReference paSr = bundleContext
-                               .getServiceReference(PackageAdmin.class.getName());
-               PackageAdmin packageAdmin = (PackageAdmin) bundleContext
-                               .getService(paSr);
-
-               // find exported package
-               ExportedPackage exportedPackage = null;
-               ExportedPackage[] exportedPackages = packageAdmin
-                               .getExportedPackages(pkg);
-               if (exportedPackages == null)
-                       throw new ArgeoException("No exported package found for " + pkg);
-               for (ExportedPackage ep : exportedPackages) {
-                       for (Bundle b : ep.getImportingBundles()) {
-                               if (b.getBundleId() == bundleContext.getBundle().getBundleId()) {
-                                       exportedPackage = ep;
-                                       break;
-                               }
-                       }
-               }
-
-               Bundle exportingBundle = null;
-               if (exportedPackage != null) {
-                       exportingBundle = exportedPackage.getExportingBundle();
-               } else {
-                       // assume this is in the same bundle
-                       exportingBundle = bundleContext.getBundle();
-                       // throw new ArgeoException("No OSGi exporting package found for "
-                       // + resUrl);
-               }
-               return exportingBundle;
-       }
-
-       /*
-        * FIELDS ACCESS
-        */
-       public void setNamespaces(Map<String, String> namespaces) {
-               this.namespaces = namespaces;
-       }
-
-       public void setCndFiles(List<String> cndFiles) {
-               this.cndFiles = cndFiles;
-       }
-
-       public void setBundleContext(BundleContext bundleContext) {
-               this.bundleContext = bundleContext;
-       }
-
-       protected BundleContext getBundleContext() {
-               return bundleContext;
-       }
-
-       public void setForceCndImport(Boolean forceCndUpdate) {
-               this.forceCndImport = forceCndUpdate;
-       }
-
-       public void setResourceLoader(ResourceLoader resourceLoader) {
-               this.resourceLoader = resourceLoader;
-       }
-
-       public void setAdminCredentials(Credentials adminCredentials) {
-               this.adminCredentials = adminCredentials;
-       }
-
-}
diff --git a/org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/OsgiJackrabbitRepositoryFactory.java b/org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/OsgiJackrabbitRepositoryFactory.java
deleted file mode 100644 (file)
index b28699e..0000000
+++ /dev/null
@@ -1,49 +0,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.
- */
-package org.argeo.jackrabbit;
-
-import java.util.Hashtable;
-import java.util.Properties;
-
-import javax.jcr.Repository;
-
-import org.osgi.framework.BundleContext;
-
-/**
- * OSGi-aware Jackrabbit repository factory which can retrieve/publish
- * {@link Repository} as OSGi services.
- */
-public class OsgiJackrabbitRepositoryFactory extends
-               JackrabbitRepositoryFactory {
-       private BundleContext bundleContext;
-
-       protected void publish(String alias, Repository repository,
-                       Properties properties) {
-               if (bundleContext != null) {
-                       // do not modify reference
-                       Hashtable<String, String> props = new Hashtable<String, String>();
-                       props.putAll(props);
-                       props.put(JCR_REPOSITORY_ALIAS, alias);
-                       bundleContext.registerService(Repository.class.getName(),
-                                       repository, props);
-               }
-       }
-
-       public void setBundleContext(BundleContext bundleContext) {
-               this.bundleContext = bundleContext;
-       }
-
-}
diff --git a/org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/repository-fs.xml b/org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/repository-fs.xml
deleted file mode 100644 (file)
index 609fc8b..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0"?>
-<!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}/fs" />
-       </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="${argeo.node.repo.defaultWorkspace}" />
-       <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" />
-               <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-                       <param name="path" value="${wsp.home}/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" />
-       </Versioning>
-
-       <!-- Indexing -->
-       <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-               <param name="path" value="${rep.home}/index" />
-               <param name="extractorPoolSize" value="2" />
-               <param name="supportHighlighting" value="true" />
-       </SearchIndex>
-
-       <!-- Security -->
-       <Security appName="Jackrabbit">
-               <SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
-                       workspaceName="security">
-               </SecurityManager>
-               <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager">
-               </AccessManager>
-               <LoginModule class="org.argeo.security.jackrabbit.ArgeoLoginModule">
-               </LoginModule>
-       </Security>
-</Repository>
\ No newline at end of file
diff --git a/org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/repository-h2.xml b/org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/repository-h2.xml
deleted file mode 100644 (file)
index b6a9252..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE Repository PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit 1.6//EN"
-                            "http://jackrabbit.apache.org/dtd/repository-2.0.dtd">
-<Repository>
-       <!-- Shared datasource -->
-       <DataSources>
-               <DataSource name="dataSource">
-                       <param name="driver" value="org.h2.Driver" />
-                       <param name="url" value="jdbc:h2:${rep.home}/h2/repository" />
-                       <param name="user" value="sa" />
-                       <param name="password" value="" />
-                       <param name="databaseType" value="h2" />
-                       <param name="maxPoolSize" value="10" />
-               </DataSource>
-       </DataSources>
-
-       <!-- File system and datastore -->
-       <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
-               <param name="dataSourceName" value="dataSource" />
-               <param name="schema" value="default" />
-               <param name="schemaObjectPrefix" value="fs_" />
-       </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" />
-       <Workspace name="${wsp.name}">
-               <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schema" value="default" />
-                       <param name="schemaObjectPrefix" value="${wsp.name}_fs_" />
-               </FileSystem>
-               <PersistenceManager
-                       class="org.apache.jackrabbit.core.persistence.pool.H2PersistenceManager">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schemaObjectPrefix" value="${wsp.name}_pm_" />
-               </PersistenceManager>
-               <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-                       <param name="path" value="${wsp.home}/index" />
-               </SearchIndex>
-       </Workspace>
-
-       <!-- Versioning -->
-       <Versioning rootPath="${rep.home}/version">
-               <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schema" value="default" />
-                       <param name="schemaObjectPrefix" value="fs_ver_" />
-               </FileSystem>
-               <PersistenceManager
-                       class="org.apache.jackrabbit.core.persistence.pool.H2PersistenceManager">
-                       <param name="dataSourceName" value="dataSource" />
-                       <param name="schemaObjectPrefix" value="pm_ver_" />
-               </PersistenceManager>
-       </Versioning>
-
-       <!-- Indexing -->
-       <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
-               <param name="path" value="${rep.home}/index" />
-               <param name="extractorPoolSize" value="2" />
-               <param name="supportHighlighting" value="true" />
-       </SearchIndex>
-
-       <!-- Security -->
-       <Security appName="Jackrabbit">
-               <SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
-                       workspaceName="security">
-               </SecurityManager>
-               <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager">
-               </AccessManager>
-               <LoginModule class="org.argeo.security.jackrabbit.ArgeoLoginModule">
-               </LoginModule>
-       </Security>
-</Repository>
\ No newline at end of file
diff --git a/org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/repository-memory.xml b/org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/repository-memory.xml
deleted file mode 100644 (file)
index e552c33..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-<?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.mem.MemoryFileSystem" />
-
-       <!-- Workspace templates -->
-       <Workspaces rootPath="${rep.home}/workspaces"
-               defaultWorkspace="main" configRootPath="/workspaces" />
-       <Workspace name="${wsp.name}">
-               <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
-               <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" />
-                       <param name="directoryManagerClass"
-                               value="org.apache.jackrabbit.core.query.lucene.directory.RAMDirectoryManager" />
-                       <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
-               </SearchIndex>
-       </Workspace>
-
-       <!-- Versioning -->
-       <Versioning rootPath="${rep.home}/version">
-               <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
-               <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="directoryManagerClass"
-                       value="org.apache.jackrabbit.core.query.lucene.directory.RAMDirectoryManager" />
-               <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
-       </SearchIndex>
-
-       <!-- Security -->
-       <Security appName="Jackrabbit">
-               <SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
-                       workspaceName="security">
-               </SecurityManager>
-               <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager">
-               </AccessManager>
-               <LoginModule class="org.argeo.security.jackrabbit.ArgeoLoginModule">
-               </LoginModule>
-       </Security>
-</Repository>
\ No newline at end of file
diff --git a/org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/servlet/OpenInViewSessionProvider.java b/org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/servlet/OpenInViewSessionProvider.java
deleted file mode 100644 (file)
index 519a218..0000000
+++ /dev/null
@@ -1,69 +0,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.
- */
-package org.argeo.jackrabbit.servlet;
-
-import java.io.Serializable;
-
-import javax.jcr.LoginException;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.jackrabbit.server.SessionProvider;
-import org.argeo.jcr.JcrUtils;
-
-/**
- * Implements an open session in view patter: a new JCR session is created for
- * each request
- */
-public class OpenInViewSessionProvider implements SessionProvider, Serializable {
-       private static final long serialVersionUID = 2270957712453841368L;
-
-       private final static Log log = LogFactory
-                       .getLog(OpenInViewSessionProvider.class);
-
-       public Session getSession(HttpServletRequest request, Repository rep,
-                       String workspace) throws LoginException, ServletException,
-                       RepositoryException {
-               return login(request, rep, workspace);
-       }
-
-       protected Session login(HttpServletRequest request, Repository repository,
-                       String workspace) throws RepositoryException {
-               if (log.isTraceEnabled())
-                       log.trace("Login to workspace "
-                                       + (workspace == null ? "<default>" : workspace)
-                                       + " in web session " + request.getSession().getId());
-               return repository.login(workspace);
-       }
-
-       public void releaseSession(Session session) {
-               JcrUtils.logoutQuietly(session);
-               if (log.isTraceEnabled())
-                       log.trace("Logged out remote JCR session " + session);
-       }
-
-       public void init() {
-       }
-
-       public void destroy() {
-       }
-
-}
diff --git a/org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/servlet/RemotingServlet.java b/org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/servlet/RemotingServlet.java
deleted file mode 100644 (file)
index 01bbb35..0000000
+++ /dev/null
@@ -1,50 +0,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.
- */
-package org.argeo.jackrabbit.servlet;
-
-import javax.jcr.Repository;
-
-import org.apache.jackrabbit.server.SessionProvider;
-import org.apache.jackrabbit.server.remoting.davex.JcrRemotingServlet;
-
-/** Provides remote access to a JCR repository */
-public class RemotingServlet extends JcrRemotingServlet {
-       public final static String INIT_PARAM_RESOURCE_PATH_PREFIX = JcrRemotingServlet.INIT_PARAM_RESOURCE_PATH_PREFIX;
-       public final static String INIT_PARAM_HOME = JcrRemotingServlet.INIT_PARAM_HOME;
-       public final static String INIT_PARAM_TMP_DIRECTORY = JcrRemotingServlet.INIT_PARAM_TMP_DIRECTORY;
-
-       private static final long serialVersionUID = 3131835511468341309L;
-
-       private final Repository repository;
-       private final SessionProvider sessionProvider;
-
-       public RemotingServlet(Repository repository,
-                       SessionProvider sessionProvider) {
-               this.repository = repository;
-               this.sessionProvider = sessionProvider;
-       }
-
-       @Override
-       protected Repository getRepository() {
-               return repository;
-       }
-
-       @Override
-       protected SessionProvider getSessionProvider() {
-               return sessionProvider;
-       }
-
-}
diff --git a/org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/servlet/WebdavServlet.java b/org.argeo.server.jackrabbit/src/org/argeo/jackrabbit/servlet/WebdavServlet.java
deleted file mode 100644 (file)
index c2346f0..0000000
+++ /dev/null
@@ -1,62 +0,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.
- */
-package org.argeo.jackrabbit.servlet;
-
-import java.io.IOException;
-
-import javax.jcr.Repository;
-import javax.servlet.ServletException;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.jackrabbit.server.SessionProvider;
-import org.apache.jackrabbit.webdav.DavException;
-import org.apache.jackrabbit.webdav.DavResource;
-import org.apache.jackrabbit.webdav.WebdavRequest;
-import org.apache.jackrabbit.webdav.WebdavResponse;
-import org.apache.jackrabbit.webdav.simple.SimpleWebdavServlet;
-
-/** WebDav servlet whose repository is injected */
-public class WebdavServlet extends SimpleWebdavServlet {
-       public final static String INIT_PARAM_RESOURCE_CONFIG = SimpleWebdavServlet.INIT_PARAM_RESOURCE_CONFIG;
-       public final static String INIT_PARAM_RESOURCE_PATH_PREFIX = SimpleWebdavServlet.INIT_PARAM_RESOURCE_PATH_PREFIX;
-
-       private static final long serialVersionUID = -369787931175177080L;
-
-       private final static Log log = LogFactory.getLog(WebdavServlet.class);
-
-       private final Repository repository;
-
-       public WebdavServlet(Repository repository, SessionProvider sessionProvider) {
-               this.repository = repository;
-               setSessionProvider(sessionProvider);
-       }
-
-       public Repository getRepository() {
-               return repository;
-       }
-
-       @Override
-       protected boolean execute(WebdavRequest request, WebdavResponse response,
-                       int method, DavResource resource) throws ServletException,
-                       IOException, DavException {
-               if (log.isTraceEnabled())
-                       log.trace(request.getMethod() + "\t" + request.getPathInfo());
-               boolean res = super.execute(request, response, method, resource);
-               return res;
-       }
-
-}
index 2b0bd1b2c6d7760ab18119fb86f018458c616cb5..d0385e232fa7446c10618de49c623afd310c5007 100644 (file)
@@ -3,4 +3,8 @@ org.xml.sax;version="0.0.0",\
 org.springframework.core;resolution:=optional,\
 org.springframework.core.io;resolution:=optional,\
 org.springframework.*;resolution:=optional,\
+org.apache.jackrabbit.*;resolution:=optional,\
+org.apache.jackrabbit.webdav.jcr;resolution:=optional,\
+org.apache.jackrabbit.webdav.server;resolution:=optional,\
 *
+Export-Package: org.argeo.jcr.*, org.argeo.jackrabbit.*
\ No newline at end of file
index bea93665153f7678cd514a5a9f0986e017515d5e..1d2423681396603cf73e7a4c174e1a2b423dfafa 100644 (file)
@@ -1,7 +1,6 @@
 source.. = src/,\
            ext/test/
-output.. = bin/,\
-           bin/test-classes/
+output.. = bin/
 bin.includes = META-INF/,\
                .
 additional.bundles = org.junit,\
@@ -12,4 +11,3 @@ additional.bundles = org.junit,\
                      org.apache.jackrabbit.jcr.commons,\
                      org.apache.jackrabbit.spi,\
                      org.apache.jackrabbit.spi.commons
-
index 790c7dfee0703b1a098d89ffea546c5f8d55e84f..95e49a8438cccb0416c8a74dbe049bcc497363af 100644 (file)
                <relativePath>..</relativePath>
        </parent>
        <artifactId>org.argeo.server.jcr</artifactId>
-       <name>Commons Server JCR</name>
-       <build>
-               <plugins>
-                       <plugin>
-                               <groupId>org.argeo.maven.plugins</groupId>
-                               <artifactId>maven-argeo-osgi-plugin</artifactId>
-                               <configuration>
-                                       <useDependencies>true</useDependencies>
-                                       <onlyCheck>true</onlyCheck>
-                                       <argsToAppend>
-                                               <arg>-clean</arg>
-                                       </argsToAppend>
-                                       <systemProperties>
-                                               <!-- Make sure that no bundle will be started -->
-                                               <argeo.osgi.start>XXX</argeo.osgi.start>
-                                       </systemProperties>
-                               </configuration>
-                       </plugin>
-               </plugins>
-       </build>
+       <name>Commons JCR</name>
        <dependencies>
                <dependency>
                        <groupId>org.argeo.commons</groupId>
                        <artifactId>org.argeo.util</artifactId>
                        <version>2.1.14-SNAPSHOT</version>
                </dependency>
-
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.tp</groupId> -->
-<!--                   <artifactId>argeo-tp</artifactId> -->
-<!--                   <version>${version.argeo-distribution}</version> -->
-<!--                   <type>pom</type> -->
-<!--                   <scope>provided</scope> -->
-<!--           </dependency> -->
-
-               <!-- JCR -->
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.tp</groupId> -->
-<!--                   <artifactId>javax.jcr</artifactId> -->
-<!--           </dependency> -->
-
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.tp</groupId> -->
-<!--                   <artifactId>org.apache.commons.io</artifactId> -->
-<!--           </dependency> -->
-
-               <!-- Spring -->
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.tp</groupId> -->
-<!--                   <artifactId>org.springframework.core</artifactId> -->
-<!--                   <scope>provided</scope> -->
-<!--           </dependency> -->
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.tp</groupId> -->
-<!--                   <artifactId>org.springframework.beans</artifactId> -->
-<!--                   <scope>provided</scope> -->
-<!--           </dependency> -->
-
-               <!-- OSGi -->
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.tp</groupId> -->
-<!--                   <artifactId>org.eclipse.osgi</artifactId> -->
-<!--                   <scope>provided</scope> -->
-<!--           </dependency> -->
-
-               <!-- Logging -->
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.tp</groupId> -->
-<!--                   <artifactId>slf4j.org.apache.commons.logging</artifactId> -->
-<!--           </dependency> -->
-
-
-               <!-- TEST -->
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.tp</groupId> -->
-<!--                   <artifactId>junit</artifactId> -->
-<!--                   <optional>true</optional> -->
-<!--           </dependency> -->
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.commons</groupId> -->
-<!--                   <artifactId>org.argeo.dep.jackrabbit</artifactId> -->
-<!--                   <version>2.1.12-SNAPSHOT</version> -->
-<!--                   <type>pom</type> -->
-<!--                   <scope>test</scope> -->
-<!--           </dependency> -->
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.commons</groupId> -->
-<!--                   <artifactId>org.argeo.dep.log4j</artifactId> -->
-<!--                   <version>2.1.12-SNAPSHOT</version> -->
-<!--                   <type>pom</type> -->
-<!--                   <scope>test</scope> -->
-<!--           </dependency> -->
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.commons</groupId> -->
-<!--                   <artifactId>org.argeo.osgi.boot</artifactId> -->
-<!--                   <version>2.1.12-SNAPSHOT</version> -->
-<!--                   <scope>test</scope> -->
-<!--           </dependency> -->
        </dependencies>
 </project>
\ No newline at end of file
diff --git a/org.argeo.server.jcr/src/org/argeo/jackrabbit/JackrabbitAuthorizations.java b/org.argeo.server.jcr/src/org/argeo/jackrabbit/JackrabbitAuthorizations.java
new file mode 100644 (file)
index 0000000..e880b67
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+package org.argeo.jackrabbit;
+
+import java.security.Principal;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.api.JackrabbitSession;
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.argeo.ArgeoException;
+import org.argeo.jcr.security.JcrAuthorizations;
+
+/** Apply authorizations to a Jackrabbit repository. */
+public class JackrabbitAuthorizations extends JcrAuthorizations {
+       private final static Log log = LogFactory
+                       .getLog(JackrabbitAuthorizations.class);
+
+       private List<String> groupPrefixes = Arrays
+                       .asList(new String[] { "ROLE_" });// new ArrayList<String>();
+
+       @Override
+       protected Principal getOrCreatePrincipal(Session session,
+                       String principalName) throws RepositoryException {
+               UserManager um = ((JackrabbitSession) session).getUserManager();
+               synchronized (um) {
+                       Authorizable authorizable = um.getAuthorizable(principalName);
+                       if (authorizable == null) {
+                               groupPrefixes: for (String groupPrefix : groupPrefixes) {
+                                       if (principalName.startsWith(groupPrefix)) {
+                                               authorizable = um.createGroup(principalName);
+                                               log.info("Created group " + principalName);
+                                               break groupPrefixes;
+                                       }
+                               }
+                               if (authorizable == null)
+                                       throw new ArgeoException("Authorizable " + principalName
+                                                       + " not found");
+                       }
+                       return authorizable.getPrincipal();
+               }
+       }
+
+       public void setGroupPrefixes(List<String> groupsToCreate) {
+               this.groupPrefixes = groupsToCreate;
+       }
+}
diff --git a/org.argeo.server.jcr/src/org/argeo/jackrabbit/JackrabbitContainer.java b/org.argeo.server.jcr/src/org/argeo/jackrabbit/JackrabbitContainer.java
new file mode 100644 (file)
index 0000000..82d58fb
--- /dev/null
@@ -0,0 +1,374 @@
+/*
+ * 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.
+ */
+package org.argeo.jackrabbit;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.UUID;
+
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.api.JackrabbitRepository;
+import org.apache.jackrabbit.core.RepositoryImpl;
+import org.apache.jackrabbit.core.config.RepositoryConfig;
+import org.apache.jackrabbit.core.config.RepositoryConfigurationParser;
+import org.argeo.ArgeoException;
+import org.argeo.jcr.ArgeoNames;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.MaintainedRepository;
+import org.springframework.core.io.Resource;
+import org.springframework.util.SystemPropertyUtils;
+import org.xml.sax.InputSource;
+
+/**
+ * Wrapper around a Jackrabbit repository which allows to configure it in Spring
+ * and expose it as a {@link Repository}.
+ */
+public class JackrabbitContainer extends JackrabbitWrapper implements
+               MaintainedRepository {
+       private final static Log log = LogFactory.getLog(JackrabbitContainer.class);
+
+       // local
+       private Resource configuration;
+
+       private Resource variables;
+
+       private RepositoryConfig repositoryConfig;
+       private File homeDirectory;
+       private Boolean inMemory = false;
+
+       /** Migrations to execute (if not already done) */
+       private Set<JackrabbitDataModelMigration> dataModelMigrations = new HashSet<JackrabbitDataModelMigration>();
+
+       /** Straight (non spring) values */
+       private Properties configurationProperties;
+       private InputSource configurationXml;
+
+       /**
+        * Empty constructor, {@link #init()} should be called after properties have
+        * been set
+        */
+       public JackrabbitContainer() {
+       }
+
+       public void init() {
+               long begin = System.currentTimeMillis();
+
+               if (getRepository() != null)
+                       throw new ArgeoException(
+                                       "Cannot be used to wrap another repository");
+               Repository repository = createJackrabbitRepository();
+               super.setRepository(repository);
+
+               // migrate if needed
+               migrate();
+
+               // apply new CND files after migration
+               prepareDataModel();
+
+               double duration = ((double) (System.currentTimeMillis() - begin)) / 1000;
+               if (log.isDebugEnabled())
+                       log.debug("Initialized JCR repository wrapper in " + duration
+                                       + " s");
+       }
+
+       /** Actually creates the new repository. */
+       protected Repository createJackrabbitRepository() {
+               long begin = System.currentTimeMillis();
+               InputStream configurationIn = null;
+               Repository repository;
+               try {
+                       // temporary
+                       if (inMemory && getHomeDirectory().exists()) {
+                               FileUtils.deleteDirectory(getHomeDirectory());
+                               log.warn("Deleted Jackrabbit home directory "
+                                               + getHomeDirectory());
+                       }
+
+                       // process configuration file
+                       Properties vars = getConfigurationProperties();
+                       vars.put(RepositoryConfigurationParser.REPOSITORY_HOME_VARIABLE,
+                                       getHomeDirectory().getCanonicalPath());
+                       InputSource is;
+                       if (configurationXml != null)
+                               is = configurationXml;
+                       else {
+                               configurationIn = readConfiguration();
+                               is = new InputSource(configurationIn);
+                       }
+                       repositoryConfig = RepositoryConfig.create(is, vars);
+
+                       //
+                       // Actual repository creation
+                       //
+                       repository = RepositoryImpl.create(repositoryConfig);
+
+                       double duration = ((double) (System.currentTimeMillis() - begin)) / 1000;
+                       if (log.isTraceEnabled())
+                               log.trace("Created Jackrabbit repository in " + duration
+                                               + " s, home: " + getHomeDirectory());
+
+                       return repository;
+               } catch (Exception e) {
+                       throw new ArgeoException("Cannot create Jackrabbit repository "
+                                       + getHomeDirectory(), e);
+               } finally {
+                       IOUtils.closeQuietly(configurationIn);
+               }
+       }
+
+       /** Lazy init. */
+       protected File getHomeDirectory() {
+               try {
+                       if (homeDirectory == null) {
+                               if (inMemory) {
+                                       homeDirectory = new File(
+                                                       System.getProperty("java.io.tmpdir")
+                                                                       + File.separator
+                                                                       + System.getProperty("user.name")
+                                                                       + File.separator + "jackrabbit-"
+                                                                       + UUID.randomUUID());
+                                       homeDirectory.mkdirs();
+                                       // will it work if directory is not empty??
+                                       homeDirectory.deleteOnExit();
+                               }
+                       }
+
+                       return homeDirectory.getCanonicalFile();
+               } catch (IOException e) {
+                       throw new ArgeoException("Cannot get canonical file for "
+                                       + homeDirectory, e);
+               }
+       }
+
+       /** Executes migrations, if needed. */
+       protected void migrate() {
+               // No migration to perform
+               if (dataModelMigrations.size() == 0)
+                       return;
+
+               Boolean restartAndClearCaches = false;
+
+               // migrate data
+               Session session = null;
+               try {
+                       session = login();
+                       for (JackrabbitDataModelMigration dataModelMigration : new TreeSet<JackrabbitDataModelMigration>(
+                                       dataModelMigrations)) {
+                               if (dataModelMigration.migrate(session)) {
+                                       restartAndClearCaches = true;
+                               }
+                       }
+               } catch (ArgeoException e) {
+                       throw e;
+               } catch (Exception e) {
+                       throw new ArgeoException("Cannot migrate", e);
+               } finally {
+                       JcrUtils.logoutQuietly(session);
+               }
+
+               // restart repository
+               if (restartAndClearCaches) {
+                       Repository repository = getRepository();
+                       if (repository instanceof RepositoryImpl) {
+                               JackrabbitDataModelMigration
+                                               .clearRepositoryCaches(((RepositoryImpl) repository)
+                                                               .getConfig());
+                       }
+                       ((JackrabbitRepository) repository).shutdown();
+                       createJackrabbitRepository();
+               }
+
+               // set data model version
+               try {
+                       session = login();
+               } catch (RepositoryException e) {
+                       throw new ArgeoException("Cannot login to migrated repository", e);
+               }
+
+               for (JackrabbitDataModelMigration dataModelMigration : new TreeSet<JackrabbitDataModelMigration>(
+                               dataModelMigrations)) {
+                       try {
+                               if (session.itemExists(dataModelMigration
+                                               .getDataModelNodePath())) {
+                                       Node dataModelNode = session.getNode(dataModelMigration
+                                                       .getDataModelNodePath());
+                                       dataModelNode.setProperty(
+                                                       ArgeoNames.ARGEO_DATA_MODEL_VERSION,
+                                                       dataModelMigration.getTargetVersion());
+                                       session.save();
+                               }
+                       } catch (Exception e) {
+                               log.error("Cannot set model version", e);
+                       }
+               }
+               JcrUtils.logoutQuietly(session);
+
+       }
+
+       /** Shutdown the repository */
+       public void destroy() throws Exception {
+               Repository repository = getRepository();
+               if (repository != null && repository instanceof RepositoryImpl) {
+                       long begin = System.currentTimeMillis();
+                       ((RepositoryImpl) repository).shutdown();
+                       if (inMemory)
+                               if (getHomeDirectory().exists()) {
+                                       FileUtils.deleteDirectory(getHomeDirectory());
+                                       if (log.isDebugEnabled())
+                                               log.debug("Deleted Jackrabbit home directory "
+                                                               + getHomeDirectory());
+                               }
+                       double duration = ((double) (System.currentTimeMillis() - begin)) / 1000;
+                       log.info("Destroyed Jackrabbit repository in " + duration
+                                       + " s, home: " + getHomeDirectory());
+               }
+               repository = null;
+       }
+
+       public void dispose() {
+               throw new IllegalArgumentException(
+                               "Call destroy() method instead of dispose()");
+       }
+
+       /*
+        * UTILITIES
+        */
+       /**
+        * Reads the configuration which will initialize a {@link RepositoryConfig}.
+        */
+       protected InputStream readConfiguration() {
+               try {
+                       return configuration != null ? configuration.getInputStream()
+                                       : null;
+               } catch (IOException e) {
+                       throw new ArgeoException("Cannot read Jackrabbit configuration "
+                                       + configuration, e);
+               }
+       }
+
+       /**
+        * Reads the variables which will initialize a {@link Properties}. Returns
+        * null by default, to be overridden.
+        * 
+        * @return a new stream or null if no variables available
+        */
+       protected InputStream readVariables() {
+               try {
+                       return variables != null ? variables.getInputStream() : null;
+               } catch (IOException e) {
+                       throw new ArgeoException("Cannot read Jackrabbit variables "
+                                       + variables, e);
+               }
+       }
+
+       /**
+        * Resolves ${} placeholders in the provided string. Based on system
+        * properties if no map is provided.
+        */
+       protected String resolvePlaceholders(String string,
+                       Map<String, String> variables) {
+               return SystemPropertyUtils.resolvePlaceholders(string);
+       }
+
+       /** Generates the properties to use in the configuration. */
+       protected Properties getConfigurationProperties() {
+               if (configurationProperties != null)
+                       return configurationProperties;
+
+               InputStream propsIn = null;
+               Properties vars;
+               try {
+                       vars = new Properties();
+                       propsIn = readVariables();
+                       if (propsIn != null) {
+                               vars.load(propsIn);
+                       }
+                       // resolve system properties
+                       for (Object key : vars.keySet()) {
+                               // TODO: implement a smarter mechanism to resolve nested ${}
+                               String newValue = resolvePlaceholders(
+                                               vars.getProperty(key.toString()), null);
+                               vars.put(key, newValue);
+                       }
+                       // override with system properties
+                       vars.putAll(System.getProperties());
+
+                       if (log.isTraceEnabled()) {
+                               log.trace("Jackrabbit config variables:");
+                               for (Object key : new TreeSet<Object>(vars.keySet()))
+                                       log.trace(key + "=" + vars.getProperty(key.toString()));
+                       }
+
+               } catch (IOException e) {
+                       throw new ArgeoException("Cannot read configuration properties", e);
+               } finally {
+                       IOUtils.closeQuietly(propsIn);
+               }
+               return vars;
+       }
+
+       /*
+        * FIELDS ACCESS
+        */
+
+       public void setHomeDirectory(File homeDirectory) {
+               this.homeDirectory = homeDirectory;
+       }
+
+       public void setInMemory(Boolean inMemory) {
+               this.inMemory = inMemory;
+       }
+
+       public void setRepository(Repository repository) {
+               throw new ArgeoException("Cannot be used to wrap another repository");
+       }
+
+       public void setDataModelMigrations(
+                       Set<JackrabbitDataModelMigration> dataModelMigrations) {
+               this.dataModelMigrations = dataModelMigrations;
+       }
+
+       public void setVariables(Resource variables) {
+               this.variables = variables;
+       }
+
+       public void setConfiguration(Resource configuration) {
+               this.configuration = configuration;
+       }
+
+       public void setConfigurationProperties(Properties configurationProperties) {
+               this.configurationProperties = configurationProperties;
+       }
+
+       public void setConfigurationXml(InputSource configurationXml) {
+               this.configurationXml = configurationXml;
+       }
+
+}
diff --git a/org.argeo.server.jcr/src/org/argeo/jackrabbit/JackrabbitDataModelMigration.java b/org.argeo.server.jcr/src/org/argeo/jackrabbit/JackrabbitDataModelMigration.java
new file mode 100644 (file)
index 0000000..401b34d
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * 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.
+ */
+package org.argeo.jackrabbit;
+
+import java.io.InputStreamReader;
+import java.io.Reader;
+
+import javax.jcr.Node;
+import javax.jcr.Session;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.commons.cnd.CndImporter;
+import org.apache.jackrabbit.core.config.RepositoryConfig;
+import org.argeo.ArgeoException;
+import org.argeo.jcr.ArgeoNames;
+import org.argeo.jcr.JcrCallback;
+import org.argeo.jcr.JcrUtils;
+import org.springframework.core.io.Resource;
+
+/** Migrate the data in a Jackrabbit repository. */
+public class JackrabbitDataModelMigration implements
+               Comparable<JackrabbitDataModelMigration> {
+       private final static Log log = LogFactory
+                       .getLog(JackrabbitDataModelMigration.class);
+
+       private String dataModelNodePath;
+       private String targetVersion;
+       private Resource migrationCnd;
+       private JcrCallback dataModification;
+
+       /**
+        * Expects an already started repository with the old data model to migrate.
+        * Expects to be run with admin rights (Repository.login() will be used).
+        * 
+        * @return true if a migration was performed and the repository needs to be
+        *         restarted and its caches cleared.
+        */
+       public Boolean migrate(Session session) {
+               long begin = System.currentTimeMillis();
+               Reader reader = null;
+               try {
+                       // check if already migrated
+                       if (!session.itemExists(dataModelNodePath)) {
+                               log.warn("Node " + dataModelNodePath
+                                               + " does not exist: nothing to migrate.");
+                               return false;
+                       }
+                       Node dataModelNode = session.getNode(dataModelNodePath);
+                       if (dataModelNode.hasProperty(ArgeoNames.ARGEO_DATA_MODEL_VERSION)) {
+                               String currentVersion = dataModelNode.getProperty(
+                                               ArgeoNames.ARGEO_DATA_MODEL_VERSION).getString();
+                               if (compareVersions(currentVersion, targetVersion) >= 0) {
+                                       log.info("Data model at version " + currentVersion
+                                                       + ", no need to migrate.");
+                                       return false;
+                               }
+                       }
+
+                       // apply transitional CND
+                       if (migrationCnd != null) {
+                               reader = new InputStreamReader(migrationCnd.getInputStream());
+                               CndImporter.registerNodeTypes(reader, session, true);
+                               session.save();
+                               log.info("Registered migration node types from " + migrationCnd);
+                       }
+
+                       // modify data
+                       dataModification.execute(session);
+
+                       // apply changes
+                       session.save();
+
+                       long duration = System.currentTimeMillis() - begin;
+                       log.info("Migration of data model " + dataModelNodePath + " to "
+                                       + targetVersion + " performed in " + duration + "ms");
+                       return true;
+               } catch (Exception e) {
+                       JcrUtils.discardQuietly(session);
+                       throw new ArgeoException("Migration of data model "
+                                       + dataModelNodePath + " to " + targetVersion + " failed.",
+                                       e);
+               } finally {
+                       JcrUtils.logoutQuietly(session);
+                       IOUtils.closeQuietly(reader);
+               }
+       }
+
+       protected static int compareVersions(String version1, String version2) {
+               // TODO do a proper version analysis and comparison
+               return version1.compareTo(version2);
+       }
+
+       /** To be called on a stopped repository. */
+       public static void clearRepositoryCaches(RepositoryConfig repositoryConfig) {
+               try {
+                       String customeNodeTypesPath = "/nodetypes/custom_nodetypes.xml";
+                       repositoryConfig.getFileSystem().deleteFile(customeNodeTypesPath);
+                       if (log.isDebugEnabled())
+                               log.debug("Cleared " + customeNodeTypesPath);
+               } catch (Exception e) {
+                       throw new ArgeoException("Cannot clear caches", e);
+               }
+
+               // File customNodeTypes = new File(home.getPath()
+               // + "/repository/nodetypes/custom_nodetypes.xml");
+               // if (customNodeTypes.exists()) {
+               // customNodeTypes.delete();
+               // if (log.isDebugEnabled())
+               // log.debug("Cleared " + customNodeTypes);
+               // } else {
+               // log.warn("File " + customNodeTypes + " not found.");
+               // }
+       }
+
+       /*
+        * FOR USE IN (SORTED) SETS
+        */
+
+       public int compareTo(JackrabbitDataModelMigration dataModelMigration) {
+               // TODO make ordering smarter
+               if (dataModelNodePath.equals(dataModelMigration.dataModelNodePath))
+                       return compareVersions(targetVersion,
+                                       dataModelMigration.targetVersion);
+               else
+                       return dataModelNodePath
+                                       .compareTo(dataModelMigration.dataModelNodePath);
+       }
+
+       @Override
+       public boolean equals(Object obj) {
+               if (!(obj instanceof JackrabbitDataModelMigration))
+                       return false;
+               JackrabbitDataModelMigration dataModelMigration = (JackrabbitDataModelMigration) obj;
+               return dataModelNodePath.equals(dataModelMigration.dataModelNodePath)
+                               && targetVersion.equals(dataModelMigration.targetVersion);
+       }
+
+       @Override
+       public int hashCode() {
+               return targetVersion.hashCode();
+       }
+
+       public void setDataModelNodePath(String dataModelNodePath) {
+               this.dataModelNodePath = dataModelNodePath;
+       }
+
+       public void setTargetVersion(String targetVersion) {
+               this.targetVersion = targetVersion;
+       }
+
+       public void setMigrationCnd(Resource migrationCnd) {
+               this.migrationCnd = migrationCnd;
+       }
+
+       public void setDataModification(JcrCallback dataModification) {
+               this.dataModification = dataModification;
+       }
+
+       public String getDataModelNodePath() {
+               return dataModelNodePath;
+       }
+
+       public String getTargetVersion() {
+               return targetVersion;
+       }
+
+}
diff --git a/org.argeo.server.jcr/src/org/argeo/jackrabbit/JackrabbitRepositoryFactory.java b/org.argeo.server.jcr/src/org/argeo/jackrabbit/JackrabbitRepositoryFactory.java
new file mode 100644 (file)
index 0000000..d64bb5e
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * 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.
+ */
+package org.argeo.jackrabbit;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.RepositoryFactory;
+import javax.jcr.Session;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.commons.JcrUtils;
+import org.apache.jackrabbit.core.RepositoryImpl;
+import org.apache.jackrabbit.core.config.RepositoryConfig;
+import org.apache.jackrabbit.core.config.RepositoryConfigurationParser;
+import org.apache.jackrabbit.jcr2dav.Jcr2davRepositoryFactory;
+import org.argeo.ArgeoException;
+import org.argeo.jcr.ArgeoJcrConstants;
+import org.argeo.jcr.DefaultRepositoryFactory;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+import org.xml.sax.InputSource;
+
+/**
+ * Repository factory which can create new repositories and access remote
+ * Jackrabbit repositories
+ */
+public class JackrabbitRepositoryFactory extends DefaultRepositoryFactory
+               implements RepositoryFactory, ArgeoJcrConstants {
+
+       private final static Log log = LogFactory
+                       .getLog(JackrabbitRepositoryFactory.class);
+
+       private Resource fileRepositoryConfiguration = new ClassPathResource(
+                       "/org/argeo/jackrabbit/repository-h2.xml");
+
+       @SuppressWarnings({ "rawtypes", "unchecked" })
+       public Repository getRepository(Map parameters) throws RepositoryException {
+               // check if can be found by alias
+               Repository repository = super.getRepository(parameters);
+               if (repository != null)
+                       return repository;
+
+               // check if remote
+               String uri = null;
+               if (parameters.containsKey(JCR_REPOSITORY_URI))
+                       uri = parameters.get(JCR_REPOSITORY_URI).toString();
+               else if (parameters.containsKey(JcrUtils.REPOSITORY_URI))
+                       uri = parameters.get(JcrUtils.REPOSITORY_URI).toString();
+
+               if (uri != null) {
+                       if (uri.startsWith("http"))// http, https
+                               repository = createRemoteRepository(uri);
+                       else if (uri.startsWith("file"))// http, https
+                               repository = createFileRepository(uri, parameters);
+                       else if (uri.startsWith("vm")) {
+                               log.warn("URI "
+                                               + uri
+                                               + " should have been managed by generic JCR repository factory");
+                               repository = getRepositoryByAlias(getAliasFromURI(uri));
+                       }
+               }
+
+               // publish under alias
+               if (parameters.containsKey(JCR_REPOSITORY_ALIAS)) {
+                       Properties properties = new Properties();
+                       properties.putAll(parameters);
+                       String alias = parameters.get(JCR_REPOSITORY_ALIAS).toString();
+                       publish(alias, repository, properties);
+                       log.info("Registered JCR repository under alias '" + alias
+                                       + "' with properties " + properties);
+               }
+
+               return repository;
+       }
+
+       protected Repository createRemoteRepository(String uri)
+                       throws RepositoryException {
+               Map<String, String> params = new HashMap<String, String>();
+               params.put(JcrUtils.REPOSITORY_URI, uri);
+               Repository repository = new Jcr2davRepositoryFactory()
+                               .getRepository(params);
+               if (repository == null)
+                       throw new ArgeoException("Remote Davex repository " + uri
+                                       + " not found");
+               log.info("Initialized remote Jackrabbit repository from uri " + uri);
+               return repository;
+       }
+
+       @SuppressWarnings({ "rawtypes", "unchecked" })
+       protected Repository createFileRepository(final String uri, Map parameters)
+                       throws RepositoryException {
+               InputStream configurationIn = null;
+               try {
+                       Properties vars = new Properties();
+                       vars.putAll(parameters);
+                       String dirPath = uri.substring("file:".length());
+                       File homeDir = new File(dirPath);
+                       if (homeDir.exists() && !homeDir.isDirectory())
+                               throw new ArgeoException("Repository home " + dirPath
+                                               + " is not a directory");
+                       if (!homeDir.exists())
+                               homeDir.mkdirs();
+                       configurationIn = fileRepositoryConfiguration.getInputStream();
+                       vars.put(RepositoryConfigurationParser.REPOSITORY_HOME_VARIABLE,
+                                       homeDir.getCanonicalPath());
+                       RepositoryConfig repositoryConfig = RepositoryConfig.create(
+                                       new InputSource(configurationIn), vars);
+
+                       // TransientRepository repository = new
+                       // TransientRepository(repositoryConfig);
+                       final RepositoryImpl repository = RepositoryImpl
+                                       .create(repositoryConfig);
+                       Session session = repository.login();
+                       // FIXME make it generic
+                       org.argeo.jcr.JcrUtils.addPrivilege(session, "/", "ROLE_ADMIN",
+                                       "jcr:all");
+                       org.argeo.jcr.JcrUtils.logoutQuietly(session);
+                       Runtime.getRuntime().addShutdownHook(
+                                       new Thread("Clean JCR repository " + uri) {
+                                               public void run() {
+                                                       repository.shutdown();
+                                                       log.info("Destroyed repository " + uri);
+                                               }
+                                       });
+                       log.info("Initialized file Jackrabbit repository from uri " + uri);
+                       return repository;
+               } catch (Exception e) {
+                       throw new ArgeoException("Cannot create repository " + uri, e);
+               } finally {
+                       IOUtils.closeQuietly(configurationIn);
+               }
+       }
+
+       /**
+        * Called after the repository has been initialised. Does nothing by
+        * default.
+        */
+       @SuppressWarnings("rawtypes")
+       protected void postInitialization(Repository repository, Map parameters) {
+
+       }
+
+       public void setFileRepositoryConfiguration(
+                       Resource fileRepositoryConfiguration) {
+               this.fileRepositoryConfiguration = fileRepositoryConfiguration;
+       }
+
+}
diff --git a/org.argeo.server.jcr/src/org/argeo/jackrabbit/JackrabbitWrapper.java b/org.argeo.server.jcr/src/org/argeo/jackrabbit/JackrabbitWrapper.java
new file mode 100644 (file)
index 0000000..53a9ff1
--- /dev/null
@@ -0,0 +1,379 @@
+/*
+ * 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.
+ */
+package org.argeo.jackrabbit;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.Credentials;
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Repository;
+import javax.jcr.Session;
+import javax.jcr.nodetype.NodeType;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.commons.NamespaceHelper;
+import org.apache.jackrabbit.commons.cnd.CndImporter;
+import org.argeo.ArgeoException;
+import org.argeo.jcr.ArgeoJcrConstants;
+import org.argeo.jcr.ArgeoNames;
+import org.argeo.jcr.ArgeoTypes;
+import org.argeo.jcr.JcrRepositoryWrapper;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.util.security.DigestUtils;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.packageadmin.ExportedPackage;
+import org.osgi.service.packageadmin.PackageAdmin;
+import org.springframework.context.ResourceLoaderAware;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+
+/**
+ * Wrapper around a Jackrabbit repository which allows to simplify configuration
+ * and intercept some actions. It exposes itself as a {@link Repository}.
+ */
+public class JackrabbitWrapper extends JcrRepositoryWrapper implements
+               ResourceLoaderAware {
+       private final static Log log = LogFactory.getLog(JackrabbitWrapper.class);
+       private final static String DIGEST_ALGORITHM = "MD5";
+
+       // local
+       private ResourceLoader resourceLoader;
+
+       // data model
+       /** Node type definitions in CND format */
+       private List<String> cndFiles = new ArrayList<String>();
+       /**
+        * Always import CNDs. Useful during development of new data models. In
+        * production, explicit migration processes should be used.
+        */
+       private Boolean forceCndImport = true;
+
+       /** Namespaces to register: key is prefix, value namespace */
+       private Map<String, String> namespaces = new HashMap<String, String>();
+
+       private BundleContext bundleContext;
+
+       /**
+        * Explicitly set admin credentials used in initialization. Useful for
+        * testing, in real applications authentication is rather dealt with
+        * externally
+        */
+       private Credentials adminCredentials = null;
+
+       /**
+        * Empty constructor, {@link #init()} should be called after properties have
+        * been set
+        */
+       public JackrabbitWrapper() {
+       }
+
+       @Override
+       public void init() {
+               prepareDataModel();
+       }
+
+       /*
+        * DATA MODEL
+        */
+
+       /**
+        * Import declared node type definitions and register namespaces. Tries to
+        * update the node definitions if they have changed. In case of failures an
+        * error will be logged but no exception will be thrown.
+        */
+       protected void prepareDataModel() {
+               if ((cndFiles == null || cndFiles.size() == 0)
+                               && (namespaces == null || namespaces.size() == 0))
+                       return;
+
+               Session session = null;
+               try {
+                       session = login(adminCredentials);
+                       // register namespaces
+                       if (namespaces.size() > 0) {
+                               NamespaceHelper namespaceHelper = new NamespaceHelper(session);
+                               namespaceHelper.registerNamespaces(namespaces);
+                       }
+
+                       // load CND files from classpath or as URL
+                       for (String resUrl : cndFiles) {
+                               processCndFile(session, resUrl);
+                       }
+               } catch (Exception e) {
+                       JcrUtils.discardQuietly(session);
+                       throw new ArgeoException("Cannot import node type definitions "
+                                       + cndFiles, e);
+               } finally {
+                       JcrUtils.logoutQuietly(session);
+               }
+
+       }
+
+       protected void processCndFile(Session session, String resUrl) {
+               Reader reader = null;
+               try {
+                       // check existing data model nodes
+                       new NamespaceHelper(session).registerNamespace(ArgeoNames.ARGEO,
+                                       ArgeoNames.ARGEO_NAMESPACE);
+                       if (!session.itemExists(ArgeoJcrConstants.DATA_MODELS_BASE_PATH))
+                               JcrUtils.mkdirs(session,
+                                               ArgeoJcrConstants.DATA_MODELS_BASE_PATH);
+                       Node dataModels = session
+                                       .getNode(ArgeoJcrConstants.DATA_MODELS_BASE_PATH);
+                       NodeIterator it = dataModels.getNodes();
+                       Node dataModel = null;
+                       while (it.hasNext()) {
+                               Node node = it.nextNode();
+                               if (node.getProperty(ArgeoNames.ARGEO_URI).getString()
+                                               .equals(resUrl)) {
+                                       dataModel = node;
+                                       break;
+                               }
+                       }
+
+                       byte[] cndContent = readCndContent(resUrl);
+                       String newDigest = DigestUtils.digest(DIGEST_ALGORITHM, cndContent);
+                       Bundle bundle = findDataModelBundle(resUrl);
+
+                       String currentVersion = null;
+                       if (dataModel != null) {
+                               currentVersion = dataModel.getProperty(
+                                               ArgeoNames.ARGEO_DATA_MODEL_VERSION).getString();
+                               if (dataModel.hasNode(Node.JCR_CONTENT)) {
+                                       String oldDigest = JcrUtils.checksumFile(dataModel,
+                                                       DIGEST_ALGORITHM);
+                                       if (oldDigest.equals(newDigest)) {
+                                               if (log.isDebugEnabled())
+                                                       log.debug("Data model " + resUrl
+                                                                       + " hasn't changed, keeping version "
+                                                                       + currentVersion);
+                                               return;
+                                       }
+                               }
+                       }
+
+                       if (dataModel != null && !forceCndImport) {
+                               log.info("Data model "
+                                               + resUrl
+                                               + " has changed since version "
+                                               + currentVersion
+                                               + (bundle != null ? ": version " + bundle.getVersion()
+                                                               + ", bundle " + bundle.getSymbolicName() : ""));
+                               return;
+                       }
+
+                       reader = new InputStreamReader(new ByteArrayInputStream(cndContent));
+                       // actually imports the CND
+                       try {
+                               CndImporter.registerNodeTypes(reader, session, true);
+                       } catch (Exception e) {
+                               log.error("Cannot import data model " + resUrl, e);
+                               return;
+                       }
+
+                       if (dataModel != null && !dataModel.isNodeType(NodeType.NT_FILE)) {
+                               dataModel.remove();
+                               dataModel = null;
+                       }
+
+                       // FIXME: what if argeo.cnd would not be the first called on
+                       // a new repo? argeo:dataModel would not be found
+                       String fileName = FilenameUtils.getName(resUrl);
+                       if (dataModel == null) {
+                               dataModel = dataModels.addNode(fileName, NodeType.NT_FILE);
+                               dataModel.addNode(Node.JCR_CONTENT, NodeType.NT_RESOURCE);
+                               dataModel.addMixin(ArgeoTypes.ARGEO_DATA_MODEL);
+                               dataModel.setProperty(ArgeoNames.ARGEO_URI, resUrl);
+                       } else {
+                               session.getWorkspace().getVersionManager()
+                                               .checkout(dataModel.getPath());
+                       }
+                       if (bundle != null)
+                               dataModel.setProperty(ArgeoNames.ARGEO_DATA_MODEL_VERSION,
+                                               bundle.getVersion().toString());
+                       else
+                               dataModel.setProperty(ArgeoNames.ARGEO_DATA_MODEL_VERSION,
+                                               "0.0.0");
+                       JcrUtils.copyBytesAsFile(dataModel.getParent(), fileName,
+                                       cndContent);
+                       JcrUtils.updateLastModified(dataModel);
+                       session.save();
+                       session.getWorkspace().getVersionManager()
+                                       .checkin(dataModel.getPath());
+
+                       if (currentVersion == null)
+                               log.info("Data model "
+                                               + resUrl
+                                               + (bundle != null ? ", version " + bundle.getVersion()
+                                                               + ", bundle " + bundle.getSymbolicName() : ""));
+                       else
+                               log.info("Data model "
+                                               + resUrl
+                                               + " updated from version "
+                                               + currentVersion
+                                               + (bundle != null ? ", version " + bundle.getVersion()
+                                                               + ", bundle " + bundle.getSymbolicName() : ""));
+               } catch (Exception e) {
+                       throw new ArgeoException("Cannot process data model " + resUrl, e);
+               } finally {
+                       IOUtils.closeQuietly(reader);
+               }
+       }
+
+       protected byte[] readCndContent(String resUrl) {
+               InputStream in = null;
+               try {
+                       boolean classpath;
+                       // normalize URL
+                       if (bundleContext != null && resUrl.startsWith("classpath:")) {
+                               resUrl = resUrl.substring("classpath:".length());
+                               classpath = true;
+                       } else if (resUrl.indexOf(':') < 0) {
+                               if (!resUrl.startsWith("/")) {
+                                       resUrl = "/" + resUrl;
+                                       log.warn("Classpath should start with '/'");
+                               }
+                               classpath = true;
+                       } else {
+                               classpath = false;
+                       }
+
+                       URL url = null;
+                       if (classpath) {
+                               if (bundleContext != null) {
+                                       Bundle currentBundle = bundleContext.getBundle();
+                                       url = currentBundle.getResource(resUrl);
+                               } else {
+                                       resUrl = "classpath:" + resUrl;
+                                       url = null;
+                               }
+                       } else if (!resUrl.startsWith("classpath:")) {
+                               url = new URL(resUrl);
+                       }
+
+                       if (url != null) {
+                               in = url.openStream();
+                       } else if (resourceLoader != null) {
+                               Resource res = resourceLoader.getResource(resUrl);
+                               in = res.getInputStream();
+                               url = res.getURL();
+                       } else {
+                               throw new ArgeoException("No " + resUrl + " in the classpath,"
+                                               + " make sure the containing" + " package is visible.");
+                       }
+
+                       return IOUtils.toByteArray(in);
+               } catch (Exception e) {
+                       throw new ArgeoException("Cannot read CND from " + resUrl, e);
+               } finally {
+                       IOUtils.closeQuietly(in);
+               }
+       }
+
+       /*
+        * REPOSITORY INTERCEPTOR
+        */
+
+       /*
+        * UTILITIES
+        */
+       /** Find which OSGi bundle provided the data model resource */
+       protected Bundle findDataModelBundle(String resUrl) {
+               if (bundleContext == null)
+                       return null;
+
+               if (resUrl.startsWith("/"))
+                       resUrl = resUrl.substring(1);
+               String pkg = resUrl.substring(0, resUrl.lastIndexOf('/')).replace('/',
+                               '.');
+               ServiceReference paSr = bundleContext
+                               .getServiceReference(PackageAdmin.class.getName());
+               PackageAdmin packageAdmin = (PackageAdmin) bundleContext
+                               .getService(paSr);
+
+               // find exported package
+               ExportedPackage exportedPackage = null;
+               ExportedPackage[] exportedPackages = packageAdmin
+                               .getExportedPackages(pkg);
+               if (exportedPackages == null)
+                       throw new ArgeoException("No exported package found for " + pkg);
+               for (ExportedPackage ep : exportedPackages) {
+                       for (Bundle b : ep.getImportingBundles()) {
+                               if (b.getBundleId() == bundleContext.getBundle().getBundleId()) {
+                                       exportedPackage = ep;
+                                       break;
+                               }
+                       }
+               }
+
+               Bundle exportingBundle = null;
+               if (exportedPackage != null) {
+                       exportingBundle = exportedPackage.getExportingBundle();
+               } else {
+                       // assume this is in the same bundle
+                       exportingBundle = bundleContext.getBundle();
+                       // throw new ArgeoException("No OSGi exporting package found for "
+                       // + resUrl);
+               }
+               return exportingBundle;
+       }
+
+       /*
+        * FIELDS ACCESS
+        */
+       public void setNamespaces(Map<String, String> namespaces) {
+               this.namespaces = namespaces;
+       }
+
+       public void setCndFiles(List<String> cndFiles) {
+               this.cndFiles = cndFiles;
+       }
+
+       public void setBundleContext(BundleContext bundleContext) {
+               this.bundleContext = bundleContext;
+       }
+
+       protected BundleContext getBundleContext() {
+               return bundleContext;
+       }
+
+       public void setForceCndImport(Boolean forceCndUpdate) {
+               this.forceCndImport = forceCndUpdate;
+       }
+
+       public void setResourceLoader(ResourceLoader resourceLoader) {
+               this.resourceLoader = resourceLoader;
+       }
+
+       public void setAdminCredentials(Credentials adminCredentials) {
+               this.adminCredentials = adminCredentials;
+       }
+
+}
diff --git a/org.argeo.server.jcr/src/org/argeo/jackrabbit/OsgiJackrabbitRepositoryFactory.java b/org.argeo.server.jcr/src/org/argeo/jackrabbit/OsgiJackrabbitRepositoryFactory.java
new file mode 100644 (file)
index 0000000..b28699e
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+package org.argeo.jackrabbit;
+
+import java.util.Hashtable;
+import java.util.Properties;
+
+import javax.jcr.Repository;
+
+import org.osgi.framework.BundleContext;
+
+/**
+ * OSGi-aware Jackrabbit repository factory which can retrieve/publish
+ * {@link Repository} as OSGi services.
+ */
+public class OsgiJackrabbitRepositoryFactory extends
+               JackrabbitRepositoryFactory {
+       private BundleContext bundleContext;
+
+       protected void publish(String alias, Repository repository,
+                       Properties properties) {
+               if (bundleContext != null) {
+                       // do not modify reference
+                       Hashtable<String, String> props = new Hashtable<String, String>();
+                       props.putAll(props);
+                       props.put(JCR_REPOSITORY_ALIAS, alias);
+                       bundleContext.registerService(Repository.class.getName(),
+                                       repository, props);
+               }
+       }
+
+       public void setBundleContext(BundleContext bundleContext) {
+               this.bundleContext = bundleContext;
+       }
+
+}
diff --git a/org.argeo.server.jcr/src/org/argeo/jackrabbit/repository-fs.xml b/org.argeo.server.jcr/src/org/argeo/jackrabbit/repository-fs.xml
new file mode 100644 (file)
index 0000000..609fc8b
--- /dev/null
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+<!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}/fs" />
+       </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="${argeo.node.repo.defaultWorkspace}" />
+       <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" />
+               <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
+                       <param name="path" value="${wsp.home}/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" />
+       </Versioning>
+
+       <!-- Indexing -->
+       <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
+               <param name="path" value="${rep.home}/index" />
+               <param name="extractorPoolSize" value="2" />
+               <param name="supportHighlighting" value="true" />
+       </SearchIndex>
+
+       <!-- Security -->
+       <Security appName="Jackrabbit">
+               <SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
+                       workspaceName="security">
+               </SecurityManager>
+               <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager">
+               </AccessManager>
+               <LoginModule class="org.argeo.security.jackrabbit.ArgeoLoginModule">
+               </LoginModule>
+       </Security>
+</Repository>
\ No newline at end of file
diff --git a/org.argeo.server.jcr/src/org/argeo/jackrabbit/repository-h2.xml b/org.argeo.server.jcr/src/org/argeo/jackrabbit/repository-h2.xml
new file mode 100644 (file)
index 0000000..b6a9252
--- /dev/null
@@ -0,0 +1,77 @@
+<?xml version="1.0"?>
+<!DOCTYPE Repository PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit 1.6//EN"
+                            "http://jackrabbit.apache.org/dtd/repository-2.0.dtd">
+<Repository>
+       <!-- Shared datasource -->
+       <DataSources>
+               <DataSource name="dataSource">
+                       <param name="driver" value="org.h2.Driver" />
+                       <param name="url" value="jdbc:h2:${rep.home}/h2/repository" />
+                       <param name="user" value="sa" />
+                       <param name="password" value="" />
+                       <param name="databaseType" value="h2" />
+                       <param name="maxPoolSize" value="10" />
+               </DataSource>
+       </DataSources>
+
+       <!-- File system and datastore -->
+       <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
+               <param name="dataSourceName" value="dataSource" />
+               <param name="schema" value="default" />
+               <param name="schemaObjectPrefix" value="fs_" />
+       </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" />
+       <Workspace name="${wsp.name}">
+               <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
+                       <param name="dataSourceName" value="dataSource" />
+                       <param name="schema" value="default" />
+                       <param name="schemaObjectPrefix" value="${wsp.name}_fs_" />
+               </FileSystem>
+               <PersistenceManager
+                       class="org.apache.jackrabbit.core.persistence.pool.H2PersistenceManager">
+                       <param name="dataSourceName" value="dataSource" />
+                       <param name="schemaObjectPrefix" value="${wsp.name}_pm_" />
+               </PersistenceManager>
+               <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
+                       <param name="path" value="${wsp.home}/index" />
+               </SearchIndex>
+       </Workspace>
+
+       <!-- Versioning -->
+       <Versioning rootPath="${rep.home}/version">
+               <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
+                       <param name="dataSourceName" value="dataSource" />
+                       <param name="schema" value="default" />
+                       <param name="schemaObjectPrefix" value="fs_ver_" />
+               </FileSystem>
+               <PersistenceManager
+                       class="org.apache.jackrabbit.core.persistence.pool.H2PersistenceManager">
+                       <param name="dataSourceName" value="dataSource" />
+                       <param name="schemaObjectPrefix" value="pm_ver_" />
+               </PersistenceManager>
+       </Versioning>
+
+       <!-- Indexing -->
+       <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
+               <param name="path" value="${rep.home}/index" />
+               <param name="extractorPoolSize" value="2" />
+               <param name="supportHighlighting" value="true" />
+       </SearchIndex>
+
+       <!-- Security -->
+       <Security appName="Jackrabbit">
+               <SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
+                       workspaceName="security">
+               </SecurityManager>
+               <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager">
+               </AccessManager>
+               <LoginModule class="org.argeo.security.jackrabbit.ArgeoLoginModule">
+               </LoginModule>
+       </Security>
+</Repository>
\ No newline at end of file
diff --git a/org.argeo.server.jcr/src/org/argeo/jackrabbit/repository-memory.xml b/org.argeo.server.jcr/src/org/argeo/jackrabbit/repository-memory.xml
new file mode 100644 (file)
index 0000000..e552c33
--- /dev/null
@@ -0,0 +1,69 @@
+<?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.mem.MemoryFileSystem" />
+
+       <!-- Workspace templates -->
+       <Workspaces rootPath="${rep.home}/workspaces"
+               defaultWorkspace="main" configRootPath="/workspaces" />
+       <Workspace name="${wsp.name}">
+               <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
+               <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" />
+                       <param name="directoryManagerClass"
+                               value="org.apache.jackrabbit.core.query.lucene.directory.RAMDirectoryManager" />
+                       <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
+               </SearchIndex>
+       </Workspace>
+
+       <!-- Versioning -->
+       <Versioning rootPath="${rep.home}/version">
+               <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
+               <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="directoryManagerClass"
+                       value="org.apache.jackrabbit.core.query.lucene.directory.RAMDirectoryManager" />
+               <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
+       </SearchIndex>
+
+       <!-- Security -->
+       <Security appName="Jackrabbit">
+               <SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
+                       workspaceName="security">
+               </SecurityManager>
+               <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager">
+               </AccessManager>
+               <LoginModule class="org.argeo.security.jackrabbit.ArgeoLoginModule">
+               </LoginModule>
+       </Security>
+</Repository>
\ No newline at end of file
diff --git a/org.argeo.server.jcr/src/org/argeo/jackrabbit/servlet/OpenInViewSessionProvider.java b/org.argeo.server.jcr/src/org/argeo/jackrabbit/servlet/OpenInViewSessionProvider.java
new file mode 100644 (file)
index 0000000..519a218
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+package org.argeo.jackrabbit.servlet;
+
+import java.io.Serializable;
+
+import javax.jcr.LoginException;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.server.SessionProvider;
+import org.argeo.jcr.JcrUtils;
+
+/**
+ * Implements an open session in view patter: a new JCR session is created for
+ * each request
+ */
+public class OpenInViewSessionProvider implements SessionProvider, Serializable {
+       private static final long serialVersionUID = 2270957712453841368L;
+
+       private final static Log log = LogFactory
+                       .getLog(OpenInViewSessionProvider.class);
+
+       public Session getSession(HttpServletRequest request, Repository rep,
+                       String workspace) throws LoginException, ServletException,
+                       RepositoryException {
+               return login(request, rep, workspace);
+       }
+
+       protected Session login(HttpServletRequest request, Repository repository,
+                       String workspace) throws RepositoryException {
+               if (log.isTraceEnabled())
+                       log.trace("Login to workspace "
+                                       + (workspace == null ? "<default>" : workspace)
+                                       + " in web session " + request.getSession().getId());
+               return repository.login(workspace);
+       }
+
+       public void releaseSession(Session session) {
+               JcrUtils.logoutQuietly(session);
+               if (log.isTraceEnabled())
+                       log.trace("Logged out remote JCR session " + session);
+       }
+
+       public void init() {
+       }
+
+       public void destroy() {
+       }
+
+}
diff --git a/org.argeo.server.jcr/src/org/argeo/jackrabbit/servlet/RemotingServlet.java b/org.argeo.server.jcr/src/org/argeo/jackrabbit/servlet/RemotingServlet.java
new file mode 100644 (file)
index 0000000..01bbb35
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+package org.argeo.jackrabbit.servlet;
+
+import javax.jcr.Repository;
+
+import org.apache.jackrabbit.server.SessionProvider;
+import org.apache.jackrabbit.server.remoting.davex.JcrRemotingServlet;
+
+/** Provides remote access to a JCR repository */
+public class RemotingServlet extends JcrRemotingServlet {
+       public final static String INIT_PARAM_RESOURCE_PATH_PREFIX = JcrRemotingServlet.INIT_PARAM_RESOURCE_PATH_PREFIX;
+       public final static String INIT_PARAM_HOME = JcrRemotingServlet.INIT_PARAM_HOME;
+       public final static String INIT_PARAM_TMP_DIRECTORY = JcrRemotingServlet.INIT_PARAM_TMP_DIRECTORY;
+
+       private static final long serialVersionUID = 3131835511468341309L;
+
+       private final Repository repository;
+       private final SessionProvider sessionProvider;
+
+       public RemotingServlet(Repository repository,
+                       SessionProvider sessionProvider) {
+               this.repository = repository;
+               this.sessionProvider = sessionProvider;
+       }
+
+       @Override
+       protected Repository getRepository() {
+               return repository;
+       }
+
+       @Override
+       protected SessionProvider getSessionProvider() {
+               return sessionProvider;
+       }
+
+}
diff --git a/org.argeo.server.jcr/src/org/argeo/jackrabbit/servlet/WebdavServlet.java b/org.argeo.server.jcr/src/org/argeo/jackrabbit/servlet/WebdavServlet.java
new file mode 100644 (file)
index 0000000..c2346f0
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+package org.argeo.jackrabbit.servlet;
+
+import java.io.IOException;
+
+import javax.jcr.Repository;
+import javax.servlet.ServletException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.server.SessionProvider;
+import org.apache.jackrabbit.webdav.DavException;
+import org.apache.jackrabbit.webdav.DavResource;
+import org.apache.jackrabbit.webdav.WebdavRequest;
+import org.apache.jackrabbit.webdav.WebdavResponse;
+import org.apache.jackrabbit.webdav.simple.SimpleWebdavServlet;
+
+/** WebDav servlet whose repository is injected */
+public class WebdavServlet extends SimpleWebdavServlet {
+       public final static String INIT_PARAM_RESOURCE_CONFIG = SimpleWebdavServlet.INIT_PARAM_RESOURCE_CONFIG;
+       public final static String INIT_PARAM_RESOURCE_PATH_PREFIX = SimpleWebdavServlet.INIT_PARAM_RESOURCE_PATH_PREFIX;
+
+       private static final long serialVersionUID = -369787931175177080L;
+
+       private final static Log log = LogFactory.getLog(WebdavServlet.class);
+
+       private final Repository repository;
+
+       public WebdavServlet(Repository repository, SessionProvider sessionProvider) {
+               this.repository = repository;
+               setSessionProvider(sessionProvider);
+       }
+
+       public Repository getRepository() {
+               return repository;
+       }
+
+       @Override
+       protected boolean execute(WebdavRequest request, WebdavResponse response,
+                       int method, DavResource resource) throws ServletException,
+                       IOException, DavException {
+               if (log.isTraceEnabled())
+                       log.trace(request.getMethod() + "\t" + request.getPathInfo());
+               boolean res = super.execute(request, response, method, resource);
+               return res;
+       }
+
+}
index a1bbc8a71ed0b6728c93ce91369028e883f2d0d5..0cb1341e15e1482513deb9d47d7f08d00a14d141 100644 (file)
@@ -8,21 +8,5 @@
                <relativePath>..</relativePath>
        </parent>
        <artifactId>org.argeo.util</artifactId>
-       <name>Commons Util (no third party dependencies)</name>
-       <!-- <dependencies> -->
-       <!-- <dependency> -->
-       <!-- <groupId>org.argeo.tp</groupId> -->
-       <!-- <artifactId>junit</artifactId> -->
-       <!-- <scope>test</scope> -->
-       <!-- </dependency> -->
-       <!-- </dependencies> -->
-<!--   <dependencies> -->
-<!--           <dependency> -->
-<!--                   <groupId>org.argeo.tp</groupId> -->
-<!--                   <artifactId>argeo-tp</artifactId> -->
-<!--                   <version>${version.argeo-distribution}</version> -->
-<!--                   <type>pom</type> -->
-<!--                   <scope>provided</scope> -->
-<!--           </dependency> -->
-<!--   </dependencies> -->
+       <name>Commons Utilities</name>
 </project>
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index e10581b251538648951701dc4979036c68005d02..8959e0fbb68e414ed2073e9eb1314f32b05f06a0 100644 (file)
--- a/pom.xml
+++ b/pom.xml
                <!-- Security -->
                <module>org.argeo.security.core</module>
                <module>org.argeo.security.jackrabbit</module>
-               <module>org.argeo.security.ldap</module>
-               <!-- Security Services -->
-               <!-- <module>org.argeo.security.auth.ldap</module> -->
-               <!-- <module>org.argeo.security.dao.ldap</module> -->
-               <!-- <module>org.argeo.security.dao.cli</module> -->
-               <!-- <module>org.argeo.security.dao.jackrabbit</module> -->
-               <!-- Server -->
-               <module>org.argeo.server.core</module>
-               <!-- <module>org.argeo.server.jcr.mvc</module> -->
-               <module>org.argeo.server.jackrabbit</module>
                <!-- Eclipse -->
                <module>org.argeo.eclipse.ui</module>
                <module>org.argeo.eclipse.ui.rap</module>
-               <!-- Argeo Node -->
-               <!-- <module>org.argeo.node.repo.jackrabbit</module> -->
+               <!-- CMS -->
                <module>org.argeo.cms</module>
                <!-- Workbench -->
                <module>org.argeo.eclipse.ui.workbench</module>
                <module>org.argeo.eclipse.ui.workbench.rap</module>
-               <!-- <module>org.argeo.security.equinox</module> -->
                <module>org.argeo.security.ui</module>
                <module>org.argeo.security.ui.admin</module>
                <module>org.argeo.security.ui.rap</module>
-               <!-- Dependencies and Distributions -->
+               <!-- Distribution -->
                <module>dep</module>
                <module>dist</module>
        </modules>