general java webstart issues, going back to the 'roots' ;-)
diff --git a/plugins/org.eclipse.epp.wizard.installerbuilder/opt/epp/htdocs/CVS_DIRECTORY_KEEPER b/plugins/org.eclipse.epp.wizard.installerbuilder/opt/epp/htdocs/CVS_DIRECTORY_KEEPER
index 7ce6f74..dc8a714 100644
--- a/plugins/org.eclipse.epp.wizard.installerbuilder/opt/epp/htdocs/CVS_DIRECTORY_KEEPER
+++ b/plugins/org.eclipse.epp.wizard.installerbuilder/opt/epp/htdocs/CVS_DIRECTORY_KEEPER
@@ -1 +1 @@
-When can we abandon CVS for something better?
+When can we abandon CVS for something better?

diff --git a/plugins/org.eclipse.epp.wizard.installerbuilder/opt/epp/templates/installer/installer.properties b/plugins/org.eclipse.epp.wizard.installerbuilder/opt/epp/templates/installer/installer.properties
index 5c8a4d6..2c019a3 100644
--- a/plugins/org.eclipse.epp.wizard.installerbuilder/opt/epp/templates/installer/installer.properties
+++ b/plugins/org.eclipse.epp.wizard.installerbuilder/opt/epp/templates/installer/installer.properties
@@ -1,7 +1,7 @@
-eclipse.p2.roots=%?%
-eclipse.p2.metadata=%?%
-eclipse.p2.artifacts=%?%
-eclipse.p2.flavor=tooling
-eclipse.p2.profileName=Custom Eclipse
-eclipse.p2.launcherName=eclipse
+eclipse.p2.roots=%?%

+eclipse.p2.metadata=%?%

+eclipse.p2.artifacts=%?%

+eclipse.p2.flavor=tooling

+eclipse.p2.profileName=Custom Eclipse

+eclipse.p2.launcherName=eclipse

 eclipse.p2.autoStart=true
\ No newline at end of file
diff --git a/plugins/org.eclipse.epp.wizard.installerbuilder/opt/epp/templates/jnlp/epp.jnlp b/plugins/org.eclipse.epp.wizard.installerbuilder/opt/epp/templates/jnlp/epp.jnlp
index 7590401..d55cd77 100644
--- a/plugins/org.eclipse.epp.wizard.installerbuilder/opt/epp/templates/jnlp/epp.jnlp
+++ b/plugins/org.eclipse.epp.wizard.installerbuilder/opt/epp/templates/jnlp/epp.jnlp
@@ -5,7 +5,7 @@
   <vendor>eclipse.org</vendor>

   <homepage href="http://eclipse.org" />

   <description>EPP Package Installer</description>

-  <icon kind="splash" href="splash.gif"/>

+  <icon kind="splash" href="splash.jpg"/>

   <offline-allowed/>

 </information>

 <security>

@@ -22,13 +22,13 @@
 <resources>

   <j2se version="1.4+"/>

   <jar href="launcher.jar"/>

-  <extension name="p2 Installer Feature" href="features/org.eclipse.equinox.p2.installer.feature_1.0.0.jnlp"/>

+  <extension name="p2 Installer Feature" href="features/org.eclipse.equinox.p2.installer.feature_1.0.100.jnlp"/>

   <property name="eclipse.product" value="org.eclipse.equinox.p2.installer.product"/>

   <property name="osgi.bundles" value="org.eclipse.equinox.app@start,org.eclipse.equinox.frameworkadmin.equinox@start,org.eclipse.equinox.simpleconfigurator.manipulator@start"/>

 

   <property name="eclipse.p2.roots" value="${roots}"/>

-  <property name="eclipse.p2.metadata" value="http://download.eclipse.org/eclipse/testUpdates"/>

-  <property name="eclipse.p2.artifacts" value="http://download.eclipse.org/eclipse/testUpdates"/>

+  <property name="eclipse.p2.metadata" value="${metadata}"/>

+  <property name="eclipse.p2.artifacts" value="${artifacts}"/>

   <property name="eclipse.p2.flavor" value="tooling"/>

   <property name="eclipse.p2.profileName" value="${profileName}"/>

   <property name="eclipse.p2.launcherName" value="eclipse"/>

diff --git a/plugins/org.eclipse.epp.wizard.installerbuilder/opt/epp/templates/jnlp/launcher.jar b/plugins/org.eclipse.epp.wizard.installerbuilder/opt/epp/templates/jnlp/launcher.jar
index 1a3e69f..ffc9f1f 100644
--- a/plugins/org.eclipse.epp.wizard.installerbuilder/opt/epp/templates/jnlp/launcher.jar
+++ b/plugins/org.eclipse.epp.wizard.installerbuilder/opt/epp/templates/jnlp/launcher.jar
Binary files differ
diff --git a/plugins/org.eclipse.epp.wizard.installerbuilder/opt/epp/templates/jnlp/splash.jpg b/plugins/org.eclipse.epp.wizard.installerbuilder/opt/epp/templates/jnlp/splash.jpg
index 85f4d37..3784eaf 100644
--- a/plugins/org.eclipse.epp.wizard.installerbuilder/opt/epp/templates/jnlp/splash.jpg
+++ b/plugins/org.eclipse.epp.wizard.installerbuilder/opt/epp/templates/jnlp/splash.jpg
Binary files differ
diff --git a/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/installerbuilder/Activator.java b/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/installerbuilder/Activator.java
index e52482c..748a0ae 100644
--- a/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/installerbuilder/Activator.java
+++ b/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/installerbuilder/Activator.java
@@ -1,80 +1,80 @@
-/*******************************************************************************
- * Copyright (c) 2008 Innoopract Informationssysteme GmbH.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Innoopract Informationssysteme GmbH - initial API and implementation
- ******************************************************************************/
-package org.eclipse.epp.wizard.installerbuilder;
-
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.Properties;
-
-import org.apache.log4j.Logger;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-
-public class Activator implements BundleActivator {
-
-  static Logger logger = Logger.getLogger( Activator.class );
-  public static final String PROPERTY_CONFIGURATION = "org.eclipse.epp.wizard.installerbuilder.configuration";
-  public static final String PROPERTY_CONFIGURATION_DEFAULT_VALUE = "installerbuilder.properties";
-  private static BundleContext context;
-
-  public static BundleContext getContext() {
-    return context;
-  }
-  private Configuration configuration;
-  private InstallerCache installerCache;
-
-  public InstallerCache getInstallerCache() {
-    return installerCache;
-  }
-  private static Activator plugin;
-
-  public Activator() {
-  }
-
-  /**
-   * Returns the shared instance
-   * 
-   * @return the shared instance
-   */
-  public static Activator getDefault() {
-    return plugin;
-  }
-
-  public void start( BundleContext context ) throws Exception {
-    Activator.context = context;
-    plugin = this;
-    getConfiguration();
-    installerCache = new InstallerCache( configuration.getInstallerCacheSize() );
-  }
-
-  public void stop( BundleContext context ) throws Exception {
-    Activator.context = null;
-  }
-
-  public synchronized Configuration getConfiguration() {
-    if( configuration == null ) {
-      String configurationFile = System.getProperty( PROPERTY_CONFIGURATION,
-                                                     PROPERTY_CONFIGURATION_DEFAULT_VALUE );
-      logger.info( "Loading configuration from file: " + configurationFile );
-      Properties properties = new Properties();
-      try {
-        properties.load( new FileInputStream( configurationFile ) );
-        configuration = new Configuration( properties );
-      } catch( FileNotFoundException exc ) {
-        logger.error( "Could not load configuration", exc );
-      } catch( IOException exc ) {
-        logger.error( "Could not load configuration", exc );
-      }
-    }
-    return configuration;
-  }
-}
+/*******************************************************************************

+ * Copyright (c) 2008 Innoopract Informationssysteme GmbH.

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * which accompanies this distribution, and is available at

+ * http://www.eclipse.org/legal/epl-v10.html

+ *

+ * Contributors:

+ *     Innoopract Informationssysteme GmbH - initial API and implementation

+ ******************************************************************************/

+package org.eclipse.epp.wizard.installerbuilder;

+

+import java.io.FileInputStream;

+import java.io.FileNotFoundException;

+import java.io.IOException;

+import java.util.Properties;

+

+import org.apache.log4j.Logger;

+import org.osgi.framework.BundleActivator;

+import org.osgi.framework.BundleContext;

+

+public class Activator implements BundleActivator {

+

+  static Logger logger = Logger.getLogger( Activator.class );

+  public static final String PROPERTY_CONFIGURATION = "org.eclipse.epp.wizard.installerbuilder.configuration";

+  public static final String PROPERTY_CONFIGURATION_DEFAULT_VALUE = "installerbuilder.properties";

+  private static BundleContext context;

+

+  public static BundleContext getContext() {

+    return context;

+  }

+  private Configuration configuration;

+  private InstallerCache installerCache;

+

+  public InstallerCache getInstallerCache() {

+    return installerCache;

+  }

+  private static Activator plugin;

+

+  public Activator() {

+  }

+

+  /**

+   * Returns the shared instance

+   * 

+   * @return the shared instance

+   */

+  public static Activator getDefault() {

+    return plugin;

+  }

+

+  public void start( BundleContext context ) throws Exception {

+    Activator.context = context;

+    plugin = this;

+    getConfiguration();

+    installerCache = new InstallerCache( configuration.getInstallerCacheSize() );

+  }

+

+  public void stop( BundleContext context ) throws Exception {

+    Activator.context = null;

+  }

+

+  public synchronized Configuration getConfiguration() {

+    if( configuration == null ) {

+      String configurationFile = System.getProperty( PROPERTY_CONFIGURATION,

+                                                     PROPERTY_CONFIGURATION_DEFAULT_VALUE );

+      logger.info( "Loading configuration from file: " + configurationFile );

+      Properties properties = new Properties();

+      try {

+        properties.load( new FileInputStream( configurationFile ) );

+        configuration = new Configuration( properties );

+      } catch( FileNotFoundException exc ) {

+        logger.error( "Could not load configuration", exc );

+      } catch( IOException exc ) {

+        logger.error( "Could not load configuration", exc );

+      }

+    }

+    return configuration;

+  }

+}

