mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

kenneth_suter
23.29.2007 23faffa02e132a30c02f928e317c6f66ac373d06
The commit contains code for the following:

- The Upgrader wizard panels (except the final progress panel) now pass real user data to the upgrader process.

- A RemoteBuildManager that handles querying for and downloading build files. Also code for handling access through web proxies.

- The create-webstart-standalone script has been modified to generate a QuickUpgrade.jnlp file that is put into the 'install' directory as a peer to the QuickSetup.jnlp script.

2 files added
23 files modified
1834 ■■■■ changed files
opends/resource/upgrade 40 ●●●● patch | view | raw | blame | history
opends/resource/webstart/create-webstart-standalone.sh 63 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/Installation.java 51 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallReviewPanel.java 19 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties 32 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/CustomHTMLEditorKit.java 16 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/FieldName.java 27 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupPanel.java 9 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupStepPanel.java 19 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/ReviewPanel.java 30 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/ServerSettingsPanel.java 4 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/UIFactory.java 39 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/Utilities.java 5 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/WebBrowserErrorDialog.java 2 ●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/WebProxyDialog.java 392 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/upgrader/Build.java 81 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/upgrader/RemoteBuildManager.java 246 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeUserData.java 20 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java 158 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/ChooseVersionPanel.java 325 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/UpgraderReviewPanel.java 82 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/WelcomePanel.java 123 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/util/BackgroundTask.java 9 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/util/BackgroundThreadTask.java 10 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/util/Utils.java 32 ●●●● patch | view | raw | blame | history
opends/resource/upgrade
@@ -36,12 +36,16 @@
    then
      . "${INSTANCE_ROOT}/bin/set-java-home"
      JAVA_BIN="${JAVA_HOME}/bin/java"
      JAVAWS_BIN="${JAVA_HOME}/bin/javaws"
      export JAVA_BIN
      export JAVAWS_BIN
    else
      JAVA_BIN=`which java 2> /dev/null`
      JAVAWS_BIN=`which javaws 2> /dev/null`
      if test ${?} -eq 0
      then
        export JAVA_BIN
        export JAVAWS_BIN
      else
        echo "Please set JAVA_HOME to the root of a Java 5.0 installation."
        exit 1
@@ -49,7 +53,9 @@
    fi
  else
    JAVA_BIN="${JAVA_HOME}/bin/java"
    JAVAWS_BIN="${JAVA_HOME}/bin/javaws"
    export JAVA_BIN
    export JAVA_WS
  fi
fi
@@ -138,19 +144,29 @@
if test ${?} -eq 0
then
  # Configure the appropriate CLASSPATH.
  # Unlike BuildExtractor, the Upgrader uses
  # the newly extracted build's jars.
  for JAR in ${INSTANCE_ROOT}/tmp/upgrade/lib/*.jar
  do
    CLASSPATH=${JAR}:${CLASSPATH}
  done
  # Launch the upgrade process.
  "${JAVA_BIN}" org.opends.quicksetup.upgrader.UpgradeLauncher "${@}"
  # Clean up if necessary
  if [ -r "./tmp/upgrade" ]
  then
    rm -fr "./tmp/upgrade"
    # Configure the appropriate CLASSPATH.
    # Unlike BuildExtractor, the Upgrader uses
    # the newly extracted build's jars.
    for JAR in ${INSTANCE_ROOT}/tmp/upgrade/lib/*.jar
    do
      CLASSPATH=${JAR}:${CLASSPATH}
    done
    # Launch the upgrade process.
    "${JAVA_BIN}" org.opends.quicksetup.upgrader.UpgradeLauncher "${@}"
    # Clean up if necessary
    if [ -r "./tmp/upgrade" ]
    then
      rm -fr "./tmp/upgrade"
    fi
  else
    # URL FOR TESTING ONLY
    # JAVAWS_VM_ARGS="-Dorg.opends.quicksetup.upgrader.Root=$INSTANCE_ROOT -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"
    JAVAWS_VM_ARGS="-Xclearcache -Dorg.opends.quicksetup.upgrader.Root=$INSTANCE_ROOT"
    export JAVAWS_VM_ARGS
    "${JAVAWS_BIN}" "http://localhost:8080/install/QuickUpgrade.jnlp"
  fi
fi
opends/resource/webstart/create-webstart-standalone.sh
@@ -31,11 +31,17 @@
fi
echo "BASE_PATH:      ${BASE_PATH}"
if test -z "${JNLP_FILENAME}"
if test -z "${INSTALL_JNLP_FILENAME}"
then
  JNLP_FILENAME="QuickSetup.jnlp"
  INSTALL_JNLP_FILENAME="QuickSetup.jnlp"
fi
echo "JNLP_FILENAME:  ${JNLP_FILENAME}"
echo "INSTALL_JNLP_FILENAME:  ${INSTALL_JNLP_FILENAME}"
if test -z "${UPGRADE_JNLP_FILENAME}"
then
  UPGRADE_JNLP_FILENAME="QuickUpgrade.jnlp"
fi
echo "UPGRADE_JNLP_FILENAME:  ${UPGRADE_JNLP_FILENAME}"
if test -z "${PORT}"
then
@@ -146,14 +152,14 @@
               -storepass "${CERT_KEYSTORE_PIN}" zipped.jar "${CERT_ALIAS}"
# Create the JNLP file with the appropriate contents.
echo "Creating JNLP file ${JNLP_FILENAME} ..."
# Create the Setup JNLP file with the appropriate contents.
echo "Creating Setup JNLP file ${INSTALL_JNLP_FILENAME} ..."
cd ..
cat > "${JNLP_FILENAME}" <<ENDOFJNLP
cat > "${INSTALL_JNLP_FILENAME}" <<ENDOFINSTALLJNLP
<?xml version="1.0" encoding="utf-8"?>
<!-- JNLP File for OpenDS Quick Setup Application -->
<jnlp spec="1.5+"
  codebase="${INSTALLER_URI}" href="${JNLP_FILENAME}">
  codebase="${INSTALLER_URI}" href="${INSTALL_JNLP_FILENAME}">
  <information>
    <title>OpenDS Quick Setup Application</title>
    <vendor>http://www.opends.org/</vendor>
@@ -187,8 +193,49 @@
  
  <application-desc main-class="org.opends.quicksetup.SplashScreen"/>
</jnlp>
ENDOFJNLP
ENDOFINSTALLJNLP
# Create the Upgrade JNLP file with the appropriate contents.
echo "Creating Upgrade JNLP file ${UPGRADE_JNLP_FILENAME} ..."
cat > "${UPGRADE_JNLP_FILENAME}" <<ENDOFUPGRADEJNLP
<?xml version="1.0" encoding="utf-8"?>
<!-- JNLP File for OpenDS Quick Upgrade Application -->
<jnlp spec="1.5+"
  codebase="${INSTALLER_URI}" href="${UPGRADE_JNLP_FILENAME}">
  <information>
    <title>OpenDS Quick Setup Application</title>
    <vendor>http://www.opends.org/</vendor>
    <homepage href="http://www.opends.org"/>
    <description>OpenDS Quick Upgrade Application</description>
    <description kind="short">OpenDS Web Start Upgrader</description>
    <icon href="images/opendshref.png" height="128" width="128"/>
    <icon kind="splash" href="images/opendssplash.png" height="114" width="479"/>
  </information>
  <security>
    <all-permissions/>
  </security>
  <resources>
    <j2se version="1.5+" java-vm-args="-client"/>
    <jar href="lib/quicksetup.jar" download="eager" main="true"/>
    <jar href="lib/OpenDS.jar" download="lazy"/>
    <jar href="lib/je.jar" download="lazy"/>
    <jar href="lib/aspectjrt.jar" download="lazy"/>
    <jar href="lib/zipped.jar" download="lazy"/>
    <property name="org.opends.quicksetup.iswebstart" value="true" />
    <property name="org.opends.quicksetup.Application.class" value="org.opends.quicksetup.upgrader.Upgrader"/>
    <property name="org.opends.quicksetup.lazyjarurls" value="${INSTALLER_URI}/lib/OpenDS.jar ${INSTALLER_URI}/lib/zipped.jar ${INSTALLER_URI}/lib/je.jar ${INSTALLER_URI}/lib/aspectjrt.jar" />
    <property name="org.opends.quicksetup.zipfilename" value="${ZIP_FILENAME_BASE}.zip"/>
  </resources>
  <resources os="AIX">
    <j2se version="1.5+"/>
  </resources>
  <application-desc main-class="org.opends.quicksetup.SplashScreen"/>
</jnlp>
ENDOFUPGRADEJNLP
# Tell the user where the files are.
echo "The deployable content may be found in ${ROOT_DIR}/build/webstart"
opends/src/quicksetup/org/opends/quicksetup/Installation.java
@@ -27,11 +27,10 @@
package org.opends.quicksetup;
import java.io.File;
import java.io.IOException;
import java.util.Set;
import java.util.Arrays;
import java.util.HashSet;
import java.io.*;
import java.util.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import org.opends.quicksetup.util.Utils;
@@ -245,6 +244,8 @@
  private Configuration baseConfiguration;
  private String buildId;
  /**
   * Creates a new instance from a root directory specified as a string.
   *
@@ -454,6 +455,46 @@
  }
  /**
   * Gets the build ID which is the 14 digit number code like 20070420110336.
   * @return String representing the build ID
   * @throws QuickSetupException if something goes wrong
   */
  public String getBuildId() throws QuickSetupException {
    if (buildId == null) {
      List<String> args = new ArrayList<String>();
      args.add(Utils.getPath(getServerStartCommandFile()));
      args.add("-V"); // verbose
      ProcessBuilder pb = new ProcessBuilder(args);
      InputStream is = null;
      try {
        Process process = pb.start();
        is = process.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        String line = null;
        Pattern p = Pattern.compile("(Build )(\\d{14})");
        while (null != (line = reader.readLine())) {
          Matcher m = p.matcher(line);
          if (m.matches()) {
            buildId = line.substring(m.start(2), m.end(2));
          }
        }
      } catch (IOException e) {
        throw new QuickSetupException(QuickSetupException.Type.START_ERROR,
                "Error attempting to determine build ID", e);
      } finally {
        if (is != null) {
          try {
            is.close();
          } catch (IOException e) {
            // ignore;
          }
        }
      }
    }
    return buildId;
  }
  /**
   * Returns the path to the configuration file of the directory server.  Note
   * that this method assumes that this code is being run locally.
   *
opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallReviewPanel.java
@@ -51,6 +51,7 @@
  private HashMap<FieldName, JTextComponent> hmFields =
      new HashMap<FieldName, JTextComponent>();
  private JCheckBox checkBox;
  /**
   * Constructor of the panel.
@@ -161,7 +162,7 @@
      JTextComponent field = UIFactory.makeJTextComponent(desc, null);
      field.setOpaque(false);
      JLabel label = makeJLabel(desc);
      JLabel label = UIFactory.makeJLabel(desc);
      hmFields.put(fieldName, field);
      label.setLabelFor(field);
@@ -313,4 +314,20 @@
    return panel;
  }
  /**
   * {@inheritDoc}
   */
  protected JCheckBox getCheckBox()
  {
    if (checkBox == null)
    {
      checkBox =
          UIFactory.makeJCheckBox(getMsg("start-server-label"),
              getMsg("start-server-tooltip"), UIFactory.TextStyle.CHECKBOX);
      checkBox.setOpaque(false);
      checkBox.setSelected(getApplication().getUserData().getStartServer());
    }
    return checkBox;
  }
}
opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties
@@ -685,6 +685,8 @@
summary-upgrade-not-started=Starting Upgrade...
summary-upgrade-initializing=Initializing Upgrade...
summary-upgrade-downloading=Downloading Build...
summary-upgrade-extracting=Extracting Build...
summary-upgrade-backing-up-db=Backing Up Data...
summary-upgrade-backing-up-files=Backing Up Files...
summary-upgrade-calculating-schema-customization=Calculating Schema \
@@ -825,19 +827,25 @@
# a language there is no translation to be done but if we have specific URL for
# each language the URL must be localized.
upgrade-welcome-panel-offline-instructions=The OpenDS Upgrade tool will upgrade \
  an existing build in place.<br><br> \
  an existing build in place.<br><br>You will be prompted to choose among a list \
  of available builds to which you can upgrade or you can specify an install\
  package (.zip) file that you have already downloaded.You can also use this tool to set up a build you have \
  downloaded manually.<br><br> \
  Additional information on this tool is available in the <a href="https://opends.dev.java.net/public/docs/index.html"> \
  Documentation Depot</a> section of OpenDS project web site.
  Documentation Depot</a> section of OpenDS project web site.<br><br>
