[izpack-devel] Production IzPack Mods

Jeff Gordon jeff.not24 at gmail.com
Thu Jan 24 20:45:26 CET 2008


Done.  The attached samples in the previous message should influence the
documentation, but I'm not setup to build or contribute to it yet.  Just
want to make sure if someone has the time to throw them in the correct spot.

- Jeff Gordon

On Jan 22, 2008 6:38 PM, Jeff Gordon <jeff.not24 at gmail.com> wrote:

> Hello,
>
> I've been working with the IzPack trunk for some time now and through our
> release cycle have included a number of patches based on feedback I have
> received from our company's developers, technical writers, and testers.
> This patch is basically the rest of the changes that can only be done in a
> single patch because of dependencies.  I know there are a lot of changes and
> additions, but I'd like to reassure everyone that these are all being used
> in production code going to global customers (I'm working on releasing some
> examples).
>
> I've added the patch as an attachment and inline for easy reading.
>
> - Jeff Gordon
>
>
> Some of the highlights for this patch are:
> - Adding multiple validator support to the password field
> - Adding password equality validator as out-of-the-box functionality
> - Adding a keystore validator as out-of-the-box functionality
> - Adding a standard path selection panel for the user's use
> - Many spelling, capitalization, and terminology corrections
>
>
>
> eng.xml
> -------
> Changed textual descriptions to more business-like terminology
> Corrected spelling and capitalization errors
> Added UserPathPanel headline, messages, and captions
> Added UserInputPanel.dir.* messages and captions
> Added UserInputPanel.file.* messages and captions
> (Need to test with alternative lang packs)
>
>
> build.xml
> ---------
> Added nimbus.jar and substance.jar for LAF
> Added ValidatorContainer (see below)
> Added section for UserPathPanel (see below)
>
>
> CompilerConfig.java
> -------------------
> Changed uninstaller name to allow file without jar extension
> (used to control uninstall and keep windows users from double-clicking it)
> (I left 4 character size restriction, but it's not that useful)
>
>
> PasswordGroup.java
> ------------------
> Added usage of ValidatorContainer
> [This may affect Piotr's use of his newly committed validator code]
> [I've been trying to get this all in, but he got some similar code ahead
> of me]
>
>
> PathSelectionPanel.java
> -----------------------
> Grammatical corrections in comments
>
>
> ProcessingClient.java
> ---------------------
> Comment about newly added fields to this interface
> (affects PasswordGroup.java)
>
>
> UserInputPanel.java
> -------------------
> Added auto-install info for selected directory
> Added error messages for no directory and not a directory
> Added showMessage() method to encapsulate message dialog
> Added auto-install info for selected file
> Added error messages for no file and not a file
> Added JavaDoc comments for specifying PasswordEqualityValidator and
> PasswordKeystoreValidator
> Added use of multiple validators for password field
>
>
> ------------------------------------
> - UserPathInputPanel.java
> - UserPathPanel.java
> - UserPathPanelAutomationHelper.java
> - UserPathSelectionPanel.java
> ------------------------------------
> Implemented copy of PathPanel as UserPathPanel (as alternative to dir type
> in UserInputPanel)
>
>
> ValidatorContainer.java
> -----------------------
> Object representation of a validator containing the validator, error
> message, and parameter Map
>
>
> PasswordEqualityValidator.java
> ------------------------------
> Implementation of sample validator for use in any installer
> Shows how to get at validator parameters as well
>
>
> PasswordKeystoreValidator.java
> ------------------------------
> Validates keystore access using password field
> Validates alias (key) access with password field
>
>
>
> ------------------------------------------------------------------------------------------------------------------------
> Patch attached, provided inline for readability
>
> ------------------------------------------------------------------------------------------------------------------------
> Index: bin/langpacks/installer/eng.xml
> ===================================================================
> --- bin/langpacks/installer/eng.xml    (revision 1998)
> +++ bin/langpacks/installer/eng.xml    (working copy)
> @@ -11,10 +11,10 @@
>      <str id="ExtendedInstallPanel.headline" txt="Installation and
> Configuration"/>
>      <str id="FinishPanel.headline" txt="Installation Finished"/>
>      <str id="HelloPanel.headline" txt="Welcome"/>
> -    <str id="HTMLInfoPanel.headline" txt="Informations"/>
> +    <str id="HTMLInfoPanel.headline" txt="Information"/>
>      <str id="HTMLLicencePanel.headline" txt="Licensing Agreements"/>
>      <str id="ImgPacksPanel.headline" txt="Select Installation Packages"/>
> -    <str id="InfoPanel.headline" txt="Informations"/>
> +    <str id="InfoPanel.headline" txt="Information"/>
>      <str id="InstallPanel.headline" txt="Installation"/>
>      <str id="JDKPathPanel.headline" txt="JDK Path"/>
>      <str id="LicencePanel.headline" txt="Licensing Agreements"/>
> @@ -25,6 +25,7 @@
>      <str id="SummaryPanel.headline" txt="Summary Configuration Data"/>
>      <str id="TargetPanel.headline" txt="Target Path"/>
>      <str id="UserInputPanel.headline" txt="User Data"/>
> +    <str id="UserPathPanel.headline" txt="Select Path"/>
>      <str id="InstallationTypePanel.headline" txt="Installation Type" />
>
>      <!-- General installer strings -->
> @@ -46,7 +47,7 @@
>      <str id="installer.Message" txt="Message"/>
>
>      <!-- Uninstaller specific strings -->
> -    <str id="uninstaller.warning" txt="This will remove the installed
> application(s)!"/>
> +    <str id="uninstaller.warning" txt="This will remove the installed
> application!"/>
>      <str id="uninstaller.destroytarget" txt=" Force the deletion of "/>
>      <str id="uninstaller.uninstall" txt="Uninstall"/>
>
> @@ -99,7 +100,7 @@
>      <str id="JDKPathPanel.nonValidPathInReg" txt="The Windows registry
> contains a non-valid path for this JDK. Should this JDK be used anyway?"/>
>
>      <str id="PacksPanel.info" txt="Select the packs you want to
> install:"/>
> -    <str id="PacksPanel.tip" txt="Note: greyed out packs are required."/>
> +    <str id="PacksPanel.tip" txt="Note: Grayed packs are required."/>
>      <str id="PacksPanel.space" txt="Total space Required: "/>
>      <str id="PacksPanel.freespace" txt="Available space: "/>
>      <str id="PacksPanel.description" txt="Description"/>
> @@ -115,7 +116,7 @@
>      <str id="InstallPanel.info" txt="Click 'Install!' to begin the
> installation process"/>
>      <str id="InstallPanel.install" txt="Install!"/>
>      <str id="InstallPanel.tip" txt="Pack installation progress:"/>
> -    <str id="InstallPanel.begin" txt="[Nothing]"/>
> +    <str id="InstallPanel.begin" txt=" "/>
>      <str id="InstallPanel.finished" txt="[Finished]"/>
>      <str id="InstallPanel.progress" txt="Overall installation
> progress:"/>
>      <str id="InstallPanel.overwrite.title" txt="File already exists"/>
> @@ -165,19 +166,38 @@
>      <str id="ShortcutPanel.location.startMenu"    txt="Start Menu"/>
>      <str id="ShortcutPanel.location.startup"      txt="Startup Group"/>
>
> -    <str id="UserInputPanel.error.caption"        txt="Input Problem"/>
> +    <str id="UserInputPanel.error.caption"        txt="Error"/>
>      <str id="UserInputPanel.search.autodetect"    txt="Autodetect"/>
>
> +    <str id="UserInputPanel.dir.nodirectory.message"   txt="You must
> select a valid directory."/>
> +    <str id="UserInputPanel.dir.nodirectory.caption"   txt="No Directory
> Selected"/>
> +    <str id="UserInputPanel.dir.notdirectory.message"   txt="The
> directory you have chosen either does not exist or is not valid."/>
> +    <str id="UserInputPanel.dir.notdirectory.caption"   txt="Invalid
> Directory"/>
> +    <str id="UserInputPanel.file.nofile.message"   txt="You must select a
> valid file."/>
> +    <str id="UserInputPanel.file.nofile.caption"   txt="No File
> Selected"/>
> +    <str id="UserInputPanel.file.notfile.message"   txt="The file you
> have chosen either does not exist or is not valid."/>
> +    <str id="UserInputPanel.file.notfile.caption"   txt="Invalid File"/>
> +
> +
>      <!-- more descriptive error message would be cool, like specifying
> what file we looked for -->
> -    <str id="UserInputPanel.search.autodetect.failed.message"
> txt="Autodetection failed."/>
> -    <str id="UserInputPanel.search.autodetect.failed.caption"
> txt="Autodetection failed."/>
> +    <str id="UserInputPanel.search.autodetect.failed.message"
> txt="Auto-detection failed."/>
> +    <str id="UserInputPanel.search.autodetect.failed.caption"
> txt="Auto-Detection Failed"/>
>      <str id="UserInputPanel.search.autodetect.tooltip"
> txt="Check for the file or directory in the paths given above."/>
>      <str id="UserInputPanel.search.location"           txt="Enter
> location of {0}."/>
>      <str id="UserInputPanel.search.location.checkedfile" txt="The
> existence of {0} is checked."/>
>      <str id="UserInputPanel.search.browse"           txt="Browse..."/>
> -    <str id="UserInputPanel.search.wrongselection.message"   txt="The
> file or directory you choose either does not exist or is not appropiate."/>
> -    <str id="UserInputPanel.search.wrongselection.caption"   txt="Invalid
> selection."/>
> +    <str id="UserInputPanel.search.wrongselection.message"   txt="The
> file or directory you have chosen either does not exist or is not
> appropriate."/>
> +    <str id="UserInputPanel.search.wrongselection.caption"   txt="Invalid
> Selection"/>
>
> +    <str id="UserPathPanel.required" txt="The chosen directory should
> exist."/>
> +    <str id="UserPathPanel.info" txt="Select the path: "/>
> +    <str id="UserPathPanel.browse" txt="Browse"/>
> +    <str id="UserPathPanel.exists_warn" txt="The directory already
> exists! Are you sure you want to install here and possibly overwrite
> existing files?"/>
> +    <str id="UserPathPanel.empty_target" txt="You have not specified a
> target location! Is this correct?"/>
> +    <str id="UserPathPanel.createdir" txt="The target directory will be
> created: " />
> +    <str id="UserPathPanel.nodir"  txt="This file is not a directory!
> Please choose a directory!"/>
> +    <str id="UserPathPanel.notwritable" txt="This directory can not be
> written! Please choose another directory!"/>
> +
>      <str id="CompilePanel.heading" txt="Compilation" />
>      <str id="CompilePanel.tip" txt="Job compilation progress:" />
>      <str id="CompilePanel.browse" txt="Browse..." />
> @@ -201,18 +221,19 @@
>      <str id="ProcessPanel.heading" txt="Processing" />
>
>      <!-- Strings for the summary of panels - START -->
> -    <str id="SummaryPanel.info" txt="Ready to install. Important data are
> listed below. Press &quot;Next&quot; to start installation, "/>
> -    <str id="TargetPanel.summaryCaption" txt="Installation path"/>
> -    <str id="JDKPathPanel.summaryCaption" txt="JDK path"/>
> -    <str id="PacksPanel.summaryCaption" txt="Chosen installation packs"/>
> -    <str id="ImgPacksPanel.summaryCaption" txt="Chosen installation
> packs"/>
> +    <str id="SummaryPanel.info" txt="Installation will proceed with the
> following settings. Press Next to continue."/>
> +    <str id="TargetPanel.summaryCaption" txt="Installation Path"/>
> +    <str id="JDKPathPanel.summaryCaption" txt="JDK Path"/>
> +    <str id="PacksPanel.summaryCaption" txt="Chosen Installation Packs"/>
> +    <str id="ImgPacksPanel.summaryCaption" txt="Chosen Installation
> Packs"/>
> +    <str id="UserPathPanel.summaryCaption" txt="Selected Path"/>
>      <!-- Strings for the summary of panels - END -->
>
>      <!-- Strings for the Registry -->
>      <str id="functionFailed.RegOpenKeyEx" txt="Cannot open registry key
> {0}\\{1}."/>
>
>      <!-- Add your own panels specific strings here if you need or use a
> custom
> -         langpack with the same syntax referred as resoure
> CustomLangpack.xml_[ISO3]"
> +         langpack with the same syntax referred as resource
> CustomLangpack.xml_[ISO3]"
>      -->
>
>      <str id="nextmedia.title" txt="Next install media"/>
> @@ -223,7 +244,7 @@
>      <str id="nextmedia.choosertitle" txt="Choose install media" />
>      <str id="nextmedia.filedesc" rdid="install packs (.pak*)" />
>
> -    <!-- Strings for the loggin/reporting system (Messenger) -->
> +    <!-- Strings for the logging/reporting system (Messenger) -->
>
>      <!-- This string defines the time stamp format in the installation
> report.
>           The format details are documented in java.text.SimpleDateFormat-->
> Index: src/build.xml
> ===================================================================
> --- src/build.xml    (revision 1998)
> +++ src/build.xml    (working copy)
> @@ -361,6 +361,8 @@
>                  <include name="lib/liquidlnf.jar" />
>                  <include name="lib/metouia.jar" />
>                  <include name="lib/looks.jar" />
> +                <include name="lib/nimbus.jar" />
> +                <include name="lib/substance.jar" />
>                  <include name="lib/ant.jar" />
>                  <include name="lib/nimbus.jar" />
>                  <include name="lib/substance.jar" />
> @@ -648,7 +650,14 @@
>              <include name="com/izforge/izpack/panels/UserInputPanel.java"
> />
>              <include
> name="com/izforge/izpack/panels/UserInputPanelAutomationHelper.java" />
>              <include name="com/izforge/izpack/panels/Validator.java" />
> +            <include
> name="com/izforge/izpack/panels/ValidatorContainer.java" />
>          </build-panel>
> +        <build-panel name="UserPathPanel">
> +            <include
> name="com/izforge/izpack/panels/UserPathInputPanel.java" />
> +            <include
> name="com/izforge/izpack/panels/UserPathSelectionPanel.java" />
> +            <include name="com/izforge/izpack/panels/UserPathPanel.java"
> />
> +            <include
> name="com/izforge/izpack/panels/UserPathPanelAutomationHelper.java" />
> +        </build-panel>
>          <build-panel name="ConditionalUserInputPanel">
>              <include
> name="com/izforge/izpack/panels/ConditionalUserInputPanel.java" />
>              <include name="com/izforge/izpack/panels/PasswordGroup.java"
> />
> @@ -660,6 +669,7 @@
>              <include name="com/izforge/izpack/panels/UserInputPanel.java"
> />
>              <include
> name="com/izforge/izpack/panels/UserInputPanelAutomationHelper.java" />
>              <include name="com/izforge/izpack/panels/Validator.java" />
> +            <include
> name="com/izforge/izpack/panels/ValidatorContainer.java" />
>          </build-panel>
>          <build-panel name="CompilePanel">
>              <include name="com/izforge/izpack/panels/CompilePanel.java"
> />
> Index: src/lib/com/izforge/izpack/compiler/CompilerConfig.java
> ===================================================================
> --- src/lib/com/izforge/izpack/compiler/CompilerConfig.java    (revision
> 1998)
> +++ src/lib/com/izforge/izpack/compiler/CompilerConfig.java    (working
> copy)
> @@ -1511,8 +1511,7 @@
>              if (uninstallInfo != null)
>              {
>                  String uninstallerName = uninstallInfo.getAttribute
> ("name");
> -                if (uninstallerName != null && uninstallerName.endsWith
> (".jar")
> -                        && uninstallerName.length() > ".jar".length())
> +                if (uninstallerName != null && uninstallerName.length() >
> ".jar".length())
>                      info.setUninstallerName(uninstallerName);
>              }
>          }
> Index: src/lib/com/izforge/izpack/panels/PasswordGroup.java
> ===================================================================
> --- src/lib/com/izforge/izpack/panels/PasswordGroup.java    (revision
> 1998)
> +++ src/lib/com/izforge/izpack/panels/PasswordGroup.java    (working copy)
> @@ -18,9 +18,10 @@
>   * See the License for the specific language governing permissions and
>   * limitations under the License.
>   */
> -
>  package com.izforge.izpack.panels;
>
> +import com.izforge.izpack.installer.InstallData;
> +import java.util.List;
>  import java.util.Map;
>  import java.util.Vector;
>
> @@ -46,13 +47,19 @@
>      //
> ------------------------------------------------------------------------
>      private Vector fields = new Vector();
>
> -    private Validator validator = null;
> -
> +    private List validatorContainers = null;
> +//  private Validator validator = null;
> +//  private boolean hasParams = false;
> +//  private Map validatorParams = null;
>      private Processor processor = null;
>
> +    private int currentValidator = 0;
> +
> +    private InstallData idata;
> +
>
> /*--------------------------------------------------------------------------*/
>      /**
> -     * Creates a passowrd group to manage one or more password fields.
> +     * Creates a password group to manage one or more password fields.
>       *
>       * @param validator A string that specifies a class that provides a
> password validation service.
>       * The class must implement the <code>Validator</code> interface. If
> an attempt to instantiate
> @@ -63,18 +70,25 @@
>       * contents of the first field will be returned.
>       */
>
> /*--------------------------------------------------------------------------*/
> -    public PasswordGroup(String validator, String processor)
> +    public PasswordGroup(InstallData idata, List validatorContainers,
> String processor)
>      {
>          // ----------------------------------------------------
>          // attempt to create an instance of the Validator
>          // ----------------------------------------------------
>          try
>          {
> -            this.validator = (Validator) Class.forName
> (validator).newInstance();
> -        }
> -        catch (Throwable exception)
> +            this.idata = idata;
> +//      this.validator = (Validator) Class.forName
> (validator).newInstance();
> +            this.validatorContainers = validatorContainers;
> +//      this.validatorParams = validatorParams;
> +//      if (validatorParams != null) {
> +//        if (validatorParams.size() > 0) {
> +//          hasParams = true;
> +//        }
> +//      }
> +        } catch (Throwable exception)
>          {
> -            this.validator = null;
> +            this.validatorContainers = null;
>          }
>
>          // ----------------------------------------------------
> @@ -83,13 +97,17 @@
>          try
>          {
>              this.processor = (Processor) Class.forName
> (processor).newInstance();
> -        }
> -        catch (Throwable exception)
> +        } catch (Throwable exception)
>          {
>              this.processor = null;
>          }
>      }
>
> +    public InstallData getIdata()
> +    {
> +        return idata;
> +    }
> +
>
> /*--------------------------------------------------------------------------*/
>      /**
>       * Returns the number of sub-fields.
> @@ -115,7 +133,10 @@
>
> /*--------------------------------------------------------------------------*/
>      public String getFieldContents(int index) throws
> IndexOutOfBoundsException
>      {
> -        if ((index < 0) || (index >= fields.size())) { throw (new
> IndexOutOfBoundsException()); }
> +        if ((index < 0) || (index >= fields.size()))
> +        {
> +            throw (new IndexOutOfBoundsException());
> +        }
>
>          String contents = new String(((JPasswordField) fields.elementAt
> (index)).getPassword());
>          return (contents);
> @@ -145,18 +166,125 @@
>       * rule exists. Otherwise <code>false</code> is returned.
>       */
>
> /*--------------------------------------------------------------------------*/
> -    public boolean validateContents()
> +    public boolean validateContents(int i)
>      {
> -        if (validator != null)
> +        boolean returnValue = true;
> +        try
>          {
> -            return (validator.validate(this));
> +            currentValidator = i;
> +            ValidatorContainer container = getValidatorContainer(i);
> +            Validator validator = container.getValidator();
> +            if (validator != null)
> +            {
> +                returnValue = validator.validate(this);
> +            }
> +        } catch (Exception e)
> +        {
> +            System.out.println("validateContents(" + i + ") failed: " +
> e);
> +        // just return true
>          }
> -        else
> +        return returnValue;
> +    }
> +
> +    public String getValidatorMessage(int i)
> +    {
> +        String returnValue = null;
> +        try
>          {
> -            return (true);
> +            ValidatorContainer container = getValidatorContainer(i);
> +            if (container != null)
> +            {
> +                returnValue = container.getMessage();
> +            }
> +        } catch (Exception e)
> +        {
> +            System.out.println("getValidatorMessage(" + i + ") failed: "
> + e);
> +        // just return true
>          }
> +        return returnValue;
>      }
>
> +    public int validatorSize()
> +    {
> +        int size = 0;
> +        if (validatorContainers != null)
> +        {
> +            size = validatorContainers.size();
> +        }
> +        return size;
> +    }
> +
> +    public ValidatorContainer getValidatorContainer()
> +    {
> +        return getValidatorContainer(currentValidator);
> +    }
> +
> +    public ValidatorContainer getValidatorContainer(int i)
> +    {
> +        ValidatorContainer container = null;
> +        try
> +        {
> +            container = (ValidatorContainer) validatorContainers.get(i);
> +        } catch (Exception e)
> +        {
> +            container = null;
> +        }
> +        return container;
> +    }
> +
> +    public boolean hasParams()
> +    {
> +        return hasParams(currentValidator);
> +    }
> +
> +    public boolean hasParams(int i)
> +    {
> +        boolean returnValue = false;
> +        try
> +        {
> +            ValidatorContainer container = getValidatorContainer(i);
> +            if (container != null)
> +            {
> +                returnValue = container.hasParams();
> +            }
> +        } catch (Exception e)
> +        {
> +            System.out.println("hasParams(" + i + ") failed: " + e);
> +        // just return true
> +        }
> +        return returnValue;
> +    }
> +
> +    public Map getValidatorParams()
> +    {
> +        return getValidatorParams(currentValidator);
> +    }
> +
> +    public Map getValidatorParams(int i)
> +    {
> +        Map returnValue = null;
> +        try
> +        {
> +            ValidatorContainer container = getValidatorContainer(i);
> +            if (container != null)
> +            {
> +                returnValue = container.getValidatorParams();
> +            }
> +        } catch (Exception e)
> +        {
> +            System.out.println("getValidatorParams(" + i + ") failed: " +
> e);
> +        // just return true
> +        }
> +        return returnValue;
> +    }
> +
> +    // This method was added to support changes to ProcessingClient
> interface
> +    // it's use is non-deterministic in the newly implemented text
> validators.
> +    public String getText()
> +    {
> +        return getValidatorMessage(currentValidator);
> +    }
> +
>
> /*--------------------------------------------------------------------------*/
>      /**
>       * Returns the password. If a processing service class was supplied
> it will be used to process
> @@ -171,36 +299,18 @@
>          if (processor != null)
>          {
>              return (processor.process(this));
> -        }
> -        else
> +        } else
>          {
>              String contents = "";
>
>              if (fields.size() > 0)
>              {
> -                contents = getText();
> +                contents = new String(((JPasswordField) fields.elementAt
> (0)).getPassword());
>              }
>
>              return (contents);
>          }
>      }
>
> -    // javadoc inherited
> -    public String getText()
> -    {
> -        return new String(((JPasswordField) fields.elementAt
> (0)).getPassword());
> -    }
> -
> -    // javadoc inherited
> -    public Map getValidatorParams()
> -    {
> -        return null;
> -    }
> -
> -    // javadoc inherited
> -    public boolean hasParams()
> -    {
> -        return false;
> -    }
>  }
>
>  /*---------------------------------------------------------------------------*/
> Index: src/lib/com/izforge/izpack/panels/PathSelectionPanel.java
> ===================================================================
> --- src/lib/com/izforge/izpack/panels/PathSelectionPanel.java    (revision
> 1998)
> +++ src/lib/com/izforge/izpack/panels/PathSelectionPanel.java    (working
> copy)
> @@ -91,9 +91,9 @@
>       */
>      protected void createLayout()
>      {
> -        // We woulduse the IzPanelLayout also in this "sub"panel.
> -        // In an IzPanel there are support of this layout manager at
> -        // more than one places. In this panel not, therefore we have
> +        // We would use the IzPanelLayout also in this "sub" panel.
> +        // In an IzPanel there is support for this layout manager in
> +        // more than one place, but not in this panel so we have
>          // to make all things needed.
>          // First create a layout helper.
>          LayoutHelper layoutHelper = new LayoutHelper(this);
> Index: src/lib/com/izforge/izpack/panels/ProcessingClient.java
> ===================================================================
> --- src/lib/com/izforge/izpack/panels/ProcessingClient.java    (revision
> 1998)
> +++ src/lib/com/izforge/izpack/panels/ProcessingClient.java    (working
> copy)
> @@ -58,7 +58,10 @@
>       */
>
> /*--------------------------------------------------------------------------*/
>      public String getFieldContents(int index);
> -
> +
> +// These newly added fields are similar to the functionality provided
> +// by the multiple validator support using the validator container.
> +
>
> /*---------------------------------------------------------------------------*/
>      /**
>       * Returns the field contents.
> Index: src/lib/com/izforge/izpack/panels/UserInputPanel.java
> ===================================================================
> --- src/lib/com/izforge/izpack/panels/UserInputPanel.java    (revision
> 1998)
> +++ src/lib/com/izforge/izpack/panels/UserInputPanel.java    (working
> copy)
> @@ -76,6 +76,8 @@
>  import com.izforge.izpack.util.OsConstraint;
>  import com.izforge.izpack.util.OsVersion;
>  import com.izforge.izpack.util.VariableSubstitutor;
> +import java.util.ArrayList;
> +import java.util.List;
>
>
>  /*---------------------------------------------------------------------------*/
>  /**
> @@ -1060,13 +1062,16 @@
>                  File ffile = new File(file);
>                  if (ffile.isDirectory()){
>                      idata.setVariable((String) field[POS_VARIABLE],file);
> +                    entries.add(new TextValuePair((String)
> field[POS_VARIABLE],file));
>                      return true;
>                  }
>                  else {
> +                    showMessage("dir.notdirectory");
>                      return false;
>                  }
>              }
>              else {
> +                showMessage("dir.nodirectory");
>                  return false;
>              }
>          }
> @@ -1078,6 +1083,13 @@
>          }
>      }
>
> +    private void showMessage(String messageType)
> +    {
> +        JOptionPane.showMessageDialog(parent, parent.langpack.getString("UserInputPanel."
> + messageType + ".message"),
> +                parent.langpack.getString("UserInputPanel." + messageType
> + ".caption"),
> +                JOptionPane.WARNING_MESSAGE);
> +    }
> +
>      private boolean readFileField(Object[] field)
>      {
>          try {
> @@ -1088,13 +1100,16 @@
>                  File ffile = new File(file);
>                  if (ffile.isFile()){
>                      idata.setVariable((String) field[POS_VARIABLE],file);
> +                    entries.add(new TextValuePair((String)
> field[POS_VARIABLE],file));
>                      return true;
>                  }
>                  else {
> +                    showMessage("file.notfile");
>                      return false;
>                  }
>              }
>              else {
> +                showMessage("file.nofile");
>                  return false;
>              }
>          }
> @@ -1973,8 +1988,24 @@
>       *        &lt;processor
> class=&quot;com.izforge.sample.PWDEncryptor&quot;/&gt;
>       *      &lt;/field&gt;
>       *
> +     * </pre>
> +     * Additionally, parameters and multiple validators can be used to
> provide
> +     * separate validation and error messages for each case.
> +     * <pre>
>       *
> -     *
> +     *    &lt;field type=&quot;password&quot; align=&quot;left&quot;
> variable=&quot;keystore.password&quot;&gt;
> +     *      &lt;spec&gt;
> +     *        &lt;pwd txt=&quot;Keystore Password:&quot;
> size=&quot;25&quot; set=&quot;&quot;/&gt;
> +     *        &lt;pwd txt=&quot;Retype Password:&quot;
> size=&quot;25&quot; set=&quot;&quot;/&gt;
> +     *      &lt;/spec&gt;
> +     *      &lt;validator
> class=&quot;com.izforge.izpack.util.PasswordEqualityValidator&quot;
> txt=&quot;Both keystore passwords must match.&quot; id=&quot;key for the
> error text&quot;/&gt;
> +     *      &lt;validator
> class=&quot;com.izforge.izpack.util.PasswordKeystoreValidator&quot;
> txt=&quot;Could not validate keystore with password and alias
> provided.&quot; id=&quot;key for the error text&quot;&gt;
> +     *        &lt;param name=&quot;keystoreFile&quot; value=&quot;${
> existing.ssl.keystore}&quot;/&gt;
> +     *        &lt;param name=&quot;keystoreType&quot;
> value=&quot;JKS&quot;/&gt;
> +     *        &lt;param name=&quot;keystoreAlias&quot; value=&quot;${
> keystore.key.alias}&quot;/&gt;
> +     *      &lt;/validator&gt;
> +     *    &lt;/field&gt;
> +     *
>       * </pre>
>       *
>       * @param spec a <code>XMLElement</code> containing the specification
> for the set of password
> @@ -1986,12 +2017,15 @@
>          Vector forPacks = spec.getChildrenNamed(SELECTEDPACKS);
>          Vector forOs = spec.getChildrenNamed(OS);
>          String variable = spec.getAttribute(VARIABLE);
> -        String validator = null;
>          String message = null;
>          String processor = null;
>          XMLElement element = null;
>          PasswordGroup group = null;
>          int size = 0;
> +        // For multiple validator support
> +        Vector validatorsElem = null;
> +        List validatorsList = new ArrayList();
> +        int vsize = 0;
>
>          // ----------------------------------------------------
>          // get the description and add it to the list of UI
> @@ -2003,11 +2037,36 @@
>          // ----------------------------------------------------
>          // get the validator and processor if they are defined
>          // ----------------------------------------------------
> -        element = spec.getFirstChildNamed(VALIDATOR);
> -        if (element != null)
> +
> +        validatorsElem = spec.getChildrenNamed(VALIDATOR);
> +        if (validatorsElem != null && validatorsElem.size() > 0)
>          {
> -            validator = element.getAttribute(CLASS);
> -            message = getText(element);
> +            vsize = validatorsElem.size();
> +            for (int i = 0; i < vsize; i++)
> +            {
> +                element = (XMLElement) validatorsElem.get(i);
> +                String validator = element.getAttribute(CLASS);
> +                message = getText(element);
> +                HashMap validateParamMap = new HashMap();
> +                //
> ----------------------------------------------------------
> +                // check and see if we have any parameters for this
> validator.
> +                // If so, then add them to validateParamMap.
> +                //
> ----------------------------------------------------------
> +                Vector validateParams = element.getChildrenNamed
> (RULE_PARAM);
> +                if (validateParams != null && validateParams.size() > 0)
> +                {
> +                    Iterator iter = validateParams.iterator();
> +                    while (iter.hasNext())
> +                    {
> +                        element = (XMLElement) iter.next();
> +                        String paramName = element.getAttribute
> (RULE_PARAM_NAME);
> +                        String paramValue = element.getAttribute
> (RULE_PARAM_VALUE);
> +                        // System.out.println("Adding parameter:
> "+paramName+"="+paramValue);
> +                        validateParamMap.put(paramName, paramValue);
> +                    }
> +                }
> +                validatorsList.add(new ValidatorContainer(validator,
> message, validateParamMap));
> +            }
>          }
>
>          element = spec.getFirstChildNamed(PROCESSOR);
> @@ -2016,7 +2075,7 @@
>              processor = element.getAttribute(CLASS);
>          }
>
> -        group = new PasswordGroup(validator, processor);
> +        group = new PasswordGroup(idata, validatorsList, processor);
>
>          // ----------------------------------------------------
>          // extract the specification details
> @@ -2067,8 +2126,14 @@
>                  TwoColumnConstraints constraints2 = new
> TwoColumnConstraints();
>                  constraints2.position = TwoColumnConstraints.EAST;
>
> -                uiElements.add(new Object[] { null, PWD_FIELD, variable,
> constraints2, field,
> -                        forPacks, forOs, null, null, message, group});
> +                // Removed message to support pulling from multiple
> validators
> +                uiElements.add(new Object[]{null, PWD_FIELD, variable,
> constraints2, field,
> +                    forPacks, forOs, null, null, null, group
> +                });
> +                // Original
> +//        uiElements.add(new Object[]{null, PWD_FIELD, variable,
> constraints2, field,
> +//          forPacks, forOs, null, null, message, group
> +//        });
>                  group.addField(field);
>              }
>          }
> @@ -2097,7 +2162,8 @@
>          {
>              group = (PasswordGroup) field[POS_GROUP];
>              variable = (String) field[POS_VARIABLE];
> -            message = (String) field[POS_MESSAGE];
> +        // Removed to support grabbing the message from multiple
> validators
> +        // message = (String) field[POS_MESSAGE];
>          }
>          catch (Throwable exception)
>          {
> @@ -2106,16 +2172,40 @@
>          if ((variable == null) || (passwordGroupsRead.contains(group))) {
> return (true); }
>          passwordGroups.add(group);
>
> -        boolean success = !validating || group.validateContents();
> +
> +        //boolean success = !validating || group.validateContents();
> +        boolean success = !validating;
> +
> +        // Use each validator to validate contents
>          if (!success)
>          {
> -            showWarningMessageDialog(parentFrame, message);
> -            return (false);
> +            int size = group.validatorSize();
> +            // System.out.println("Found "+(size)+" validators");
> +            for (int i = 0; i < size; i++)
> +            {
> +                success = group.validateContents(i);
> +                if (!success)
> +                {
> +                    JOptionPane.showMessageDialog(parentFrame,
> group.getValidatorMessage(i),
> +                            parentFrame.langpack.getString("
> UserInputPanel.error.caption"),
> +                            JOptionPane.WARNING_MESSAGE);
> +                    break;
> +                }
> +            }
>          }
>
> -        idata.setVariable(variable, group.getPassword());
> -        entries.add(new TextValuePair(variable, group.getPassword()));
> -        return (true);
> +//    // Changed to show messages for each validator
> +//    if (!success) {
> +//      JOptionPane.showMessageDialog(parentFrame, message,
> parentFrame.langpack.getString("UserInputPanel.error.caption"),
> JOptionPane.WARNING_MESSAGE);
> +//      return (false);
> +//    }
> +
> +        if (success)
> +        {
> +            idata.setVariable(variable, group.getPassword());
> +            entries.add(new TextValuePair(variable, group.getPassword
> ()));
> +        }
> +        return success;
>      }
>
>
> /*--------------------------------------------------------------------------*/
> Index: src/lib/com/izforge/izpack/panels/UserPathInputPanel.java
> ===================================================================
> --- src/lib/com/izforge/izpack/panels/UserPathInputPanel.java    (revision
> 0)
> +++ src/lib/com/izforge/izpack/panels/UserPathInputPanel.java    (revision
> 0)
> @@ -0,0 +1,422 @@
> +/*
> + * IzPack - Copyright 2001-2007 Julien Ponge, All Rights Reserved.
> + *
> + * http://izpack.org/
> + * http://developer.berlios.de/projects/izpack/
> + *
> + * Copyright 2004 Klaus Bartz
> + *
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at
> + *
> + *     http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +package com.izforge.izpack.panels;
> +
> +import java.awt.event.ActionEvent;
> +import java.awt.event.ActionListener;
> +import java.io.BufferedReader;
> +import java.io.File;
> +import java.io.IOException;
> +import java.io.InputStream;
> +import java.io.InputStreamReader;
> +
> +import com.izforge.izpack.gui.IzPanelLayout;
> +import com.izforge.izpack.installer.InstallData;
> +import com.izforge.izpack.installer.InstallerFrame;
> +import com.izforge.izpack.installer.IzPanel;
> +import com.izforge.izpack.installer.ResourceNotFoundException;
> +import com.izforge.izpack.util.AbstractUIHandler;
> +import com.izforge.izpack.util.Debug;
> +import com.izforge.izpack.util.IoHelper;
> +import com.izforge.izpack.util.OsVersion;
> +import com.izforge.izpack.util.VariableSubstitutor;
> +
> +/**
> + * Base class for panels which asks for paths.
> + *
> + * @author Klaus Bartz
> + * @author Jeff Gordon
> + *
> + */
> +public class UserPathInputPanel extends IzPanel implements ActionListener
> {
> +
> +  /**
> +   *
> +   */
> +  private InstallerFrame _parent;
> +  private InstallData _idata;
> +  private static final long serialVersionUID = 3257566217698292531L;
> +  /** Flag whether the choosen path must exist or not */
> +  protected boolean _mustExist = false;
> +  protected boolean _loadedDefaultDir = false;
> +  /** Files which should be exist */
> +  protected String[] _existFiles = null;
> +  /** The path which was chosen */
> +  // protected String chosenPath;
> +  /** The path selection sub panel */
> +  protected UserPathSelectionPanel _pathSelectionPanel;
> +  protected String _error;
> +  protected String _warn;
> +  protected String _emptyTargetMsg;
> +  protected String _warnMsg;
> +  protected String _reqMsg;
> +  protected String _notValidMsg;
> +  protected String _notWritableMsg;
> +  protected String _createDirMsg;
> +  protected String _defaultDir = null;
> +  protected String _thisPanel = "UserPathInputPanel";
> +  protected String _defaultPanelName = "TargetPanel";
> +  protected String _targetPanel = "UserPathPanel";
> +  protected String _variableName = "pathVariable";
> +
> +  /**
> +   * The constructor.
> +   *
> +   * @param parent The parent window.
> +   * @param idata The installation data.
> +   */
> +  public UserPathInputPanel(InstallerFrame parent, InstallData idata,
> String targetPanel, String variableName) {
> +    super(parent, idata, new IzPanelLayout());
> +    _parent = parent;
> +    _idata = idata;
> +    _targetPanel = targetPanel;
> +    _variableName = variableName;
> +    // Set default values
> +    loadMessages();
> +    String introText = getI18nStringForClass("extendedIntro",
> _thisPanel);
> +    if (introText == null || introText.endsWith("extendedIntro") ||
> introText.indexOf('$') > -1) {
> +      introText = getI18nStringForClass("intro", _thisPanel);
> +      if (introText == null || introText.endsWith("intro")) {
> +        introText = "";
> +      }
> +    }
> +    // Intro
> +    // row 0 column 0
> +    add(createMultiLineLabel(introText));
> +    add(IzPanelLayout.createParagraphGap());
> +    // Label for input
> +    // row 1 column 0.
> +    add(createLabel("info", _targetPanel, "open", LEFT, true),
> NEXT_LINE);
> +    // Create path selection components and add they to this panel.
> +    _pathSelectionPanel = new UserPathSelectionPanel(this, idata,
> _targetPanel, _variableName);
> +    add(_pathSelectionPanel, NEXT_LINE);
> +    createLayoutBottom();
> +    getLayoutHelper().completeLayout();
> +  }
> +
> +  /**
> +   * This method does nothing. It is called from ctor of
> UserPathInputPanel, to give in a derived
> +   * class the possibility to add more components under the path input
> components.
> +   */
> +  public void createLayoutBottom() {
> +  // Derived classes implements additional elements.
> +  }
> +
> +  /**
> +   * Actions-handling method.
> +   *
> +   * @param e The event.
> +   */
> +  public void actionPerformed(ActionEvent e) {
> +    Object source = e.getSource();
> +    if (source == _pathSelectionPanel.getPathInputField()) {
> +      parent.navigateNext();
> +    }
> +
> +  }
> +
> +  private void loadMessages() {
> +    _error = parent.langpack.getString("installer.error");
> +    _warn = parent.langpack.getString("installer.warning");
> +    _reqMsg = getMessage("required");
> +    _emptyTargetMsg = getMessage("empty_target");
> +    _warnMsg = getMessage("exists_warn");
> +    _notValidMsg = getMessage("notValid");
> +    _notWritableMsg = getMessage("notwritable");
> +    _createDirMsg = getMessage("createdir");
> +  }
> +
> +  private String getMessage(String type) {
> +    String msg = null;
> +    msg = getI18nStringForClass(type, _targetPanel);
> +    if (msg == null) {
> +      msg = getI18nStringForClass(type, _defaultPanelName);
> +    }
> +    return msg;
> +  }
> +
> +  /**
> +   * Indicates whether the panel has been validated or not.
> +   *
> +   * @return Whether the panel has been validated or not.
> +   */
> +  public boolean isValidated() {
> +    String chosenPath = _pathSelectionPanel.getPath();
> +    boolean ok = true;
> +    // We put a warning if the specified target is nameless
> +    if (chosenPath.length() == 0) {
> +      if (isMustExist()) {
> +        emitError(_error, _reqMsg);
> +        return false;
> +      }
> +      ok = emitWarning(_warn, _emptyTargetMsg);
> +    }
> +    if (!ok) {
> +      return ok;
> +    }
> +    // Normalize the path
> +    File path = new File(chosenPath).getAbsoluteFile();
> +    chosenPath = path.toString();
> +    _pathSelectionPanel.setPath(chosenPath);
> +    if (isMustExist()) {
> +      if (!path.exists()) {
> +        emitError(_error, _reqMsg);
> +        return false;
> +      }
> +      if (!pathIsValid()) {
> +        emitError(_error, _notValidMsg);
> +        return false;
> +      }
> +    } else {
> +      // We assume, that we would install something into this dir
> +      if (!isWriteable()) {
> +        emitError(_error, _notWritableMsg);
> +        return false;
> +      }
> +      // We put a warning if the directory exists else we warn
> +      // that it will be created
> +      if (path.exists()) {
> +        int res = askQuestion(_warn, _warnMsg,
> +                AbstractUIHandler.CHOICES_YES_NO,
> AbstractUIHandler.ANSWER_YES);
> +        ok = res == AbstractUIHandler.ANSWER_YES;
> +      } else {
> +        ok = this.emitNotificationFeedback(_createDirMsg + "\n" +
> chosenPath);
> +      }
> +    }
> +    return ok;
> +  }
> +
> +  /**
> +   * Returns whether the chosen path is true or not. If existFiles are
> not null, the existence of
> +   * it under the choosen path are detected. This method can be also
> implemented in derived
> +   * classes to handle special verification of the path.
> +   *
> +   * @return true if existFiles are exist or not defined, else false
> +   */
> +  protected boolean pathIsValid() {
> +    if (_existFiles == null) {
> +      return true;
> +    }
> +    for (int i = 0; i < _existFiles.length; ++i) {
> +      File path = new File(_pathSelectionPanel.getPath(),
> _existFiles[i]).getAbsoluteFile();
> +      if (!path.exists()) {
> +        return false;
> +      }
> +    }
> +    return true;
> +  }
> +
> +  /**
> +   * Returns the must exist state.
> +   *
> +   * @return the must exist state
> +   */
> +  public boolean isMustExist() {
> +    return _mustExist;
> +  }
> +
> +  /**
> +   * Sets the must exist state. If it is true, the path must exist.
> +   *
> +   * @param b must exist state
> +   */
> +  public void setMustExist(boolean b) {
> +    _mustExist = b;
> +  }
> +
> +  /**
> +   * Returns the array of strings which are described the files which
> must exist.
> +   *
> +   * @return paths of files which must exist
> +   */
> +  public String[] getExistFiles() {
> +    return _existFiles;
> +  }
> +
> +  /**
> +   * Sets the paths of files which must exist under the chosen path.
> +   *
> +   * @param strings paths of files which must exist under the chosen path
> +   */
> +  public void setExistFiles(String[] strings) {
> +    _existFiles = strings;
> +  }
> +
> +  /**
> +   * "targetPanel" is typically the class name of the implementing panel,
> such as
> +   * "UserPathPanel" or "TargetPanel" set when the class is created, but
> can be set
> +   * with setDefaultDir().
> +   * Loads up the "dir" resource associated with targetPanel. Acceptable
> dir resource names:
> +   * <code>
> +   *   targetPanel.dir.macosx
> +   *   targetPanel.dir.mac
> +   *   targetPanel.dir.windows
> +   *   targetPanel.dir.unix
> +   *   targetPanel.dir.xxx,
> +   *     where xxx is the lower case version of System.getProperty("
> os.name"),
> +   *     with any spaces replace with underscores
> +   *   targetPanel.dir (generic that will be applied if none of above is
> found)
> +   *   </code>
> +   * As with all IzPack resources, each the above ids should be
> associated with a separate
> +   * filename, which is set in the install.xml file at compile time.
> +   */
> +  private void loadDefaultDir() {
> +    // Load only once ...
> +    if (!(_loadedDefaultDir)) {
> +      BufferedReader br = null;
> +      try {
> +        InputStream in = null;
> +        if (OsVersion.IS_WINDOWS) {
> +          try {
> +            in = _parent.getResource(_targetPanel + ".dir.windows");
> +          } catch (ResourceNotFoundException rnfe) {
> +          }//it's usual, that the resource does not exist
> +        } else if (OsVersion.IS_OSX) {
> +          try {
> +            in = _parent.getResource(_targetPanel + ".dir.macosx");
> +          } catch (ResourceNotFoundException rnfe) {
> +          }//it's usual, that the resource does not exist
> +        } else {
> +          String os = System.getProperty("os.name");
> +          // first try to look up by specific os name
> +          os = os.replace(' ', '_'); // avoid spaces in file names
> +          os = os.toLowerCase(); // for consistency among targetPanel res
> files
> +          try {
> +            in = _parent.getResource(_targetPanel + ".dir.".concat(os));
> +          } catch (ResourceNotFoundException rnfe) {
> +          }
> +          // if not specific os, try getting generic 'unix' resource file
> +          if (in == null) {
> +            try {
> +              in = _parent.getResource(_targetPanel + ".dir.unix");
> +            } catch (ResourceNotFoundException eee) {
> +            }
> +          }
> +        }
> +        // if all above tests failed, there is no resource file,
> +        // so use system default
> +        if (in == null) {
> +          try {
> +            in = _parent.getResource(_targetPanel + ".dir");
> +          } catch (ResourceNotFoundException eee) {
> +          }
> +        }
> +        if (in != null) {
> +          // now read the file, once we've identified which one to read
> +          InputStreamReader isr = new InputStreamReader(in);
> +          br = new BufferedReader(isr);
> +          String line;
> +          while ((line = br.readLine()) != null) {
> +            line = line.trim();
> +            // use the first non-blank line
> +            if (!"".equals(line)) {
> +              break;
> +            }
> +          }
> +          _defaultDir = line;
> +          VariableSubstitutor vs = new VariableSubstitutor(
> idata.getVariables());
> +          _defaultDir = vs.substitute(_defaultDir, null);
> +        }
> +      } catch (Exception e) {
> +        //mar: what's the common way to log an exception ?
> +        e.printStackTrace();
> +        _defaultDir = null;
> +      // leave unset to take the system default set by Installer class
> +      } finally {
> +        try {
> +          if (br != null) {
> +            br.close();
> +          }
> +        } catch (IOException ignored) {
> +        }
> +      }
> +    }
> +    _loadedDefaultDir = true;
> +  }
> +
> +  /**
> +   * This method determines whether the chosen dir is writeable or not.
> +   *
> +   * @return whether the chosen dir is writeable or not
> +   */
> +  public boolean isWriteable() {
> +    File existParent = IoHelper.existingParent(new
> File(_pathSelectionPanel.getPath()));
> +    if (existParent == null) {
> +      return false;
> +    }
> +    // On windows we cannot use canWrite because
> +    // it looks to the dos flags which are not valid
> +    // on NT or 2k XP or ...
> +    if (OsVersion.IS_WINDOWS) {
> +      File tmpFile;
> +      try {
> +        tmpFile = File.createTempFile("izWrTe", ".tmp", existParent);
> +        tmpFile.deleteOnExit();
> +      } catch (IOException e) {
> +        Debug.trace(e.toString());
> +        return false;
> +      }
> +      return true;
> +    }
> +    return existParent.canWrite();
> +  }
> +
> +  /**
> +   * Returns the default for the directory.
> +   *
> +   * @return the default for the directory
> +   */
> +  public String getDefaultDir() {
> +    if (_defaultDir == null && (!(_loadedDefaultDir))) {
> +      loadDefaultDir();
> +    }
> +    return _defaultDir;
> +  }
> +
> +  /**
> +   * Sets the default for the directory to the given string.
> +   *
> +   * @param string path for default directory
> +   */
> +  public void setDefaultDir(String string) {
> +    _defaultDir = string;
> +  }
> +
> +  /**
> +   * Returns the panel name extending this class.
> +   * Used for looking up localized text and resources.
> +   *
> +   * @return the default for the directory
> +   */
> +  public String getTargetPanel() {
> +    return _targetPanel;
> +  }
> +
> +  /**
> +   * Sets the panel name extending this class.
> +   * Used for looking up localized text and resources.
> +   *
> +   * @param string path for default directory
> +   */
> +  public void setTargetPanel(String string) {
> +    _targetPanel = string;
> +  }
> +}
> Index: src/lib/com/izforge/izpack/panels/UserPathPanel.java
> ===================================================================
> --- src/lib/com/izforge/izpack/panels/UserPathPanel.java    (revision 0)
> +++ src/lib/com/izforge/izpack/panels/UserPathPanel.java    (revision 0)
> @@ -0,0 +1,138 @@
> +/*
> + * IzPack - Copyright 2001-2007 Julien Ponge, All Rights Reserved.
> + *
> + * http://izpack.org/
> + * http://developer.berlios.de/projects/izpack/
> + *
> + * Copyright 2004 Klaus Bartz
> + *
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at
> + *
> + *     http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +package com.izforge.izpack.panels;
> +
> +import com.izforge.izpack.Pack;
> +import net.n3.nanoxml.XMLElement;
> +
> +import com.izforge.izpack.installer.InstallData;
> +import com.izforge.izpack.installer.InstallerFrame;
> +import com.izforge.izpack.util.AbstractUIHandler;
> +import com.izforge.izpack.util.Debug;
> +import com.izforge.izpack.util.OsConstraint;
> +import java.util.ArrayList;
> +import java.util.HashMap;
> +import java.util.Iterator;
> +
> +/**
> + * The taget directory selection panel.
> + *
> + * @author Julien Ponge
> + * @author Jeff Gordon
> + */
> +public class UserPathPanel extends UserPathInputPanel {
> +
> +  /**
> +   *
> +   */
> +  private static final long serialVersionUID = 3256443616359429170L;
> +  private static String thisName = "UserPathPanel";
> +  private boolean _skip = false;
> +  public static String pathVariableName = "UserPathPanelVariable";
> +  public static String pathPackDependsName = "UserPathPanelDependsName";
> +  public static String pathElementName = "UserPathPanelElement";
> +  private XMLElement panelElement;
> +
> +  /**
> +   * The constructor.
> +   *
> +   * @param parent The parent window.
> +   * @param idata The installation data.
> +   */
> +  public UserPathPanel(InstallerFrame parent, InstallData idata) {
> +    super(parent, idata, thisName, parent.langpack.getString
> (thisName+".variableName"));
> +    // load the default directory info (if present)
> +    if (getDefaultDir() != null) {
> +      idata.setVariable(pathVariableName, getDefaultDir());
> +    }
> +  }
> +
> +  /** Called when the panel becomes active. */
> +  public void panelActivate() {
> +    boolean found = false;
> +    System.out.println(thisName+" looking for activation condition");
> +    // Need to have a way to supress panel if not in selected packs.
> +    String dependsName = idata.getVariable(pathPackDependsName);
> +    if (dependsName!=null && !(dependsName.equalsIgnoreCase(""))) {
> +      System.out.println("Checking for pack dependency of "+dependsName);
> +      Iterator iter = idata.selectedPacks.iterator();
> +      while (iter.hasNext()) {
> +        Pack pack = (Pack)iter.next();
> +        System.out.println("- Checking if "+pack.name+" equals
> "+dependsName);
> +        if (pack.name.equalsIgnoreCase(dependsName)) {
> +          found = true;
> +          System.out.println("-- Found "+dependsName+", panel will be
> shown");
> +          break;
> +        }
> +      }
> +      _skip = !(found);
> +    } else {
> +      System.out.println("Not Checking for a pack dependency, panel will
> be shown");
> +      _skip = false;
> +    }
> +    if (_skip) {
> +      System.out.println(thisName+" will not be shown");
> +      parent.skipPanel();
> +      return;
> +    }
> +    super.panelActivate();
> +    // Set the default or old value to the path selection panel.
> +    _pathSelectionPanel.setPath(idata.getVariable(pathVariableName));
> +  }
> +
> +  /**
> +   * Indicates whether the panel has been validated or not.
> +   *
> +   * @return Whether the panel has been validated or not.
> +   */
> +  public boolean isValidated() {
> +    // Standard behavior of PathInputPanel.
> +    if (!super.isValidated()) {
> +      return (false);
> +    }
> +    idata.setVariable(pathVariableName, _pathSelectionPanel.getPath());
> +    return (true);
> +  }
> +
> +  /**
> +   * Asks to make the XML panel data.
> +   *
> +   * @param panelRoot The tree to put the data in.
> +   */
> +  public void makeXMLData(XMLElement panelRoot) {
> +    if (!(_skip)) {
> +      new UserPathPanelAutomationHelper().makeXMLData(idata, panelRoot);
> +    }
> +  }
> +
> +  /*
> +   * (non-Javadoc)
> +   *
> +   * @see com.izforge.izpack.installer.IzPanel#getSummaryBody()
> +   */
> +  public String getSummaryBody() {
> +    if (_skip) {
> +      return null;
> +    } else {
> +      return (idata.getVariable(pathVariableName));
> +    }
> +  }
> +}
> Index:
> src/lib/com/izforge/izpack/panels/UserPathPanelAutomationHelper.java
> ===================================================================
> ---
> src/lib/com/izforge/izpack/panels/UserPathPanelAutomationHelper.java
> (revision 0)
> +++
> src/lib/com/izforge/izpack/panels/UserPathPanelAutomationHelper.java
> (revision 0)
> @@ -0,0 +1,77 @@
> +/*
> + * IzPack - Copyright 2001-2007 Julien Ponge, All Rights Reserved.
> + *
> + * http://izpack.org/
> + * http://developer.berlios.de/projects/izpack/
> + *
> + * Copyright 2003 Jonathan Halliday
> + *
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at
> + *
> + *     http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +package com.izforge.izpack.panels;
> +
> +import net.n3.nanoxml.XMLElement;
> +import com.izforge.izpack.installer.AutomatedInstallData;
> +import com.izforge.izpack.installer.PanelAutomation;
> +import com.izforge.izpack.util.VariableSubstitutor;
> +
> +/**
> + * Functions to support automated usage of the UserPathPanel
> + *
> + * @author Jonathan Halliday
> + * @author Julien Ponge
> + * @author Jeff Gordon
> + */
> +public class UserPathPanelAutomationHelper implements PanelAutomation {
> +
> +  /**
> +   * Asks to make the XML panel data.
> +   *
> +   * @param idata The installation data.
> +   * @param panelRoot The tree to put the data in.
> +   */
> +  public void makeXMLData(AutomatedInstallData idata, XMLElement
> panelRoot) {
> +    // Installation path markup
> +    XMLElement ipath = new XMLElement(UserPathPanel.pathElementName);
> +    // check this writes even if value is the default,
> +    // because without the constructor, default does not get set.
> +    ipath.setContent(idata.getVariable(UserPathPanel.pathVariableName));
> +
> +    // Checkings to fix bug #1864
> +    XMLElement prev = panelRoot.getFirstChildNamed(
> UserPathPanel.pathElementName);
> +    if (prev != null) {
> +      panelRoot.removeChild(prev);
> +    }
> +    panelRoot.addChild(ipath);
> +  }
> +
> +  /**
> +   * Asks to run in the automated mode.
> +   *
> +   * @param idata The installation data.
> +   * @param panelRoot The XML tree to read the data from.
> +   *
> +   * @return always true.
> +   */
> +  public boolean runAutomated(AutomatedInstallData idata, XMLElement
> panelRoot) {
> +    // We set the installation path
> +    XMLElement ipath = panelRoot.getFirstChildNamed(
> UserPathPanel.pathElementName);
> +
> +    // Allow for variable substitution of the installpath value
> +    VariableSubstitutor vs = new VariableSubstitutor(idata.getVariables
> ());
> +    String path = ipath.getContent();
> +    path = vs.substitute(path, null);
> +    idata.setVariable(UserPathPanel.pathVariableName, path);
> +    return true;
> +  }
> +}
> Index: src/lib/com/izforge/izpack/panels/UserPathSelectionPanel.java
> ===================================================================
> --- src/lib/com/izforge/izpack/panels/UserPathSelectionPanel.java
> (revision 0)
> +++ src/lib/com/izforge/izpack/panels/UserPathSelectionPanel.java
> (revision 0)
> @@ -0,0 +1,197 @@
> +/*
> + * IzPack - Copyright 2001-2007 Julien Ponge, All Rights Reserved.
> + *
> + * http://izpack.org/
> + * http://developer.berlios.de/projects/izpack/
> + *
> + * Copyright 2004 Klaus Bartz
> + *
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at
> + *
> + *     http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +package com.izforge.izpack.panels;
> +
> +import java.awt.Dimension;
> +import java.awt.event.ActionEvent;
> +import java.awt.event.ActionListener;
> +import java.io.File;
> +
> +import javax.swing.JButton;
> +import javax.swing.JFileChooser;
> +import javax.swing.JPanel;
> +import javax.swing.JTextField;
> +
> +import com.izforge.izpack.gui.ButtonFactory;
> +import com.izforge.izpack.gui.IzPanelConstraints;
> +import com.izforge.izpack.gui.IzPanelLayout;
> +import com.izforge.izpack.gui.LayoutConstants;
> +import com.izforge.izpack.installer.InstallData;
> +import com.izforge.izpack.installer.IzPanel;
> +import com.izforge.izpack.installer.LayoutHelper;
> +
> +/**
> + * This is a sub panel which contains a text field and a browse button
> for path selection. This is
> + * NOT an IzPanel, else it is made to use in an IzPanel for any path
> selection. If the IzPanel
> + * parent implements ActionListener, the ActionPerformed method will be
> called, if
> + * PathSelectionPanel.ActionPerformed was called with a source other than
> the browse button. This
> + * can be used to perform parentFrame.navigateNext in the IzPanel parent.
> An example implementation
> + * is done in com.izforge.izpack.panels.PathInputPanel.
> + *
> + * @author Klaus Bartz
> + * @author Jeff Gordon
> + *
> + */
> +public class UserPathSelectionPanel extends JPanel implements
> ActionListener, LayoutConstants {
> +
> +  /**
> +   *
> +   */
> +  private static final long serialVersionUID ...
>
> [Message clipped]
-------------- next part --------------
An HTML attachment was scrubbed...
URL: https://lists.berlios.de/pipermail/izpack-devel/attachments/20080124/ad4c0fef/attachment-0001.html 


More information about the izpack-devel mailing list