]> git.argeo.org Git - gpl/argeo-slc.git/commitdiff
Provisioning
authorMathieu Baudier <mbaudier@argeo.org>
Sun, 28 Jun 2009 23:58:05 +0000 (23:58 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Sun, 28 Jun 2009 23:58:05 +0000 (23:58 +0000)
git-svn-id: https://svn.argeo.org/slc/trunk@2616 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

44 files changed:
demo/pom.xml
dep/org.argeo.slc.dep.agent/pom.xml
modules/server/.classpath [new file with mode: 0644]
modules/server/.project [new file with mode: 0644]
modules/server/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
modules/server/.settings/org.maven.ide.eclipse.prefs [new file with mode: 0644]
modules/server/org.argeo.slc.webapp.war/WEB-INF/osgi.xml
modules/server/org.argeo.slc.webapp.war/WEB-INF/provisioning-servlet.xml [new file with mode: 0644]
modules/server/org.argeo.slc.webapp.war/WEB-INF/web.xml
modules/server/pom.xml
pom.xml
runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/build/ResourceDistribution.java
runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/build/VersionedResourceDistribution.java [new file with mode: 0644]
runtime/org.argeo.slc.osgiboot/src/main/java/org/argeo/slc/osgiboot/Activator.java
runtime/org.argeo.slc.osgiboot/src/main/java/org/argeo/slc/osgiboot/OsgiBoot.java
runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/AbstractAvailableModules.java [new file with mode: 0644]
runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/AbstractProvisioningInterceptor.java [new file with mode: 0644]
runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/AvailableDistributions.java [new file with mode: 0644]
runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/AvailableModulesHtml.java [new file with mode: 0644]
runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/AvailableModulesOsgiBoot.java [new file with mode: 0644]
runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/AvailableModulesPlain.java [new file with mode: 0644]
runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/BundleHandler.java [new file with mode: 0644]
runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/BundleJarInterceptor.java [new file with mode: 0644]
runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/EclipseUpdateSite.java [deleted file]
runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/EclipseUpdateSiteCategory.java [deleted file]
runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/EclipseUpdateSiteFeature.java [deleted file]
runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/EclipseUpdateSiteHandler.java
runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/EclipseUpdateSiteInterceptor.java [new file with mode: 0644]
runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/FileProvider.java [deleted file]
runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/ModularDistributionInterceptor.java [new file with mode: 0644]
runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/PluginHandler.java [deleted file]
runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/StreamReadable.java [new file with mode: 0644]
runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/build/BasicNameVersion.java [new file with mode: 0644]
runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/build/ModularDistribution.java [new file with mode: 0644]
runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/build/NameVersion.java [new file with mode: 0644]
runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/DeployedSystem.java
runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/deploy/Module.java
runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/OsgiBundle.java
runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/OsgiRuntime.java
runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/build/BundleModularDistribution.java [new file with mode: 0644]
runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/build/EclipseUpdateSite.java [new file with mode: 0644]
runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/build/EclipseUpdateSiteCategory.java [new file with mode: 0644]
runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/build/EclipseUpdateSiteFeature.java [new file with mode: 0644]
runtime/org.argeo.slc.unit/src/main/java/org/argeo/slc/unit/db/DbUnitDeployment.java

index 0fcdaaf859823652d95154b5e0d7cb565d0b2615..71be268c1d29b390b0a2ea5ef4e1bd7328264e6f 100644 (file)
                                                                        org.argeo.slc.ria
                                                                </slc.osgi.start>
                                                                <slc.osgi.bundles>
                                                                        org.argeo.slc.ria
                                                                </slc.osgi.start>
                                                                <slc.osgi.bundles>
-                                                                       ${basedir}/../modules/server;in=*;ex=pom.xml;ex=target
+                                                                       ${user.home}/dev/src/sparta/dist/runtime/target;in=*.jar,
+                                                                       ${basedir}/site;in=*;ex=pom.xml;ex=target,
+                                                                       ${basedir}/../modules/server;in=*;ex=pom.xml;ex=target;ex=.*
                                                                </slc.osgi.bundles>
                                                        </systemProperties>
                                                </configuration>
                                                                </slc.osgi.bundles>
                                                        </systemProperties>
                                                </configuration>
index 65f6df5a9484f0d7e62802f98d77ed9d4568ab6a..31c229f4851fbab3bc45086d38ec371d09ca0515 100644 (file)
@@ -32,5 +32,9 @@
                        <groupId>org.argeo.slc.runtime</groupId>
                        <artifactId>org.argeo.slc.support.castor</artifactId>
                </dependency>
                        <groupId>org.argeo.slc.runtime</groupId>
                        <artifactId>org.argeo.slc.support.castor</artifactId>
                </dependency>
+               <dependency>
+                       <groupId>org.argeo.slc.runtime</groupId>
+                       <artifactId>org.argeo.slc.support.ant</artifactId>
+               </dependency>
        </dependencies>
 </project>
\ No newline at end of file
        </dependencies>
 </project>
\ No newline at end of file
diff --git a/modules/server/.classpath b/modules/server/.classpath
new file mode 100644 (file)
index 0000000..d0bec0f
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+       <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
+       <classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/modules/server/.project b/modules/server/.project
new file mode 100644 (file)
index 0000000..c8893ab
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>org.argeo.slc.modules.server</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.maven.ide.eclipse.maven2Builder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+               <nature>org.maven.ide.eclipse.maven2Nature</nature>
+       </natures>
+</projectDescription>
diff --git a/modules/server/.settings/org.eclipse.jdt.core.prefs b/modules/server/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..9bd0186
--- /dev/null
@@ -0,0 +1,5 @@
+#Sat Jun 27 18:22:37 CEST 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/modules/server/.settings/org.maven.ide.eclipse.prefs b/modules/server/.settings/org.maven.ide.eclipse.prefs
new file mode 100644 (file)
index 0000000..c4d2294
--- /dev/null
@@ -0,0 +1,9 @@
+#Sat Jun 27 18:22:31 CEST 2009
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+includeModules=false
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+skipCompilerPlugin=true
+version=1
index a75bac77a67301a1c3c021a0ac73599b57482d4b..c79f6a6eaacc7207f03f4b5d94d0494b33a08f2a 100644 (file)
@@ -43,5 +43,8 @@
        <!-- Runtime -->\r
        <reference id="dynamicRuntime" interface="org.argeo.slc.deploy.DynamicRuntime" />\r
 \r
        <!-- Runtime -->\r
        <reference id="dynamicRuntime" interface="org.argeo.slc.deploy.DynamicRuntime" />\r
 \r
+       <!-- Provisioning -->\r
+       <set id="modularDistributions" interface="org.argeo.slc.build.ModularDistribution"\r
+               cardinality="0..N" />\r
 \r
 </beans:beans>
\ No newline at end of file
 \r
 </beans:beans>
\ No newline at end of file
diff --git a/modules/server/org.argeo.slc.webapp.war/WEB-INF/provisioning-servlet.xml b/modules/server/org.argeo.slc.webapp.war/WEB-INF/provisioning-servlet.xml
new file mode 100644 (file)
index 0000000..a0f4c64
--- /dev/null
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
+       xsi:schemaLocation="
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
+       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
+
+       <bean name="getBundleHandler" class="org.argeo.slc.web.mvc.provisioning.BundleHandler">
+       </bean>
+
+       <bean name="updateSiteHandler"
+               class="org.argeo.slc.web.mvc.provisioning.EclipseUpdateSiteHandler">
+       </bean>
+
+       <bean name="availableDistributions"
+               class="org.argeo.slc.web.mvc.provisioning.AvailableDistributions">
+               <property name="modularDistributions" ref="modularDistributions" />
+       </bean>
+
+       <bean name="availableModulesHtml"
+               class="org.argeo.slc.web.mvc.provisioning.AvailableModulesHtml" />
+       <bean name="availableModulesPlain"
+               class="org.argeo.slc.web.mvc.provisioning.AvailableModulesPlain" />
+       <bean name="availableModulesOsgiBoot"
+               class="org.argeo.slc.web.mvc.provisioning.AvailableModulesOsgiBoot" />
+
+       <!-- MVC -->
+       <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
+               <property name="interceptors">
+                       <list>
+                               <ref local="modularDistributionInterceptor" />
+                       </list>
+               </property>
+               <property name="mappings">
+                       <value>
+                               /*/*/modules.html=availableModulesHtml
+                               /*/*/modules=availableModulesPlain
+                               /*/*/osgiBoot=availableModulesOsgiBoot
+                               /*/*/site.xml=updateSiteHandler
+                       </value>
+               </property>
+       </bean>
+
+       <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
+               <property name="interceptors">
+                       <list>
+                               <ref local="modularDistributionInterceptor" />
+                               <ref local="eclipseUpdateSiteInterceptor" />
+                       </list>
+               </property>
+               <property name="mappings">
+                       <value>
+                               /*/*/plugins/*=getBundleHandler
+                               /*/*/features/*=getBundleHandler
+                       </value>
+               </property>
+       </bean>
+
+       <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
+               <property name="interceptors">
+                       <list>
+                               <ref local="modularDistributionInterceptor" />
+                               <ref local="bundleJarInterceptor" />
+                       </list>
+               </property>
+               <property name="mappings">
+                       <value>
+                               /*/*/*.jar=getBundleHandler
+                       </value>
+               </property>
+       </bean>
+
+       <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
+               <property name="interceptors">
+                       <list>
+                       </list>
+               </property>
+               <property name="mappings">
+                       <value>
+                               /distributions=availableDistributions
+                       </value>
+               </property>
+       </bean>
+
+       <bean id="modularDistributionInterceptor"
+               class="org.argeo.slc.web.mvc.provisioning.ModularDistributionInterceptor">
+               <property name="modularDistributions" ref="modularDistributions" />
+       </bean>
+
+       <bean id="eclipseUpdateSiteInterceptor"
+               class="org.argeo.slc.web.mvc.provisioning.EclipseUpdateSiteInterceptor" />
+
+       <bean id="bundleJarInterceptor" class="org.argeo.slc.web.mvc.provisioning.BundleJarInterceptor" />
+</beans>
\ No newline at end of file
index 0e1ad8909ce1f1825713dcd6ec5bff6eabbedacd..3e9d60b93f79db8e849b7c568306a5f34e1e33f3 100644 (file)
                <url-pattern>*.pdf</url-pattern>
        </servlet-mapping>
 
                <url-pattern>*.pdf</url-pattern>
        </servlet-mapping>
 
+       <!-- PROVISIONING servlet -->
+       <servlet>
+               <servlet-name>provisioning</servlet-name>
+               <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
+               <init-param>
+                       <param-name>contextClass</param-name>
+                       <param-value>org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext</param-value>
+               </init-param>
+               <load-on-startup>1</load-on-startup>
+       </servlet>
+       <servlet-mapping>
+               <servlet-name>provisioning</servlet-name>
+               <url-pattern>/dist/*</url-pattern>
+       </servlet-mapping>
+
        <!-- General -->
        <context-param>
                <param-name>contextConfigLocation</param-name>
        <!-- General -->
        <context-param>
                <param-name>contextConfigLocation</param-name>
index 534ae5376ecd6c330da87d1faa8c1a1bfce69874..90795a618850f68353a82bfbd5b71dc5014e01bf 100644 (file)
@@ -1,4 +1,5 @@
-<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.slc</groupId>
        <modelVersion>4.0.0</modelVersion>
        <parent>
                <groupId>org.argeo.slc</groupId>
                        </plugin>
                </plugins>
        </build>
                        </plugin>
                </plugins>
        </build>
+       <dependencies>
+               <dependency>
+                       <groupId>org.argeo.slc.dep</groupId>
+                       <artifactId>org.argeo.slc.dep.server</artifactId>
+                       <version>${project.version}</version>
+                       <scope>test</scope>
+               </dependency>
+       </dependencies>
 </project>
\ No newline at end of file
 </project>
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 6a6346d2c89424a2deb2707a36cf990f6699ac93..754fdfd6c001cf1442c52b35d7f9aa96d78c5c5c 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -574,7 +574,7 @@ limitations under the License.
                        <dependency>
                                <groupId>org.argeo.dep.osgi</groupId>
                                <artifactId>org.argeo.dep.osgi.commons.cli</artifactId>
                        <dependency>
                                <groupId>org.argeo.dep.osgi</groupId>
                                <artifactId>org.argeo.dep.osgi.commons.cli</artifactId>
-                               <version>1.1</version>
+                               <version>1.1.0.argeo1</version>
                        </dependency>
                        <dependency>
                                <groupId>org.argeo.dep.osgi</groupId>
                        </dependency>
                        <dependency>
                                <groupId>org.argeo.dep.osgi</groupId>
index c24d6ec6c0017b3c5acc8e9ea7622f5e23b0ea3d..633be7a7fd97d9f2e46cddc12f54b7b4a42ff75e 100644 (file)
@@ -1,9 +1,14 @@
 package org.argeo.slc.core.build;
 
 package org.argeo.slc.core.build;
 
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.argeo.slc.SlcException;
+import org.argeo.slc.StreamReadable;
 import org.argeo.slc.build.Distribution;
 import org.springframework.core.io.Resource;
 
 import org.argeo.slc.build.Distribution;
 import org.springframework.core.io.Resource;
 
-public class ResourceDistribution implements Distribution {
+public class ResourceDistribution implements Distribution, StreamReadable {
        private Resource location;
 
        public ResourceDistribution() {
        private Resource location;
 
        public ResourceDistribution() {
@@ -25,4 +30,12 @@ public class ResourceDistribution implements Distribution {
                this.location = location;
        }
 
                this.location = location;
        }
 
+       public InputStream getInputStream() {
+               try {
+                       return location.getInputStream();
+               } catch (IOException e) {
+                       throw new SlcException("Cannot get input stream", e);
+               }
+       }
+
 }
 }
diff --git a/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/build/VersionedResourceDistribution.java b/runtime/org.argeo.slc.core/src/main/java/org/argeo/slc/core/build/VersionedResourceDistribution.java
new file mode 100644 (file)
index 0000000..a813438
--- /dev/null
@@ -0,0 +1,38 @@
+package org.argeo.slc.core.build;
+
+import org.argeo.slc.build.NameVersion;
+import org.springframework.core.io.Resource;
+
+public class VersionedResourceDistribution extends ResourceDistribution
+               implements NameVersion {
+       private String name;
+       private String version;
+
+       public VersionedResourceDistribution() {
+               super();
+       }
+
+       public VersionedResourceDistribution(String name, String version,
+                       Resource resource) {
+               super(resource);
+               this.name = name;
+               this.version = version;
+       }
+
+       public String getName() {
+               return name;
+       }
+
+       public void setName(String name) {
+               this.name = name;
+       }
+
+       public String getVersion() {
+               return version;
+       }
+
+       public void setVersion(String version) {
+               this.version = version;
+       }
+
+}
index d3dc59ff62e74fe2537f2a6f3db2447e6856f8e8..0945ca7197f5ea2c19904219e70a0a2aef3c9b29 100644 (file)
@@ -11,6 +11,7 @@ public class Activator implements BundleActivator {
                        OsgiBoot osgiBoot = new OsgiBoot(bundleContext);
                        osgiBoot.installUrls(osgiBoot.getBundlesUrls());
                        osgiBoot.installUrls(osgiBoot.getLocationsUrls());
                        OsgiBoot osgiBoot = new OsgiBoot(bundleContext);
                        osgiBoot.installUrls(osgiBoot.getBundlesUrls());
                        osgiBoot.installUrls(osgiBoot.getLocationsUrls());
+                       osgiBoot.installUrls(osgiBoot.getModulesUrls());
                        osgiBoot.startBundles();
                        OsgiBoot.info("SLC OSGi bootstrap completed");
                } catch (Exception e) {
                        osgiBoot.startBundles();
                        OsgiBoot.info("SLC OSGi bootstrap completed");
                } catch (Exception e) {
index 2c6d1434ab58fbe4aeb579f083f44c1249878792..dd2b1b691930f011d3a8f329f1d764a9d7e75b33 100644 (file)
@@ -1,9 +1,14 @@
 package org.argeo.slc.osgiboot;
 
 package org.argeo.slc.osgiboot;
 
+import java.io.BufferedReader;
 import java.io.File;
 import java.io.IOException;
 import java.io.File;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.StringTokenizer;
 import java.util.List;
 import java.util.Map;
 import java.util.StringTokenizer;
@@ -14,12 +19,14 @@ import org.argeo.slc.osgiboot.internal.springutil.SystemPropertyUtils;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleException;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
 
 public class OsgiBoot {
        public final static String PROP_SLC_OSGI_START = "slc.osgi.start";
        public final static String PROP_SLC_OSGI_BUNDLES = "slc.osgi.bundles";
        public final static String PROP_SLC_OSGI_LOCATIONS = "slc.osgi.locations";
        public final static String PROP_SLC_OSGI_BASE_URL = "slc.osgi.baseUrl";
 
 public class OsgiBoot {
        public final static String PROP_SLC_OSGI_START = "slc.osgi.start";
        public final static String PROP_SLC_OSGI_BUNDLES = "slc.osgi.bundles";
        public final static String PROP_SLC_OSGI_LOCATIONS = "slc.osgi.locations";
        public final static String PROP_SLC_OSGI_BASE_URL = "slc.osgi.baseUrl";
+       public final static String PROP_SLC_OSGI_MODULES_URL = "slc.osgi.modulesUrl";
        public final static String PROP_SLC_OSGIBOOT_DEBUG = "slc.osgiboot.debug";
 
        public final static String DEFAULT_BASE_URL = "reference:file:";
        public final static String PROP_SLC_OSGIBOOT_DEBUG = "slc.osgiboot.debug";
 
        public final static String DEFAULT_BASE_URL = "reference:file:";
@@ -30,6 +37,7 @@ public class OsgiBoot {
                        .booleanValue();
 
        private boolean excludeSvn = true;
                        .booleanValue();
 
        private boolean excludeSvn = true;
+       private String modulesUrlSeparator = ";";
 
        private final BundleContext bundleContext;
 
 
        private final BundleContext bundleContext;
 
@@ -62,6 +70,45 @@ public class OsgiBoot {
 
        }
 
 
        }
 
+       public void installOrUpdateUrls(Map urls) {
+               Map installedBundles = getBundles();
+
+               for (Iterator modules = urls.keySet().iterator(); modules.hasNext();) {
+                       String moduleName = (String) modules.next();
+                       String urlStr = (String) urls.get(moduleName);
+                       if (installedBundles.containsKey(moduleName)) {
+                               Bundle bundle = (Bundle) installedBundles.get(moduleName);
+                               InputStream in;
+                               try {
+                                       URL url = new URL(urlStr);
+                                       in = url.openStream();
+                                       bundle.update(in);
+                                       info("Updated bundle " + moduleName + " from " + urlStr);
+                               } catch (Exception e) {
+                                       throw new RuntimeException("Cannot update " + moduleName
+                                                       + " from " + urlStr);
+                               }
+                               if (in != null)
+                                       try {
+                                               in.close();
+                                       } catch (IOException e) {
+                                               e.printStackTrace();
+                                       }
+                       } else {
+                               try {
+                                       Bundle bundle = bundleContext.installBundle(urlStr);
+                                       if (debug)
+                                               debug("Installed bundle " + bundle.getSymbolicName()
+                                                               + " from " + urlStr);
+                               } catch (BundleException e) {
+                                       warn("Could not install bundle from " + urlStr + ": "
+                                                       + e.getMessage());
+                               }
+                       }
+               }
+
+       }
+
        public void startBundles() throws Exception {
                String bundlesToStart = getProperty(PROP_SLC_OSGI_START);
                startBundles(bundlesToStart);
        public void startBundles() throws Exception {
                String bundlesToStart = getProperty(PROP_SLC_OSGI_START);
                startBundles(bundlesToStart);
@@ -84,21 +131,24 @@ public class OsgiBoot {
                if (bundlesToStart.size() == 0)
                        return;
 
                if (bundlesToStart.size() == 0)
                        return;
 
-               Map bundles = getBundles();
-               for (int i = 0; i < bundlesToStart.size(); i++) {
-                       String name = bundlesToStart.get(i).toString();
-                       Bundle bundle = (Bundle) bundles.get(name);
-                       if (bundle != null)
+               List notStartedBundles = new ArrayList(bundlesToStart);
+               Bundle[] bundles = bundleContext.getBundles();
+               for (int i = 0; i < bundles.length; i++) {
+                       Bundle bundle = bundles[i];
+                       String symbolicName = bundle.getSymbolicName();
+                       if (bundlesToStart.contains(symbolicName))
                                try {
                                        bundle.start();
                                try {
                                        bundle.start();
+                                       notStartedBundles.remove(symbolicName);
                                } catch (Exception e) {
                                } catch (Exception e) {
-                                       warn("Bundle " + name + " cannot be started: "
+                                       warn("Bundle " + symbolicName + " cannot be started: "
                                                        + e.getMessage());
                                }
                                                        + e.getMessage());
                                }
-                       else
-                               warn("Bundle " + name + " not installed.");
-
                }
                }
+
+               for (int i = 0; i < notStartedBundles.size(); i++)
+                       warn("Bundle " + notStartedBundles.get(i)
+                                       + " not started because it was not found.");
        }
 
        /** Key is location */
        }
 
        /** Key is location */