upgrade-welcome-panel-webstart-instructions=The OpenDS Upgrade tool will upgrade \
  an existing build in place.<br><br>You can also use this tool to set up a build you have \
  downloaded manually. To run Upgrade in this case, use the {0} command at \
  the top level of the OpenDS directory.<br><br> \
  an existing build in place.<br><br>You will be prompted to choose among a list \
  of available builds to which you can upgrade or you can specify an install\
  package (.zip) file that you have already downloaded.You can also use this tool to set up a build you have \
  downloaded manually.<br><br> \
  Additional information on this tool is available in the <a href="https://opends.dev.java.net/public/docs/index.html"> \
  Documentation Depot</a> section of OpenDS project web site.<br><br>
upgrade-location-label=Server to Upgrade:
upgrade-location-tooltip=File system location of the build that will be upgraded
upgrade-build-id-label=Build Version:
upgrade-build-id-tooltip=The ID of the build version installed in the above location
upgrade-build-id-unknown=Unknown
error-invalid-server-location=Invalid server location: {0}
#
# Upgrader Choose Version Panel
@@ -851,9 +859,18 @@
upgrade-choose-version-remote-weekly=Weekly Builds
upgrade-choose-version-remote-nightly=Nightly Builds
upgrade-choose-version-local-label=Upgrade Based on Downloaded Weekly Build (.zip)
upgrade-choose-version-local-tooltip=Upgrade to a build whose .zip file you have\
upgrade-choose-version-local-tooltip=Upgrade to a build whose .zip file you have \
  already downloaded.
upgrade-choose-version-local-path=Path:
upgrade-choose-version-build-list-error=<b>Error Accessing Build Information.</b>\
  <br>Unable to retrieve the list of builds from {0} due to: {1}.<br>\
  Possible Causes:<br>\
  <ul><li>Need to specify a proxy.<br><table><tr><td>\
  <input value="Specify Proxy" type="submit"/></td><td>Current Proxy: {2}<td>\
  </tr></table><br></li><li>{0} \
  is down or experiencing difficulty.</li></ul><br>You can still continue with \
  upgrade but will need to download a build separately and then point to it in \
  the wizard.
upgrade-review-panel-title=Review
upgrade-review-panel-instructions=Review your settings and click Finish if they \
@@ -865,4 +882,5 @@
upgrade-review-panel-new-version-label=New Version:
upgrade-review-panel-new-version-tooltip=The target version of the server
upgrade-review-panel-start-server=Start Server when the Upgrade has Completed
upgrade-review-panel-start-server-tooltip=Check this check box if you want to \
  start the server once the upgrade has completed
opends/src/quicksetup/org/opends/quicksetup/ui/CustomHTMLEditorKit.java
@@ -40,7 +40,7 @@
/**
 * Class used to be able to detect events in the button inside an HTML pane.
 */
class CustomHTMLEditorKit extends HTMLEditorKit
public class CustomHTMLEditorKit extends HTMLEditorKit
{
  private HashSet<ActionListener> listeners = new HashSet<ActionListener>();
  private static final long serialVersionUID = 298103926252426388L;
@@ -48,7 +48,7 @@
  /**
   * Default constructor.
   */
  CustomHTMLEditorKit()
  public CustomHTMLEditorKit()
  {
    super();
  }
@@ -116,10 +116,16 @@
     */
    public void actionPerformed(ActionEvent ev)
    {
      for (ActionListener l: listeners)
      {
        l.actionPerformed(ev);
      if (ev != null && ev.getWhen() != lastActionWhen) {
        lastActionWhen = ev.getWhen();
        for (ActionListener l: listeners)
        {
          l.actionPerformed(ev);
        }
      }
    }
  }
  private static long lastActionWhen = 0;
}
opends/src/quicksetup/org/opends/quicksetup/ui/FieldName.java
@@ -41,6 +41,8 @@
{
  /**
   * The value associated with this is a String.
   * The upgrader uses this field to indicate the
   * location of the server to upgrade.
   */
  SERVER_LOCATION,
  /**
@@ -114,6 +116,29 @@
  /**
   * The value associated with this is a Set of String.
   */
  EXTERNAL_LOG_FILES
  EXTERNAL_LOG_FILES,
  /**
   * Indicates whether the upgrade will need to first download
   * an OpenDS install package (.zip) to download or the
   * upgrader will use a file that has already been
   * downloaded.  The value of this field is boolean and if
   * true must be accompanied by a value for UPGRADE_BUILD_TO_DOWNLOAD.
   * If false UPGRADE_FILE must be specified.
   */
  UPGRADE_DOWNLOAD,
  /**
   * Display name of the build to which the upgrader
   * will upgrade the build indicated by SERVER_LOCATION.
   */
  UPGRADE_BUILD_TO_DOWNLOAD,
  /**
   * Local OpenDS install package (.zip) file containing
   * a build to which the build indicated by SERVER_LOCATION
   * will be upgraded.
   */
  UPGRADE_FILE
}
opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupPanel.java
@@ -34,6 +34,7 @@
import javax.swing.JPanel;
import org.opends.quicksetup.i18n.ResourceProvider;
import org.opends.quicksetup.UserData;
/**
 * This class is an abstract class that provides some commodity methods.
@@ -92,6 +93,14 @@
  }
  /**
   * Gets the user data associated with the current application.
   * @return UserData user specified data
   */
  protected UserData getUserData() {
    return application.getUserData();
  }
  /**
   * Returns a localized message for a key value.  In  the properties file we
   * have something of type:
   * key=value
opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupStepPanel.java
@@ -304,25 +304,6 @@
  }
  /**
   * Commodity method that returns a JLabel based on a LabelFieldDescriptor.
   * @param desc the LabelFieldDescriptor describing the JLabel.
   * @return a JLabel based on a LabelFieldDescriptor.
   */
  protected JLabel makeJLabel(LabelFieldDescriptor desc)
  {
    UIFactory.TextStyle style;
    if (desc.getLabelType() == LabelFieldDescriptor.LabelType.PRIMARY)
    {
      style = UIFactory.TextStyle.PRIMARY_FIELD_VALID;
    } else
    {
      style = UIFactory.TextStyle.SECONDARY_FIELD_VALID;
    }
    return UIFactory.makeJLabel(UIFactory.IconType.NO_ICON, desc.getLabel(),
        style);
  }
  /**
   * Creates and returns the panel that contains the layout specific to the
   * panel.
   * @return the panel that contains the layout specific to the
opends/src/quicksetup/org/opends/quicksetup/ui/ReviewPanel.java
@@ -36,8 +36,6 @@
 */
public abstract class ReviewPanel extends QuickSetupStepPanel {
  private JCheckBox checkBox;
  /**
   * Creates an instance.
   * @param application GuiApplication this panel represents
@@ -57,8 +55,8 @@
   */
  final protected Component createInputPanel()
  {
    JPanel panel = new JPanel(new GridBagLayout());
    panel.setOpaque(false);
    JPanel panel = UIFactory.makeJPanel();
    panel.setLayout(new GridBagLayout());
    GridBagConstraints gbc = new GridBagConstraints();
@@ -70,10 +68,13 @@
    addVerticalGlue(panel);
    gbc.insets.top = UIFactory.TOP_INSET_PRIMARY_FIELD;
    gbc.weighty = 0.0;
    gbc.fill = GridBagConstraints.HORIZONTAL;
    panel.add(getCheckBox(), gbc);
    JCheckBox chk = getCheckBox();
    if (chk != null) {
      gbc.insets.top = UIFactory.TOP_INSET_PRIMARY_FIELD;
      gbc.weighty = 0.0;
      gbc.fill = GridBagConstraints.HORIZONTAL;
      panel.add(chk, gbc);
    }
    return panel;
  }
@@ -83,16 +84,5 @@
   * If it does not exist creates the start server check box.
   * @return the start server check box.
   */
  protected JCheckBox getCheckBox()
  {
    if (checkBox == null)
    {
      checkBox =
          UIFactory.makeJCheckBox(getMsg("start-server-label"),
              getMsg("start-server-tooltip"), UIFactory.TextStyle.CHECKBOX);
      checkBox.setOpaque(false);
      checkBox.setSelected(getApplication().getUserData().getStartServer());
    }
    return checkBox;
  }
  protected abstract JCheckBox getCheckBox();
}
opends/src/quicksetup/org/opends/quicksetup/ui/ServerSettingsPanel.java
@@ -450,7 +450,7 @@
      LabelFieldDescriptor desc = hm.get(fieldName);
      String defaultValue = getDefaultValue(fieldName);
      JLabel label = makeJLabel(desc);
      JLabel label = UIFactory.makeJLabel(desc);
      if (fieldName != FieldName.SECURITY_OPTIONS)
      {
@@ -473,7 +473,7 @@
            getMsg("server-location-parent-tooltip"),
            LabelFieldDescriptor.FieldType.TEXTFIELD,
            LabelFieldDescriptor.LabelType.PRIMARY, UIFactory.PATH_FIELD_SIZE);
    lServerLocation = makeJLabel(desc);
    lServerLocation = UIFactory.makeJLabel(desc);
    tfServerLocationParent = UIFactory.makeJTextComponent(desc, "");
    lServerLocation.setLabelFor(tfServerLocationParent);