diff --git a/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/installerbuilder/BuildInstaller.java b/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/installerbuilder/BuildInstaller.java
index c19a874..3b0ad88 100644
--- a/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/installerbuilder/BuildInstaller.java
+++ b/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/installerbuilder/BuildInstaller.java
@@ -1,286 +1,286 @@
-/*******************************************************************************
- * Copyright (c) 2008 Innoopract Informationssysteme GmbH.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Innoopract Informationssysteme GmbH - initial API and implementation
- ******************************************************************************/
-package org.eclipse.epp.wizard.installerbuilder;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.StringTokenizer;
-import java.util.zip.GZIPInputStream;
-import java.util.zip.GZIPOutputStream;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-import java.util.zip.ZipOutputStream;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.tools.tar.TarEntry;
-import org.apache.tools.tar.TarInputStream;
-import org.apache.tools.tar.TarOutputStream;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.epp.wizard.util.OsUtil;
-import org.eclipse.epp.wizard.util.StringUtil;
-
-/**
- * @author Jordi Boehme Lopez <jboehme@innoopract.com>
- */
-public class BuildInstaller extends HttpServlet {
-
-  public static final String OUTPUT_PATH = "htdocs";
-  private static final String INSTALLER_TEMPLATE_PATH = "templates/installer";
-  private static final String ENCODING = "UTF-8";
-  private static final int BUFFER = 512;
-  private static final long serialVersionUID = 1L;
-
-  @Override
-  protected void doGet( final HttpServletRequest req,
-                        final HttpServletResponse resp )
-    throws ServletException, IOException
-  {
-    String os = req.getParameter( "os" );
-    String iuParam = req.getParameter( "ius" );
-    String filename = req.getParameter( "filename" );
-    execute( os, iuParam, filename );
-  }
-
-  public static void execute( final String os,
-                              final String iuParam,
-                              final String filename ) throws IOException
-  {
-    File downloadDir = Activator.getDefault()
-      .getConfiguration()
-      .getDownloadsDirectory();
-    IPath outDirPath = new Path( new File( downloadDir, OUTPUT_PATH ).getAbsolutePath() );
-    IPath rawInstallerDirPath = new Path( new File( downloadDir,
-                                                    INSTALLER_TEMPLATE_PATH ).getAbsolutePath() );
-    String[] ius = getIUs( iuParam );
-    File template = findRawInstallerFile( rawInstallerDirPath, os );
-    IPath outFilePath = outDirPath.append( filename );
-    ceateCustomInstaller( os, template, ius, outFilePath.toFile() );
-  }
-
-  public static String getFileName( final String os, final String[] ids ) {
-    String hash = ids.toString();
-    try {
-      hash = StringUtil.getHash( ids );
-    } catch( NoSuchAlgorithmException exc ) {
-      // should not happen! - but trace anyway
-      exc.printStackTrace();
-    }
-    return "eclipse-" + os + "-" + hash + "." + OsUtil.getArchiveExtension( os );
-  }
-
-  // ////////////////
-  // helping methods
-  // ////////////////
-  private static String[] getIUs( final String param ) {
-    List<String> result = new ArrayList<String>();
-    StringTokenizer tknizr = new StringTokenizer( param, ",", false );
-    while( tknizr.hasMoreTokens() ) {
-      String token = tknizr.nextToken();
-      result.add( token );
-    }
-    return result.toArray( new String[ result.size() ] );
-  }
-
-  private static void ceateCustomInstaller( final String os,
-                                            final File inFile,
-                                            final String ius[],
-                                            final File outFile )
-    throws IOException // FIXME
-  {
-    InputStream in = null;
-    OutputStream out = null;
-    try {
-      out = new FileOutputStream( outFile );
-      in = new FileInputStream( inFile );
-      String config = getInstallerConfiguration( ius );
-      byte[] bytes = config.getBytes( ENCODING );
-      if( inFile.getName().endsWith( ".zip" ) ) {
-        ZipInputStream zis = null;
-        ZipOutputStream zos = null;
-        try {
-          zis = new ZipInputStream( in );
-          zos = new ZipOutputStream( out );
-          ZipEntry entry = zis.getNextEntry();
-          while( entry != null ) {
-            zos.putNextEntry( new ZipEntry( entry.getName() ) );
-            copy( readSubStream( zis ), zos );
-            entry = zis.getNextEntry();
-          }
-          zos.putNextEntry( new ZipEntry( "eclipse/installer.properties" ) );
-          ByteArrayInputStream confStream = new ByteArrayInputStream( bytes );
-          copy( confStream, zos );
-          zos.closeEntry();
-        } catch( IOException e ) {
-          // TODO
-          e.printStackTrace();
-        } finally {
-          tryClose( zis );
-          tryClose( zos );
-        }
-      } else if( inFile.getName().endsWith( ".tar.gz" ) ) {
-        GZIPInputStream gzis = null;
-        TarInputStream tis = null;
-        GZIPOutputStream gzos = null;
-        TarOutputStream tos = null;
-        try {
-          gzis = new GZIPInputStream( in );
-          tis = new TarInputStream( gzis );
-          gzos = new GZIPOutputStream( out );
-          tos = new TarOutputStream( gzos );
-          tos.setLongFileMode( TarOutputStream.LONGFILE_GNU );
-          TarEntry entry = tis.getNextEntry();
-          while( entry != null ) {
-            tos.putNextEntry( entry );
-            copy( readSubStream( tis ), tos );
-            tos.closeEntry();
-            entry = tis.getNextEntry();
-          }
-          String entryName = "eclipse/installer.properties";
-          if( os == "macosx" ) {
-            entryName = "eclipse/p2installer.app/Contents/MacOS/installer.properties";
-          }
-          TarEntry tarEntry = new TarEntry( entryName );
-          ByteArrayInputStream confStream = new ByteArrayInputStream( bytes );
-          tarEntry.setSize( bytes.length );
-          tos.putNextEntry( tarEntry );
-          copy( confStream, tos );
-          tos.closeEntry();
-        } catch( IOException e ) {
-          // TODO
-          e.printStackTrace();
-        } finally {
-          tryClose( tis );
-          tryClose( gzis );
-          tryClose( tos );
-          tryClose( gzos );
-        }
-      }
-    } catch( IOException ioe ) {
-      ioe.printStackTrace();
-    } finally {
-      tryClose( in );
-      tryClose( out );
-    }
-  }
-
-  private static String getInstallerConfiguration( final String ius[] )
-    throws IOException // FIXME
-  {
-    String result = "";
-    File downloadDir = Activator.getDefault()
-      .getConfiguration()
-      .getDownloadsDirectory();
-    IPath templateDirPath = new Path( new File( downloadDir,
-                                                INSTALLER_TEMPLATE_PATH ).getAbsolutePath() );
-    File inFile = templateDirPath.append( "installer.properties" ).toFile();
-    InputStream in = null;
-    try {
-      in = new FileInputStream( inFile );
-      ByteArrayOutputStream bufferStream = new ByteArrayOutputStream();
-      copy( in, bufferStream );
-      result = customize( bufferStream.toString( ENCODING ), ius );
-    } catch( IOException ioe ) {
-      ioe.printStackTrace();
-    } finally {
-      tryClose( in );
-    }
-    return result;
-  }
-
-  private static String customize( final String input, final String[] ius ) {
-    String result = input;
-    result = result.replaceAll( "\\$\\{roots\\}",
-                                StringUtil.toCommaList( ius, false ) );
-    result = result.replaceAll( "\\$\\{profileName\\}", "ProfileNameHere" ); // FIXME
-                                                                             // :
-                                                                             // (
-                                                                             // jb
-                                                                             // )
-                                                                             // get
-                                                                             // this
-                                                                             // from
-                                                                             // initial
-                                                                             // selection
-                                                                             // on
-                                                                             // eclispe
-                                                                             // .
-                                                                             // org
-    return result;
-  }
-
-  private static File findRawInstallerFile( final IPath path, final String os )
-  {
-    File result = null;
-    File dir = path.toFile();
-    File[] files = dir.listFiles();
-    for( File found : files ) {
-      if( found.getName().indexOf( os ) > -1 ) {
-        result = found;
-      }
-    }
-    return result;
-  }
-
-  private static void tryClose( final InputStream stream ) {
-    if( stream != null ) {
-      try {
-        stream.close();
-      } catch( IOException e ) {
-        e.printStackTrace();
-        // TODO Activator.log( e );
-      }
-    }
-  }
-
-  private static void tryClose( final OutputStream stream ) {
-    if( stream != null ) {
-      try {
-        stream.close();
-      } catch( IOException e ) {
-        e.printStackTrace();
-        // TODO Activator.log( e );
-      }
-    }
-  }
-
-  private static void copy( final InputStream in, final OutputStream out )
-    throws IOException
-  {
-    byte[] data = new byte[ BUFFER ];
-    int currentByte = in.read( data, 0, BUFFER );
-    while( currentByte != -1 ) {
-      out.write( data, 0, currentByte );
-      currentByte = in.read( data, 0, BUFFER );
-    }
-  }
-
-  private static InputStream readSubStream( final InputStream is )
-    throws IOException
-  {
-    ByteArrayOutputStream baos = new ByteArrayOutputStream();
-    copy( is, baos );
-    return new ByteArrayInputStream( baos.toByteArray() );
-  }
+/*******************************************************************************

+ * Copyright (c) 2008 Innoopract Informationssysteme GmbH.

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * which accompanies this distribution, and is available at

+ * http://www.eclipse.org/legal/epl-v10.html

+ *

+ * Contributors:

+ *     Innoopract Informationssysteme GmbH - initial API and implementation

+ ******************************************************************************/

+package org.eclipse.epp.wizard.installerbuilder;

+

+import java.io.ByteArrayInputStream;

+import java.io.ByteArrayOutputStream;

+import java.io.File;

+import java.io.FileInputStream;

+import java.io.FileOutputStream;

+import java.io.IOException;

+import java.io.InputStream;

+import java.io.OutputStream;

+import java.security.NoSuchAlgorithmException;

+import java.util.ArrayList;

+import java.util.List;

+import java.util.StringTokenizer;

+import java.util.zip.GZIPInputStream;

+import java.util.zip.GZIPOutputStream;

+import java.util.zip.ZipEntry;

+import java.util.zip.ZipInputStream;

+import java.util.zip.ZipOutputStream;

+

+import javax.servlet.ServletException;

+import javax.servlet.http.HttpServlet;

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.apache.tools.tar.TarEntry;

+import org.apache.tools.tar.TarInputStream;

+import org.apache.tools.tar.TarOutputStream;

+import org.eclipse.core.runtime.IPath;

+import org.eclipse.core.runtime.Path;

+import org.eclipse.epp.wizard.util.OsUtil;

+import org.eclipse.epp.wizard.util.StringUtil;

+

+/**

+ * @author Jordi Boehme Lopez <jboehme@innoopract.com>

+ */

+public class BuildInstaller extends HttpServlet {

+

+  public static final String OUTPUT_PATH = "htdocs";

+  private static final String INSTALLER_TEMPLATE_PATH = "templates/installer";

+  private static final String ENCODING = "UTF-8";

+  private static final int BUFFER = 512;

+  private static final long serialVersionUID = 1L;

+

+  @Override

+  protected void doGet( final HttpServletRequest req,

+                        final HttpServletResponse resp )

+    throws ServletException, IOException

+  {

+    String os = req.getParameter( "os" );

+    String iuParam = req.getParameter( "ius" );

+    String filename = req.getParameter( "filename" );

+    execute( os, iuParam, filename );

+  }

+

+  public static void execute( final String os,

+                              final String iuParam,

+                              final String filename ) throws IOException

+  {

+    File downloadDir = Activator.getDefault()

+      .getConfiguration()

+      .getDownloadsDirectory();

+    IPath outDirPath = new Path( new File( downloadDir, OUTPUT_PATH ).getAbsolutePath() );

+    IPath rawInstallerDirPath = new Path( new File( downloadDir,

+                                                    INSTALLER_TEMPLATE_PATH ).getAbsolutePath() );

+    String[] ius = getIUs( iuParam );

+    File template = findRawInstallerFile( rawInstallerDirPath, os );

+    IPath outFilePath = outDirPath.append( filename );

+    ceateCustomInstaller( os, template, ius, outFilePath.toFile() );

+  }

+

+  public static String getFileName( final String os, final String[] ids ) {

+    String hash = ids.toString();

+    try {

+      hash = StringUtil.getHash( ids );

+    } catch( NoSuchAlgorithmException exc ) {

+      // should not happen! - but trace anyway

+      exc.printStackTrace();

+    }

+    return "eclipse-" + os + "-" + hash + "." + OsUtil.getArchiveExtension( os );

+  }

+

+  // ////////////////

+  // helping methods

+  // ////////////////

+  private static String[] getIUs( final String param ) {

+    List<String> result = new ArrayList<String>();

+    StringTokenizer tknizr = new StringTokenizer( param, ",", false );

+    while( tknizr.hasMoreTokens() ) {

+      String token = tknizr.nextToken();

+      result.add( token );

+    }

+    return result.toArray( new String[ result.size() ] );

+  }

+

+  private static void ceateCustomInstaller( final String os,

+                                            final File inFile,

+                                            final String ius[],

+                                            final File outFile )

+    throws IOException // FIXME

+  {

+    InputStream in = null;

+    OutputStream out = null;

+    try {

+      out = new FileOutputStream( outFile );

+      in = new FileInputStream( inFile );

+      String config = getInstallerConfiguration( ius );

+      byte[] bytes = config.getBytes( ENCODING );

+      if( inFile.getName().endsWith( ".zip" ) ) {

+        ZipInputStream zis = null;

+        ZipOutputStream zos = null;

+        try {

+          zis = new ZipInputStream( in );

+          zos = new ZipOutputStream( out );

+          ZipEntry entry = zis.getNextEntry();

+          while( entry != null ) {

+            zos.putNextEntry( new ZipEntry( entry.getName() ) );

+            copy( readSubStream( zis ), zos );

+            entry = zis.getNextEntry();

+          }

+          zos.putNextEntry( new ZipEntry( "eclipse/installer.properties" ) );

+          ByteArrayInputStream confStream = new ByteArrayInputStream( bytes );

+          copy( confStream, zos );

+          zos.closeEntry();

+        } catch( IOException e ) {

+          // TODO

+          e.printStackTrace();

+        } finally {

+          tryClose( zis );

+          tryClose( zos );

+        }

+      } else if( inFile.getName().endsWith( ".tar.gz" ) ) {

+        GZIPInputStream gzis = null;

+        TarInputStream tis = null;

+        GZIPOutputStream gzos = null;

+        TarOutputStream tos = null;

+        try {

+          gzis = new GZIPInputStream( in );

+          tis = new TarInputStream( gzis );

+          gzos = new GZIPOutputStream( out );

+          tos = new TarOutputStream( gzos );

+          tos.setLongFileMode( TarOutputStream.LONGFILE_GNU );

+          TarEntry entry = tis.getNextEntry();

+          while( entry != null ) {

+            tos.putNextEntry( entry );

+            copy( readSubStream( tis ), tos );

+            tos.closeEntry();

+            entry = tis.getNextEntry();

+          }

+          String entryName = "eclipse/installer.properties";

+          if( os == "macosx" ) {

+            entryName = "eclipse/p2installer.app/Contents/MacOS/installer.properties";

+          }

+          TarEntry tarEntry = new TarEntry( entryName );

+          ByteArrayInputStream confStream = new ByteArrayInputStream( bytes );

+          tarEntry.setSize( bytes.length );

+          tos.putNextEntry( tarEntry );

+          copy( confStream, tos );

+          tos.closeEntry();

+        } catch( IOException e ) {

+          // TODO

+          e.printStackTrace();

+        } finally {

+          tryClose( tis );

+          tryClose( gzis );

+          tryClose( tos );

+          tryClose( gzos );

+        }

+      }

+    } catch( IOException ioe ) {

+      ioe.printStackTrace();

+    } finally {

+      tryClose( in );

+      tryClose( out );

+    }

+  }

+

+  private static String getInstallerConfiguration( final String ius[] )

+    throws IOException // FIXME

+  {

+    String result = "";

+    File downloadDir = Activator.getDefault()

+      .getConfiguration()

+      .getDownloadsDirectory();

+    IPath templateDirPath = new Path( new File( downloadDir,

+                                                INSTALLER_TEMPLATE_PATH ).getAbsolutePath() );

+    File inFile = templateDirPath.append( "installer.properties" ).toFile();

+    InputStream in = null;

+    try {

+      in = new FileInputStream( inFile );

+      ByteArrayOutputStream bufferStream = new ByteArrayOutputStream();

+      copy( in, bufferStream );

+      result = customize( bufferStream.toString( ENCODING ), ius );

+    } catch( IOException ioe ) {

+      ioe.printStackTrace();

+    } finally {

+      tryClose( in );

+    }

+    return result;

+  }

+

+  private static String customize( final String input, final String[] ius ) {

+    String result = input;

+    result = result.replaceAll( "\\$\\{roots\\}",

+                                StringUtil.toCommaList( ius, false ) );

+    result = result.replaceAll( "\\$\\{profileName\\}", "ProfileNameHere" ); // FIXME

+                                                                             // :

+                                                                             // (

+                                                                             // jb

+                                                                             // )

+                                                                             // get

+                                                                             // this

+                                                                             // from

+                                                                             // initial

+                                                                             // selection

+                                                                             // on

+                                                                             // eclispe

+                                                                             // .

+                                                                             // org

+    return result;

+  }

+

+  private static File findRawInstallerFile( final IPath path, final String os )

+  {

+    File result = null;

+    File dir = path.toFile();

+    File[] files = dir.listFiles();

+    for( File found : files ) {

+      if( found.getName().indexOf( os ) > -1 ) {

+        result = found;

+      }

+    }

+    return result;

+  }

+

+  private static void tryClose( final InputStream stream ) {

+    if( stream != null ) {

+      try {

+        stream.close();

+      } catch( IOException e ) {

+        e.printStackTrace();

+        // TODO Activator.log( e );

+      }

+    }

+  }

+

+  private static void tryClose( final OutputStream stream ) {

+    if( stream != null ) {

+      try {

+        stream.close();

+      } catch( IOException e ) {

+        e.printStackTrace();

+        // TODO Activator.log( e );

+      }

+    }

+  }

+

+  private static void copy( final InputStream in, final OutputStream out )

+    throws IOException

+  {

+    byte[] data = new byte[ BUFFER ];

+    int currentByte = in.read( data, 0, BUFFER );

+    while( currentByte != -1 ) {

+      out.write( data, 0, currentByte );

+      currentByte = in.read( data, 0, BUFFER );

+    }

+  }

+

+  private static InputStream readSubStream( final InputStream is )

+    throws IOException

+  {

+    ByteArrayOutputStream baos = new ByteArrayOutputStream();

+    copy( is, baos );

+    return new ByteArrayInputStream( baos.toByteArray() );

+  }

 }
\ No newline at end of file
diff --git a/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/installerbuilder/Configuration.java b/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/installerbuilder/Configuration.java
index 51031c1..8e584bc 100644
--- a/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/installerbuilder/Configuration.java
+++ b/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/installerbuilder/Configuration.java
@@ -1,79 +1,79 @@
-/*******************************************************************************
- * Copyright (c) 2008 Innoopract Informationssysteme GmbH.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Innoopract Informationssysteme GmbH - initial API and implementation
- ******************************************************************************/
-package org.eclipse.epp.wizard.installerbuilder;
-
-import java.io.File;
-import java.util.Properties;
-
-import org.apache.log4j.Logger;
-
-public class Configuration {
-
-  static Logger logger = Logger.getLogger( Configuration.class );
-  final static String DOWNLOADS = "downloads";
-  final static String TMPDIR = "tmpdir";
-  final static String INSTALLER_CACHE_SIZE = "installer.cache.size";
-  final static String INSTALLER_CACHE_SIZE_DEFAULT = "100";
-  protected int installerCacheSize;
-
-  public int getInstallerCacheSize() {
-    return installerCacheSize;
-  }
-  protected File downloadsDirectory;
-  protected File tempDirectory;
-
-  public File getTempDirectory() {
-    return tempDirectory;
-  }
-  private Properties properties;
-
-  public Configuration( Properties properties ) {
-    this.properties = properties;
-    downloadsDirectory = createDirectoryObject( DOWNLOADS );
-    tempDirectory = createDirectoryObject( TMPDIR );
-    installerCacheSize = Integer.parseInt( properties.getProperty( INSTALLER_CACHE_SIZE,
-                                                                   INSTALLER_CACHE_SIZE_DEFAULT ) );
-    if( logger.isInfoEnabled() ) {
-      StringBuilder sb = new StringBuilder();
-      sb.append( "EPP Wizard Installer builder configuration:" );
-      sb.append( "\n\t downloadsDirectory: "
-                 + downloadsDirectory.getAbsolutePath() );
-      sb.append( "\n\t tempDirectory:      " + tempDirectory.getAbsolutePath() );
-      sb.append( "\n\t installerCacheSize: " + installerCacheSize );
-      logger.info( sb );
-    }
-  }
-
-  private File createDirectoryObject( String key ) {
-    String value = properties.getProperty( key );
-    if( value == null ) {
-      throw new RuntimeException( "Configuration value for '"
-                                  + key
-                                  + "' not defined in configuration properties" );
-    }
-    File file = new File( value );
-    if( !file.canRead() ) {
-      throw new RuntimeException( "Cannot read from file '"
-                                  + file.getAbsolutePath()
-                                  + "'" );
-    }
-    if( !file.isDirectory() ) {
-      throw new RuntimeException( "'"
-                                  + file.getAbsolutePath()
-                                  + "' is not a directory" );
-    }
-    return file;
-  }
-
-  public File getDownloadsDirectory() {
-    return downloadsDirectory;
-  }
-}
+/*******************************************************************************

+ * Copyright (c) 2008 Innoopract Informationssysteme GmbH.

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * which accompanies this distribution, and is available at

+ * http://www.eclipse.org/legal/epl-v10.html

+ *

+ * Contributors:

+ *     Innoopract Informationssysteme GmbH - initial API and implementation

+ ******************************************************************************/

+package org.eclipse.epp.wizard.installerbuilder;

+

+import java.io.File;

+import java.util.Properties;

+

+import org.apache.log4j.Logger;

+

+public class Configuration {

+

+  static Logger logger = Logger.getLogger( Configuration.class );

+  final static String DOWNLOADS = "downloads";

+  final static String TMPDIR = "tmpdir";

+  final static String INSTALLER_CACHE_SIZE = "installer.cache.size";

+  final static String INSTALLER_CACHE_SIZE_DEFAULT = "100";

+  protected int installerCacheSize;

+

+  public int getInstallerCacheSize() {

+    return installerCacheSize;

+  }

+  protected File downloadsDirectory;

+  protected File tempDirectory;

+

+  public File getTempDirectory() {

+    return tempDirectory;

+  }

+  private Properties properties;

+

+  public Configuration( Properties properties ) {

+    this.properties = properties;

+    downloadsDirectory = createDirectoryObject( DOWNLOADS );

+    tempDirectory = createDirectoryObject( TMPDIR );

+    installerCacheSize = Integer.parseInt( properties.getProperty( INSTALLER_CACHE_SIZE,

+                                                                   INSTALLER_CACHE_SIZE_DEFAULT ) );

+    if( logger.isInfoEnabled() ) {

+      StringBuilder sb = new StringBuilder();

+      sb.append( "EPP Wizard Installer builder configuration:" );

+      sb.append( "\n\t downloadsDirectory: "

+                 + downloadsDirectory.getAbsolutePath() );

+      sb.append( "\n\t tempDirectory:      " + tempDirectory.getAbsolutePath() );

+      sb.append( "\n\t installerCacheSize: " + installerCacheSize );

+      logger.info( sb );

+    }

+  }

+

+  private File createDirectoryObject( String key ) {

+    String value = properties.getProperty( key );

+    if( value == null ) {

+      throw new RuntimeException( "Configuration value for '"

+                                  + key

+                                  + "' not defined in configuration properties" );

+    }

+    File file = new File( value );

+    if( !file.canRead() ) {

+      throw new RuntimeException( "Cannot read from file '"

+                                  + file.getAbsolutePath()

+                                  + "'" );

+    }

+    if( !file.isDirectory() ) {

+      throw new RuntimeException( "'"

+                                  + file.getAbsolutePath()

+                                  + "' is not a directory" );

+    }

+    return file;

+  }

+

+  public File getDownloadsDirectory() {

+    return downloadsDirectory;

+  }

+}

diff --git a/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/installerbuilder/Download.java b/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/installerbuilder/Download.java
index 8a15d49..e68182d 100644
--- a/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/installerbuilder/Download.java
+++ b/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/installerbuilder/Download.java
@@ -1,233 +1,223 @@
-/*******************************************************************************
- * Copyright (c) 2008 Innoopract Informationssysteme GmbH.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Innoopract Informationssysteme GmbH - initial API and implementation
- ******************************************************************************/
-package org.eclipse.epp.wizard.installerbuilder;
-
-import java.io.BufferedOutputStream;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.Map;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.Path;
-
-/**
- * @author Jordi Boehme Lopez <jboehme@innoopract.com>
- */
-public class Download extends HttpServlet {
-
-  @Override
-  protected void doPost( HttpServletRequest req, HttpServletResponse resp )
-    throws ServletException, IOException
-  {
-    doGet( req, resp );
-  }
-  private static final String ENCODING = "UTF-8";
-  private static final long serialVersionUID = 1L;
-  private static final int BUFFER = 1024;
-
-  @SuppressWarnings("unchecked")
-  @Override
-  protected void doGet( final HttpServletRequest req,
-                        final HttpServletResponse resp )
-    throws ServletException, IOException
-  {
-    resp.setHeader( "Content-Disposition", "attachment; filename="
-                                           + "out.txt"
-                                           + ";" );
-    PrintStream printStream = new PrintStream( new BufferedOutputStream( resp.getOutputStream() ) );
-    printStream.print( "foo.bar" );
-    printStream.close();
-    if( true )
-      return;
-    Map<Object, Object> map = req.getParameterMap();
-    String requestedPath = req.getPathInfo();
-    String reqURL = req.getRequestURL().toString();
-    String codebase = reqURL.substring( 0, reqURL.length()
-                                           - requestedPath.length() );
-    IPath path = new Path( "" );
-    if( requestedPath != null ) {
-      path = new Path( requestedPath );
-    }
-    if( !trySendGeneratedFile( resp, path, codebase ) ) {
-      if( !isTemplateFile( resp, path, codebase ) ) {
-        send404( resp );
-      }
-    }
-    resp.flushBuffer();
-  }
-
-  // ////////////////
-  // helping methods
-  // ////////////////
-  private void send404( final HttpServletResponse resp ) {
-    try {
-      resp.sendError( 404 );
-    } catch( IOException exc ) {
-      // TODO Auto-generated catch block
-      exc.printStackTrace();
-    }
-    resp.addHeader( "Status", "404 Not Found" );
-  }
-
-  private boolean isTemplateFile( final HttpServletResponse resp,
-                                  final IPath path,
-                                  final String codebase )
-  {
-    boolean result = false;
-    File downloadDir = Activator.getDefault()
-      .getConfiguration()
-      .getDownloadsDirectory();
-    File jnlpDir = new File( downloadDir, "templates/jnlp" );
-    File item = new File( jnlpDir, path.toString() );
-    URL entry = null;
-    try {
-      entry = item.toURI().toURL();
-    } catch( MalformedURLException exc1 ) {
-      exc1.printStackTrace();
-    }
-    if( entry != null ) {
-      try {
-        sendFile( resp, entry, codebase );
-        result = true;
-      } catch( IOException exc ) {
-        // thats ok, will try to satisfy the request later
-        exc.printStackTrace();
-      }
-    }
-    return result;
-  }
-
-  private void sendFile( final HttpServletResponse resp,
-                         final File archiveFile,
-                         final String codebase )
-    throws FileNotFoundException, IOException
-  {
-    String ext = new Path( archiveFile.toString() ).getFileExtension();
-    sendFile( resp, new FileInputStream( archiveFile ), codebase, ext );
-  }
-
-  private void sendFile( final HttpServletResponse resp,
-                         final URL entry,
-                         final String codebase ) throws IOException
-  {
-    String ext = new Path( entry.getFile() ).getFileExtension();
-    ByteArrayOutputStream bufferStream = new ByteArrayOutputStream();
-    copy( entry.openStream(), bufferStream );
-    sendFile( resp,
-              new ByteArrayInputStream( bufferStream.toByteArray() ),
-              codebase,
-              ext );
-  }
-
-  private void sendFile( final HttpServletResponse resp,
-                         final InputStream is,
-                         final String codebase,
-                         final String ext ) throws IOException
-  {
-    InputStream inputStream = is;
-    if( ext.equals( "jnlp" ) ) {
-      String result = "";
-      try {
-        ByteArrayOutputStream bufferStream = new ByteArrayOutputStream();
-        copy( is, bufferStream );
-        result = bufferStream.toString( ENCODING )
-          .replaceAll( "\\$\\{codebase\\}", codebase );
-      } catch( IOException ioe ) {
-        ioe.printStackTrace();
-      } finally {
-        tryClose( is );
-      }
-      inputStream = new ByteArrayInputStream( result.getBytes( ENCODING ) );
-    }
-    resp.addHeader( "Content-Type", getContentType( ext ) );
-    resp.addHeader( "Content-Length", String.valueOf( inputStream.available() ) );
-    resp.flushBuffer();
-    OutputStream os = resp.getOutputStream(); // TODO: (jb) errorhandling
-    copy( inputStream, os );
-    os.flush();
-  }
-
-  private boolean trySendGeneratedFile( final HttpServletResponse resp,
-                                        final IPath path,
-                                        final String codebase )
-  {
-    boolean result = false;
-    File downloadDir = Activator.getDefault()
-      .getConfiguration()
-      .getDownloadsDirectory();
-    Path outPath = new Path( new File( downloadDir, BuildInstaller.OUTPUT_PATH ).getAbsolutePath() );
-    File archiveFile = outPath.append( path.lastSegment() ).toFile();
-    if( archiveFile.isFile() ) {
-      try {
-        sendFile( resp, archiveFile, codebase );
-        result = true;
-      } catch( FileNotFoundException exc ) {
-        // thats ok, will try to satisfy the request later
-      } catch( IOException exc ) {
-        // thats ok, will try to satisfy the request later
-        exc.printStackTrace();
-      }
-    }
-    return result;
-  }
-
-  private String getContentType( final String fileExt ) {
-    String result = "application/octet-stream";
-    if( fileExt.equalsIgnoreCase( "zip" ) ) {
-      result = "application/x-zip";
-    } else if( fileExt.equalsIgnoreCase( "gz" ) ) {
-      result = "application/x-gzip";
-    } else if( fileExt.equalsIgnoreCase( "tar" ) ) {
-      result = "application/x-tar";
-    } else if( fileExt.equalsIgnoreCase( "jnlp" ) ) {
-      result = "application/x-java-jnlp-file";
-    } else if( fileExt.equalsIgnoreCase( "jar" ) ) {
-      result = "application/java-archive";
-    }
-    return result;
-  }
-
-  private static void copy( final InputStream in, final OutputStream out )
-    throws IOException
-  {
-    byte[] data = new byte[ BUFFER ];
-    int currentByte = in.read( data, 0, BUFFER );
-    while( currentByte != -1 ) {
-      out.write( data, 0, currentByte );
-      currentByte = in.read( data, 0, BUFFER );
-    }
-  }
-
-  private static void tryClose( final InputStream stream ) {
-    if( stream != null ) {
-      try {
-        stream.close();
-      } catch( IOException e ) {
-        e.printStackTrace();
-        // TODO Activator.log( e );
-      }
-    }
-  }
-}
+/*******************************************************************************

+ * Copyright (c) 2008 Innoopract Informationssysteme GmbH.

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * which accompanies this distribution, and is available at

+ * http://www.eclipse.org/legal/epl-v10.html

+ *

+ * Contributors:

+ *     Innoopract Informationssysteme GmbH - initial API and implementation

+ ******************************************************************************/

+package org.eclipse.epp.wizard.installerbuilder;

+

+import java.io.ByteArrayInputStream;

+import java.io.ByteArrayOutputStream;

+import java.io.File;

+import java.io.FileInputStream;

+import java.io.FileNotFoundException;

+import java.io.IOException;

+import java.io.InputStream;

+import java.io.OutputStream;

+import java.net.MalformedURLException;

+import java.net.URL;

+import java.util.Map;

+

+import javax.servlet.ServletException;

+import javax.servlet.http.HttpServlet;

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.eclipse.core.runtime.IPath;

+import org.eclipse.core.runtime.Path;

+

+/**

+ * @author Jordi Boehme Lopez <jboehme@innoopract.com>

+ */

+public class Download extends HttpServlet {

+

+  @Override

+  protected void doPost( HttpServletRequest req, HttpServletResponse resp )

+    throws ServletException, IOException

+  {

+    doGet( req, resp );

+  }

+  private static final String ENCODING = "UTF-8";

+  private static final long serialVersionUID = 1L;

+  private static final int BUFFER = 1024;

+

+  @SuppressWarnings("unchecked")

+  @Override

+  protected void doGet( final HttpServletRequest req,

+                        final HttpServletResponse resp )

+    throws ServletException, IOException

+  {

+    Map<Object, Object> map = req.getParameterMap();

+    String requestedPath = req.getPathInfo();

+    String reqURL = req.getRequestURL().toString();

+    String codebase = reqURL.substring( 0, reqURL.length()

+                                           - requestedPath.length() );

+    IPath path = new Path( "" );

+    if( requestedPath != null ) {

+      path = new Path( requestedPath );

+    }

+    if( !trySendGeneratedFile( resp, path, codebase ) ) {

+      if( !isTemplateFile( resp, path, codebase ) ) {

+        send404( resp );

+      }

+    }

+    resp.flushBuffer();

+  }

+

+  // ////////////////

+  // helping methods

+  // ////////////////

+  private void send404( final HttpServletResponse resp ) {

+    try {

+      resp.sendError( 404 );

+    } catch( IOException exc ) {

+      // TODO Auto-generated catch block

+      exc.printStackTrace();

+    }

+    resp.addHeader( "Status", "404 Not Found" );

+  }

+

+  private boolean isTemplateFile( final HttpServletResponse resp,

+                                  final IPath path,

+                                  final String codebase )

+  {

+    boolean result = false;

+    File downloadDir = Activator.getDefault()

+      .getConfiguration()

+      .getDownloadsDirectory();

+    File jnlpDir = new File( downloadDir, "templates/jnlp" );

+    File item = new File( jnlpDir, path.toString() );

+    URL entry = null;

+    try {

+      entry = item.toURI().toURL();

+    } catch( MalformedURLException exc1 ) {

+      exc1.printStackTrace();

+    }

+    if( entry != null ) {

+      try {

+        sendFile( resp, entry, codebase );

+        result = true;

+      } catch( IOException exc ) {

+        // thats ok, will try to satisfy the request later

+        exc.printStackTrace();

+      }

+    }

+    return result;

+  }

+

+  private void sendFile( final HttpServletResponse resp,

+                         final File archiveFile,

+                         final String codebase )

+    throws FileNotFoundException, IOException

+  {

+    String ext = new Path( archiveFile.toString() ).getFileExtension();

+    sendFile( resp, new FileInputStream( archiveFile ), codebase, ext );

+  }

+

+  private void sendFile( final HttpServletResponse resp,

+                         final URL entry,

+                         final String codebase ) throws IOException

+  {

+    String ext = new Path( entry.getFile() ).getFileExtension();

+    ByteArrayOutputStream bufferStream = new ByteArrayOutputStream();

+    copy( entry.openStream(), bufferStream );

+    sendFile( resp,

+              new ByteArrayInputStream( bufferStream.toByteArray() ),

+              codebase,

+              ext );

+  }

+

+  private void sendFile( final HttpServletResponse resp,

+                         final InputStream is,

+                         final String codebase,

+                         final String ext ) throws IOException

+  {

+    InputStream inputStream = is;

+    if( ext.equals( "jnlp" ) ) {

+      String result = "";

+      try {

+        ByteArrayOutputStream bufferStream = new ByteArrayOutputStream();

+        copy( is, bufferStream );

+        result = bufferStream.toString( ENCODING )

+          .replaceAll( "\\$\\{codebase\\}", codebase );

+      } catch( IOException ioe ) {

+        ioe.printStackTrace();

+      } finally {

+        tryClose( is );

+      }

+      inputStream = new ByteArrayInputStream( result.getBytes( ENCODING ) );

+    }

+    resp.addHeader( "Content-Type", getContentType( ext ) );

+    resp.addHeader( "Content-Length", String.valueOf( inputStream.available() ) );

+    resp.flushBuffer();

+    OutputStream os = resp.getOutputStream(); // TODO: (jb) errorhandling

+    copy( inputStream, os );

+    os.flush();

+  }

+

+  private boolean trySendGeneratedFile( final HttpServletResponse resp,

+                                        final IPath path,

+                                        final String codebase )

+  {

+    boolean result = false;

+    File downloadDir = Activator.getDefault()

+      .getConfiguration()

+      .getDownloadsDirectory();

+    Path outPath = new Path( new File( downloadDir, BuildInstaller.OUTPUT_PATH ).getAbsolutePath() );

+    File archiveFile = outPath.append( path.lastSegment() ).toFile();

+    if( archiveFile.isFile() ) {

+      try {

+        sendFile( resp, archiveFile, codebase );

+        result = true;

+      } catch( FileNotFoundException exc ) {

+        // thats ok, will try to satisfy the request later

+      } catch( IOException exc ) {

+        // thats ok, will try to satisfy the request later

+        exc.printStackTrace();

+      }

+    }

+    return result;

+  }

+

+  private String getContentType( final String fileExt ) {

+    String result = "application/octet-stream";

+    if( fileExt.equalsIgnoreCase( "zip" ) ) {

+      result = "application/x-zip";

+    } else if( fileExt.equalsIgnoreCase( "gz" ) ) {

+      result = "application/x-gzip";

+    } else if( fileExt.equalsIgnoreCase( "tar" ) ) {

+      result = "application/x-tar";

+    } else if( fileExt.equalsIgnoreCase( "jnlp" ) ) {

+      result = "application/x-java-jnlp-file";

+    } else if( fileExt.equalsIgnoreCase( "jar" ) ) {

+      result = "application/java-archive";

+    }

+    return result;

+  }

+

+  private static void copy( final InputStream in, final OutputStream out )

+    throws IOException

+  {

+    byte[] data = new byte[ BUFFER ];

+    int currentByte = in.read( data, 0, BUFFER );

+    while( currentByte != -1 ) {

+      out.write( data, 0, currentByte );

+      currentByte = in.read( data, 0, BUFFER );

+    }

+  }

+

+  private static void tryClose( final InputStream stream ) {

+    if( stream != null ) {

+      try {

+        stream.close();

+      } catch( IOException e ) {

+        e.printStackTrace();

+        // TODO Activator.log( e );

+      }

+    }

+  }

+}

diff --git a/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/installerbuilder/Installer.java b/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/installerbuilder/Installer.java
index 1654d4e..4a8a92c 100644
--- a/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/installerbuilder/Installer.java
+++ b/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/installerbuilder/Installer.java
@@ -1,151 +1,151 @@
-/*******************************************************************************
- * Copyright (c) 2008 Innoopract Informationssysteme GmbH.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Innoopract Informationssysteme GmbH - initial API and implementation
- ******************************************************************************/
-package org.eclipse.epp.wizard.installerbuilder;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Properties;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.log4j.Logger;
-import org.eclipse.epp.wizard.util.OsUtil;
-
-/**
- * @author Jordi Boehme Lopez <jboehme@innoopract.com>
- */
-public class Installer extends HttpServlet {
-
-  static Logger logger = Logger.getLogger( Installer.class );
-  private static final char FILE_EXTENSION_SEPARATOR = '.';
-  private static final long serialVersionUID = 1L;
-  private static final int BUFFER = 1024;
-  private HttpServletRequest request;
-  private static final String[] P2_PROPERTIES = {
-    "eclipse.p2.roots", "eclipse.p2.metadata", "eclipse.p2.artifacts"
-  };
-
-  @Override
-  protected void doPost( HttpServletRequest req, HttpServletResponse resp )
-    throws ServletException, IOException
-  {
-    doGet( req, resp );
-  }
-
-  @Override
-  protected void doGet( final HttpServletRequest req,
-                        final HttpServletResponse resp )
-    throws ServletException, IOException
-  {
-    try {
-      String os = req.getParameter( "os" );
-      request = req;
-      Properties p2Properties = extractP2Properties();
-      String extension = OsUtil.getArchiveExtension( os );
-      InstallerCache.Entry installerFile = getCustomInstaller( os, p2Properties );
-      try {
-        sendFile( resp,
-                  new FileInputStream( installerFile.getFile() ),
-                  "eclipse-wizard-installer",
-                  extension );
-      } finally {
-        installerFile.release();
-      }
-    } catch( IOException ex ) {
-      // This happens usually when the download is aborted by the client
-      logger.warn( "IO exception handling installer request", ex );
-      throw new RuntimeException( "IO error handling installer request", ex );
-    } catch( Throwable t ) {
-      logger.error( "Internal error handling installer request", t );
-      throw new RuntimeException( "Internal error handling installer request",
-                                  t );
-    }
-  }
-
-  private Properties extractP2Properties() {
-    Properties properties = new Properties();
-    for( String key : P2_PROPERTIES ) {
-      String value = request.getParameter( key );
-      properties.setProperty( key, value );
-    }
-    return properties;
-  }
-
-  public static String getExtension( File file ) {
-    String extension = null;
-    String filename = file.getName();
-    int index = filename.lastIndexOf( FILE_EXTENSION_SEPARATOR );
-    if( index > 0 && index < filename.length() - 1 ) {
-      extension = filename.substring( index + 1 ).toLowerCase();
-    }
-    return extension;
-  }
-
-  private void sendFile( final HttpServletResponse resp,
-                         final InputStream inputStream,
-                         final String filename,
-                         final String ext ) throws IOException
-  {
-    resp.addHeader( "Content-Type", getContentType( ext ) );
-    resp.addHeader( "Content-Length", String.valueOf( inputStream.available() ) );
-    resp.setHeader( "Content-Disposition", "attachment; filename="
-                                           + filename
-                                           + "."
-                                           + ext
-                                           + ";" );
-    resp.flushBuffer();
-    OutputStream os = resp.getOutputStream(); // TODO: (jb) errorhandling
-    copy( inputStream, os );
-    os.flush();
-    inputStream.close();
-  }
-
-  private String getContentType( final String fileExt ) {
-    String result = "application/octet-stream";
-    if( fileExt.equalsIgnoreCase( "zip" ) ) {
-      result = "application/x-zip";
-    } else if( fileExt.equalsIgnoreCase( "gz" ) ) {
-      result = "application/x-gzip";
-    } else if( fileExt.equalsIgnoreCase( "tar" ) ) {
-      result = "application/x-tar";
-    } else if( fileExt.equalsIgnoreCase( "jnlp" ) ) {
-      result = "application/x-java-jnlp-file";
-    } else if( fileExt.equalsIgnoreCase( "jar" ) ) {
-      result = "application/java-archive";
-    }
-    return result;
-  }
-
-  private InstallerCache.Entry getCustomInstaller( final String os,
-                                                   Properties properties )
-  {
-    InstallerCache.Key key = new InstallerCache.Key( os, properties );
-    logger.debug( "Request for " + key );
-    return Activator.getDefault().getInstallerCache().getInstaller( key );
-  }
-
-  private static void copy( final InputStream in, final OutputStream out )
-    throws IOException
-  {
-    byte[] data = new byte[ BUFFER ];
-    int currentByte = in.read( data, 0, BUFFER );
-    while( currentByte != -1 ) {
-      out.write( data, 0, currentByte );
-      currentByte = in.read( data, 0, BUFFER );
-    }
-  }
-}
+/*******************************************************************************

+ * Copyright (c) 2008 Innoopract Informationssysteme GmbH.

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * which accompanies this distribution, and is available at

+ * http://www.eclipse.org/legal/epl-v10.html

+ *

+ * Contributors:

+ *     Innoopract Informationssysteme GmbH - initial API and implementation

+ ******************************************************************************/

+package org.eclipse.epp.wizard.installerbuilder;

+

+import java.io.File;

+import java.io.FileInputStream;

+import java.io.IOException;

+import java.io.InputStream;

+import java.io.OutputStream;

+import java.util.Properties;

+

+import javax.servlet.ServletException;

+import javax.servlet.http.HttpServlet;

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.apache.log4j.Logger;

+import org.eclipse.epp.wizard.util.OsUtil;

+

+/**

+ * @author Jordi Boehme Lopez <jboehme@innoopract.com>

+ */

+public class Installer extends HttpServlet {

+

+  static Logger logger = Logger.getLogger( Installer.class );

+  private static final char FILE_EXTENSION_SEPARATOR = '.';

+  private static final long serialVersionUID = 1L;

+  private static final int BUFFER = 1024;

+  private HttpServletRequest request;

+  private static final String[] P2_PROPERTIES = {

+    "eclipse.p2.roots", "eclipse.p2.metadata", "eclipse.p2.artifacts"

+  };

+

+  @Override

+  protected void doPost( HttpServletRequest req, HttpServletResponse resp )

+    throws ServletException, IOException

+  {

+    doGet( req, resp );

+  }

+

+  @Override

+  protected void doGet( final HttpServletRequest req,

+                        final HttpServletResponse resp )

+    throws ServletException, IOException

+  {

+    try {

+      String os = req.getParameter( "os" );

+      request = req;

+      Properties p2Properties = extractP2Properties();

+      String extension = OsUtil.getArchiveExtension( os );

+      InstallerCache.Entry installerFile = getCustomInstaller( os, p2Properties );

+      try {

+        sendFile( resp,

+                  new FileInputStream( installerFile.getFile() ),

+                  "eclipse-wizard-installer",

+                  extension );

+      } finally {

+        installerFile.release();

+      }

+    } catch( IOException ex ) {

+      // This happens usually when the download is aborted by the client

+      logger.warn( "IO exception handling installer request", ex );

+      throw new RuntimeException( "IO error handling installer request", ex );

+    } catch( Throwable t ) {

+      logger.error( "Internal error handling installer request", t );

+      throw new RuntimeException( "Internal error handling installer request",

+                                  t );

+    }

+  }

+

+  private Properties extractP2Properties() {

+    Properties properties = new Properties();

+    for( String key : P2_PROPERTIES ) {

+      String value = request.getParameter( key );

+      properties.setProperty( key, value );

+    }

+    return properties;

+  }

+

+  public static String getExtension( File file ) {

+    String extension = null;

+    String filename = file.getName();

+    int index = filename.lastIndexOf( FILE_EXTENSION_SEPARATOR );

+    if( index > 0 && index < filename.length() - 1 ) {

+      extension = filename.substring( index + 1 ).toLowerCase();

+    }

+    return extension;

+  }

+

+  private void sendFile( final HttpServletResponse resp,

+                         final InputStream inputStream,

+                         final String filename,

+                         final String ext ) throws IOException

+  {

+    resp.addHeader( "Content-Type", getContentType( ext ) );

+    resp.addHeader( "Content-Length", String.valueOf( inputStream.available() ) );

+    resp.setHeader( "Content-Disposition", "attachment; filename="

+                                           + filename

+                                           + "."

+                                           + ext

+                                           + ";" );

+    resp.flushBuffer();

+    OutputStream os = resp.getOutputStream(); // TODO: (jb) errorhandling

+    copy( inputStream, os );

+    os.flush();

+    inputStream.close();

+  }

+

+  private String getContentType( final String fileExt ) {

+    String result = "application/octet-stream";

+    if( fileExt.equalsIgnoreCase( "zip" ) ) {

+      result = "application/x-zip";

+    } else if( fileExt.equalsIgnoreCase( "gz" ) ) {

+      result = "application/x-gzip";

+    } else if( fileExt.equalsIgnoreCase( "tar" ) ) {

+      result = "application/x-tar";

+    } else if( fileExt.equalsIgnoreCase( "jnlp" ) ) {

+      result = "application/x-java-jnlp-file";

+    } else if( fileExt.equalsIgnoreCase( "jar" ) ) {

+      result = "application/java-archive";

+    }

+    return result;

+  }

+

+  private InstallerCache.Entry getCustomInstaller( final String os,

+                                                   Properties properties )

+  {

+    InstallerCache.Key key = new InstallerCache.Key( os, properties );

+    logger.debug( "Request for " + key );

+    return Activator.getDefault().getInstallerCache().getInstaller( key );

+  }

+

+  private static void copy( final InputStream in, final OutputStream out )

+    throws IOException

+  {

+    byte[] data = new byte[ BUFFER ];

+    int currentByte = in.read( data, 0, BUFFER );

+    while( currentByte != -1 ) {

+      out.write( data, 0, currentByte );

+      currentByte = in.read( data, 0, BUFFER );

+    }

+  }

+}

diff --git a/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/installerbuilder/InstallerCache.java b/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/installerbuilder/InstallerCache.java
index 382c776..4a36173 100644
--- a/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/installerbuilder/InstallerCache.java
+++ b/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/installerbuilder/InstallerCache.java
@@ -1,391 +1,391 @@
-/*******************************************************************************
- * Copyright (c) 2008 Innoopract Informationssysteme GmbH.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Innoopract Informationssysteme GmbH - initial API and implementation
- ******************************************************************************/
-package org.eclipse.epp.wizard.installerbuilder;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Properties;
-import java.util.zip.GZIPInputStream;
-import java.util.zip.GZIPOutputStream;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-import java.util.zip.ZipOutputStream;
-
-import org.apache.log4j.Logger;
-import org.apache.tools.tar.TarEntry;
-import org.apache.tools.tar.TarInputStream;
-import org.apache.tools.tar.TarOutputStream;
-
-/**
- * Cache for generated installers, uses the filesystem as a backing store
- * 
- * @author mwoelker
- */
-public class InstallerCache {
-
-  static Logger logger = Logger.getLogger( InstallerCache.class );
-  public static class Key {
-
-    @Override
-    public String toString() {
-      return "os=" + os + ";" + properties.toString();
-    }
-
-    public String getOs() {
-      return os;
-    }
-
-    public Properties getProperties() {
-      return properties;
-    }
-
-    @Override
-    public int hashCode() {
-      final int prime = 31;
-      int result = 1;
-      result = prime * result + ( ( os == null )
-                                                ? 0
-                                                : os.hashCode() );
-      result = prime
-               * result
-               + ( ( properties == null )
-                                         ? 0
-                                         : properties.hashCode() );
-      return result;
-    }
-
-    @Override
-    public boolean equals( Object obj ) {
-      if( this == obj )
-        return true;
-      if( obj == null )
-        return false;
-      if( getClass() != obj.getClass() )
-        return false;
-      Key other = ( Key )obj;
-      if( os == null ) {
-        if( other.os != null )
-          return false;
-      } else if( !os.equals( other.os ) )
-        return false;
-      if( properties == null ) {
-        if( other.properties != null )
-          return false;
-      } else if( !properties.equals( other.properties ) )
-        return false;
-      return true;
-    }
-    String os;
-
-    public Key( String os, Properties properties ) {
-      super();
-      this.os = os;
-      this.properties = properties;
-    }
-    Properties properties;
-  }
-  /**
-   * Entry in the cache, the actual installer file is created lazily, to reduce
-   * monitor contention on the cacheMap
-   * 
-   * @author mwoelker
-   */
-  public class Entry {
-
-    private Key key;
-
-    public Entry( Key key ) {
-      super();
-      this.key = key;
-    }
-    long acquisitionCount = 0;
-
-    public synchronized File getFile() {
-      if( file == null ) {
-        file = createInstaller( key );
-      }
-      return file;
-    }
-    File file;
-    boolean evicted = false;
-    boolean disposed = false;
-
-    public synchronized void acquire() {
-      acquisitionCount++;
-    }
-
-    public synchronized void release() {
-      acquisitionCount--;
-      if( acquisitionCount == 0 && evicted ) {
-        // Perform postponed eviction
-        logger.debug( "Evicting (actual): " + key );
-        deleteFile();
-      }
-    }
-
-    private void deleteFile() {
-      if( file != null ) {
-        file.delete();
-      }
-    }
-
-    public synchronized void evict() {
-      evicted = true;
-      if( acquisitionCount == 0 ) {
-        logger.debug( "Evicting directly: " + key );
-        deleteFile();
-      } else {
-        // File still in use, evict later
-        logger.debug( "Evicting (postponed): " + key );
-      }
-    }
-  }
-  protected class CacheMap extends LinkedHashMap<Key, Entry> {
-
-    private static final long serialVersionUID = 1L;
-    private final int capacity;
-
-    @Override
-    protected boolean removeEldestEntry( Map.Entry<Key, org.eclipse.epp.wizard.installerbuilder.InstallerCache.Entry> eldest )
-    {
-      boolean remove = false;
-      if( this.size() > this.capacity ) {
-        // remove Least recently used entry, and evict value from cache
-        remove = true;
-        eldest.getValue().evict();
-      }
-      return remove;
-    }
-
-    public CacheMap( int capacity, float loadFactor, boolean accessOrder ) {
-      super( capacity, loadFactor, accessOrder );
-      this.capacity = capacity;
-    }
-  }
-  final CacheMap cacheMap;
-  Configuration configuration = Activator.getDefault().getConfiguration();
-  private static final String INSTALLER_PROPERTIES_FILENAME = "installer.properties";
-  private static final String INSTALLER_TEMPLATE_PATH = "templates/installer";
-  private static final String PROPERTY_PLACEHOLDER_MARKER = "%?%";
-  private static final String ENCODING = "UTF-8";
-  private static final String TEMPFILE_EXTENSION = ".tmp";
-  private static final String TEMPFILE_NAME = "installer";
-  private static final int BUFFER = 1024;
-
-  public InstallerCache( int installerCacheSize ) {
-    cacheMap = new CacheMap( installerCacheSize, 1.75f, true );
-  }
-
-  public Entry getInstaller( Key key ) {
-    Entry entry;
-    synchronized( cacheMap ) {
-      entry = cacheMap.get( key );
-      if( entry == null ) {
-        entry = new Entry( key );
-        cacheMap.put( key, entry );
-      }
-      entry.acquire();
-    }
-    return entry;
-  }
-
-  protected File createInstaller( Key key ) {
-    File outFile = createTempFile();
-    File inFile = findRawInstallerFile( new File( configuration.getDownloadsDirectory(),
-                                                  "templates/installer" ),
-                                        key.getOs() );
-    InputStream in = null;
-    OutputStream out = null;
-    try {
-      out = new FileOutputStream( outFile );
-      in = new FileInputStream( inFile );
-      String config = getInstallerConfiguration( key.getOs(),
-                                                 key.getProperties() );
-      byte[] bytes = config.getBytes( ENCODING );
-      if( inFile.getName().endsWith( ".zip" ) ) {
-        ZipInputStream zis = null;
-        ZipOutputStream zos = null;
-        try {
-          zis = new ZipInputStream( in );
-          zos = new ZipOutputStream( out );
-          ZipEntry entry = zis.getNextEntry();
-          while( entry != null ) {
-            // Do not store directories explicitly
-            if( !entry.isDirectory() ) {
-              ZipEntry zipEntry = new ZipEntry( entry.getName() );
-              zos.putNextEntry( zipEntry );
-              copy( readSubStream( zis ), zos );
-            }
-            entry = zis.getNextEntry();
-          }
-          zos.putNextEntry( new ZipEntry( "eclipse/installer.properties" ) );
-          ByteArrayInputStream confStream = new ByteArrayInputStream( bytes );
-          copy( confStream, zos );
-          zos.closeEntry();
-        } catch( IOException e ) {
-          logger.error( "Could not create installer", e );
-        } finally {
-          tryClose( zis );
-          tryClose( zos );
-        }
-      } else if( inFile.getName().endsWith( ".tar.gz" ) ) {
-        GZIPInputStream gzis = null;
-        TarInputStream tis = null;
-        GZIPOutputStream gzos = null;
-        TarOutputStream tos = null;
-        try {
-          gzis = new GZIPInputStream( in );
-          tis = new TarInputStream( gzis );
-          gzos = new GZIPOutputStream( out );
-          tos = new TarOutputStream( gzos );
-          tos.setLongFileMode( TarOutputStream.LONGFILE_GNU );
-          TarEntry entry = tis.getNextEntry();
-          while( entry != null ) {
-            tos.putNextEntry( entry );
-            copy( readSubStream( tis ), tos );
-            tos.closeEntry();
-            entry = tis.getNextEntry();
-          }
-          String entryName = "eclipse/installer.properties";
-          if( key.getOs().equals( "macosx" ) ) {
-            entryName = "eclipse/p2installer.app/Contents/MacOS/installer.properties";
-          }
-          TarEntry tarEntry = new TarEntry( entryName );
-          ByteArrayInputStream confStream = new ByteArrayInputStream( bytes );
-          tarEntry.setSize( bytes.length );
-          tos.putNextEntry( tarEntry );
-          copy( confStream, tos );
-          tos.closeEntry();
-        } catch( IOException e ) {
-          logger.error( "Could not create installer", e );
-        } finally {
-          tryClose( tis );
-          tryClose( gzis );
-          tryClose( tos );
-          tryClose( gzos );
-        }
-      }
-    } catch( IOException ioe ) {
-      logger.error( "Could not create installer", ioe );
-    } finally {
-      tryClose( in );
-      tryClose( out );
-    }
-    return outFile;
-  }
-
-  private File findRawInstallerFile( final File dir, final String os ) {
-    File result = null;
-    File[] files = dir.listFiles();
-    for( File found : files ) {
-      if( found.getName().indexOf( os ) > -1 ) {
-        result = found;
-      }
-    }
-    return result;
-  }
-
-  private String getInstallerConfiguration( String os, Properties p2Properties )
-    throws IOException // FIXME
-  {
-    String result = "";
-    File downloadDir = Activator.getDefault()
-      .getConfiguration()
-      .getDownloadsDirectory();
-    File templateDir = new File( downloadDir, INSTALLER_TEMPLATE_PATH );
-    File inFile = new File( templateDir, INSTALLER_PROPERTIES_FILENAME );
-    Properties installerProperties = new Properties();
-    installerProperties.load( new FileInputStream( inFile ) );
-    for( Object okey : installerProperties.keySet() ) {
-      String key = ( String )okey;
-      if( installerProperties.getProperty( key )
-        .equals( PROPERTY_PLACEHOLDER_MARKER ) )
-      {
-        String value = p2Properties.getProperty( key );
-        if( value != null ) {
-          installerProperties.setProperty( key, value );
-        } else {
-          throw new RuntimeException( "No value for placeholder parameter in request: "
-                                      + key );
-        }
-      }
-    }
-    try {
-      ByteArrayOutputStream bufferStream = new ByteArrayOutputStream();
-      installerProperties.store( bufferStream, "" );
-      result = bufferStream.toString();
-    } catch( IOException e ) {
-      logger.error( "Could not create installer", e );
-    } finally {
-    }
-    return result;
-  }
-
-  private static InputStream readSubStream( final InputStream is )
-    throws IOException
-  {
-    ByteArrayOutputStream baos = new ByteArrayOutputStream();
-    copy( is, baos );
-    return new ByteArrayInputStream( baos.toByteArray() );
-  }
-
-  private static void tryClose( final InputStream stream ) {
-    if( stream != null ) {
-      try {
-        stream.close();
-      } catch( IOException e ) {
-        logger.error( "Could not create installer", e );
-      }
-    }
-  }
-
-  private static void tryClose( final OutputStream stream ) {
-    if( stream != null ) {
-      try {
-        stream.close();
-      } catch( IOException e ) {
-        logger.error( "Could not create installer", e );
-      }
-    }
-  }
-
-  private File createTempFile() {
-    File downloadsDirectory = configuration.getTempDirectory();
-    File tempFile;
-    try {
-      tempFile = File.createTempFile( TEMPFILE_NAME,
-                                      TEMPFILE_EXTENSION,
-                                      downloadsDirectory );
-    } catch( IOException e ) {
-      throw new RuntimeException( "Unable to create installer temp file", e );
-    }
-    return tempFile;
-  }
-
-  private static void copy( final InputStream in, final OutputStream out )
-    throws IOException
-  {
-    byte[] data = new byte[ BUFFER ];
-    int currentByte = in.read( data, 0, BUFFER );
-    while( currentByte != -1 ) {
-      out.write( data, 0, currentByte );
-      currentByte = in.read( data, 0, BUFFER );
-    }
-  }
-}
+/*******************************************************************************

+ * Copyright (c) 2008 Innoopract Informationssysteme GmbH.

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * which accompanies this distribution, and is available at

+ * http://www.eclipse.org/legal/epl-v10.html

+ *

+ * Contributors:

+ *     Innoopract Informationssysteme GmbH - initial API and implementation

+ ******************************************************************************/

+package org.eclipse.epp.wizard.installerbuilder;

+

+import java.io.ByteArrayInputStream;

+import java.io.ByteArrayOutputStream;

+import java.io.File;

+import java.io.FileInputStream;

+import java.io.FileOutputStream;

+import java.io.IOException;

+import java.io.InputStream;

+import java.io.OutputStream;

+import java.util.LinkedHashMap;

+import java.util.Map;

+import java.util.Properties;

+import java.util.zip.GZIPInputStream;

+import java.util.zip.GZIPOutputStream;

+import java.util.zip.ZipEntry;

+import java.util.zip.ZipInputStream;

+import java.util.zip.ZipOutputStream;

+

+import org.apache.log4j.Logger;

+import org.apache.tools.tar.TarEntry;

+import org.apache.tools.tar.TarInputStream;

+import org.apache.tools.tar.TarOutputStream;

+

+/**

+ * Cache for generated installers, uses the filesystem as a backing store

+ * 

+ * @author mwoelker

+ */

+public class InstallerCache {

+

+  static Logger logger = Logger.getLogger( InstallerCache.class );

+  public static class Key {

+

+    @Override

+    public String toString() {

+      return "os=" + os + ";" + properties.toString();

+    }

+

+    public String getOs() {

+      return os;

+    }

+

+    public Properties getProperties() {

+      return properties;

+    }

+

+    @Override

+    public int hashCode() {

+      final int prime = 31;

+      int result = 1;

+      result = prime * result + ( ( os == null )

+                                                ? 0

+                                                : os.hashCode() );

+      result = prime

+               * result

+               + ( ( properties == null )

+                                         ? 0

+                                         : properties.hashCode() );

+      return result;

+    }

+

+    @Override

+    public boolean equals( Object obj ) {

+      if( this == obj )

+        return true;

+      if( obj == null )

+        return false;

+      if( getClass() != obj.getClass() )

+        return false;

+      Key other = ( Key )obj;

+      if( os == null ) {

+        if( other.os != null )

+          return false;

+      } else if( !os.equals( other.os ) )

+        return false;

+      if( properties == null ) {

+        if( other.properties != null )

+          return false;

+      } else if( !properties.equals( other.properties ) )

+        return false;

+      return true;

+    }

+    String os;

+

+    public Key( String os, Properties properties ) {

+      super();

+      this.os = os;

+      this.properties = properties;

+    }

+    Properties properties;

+  }

+  /**

+   * Entry in the cache, the actual installer file is created lazily, to reduce

+   * monitor contention on the cacheMap

+   * 

+   * @author mwoelker

+   */

+  public class Entry {

+

+    private Key key;

+

+    public Entry( Key key ) {

+      super();

+      this.key = key;

+    }

+    long acquisitionCount = 0;

+

+    public synchronized File getFile() {

+      if( file == null ) {

+        file = createInstaller( key );

+      }

+      return file;

+    }

+    File file;

+    boolean evicted = false;

+    boolean disposed = false;

+

+    public synchronized void acquire() {

+      acquisitionCount++;

+    }

+

+    public synchronized void release() {

+      acquisitionCount--;

+      if( acquisitionCount == 0 && evicted ) {

+        // Perform postponed eviction

+        logger.debug( "Evicting (actual): " + key );

+        deleteFile();

+      }

+    }

+

+    private void deleteFile() {

+      if( file != null ) {

+        file.delete();

+      }

+    }

+

+    public synchronized void evict() {

+      evicted = true;

+      if( acquisitionCount == 0 ) {

+        logger.debug( "Evicting directly: " + key );

+        deleteFile();

+      } else {

+        // File still in use, evict later

+        logger.debug( "Evicting (postponed): " + key );

+      }

+    }

+  }

+  protected class CacheMap extends LinkedHashMap<Key, Entry> {

+

+    private static final long serialVersionUID = 1L;

+    private final int capacity;

+

+    @Override

+    protected boolean removeEldestEntry( Map.Entry<Key, org.eclipse.epp.wizard.installerbuilder.InstallerCache.Entry> eldest )

+    {

+      boolean remove = false;

+      if( this.size() > this.capacity ) {

+        // remove Least recently used entry, and evict value from cache

+        remove = true;

+        eldest.getValue().evict();

+      }

+      return remove;

+    }

+

+    public CacheMap( int capacity, float loadFactor, boolean accessOrder ) {

+      super( capacity, loadFactor, accessOrder );

+      this.capacity = capacity;

+    }

+  }

+  final CacheMap cacheMap;

+  Configuration configuration = Activator.getDefault().getConfiguration();

+  private static final String INSTALLER_PROPERTIES_FILENAME = "installer.properties";

+  private static final String INSTALLER_TEMPLATE_PATH = "templates/installer";

+  private static final String PROPERTY_PLACEHOLDER_MARKER = "%?%";

+  private static final String ENCODING = "UTF-8";

+  private static final String TEMPFILE_EXTENSION = ".tmp";

+  private static final String TEMPFILE_NAME = "installer";

+  private static final int BUFFER = 1024;

+

+  public InstallerCache( int installerCacheSize ) {

+    cacheMap = new CacheMap( installerCacheSize, 1.75f, true );

+  }

+

+  public Entry getInstaller( Key key ) {

+    Entry entry;

+    synchronized( cacheMap ) {

+      entry = cacheMap.get( key );

+      if( entry == null ) {

+        entry = new Entry( key );

+        cacheMap.put( key, entry );

+      }

+      entry.acquire();

+    }

+    return entry;

+  }

+

+  protected File createInstaller( Key key ) {

+    File outFile = createTempFile();

+    File inFile = findRawInstallerFile( new File( configuration.getDownloadsDirectory(),

+                                                  "templates/installer" ),

+                                        key.getOs() );

+    InputStream in = null;

+    OutputStream out = null;

+    try {

+      out = new FileOutputStream( outFile );

+      in = new FileInputStream( inFile );

+      String config = getInstallerConfiguration( key.getOs(),

+                                                 key.getProperties() );

+      byte[] bytes = config.getBytes( ENCODING );

+      if( inFile.getName().endsWith( ".zip" ) ) {

+        ZipInputStream zis = null;

+        ZipOutputStream zos = null;

+        try {

+          zis = new ZipInputStream( in );

+          zos = new ZipOutputStream( out );

+          ZipEntry entry = zis.getNextEntry();

+          while( entry != null ) {

+            // Do not store directories explicitly

+            if( !entry.isDirectory() ) {

+              ZipEntry zipEntry = new ZipEntry( entry.getName() );

+              zos.putNextEntry( zipEntry );

+              copy( readSubStream( zis ), zos );

+            }

+            entry = zis.getNextEntry();

+          }

+          zos.putNextEntry( new ZipEntry( "eclipse/installer.properties" ) );

+          ByteArrayInputStream confStream = new ByteArrayInputStream( bytes );

+          copy( confStream, zos );

+          zos.closeEntry();

+        } catch( IOException e ) {

+          logger.error( "Could not create installer", e );

+        } finally {

+          tryClose( zis );

+          tryClose( zos );

+        }

+      } else if( inFile.getName().endsWith( ".tar.gz" ) ) {

+        GZIPInputStream gzis = null;

+        TarInputStream tis = null;

+        GZIPOutputStream gzos = null;

+        TarOutputStream tos = null;

+        try {

+          gzis = new GZIPInputStream( in );

+          tis = new TarInputStream( gzis );

+          gzos = new GZIPOutputStream( out );

+          tos = new TarOutputStream( gzos );

+          tos.setLongFileMode( TarOutputStream.LONGFILE_GNU );

+          TarEntry entry = tis.getNextEntry();

+          while( entry != null ) {

+            tos.putNextEntry( entry );

+            copy( readSubStream( tis ), tos );

+            tos.closeEntry();

+            entry = tis.getNextEntry();

+          }

+          String entryName = "eclipse/installer.properties";

+          if( key.getOs().equals( "macosx" ) ) {

+            entryName = "eclipse/p2installer.app/Contents/MacOS/installer.properties";

+          }

+          TarEntry tarEntry = new TarEntry( entryName );

+          ByteArrayInputStream confStream = new ByteArrayInputStream( bytes );

+          tarEntry.setSize( bytes.length );

+          tos.putNextEntry( tarEntry );

+          copy( confStream, tos );

+          tos.closeEntry();

+        } catch( IOException e ) {

+          logger.error( "Could not create installer", e );

+        } finally {

+          tryClose( tis );

+          tryClose( gzis );

+          tryClose( tos );

+          tryClose( gzos );

+        }

+      }

+    } catch( IOException ioe ) {

+      logger.error( "Could not create installer", ioe );

+    } finally {

+      tryClose( in );

+      tryClose( out );

+    }

+    return outFile;

+  }

+

+  private File findRawInstallerFile( final File dir, final String os ) {

+    File result = null;

+    File[] files = dir.listFiles();

+    for( File found : files ) {

+      if( found.getName().indexOf( os ) > -1 ) {

+        result = found;

+      }

+    }

+    return result;

+  }

+

+  private String getInstallerConfiguration( String os, Properties p2Properties )

+    throws IOException // FIXME

+  {

+    String result = "";

+    File downloadDir = Activator.getDefault()

+      .getConfiguration()

+      .getDownloadsDirectory();

+    File templateDir = new File( downloadDir, INSTALLER_TEMPLATE_PATH );

+    File inFile = new File( templateDir, INSTALLER_PROPERTIES_FILENAME );

+    Properties installerProperties = new Properties();

+    installerProperties.load( new FileInputStream( inFile ) );

+    for( Object okey : installerProperties.keySet() ) {

+      String key = ( String )okey;

+      if( installerProperties.getProperty( key )

+        .equals( PROPERTY_PLACEHOLDER_MARKER ) )

+      {

+        String value = p2Properties.getProperty( key );

+        if( value != null ) {

+          installerProperties.setProperty( key, value );

+        } else {

+          throw new RuntimeException( "No value for placeholder parameter in request: "

+                                      + key );

+        }

+      }

+    }

+    try {

+      ByteArrayOutputStream bufferStream = new ByteArrayOutputStream();

+      installerProperties.store( bufferStream, "" );

+      result = bufferStream.toString();

+    } catch( IOException e ) {

+      logger.error( "Could not create installer", e );

+    } finally {

+    }

+    return result;

+  }

+

+  private static InputStream readSubStream( final InputStream is )

+    throws IOException

+  {

+    ByteArrayOutputStream baos = new ByteArrayOutputStream();

+    copy( is, baos );

+    return new ByteArrayInputStream( baos.toByteArray() );

+  }

+

+  private static void tryClose( final InputStream stream ) {

+    if( stream != null ) {

+      try {

+        stream.close();

+      } catch( IOException e ) {

+        logger.error( "Could not create installer", e );

+      }

+    }

+  }

+

+  private static void tryClose( final OutputStream stream ) {

+    if( stream != null ) {

+      try {

+        stream.close();

+      } catch( IOException e ) {

+        logger.error( "Could not create installer", e );

+      }

+    }

+  }

+

+  private File createTempFile() {

+    File downloadsDirectory = configuration.getTempDirectory();

+    File tempFile;

+    try {

+      tempFile = File.createTempFile( TEMPFILE_NAME,

+                                      TEMPFILE_EXTENSION,

+                                      downloadsDirectory );

+    } catch( IOException e ) {

+      throw new RuntimeException( "Unable to create installer temp file", e );

+    }

+    return tempFile;

+  }

+

+  private static void copy( final InputStream in, final OutputStream out )

+    throws IOException

+  {

+    byte[] data = new byte[ BUFFER ];

+    int currentByte = in.read( data, 0, BUFFER );

+    while( currentByte != -1 ) {

+      out.write( data, 0, currentByte );

+      currentByte = in.read( data, 0, BUFFER );

+    }

+  }

+}

diff --git a/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/jnlpbuilder/CustomJnlp.java b/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/jnlpbuilder/CustomJnlp.java
index 268ba4a..dc8b9cc 100644
--- a/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/jnlpbuilder/CustomJnlp.java
+++ b/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/jnlpbuilder/CustomJnlp.java
@@ -1,212 +1,210 @@
-/*******************************************************************************
- * Copyright (c) 2008 Innoopract Informationssysteme GmbH.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Innoopract Informationssysteme GmbH - initial API and implementation
- ******************************************************************************/
-package org.eclipse.epp.wizard.jnlpbuilder;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.URL;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.StringTokenizer;
-
-import javax.servlet.ServletException;
-import javax.servlet.ServletOutputStream;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.epp.wizard.installerbuilder.Activator;
-import org.eclipse.epp.wizard.installerbuilder.BuildInstaller;
-import org.eclipse.epp.wizard.util.StringUtil;
-
-/**
- * @author Jordi Boehme Lopez <jboehme@innoopract.com>
- */
-public class CustomJnlp extends HttpServlet {
-
-
-  // public static final String OUT_PATH = "/opt/epp/htdocs";
-  // public static final String OUT_PATH = "C:/opt/epp/htdocs";
-  public static final String JNLP_TEMPLATE_PATH = "templates/jnlp/epp.jnlp";
-  private static final String ENCODING = "UTF-8";
-  private static final int BUFFER = 512;
-  private static final long serialVersionUID = 1L;
-
-  @Override
-  protected void doPost( final HttpServletRequest req, 
-                         final HttpServletResponse resp)
-      throws ServletException, IOException {
-    doGet(req, resp);
-  }
-  
-  @Override
-  protected void doGet( final HttpServletRequest req,
-                        final HttpServletResponse resp )
-    throws ServletException, IOException
-  {
-    String codebase = "http://"
-                      + req.getServerName()
-                      + ":"
-                      + req.getServerPort()
-                      + "/download";
-    String iuParam = req.getParameter( "ius" );
-//    String href = req.getRequestURL()
-//      .append( "?" + req.getQueryString() )
-//      .toString();
-    resp.addHeader( "Content-Type", "application/x-java-jnlp-file" );
-    IPath jnlp_file = execute( codebase, iuParam );
-    
-    resp.flushBuffer();
-    ServletOutputStream os = resp.getOutputStream();
-    copy( new FileInputStream(jnlp_file.toFile()) , os);
-    os.flush();
-  }
-
-  public static IPath execute( final String codebase,
-                              final String iuParam ) throws IOException
-  {
-    File downloadDir = Activator.getDefault()
-      .getConfiguration()
-      .getDownloadsDirectory();
-    IPath outDirPath = new Path( new File( downloadDir,
-                                           BuildInstaller.OUTPUT_PATH ).getAbsolutePath() );
-    String[] ius = getIUs( iuParam );
-    String filename = getFileName( ius );
-    // URL template =
-    // Activator.getContext().getBundle().getEntry(TEMPLATE_PATH);
-    IPath outFilePath = outDirPath.append( filename );
-    File templateFile = new File( downloadDir, JNLP_TEMPLATE_PATH );
-    String jnlp = ceateCustomJnlp( templateFile.toURI().toURL(),
-                                   ius,
-                                   codebase,
-                                   filename );
-    OutputStream os = new FileOutputStream( outFilePath.toFile() );
-    os.write( jnlp.getBytes( ENCODING ) );
-    tryClose( os );
-    
-    return outFilePath;
-  }
-
-  // ////////////////
-  // helping methods
-  // ////////////////
-  private static String[] getIUs( final String param ) {
-    List<String> result = new ArrayList<String>();
-    StringTokenizer tknizr = new StringTokenizer( param, ",", false );
-    while( tknizr.hasMoreTokens() ) {
-      String token = tknizr.nextToken();
-      result.add( token );
-    }
-    return result.toArray( new String[ result.size() ] );
-  }
-
-  private static String ceateCustomJnlp( final URL template,
-                                         final String ius[],
-                                         final String codebase,
-                                         final String filename )
-  {
-    String result = "";
-    InputStream in = null;
-    try {
-      in = template.openStream();
-      ByteArrayOutputStream bufferStream = new ByteArrayOutputStream();
-      copy( in, bufferStream );
-      result = customize( bufferStream.toString( ENCODING ),
-                          ius,
-                          codebase,
-                          filename );
-    } catch( IOException ioe ) {
-      ioe.printStackTrace();
-    } finally {
-      tryClose( in );
-    }
-    return result;
-  }
-
-  private static String customize( final String input,
-                                   final String[] ius,
-                                   final String codebase,
-                                   final String href )
-  {
-    String result = input;
-    result = result.replaceAll( "\\$\\{codebase\\}", codebase );
-    result = result.replaceAll( "\\$\\{href\\}", href );
-    result = result.replaceAll( "\\$\\{roots\\}",
-                                StringUtil.toCommaList( ius, false ) );
-    result = result.replaceAll( "\\$\\{profileName\\}", "ProfileNameHere" ); // FIXME
-                                                                             // :
-                                                                             // (
-                                                                             // jb
-                                                                             // )
-                                                                             // get
-                                                                             // this
-                                                                             // from
-                                                                             // initial
-                                                                             // selection
-                                                                             // on
-                                                                             // eclispe
-                                                                             // .
-                                                                             // org
-    return result;
-  }
-
-  private static void tryClose( final InputStream stream ) {
-    if( stream != null ) {
-      try {
-        stream.close();
-      } catch( IOException e ) {
-        e.printStackTrace();
-        // TODO Activator.log( e );
-      }
-    }
-  }
-
-  private static void tryClose( final OutputStream stream ) {
-    if( stream != null ) {
-      try {
-        stream.close();
-      } catch( IOException e ) {
-        e.printStackTrace();
-        // TODO Activator.log( e );
-      }
-    }
-  }
-
-  private static void copy( final InputStream in, final OutputStream out )
-    throws IOException
-  {
-    byte[] data = new byte[ BUFFER ];
-    int currentByte = in.read( data, 0, BUFFER );
-    while( currentByte != -1 ) {
-      out.write( data, 0, currentByte );
-      currentByte = in.read( data, 0, BUFFER );
-    }
-  }
-
-  public static String getFileName( final String[] ids ) {
-    String hash = ids.toString();
-    try {
-      hash = StringUtil.getHash( ids );
-    } catch( NoSuchAlgorithmException exc ) {
-      // should not happen! - but trace anyway
-      exc.printStackTrace();
-    }
-    return "startinstaller-" + hash + ".jnlp";
-  }
+/*******************************************************************************

+ * Copyright (c) 2008 Innoopract Informationssysteme GmbH.

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * which accompanies this distribution, and is available at

+ * http://www.eclipse.org/legal/epl-v10.html

+ *

+ * Contributors:

+ *     Innoopract Informationssysteme GmbH - initial API and implementation

+ ******************************************************************************/

+package org.eclipse.epp.wizard.jnlpbuilder;

+

+import java.io.ByteArrayOutputStream;

+import java.io.File;

+import java.io.FileInputStream;

+import java.io.FileOutputStream;

+import java.io.IOException;

+import java.io.InputStream;

+import java.io.OutputStream;

+import java.net.URL;

+import java.security.NoSuchAlgorithmException;

+import java.util.ArrayList;

+import java.util.List;

+import java.util.StringTokenizer;

+

+import javax.servlet.ServletException;

+import javax.servlet.ServletOutputStream;

+import javax.servlet.http.HttpServlet;

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.eclipse.core.runtime.IPath;

+import org.eclipse.core.runtime.Path;

+import org.eclipse.epp.wizard.installerbuilder.Activator;

+import org.eclipse.epp.wizard.installerbuilder.BuildInstaller;

+import org.eclipse.epp.wizard.util.StringUtil;

+

+/**

+ * @author Jordi Boehme Lopez <jboehme@innoopract.com>

+ */

+public class CustomJnlp extends HttpServlet {

+

+

+  // public static final String OUT_PATH = "/opt/epp/htdocs";

+  // public static final String OUT_PATH = "C:/opt/epp/htdocs";

+  public static final String JNLP_TEMPLATE_PATH = "templates/jnlp/epp.jnlp";

+  private static final String ENCODING = "UTF-8";

+  private static final int BUFFER = 512;

+  private static final long serialVersionUID = 1L;

+

+  @Override

+  protected void doPost( final HttpServletRequest req, 

+                         final HttpServletResponse resp)

+      throws ServletException, IOException {

+    doGet(req, resp);

+  }

+  

+  @Override

+  protected void doGet( final HttpServletRequest req,

+                        final HttpServletResponse resp )

+    throws ServletException, IOException

+  {

+    String codebase = "http://"

+                      + req.getServerName()

+                      + ":"

+                      + req.getServerPort()

+                      + "/download";

+    String iuParam = req.getParameter( "eclipse.p2.roots" );

+    String metadata = req.getParameter( "eclipse.p2.metadata" );

+    String artifacts = req.getParameter( "eclipse.p2.artifacts" );

+

+    resp.addHeader( "Content-Type", "application/x-java-jnlp-file" );

+    IPath jnlp_file = execute( codebase, iuParam, metadata, artifacts );

+    

+    resp.flushBuffer();

+    ServletOutputStream os = resp.getOutputStream();

+    copy( new FileInputStream(jnlp_file.toFile()) , os);

+    os.flush();

+  }

+

+  public static IPath execute( final String codebase,

+                               final String iuParam, 

+                               final String metadata, 

+                               final String artifacts ) throws IOException

+  {

+    File downloadDir = Activator.getDefault()

+      .getConfiguration()

+      .getDownloadsDirectory();

+    IPath outDirPath = new Path( new File( downloadDir,

+                                           BuildInstaller.OUTPUT_PATH ).getAbsolutePath() );

+    String[] ius = getIUs( iuParam );

+    String filename = getFileName( ius );

+    IPath outFilePath = outDirPath.append( filename );

+    File templateFile = new File( downloadDir, JNLP_TEMPLATE_PATH );

+    String jnlp = ceateCustomJnlp( templateFile.toURI().toURL(),

+                                   ius,

+                                   codebase,

+                                   filename,

+                                   metadata,

+                                   artifacts );

+    OutputStream os = new FileOutputStream( outFilePath.toFile() );

+    os.write( jnlp.getBytes( ENCODING ) );

+    tryClose( os );

+    

+    return outFilePath;

+  }

+

+  // ////////////////

+  // helping methods

+  // ////////////////

+  private static String[] getIUs( final String param ) {

+    List<String> result = new ArrayList<String>();

+    StringTokenizer tknizr = new StringTokenizer( param, ",", false );

+    while( tknizr.hasMoreTokens() ) {

+      String token = tknizr.nextToken();

+      result.add( token );

+    }

+    return result.toArray( new String[ result.size() ] );

+  }

+

+  private static String ceateCustomJnlp( final URL template,

+                                         final String ius[],

+                                         final String codebase,

+                                         final String filename, 

+                                         final String metadata, 

+                                         final String artifacts )

+  {

+    String result = "";

+    InputStream in = null;

+    try {

+      in = template.openStream();

+      ByteArrayOutputStream bufferStream = new ByteArrayOutputStream();

+      copy( in, bufferStream );

+      result = customize( bufferStream.toString( ENCODING ),

+                          ius,

+                          codebase,

+                          filename,

+                          metadata, 

+                          artifacts );

+    } catch( IOException ioe ) {

+      ioe.printStackTrace();

+    } finally {

+      tryClose( in );

+    }

+    return result;

+  }

+

+  private static String customize( final String input,

+                                   final String[] ius,

+                                   final String codebase,

+                                   final String href, 

+                                   final String metadata, 

+                                   final String artifacts )

+  {

+    String result = input;

+    result = result.replaceAll( "\\$\\{codebase\\}", codebase );

+    result = result.replaceAll( "\\$\\{href\\}", href );

+    result = result.replaceAll( "\\$\\{roots\\}",

+                                StringUtil.toCommaList( ius, false ) );

+    result = result.replaceAll( "\\$\\{metadata\\}", metadata );

+    result = result.replaceAll( "\\$\\{artifacts\\}", artifacts );

+    // FIXME : (jb) get this from initial selection on eclispe.org

+    result = result.replaceAll( "\\$\\{profileName\\}", "Custom Eclipse" ); 

+    return result;

+  }

+

+  private static void tryClose( final InputStream stream ) {

+    if( stream != null ) {

+      try {

+        stream.close();

+      } catch( IOException e ) {

+        e.printStackTrace();

+        // TODO Activator.log( e );

+      }

+    }

+  }

+

+  private static void tryClose( final OutputStream stream ) {

+    if( stream != null ) {

+      try {

+        stream.close();

+      } catch( IOException e ) {

+        e.printStackTrace();

+        // TODO Activator.log( e );

+      }

+    }

+  }

+

+  private static void copy( final InputStream in, final OutputStream out )

+    throws IOException

+  {

+    byte[] data = new byte[ BUFFER ];

+    int currentByte = in.read( data, 0, BUFFER );

+    while( currentByte != -1 ) {

+      out.write( data, 0, currentByte );

+      currentByte = in.read( data, 0, BUFFER );

+    }

+  }

+

+  public static String getFileName( final String[] ids ) {

+    String hash = ids.toString();

+    try {

+      hash = StringUtil.getHash( ids );

+    } catch( NoSuchAlgorithmException exc ) {

+      // should not happen! - but trace anyway

+      exc.printStackTrace();

+    }

+    return "startinstaller-" + hash + ".jnlp";

+  }

 }
\ No newline at end of file
diff --git a/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/util/OsUtil.java b/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/util/OsUtil.java
index e487d38..74188c7 100644
--- a/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/util/OsUtil.java
+++ b/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/util/OsUtil.java
@@ -1,38 +1,38 @@
-/*******************************************************************************
- * Copyright (c) 2008 Innoopract Informationssysteme GmbH.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Innoopract Informationssysteme GmbH - initial API and implementation
- ******************************************************************************/
-package org.eclipse.epp.wizard.util;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * @author Jordi Boehme Lopez <jboehme@innoopract.com>
- */
-public class OsUtil {
-
-  private static final String[] PLATFORMS = new String[]{
-    "win32", "linux", "macosx"
-  };
-  private static final Map<String, String> EXTS = new HashMap<String, String>();
-  static {
-    EXTS.put( "win32", "zip" );
-    EXTS.put( "linux", "tar.gz" );
-    EXTS.put( "macosx", "tar.gz" );
-  }
-
-  public static String[] getPlatforms() {
-    return PLATFORMS;
-  }
-
-  public static String getArchiveExtension( final String os ) {
-    return EXTS.get( os );
-  }
-}
+/*******************************************************************************

+ * Copyright (c) 2008 Innoopract Informationssysteme GmbH.

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * which accompanies this distribution, and is available at

+ * http://www.eclipse.org/legal/epl-v10.html

+ *

+ * Contributors:

+ *     Innoopract Informationssysteme GmbH - initial API and implementation

+ ******************************************************************************/

+package org.eclipse.epp.wizard.util;

+

+import java.util.HashMap;

+import java.util.Map;

+

+/**

+ * @author Jordi Boehme Lopez <jboehme@innoopract.com>

+ */

+public class OsUtil {

+

+  private static final String[] PLATFORMS = new String[]{

+    "win32", "linux", "macosx"

+  };

+  private static final Map<String, String> EXTS = new HashMap<String, String>();

+  static {

+    EXTS.put( "win32", "zip" );

+    EXTS.put( "linux", "tar.gz" );

+    EXTS.put( "macosx", "tar.gz" );

+  }

+

+  public static String[] getPlatforms() {

+    return PLATFORMS;

+  }

+

+  public static String getArchiveExtension( final String os ) {

+    return EXTS.get( os );

+  }

+}

diff --git a/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/util/StressTest.java b/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/util/StressTest.java
index 3d0aa76..2891ab5 100644
--- a/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/util/StressTest.java
+++ b/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/util/StressTest.java
@@ -1,104 +1,104 @@
-/*******************************************************************************
- * Copyright (c) 2008 Innoopract Informationssysteme GmbH.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Innoopract Informationssysteme GmbH - initial API and implementation
- ******************************************************************************/
-package org.eclipse.epp.wizard.util;
-
-import java.io.InputStream;
-import java.io.OutputStreamWriter;
-import java.net.URL;
-import java.net.URLConnection;
-import java.net.URLEncoder;
-import java.util.Random;
-
-public class StressTest implements Runnable {
-
-  private static final int THREADS = 10;
-  private static final int TIMES = 10;
-  private static final int SPREAD = 10;
-  static Random random = new Random();
-
-  /**
-   * @param args
-   */
-  public static void main( String[] args ) {
-    for( int i = 0; i < THREADS; i++ ) {
-      Thread thread = new Thread( new StressTest() );
-      thread.setName( String.format( "Stresser %3d", i ) );
-      thread.start();
-    }
-  }
-  static double total = 0;
-  static double count = 0;
-
-  private static synchronized double getAverage( double datapoint ) {
-    total += datapoint;
-    count++;
-    return total / count;
-  }
-
-  private static void runTest() {
-    try {
-      int value = Math.abs( ( int )( SPREAD * random.nextGaussian() ) );
-      long start = System.nanoTime();
-      // Construct data
-      String data = URLEncoder.encode( "os", "UTF-8" )
-                    + "="
-                    + URLEncoder.encode( "linux", "UTF-8" );
-      data += "&"
-              + URLEncoder.encode( "eclipse.p2.roots", "UTF-8" )
-              + "="
-              + URLEncoder.encode( "value2", "UTF-8" );
-      data += "&"
-              + URLEncoder.encode( "eclipse.p2.metadata", "UTF-8" )
-              + "="
-              + URLEncoder.encode( "value2", "UTF-8" );
-      data += "&"
-              + URLEncoder.encode( "eclipse.p2.artifacts", "UTF-8" )
-              + "="
-              + URLEncoder.encode( "value" + value, "UTF-8" );
-      // Send data
-      URL url = new URL( "http://localhost:8888/installer/" );
-      URLConnection conn = url.openConnection();
-      conn.setDoOutput( true );
-      OutputStreamWriter wr = new OutputStreamWriter( conn.getOutputStream() );
-      wr.write( data );
-      wr.flush();
-      // Get the response
-      if( true ) {
-        // FileOutputStream fos = new FileOutputStream("out.tar.gz");
-        InputStream is = conn.getInputStream();
-        byte[] buffer = new byte[ 1024 ];
-        @SuppressWarnings("unused")
-        int bytes;
-        while( -1 != ( bytes = is.read( buffer ) ) ) {
-          // fos.write(buffer, 0, bytes);
-        }
-        is.close();
-        // fos.close();
-      }
-      wr.close();
-      long end = System.nanoTime();
-      double average = getAverage( ( end - start ) / 1000 );
-      System.out.println( String.format( "%s Time [%5d] %20d (avg: %12.3f)",
-                                         Thread.currentThread().getName(),
-                                         value,
-                                         ( end - start ) / 1000,
-                                         average ) );
-    } catch( Exception e ) {
-      e.printStackTrace();
-    }
-  }
-
-  public void run() {
-    for( int i = 0; i < TIMES; i++ ) {
-      runTest();
-    }
-  }
-}
+/*******************************************************************************

+ * Copyright (c) 2008 Innoopract Informationssysteme GmbH.

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * which accompanies this distribution, and is available at

+ * http://www.eclipse.org/legal/epl-v10.html

+ *

+ * Contributors:

+ *     Innoopract Informationssysteme GmbH - initial API and implementation

+ ******************************************************************************/

+package org.eclipse.epp.wizard.util;

+

+import java.io.InputStream;

+import java.io.OutputStreamWriter;

+import java.net.URL;

+import java.net.URLConnection;

+import java.net.URLEncoder;

+import java.util.Random;

+

+public class StressTest implements Runnable {

+

+  private static final int THREADS = 10;

+  private static final int TIMES = 10;

+  private static final int SPREAD = 10;

+  static Random random = new Random();

+

+  /**

+   * @param args

+   */

+  public static void main( String[] args ) {

+    for( int i = 0; i < THREADS; i++ ) {

+      Thread thread = new Thread( new StressTest() );

+      thread.setName( String.format( "Stresser %3d", i ) );

+      thread.start();

+    }

+  }

+  static double total = 0;

+  static double count = 0;

+

+  private static synchronized double getAverage( double datapoint ) {

+    total += datapoint;

+    count++;

+    return total / count;

+  }

+

+  private static void runTest() {

+    try {

+      int value = Math.abs( ( int )( SPREAD * random.nextGaussian() ) );

+      long start = System.nanoTime();

+      // Construct data

+      String data = URLEncoder.encode( "os", "UTF-8" )

+                    + "="

+                    + URLEncoder.encode( "linux", "UTF-8" );

+      data += "&"

+              + URLEncoder.encode( "eclipse.p2.roots", "UTF-8" )

+              + "="

+              + URLEncoder.encode( "value2", "UTF-8" );

+      data += "&"

+              + URLEncoder.encode( "eclipse.p2.metadata", "UTF-8" )

+              + "="

+              + URLEncoder.encode( "value2", "UTF-8" );

+      data += "&"

+              + URLEncoder.encode( "eclipse.p2.artifacts", "UTF-8" )

+              + "="

+              + URLEncoder.encode( "value" + value, "UTF-8" );

+      // Send data

+      URL url = new URL( "http://localhost:8888/installer/" );

+      URLConnection conn = url.openConnection();

+      conn.setDoOutput( true );

+      OutputStreamWriter wr = new OutputStreamWriter( conn.getOutputStream() );

+      wr.write( data );

+      wr.flush();

+      // Get the response

+      if( true ) {

+        // FileOutputStream fos = new FileOutputStream("out.tar.gz");

+        InputStream is = conn.getInputStream();

+        byte[] buffer = new byte[ 1024 ];

+        @SuppressWarnings("unused")

+        int bytes;

+        while( -1 != ( bytes = is.read( buffer ) ) ) {

+          // fos.write(buffer, 0, bytes);

+        }

+        is.close();

+        // fos.close();

+      }

+      wr.close();

+      long end = System.nanoTime();

+      double average = getAverage( ( end - start ) / 1000 );

+      System.out.println( String.format( "%s Time [%5d] %20d (avg: %12.3f)",

+                                         Thread.currentThread().getName(),

+                                         value,

+                                         ( end - start ) / 1000,

+                                         average ) );

+    } catch( Exception e ) {

+      e.printStackTrace();

+    }

+  }

+

+  public void run() {

+    for( int i = 0; i < TIMES; i++ ) {

+      runTest();

+    }

+  }

+}

diff --git a/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/util/StringUtil.java b/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/util/StringUtil.java
index 0caa98b..f084c5a 100644
--- a/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/util/StringUtil.java
+++ b/plugins/org.eclipse.epp.wizard.installerbuilder/src/org/eclipse/epp/wizard/util/StringUtil.java
@@ -1,46 +1,46 @@
-/*******************************************************************************
- * Copyright (c) 2008 Innoopract Informationssysteme GmbH.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Innoopract Informationssysteme GmbH - initial API and implementation
- ******************************************************************************/
-package org.eclipse.epp.wizard.util;
-
-import java.security.NoSuchAlgorithmException;
-
-/**
- * @author Jordi Boehme Lopez <jboehme@innoopract.com>
- */
-public class StringUtil {
-
-  public static String toCommaList( final String[] items, final boolean space )
-  {
-    StringBuilder result = new StringBuilder();
-    for( int i = 0; i < items.length; i++ ) {
-      if( i > 0 ) {
-        result.append( "," );
-        if( space ) {
-          result.append( " " );
-        }
-      }
-      result.append( items[ i ].trim() );
-    }
-    return result.toString();
-  }
-
-  public static String getHash( final String[] ids )
-    throws NoSuchAlgorithmException
-  {
-    return getHash( toCommaList( ids, false ) );
-  }
-
-  private static String getHash( final String value )
-    throws NoSuchAlgorithmException
-  {
-    return Crypt.md5encrypt( value );
-  }
-}
+/*******************************************************************************

+ * Copyright (c) 2008 Innoopract Informationssysteme GmbH.

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * which accompanies this distribution, and is available at

+ * http://www.eclipse.org/legal/epl-v10.html

+ *

+ * Contributors:

+ *     Innoopract Informationssysteme GmbH - initial API and implementation

+ ******************************************************************************/

+package org.eclipse.epp.wizard.util;

+

+import java.security.NoSuchAlgorithmException;

+

+/**

+ * @author Jordi Boehme Lopez <jboehme@innoopract.com>

+ */

+public class StringUtil {

+

+  public static String toCommaList( final String[] items, final boolean space )

+  {

+    StringBuilder result = new StringBuilder();

+    for( int i = 0; i < items.length; i++ ) {

+      if( i > 0 ) {

+        result.append( "," );

+        if( space ) {

+          result.append( " " );

+        }

+      }

+      result.append( items[ i ].trim() );

+    }

+    return result.toString();

+  }

+

+  public static String getHash( final String[] ids )

+    throws NoSuchAlgorithmException

+  {

+    return getHash( toCommaList( ids, false ) );

+  }

+

+  private static String getHash( final String value )

+    throws NoSuchAlgorithmException

+  {

+    return Crypt.md5encrypt( value );

+  }

+}