@@ -128,6 +178,114 @@ public class OsgiBoot {
                return getLocationsUrls(baseUrl, bundleLocations);
        }
 
                return getLocationsUrls(baseUrl, bundleLocations);
        }
 
+       public List getModulesUrls() {
+               List urls = new ArrayList();
+               String modulesUrlStr = getProperty(PROP_SLC_OSGI_MODULES_URL);
+               if (modulesUrlStr == null)
+                       return urls;
+
+               Map installedBundles = getBundles();
+
+               BufferedReader reader = null;
+               try {
+                       URL modulesUrl = new URL(modulesUrlStr);
+                       reader = new BufferedReader(new InputStreamReader(modulesUrl
+                                       .openStream()));
+                       String line = null;
+                       while ((line = reader.readLine()) != null) {
+                               StringTokenizer st = new StringTokenizer(line,
+                                               modulesUrlSeparator);
+                               String moduleName = st.nextToken();
+                               String moduleVersion = st.nextToken();
+                               String url = st.nextToken();
+
+                               if (installedBundles.containsKey(moduleName)) {
+                                       Bundle bundle = (Bundle) installedBundles.get(moduleName);
+                                       String bundleVersion = bundle.getHeaders().get(
+                                                       Constants.BUNDLE_VERSION).toString();
+                                       int comp = compareVersions(bundleVersion, moduleVersion);
+                                       if (comp > 0) {
+                                               warn("Installed version " + bundleVersion
+                                                               + " of bundle " + moduleName
+                                                               + " is newer than  provided version "
+                                                               + moduleVersion);
+                                       } else if (comp < 0) {
+                                               urls.add(url);
+                                               info("Updated bundle " + moduleName + " with version "
+                                                               + moduleVersion + " (old version was "
+                                                               + bundleVersion + ")");
+                                       } else {
+                                               // do nothing
+                                       }
+                               } else {
+                                       urls.add(url);
+                               }
+                       }
+               } catch (Exception e1) {
+                       throw new RuntimeException("Cannot read url " + modulesUrlStr, e1);
+               } finally {
+                       if (reader != null)
+                               try {
+                                       reader.close();
+                               } catch (IOException e) {
+                                       e.printStackTrace();
+                               }
+               }
+               return urls;
+       }
+
+       /**
+        * @return ==0: versions are identical, <0: tested version is newer, >0:
+        *         currentVersion is newer.
+        */
+       protected int compareVersions(String currentVersion, String testedVersion) {
+               List cToks = new ArrayList();
+               StringTokenizer cSt = new StringTokenizer(currentVersion, ".");
+               while (cSt.hasMoreTokens())
+                       cToks.add(cSt.nextToken());
+               List tToks = new ArrayList();
+               StringTokenizer tSt = new StringTokenizer(currentVersion, ".");
+               while (tSt.hasMoreTokens())
+                       tToks.add(tSt.nextToken());
+
+               int comp = 0;
+               comp: for (int i = 0; i < cToks.size(); i++) {
+                       if (tToks.size() <= i) {
+                               // equals until then, tested shorter
+                               comp = 1;
+                               break comp;
+                       }
+
+                       String c = (String) cToks.get(i);
+                       String t = (String) tToks.get(i);
+
+                       try {
+                               int cInt = Integer.parseInt(c);
+                               int tInt = Integer.parseInt(t);
+                               if (cInt == tInt)
+                                       continue comp;
+                               else {
+                                       comp = (cInt - tInt);
+                                       break comp;
+                               }
+                       } catch (NumberFormatException e) {
+                               if (c.equals(t))
+                                       continue comp;
+                               else {
+                                       comp = c.compareTo(t);
+                                       break comp;
+                               }
+                       }
+               }
+
+               if (comp == 0 && tToks.size() > cToks.size()) {
+                       // equals until then, current shorter
+                       comp = -1;
+               }
+
+               return comp;
+       }
+
        public List getLocationsUrls(String baseUrl, String bundleLocations) {
                List urls = new ArrayList();
 
        public List getLocationsUrls(String baseUrl, String bundleLocations) {
                List urls = new ArrayList();
 
diff --git a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/AbstractAvailableModules.java b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/AbstractAvailableModules.java
new file mode 100644 (file)
index 0000000..e9acf08
--- /dev/null
@@ -0,0 +1,36 @@
+package org.argeo.slc.web.mvc.provisioning;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.argeo.slc.build.ModularDistribution;
+import org.springframework.web.HttpRequestHandler;
+
+/** List of modules for a distribution. */
+public abstract class AbstractAvailableModules implements HttpRequestHandler {
+       protected abstract void print(Writer out, String baseUrl,
+                       ModularDistribution md) throws IOException;
+
+       public final void handleRequest(HttpServletRequest request,
+                       HttpServletResponse response) throws ServletException, IOException {
+               response.setContentType(getContentType());
+
+               ModularDistribution md = (ModularDistribution) request
+                               .getAttribute("modularDistribution");
+
+               String baseUrl = "http://" + request.getServerName() + ":"
+                               + request.getServerPort() + request.getContextPath() + "/"
+                               + md.getName() + "/" + md.getVersion() + "/";
+
+               print(response.getWriter(), baseUrl, md);
+       }
+
+       public String getContentType() {
+               return "text/plain";
+       }
+
+}
diff --git a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/AbstractProvisioningInterceptor.java b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/AbstractProvisioningInterceptor.java
new file mode 100644 (file)
index 0000000..613de2c
--- /dev/null
@@ -0,0 +1,8 @@
+package org.argeo.slc.web.mvc.provisioning;
+
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+public abstract class AbstractProvisioningInterceptor extends
+               HandlerInterceptorAdapter {
+       
+}
diff --git a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/AvailableDistributions.java b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/AvailableDistributions.java
new file mode 100644 (file)
index 0000000..b4a2cc9
--- /dev/null
@@ -0,0 +1,62 @@
+package org.argeo.slc.web.mvc.provisioning;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Iterator;
+import java.util.Set;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.argeo.slc.build.ModularDistribution;
+import org.springframework.web.HttpRequestHandler;
+
+/** List of distributions. */
+public class AvailableDistributions implements HttpRequestHandler {
+       private Set<ModularDistribution> modularDistributions;
+
+       public void handleRequest(HttpServletRequest request,
+                       HttpServletResponse response) throws ServletException, IOException {
+               response.setContentType("text/html");
+
+               String baseUrl = "http://" + request.getServerName() + ":"
+                               + request.getServerPort() + request.getContextPath()
+                               + request.getServletPath() + "/";
+
+               Writer out = response.getWriter();
+
+               out.write("<h1>Distributions</h1>");
+               for (Iterator<ModularDistribution> it = modularDistributions.iterator(); it
+                               .hasNext();) {
+                       ModularDistribution md = it.next();
+                       out.write("<h2>" + md + "</h2>");
+                       out.write("Modules: ");
+                       String moduleBase = baseUrl + md.getName() + "/" + md.getVersion()
+                                       + "/";
+
+                       String modulesListHtml = moduleBase + "modules.html";
+                       out.write(" <a href=\"" + modulesListHtml + "\">html</a>");
+
+                       String modulesListPlain = moduleBase + "modules";
+                       out.write(" <a href=\"" + modulesListPlain + "\">plain</a>");
+
+                       String modulesListOsgiBoot = moduleBase + "osgiBoot";
+                       out.write(" <a href=\"" + modulesListOsgiBoot + "\">osgiBoot</a>");
+
+                       out.write("<br/>");
+
+                       out.write("Eclipse update site: ");
+                       String updateSiteUrl = baseUrl + md.getName() + "/"
+                                       + md.getVersion() + "/site.xml";
+                       out.write("<a href=\"" + updateSiteUrl + "\">" + updateSiteUrl
+                                       + "</a>");
+               }
+       }
+
+       public void setModularDistributions(
+                       Set<ModularDistribution> modularDistributions) {
+               this.modularDistributions = modularDistributions;
+       }
+
+}
diff --git a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/AvailableModulesHtml.java b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/AvailableModulesHtml.java
new file mode 100644 (file)
index 0000000..338de83
--- /dev/null
@@ -0,0 +1,31 @@
+package org.argeo.slc.web.mvc.provisioning;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import org.argeo.slc.build.ModularDistribution;
+import org.argeo.slc.build.NameVersion;
+
+/** List of modules for a distribution. */
+public class AvailableModulesHtml extends AbstractAvailableModules {
+       @Override
+       protected void print(Writer out, String baseUrl, ModularDistribution md)
+                       throws IOException {
+               out.write("<h1>Distribution " + md + "</h1>");
+
+               for (NameVersion nameVersion : md.listModulesNameVersions()) {
+                       String fileName = nameVersion.getName() + "-"
+                                       + nameVersion.getVersion() + ".jar";
+                       String moduleUrl = baseUrl + fileName;
+                       out
+                                       .write("<a href=\"" + moduleUrl + "\">" + fileName
+                                                       + "</a><br/>");
+               }
+       }
+
+       @Override
+       public String getContentType() {
+               return "text/html";
+       }
+
+}
diff --git a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/AvailableModulesOsgiBoot.java b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/AvailableModulesOsgiBoot.java
new file mode 100644 (file)
index 0000000..a31dae9
--- /dev/null
@@ -0,0 +1,30 @@
+package org.argeo.slc.web.mvc.provisioning;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import org.argeo.slc.build.ModularDistribution;
+import org.argeo.slc.build.NameVersion;
+
+/** List of modules for a distribution. */
+public class AvailableModulesOsgiBoot extends AbstractAvailableModules {
+       private String separator = ";";
+
+       @Override
+       protected void print(Writer out, String baseUrl, ModularDistribution md)
+                       throws IOException {
+               for (NameVersion nameVersion : md.listModulesNameVersions()) {
+                       String fileName = nameVersion.getName() + "-"
+                                       + nameVersion.getVersion() + ".jar";
+                       String moduleUrl = baseUrl + fileName;
+                       out.write(nameVersion.getName() + separator
+                                       + nameVersion.getVersion() + separator + moduleUrl);
+                       out.write("\n");
+               }
+       }
+
+       public void setSeparator(String separator) {
+               this.separator = separator;
+       }
+
+}
diff --git a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/AvailableModulesPlain.java b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/AvailableModulesPlain.java
new file mode 100644 (file)
index 0000000..fb7c7c9
--- /dev/null
@@ -0,0 +1,22 @@
+package org.argeo.slc.web.mvc.provisioning;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import org.argeo.slc.build.ModularDistribution;
+import org.argeo.slc.build.NameVersion;
+
+/** List of modules for a distribution. */
+public class AvailableModulesPlain extends AbstractAvailableModules {
+       @Override
+       protected void print(Writer out, String baseUrl, ModularDistribution md)
+                       throws IOException {
+               for (NameVersion nameVersion : md.listModulesNameVersions()) {
+                       String fileName = nameVersion.getName() + "-"
+                                       + nameVersion.getVersion() + ".jar";
+                       String moduleUrl = baseUrl + fileName;
+                       out.write(moduleUrl);
+                       out.write("\n");
+               }
+       }
+}
diff --git a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/BundleHandler.java b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/BundleHandler.java
new file mode 100644 (file)
index 0000000..9936d88
--- /dev/null
@@ -0,0 +1,46 @@
+package org.argeo.slc.web.mvc.provisioning;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.StreamReadable;
+import org.argeo.slc.UnsupportedException;
+import org.argeo.slc.build.Distribution;
+import org.argeo.slc.build.ModularDistribution;
+import org.springframework.web.HttpRequestHandler;
+
+public class BundleHandler implements HttpRequestHandler {
+       private final static Log log = LogFactory.getLog(BundleHandler.class);
+
+       public void handleRequest(HttpServletRequest request,
+                       HttpServletResponse response) throws ServletException, IOException {
+               String path = request.getPathInfo();
+
+               if (log.isDebugEnabled())
+                       log.debug("Bundle jar Requested: " + path);
+               response.setContentType("application/java-archive");
+
+               String moduleName = request.getParameter("moduleName");
+               if (moduleName == null)
+                       moduleName = request.getAttribute("moduleName").toString();
+               String moduleVersion = request.getParameter("moduleVersion");
+               if (moduleVersion == null)
+                       moduleVersion = request.getAttribute("moduleVersion").toString();
+
+               ModularDistribution modularDistribution = (ModularDistribution) request
+                               .getAttribute("modularDistribution");
+               Distribution distribution = modularDistribution.getModuleDistribution(
+                               moduleName, moduleVersion);
+               if (distribution instanceof StreamReadable)
+                       IOUtils.copy(((StreamReadable) distribution).getInputStream(),
+                                       response.getOutputStream());
+               else
+                       throw new UnsupportedException("distribution", distribution);
+       }
+}
diff --git a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/BundleJarInterceptor.java b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/BundleJarInterceptor.java
new file mode 100644 (file)
index 0000000..a439f81
--- /dev/null
@@ -0,0 +1,42 @@
+package org.argeo.slc.web.mvc.provisioning;
+
+import java.util.StringTokenizer;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.argeo.slc.SlcException;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+public class BundleJarInterceptor extends HandlerInterceptorAdapter {
+
+       @Override
+       public boolean preHandle(HttpServletRequest request,
+                       HttpServletResponse response, Object handler) throws Exception {
+               String path = request.getPathInfo();
+               StringTokenizer stS = new StringTokenizer(path, "/");
+               String fileName = null;
+               while (stS.hasMoreTokens()) {
+                       String token = stS.nextToken();
+                       if (!stS.hasMoreTokens()) {
+                               fileName = token;
+                       }
+               }
+
+               int ind_ = fileName.indexOf('-');
+               String moduleName;
+               if (ind_ > -1)
+                       moduleName = fileName.substring(0, ind_);
+               else
+                       throw new SlcException("Cannot determine version for " + fileName);
+
+               String versionAndExtension = fileName.substring(ind_ + 1);
+               int indExt = versionAndExtension.lastIndexOf('.');
+               String moduleVersion = versionAndExtension.substring(0, indExt);
+
+               request.setAttribute("moduleName", moduleName);
+               request.setAttribute("moduleVersion", moduleVersion);
+
+               return true;
+       }
+}
diff --git a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/EclipseUpdateSite.java b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/EclipseUpdateSite.java
deleted file mode 100644 (file)
index 36a0949..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.argeo.slc.web.mvc.provisioning;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class EclipseUpdateSite {
-       private List<EclipseUpdateSiteFeature> features = new ArrayList<EclipseUpdateSiteFeature>();
-
-       public List<EclipseUpdateSiteFeature> getFeatures() {
-               return features;
-       }
-
-       public void setFeatures(List<EclipseUpdateSiteFeature> features) {
-               this.features = features;
-       }
-
-}
diff --git a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/EclipseUpdateSiteCategory.java b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/EclipseUpdateSiteCategory.java
deleted file mode 100644 (file)
index 04e8e2b..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-package org.argeo.slc.web.mvc.provisioning;
-
-public class EclipseUpdateSiteCategory {
-       private String name;
-       private String label;
-       private String description;
-
-       public String getLabel() {
-               return label;
-       }
-
-       public void setLabel(String label) {
-               this.label = label;
-       }
-
-       public String getDescription() {
-               return description;
-       }
-
-       public void setDescription(String description) {
-               this.description = description;
-       }
-
-       public String getName() {
-               return name;
-       }
-
-       public void setName(String name) {
-               this.name = name;
-       }
-
-}
diff --git a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/EclipseUpdateSiteFeature.java b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/EclipseUpdateSiteFeature.java
deleted file mode 100644 (file)
index dc24f28..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.argeo.slc.web.mvc.provisioning;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class EclipseUpdateSiteFeature {
-       private String name;
-       private List<EclipseUpdateSiteCategory> categories = new ArrayList<EclipseUpdateSiteCategory>();
-
-       public String getName() {
-               return name;
-       }
-
-       public void setName(String name) {
-               this.name = name;
-       }
-
-       public List<EclipseUpdateSiteCategory> getCategories() {
-               return categories;
-       }
-
-       public void setCategories(List<EclipseUpdateSiteCategory> categories) {
-               this.categories = categories;
-       }
-
-}
index 7718ca38a05d956e32cc8ef604f907dad2524168..d4c7260a91e0135e699cedede475224965ab7b4f 100644 (file)
@@ -1,83 +1,22 @@
 package org.argeo.slc.web.mvc.provisioning;
 
 import java.io.IOException;
 package org.argeo.slc.web.mvc.provisioning;
 
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.StringTokenizer;
-import java.util.jar.JarInputStream;
-import java.util.jar.Manifest;
 
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.springframework.core.io.Resource;
+import org.argeo.slc.build.ModularDistribution;
 import org.springframework.web.HttpRequestHandler;
 
 /** An Eclipse update site, serving site.xml features/* and plugins/*. */
 public class EclipseUpdateSiteHandler implements HttpRequestHandler {
 import org.springframework.web.HttpRequestHandler;
 
 /** An Eclipse update site, serving site.xml features/* and plugins/*. */
 public class EclipseUpdateSiteHandler implements HttpRequestHandler {
-       private FileProvider provider;
-       private String baseVersion = "0.9.4-SNAPSHOT";
-
-       private EclipseUpdateSite updateSite;
-
        public void handleRequest(HttpServletRequest request,
                        HttpServletResponse response) throws ServletException, IOException {
        public void handleRequest(HttpServletRequest request,
                        HttpServletResponse response) throws ServletException, IOException {
-               String path = request.getPathInfo();
-               StringTokenizer stS = new StringTokenizer(path, "/");
-               String distribution = stS.nextToken();
-
-               StringBuffer buf = new StringBuffer("");
-               buf.append("<site>");
-
-               List<EclipseUpdateSiteCategory> usedCategories = new ArrayList<EclipseUpdateSiteCategory>();
-               for (EclipseUpdateSiteFeature feature : updateSite.getFeatures()) {
-                       Resource bundle = provider.getBundle(distribution, feature
-                                       .getName(), baseVersion);
-                       JarInputStream in = new JarInputStream(bundle.getInputStream());
-                       Manifest mf = in.getManifest();
-                       String version = mf.getMainAttributes().getValue("Bundle-Version");
-                       String featureId = feature.getName();
-                       buf.append("<feature");
-                       buf.append(" url=\"features/").append(featureId).append('_')
-                                       .append(version).append(".jar\"");
-                       buf.append(" id=\"").append(featureId).append("\"");
-                       buf.append(" version=\"").append(version).append("\"");
-                       buf.append(">\n");
-
-                       for (EclipseUpdateSiteCategory category : feature.getCategories()) {
-                               usedCategories.add(category);
-                               buf.append("  <category name=\"").append(category.getName())
-                                               .append("\"/>\n");
-                       }
-                       buf.append("</feature>\n\n");
-               }
-
-               for (EclipseUpdateSiteCategory category : usedCategories) {
-                       buf.append("<category-def");
-                       buf.append(" name=\"").append(category.getName()).append("\"");
-                       buf.append(" label=\"").append(category.getLabel()).append("\"");
-                       buf.append(">\n");
-                       buf.append("  <description>").append(category.getDescription())
-                                       .append("</decription>\n");
-                       buf.append("</category-def>\n\n");
-               }
-
-               buf.append("</site>");
 
 
-               response.getWriter().print(buf.toString());
+               ModularDistribution modularDistribution = (ModularDistribution) request
+                               .getAttribute("modularDistribution");
+               response.getWriter().write(
+                               modularDistribution.getDescriptor("eclipse").toString());
        }
        }
-
-       public void setProvider(FileProvider provider) {
-               this.provider = provider;
-       }
-
-       public void setBaseVersion(String baseVersion) {
-               this.baseVersion = baseVersion;
-       }
-
-       public void setUpdateSite(EclipseUpdateSite updateSite) {
-               this.updateSite = updateSite;
-       }
-
 }
 }
diff --git a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/EclipseUpdateSiteInterceptor.java b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/EclipseUpdateSiteInterceptor.java
new file mode 100644 (file)
index 0000000..5dab52b
--- /dev/null
@@ -0,0 +1,51 @@
+package org.argeo.slc.web.mvc.provisioning;
+
+import java.util.StringTokenizer;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.argeo.slc.SlcException;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+public class EclipseUpdateSiteInterceptor extends HandlerInterceptorAdapter {
+       public final static String RELEASE = "RELEASE";
+       public final static String LATEST = "LATEST";
+
+       @Override
+       public boolean preHandle(HttpServletRequest request,
+                       HttpServletResponse response, Object handler) throws Exception {
+               String path = request.getPathInfo();
+               StringTokenizer stS = new StringTokenizer(path, "/");
+               String type = null;
+               pathTokenizer: while (stS.hasMoreTokens()) {
+                       String token = stS.nextToken();
+                       if (token.equals("plugins") || token.equals("features")) {
+                               type = token;
+                               break pathTokenizer;
+                       }
+               }
+
+               if (type == null || !stS.hasMoreTokens())
+                       throw new SlcException("Cannot determine file name from path "
+                                       + path);
+
+               String fileName = stS.nextToken();
+
+               int ind_ = fileName.indexOf('_');
+               String moduleName;
+               if (ind_ > -1)
+                       moduleName = fileName.substring(0, ind_);
+               else
+                       throw new SlcException("Cannot determine version for " + fileName);
+
+               String versionAndExtension = fileName.substring(ind_ + 1);
+               int indExt = versionAndExtension.lastIndexOf('.');
+               String moduleVersion = versionAndExtension.substring(0, indExt);
+
+               request.setAttribute("moduleName", moduleName);
+               request.setAttribute("moduleVersion", moduleVersion);
+
+               return true;
+       }
+}
diff --git a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/FileProvider.java b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/FileProvider.java
deleted file mode 100644 (file)
index 6751e09..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-package org.argeo.slc.web.mvc.provisioning;
-
-import java.io.InputStream;
-import java.io.OutputStream;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.slc.SlcException;
-import org.springframework.core.io.Resource;
-
-public class FileProvider {
-       private final static Log log = LogFactory.getLog(FileProvider.class);
-
-       private Resource base;
-
-       public void read(String distribution, String name, String version,
-                       OutputStream out) {
-               Resource bundle = getBundle(distribution, name, version);
-               InputStream in = null;
-               try {
-                       in = bundle.getInputStream();
-                       IOUtils.copy(in, out);
-               } catch (Exception e) {
-                       throw new SlcException("Cannot read bundle for " + name + " ("
-                                       + version + ")",e);
-               } finally {
-                       IOUtils.closeQuietly(in);
-               }
-       }
-
-       public Resource getBundle(String distribution, String name, String version) {
-               try {
-                       String shortVersion = version;
-                       int indR = version.indexOf("-r");
-                       if (indR > -1) {
-                               shortVersion = version.substring(0, indR);
-                       }
-
-                       int indS = shortVersion.indexOf(".SNAPSHOT");
-                       if (indS > -1) {
-                               StringBuffer buf = new StringBuffer(shortVersion);
-                               buf.setCharAt(indS, '-');
-                               shortVersion = buf.toString();
-                       }
-
-                       if (log.isDebugEnabled())
-                               log.debug("Short version for " + name + ": " + shortVersion);
-
-                       Resource res = base.createRelative("lib/" + name + "-"
-                                       + shortVersion + ".jar");
-                       return res;
-               } catch (Exception e) {
-                       throw new SlcException("Cannot get bundle for " + name + " ("
-                                       + version + ")",e);
-               }
-       }
-
-       public void setBase(Resource base) {
-               this.base = base;
-       }
-
-}
diff --git a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/ModularDistributionInterceptor.java b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/ModularDistributionInterceptor.java
new file mode 100644 (file)
index 0000000..309b996
--- /dev/null
@@ -0,0 +1,67 @@
+package org.argeo.slc.web.mvc.provisioning;
+
+import java.util.Iterator;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.StringTokenizer;
+import java.util.TreeMap;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.argeo.slc.SlcException;
+import org.argeo.slc.build.BasicNameVersion;
+import org.argeo.slc.build.ModularDistribution;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+public class ModularDistributionInterceptor extends HandlerInterceptorAdapter {
+       private Set<ModularDistribution> modularDistributions;
+
+       public final static String RELEASE = "RELEASE";
+       public final static String LATEST = "LATEST";
+
+       @Override
+       public boolean preHandle(HttpServletRequest request,
+                       HttpServletResponse response, Object handler) throws Exception {
+               String path = request.getPathInfo();
+               StringTokenizer stS = new StringTokenizer(path, "/");
+               String distributionName = stS.nextToken();
+               String distributionVersion = stS.nextToken();
+
+               SortedMap<String, ModularDistribution> choices = new TreeMap<String, ModularDistribution>();
+               distribs: for (Iterator<ModularDistribution> it = modularDistributions
+                               .iterator(); it.hasNext();) {
+                       ModularDistribution md = it.next();
+                       if (md.getName().equals(distributionName)) {
+                               if (distributionVersion.equals(RELEASE)
+                                               && md.getVersion().contains("SNAPSHOT"))
+                                       continue distribs;
+
+                               else if (distributionVersion.equals(LATEST))
+                                       choices.put(md.getVersion(), md);
+                               else if (distributionVersion.equals(md.getVersion())) {
+                                       choices.put(md.getVersion(), md);
+                                       break distribs;
+                               }
+                       }
+               }
+
+               if (choices.size() == 0)
+                       throw new SlcException("Cannot find distribution for "
+                                       + new BasicNameVersion(distributionName,
+                                                       distributionVersion));
+
+               ModularDistribution modularDistribution = choices.get(choices
+                               .firstKey());
+
+               request.setAttribute("modularDistribution", modularDistribution);
+
+               return true;
+       }
+
+       public void setModularDistributions(
+                       Set<ModularDistribution> modularDistributions) {
+               this.modularDistributions = modularDistributions;
+       }
+
+}
diff --git a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/PluginHandler.java b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/mvc/provisioning/PluginHandler.java
deleted file mode 100644 (file)
index 7f44d0d..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-package org.argeo.slc.web.mvc.provisioning;
-
-import java.io.IOException;
-import java.util.StringTokenizer;
-
-import javax.servlet.ServletException;
-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.slc.SlcException;
-import org.springframework.web.HttpRequestHandler;
-
-public class PluginHandler implements HttpRequestHandler {
-       private final static Log log = LogFactory.getLog(PluginHandler.class);
-
-       private FileProvider provider;
-
-       public void handleRequest(HttpServletRequest request,
-                       HttpServletResponse response) throws ServletException, IOException {
-               // log.debug(request.getContextPath());
-               // log.debug(request.getServletPath());
-               // log.debug(request.getPathInfo());
-               // log.debug(request.getPathTranslated());
-               // log.debug(request.getLocalName());
-               // log.debug(request.getLocalAddr());
-               // log.debug(request.getQueryString());
-               // log.debug(request.getRequestURL());
-               // log.debug(request.getRequestURI());
-
-               String path = request.getPathInfo();
-
-               if (log.isDebugEnabled())
-                       log.debug("Request " + path);
-
-               StringTokenizer stS = new StringTokenizer(path, "/");
-               String distribution = stS.nextToken();
-               stS.nextToken();// plugins
-               String fileName = stS.nextToken();
-
-               int ind_ = fileName.indexOf('_');
-               String moduleName;
-               if (ind_ > -1)
-                       moduleName = fileName.substring(0, ind_);
-               else
-                       throw new SlcException("Cannot determine version for " + fileName);
-
-               String versionAndExtension = fileName.substring(ind_ + 1);
-               int indExt = versionAndExtension.lastIndexOf('.');
-               String moduleVersion = versionAndExtension.substring(0, indExt);
-
-               provider.read(distribution, moduleName, moduleVersion, response
-                               .getOutputStream());
-       }
-
-       public void setProvider(FileProvider provider) {
-               this.provider = provider;
-       }
-
-}
diff --git a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/StreamReadable.java b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/StreamReadable.java
new file mode 100644 (file)
index 0000000..f1bef22
--- /dev/null
@@ -0,0 +1,7 @@
+package org.argeo.slc;
+
+import java.io.InputStream;
+
+public interface StreamReadable {
+       public InputStream getInputStream();
+}
diff --git a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/build/BasicNameVersion.java b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/build/BasicNameVersion.java
new file mode 100644 (file)
index 0000000..c83ef3c
--- /dev/null
@@ -0,0 +1,63 @@
+package org.argeo.slc.build;
+
+public class BasicNameVersion implements NameVersion, Comparable<NameVersion> {
+       private String name;
+       private String version;
+
+       public BasicNameVersion() {
+       }
+
+       public BasicNameVersion(String name, String version) {
+               this.name = name;
+               this.version = version;
+       }
+
+       public BasicNameVersion(NameVersion nameVersion) {
+               this.name = nameVersion.getName();
+               this.version = nameVersion.getVersion();
+       }
+
+       public String getName() {
+               return name;
+       }
+
+       public void setName(String name) {
+               this.name = name;
+       }
+
+       public String getVersion() {
+               return version;
+       }
+
+       public void setVersion(String version) {
+               this.version = version;
+       }
+
+       @Override
+       public boolean equals(Object obj) {
+               if (obj instanceof NameVersion) {
+                       NameVersion nameVersion = (NameVersion) obj;
+                       return name.equals(nameVersion.getName())
+                                       && version.equals(nameVersion.getVersion());
+               } else
+                       return false;
+       }
+
+       @Override
+       public int hashCode() {
+               return name.hashCode() + version.hashCode();
+       }
+
+       @Override
+       public String toString() {
+               return name + ":" + version;
+       }
+
+       public int compareTo(NameVersion o) {
+               if (o.getName().equals(name))
+                       return version.compareTo(o.getVersion());
+               else
+                       return name.compareTo(o.getName());
+       }
+
+}
diff --git a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/build/ModularDistribution.java b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/build/ModularDistribution.java
new file mode 100644 (file)
index 0000000..cc9aacd
--- /dev/null
@@ -0,0 +1,12 @@
+package org.argeo.slc.build;
+
+import java.util.Set;
+
+public interface ModularDistribution extends Distribution, NameVersion {
+       public Distribution getModuleDistribution(String moduleName,
+                       String moduleVersion);
+
+       public Set<NameVersion> listModulesNameVersions();
+
+       public Object getDescriptor(String descriptorType);
+}
diff --git a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/build/NameVersion.java b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/build/NameVersion.java
new file mode 100644 (file)
index 0000000..ae65255
--- /dev/null
@@ -0,0 +1,7 @@
+package org.argeo.slc.build;
+
+public interface NameVersion {
+       public String getName();
+
+       public String getVersion();
+}
index cd2e95eb992ab8d21a075d72c40865bf83ce3d24..be28154fe1db2701ffdf239b363417f24eb88615 100644 (file)
@@ -3,7 +3,7 @@ package org.argeo.slc.deploy;
 import org.argeo.slc.build.Distribution;\r
 \r
 /** An instance of a software system. */\r
 import org.argeo.slc.build.Distribution;\r
 \r
 /** An instance of a software system. */\r
-public interface DeployedSystem<D extends Distribution> extends TargetData {\r
+public interface DeployedSystem extends TargetData {\r
        /** Unique ID for this system instance. */\r
        public String getDeployedSystemId();\r
 \r
        /** Unique ID for this system instance. */\r
        public String getDeployedSystemId();\r
 \r
index 57e38792421ed042381de62a54d598a1b9e6bec2..0020ad6a304649f11128ba94307a9c73a79e5f19 100644 (file)
@@ -1,9 +1,6 @@
 package org.argeo.slc.deploy;
 
 package org.argeo.slc.deploy;
 
-import org.argeo.slc.build.Distribution;
+import org.argeo.slc.build.NameVersion;
 
 
-public interface Module<D extends Distribution> extends DeployedSystem<D> {
-       public String getName();
-
-       public String getVersion();
+public interface Module extends DeployedSystem, NameVersion {
 }
 }
index ff90b95b78e122a99037a13a0ed589e18d097e31..745ba76a616218bb244074fb4fc17b4aadf97fde 100644 (file)
@@ -1,7 +1,6 @@
 package org.argeo.slc.osgi;
 
 import org.argeo.slc.build.Distribution;
 package org.argeo.slc.osgi;
 
 import org.argeo.slc.build.Distribution;
-import org.argeo.slc.core.build.ResourceDistribution;
 import org.argeo.slc.deploy.DeploymentData;
 import org.argeo.slc.deploy.Module;
 import org.argeo.slc.deploy.TargetData;
 import org.argeo.slc.deploy.DeploymentData;
 import org.argeo.slc.deploy.Module;
 import org.argeo.slc.deploy.TargetData;
@@ -9,7 +8,7 @@ import org.argeo.slc.process.RealizedFlow;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.Constants;
 
 import org.osgi.framework.Bundle;
 import org.osgi.framework.Constants;
 
-public class OsgiBundle implements Module<ResourceDistribution> {
+public class OsgiBundle implements Module {
        private String name;
        private String version;
        private Distribution distribution;
        private String name;
        private String version;
        private Distribution distribution;
@@ -20,6 +19,11 @@ public class OsgiBundle implements Module<ResourceDistribution> {
 
        }
 
 
        }
 
+       public OsgiBundle(String name, String version) {
+               this.name = name;
+               this.version = version;
+       }
+
        public OsgiBundle(Bundle bundle) {
                name = bundle.getSymbolicName();
                version = bundle.getHeaders().get(Constants.BUNDLE_VERSION).toString();
        public OsgiBundle(Bundle bundle) {
                name = bundle.getSymbolicName();
                version = bundle.getHeaders().get(Constants.BUNDLE_VERSION).toString();
index f82ceffbaf9092b6b80efdfda6ad266338e48389..e433d7e29e18a14597460a1b483959c659c023a5 100644 (file)
@@ -6,7 +6,7 @@ import java.util.UUID;
 
 import org.argeo.slc.UnsupportedException;
 import org.argeo.slc.build.Distribution;
 
 import org.argeo.slc.UnsupportedException;
 import org.argeo.slc.build.Distribution;
-import org.argeo.slc.core.build.ResourceDistribution;
+import org.argeo.slc.core.build.VersionedResourceDistribution;
 import org.argeo.slc.deploy.DeploymentData;
 import org.argeo.slc.deploy.ModularDeployedSystem;
 import org.argeo.slc.deploy.TargetData;
 import org.argeo.slc.deploy.DeploymentData;
 import org.argeo.slc.deploy.ModularDeployedSystem;
 import org.argeo.slc.deploy.TargetData;
@@ -32,7 +32,10 @@ public class OsgiRuntime implements ModularDeployedSystem<OsgiBundle>,
                        String location = bundle.getLocation();
                        if (location != null) {
                                Resource resource = resourceLoader.getResource(location);
                        String location = bundle.getLocation();
                        if (location != null) {
                                Resource resource = resourceLoader.getResource(location);
-                               osgiBundle.setDistribution(new ResourceDistribution(resource));
+                               osgiBundle
+                                               .setDistribution(new VersionedResourceDistribution(
+                                                               osgiBundle.getName(), osgiBundle.getVersion(),
+                                                               resource));
                        }
                }
                return modules;
                        }
                }
                return modules;
diff --git a/runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/build/BundleModularDistribution.java b/runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/build/BundleModularDistribution.java
new file mode 100644 (file)
index 0000000..79bc3e6
--- /dev/null
@@ -0,0 +1,216 @@
+package org.argeo.slc.osgi.build;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.StringTokenizer;
+import java.util.TreeMap;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.UnsupportedException;
+import org.argeo.slc.build.BasicNameVersion;
+import org.argeo.slc.build.Distribution;
+import org.argeo.slc.build.ModularDistribution;
+import org.argeo.slc.build.NameVersion;
+import org.argeo.slc.core.build.VersionedResourceDistribution;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.ResourceLoaderAware;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.osgi.context.BundleContextAware;
+
+public class BundleModularDistribution implements ModularDistribution,
+               BundleContextAware, InitializingBean, ResourceLoaderAware {
+       private final static Log log = LogFactory
+                       .getLog(BundleModularDistribution.class);
+
+       private BundleContext bundleContext;
+       private ResourceLoader resourceLoader;
+
+       private String libDirectory = "/lib";
+       private EclipseUpdateSite eclipseUpdateSite;
+
+       /** Initialized by the object itself. */
+       private SortedMap<NameVersion, VersionedResourceDistribution> distributions = new TreeMap<NameVersion, VersionedResourceDistribution>();
+
+       public Distribution getModuleDistribution(String moduleName,
+                       String moduleVersion) {
+               return distributions
+                               .get(new BasicNameVersion(moduleName, moduleVersion));
+               // URL url = findModule(moduleName, moduleVersion);
+               // return new ResourceDistribution(new UrlResource(url));
+       }
+
+       @SuppressWarnings(value = { "unchecked" })
+       protected URL findModule(String moduleName, String version) {
+               Enumeration<URL> urls = (Enumeration<URL>) bundleContext.getBundle()
+                               .findEntries(libDirectory, moduleName + "*", false);
+
+               if (!urls.hasMoreElements())
+                       throw new SlcException("Cannot find module " + moduleName);
+
+               URL url = urls.nextElement();
+
+               // TODO: check version as well
+               if (urls.hasMoreElements())
+                       throw new SlcException("More than one module with name "
+                                       + moduleName);
+               return url;
+       }
+
+       public String getDistributionId() {
+               return bundleContext.getBundle().getSymbolicName()
+                               + "-"
+                               + bundleContext.getBundle().getHeaders().get(
+                                               Constants.BUNDLE_VERSION);
+       }
+
+       public Set<NameVersion> listModulesNameVersions() {
+               return distributions.keySet();
+       }
+
+       public void setBundleContext(BundleContext bundleContext) {
+               this.bundleContext = bundleContext;
+       }
+
+       @SuppressWarnings(value = { "unchecked" })
+       public void afterPropertiesSet() throws Exception {
+               Enumeration<URL> urls = (Enumeration<URL>) bundleContext.getBundle()
+                               .findEntries(libDirectory, "*.jar", false);
+               while (urls.hasMoreElements()) {
+                       URL url = urls.nextElement();
+                       JarInputStream in = null;
+                       try {
+                               in = new JarInputStream(url.openStream());
+                               Manifest mf = in.getManifest();
+                               String name = mf.getMainAttributes().getValue(
+                                               Constants.BUNDLE_SYMBOLICNAME);
+                               // Skip additional specs such as
+                               // ; singleton:=true
+                               if (name.indexOf(';') > -1) {
+                                       name = new StringTokenizer(name, " ;").nextToken();
+                               }
+
+                               String version = mf.getMainAttributes().getValue(
+                                               Constants.BUNDLE_VERSION);
+                               BasicNameVersion nameVersion = new BasicNameVersion(name,
+                                               version);
+                               distributions.put(nameVersion,
+                                               new VersionedResourceDistribution(name, version,
+                                                               resourceLoader.getResource(url.toString())));
+                       } finally {
+                               IOUtils.closeQuietly(in);
+                       }
+               }
+               if (log.isDebugEnabled())
+                       log.debug("Distribution " + getName() + ":" + getVersion()
+                                       + " loaded (" + distributions.size() + " modules)");
+
+       }
+
+       protected String findVersion(String name) {
+               Set<String> versions = new HashSet<String>();
+               for (NameVersion key : distributions.keySet()) {
+                       if (key.getName().equals(name))
+                               versions.add(key.getVersion());
+               }
+
+               if (versions.size() == 0)
+                       throw new SlcException("Cannot find version for name " + name);
+               else if (versions.size() > 1)
+                       throw new SlcException("Found more than one version for name "
+                                       + name + ": " + versions);
+               else
+                       return versions.iterator().next();
+
+       }
+
+       public void setLibDirectory(String libDirectory) {
+               this.libDirectory = libDirectory;
+       }
+
+       public Object getDescriptor(String descriptorType) {
+               if (descriptorType.equals("eclipse"))
+                       return writeEclipseUpdateSite();
+               else
+                       throw new UnsupportedException("descriptorType", descriptorType);
+       }
+
+       protected Set<NameVersion> writePlainUrlList() {
+               return distributions.keySet();
+       }
+
+       protected String writeEclipseUpdateSite() {
+               if (eclipseUpdateSite == null)
+                       throw new SlcException("No eclipse update site declared.");
+
+               StringBuffer buf = new StringBuffer("");
+               buf.append("<site>");
+
+               List<EclipseUpdateSiteCategory> usedCategories = new ArrayList<EclipseUpdateSiteCategory>();
+               for (EclipseUpdateSiteFeature feature : eclipseUpdateSite.getFeatures()) {
+
+                       String featureId = feature.getName();
+                       String featureVersion = findVersion(featureId);
+                       buf.append("<feature");
+                       buf.append(" url=\"features/").append(featureId).append('_')
+                                       .append(featureVersion).append(".jar\"");
+                       buf.append(" id=\"").append(featureId).append("\"");
+                       buf.append(" version=\"").append(featureVersion).append("\"");
+                       buf.append(">\n");
+
+                       for (EclipseUpdateSiteCategory category : feature.getCategories()) {
+                               usedCategories.add(category);
+                               buf.append("  <category name=\"").append(category.getName())
+                                               .append("\"/>\n");
+                       }
+                       buf.append("</feature>\n\n");
+               }
+
+               for (EclipseUpdateSiteCategory category : usedCategories) {
+                       buf.append("<category-def");
+                       buf.append(" name=\"").append(category.getName()).append("\"");
+                       buf.append(" label=\"").append(category.getLabel()).append("\"");
+                       buf.append(">\n");
+                       buf.append("  <description>").append(category.getDescription())
+                                       .append("</description>\n");
+                       buf.append("</category-def>\n\n");
+               }
+
+               buf.append("</site>");
+               return buf.toString();
+       }
+
+       public void setResourceLoader(ResourceLoader resourceLoader) {
+               this.resourceLoader = resourceLoader;
+       }
+
+       public String getName() {
+               return bundleContext.getBundle().getSymbolicName();
+       }
+
+       public String getVersion() {
+               return bundleContext.getBundle().getHeaders().get(
+                               Constants.BUNDLE_VERSION).toString();
+       }
+
+       @Override
+       public String toString() {
+               return new BasicNameVersion(this).toString();
+       }
+
+       public void setEclipseUpdateSite(EclipseUpdateSite eclipseUpdateSite) {
+               this.eclipseUpdateSite = eclipseUpdateSite;
+       }
+
+}
diff --git a/runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/build/EclipseUpdateSite.java b/runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/build/EclipseUpdateSite.java
new file mode 100644 (file)
index 0000000..b8debf5
--- /dev/null
@@ -0,0 +1,17 @@
+package org.argeo.slc.osgi.build;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class EclipseUpdateSite {
+       private List<EclipseUpdateSiteFeature> features = new ArrayList<EclipseUpdateSiteFeature>();
+
+       public List<EclipseUpdateSiteFeature> getFeatures() {
+               return features;
+       }
+
+       public void setFeatures(List<EclipseUpdateSiteFeature> features) {
+               this.features = features;
+       }
+
+}
diff --git a/runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/build/EclipseUpdateSiteCategory.java b/runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/build/EclipseUpdateSiteCategory.java
new file mode 100644 (file)
index 0000000..510a555
--- /dev/null
@@ -0,0 +1,32 @@
+package org.argeo.slc.osgi.build;
+
+public class EclipseUpdateSiteCategory {
+       private String name;
+       private String label;
+       private String description;
+
+       public String getLabel() {
+               return label;
+       }
+
+       public void setLabel(String label) {
+               this.label = label;
+       }
+
+       public String getDescription() {
+               return description;
+       }
+
+       public void setDescription(String description) {
+               this.description = description;
+       }
+
+       public String getName() {
+               return name;
+       }
+
+       public void setName(String name) {
+               this.name = name;
+       }
+
+}
diff --git a/runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/build/EclipseUpdateSiteFeature.java b/runtime/org.argeo.slc.support.osgi/src/main/java/org/argeo/slc/osgi/build/EclipseUpdateSiteFeature.java
new file mode 100644 (file)
index 0000000..42ded0b
--- /dev/null
@@ -0,0 +1,26 @@
+package org.argeo.slc.osgi.build;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class EclipseUpdateSiteFeature {
+       private String name;
+       private List<EclipseUpdateSiteCategory> categories = new ArrayList<EclipseUpdateSiteCategory>();
+
+       public String getName() {
+               return name;
+       }
+
+       public void setName(String name) {
+               this.name = name;
+       }
+
+       public List<EclipseUpdateSiteCategory> getCategories() {
+               return categories;
+       }
+
+       public void setCategories(List<EclipseUpdateSiteCategory> categories) {
+               this.categories = categories;
+       }
+
+}
index 998a36e5aad7000a11b720e09e6c7c35e4f4cd4f..7c10f8e9531a8292b7ce91195620a9b42c4ca8ed 100644 (file)
@@ -56,7 +56,7 @@ public class DbUnitDeployment implements Deployment {
                }\r
        }\r
 \r
                }\r
        }\r
 \r
-       public DeployedSystem<?> getDeployedSystem() {\r
+       public DeployedSystem getDeployedSystem() {\r
                throw new UnsupportedOperationException();\r
        }\r
 \r
                throw new UnsupportedOperationException();\r
        }\r
 \r