opends/src/quicksetup/org/opends/quicksetup/ui/UIFactory.java
@@ -40,6 +40,7 @@
import javax.swing.*;
import javax.swing.text.JTextComponent;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.table.TableCellRenderer;
@@ -460,7 +461,7 @@
  /**
   * Specifies the font for the text in the WebBrowserErrorDialog.
   */
  public static final Font BROWSER_ERROR_DIALOG_FONT =
  public static final Font ERROR_DIALOG_FONT =
      Font.decode("Arial-PLAIN-12");
  private static final String SPAN_CLOSE = "</span>";
@@ -655,11 +656,24 @@
  }
  /**
   * Creates a new JPanel.
   * @return JPanel newly created
   */
  public static JPanel makeJPanel() {
    JPanel pnl = new JPanel();
    pnl.setOpaque(false);
    return pnl;
  }
  /**
   * Creates a JComboBox.
   * @return JComboBox a new combo box
   */
  static public JComboBox makeJComboBox() {
    return new JComboBox();
    JComboBox cbo = new JComboBox();
    cbo.setOpaque(true);
    cbo.setBackground(Color.WHITE);
    return cbo;
  }
  /**
@@ -1037,8 +1051,25 @@
   */
  public static JEditorPane makeHtmlPane(String text, Font font)
  {
    JEditorPane pane =
        new JEditorPane("text/html", applyFontToHtmlWithDiv(text, font));
    return makeHtmlPane(text, null, font);
  }
  /**
   * Returns a read only JEditorPane containing the provided text with the
   * provided font.  The JEditorPane will assume that the text is HTML text.
   * @param text the text to be used to initialize the JEditorPane contents.
   * @param ek HTMLEditor kit used for the new HTML pane
   * @param font the font to be used.
   * @return a read only JEditorPane containing the provided text with the
   * provided font.
   */
  public static JEditorPane makeHtmlPane(String text, HTMLEditorKit ek,
                                         Font font)
  {
    JEditorPane pane = new JEditorPane();
    if (ek != null) pane.setEditorKit(ek);
    pane.setContentType("text/html");
    pane.setText(applyFontToHtmlWithDiv(text, font));
    pane.setEditable(false);
    pane.setBorder(new EmptyBorder(0, 0, 0, 0));
    return pane;
opends/src/quicksetup/org/opends/quicksetup/ui/Utilities.java
@@ -49,8 +49,9 @@
  {
    GridBagConstraints gbc = new GridBagConstraints();
    JPanel panel = new JPanel(new GridBagLayout());
    panel.setOpaque(false);
    JPanel panel = UIFactory.makeJPanel();
    panel.setLayout(new GridBagLayout());
    gbc.insets = UIFactory.getEmptyInsets();
    gbc.gridwidth = 4;
    gbc.weightx = 0.0;
opends/src/quicksetup/org/opends/quicksetup/ui/WebBrowserErrorDialog.java
@@ -134,7 +134,7 @@
      { url });
    JTextComponent tf =
        UIFactory.makeHtmlPane(msg,
            UIFactory.BROWSER_ERROR_DIALOG_FONT);
            UIFactory.ERROR_DIALOG_FONT);
    tf.setOpaque(false);
    tf.setEditable(false);
    p1.add(tf, gbc);
opends/src/quicksetup/org/opends/quicksetup/ui/WebProxyDialog.java
New file
@@ -0,0 +1,392 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.quicksetup.ui;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
import java.util.Properties;
import java.net.SocketAddress;
import java.net.InetSocketAddress;
/**
 * Dialog allowing the user to specify a host, port, user name and passoword
 * for accessing a web proxy.
 */
public class WebProxyDialog extends JDialog
        implements PropertyChangeListener, ActionListener {
  private static final long serialVersionUID = 4402474441754399992L;
  private JTextField tfHost;
  private JTextField tfPort;
  private JCheckBox chkRequiresAuth;
  private JTextField tfUserName;
  private JPasswordField tfPassword;
  private JOptionPane optionPane;
  /**
   * Creates an instance loading values from system properties.
   * @param parent of this dialog
   */
  public WebProxyDialog(Frame parent) {
    this(parent, null, null, null, null);
    loadSystemProperties();
  }
  /**
   * Creates an instance loading values from system properties.
   * @param parent of this dialog
   */
  public WebProxyDialog(Dialog parent) {
    this(parent, null, null, null, null);
    loadSystemProperties();
  }
  /**
   * Creates an instance.
   * @param parent of this dialog
   * @param host default value for host field
   * @param port default value for port field
   * @param user default value for user field
   * @param pw default value for password field
   */
  public WebProxyDialog(Frame parent, String host, Integer port,
                        String user, char[] pw) {
    super(parent, /*modal=*/true);
    init(host, port, user, pw);
  }
  /**
   * Creates an instance.
   * @param parent of this dialog
   * @param host default value for host field
   * @param port default value for port field
   * @param user default value for user field
   * @param pw default value for password field
   */
  public WebProxyDialog(Dialog parent, String host, Integer port,
                        String user, char[] pw) {
    super(parent, /*modal=*/true);
    init(host, port, user, pw);
  }
  private void init(String host, Integer port, String user, char[] pw) {
    setTitle("Proxy Configuration");
    optionPane = createContentPane(host, port, user, pw);
    optionPane.addPropertyChangeListener(this);
    setContentPane(optionPane);
    setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    //Ensure the text field always gets the first focus.
    addComponentListener(new ComponentAdapter() {
      public void componentShown(ComponentEvent ce) {
        tfHost.requestFocusInWindow();
      }
    });
    pack();
  }
  /**
   * Creates a SocketAddress from current data.
   * @return newly created SocketAddress from the current value of the
   * host and port fields
   */
  public SocketAddress getSocketAddress() {
    SocketAddress addr = null;
    String host = getHost();
    Integer port = getPort();
    if (host != null && port != null) {
      addr = new InetSocketAddress(host, port);
    }
    return addr;
  }
  private JOptionPane createContentPane(String host, Integer port,
                                        String user, char[] pw) {
    JOptionPane pane = new JOptionPane(createPanel(host, port, user, pw),
            JOptionPane.INFORMATION_MESSAGE,
            JOptionPane.OK_CANCEL_OPTION);
    return pane;
  }
  /**
   * {@inheritDoc}
   */
  public void propertyChange(PropertyChangeEvent e) {
    String prop = e.getPropertyName();
    if (isVisible()
            && (e.getSource() == optionPane)
            && (JOptionPane.VALUE_PROPERTY.equals(prop) ||
            JOptionPane.INPUT_VALUE_PROPERTY.equals(prop))) {
      Object value = optionPane.getValue();
      if (value == JOptionPane.UNINITIALIZED_VALUE) {
        //ignore reset
        return;
      }
      //Reset the JOptionPane's value.
      //If you don't do this, then if the user
      //presses the same button next time, no
      //property change event will be fired.
      optionPane.setValue(
              JOptionPane.UNINITIALIZED_VALUE);
      if (value.equals(JOptionPane.OK_OPTION)) {
        if (validateUserData()) {
          setVisible(false);
        }
      } else if (value.equals(JOptionPane.CANCEL_OPTION)) {
        setVisible(false);
      }
    }
  }
  /**
   * {@inheritDoc}
   */
  public void actionPerformed(ActionEvent actionEvent) {
    optionPane.setValue(JOptionPane.OK_OPTION);
  }
  /**
   * Gets the current value of the host field.
   * @return String representing the host value
   */
  public String getHost() {
    String v = tfHost.getText();
    if (v != null && v.trim().length() == 0) v = null;
    return v;
  }
  /**
   * Gets the current value of the port field.
   * @return String representing the port value
   */
  public Integer getPort() {
    Integer i = null;
    String v = tfPort.getText();
    if (v != null && v.trim().length() == 0) v = null;
    try {
      i = Integer.parseInt(v);
    } catch (NumberFormatException e) {
      // do nothing;
    }
    return i;
  }
  /**
   * Gets the current value of the user field.
   * @return String representing the user value
   */
  public String getUserName() {
    String v = tfUserName.getText();
    if ((v != null && v.trim().length() == 0) ||
          !chkRequiresAuth.isSelected()) v = null;
    return v;
  }
  /**
   * Gets the current value of the password field.
   * @return char[] representing the password value
   */
  public char[] getPassword() {
    char[] v = tfPassword.getPassword();
    if ((v != null && v.length == 0) ||
          !chkRequiresAuth.isSelected()) v = null;
    return v;
  }
  /**
   * Writes the current values to system properties.
   */
  public void applySystemProperties() {
    Properties systemSettings = System.getProperties();
    String v = tfHost.getText();
    if (v != null && v.trim().length() == 0) v = null;
    systemSettings.put("http.proxyHost", v);
    systemSettings.put("https.proxyHost", v);
    v = tfPort.getText();
    if (v != null && v.trim().length() == 0) v = null;
    systemSettings.put("http.proxyPort", v);
    systemSettings.put("https.proxyPort", v);
    System.setProperties(systemSettings);
  }
  private void loadSystemProperties() {
    Properties systemSettings = System.getProperties();
    Object v = systemSettings.get("http.proxyHost");
    tfHost.setText(v != null ? v.toString() : "");
    v = systemSettings.get("http.proxyPort");
    tfPort.setText(v != null ? v.toString() : "");
  }
  private JPanel createPanel(String host, Integer port,
                             String user, char[] pw) {
    JPanel p = new JPanel();
    p.setLayout(new GridBagLayout());
    GridBagConstraints gbc = new GridBagConstraints();
    final JLabel lblUser = UIFactory.makeJLabel(null, "User:",
            UIFactory.TextStyle.SECONDARY_FIELD_VALID);
    final JLabel lblPassword = UIFactory.makeJLabel(null, "Password:",
            UIFactory.TextStyle.SECONDARY_FIELD_VALID);
    gbc.gridx = 0;
    gbc.gridy = 0;
    gbc.anchor = GridBagConstraints.FIRST_LINE_START;
    gbc.fill = GridBagConstraints.NONE;
    p.add(new JLabel("Proxy Host:"), gbc);
    gbc.gridx = 1;
    gbc.gridy = 0;
    gbc.fill = GridBagConstraints.HORIZONTAL;
    gbc.weightx = 1.0;
    p.add(tfHost = new JTextField(host), gbc);
    gbc.gridx = 0;
    gbc.gridy = 1;
    gbc.weightx = 0;
    gbc.fill = GridBagConstraints.NONE;
    p.add(new JLabel("Proxy Port:"), gbc);
    gbc.gridx = 1;
    gbc.gridy = 1;
    gbc.fill = GridBagConstraints.HORIZONTAL;
    p.add(tfPort = new JTextField(port != null?port.toString():""), gbc);
    gbc.gridx = 0;
    gbc.gridy = 2;
    gbc.weightx = 0;
    gbc.fill = GridBagConstraints.NONE;
    gbc.insets.top = 7; // I don't understand why this is necesary
    p.add(new JLabel("Auhentication:"), gbc);
    gbc.gridx = 1;
    gbc.gridy = 2;
    gbc.fill = GridBagConstraints.HORIZONTAL;
    gbc.insets.top = 0;
    p.add(chkRequiresAuth = new JCheckBox("Required by proxy"), gbc);
    chkRequiresAuth.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent actionEvent) {
        tfUserName.setEnabled(chkRequiresAuth.isSelected());
        tfPassword.setEnabled(chkRequiresAuth.isSelected());
        lblUser.setEnabled(chkRequiresAuth.isSelected());
        lblPassword.setEnabled(chkRequiresAuth.isSelected());
      }
    });
    gbc.gridx = 0;
    gbc.gridy = 3;
    gbc.gridwidth = 1;
    gbc.fill = GridBagConstraints.NONE;
    gbc.insets.left = UIFactory.LEFT_INSET_SECONDARY_FIELD;
    p.add(lblUser, gbc);
    gbc.gridx = 1;
    gbc.gridy = 3;
    gbc.fill = GridBagConstraints.HORIZONTAL;
    gbc.insets.left = 0;
    p.add(tfUserName = new JTextField(user), gbc);
    gbc.gridx = 0;
    gbc.gridy = 4;
    gbc.fill = GridBagConstraints.NONE;
    gbc.insets.left = UIFactory.LEFT_INSET_SECONDARY_FIELD;
    p.add(lblPassword, gbc);
    gbc.gridx = 1;
    gbc.gridy = 4;
    gbc.fill = GridBagConstraints.HORIZONTAL;
    gbc.insets.left = 0;
    gbc.weighty = 1.0;
    p.add(tfPassword = new JPasswordField(pw != null ? new String(pw) : ""),
            gbc);
    // By default, proxy does not require auth
    chkRequiresAuth.setSelected(false);
    tfUserName.setEnabled(false);
    tfPassword.setEnabled(false);
    lblPassword.setEnabled(false);
    lblUser.setEnabled(false);
    // For automatic closure
    tfHost.addActionListener(this);
    tfPort.addActionListener(this);
    tfUserName.addActionListener(this);
    tfPassword.addActionListener(this);
    return p;
  }
  private boolean validateUserData() {
    String errorMsg = null;
    String portString = tfPort.getText();
    //TODO better port number verification
    try {
      Integer.parseInt(portString);
    } catch (NumberFormatException e) {
      errorMsg = "Illegal port value " + portString;
    }
    if (errorMsg != null) {
      JOptionPane.showMessageDialog(this, errorMsg);
    }
    return (errorMsg == null);
  }
