aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Bauersachs <ingo@jitsi.org>2014-02-03 23:33:16 +0100
committerIngo Bauersachs <ingo@jitsi.org>2014-02-03 23:33:16 +0100
commit8cfed9f5c6d958e2775ebeebf10a9dfec55e8071 (patch)
tree90306b7b9d1b15d1c743353a47311afd2a802a11
parent999e65869142610ff9d6860a0e0e74fe221ffcd7 (diff)
downloadjitsi-8cfed9f5c6d958e2775ebeebf10a9dfec55e8071.zip
jitsi-8cfed9f5c6d958e2775ebeebf10a9dfec55e8071.tar.gz
jitsi-8cfed9f5c6d958e2775ebeebf10a9dfec55e8071.tar.bz2
Webstart-launcher (with HUGE hacks)
-rw-r--r--.gitignore1
-rw-r--r--build.xml2
-rw-r--r--src/net/java/sip/communicator/launcher/SIPCommunicatorJWS.java140
-rw-r--r--web-start/WebStartBuild.properties.sample9
-rw-r--r--web-start/WebStartBuild.xml292
-rw-r--r--web-start/ant-ext/FelixConfigSelector.java92
-rw-r--r--web-start/ant-ext/GenerateFelixConfigs.java161
-rw-r--r--web-start/ant-ext/PutJarsToJnlp.java76
-rw-r--r--web-start/client.jnlp_template102
-rw-r--r--web-start/index.html21
10 files changed, 895 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
index e1a5353..35c6451 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,4 @@ sip-communicator.utest.bin
release
lib/accounts.properties
.DS_Store
+web-start/WebStartBuild.properties
diff --git a/build.xml b/build.xml
index a8d0fb6..85b9ee7 100644
--- a/build.xml
+++ b/build.xml
@@ -1463,7 +1463,7 @@ javax.swing.event, javax.swing.border"/>
<!--BUNDLE-SIP-->
<target name="bundle-sip">
<!--internal-target- Creates a bundle containing the sip implementation of the protocol provider package -->
- <jar compress="false" destfile="${bundles.dest}/protocol-sip.jar"
+ <jar compress="false" destfile="${bundles.dest}/protocol-sip.jar" duplicate="preserve"
manifest="${src}/net/java/sip/communicator/impl/protocol/sip/sip.provider.manifest.mf">
<zipfileset dir="${dest}/net/java/sip/communicator/impl/protocol/sip"
prefix="net/java/sip/communicator/impl/protocol/sip"/>
diff --git a/src/net/java/sip/communicator/launcher/SIPCommunicatorJWS.java b/src/net/java/sip/communicator/launcher/SIPCommunicatorJWS.java
new file mode 100644
index 0000000..51c02c4
--- /dev/null
+++ b/src/net/java/sip/communicator/launcher/SIPCommunicatorJWS.java
@@ -0,0 +1,140 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.launcher;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.net.*;
+import java.util.*;
+import java.util.jar.*;
+import java.util.logging.*;
+
+import net.java.sip.communicator.util.FileHandler;
+import net.java.sip.communicator.util.*;
+
+public class SIPCommunicatorJWS
+{
+ public static void main(String[] args) throws Exception
+ {
+ // allow access to everything
+ System.setSecurityManager(null);
+
+ // prepare the logger
+ // needed by the FileHandler-Logger
+ SIPCommunicator.setScHomeDir(System.getProperty("os.name"));
+ LogManager.getLogManager()
+ .readConfiguration(
+ SIPCommunicatorJWS.class
+ .getResourceAsStream("/logging.properties"));
+
+ for (Handler h : LogManager.getLogManager().getLogger("").getHandlers())
+ LogManager.getLogManager().getLogger("").removeHandler(h);
+ LogManager.getLogManager().getLogger("").addHandler(new FileHandler());
+ LogManager.getLogManager().getLogger("")
+ .addHandler(new ConsoleHandler());
+ for (Handler h : LogManager.getLogManager().getLogger("").getHandlers())
+ h.setFormatter(new ScLogFormatter());
+
+ // be evil :-)
+ // find the path of the nativelibs under webstart (findLibrary is
+ // protected and therefore at least documented api)
+ Method findLibrary =
+ SIPCommunicatorJWS.class.getClassLoader().getClass()
+ .getDeclaredMethod("findLibrary", String.class);
+ findLibrary.setAccessible(true);
+ File path =
+ new File((String) findLibrary.invoke(
+ SIPCommunicatorJWS.class.getClassLoader(), "hid"))
+ .getParentFile();
+ System.setProperty(
+ "java.library.path",
+ System.getProperty("java.library.path") + File.pathSeparator
+ + path.getAbsolutePath());
+
+ // reset sys_paths to re-read usr_paths (runtime-dependent and therefore
+ // very very ugly :()
+ Field sys_paths = ClassLoader.class.getDeclaredField("sys_paths");
+ sys_paths.setAccessible(true);
+ sys_paths.set(null, null);
+
+ // prepare the felix-config with the absolute paths
+ Properties pIn = new Properties();
+ Properties pOut = new Properties();
+ pIn.load(SIPCommunicatorJWS.class.getResourceAsStream(System
+ .getProperty("felix.config.properties")));
+
+ String baseServerUrl =
+ System.getProperty("net.java.sip.communicator.SC_JWS_BASEDIR");
+ ClassLoader cl = SIPCommunicatorJWS.class.getClassLoader();
+ Method getJarFile =
+ cl.getClass().getDeclaredMethod("getJarFile", URL.class);
+ getJarFile.setAccessible(true);
+ for (Map.Entry<Object, Object> e : pIn.entrySet())
+ {
+ if (((String) e.getKey()).startsWith("felix.auto.start."))
+ {
+ String[] refs = ((String) e.getValue()).split("\\s");
+ StringBuilder sb = new StringBuilder();
+ for (String ref : refs)
+ {
+ JarFile localFile =
+ (JarFile) getJarFile.invoke(cl, new URL(baseServerUrl
+ + ref.replace("@URL@", "")));
+ if (localFile != null)
+ {
+ String localFileName =
+ new File(localFile.getName()).toURI().toString();
+ sb.append("reference:");
+ sb.append(localFileName);
+ sb.append(" ");
+ }
+ else
+ {
+ throw new Exception("ref <" + ref
+ + "> not found in cache");
+ }
+ }
+ pOut.put(e.getKey(), sb.toString());
+ }
+ else
+ {
+ pOut.put(e.getKey(), e.getValue());
+ }
+ }
+ File jwsFelixConfig = File.createTempFile("jws", ".properties");
+ jwsFelixConfig.deleteOnExit();
+ pOut.store(new FileOutputStream(jwsFelixConfig),
+ "--- autogenerated, do not edit! ---");
+ System.setProperty("felix.config.properties", jwsFelixConfig.toURI()
+ .toString());
+
+ // Workaround broken desktop shortcut in ubuntu linux:
+ // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6957030
+ try
+ {
+ if (System.getProperty("os.name").equals("Linux"))
+ {
+ File desktop =
+ new File(System.getProperty("user.home") + "/Desktop");
+ File[] files = desktop.listFiles();
+ for (File file : files)
+ {
+ if (file.getName().contains("jws_app_shortcut_"))
+ {
+ file.setExecutable(true, false);
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ }
+
+ // launch the original app
+ SIPCommunicator.main(args);
+ }
+}
diff --git a/web-start/WebStartBuild.properties.sample b/web-start/WebStartBuild.properties.sample
new file mode 100644
index 0000000..f2591cc
--- /dev/null
+++ b/web-start/WebStartBuild.properties.sample
@@ -0,0 +1,9 @@
+# value without trailing '/' (slash)
+java.jdk.dir = c:\\java\\jdk6
+
+keystore.alias =
+keystore.file =
+keystore.password =
+
+# value without trailing '/' (slash)
+webstart.codebase.url = http://localhost/client
diff --git a/web-start/WebStartBuild.xml b/web-start/WebStartBuild.xml
new file mode 100644
index 0000000..5af2789
--- /dev/null
+++ b/web-start/WebStartBuild.xml
@@ -0,0 +1,292 @@
+<!DOCTYPE project>
+<!-- Disables DTD warning -->
+
+<project name="jitsi-webstart">
+
+ <!-- import user-specific/alterable properties -->
+ <property file="${basedir}/WebStartBuild.properties" />
+
+ <property name="webstart.dir" value="${basedir}" />
+ <property name="sc.basedir" value="${webstart.dir}/.." />
+ <property name="release.dir" value="${sc.basedir}/release/web-start" />
+ <property name="tmp.dir" value="${release.dir}/temp" />
+ <property name="ant-ext-src.dir" value="${webstart.dir}/ant-ext" />
+ <property name="ant-ext.dir" value="${sc.basedir}/release/ant-ext" />
+
+ <property name="pack200.path" value="${java.jdk.dir}/bin/pack200" />
+ <property name="unpack200.path" value="${java.jdk.dir}/bin/unpack200" />
+ <property name="jarsigner.path" value="${java.jdk.dir}/bin/jarsigner" />
+
+ <target name="compile-ant-ext">
+ <javac srcdir="${ant-ext-src.dir}" destdir="${ant-ext.dir}" includeantruntime="true" />
+ </target>
+
+ <!-- Custom ant target and typedefs -->
+ <target name="load-ant-ext" depends="compile-ant-ext">
+ <typedef name="felixConfigSelector" classname="FelixConfigSelector" classpath="${ant-ext.dir}" />
+ <taskdef name="PutJarsToJnlp" classname="PutJarsToJnlp" classpath="${ant-ext.dir}" />
+ <taskdef name="GenerateFelixConfigs" classname="GenerateFelixConfigs" classpath="${ant-ext.dir}" />
+ </target>
+
+ <!-- Exclusion of unsupported os's -->
+ <patternset id="unsupported.os.exclude">
+ <exclude name="**/freebsd*/**" />
+ <exclude name="**/solaris*/**" />
+ </patternset>
+
+ <!-- Excluded Bundles or Libs -->
+ <patternset id="excluded.bundles">
+ <exclude name="sc-bundles/addrbook.jar" if="exclude.addressbook" />
+ </patternset>
+
+ <!-- Testing build -->
+ <target name="-all-test">
+ <property name="jnlp.packEnabled" value="false" />
+ <property name="release.name" value="" />
+ </target>
+ <target name="all-test" depends="-all-test, load-ant-ext, make, prepare, copy-libs, copy-config-files, sign-libs" description="Testing build without repacking and compression (faster)." />
+
+ <!-- Production build -->
+ <target name="-all-prod">
+ <property name="jnlp.packEnabled" value="true" />
+ <property name="release.name" value="" />
+ </target>
+ <target name="all-prod" depends="-all-prod, clean, load-ant-ext, make, prepare, copy-libs, copy-config-files, repack-libs, sign-libs, compress-libs, verify-compressed-jars" description="Production build includes all steps (slow)." />
+
+ <target name="all-prod-without-addrbook">
+ <property name="exclude.addressbook" value="true" />
+ <property name="release.name" value="-without-addrbook" />
+ <antcall target="-all-prod" />
+ <antcall target="clean" />
+ <antcall target="make" />
+ <antcall target="prepare" />
+ <antcall target="copy-libs" />
+ <antcall target="copy-config-files" />
+
+ <!-- rename jnlp and configs.jar -->
+ <move file="${release.dir}/client.jnlp" tofile="${release.dir}/client${release.name}.jnlp" />
+ <move file="${release.dir}/jnlp.jar" tofile="${release.dir}/jnlp${release.name}.jar" />
+ <move file="${release.dir}/lib/configs.jar" tofile="${release.dir}/lib/configs${release.name}.jar" />
+
+ <antcall target="repack-libs" />
+ <antcall target="sign-libs" />
+ <antcall target="compress-libs" />
+ <antcall target="verify-compressed-jars" />
+ </target>
+
+ <!-- clean -->
+ <target name="clean" description="Cleans release and temporary directories.">
+ <delete dir="${release.dir}" />
+ <delete dir="${tmp.dir}" />
+ </target>
+
+ <!-- prepare -->
+ <target name="prepare" description="Create folder sturcture.">
+ <mkdir dir="${release.dir}" />
+ <mkdir dir="${release.dir}/lib" />
+ <mkdir dir="${release.dir}/lib/bundle" />
+ <mkdir dir="${release.dir}/native" />
+ <mkdir dir="${release.dir}/sc-bundles" />
+ <mkdir dir="${ant-ext.dir}" />
+ <mkdir dir="${tmp.dir}" />
+ <mkdir dir="${tmp.dir}/JNLP-INF" />
+ </target>
+
+ <!-- make -->
+ <target name="make" description="Compile and package the main project.">
+ <ant dir="${sc.basedir}" antfile="build.xml" target="make-and-deploy" />
+ </target>
+
+ <!-- copy libs -->
+ <target name="copy-libs" description="Copy required libraries in release folder.">
+ <echo message="Copying libs in ${release.dir}" />
+ <copy todir="${release.dir}">
+ <fileset dir="${sc.basedir}">
+ <!-- Include ... -->
+ <!-- ... jars for felix startup -->
+ <include name="lib/*.jar" />
+ <!-- ... os specific jars for felix startup -->
+ <include name="lib/os-specific/**/*.jar" />
+ <!-- ... os specific Sip-Comm bundles -->
+ <include name="sc-bundles/os-specific/**/*.jar" />
+ <!-- ... Sip-Comm launcher -->
+ <include name="sc-bundles/sc-launcher.jar" />
+
+ <!-- Exclude ... -->
+ <!-- ... installer stuff -->
+ <exclude name="**/installer-exclude/*" />
+ <!-- ... unsupported os's -->
+ <patternset refid="unsupported.os.exclude" />
+ </fileset>
+
+ <fileset dir="${sc.basedir}">
+ <!-- Copy all bundles referenced in felix config file. -->
+ <include name="lib/**" />
+ <include name="sc-bundles/**" />
+ <felixConfigSelector felixConfig="${sc.basedir}/lib/felix.client.run.properties" />
+ <patternset refid="excluded.bundles" />
+ </fileset>
+ </copy>
+
+ <!-- Package and copy native libraries -->
+ <subant genericantfile="${ant.file}" target="-jar-natives" inheritall="true">
+ <dirset dir="${sc.basedir}/lib/native/" includes="*">
+ <patternset refid="unsupported.os.exclude" />
+ </dirset>
+ </subant>
+ </target>
+
+ <!-- Package and copy native libraries -->
+ <target name="-jar-natives">
+ <!-- Get the last part of the directory (windows, linux, etc.) -->
+ <basename file="${basedir}" property="jarname" />
+
+ <jar destfile="${release.dir}/native/${jarname}.jar">
+ <fileset dir="${basedir}" />
+ </jar>
+ </target>
+
+ <!-- sign libs -->
+ <target name="sign-libs" description="Sign all jars within the release folder.">
+ <echo message="Signing libs in ${release.dir}" />
+ <signjar alias="${keystore.alias}" keystore="${keystore.file}" storepass="${keystore.password}" lazy="true">
+ <path>
+ <fileset dir="${release.dir}" includes="**/*.jar" />
+ </path>
+ </signjar>
+ </target>
+
+ <!-- repack libs -->
+ <target name="repack-libs" description="Repack all jars within release folder.">
+ <echo message="Repacking libs in ${release.dir}" />
+ <apply executable="${pack200.path}" parallel="false">
+ <arg value="--repack" />
+ <fileset dir="${release.dir}" includes="**/*.jar" />
+ </apply>
+ </target>
+
+ <!-- compress libs -->
+ <target name="compress-libs" description="Comperss all jars within release folder.">
+ <echo message="Compressing libs in ${release.dir}" />
+ <apply executable="${pack200.path}" parallel="false" dest="${release.dir}">
+ <!--<arg value="- -modification-time=latest"/>-->
+ <!-- Arg 'segment-limit=-1' omitted because it broke signatures of some jars -->
+ <targetfile />
+ <srcfile />
+ <fileset dir="${release.dir}" includes="**/*.jar">
+ <!-- Exclude Libs which can not be compressed -->
+ <exclude name="**/os-specific/macosx/neomedia.jar" />
+ <exclude name="**/os-specific/linux/neomedia.jar" />
+ </fileset>
+ <mapper type="glob" from="*" to="*.pack.gz" />
+ </apply>
+ </target>
+
+ <!-- verify compressed jars -->
+ <target name="verify-compressed-jars">
+ <echo message="Verifying compressed libs in ${release.dir}" />
+
+ <!-- create temporary folder -->
+ <property name="verify.dir" value="${tmp.dir}/verification" />
+ <mkdir dir="${tmp.dir}/verification" />
+
+ <!-- unpack in temporary folder -->
+ <apply executable="${unpack200.path}" parallel="false" dest="${verify.dir}">
+ <!--<arg value="-v" />-->
+ <srcfile />
+ <targetfile />
+ <fileset dir="${release.dir}" includes="**/*.jar.pack.gz" />
+ <chainedmapper>
+ <packagemapper from="*" to="*" />
+ <mapper type="glob" from="*.jar.pack.gz" to="*.jar" />
+ <!-- rename -->
+ </chainedmapper>
+ </apply>
+
+ <!-- verify unpacked jars -->
+ <apply executable="${jarsigner.path}" failonerror="false">
+ <arg value="-verify" />
+ <!--<arg value="-verbose" />-->
+ <srcfile />
+ <fileset dir="${verify.dir}" includes="**/*.jar" />
+ </apply>
+ </target>
+
+ <!-- copy config files -->
+ <target name="copy-config-files" description="Copy and package webstart configuration files.">
+ <echo message="Create and copy config files in ${release.dir}" />
+ <PutJarsToJnlp bundledir="${release.dir}/sc-bundles" osbundles="${release.dir}/sc-bundles/os-specific" />
+ <subant genericantfile="${ant.file}" target="-build-felix-files-os" inheritall="true">
+ <dirset dir="${release.dir}/sc-bundles/os-specific" includes="*" />
+ </subant>
+
+ <!-- Copy template files -->
+ <copy todir="${tmp.dir}" overwrite="yes">
+ <fileset dir=".">
+ <include name="*_template" />
+ </fileset>
+
+ <!-- remove '_template' suffix -->
+ <mapper type="glob" from="*_template" to="*" />
+
+ <!-- replace '@_@' tokens with value -->
+ <filterset>
+ <filter token="URL" value="${webstart.codebase.url}" />
+ <filter token="COMMON" value="${jnlp.jars.common}" />
+ <filter token="WINDOWS" value="${jnlp.jars.windows}" />
+ <filter token="LINUX" value="${jnlp.jars.linux}" />
+ <filter token="MACOSX" value="${jnlp.jars.macosx}" />
+ <filter token="PACKENABLED" value="${jnlp.packEnabled}" />
+ <filter token="RELEASE" value="${release.name}" />
+ </filterset>
+ </copy>
+
+ <!-- Delete comments marked as INTERNAL_COMMENT from jnlp file. Example on next line: -->
+ <!-- INTERNAL_COMMENT some text ... -->
+ <replaceregexp match="&lt;!-- INTERNAL_COMMENT .*?-->" replace="" flags="gs">
+ <fileset dir="${tmp.dir}">
+ <include name="*.jnlp" />
+ </fileset>
+ </replaceregexp>
+
+ <copy todir="${release.dir}">
+ <fileset dir="${tmp.dir}">
+ <include name="client.jnlp" />
+ </fileset>
+ </copy>
+
+ <copy tofile="${tmp.dir}/JNLP-INF/APPLICATION.JNLP" file="${tmp.dir}/client.jnlp" />
+ <jar destfile="${release.dir}/jnlp.jar">
+ <fileset dir="${tmp.dir}">
+ <include name="JNLP-INF/**" />
+ </fileset>
+ </jar>
+
+ <jar destfile="${release.dir}/lib/configs.jar">
+ <fileset dir="${sc.basedir}/resources/install">
+ <include name="logging.properties" />
+ </fileset>
+ <fileset dir="${tmp.dir}">
+ <include name="*.properties" />
+ </fileset>
+ </jar>
+
+ <!-- Copy index.html and images -->
+ <copy file="index.html" todir="${release.dir}"/>
+ <copy file="${sc.basedir}/resources/images/logo/sc_logo_64x64.png" todir="${release.dir}" />
+ </target>
+
+ <!-- Assemble os specific felix configuration files -->
+ <target name="-build-felix-files-os">
+ <!-- Get the last part of the directory (windows, linux, etc.) -->
+ <basename file="${basedir}" property="osname" />
+
+ <GenerateFelixConfigs file="${sc.basedir}/lib/felix.client.run.properties" os="${osname}" bundledir="${release.dir}/sc-bundles" libdir="${release.dir}/lib/bundle" output="${tmp.dir}/felix.client.run.${osname}.properties" />
+ </target>
+</project>
+
+<!--
+ Useful sources:
+ - Pack200 and Compression: http://download.oracle.com/javase/6/docs/technotes/guides/deployment/deployment-guide/pack200.html
+ - Pack200 in Ant: http://stackoverflow.com/questions/3312401/how-to-make-an-ant-task-to-sign-and-pack200-all-my-jar-files
+-->
diff --git a/web-start/ant-ext/FelixConfigSelector.java b/web-start/ant-ext/FelixConfigSelector.java
new file mode 100644
index 0000000..e1ceae8
--- /dev/null
+++ b/web-start/ant-ext/FelixConfigSelector.java
@@ -0,0 +1,92 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license. See terms of license at gnu.org.
+ */
+import java.io.*;
+import java.util.*;
+
+import org.apache.tools.ant.*;
+import org.apache.tools.ant.types.selectors.*;
+
+/**
+ * Selector which lets those files through that are referenced in the felix
+ * configuration file.
+ */
+public class FelixConfigSelector
+ implements FileSelector
+{
+ private Set<File> referencedBundleCache;
+
+ private File felixConfig;
+
+ public void setFelixConfig(File felixConifg)
+ {
+ if (!felixConifg.isFile())
+ throw new BuildException("No felix configuration file provided.");
+
+ this.felixConfig = felixConifg;
+ }
+
+ @Override
+ public boolean isSelected(File basedir, String filename, File file)
+ {
+ cacheConfigEntries(basedir);
+ return referencedBundleCache.contains(file);
+ }
+
+ private void cacheConfigEntries(File basedir)
+ {
+ if (referencedBundleCache != null)
+ return;
+
+ // cache files referenced in felix config
+ referencedBundleCache = new HashSet<File>();
+
+ // load felix config
+ Properties pIn = new Properties();
+ try
+ {
+ pIn.load(new FileInputStream(felixConfig));
+ }
+ catch (FileNotFoundException e)
+ {
+ throw new BuildException(e);
+ }
+ catch (IOException e)
+ {
+ throw new BuildException(e);
+ }
+
+ for (Map.Entry<Object, Object> e : pIn.entrySet())
+ {
+ if (((String) e.getKey()).startsWith("felix.auto.start."))
+ {
+ String[] refs = ((String) e.getValue()).split("\\s");
+ for (String jar : refs)
+ {
+ if (jar.startsWith("reference:file:"))
+ {
+ String relPath =
+ jar.substring("reference:file:".length());
+ String absPath =
+ basedir.getPath() + File.separator + relPath;
+ File f = new File(absPath);
+ if (f.isFile())
+ {
+ referencedBundleCache.add(f);
+ }
+ else
+ {
+ System.out.println(
+ "WARNING: Referenced file does not exist: "
+ + f.getPath());
+ }
+ }
+ }
+ }
+ }
+
+ }
+
+}
diff --git a/web-start/ant-ext/GenerateFelixConfigs.java b/web-start/ant-ext/GenerateFelixConfigs.java
new file mode 100644
index 0000000..2a1db05
--- /dev/null
+++ b/web-start/ant-ext/GenerateFelixConfigs.java
@@ -0,0 +1,161 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license. See terms of license at gnu.org.
+ */
+import org.apache.tools.ant.*;
+
+import java.io.*;
+import java.util.*;
+
+public class GenerateFelixConfigs
+ extends Task
+{
+ private File baseConfig;
+
+ private String os;
+
+ private File libdir;
+
+ private File bundledir;
+
+ private File output;
+
+ public void setFile(File f)
+ {
+ baseConfig = f;
+ }
+
+ public void setOs(String os)
+ {
+ this.os = os;
+ }
+
+ public void setBundledir(File bundledir)
+ {
+ this.bundledir = bundledir;
+ }
+
+ public void setLibdir(File libdir)
+ {
+ this.libdir = libdir;
+ }
+
+ public void setOutput(File output)
+ {
+ this.output = output;
+ }
+
+ public void execute() throws BuildException
+ {
+ try
+ {
+ execute0();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ throw new BuildException(e);
+ }
+ }
+
+ public void execute0() throws BuildException
+ {
+ Properties pIn = new Properties();
+ Properties pOut = new Properties();
+ try
+ {
+ pIn.load(new FileInputStream(baseConfig));
+ }
+ catch (FileNotFoundException e)
+ {
+ throw new BuildException(e);
+ }
+ catch (IOException e)
+ {
+ throw new BuildException(e);
+ }
+
+ for (Map.Entry<Object, Object> e : pIn.entrySet())
+ {
+ if (((String) e.getKey()).startsWith("felix.auto.start."))
+ {
+ String[] refs = ((String) e.getValue()).split("\\s");
+ StringBuilder value = new StringBuilder();
+ for (String jar : refs)
+ {
+ if (jar.startsWith("reference:file:sc-bundles/"))
+ {
+ String name =
+ jar.substring("reference:file:sc-bundles/".length());
+ if (contains(
+ new File(bundledir, "os-specific/" + os).list(),
+ name))
+ {
+ value.append("@URL@/sc-bundles/");
+ value.append("os-specific/");
+ value.append(os);
+ value.append("/");
+ value.append(name);
+ }
+ else if (contains(bundledir.list(), name))
+ {
+ value.append("@URL@/sc-bundles/");
+ value.append(name);
+ }
+ else
+ {
+ log("Bundle <" + name + "> not found in <"
+ + bundledir.getName()
+ + ">. Seems like this bundle was ignored.");
+ }
+ }
+ else if (jar.startsWith("reference:file:lib/bundle/"))
+ {
+ String name =
+ jar.substring("reference:file:lib/bundle/".length());
+ if (contains(libdir.list(), name))
+ {
+ value.append("@URL@/lib/bundle/");
+ value.append(name);
+ }
+ else
+ {
+ log("Lib <" + name + "> not found in <" + libdir
+ + ">. Seems like this lib was ignored.");
+ }
+ }
+ else
+ {
+ throw new BuildException(
+ "unsupported reference prefix: " + jar);
+ }
+ value.append(" ");
+ }
+ pOut.put(e.getKey(), value.toString());
+ }
+ else
+ {
+ pOut.put(e.getKey(), e.getValue());
+ }
+ }
+ try
+ {
+ pOut.store(new FileOutputStream(output),
+ "--- autogenerated by GenerateFelixConfigs, do not edit! ---");
+ }
+ catch (FileNotFoundException e)
+ {
+ throw new BuildException(e);
+ }
+ catch (IOException e)
+ {
+ throw new BuildException(e);
+ }
+ }
+
+ private boolean contains(String[] files, String file)
+ {
+ return Arrays.asList(files).contains(file);
+ }
+}
diff --git a/web-start/ant-ext/PutJarsToJnlp.java b/web-start/ant-ext/PutJarsToJnlp.java
new file mode 100644
index 0000000..de59760
--- /dev/null
+++ b/web-start/ant-ext/PutJarsToJnlp.java
@@ -0,0 +1,76 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license. See terms of license at gnu.org.
+ */
+import org.apache.tools.ant.*;
+
+import java.io.*;
+import java.util.*;
+
+public class PutJarsToJnlp
+ extends Task
+{
+ private File bundledir;
+
+ private File osbundles;
+
+ public void setBundledir(File b)
+ {
+ bundledir = b;
+ }
+
+ public void setOsbundles(File f)
+ {
+ osbundles = f;
+ }
+
+ public void execute() throws BuildException
+ {
+ try
+ {
+ execute0();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ throw new BuildException(e);
+ }
+ }
+
+ public void execute0() throws BuildException
+ {
+ StringBuilder common = new StringBuilder();
+ for (File jar : bundledir.listFiles())
+ {
+ if (jar.isFile())
+ {
+ common.append("<jar href=\"sc-bundles/");
+ common.append(jar.getName());
+ common.append("\"/>\n");
+ }
+ }
+ getProject().setProperty("jnlp.jars.common", common.toString());
+
+ for (File dir : osbundles.listFiles())
+ {
+ if (dir.isDirectory())
+ {
+ StringBuilder os = new StringBuilder();
+ for (File jar : dir.listFiles())
+ {
+ if (jar.isFile())
+ {
+ os.append("<jar href=\"sc-bundles/os-specific/");
+ os.append(dir.getName());
+ os.append("/");
+ os.append(jar.getName());
+ os.append("\"/>\n");
+ }
+ }
+ getProject().setProperty("jnlp.jars." + dir.getName(),
+ os.toString());
+ }
+ }
+ }
+}
diff --git a/web-start/client.jnlp_template b/web-start/client.jnlp_template
new file mode 100644
index 0000000..58079dd
--- /dev/null
+++ b/web-start/client.jnlp_template
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- JNLP File -->
+<jnlp spec="1.0+" codebase="@URL@" href="client@RELEASE@.jnlp">
+ <information>
+ <title>Jitsi</title>
+ <vendor>jitsi.org</vendor>
+ <description>Jitsi - Open Source Video Calls and Chat</description>
+ <homepage href="@URL@"/>
+ <icon href="sc_logo_64x64.png"/>
+ <!-- INTERNAL_COMMENT
+ Seems the Splashscreen does not work properly.
+ See: http://blogs.sun.com/thejavatutorials/entry/changing_the_java_web_start
+ -->
+ <shortcut online="true">
+ <desktop/>
+ <menu submenu="Jitsi"/>
+ </shortcut>
+ </information>
+
+ <!-- INTERNAL_COMMENT
+ Request all permissions. Application must be signed. -->
+ <security>
+ <all-permissions/>
+ </security>
+
+ <!-- Windows common -->
+ <resources os="Windows">
+ <!--<jar href="lib/os-specific/windows/jdic_stub.jar" />-->
+ <property name="felix.config.properties" value="/felix.client.run.windows.properties" />
+ <property name="net.java.sip.communicator.SC_HOME_DIR_NAME" value="jitsi-jws"/>
+
+ @WINDOWS@
+ </resources>
+
+ <!-- Windows 32 bit -->
+ <resources os="Windows" arch="x86">
+ <nativelib href="native/windows.jar"/>
+ </resources>
+
+ <!-- Windows 64 bit -->
+ <resources os="Windows" arch="x86_64 amd64">
+ <nativelib href="native/windows-64.jar"/>
+ </resources>
+
+ <!-- Linux common -->
+ <resources os="Linux">
+ <!--<jar href="lib/os-specific/linux/jdic_stub.jar" />-->
+ <property name="felix.config.properties" value="/felix.client.run.linux.properties" />
+ <property name="net.java.sip.communicator.SC_HOME_DIR_NAME" value=".jitsi-jws"/>
+ <!-- INTERNAL_COMMENT
+ Accelerates certificate generation in unix systems. This property instructs NativePRNG
+ class to use /dev/urandom to build up entropy. Normally /dev/random is used, which is safer
+ but much more slower because the entropy is build upon system events.
+ See: http://stackoverflow.com/questions/137212/how-to-solve-performance-problem-with-java-securerandom
+ !!! The '.' in the path of the url is necessary to avoid Java Bug 6202721 !!!
+ See: http://bugs.sun.com/view_bug.do;jsessionid=ff625daf459fdffffffffcd54f1c775299e0?bug_id=6202721
+ -->
+ <property name="java.security.egd" value="file:/dev/./urandom"/>
+
+ @LINUX@
+ </resources>
+
+ <!-- Linux 32 bit -->
+ <resources os="Linux" arch="i386">
+ <nativelib href="native/linux.jar"/>
+ </resources>
+
+ <!-- Linux 64 bit -->
+ <resources os="Linux" arch="amd64">
+ <nativelib href="native/linux-64.jar"/>
+ </resources>
+
+ <!-- Mac -->
+ <resources os="Mac OS X">
+ <!--<jar href="lib/os-specific/mac/jdic_stub.jar" />-->
+ <property name="felix.config.properties" value="/felix.client.run.macosx.properties" />
+ <property name="net.java.sip.communicator.SC_HOME_DIR_NAME" value=".jitsi-jws"/>
+ <nativelib href="native/mac.jar"/>
+
+ @MACOSX@
+ </resources>
+
+ <resources>
+ <j2se version="1.6+" href="http://java.sun.com/products/autodl/j2se"/>
+ <property name="net.java.sip.communicator.SC_JWS_BASEDIR" value="@URL@"/>
+ <!-- INTERNAL_COMMENT
+ Use compressed Jars if available -->
+ <property name="jnlp.packEnabled" value="@PACKENABLED@"/>
+
+ <jar href="jnlp@RELEASE@.jar" main="true" />
+ <jar href="lib/configs@RELEASE@.jar" />
+ <!--<jar href="lib/jdic-all.jar" />-->
+ <jar href="lib/felix.jar" />
+ <jar href="lib/bundle/org.apache.felix.bundlerepository-1.6.4.jar" />
+ <jar href="lib/bundle/log4j.jar" />
+ <jar href="lib/bundle/commons-logging.jar" />
+ @COMMON@
+ </resources>
+
+ <application-desc main-class="net.java.sip.communicator.launcher.SIPCommunicatorJWS"/>
+</jnlp>
+
diff --git a/web-start/index.html b/web-start/index.html
new file mode 100644
index 0000000..cdeadcd
--- /dev/null
+++ b/web-start/index.html
@@ -0,0 +1,21 @@
+<html>
+<body>
+<a href="client.jnlp">Launch Jitsi</a> </br>
+
+<p>
+Tested Operating Systems:
+<ul>
+ <li>Windows Vista, 7, 8 (32 & 64 bit)</li>
+ <li>Windows XP 32 bit</li>
+ <li>Mac OS X</li>
+ <li>Ubuntu Linux 32 & 64 bit</li>
+</ul>
+Only Sun's/Oracle's JVM is supported and tested. Your Java Web Start cache must be enabled.
+</p>
+<p>
+In case Jitsi starts with errors please delete the 'jitsi-jws'
+folder in your home directory and try again. If this does not solve the problem contact us.
+</p>
+
+</body>
+</html>