//  /**
//   * For testing.
//   * @param args cl args
//   */
//  public static void main(String[] args) {
//    JDialog dlg = new WebProxyDialog(new JFrame());
//    dlg.addComponentListener(new ComponentAdapter() {
//      public void componentHidden(ComponentEvent componentEvent) {
//        System.exit(0);
//      }
//    });
//    dlg.setVisible(true);
//  }
}
opends/src/quicksetup/org/opends/quicksetup/upgrader/Build.java
New file
@@ -0,0 +1,81 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.quicksetup.upgrader;
import java.net.URL;
/**
   * Representation of an OpenDS build package.
 */
public class Build {
  private URL url;
  private String id;
  /**
   * Creates an instance.
   * @param url where the build package can be accessed
   * @param id of the new build
   */
  Build(URL url, String id) {
    this.url = url;
    this.id = id;
  }
  /**
   * Gets the URL where the build can be accessed.
   * @return URL representing access to the build package
   */
  public URL getUrl() {
    return url;
  }
  /**
   * Gets the builds ID number, a 14 digit number representing the time
   * the build was created.
   * @return String represenging the build
   */
  public String getId() {
    return id;
  }
  /**
   * Gets a string appropriate for presentation to a user.
   * @return String representing this build
   */
  public String getDisplayName() {
    return getId();
  }
  /**
   * {@inheritDoc}
   */
  public String toString() {
    return getDisplayName();
  }
}
opends/src/quicksetup/org/opends/quicksetup/upgrader/RemoteBuildManager.java
@@ -29,14 +29,17 @@
import org.opends.quicksetup.Application;
import javax.swing.*;
import java.net.URL;
import java.net.Proxy;
import java.net.URLConnection;
import java.util.*;
import java.util.List;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.logging.Logger;
import java.io.*;
import java.awt.*;
/**
 * Manages listing and retreival of build packages on a remote host.
@@ -51,54 +54,27 @@
   */
  enum BuildType {
    /**
     * Nightly build descriptor.
     */
    NIGHTLY,
    /**
     * Weekly build descriptor.
     */
    WEEKLY
  }
  /**
   * Representation of an OpenDS build package.
   */
  public class Build {
    private URL url;
    private String id;
    /**
     * Creates an instance.
     * @param url where the build package can be accessed
     * @param id of the new build
     */
    Build(URL url, String id) {
      this.url = url;
      this.id = id;
    }
    /**
     * Gets the URL where the build can be accessed.
     * @return URL representing access to the build package
     */
    public URL getUrl() {
      return url;
    }
    /**
     * Gets the builds ID number, a 14 digit number representing the time
     * the build was created.
     * @return String represenging the build
     */
    public String getId() {
      return id;
    }
  }
  private Application app;
  private URL url;
  private Proxy proxy;
  private URL url;
  private String proxyUserName;
  private char[] proxyPw;
  /**
   * Creates an instance.
@@ -111,14 +87,36 @@
  }
  /**
   * Gets the base context where the build information is stored.
   * @return URL representing base context of the build repo
   */
  public URL getBaseContext() {
    return this.url;
  }
  /**
   * Gets a list of builds found in the remote repository.
   * @return List of Build objects representing remote builds
   * @throws IOException if there was a problem contacting the build
   * repository
   */
  public List<Build> listBuilds() throws IOException {
    return listBuilds(null, null);
  }
  /**
   * Gets the list of builds from the build repository using a
   * progress monitor to keep the user informed about the status
   * of downloading the build page.
   * @param c Component to act as parent of the progress monitor
   * @param o message to display in the progress monitor
   * @return list of Build objects
   * @throws IOException if something goes wrong loading the list
   * from the build repository
   */
  public List<Build> listBuilds(Component c, Object o) throws IOException {
    List<Build> buildList = new ArrayList<Build>();
    String dailyBuildsPage = getDailyBuildsPage();
    String dailyBuildsPage = downloadDailyBuildsPage(c, o);
    Pattern p = Pattern.compile("\\d{14}");
    Matcher m = p.matcher(dailyBuildsPage);
    Set<String> buildIds = new HashSet<String>();
@@ -131,7 +129,9 @@
    return buildList;
  }
  private String getDailyBuildsPage() throws IOException {
  private String downloadDailyBuildsPage(Component c, Object o)
          throws IOException
  {
    URL dailyBuildsUrl = new URL(url, "daily-builds");
    URLConnection conn;
    if (proxy == null) {
@@ -139,7 +139,21 @@
    } else {
      conn = dailyBuildsUrl.openConnection(proxy);
    }
    InputStream in = conn.getInputStream();
    String proxyAuthString = createProxyAuthString();
    if (proxyAuthString != null) {
      conn.setRequestProperty("Proxy-Authorization", "Basic " +
              proxyAuthString);
    }
    InputStream in;
    if (c != null) {
      ProgressMonitorInputStream pmis =
              new ProgressMonitorInputStream(c, o, conn.getInputStream());
      ProgressMonitor pm = pmis.getProgressMonitor();
      pm.setMillisToDecideToPopup(0);
      in = pmis;
    } else {
      in = conn.getInputStream();
    }
    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
    StringBuilder builder = new StringBuilder();
    String line;
@@ -154,30 +168,146 @@
   * location on the local file system.
   * @param build to download
   * @param destination directory for the newly downloaded file
   * @throws IOException if the build could not be downloaded
   */
  public void download(Build build, File destination) {
  public void download(Build build, File destination) throws IOException {
    download(build.getUrl(), destination);
  }
  private void download(URL url, File destination) throws IOException {
    URLConnection conn = null;
    if (proxy == null) {
      conn = url.openConnection();
    } else {
      conn = url.openConnection(proxy);
    }
    String proxyAuthString = createProxyAuthString();
    if (proxyAuthString != null) {
      conn.setRequestProperty("Proxy-Authorization", "Basic " +
              proxyAuthString);
    }
    InputStream is = null;
    FileOutputStream fos = null;
    try {
      is = conn.getInputStream();
      fos = new FileOutputStream(destination);
      int i = 0;
      int bytesRead = 0;
      byte[] buf = new byte[1024];
      while ((i = is.read(buf)) != -1) {
        fos.write(buf, 0, i);
        bytesRead += i;
      }
    } finally {
      if (is != null) {
        is.close();
      }
      if (fos != null) {
        fos.close();
      }
    }
  }
  /**
   * Sets the proxy object this class will use when establishing network
   * connections.
   * @param proxy to use when establishing connections
   */
  public void setProxy(Proxy proxy) {
    this.proxy = proxy;
  }
  /**
   * Gets the proxy object this class uses when establishing network
   * connections.
   * @return Proxy to use when establishing connections
   */
  public Proxy getProxy() {
    return this.proxy;
  }
  /**
   * Sets the user name this class will use to authenticate to its
   * proxy when establishing network connections.
   * @param user this class is acting on behalf of
   */
  public void setProxyUserName(String user) {
    this.proxyUserName = user;
  }
  /**
   * Sets the user name this class will use to authenticate to its
   * proxy when establishing network connections.
   * @return String representing the name of the user of which this class is
   * acting on behalf
   */
  public String getProxyUserName() {
    return this.proxyUserName;
  }
  /**
   * Sets the password this class will use to authenticate to its
   * proxy when establishing network connections.
   * @param pw char[] representing the password of the user of which this class
   * is acting on behalf
   */
  public void setProxyPassword(char[] pw) {
    this.proxyPw = pw;
  }
  /**
   * Sets the password this class will use to authenticate to its
   * proxy when establishing network connections.
   * @return char[] representing the password of the user of which this class is
   * acting on behalf
   */
  public char[] getProxyPassword() {
    return this.proxyPw;
  }
  private String createProxyAuthString() {
    return createAuthenticationString(getProxyUserName(), getProxyPassword());
  }
  static private String createAuthenticationString(String user, char[] pw) {
    String s = null;
    if (user != null && pw != null) {
      StringBuilder sb = new StringBuilder()
              .append(user)
              .append(":")
              .append(pw);
      s = org.opends.server.util.Base64.encode(sb.toString().getBytes());
    }
    return s;
  }
  /**
   * For testing only.
   * @param args command line arguments
   */
  public static void main(String[] args) {
    try {
      Properties systemSettings = System.getProperties();
      systemSettings.put("http.proxyHost", "webcache.central.sun.com");
      systemSettings.put("http.proxyPort", "8080");
      System.setProperties(systemSettings);
      URL url = new URL("http://builds.opends.org");
      RemoteBuildManager rbm = new RemoteBuildManager(null, url);
      List<Build> builds = rbm.listBuilds();
      for (Build build : builds) {
        System.out.println("build " + build.getId());
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
//  public static void main(String[] args) {
//    try {
//      Properties systemSettings = System.getProperties();
//      systemSettings.put("http.proxyHost", "webcache.central.sun.com");
//      systemSettings.put("http.proxyPort", "8080");
//      systemSettings.put("https.proxyHost", "webcache.central.sun.com");
//      systemSettings.put("https.proxyPort", "8080");
//
//      System.setProperties(systemSettings);
//
//      URL url = new URL("http://builds.opends.org");
//      RemoteBuildManager rbm = new RemoteBuildManager(null, url);
//      //List<Build> builds = rbm.listBuilds();
//      //for (Build build : builds) {
//      //  System.out.println("build " + build);
//      //}
//      rbm.download(new URL("https://opends.dev.java.net/" +
//              "files/documents/4926/55351/OpenDS-0.1-build035.zip"),
//              new File("/tmp/OpenDS-xxx.zip"));
//    } catch (IOException e) {
//      e.printStackTrace();
//    }
//
//  }
  }
}
opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeUserData.java
@@ -38,6 +38,8 @@
  File installPackage;
  Build buildToDownload;
  /**
   * Gets the OpenDS package (.zip) file whose contents will
   * be used in the upgrade/reversion.
@@ -56,4 +58,22 @@
    this.installPackage = installPackage;
  }
  /**
   * Gets the Build that will need to be downloaded before
   * the upgrade can begin.
   * @return Build representing the build to download
   */
  public Build getInstallPackageToDownload() {
    return buildToDownload;
  }
  /**
   * Sets the Build that will need to be downloaded before
   * the upgrade can begin.
   * @param build Build to download
   */
  public void setBuildToDownload(Build build) {
    this.buildToDownload = build;
  }
}
opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java
@@ -34,6 +34,7 @@
import org.opends.quicksetup.util.Utils;
import org.opends.quicksetup.util.FileManager;
import org.opends.quicksetup.util.ServerController;
import org.opends.quicksetup.util.ZipExtractor;
import org.opends.quicksetup.ui.*;
import org.opends.server.tools.BackUpDB;
import org.opends.server.tools.LDIFDiff;
@@ -49,6 +50,8 @@
import java.util.logging.Level;
import java.util.logging.Logger;
import java.io.*;
import java.net.URL;
import java.net.MalformedURLException;
import static org.opends.quicksetup.Installation.*;
@@ -92,6 +95,10 @@
    NOT_STARTED("summary-upgrade-not-started"),
    DOWNLOADING("summary-upgrade-downloading"),
    EXTRACTING("summary-upgrade-extracting"),
    INITIALIZING("summary-upgrade-initializing"),
    STARTING_SERVER("summary-starting"),
@@ -203,6 +210,8 @@
  /** SVN rev number of the build in the stage directory. */
  private Integer stagedVersion = null;
  private RemoteBuildManager remoteBuildManager = null;
  /**
   * {@inheritDoc}
   */
@@ -227,6 +236,26 @@
  }
  /**
   * Gets a remote build manager that this class can use to find
   * out about and download builds for upgrading.
   * @return RemoteBuildManager to use for builds
   */
  public RemoteBuildManager getRemoteBuildManager() {
    if (remoteBuildManager == null) {
      try {
        // TODO: make this configurable.
        // The slash at the end of the URL was/is important in getting the
        // correct redirection from the web server
        URL buildRepo = new URL("http://builds.opends.org/");
        remoteBuildManager = new RemoteBuildManager(this, buildRepo);
      } catch (MalformedURLException e) {
        LOG.log(Level.INFO, "error", e);
      }
    }
    return remoteBuildManager;
  }
  /**
   * {@inheritDoc}
   */
  protected String getInstallationPath() {
@@ -236,9 +265,20 @@
    // we still want the Installation to point at the build being
    // upgraded so the install path reported in [installroot].
    String stagePath = Utils.getInstallPathFromClasspath();
    File f = new File(stagePath);
    return Utils.getPath(f.getParentFile().getParentFile());
    String installationPath = null;
    String path = Utils.getInstallPathFromClasspath();
    if (path != null) {
      File f = new File(path);
      if (f.getParentFile() != null &&
              f.getParentFile().getParentFile() != null &&
              new File(f.getParentFile().getParentFile(),
                      Installation.LOCKS_PATH_RELATIVE).exists()) {
        installationPath = Utils.getPath(f.getParentFile().getParentFile());
      } else {
        installationPath = path;
      }
    }
    return installationPath;
  }
  /**
@@ -352,6 +392,60 @@
   */
  public void updateUserData(WizardStep cStep, QuickSetup qs)
          throws UserDataException {
    List<String> errorMsgs = new ArrayList<String>();
    UpgradeUserData uud = getUpgradeUserData();
    if (cStep == UpgradeWizardStep.WELCOME) {
      // User can only select the installation to upgrade
      // in the webstart version of this tool.  Otherwise
      // the fields are readonly.
      if (Utils.isWebStart()) {
        String serverLocationString =
                qs.getFieldStringValue(FieldName.SERVER_LOCATION);
        if ((serverLocationString == null) ||
                ("".equals(serverLocationString.trim()))) {
          errorMsgs.add(getMsg("empty-server-location"));
          qs.displayFieldInvalid(FieldName.SERVER_LOCATION, true);
        } else {
          try {
            File serverLocation = new File(serverLocationString);
            Installation.validateRootDirectory(serverLocation);
            // If we get here the value is acceptable
            Installation installation = new Installation(serverLocation);
            setInstallation(installation);
            uud.setServerLocation(serverLocationString);
          } catch (IllegalArgumentException iae) {
            errorMsgs.add(getMsg("error-invalid-server-location",
                    iae.getLocalizedMessage()));
            qs.displayFieldInvalid(FieldName.SERVER_LOCATION, true);
          }
        }
      } else {
        // do nothing; all fields are read-only
      }
    } else if (cStep == UpgradeWizardStep.CHOOSE_VERSION) {
      Build buildToDownload = null;
      File buildFile = null;
      Boolean downloadFirst =
              (Boolean)qs.getFieldValue(FieldName.UPGRADE_DOWNLOAD);
      if (downloadFirst) {
        buildToDownload =
                (Build)qs.getFieldValue(FieldName.UPGRADE_BUILD_TO_DOWNLOAD);
      } else {
        buildFile = (File)qs.getFieldValue(FieldName.UPGRADE_FILE);
      }
      uud.setBuildToDownload(buildToDownload);
      uud.setInstallPackage(buildFile);
    }
    if (errorMsgs.size() > 0) {
      throw new UserDataException(Step.SERVER_SETTINGS,
          Utils.getStringFromCollection(errorMsgs, "\n"));
    }
  }
  /**
@@ -402,6 +496,51 @@
    runException = null;
    try {
      File buildZip;
      Build buildToDownload =
              getUpgradeUserData().getInstallPackageToDownload();
      if (buildToDownload != null) {
        try {
          setCurrentProgressStep(UpgradeProgressStep.DOWNLOADING);
          buildZip = new File(getStageDirectory(), "OpenDS.zip");
          if (buildZip.exists()) {
            if (!buildZip.delete()) {
              throw ApplicationException.createFileSystemException(
                      "Could not delete existing build file " +
                              Utils.getPath(buildZip), null);
            }
          }
          getRemoteBuildManager().download(buildToDownload, buildZip);
        } catch (ApplicationException e) {
          LOG.log(Level.INFO, "Error downloading build file", e);
          throw e;
        }
      } else {
        buildZip = getUpgradeUserData().getInstallPackage();
      }
      if (buildZip != null) {
        try {
          setCurrentProgressStep(UpgradeProgressStep.EXTRACTING);
          ZipExtractor extractor = new ZipExtractor(buildZip,
                  1, 10, // TODO figure out these values
                  Utils.getNumberZipEntries(), this);
          extractor.extract(getStageDirectory());
        } catch (ApplicationException e) {
          LOG.log(Level.INFO, "Error extracting build file", e);
          throw e;
        }
      }
      try {
        setCurrentProgressStep(UpgradeProgressStep.INITIALIZING);
        initialize();
      } catch (ApplicationException e) {
        LOG.log(Level.INFO, "Error initializing upgrader", e);
        throw e;
      }
      try {
        setCurrentProgressStep(UpgradeProgressStep.INITIALIZING);
        initialize();
@@ -1062,6 +1201,19 @@
  /**
   * {@inheritDoc}
   */
  public UserData createUserData() {
    UpgradeUserData uud = new UpgradeUserData();
    String instanceRootFromSystem =
            System.getProperty("org.opends.quicksetup.upgrader.Root");
    if (instanceRootFromSystem != null) {
      uud.setServerLocation(instanceRootFromSystem);
    }
    return uud;
  }
  /**
   * {@inheritDoc}
   */
  public UserData createUserData(String[] args, CurrentInstallStatus cis)
          throws UserDataException {
    return getCliHelper().createUserData(args, cis);
opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/ChooseVersionPanel.java
@@ -27,23 +27,52 @@
package org.opends.quicksetup.upgrader.ui;
import org.opends.quicksetup.UserData;
import org.opends.quicksetup.ui.CustomHTMLEditorKit;
import org.opends.quicksetup.ui.FieldName;
import org.opends.quicksetup.ui.GuiApplication;
import org.opends.quicksetup.ui.QuickSetupStepPanel;
import org.opends.quicksetup.ui.UIFactory;
import org.opends.quicksetup.ui.Utilities;
import org.opends.quicksetup.ui.GuiApplication;
import org.opends.quicksetup.ui.WebProxyDialog;
import org.opends.quicksetup.upgrader.Build;
import org.opends.quicksetup.upgrader.RemoteBuildManager;
import org.opends.quicksetup.upgrader.Upgrader;
import org.opends.quicksetup.util.BackgroundTask;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.SocketAddress;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
 * This panel allows the user to select a remote or local build for upgrade.
 */
public class ChooseVersionPanel extends QuickSetupStepPanel {
  private static final long serialVersionUID = -6941309163077121917L;
  static private final Logger LOG =
          Logger.getLogger(ChooseVersionPanel.class.getName());
  static private final long serialVersionUID = -6941309163077121917L;
  private JRadioButton rbRemote = null;
  private JRadioButton rbLocal = null;
  private ButtonGroup grpRemoteLocal = null;
  private JComboBox cboBuild = null;
  private JTextField tfFile = null;
  private boolean loadBuildListAttempted = false;
  /**
   * Creates an instance.
   *
   * @param application this panel represents.
   */
  public ChooseVersionPanel(GuiApplication application) {
@@ -53,33 +82,63 @@
  /**
   * {@inheritDoc}
   */
  public void beginDisplay(UserData data) {
    super.beginDisplay(data);
    if (!loadBuildListAttempted) {
      loadBuildList();
    }
  }
  /**
   * {@inheritDoc}
   */
  public Object getFieldValue(FieldName fieldName) {
    Object value = null;
    if (FieldName.UPGRADE_DOWNLOAD.equals(fieldName)) {
      value = new Boolean(rbRemote.isSelected());
    } else if (FieldName.UPGRADE_BUILD_TO_DOWNLOAD.equals(fieldName)) {
      value = cboBuild.getSelectedItem();
    } else if (FieldName.UPGRADE_FILE.equals(fieldName)) {
      value = new File(tfFile.getText());
    }
    return value;
  }
  /**
   * {@inheritDoc}
   */
  protected Component createInputPanel() {
    Component c;
    JPanel p = new JPanel();
    JPanel p = UIFactory.makeJPanel();
    JRadioButton rbRemote = UIFactory.makeJRadioButton(
    rbRemote = UIFactory.makeJRadioButton(
            getMsg("upgrade-choose-version-remote-label"),
            getMsg("upgrade-choose-version-remote-tooltip"),
            UIFactory.TextStyle.SECONDARY_FIELD_VALID);
    JRadioButton rbLocal = UIFactory.makeJRadioButton(
    rbLocal = UIFactory.makeJRadioButton(
            getMsg("upgrade-choose-version-local-label"),
            getMsg("upgrade-choose-version-local-tooltip"),
            UIFactory.TextStyle.SECONDARY_FIELD_VALID);
    JComboBox cboBuild = UIFactory.makeJComboBox();
    cboBuild.setModel(createBuildComboBoxModel());
    grpRemoteLocal = new ButtonGroup();
    grpRemoteLocal.add(rbRemote);
    grpRemoteLocal.add(rbLocal);
    grpRemoteLocal.setSelected(rbRemote.getModel(), true);
    cboBuild = UIFactory.makeJComboBox();
    cboBuild.setEditable(false);
    // TODO: use UIFactory
    JTextField tfBuild = new JTextField();
    tfBuild.setColumns(20);
    tfFile = new JTextField();
    tfFile.setColumns(20);
    JPanel pnlBrowse = Utilities.createBrowseButtonPanel(
            UIFactory.makeJLabel(null,
                    getMsg("upgrade-choose-version-local-path"),
                    UIFactory.TextStyle.SECONDARY_FIELD_VALID),
            tfBuild,
            tfFile,
            UIFactory.makeJButton(getMsg("browse-button-label"),
                    getMsg("browse-button-tooltip")));
@@ -113,7 +172,7 @@
    gbc.anchor = GridBagConstraints.CENTER;
    gbc.fill = GridBagConstraints.HORIZONTAL;
    gbc.insets = UIFactory.getEmptyInsets();
    JPanel fill = new JPanel();
    JPanel fill = UIFactory.makeJPanel();
    // fill.setBorder(BorderFactory.createLineBorder(Color.BLUE));
    p.add(fill, gbc);
@@ -134,11 +193,10 @@
    gbc.weightx = 1.0;
    gbc.fill = GridBagConstraints.BOTH;
    gbc.anchor = GridBagConstraints.LINE_START;
    JPanel fill2 = new JPanel();
    JPanel fill2 = UIFactory.makeJPanel();
    //fill.setBorder(BorderFactory.createLineBorder(Color.BLUE));
    p.add(fill2, gbc);
    c = p;
    return c;
  }
@@ -157,10 +215,243 @@
    return getMsg("upgrade-choose-version-panel-instructions");
  }
  private ComboBoxModel createBuildComboBoxModel() {
    // TODO:  populate a list model with builds.
    ComboBoxModel cbm = new DefaultComboBoxModel(new String[] {"xx","YY","ZZ"});
    return cbm;
  private void loadBuildList() {
    RemoteBuildListComboBoxModelCreator bld =
            new RemoteBuildListComboBoxModelCreator();
    bld.startBackgroundTask();
  }
  private void specifyProxy(final Component parent) {
    Runnable proxySpecifier = new Runnable() {
      public void run() {
        String host = null;
        Integer port = null;
        RemoteBuildManager rbm =
                ((Upgrader) getApplication()).getRemoteBuildManager();
        Proxy proxy = rbm.getProxy();
        if (proxy != null) {
          SocketAddress address = proxy.address();
          if (address instanceof InetSocketAddress) {
            host = ((InetSocketAddress) address).getHostName();
            port = ((InetSocketAddress) address).getPort();
          }
        }
        String user = rbm.getProxyUserName();
        char[] pw = rbm.getProxyPassword();
        WebProxyDialog dlg;
        if (parent instanceof Dialog) {
          dlg = new WebProxyDialog((Dialog) parent, host, port, user, pw);
        } else if (parent instanceof Frame) {
          dlg = new WebProxyDialog((Frame) parent, host, port, user, pw);
        } else {
          dlg = new WebProxyDialog((Frame) null, host, port, user, pw);
        }
        dlg.setVisible(true);
        SocketAddress address = dlg.getSocketAddress();
        if (address != null) {
          proxy = new Proxy(Proxy.Type.HTTP, address);
          rbm.setProxy(proxy);
          rbm.setProxyUserName(dlg.getUserName());
          rbm.setProxyPassword(dlg.getPassword());
        }
      }
    };
    if (SwingUtilities.isEventDispatchThread()) {
      proxySpecifier.run();
    } else {
      try {
        SwingUtilities.invokeAndWait(proxySpecifier);
      } catch (InterruptedException e) {
        LOG.log(Level.INFO, "error", e);
      } catch (InvocationTargetException e) {
        LOG.log(Level.INFO, "error", e);
      } catch (Throwable t) {
        LOG.log(Level.INFO, "error", t);
      }
    }
  }
  /**
   * Renders the combo box when there has been an error downloading
   * the build information.
   */
  private class BuildListErrorComboBoxRenderer extends JLabel
          implements ListCellRenderer {
    /**
     * Creates a default instance.
     */
    public BuildListErrorComboBoxRenderer() {
      super("Error accessing build information",
              UIFactory.getImageIcon(UIFactory.IconType.ERROR),
              SwingConstants.LEFT);
      UIFactory.setTextStyle(this, UIFactory.TextStyle.SECONDARY_FIELD_INVALID);
      setOpaque(true);
      setBackground(Color.WHITE);
    }
    /**
     * {@inheritDoc}
     */
    public Component getListCellRendererComponent(JList jList,
                                                  Object object,
                                                  int i,
                                                  boolean b,
                                                  boolean b1) {
      return this;
    }
  }
  /**
   * This panel represents the big error message the pops up when the
   * panel can't download the build information.
   */
  private class BuildListDownloadErrorPanel extends JPanel {
    private RemoteBuildManager rbm = null;
    private Throwable reason = null;
    /**
     * Creates an instance.
     * @param rbm RemoteBuildManager that is having trouble.
     */
    public BuildListDownloadErrorPanel(RemoteBuildManager rbm,
                                       Throwable reason) {
      this.rbm = rbm;
      this.reason = reason;
      layoutPanel();
    }
    private void layoutPanel() {
      setLayout(new GridBagLayout());
      String proxyString = "None";
      Proxy proxy = rbm.getProxy();
      if (proxy != null) {
        SocketAddress addr = proxy.address();
        proxyString = addr.toString();
      }
      String baseContext = "Unspecified";
      URL url = rbm.getBaseContext();
      if (url != null) {
        baseContext = url.toString();
      }
      String html = getMsg("upgrade-choose-version-build-list-error",
              new String[]{
                      baseContext,
                      reason.getLocalizedMessage(),
                      proxyString});
      /* This helps with debugger the HTML rendering
      StringBuffer content = new StringBuffer();
      try {
        FileInputStream fis = new FileInputStream("/tmp/error-html");
        BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
        String line = null;
        while (null != (line = reader.readLine())) {
          content.append(line);
        }
        html = content.toString();
      } catch (IOException e) {
        e.printStackTrace();
      }
      */
      CustomHTMLEditorKit ek = new CustomHTMLEditorKit();
      ek.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent ev) {
          specifyProxy(getParent());
          // Since the proxy info may change we need
          // to regenerate the text
          removeAll();
          layoutPanel();
          repaint();
          validate();
        }
      });
      add(UIFactory.makeHtmlPane(html, ek, UIFactory.INSTRUCTIONS_FONT));
    }
  }
  /**
   * Uses the remote build manager is a separate thread to create
   * and populate the combo box model with build information.  Contains
   * the loop and dialog prompting that happens if there is a problem
   * accessing the remote build repository.
   */
  private class RemoteBuildListComboBoxModelCreator
          extends BackgroundTask<java.util.List<Build>> {
    private RemoteBuildManager rbm = null;
    /**
     * {@inheritDoc}
     */
    public java.util.List<Build> processBackgroundTask() throws Exception {
      rbm = ((Upgrader)getApplication()).getRemoteBuildManager();
      return rbm.listBuilds(getMainWindow(), "Loading build information");
    }
    /**
     * {@inheritDoc}
     */
    public void backgroundTaskCompleted(java.util.List<Build> buildList,
                                        Throwable throwable) {
      ComboBoxModel cbm = null;
      if (throwable == null) {
        cbm = new DefaultComboBoxModel(buildList.toArray());
      } else {
        try {
        String[] options = { "Retry", "Close" };
        int i = JOptionPane.showOptionDialog(getMainWindow(),
                new BuildListDownloadErrorPanel(rbm, throwable),
                "Network Error",
                JOptionPane.YES_NO_OPTION,
                JOptionPane.ERROR_MESSAGE,
                null,
                options,
                null);
        if (i == JOptionPane.NO_OPTION ||
                i == JOptionPane.CLOSED_OPTION) {
          SwingUtilities.invokeLater(new Runnable() {
            public void run() {
              cboBuild.setRenderer(new BuildListErrorComboBoxRenderer());
              // Disable the remote widgets
              cboBuild.setEnabled(false);
              rbLocal.setSelected(true);
              rbRemote.setSelected(false);
              // grpRemoteLocal.setSelected(rbRemote.getModel(), false);
              rbRemote.setEnabled(false);
            }
          });
        } else {
          loadBuildList();
        }
        } catch (Throwable t) {
          t.printStackTrace();
        }
      }
      final ComboBoxModel cbmFinal = cbm;
      if (cbm != null) {
        SwingUtilities.invokeLater(new Runnable() {
          public void run() {
            loadBuildListAttempted = true;
            cboBuild.setModel(cbmFinal);
            cboBuild.setRenderer(new DefaultListCellRenderer());
            // Disable the remote widgets
            cboBuild.setEnabled(true);
            rbLocal.setSelected(false);
            rbRemote.setSelected(true);
            // grpRemoteLocal.setSelected(rbRemote.getModel(), false);
            rbRemote.setEnabled(true);
          }
        });
      }
    }
  }
}
opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/UpgraderReviewPanel.java
@@ -31,9 +31,16 @@
import org.opends.quicksetup.ui.UIFactory;
import org.opends.quicksetup.ui.LabelFieldDescriptor;
import org.opends.quicksetup.upgrader.Upgrader;
import org.opends.quicksetup.upgrader.UpgradeUserData;
import org.opends.quicksetup.upgrader.Build;
import org.opends.quicksetup.QuickSetupException;
import org.opends.quicksetup.UserData;
import javax.swing.*;
import javax.swing.text.JTextComponent;
import java.awt.*;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
 * Presents upgrade information to the user to confirm before starting the
@@ -41,8 +48,16 @@
 */
public class UpgraderReviewPanel extends ReviewPanel {
  static private final Logger LOG =
          Logger.getLogger(UpgraderReviewPanel.class.getName());
  private static final long serialVersionUID = 5942916658585976799L;
  JTextComponent tcServerLocation = null;
  JTextComponent tcOldBuild = null;
  JTextComponent tcNewBuild = null;
  private JCheckBox checkBox;
  /**
   * Creates an instance.
   * @param application Application represented by this panel
@@ -54,6 +69,15 @@
  /**
   * {@inheritDoc}
   */
  public void beginDisplay(UserData data) {
    tcServerLocation.setText(getServerToUpgrade());
    tcOldBuild.setText(getOldBuildId());
    tcNewBuild.setText(getNewBuildId());
  }
  /**
   * {@inheritDoc}
   */
  protected String getTitle() {
    return getMsg("upgrade-review-panel-title");
  }
@@ -69,7 +93,9 @@
   * {@inheritDoc}
   */
  protected JPanel createFieldsPanel() {
    JPanel p = new JPanel();
    UpgradeUserData uud = (UpgradeUserData)getUserData();
    JPanel p = UIFactory.makeJPanel();
    LabelFieldDescriptor serverDescriptor = new LabelFieldDescriptor(
      getMsg("upgrade-review-panel-server-label"),
@@ -110,7 +136,8 @@
    gbc.gridy = 0;
    gbc.weightx = 1.0;
    gbc.fill = GridBagConstraints.HORIZONTAL;
    p.add(UIFactory.makeJTextComponent(serverDescriptor, "/xx/xx/xx"), gbc);
    p.add(tcServerLocation = UIFactory.makeJTextComponent(serverDescriptor,
            null), gbc);
    gbc.gridx = 0;
    gbc.gridy = 1;
@@ -120,7 +147,8 @@
    gbc.gridx = 1;
    gbc.gridy = 1;
    gbc.fill = GridBagConstraints.HORIZONTAL;
    p.add(UIFactory.makeJTextComponent(oldVersionDescriptor, "abcdefg"), gbc);
    p.add(tcOldBuild = UIFactory.makeJTextComponent(oldVersionDescriptor,
            null), gbc);
    gbc.gridx = 0;
    gbc.gridy = 2;
@@ -131,8 +159,54 @@
    gbc.gridy = 2;
    gbc.weighty = 1.0;
    gbc.fill = GridBagConstraints.HORIZONTAL;
    p.add(UIFactory.makeJTextComponent(newVersionDescriptor, "1234567"), gbc);
    p.add(tcNewBuild = UIFactory.makeJTextComponent(newVersionDescriptor,
            null), gbc);
    return p;
  }
  private String getServerToUpgrade() {
    return getUserData().getServerLocation();
  }
  private String getOldBuildId() {
    String oldVersion;
    try {
      oldVersion = getApplication().getInstallation().getBuildId();
    } catch (QuickSetupException e) {
      LOG.log(Level.INFO, "error", e);
      oldVersion = getMsg("upgrade-build-id-unknown");
    }
    return oldVersion;
  }
  private String getNewBuildId() {
    String newVersion;
    UpgradeUserData uud = (UpgradeUserData)getUserData();
    Build build = uud.getInstallPackageToDownload();
    if (build != null) {
      newVersion = build.getId();
    } else {
      // TODO: figure out the build from the zip somehow
      newVersion = getMsg("upgrade-build-id-unknown");
    }
    return newVersion;
  }
  /**
   * {@inheritDoc}
   */
  protected JCheckBox getCheckBox()
  {
    if (checkBox == null)
    {
      checkBox =
          UIFactory.makeJCheckBox(getMsg("upgrade-review-panel-start-server"),
              getMsg("start-server-tooltip"), UIFactory.TextStyle.CHECKBOX);
      checkBox.setOpaque(false);
      checkBox.setSelected(getApplication().getUserData().getStartServer());
    }
    return checkBox;
  }
}
opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/WelcomePanel.java
@@ -27,12 +27,10 @@
package org.opends.quicksetup.upgrader.ui;
import org.opends.quicksetup.ui.QuickSetupStepPanel;
import org.opends.quicksetup.ui.UIFactory;
import org.opends.quicksetup.ui.Utilities;
import org.opends.quicksetup.ui.LabelFieldDescriptor;
import org.opends.quicksetup.ui.*;
import org.opends.quicksetup.util.Utils;
import org.opends.quicksetup.Installation;
import org.opends.quicksetup.UserData;
import org.opends.quicksetup.event.BrowseActionListener;
import org.opends.quicksetup.upgrader.Upgrader;
@@ -42,12 +40,18 @@
import java.util.ArrayList;
/**
 * This panel is used to show a welcome message.
 * This panel is used to show a welcome message.  If this is the WebStart,
 * allows the user to select a build to upgrade.  Otherwise shows the user
 * some readonly information about the current build.
 */
public class WelcomePanel extends QuickSetupStepPanel {
  private static final long serialVersionUID = 8695606871542491768L;
  private JTextComponent tcServerLocation;
  private JTextComponent tcCurrentServerBuildNumber;
  /**
   * Default constructor.
   * @param application Upgrader application
@@ -59,6 +63,25 @@
  /**
   * {@inheritDoc}
   */
  public void beginDisplay(UserData data) {
    super.beginDisplay(data);
    tcServerLocation.setText(data.getServerLocation());
  }
  /**
   * {@inheritDoc}
   */
  public Object getFieldValue(FieldName fieldName) {
    Object v = null;
    if (FieldName.SERVER_LOCATION.equals(fieldName)) {
      v = tcServerLocation.getText();
    }
    return v;
  }
  /**
   * {@inheritDoc}
   */
  protected String getTitle() {
    return getMsg("upgrade-welcome-panel-title");
  }
@@ -91,43 +114,65 @@
  protected Component createInputPanel() {
    Component c;
    JPanel pnlBuildInfo = new JPanel();
    LabelFieldDescriptor serverLocationDescriptor =
            new LabelFieldDescriptor(getMsg("upgrade-location-label"),
                    getMsg("upgrade-location-tooltip"),
                    LabelFieldDescriptor.FieldType.TEXTFIELD,
                    LabelFieldDescriptor.LabelType.PRIMARY,
                    UIFactory.PATH_FIELD_SIZE);
    LabelFieldDescriptor serverLocationDescriptorRO =
            new LabelFieldDescriptor(getMsg("upgrade-location-label"),
                    getMsg("upgrade-location-tooltip"),
                    LabelFieldDescriptor.FieldType.READ_ONLY,
                    LabelFieldDescriptor.LabelType.PRIMARY,
                    UIFactory.PATH_FIELD_SIZE);
    LabelFieldDescriptor serverBuildDescriptorRO =
            new LabelFieldDescriptor(getMsg("upgrade-build-id-label"),
                    getMsg("upgrade-build-id-tooltip"),
                    LabelFieldDescriptor.FieldType.READ_ONLY,
                    LabelFieldDescriptor.LabelType.PRIMARY,
                    UIFactory.PATH_FIELD_SIZE);
    JPanel pnlBuildInfo = UIFactory.makeJPanel();
    pnlBuildInfo.setLayout(new GridBagLayout());
    GridBagConstraints gbc = new GridBagConstraints();
    UserData userData = getApplication().getUserData();
    // The WebStart version of this tool allows the user to
    // select a build to upgrade.  Running the tool from the
    // command line implies a build.
    if (!Utils.isWebStart()) {
    if (Utils.isWebStart()) {
      LabelFieldDescriptor serverLocationDescriptor =
              new LabelFieldDescriptor(getMsg("upgrade-location-label"),
                      getMsg("upgrade-location-tooltip"),
                      LabelFieldDescriptor.FieldType.TEXTFIELD,
                      LabelFieldDescriptor.LabelType.PRIMARY,
                      UIFactory.PATH_FIELD_SIZE);
      JTextComponent tfBuild =
              UIFactory.makeJTextComponent(serverLocationDescriptor, null);
      tcServerLocation =
              UIFactory.makeJTextComponent(serverLocationDescriptor,
                      userData.getServerLocation());
      JButton butBrowse =
              UIFactory.makeJButton(getMsg("browse-button-label"),
                      getMsg("browse-button-tooltip"));
      BrowseActionListener l =
              new BrowseActionListener(tfBuild,
              new BrowseActionListener(tcServerLocation,
                      BrowseActionListener.BrowseType.LOCATION_DIRECTORY,
                      getMainWindow());
      butBrowse.addActionListener(l);
      JPanel pnlBrowser = Utilities.createBrowseButtonPanel(
              UIFactory.makeJLabel(serverLocationDescriptor),
              tfBuild,
              tcServerLocation,
              butBrowse);
      // pnlBrowser.setBorder(BorderFactory.createLineBorder(Color.GREEN));
      pnlBrowser.setOpaque(false);
      //pnlBrowser.setBorder(BorderFactory.createLineBorder(Color.GREEN));
      gbc.insets.top = 15; // non-standard but looks better
      gbc.insets.left = UIFactory.LEFT_INSET_PRIMARY_FIELD;
      gbc.anchor = GridBagConstraints.FIRST_LINE_START;
      gbc.gridwidth = GridBagConstraints.REMAINDER;
      gbc.weightx = 1.0;
      gbc.fill = GridBagConstraints.BOTH;
      pnlBuildInfo.add(pnlBrowser, gbc);
      gbc.gridy = 1;
@@ -135,25 +180,26 @@
      gbc.weightx = 1.0;
      gbc.fill = GridBagConstraints.BOTH;
      gbc.anchor = GridBagConstraints.LINE_START;
      JPanel fill = new JPanel();
      JPanel fill = UIFactory.makeJPanel();
      // fill.setBorder(BorderFactory.createLineBorder(Color.BLUE));
      pnlBuildInfo.add(fill, gbc);
    } else {
      LabelFieldDescriptor serverLocationDescriptorRO =
              new LabelFieldDescriptor(getMsg("upgrade-location-label"),
                      getMsg("upgrade-location-tooltip"),
                      LabelFieldDescriptor.FieldType.READ_ONLY,
                      LabelFieldDescriptor.LabelType.PRIMARY,
                      UIFactory.PATH_FIELD_SIZE);
      tcServerLocation = UIFactory.makeJTextComponent(
                       serverLocationDescriptorRO, null);
      LabelFieldDescriptor serverBuildDescriptorRO =
              new LabelFieldDescriptor(getMsg("upgrade-build-id-label"),
                      getMsg("upgrade-build-id-tooltip"),
                      LabelFieldDescriptor.FieldType.READ_ONLY,
                      LabelFieldDescriptor.LabelType.PRIMARY,
                      UIFactory.PATH_FIELD_SIZE);
      String buildId = null;
      Installation installation = getApplication().getInstallation();
      try {
        buildId = installation.getBuildId();
      } catch (Exception e) {
        buildId = getMsg("upgrade-build-id-unknown");
      }
      tcCurrentServerBuildNumber = UIFactory.makeJTextComponent(
                        serverBuildDescriptorRO,
                        buildId);
      gbc.gridx = 0;
      gbc.gridy = 0;
@@ -162,17 +208,14 @@
      gbc.insets.left = UIFactory.LEFT_INSET_PRIMARY_FIELD;
      pnlBuildInfo.add(UIFactory.makeJLabel(serverLocationDescriptorRO), gbc);
      gbc.gridx = 1;
      gbc.gridy = 0;
      gbc.weightx = 1.0;
      gbc.insets.left = UIFactory.LEFT_INSET_PRIMARY_FIELD;
      gbc.fill = GridBagConstraints.HORIZONTAL;
      gbc.anchor = GridBagConstraints.PAGE_START;
      String installLocation = Utils.getPath(
              getApplication().getInstallation().getRootDirectory());
      pnlBuildInfo.add(
              UIFactory.makeJTextComponent(
                      serverLocationDescriptorRO, installLocation), gbc);
      pnlBuildInfo.add(tcServerLocation, gbc);
      gbc.gridx = 0;
      gbc.gridy = 1;
@@ -185,16 +228,14 @@
      gbc.gridy = 1;
      gbc.insets.left = UIFactory.LEFT_INSET_PRIMARY_FIELD;
      gbc.fill = GridBagConstraints.HORIZONTAL;
      pnlBuildInfo.add(UIFactory.makeJTextComponent(
              serverBuildDescriptorRO,
              org.opends.server.util.DynamicConstants.BUILD_ID), gbc);
      pnlBuildInfo.add(tcCurrentServerBuildNumber, gbc);
      gbc.gridy = 2;
      gbc.weighty = 1.0;
      gbc.weightx = 1.0;
      gbc.fill = GridBagConstraints.BOTH;
      gbc.anchor = GridBagConstraints.LINE_START;
      JPanel fill = new JPanel();
      JPanel fill = UIFactory.makeJPanel();
      //fill.setBorder(BorderFactory.createLineBorder(Color.BLUE));
      pnlBuildInfo.add(fill, gbc);
    }
opends/src/quicksetup/org/opends/quicksetup/util/BackgroundTask.java
@@ -32,8 +32,9 @@
 * This class provides a mechanism for running a task in the background using a
 * separate thread and providing the caller with notification when it has
 * completed.
 * @param <T> type of object returned by this process
 */
public abstract class BackgroundTask
public abstract class BackgroundTask<T>
{
  /**
   * Creates a new thread and begins running the task in the background.  When
@@ -42,7 +43,7 @@
   */
  public final void startBackgroundTask()
  {
    BackgroundTaskThread taskThread = new BackgroundTaskThread(this);
    BackgroundTaskThread taskThread = new BackgroundTaskThread<T>(this);
    taskThread.start();
  }
@@ -57,7 +58,7 @@
   * @throws Exception exception that will be passed through the method
   *          backgroundTaskCompleted.
   */
  public abstract Object processBackgroundTask() throws Exception;
  public abstract T processBackgroundTask() throws Exception;
@@ -77,6 +78,6 @@
   *                      was raised during processing, or {@code null} if all
   *                      processing completed successfully.
   */
  public abstract void backgroundTaskCompleted(Object returnValue,
  public abstract void backgroundTaskCompleted(T returnValue,
                                               Throwable throwable);
}
opends/src/quicksetup/org/opends/quicksetup/util/BackgroundThreadTask.java
@@ -31,12 +31,14 @@
/**
 * This class defines a thread that will be used to actually perform the
 * processing for a background task.
 * @param <T> type of object returned by the background task fed to this
 * object
 */
class BackgroundTaskThread
class BackgroundTaskThread<T>
      extends Thread
{
  // The background task that is to be processed.
  private final BackgroundTask backgroundTask;
  private final BackgroundTask<T> backgroundTask;
@@ -46,7 +48,7 @@
   *
   * @param  backgroundTask  The task to be processed.
   */
  public BackgroundTaskThread(BackgroundTask backgroundTask)
  public BackgroundTaskThread(BackgroundTask<T> backgroundTask)
  {
    this.backgroundTask = backgroundTask;
  }
@@ -60,7 +62,7 @@
  {
    try
    {
      Object returnValue = backgroundTask.processBackgroundTask();
      T returnValue = backgroundTask.processBackgroundTask();
      backgroundTask.backgroundTaskCompleted(returnValue, null);
    }
    catch (Throwable t)
opends/src/quicksetup/org/opends/quicksetup/util/Utils.java
@@ -898,7 +898,7 @@
   */
  public static String getInstallPathFromClasspath()
  {
    String installPath;
    String installPath = null;
    /* Get the install path from the Class Path */
    String sep = System.getProperty("path.separator");
@@ -916,21 +916,23 @@
        }
      }
    }
    File f = new File(path).getAbsoluteFile();
    File librariesDir = f.getParentFile();
    if (path != null) {
      File f = new File(path).getAbsoluteFile();
      File librariesDir = f.getParentFile();
    /*
     * Do a best effort to avoid having a relative representation (for
     * instance to avoid having ../../../).
     */
    try
    {
      installPath = librariesDir.getParentFile().getCanonicalPath();
    }
    catch (IOException ioe)
    {
      // Best effort
      installPath = librariesDir.getParent();
      /*
       * Do a best effort to avoid having a relative representation (for
       * instance to avoid having ../../../).
       */
      try
      {
        installPath = librariesDir.getParentFile().getCanonicalPath();
      }
      catch (IOException ioe)
      {
        // Best effort
        installPath = librariesDir.getParent();
      }
    }
    return installPath;
  }