<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>src/lib/com/izforge/izpack/panels/DirInputField.java</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -706,6 +706,7 @@
             &lt;include name=&quot;com/izforge/izpack/panels/RuleTextField.java&quot;/&gt;
             &lt;include name=&quot;com/izforge/izpack/panels/TextInputField.java&quot;/&gt;
         	&lt;include name=&quot;com/izforge/izpack/panels/FileInputField.java&quot;/&gt;
+        	&lt;include name=&quot;com/izforge/izpack/panels/DirInputField.java&quot;/&gt;
         	&lt;include name=&quot;com/izforge/izpack/panels/MultipleFileInputField.java&quot;/&gt;
             &lt;include name=&quot;com/izforge/izpack/panels/UserInputPanel.java&quot;/&gt;
             &lt;include name=&quot;com/izforge/izpack/panels/UserInputPanelAutomationHelper.java&quot;/&gt;
@@ -732,6 +733,7 @@
             &lt;include name=&quot;com/izforge/izpack/panels/RuleInputField.java&quot;/&gt;
             &lt;include name=&quot;com/izforge/izpack/panels/RuleTextField.java&quot;/&gt;
         	&lt;include name=&quot;com/izforge/izpack/panels/FileInputField.java&quot;/&gt;
+        	&lt;include name=&quot;com/izforge/izpack/panels/DirInputField.java&quot;/&gt;
         	&lt;include name=&quot;com/izforge/izpack/panels/MultipleFileInputField.java&quot;/&gt;
             &lt;include name=&quot;com/izforge/izpack/panels/TextInputField.java&quot;/&gt;
             &lt;include name=&quot;com/izforge/izpack/panels/UserInputPanel.java&quot;/&gt;</diff>
      <filename>src/build.xml</filename>
    </modified>
    <modified>
      <diff>@@ -642,7 +642,7 @@ the selection or a static text element can be added to display above the selecti
 
        &lt;field type=&quot;staticText&quot; align=&quot;left&quot; txt=&quot;Existing SSL keystore to import:&quot;/&gt;
         &lt;field type=&quot;file&quot; align=&quot;left&quot; variable=&quot;existing.ssl.keystore&quot;&gt;
-          &lt;spec txt=&quot;&quot; size=&quot;25&quot; set=&quot;$myconfig&quot; mustExist=&quot;false&quot; /&gt;
+          &lt;spec txt=&quot;&quot; size=&quot;25&quot; set=&quot;$myconfig&quot; /&gt;
         &lt;/field&gt;
 
 .. image:: file-field.png
@@ -746,6 +746,15 @@ field will ensure a directory is selected.
         &lt;/field&gt;
 
 
+
+The directory supports the following two special attributes for the ``&lt;spec&gt;`` element:
+
+**mustExist** `- optional (default: true)`
+Specifies whether or not the selected path must be an existing directory.
+
+**create** `- optional (default: false)`
+Specifies whether or not the selected directory should be created if it does not exist (requires `mustExist=true`).
+
 Messages for the directory field can be customized by creating a custom lang pack and
 overriding the following values (attribute values wrapped for readability):
 </diff>
      <filename>src/doc-reST/user-input.txt</filename>
    </modified>
    <modified>
      <diff>@@ -22,8 +22,6 @@ package com.izforge.izpack.panels;
 
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
-import java.awt.event.FocusEvent;
-import java.awt.event.FocusListener;
 import java.io.*;
 import java.util.List;
 
@@ -38,16 +36,12 @@ import com.izforge.izpack.installer.InstallData;
 import com.izforge.izpack.installer.InstallerFrame;
 import com.izforge.izpack.installer.IzPanel;
 import com.izforge.izpack.util.Debug;
-import com.izforge.izpack.util.IoHelper;
-import com.izforge.izpack.util.OsVersion;
 
-public class FileInputField extends JPanel implements ActionListener, FocusListener
+public class FileInputField extends JPanel implements ActionListener
 {
 
     private static final long serialVersionUID = 4673684743657328492L;
 
-    boolean isDirectory;
-
     InstallerFrame parentFrame;
 
     IzPanel parent;
@@ -69,18 +63,17 @@ public class FileInputField extends JPanel implements ActionListener, FocusListe
     String fileExtensionDescription;
 
     boolean allowEmpty;
+    
+    protected static final int INVALID = 0, EMPTY = 1; 
 
-    boolean mustExist;
-
-    public FileInputField(IzPanel parent, InstallData data, boolean directory, boolean mustExist,
-            String set, int size, List&lt;ValidatorContainer&gt; validatorConfig)
+    public FileInputField(IzPanel parent, InstallData data, boolean directory, String set,
+            int size, List&lt;ValidatorContainer&gt; validatorConfig)
     {
-        this(parent, data, directory, mustExist, set, size, validatorConfig, null, null);
+        this(parent, data, directory, set, size, validatorConfig, null, null);
     }
 
-    public FileInputField(IzPanel parent, InstallData data, boolean directory, boolean mustExist,
-            String set, int size, List&lt;ValidatorContainer&gt; validatorConfig, String fileExt,
-            String fileExtDesc)
+    public FileInputField(IzPanel parent, InstallData data, boolean directory, String set,
+            int size, List&lt;ValidatorContainer&gt; validatorConfig, String fileExt, String fileExtDesc)
     {
         this.parent = parent;
         this.parentFrame = parent.getInstallerFrame();
@@ -90,16 +83,13 @@ public class FileInputField extends JPanel implements ActionListener, FocusListe
         this.size = size;
         this.fileExtension = fileExt;
         this.fileExtensionDescription = fileExtDesc;
-        this.isDirectory = directory;
-        this.mustExist = mustExist;
         this.initialize();
     }
 
-    public void initialize()
+    private void initialize()
     {
         filetxt = new JTextField(set, size);
         filetxt.setCaretPosition(0);
-        filetxt.addFocusListener(this);
 
         // TODO: use separate key for button text
         browseBtn = ButtonFactory.createButton(data.langpack
@@ -125,21 +115,7 @@ public class FileInputField extends JPanel implements ActionListener, FocusListe
                 initialPath = filetxt.getText();
             }
             JFileChooser filechooser = new JFileChooser(initialPath);
-            if (isDirectory)
-            {
-                filechooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
-            }
-            else
-            {
-                filechooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
-                if ((fileExtension != null) &amp;&amp; (fileExtensionDescription != null))
-                {
-                    UserInputFileFilter fileFilter = new UserInputFileFilter();
-                    fileFilter.setFileExt(fileExtension);
-                    fileFilter.setFileExtDesc(fileExtensionDescription);
-                    filechooser.setFileFilter(fileFilter);
-                }
-            }
+            prepareFileChooser(filechooser);
 
             if (filechooser.showOpenDialog(parentFrame) == JFileChooser.APPROVE_OPTION)
             {
@@ -149,6 +125,17 @@ public class FileInputField extends JPanel implements ActionListener, FocusListe
             }
         }
     }
+    
+    protected void prepareFileChooser(JFileChooser filechooser) {
+        filechooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
+        if ((fileExtension != null) &amp;&amp; (fileExtensionDescription != null))
+        {
+            UserInputFileFilter fileFilter = new UserInputFileFilter();
+            fileFilter.setFileExt(fileExtension);
+            fileFilter.setFileExtDesc(fileExtensionDescription);
+            filechooser.setFileFilter(fileFilter);
+        }
+    }
 
     public File getSelectedFile()
     {
@@ -160,7 +147,19 @@ public class FileInputField extends JPanel implements ActionListener, FocusListe
         return result;
     }
 
-    private void showMessage(String messageType)
+    protected void showMessage(int k)
+    {
+        if (k == INVALID)
+        {
+            showMessage(&quot;file.notfile&quot;);
+        }
+        else if (k == EMPTY)
+        {
+            showMessage(&quot;file.nofile&quot;);
+        }
+    }
+    
+    protected void showMessage(String messageType)
     {
         JOptionPane.showMessageDialog(parentFrame, parentFrame.langpack.getString(&quot;UserInputPanel.&quot;
                 + messageType + &quot;.message&quot;), parentFrame.langpack.getString(&quot;UserInputPanel.&quot;
@@ -171,37 +170,30 @@ public class FileInputField extends JPanel implements ActionListener, FocusListe
     {
         boolean result = false;
         String input = filetxt.getText();
+        
         if (allowEmpty &amp;&amp; ((input == null) || (input.length() == 0)))
         {
             result = true;
         }
         else if (input != null)
         {
-            File file = new File(input);
-
-            if (isDirectory &amp;&amp; !file.isDirectory())
+            // Expand unix home reference
+            if (input.startsWith(&quot;~&quot;))
             {
-                if (mustExist)
-                {
-                    result = false;
-                    showMessage(&quot;dir.notdirectory&quot;);
-                }
-                else
-                {
-                    result = verifyCreateOK();
-                }
+                String home = System.getProperty(&quot;user.home&quot;);
+                input = home + input.substring(1);
             }
-            else if (!isDirectory &amp;&amp; !file.isFile())
+
+            // Normalize the path
+            File file = new File(input).getAbsoluteFile();
+            input = file.toString();
+
+            filetxt.setText(input);
+            
+            if (!_validate(file))
             {
-                if (mustExist)
-                {
-                    result = false;
-                    showMessage(&quot;file.notfile&quot;);
-                }
-                else
-                {
-                    result = verifyCreateOK();
-                }
+                result = false;
+                showMessage(INVALID);
             }
             else
             {
@@ -221,81 +213,14 @@ public class FileInputField extends JPanel implements ActionListener, FocusListe
         }
         else
         {
-            if (isDirectory)
-            {
-                showMessage(&quot;dir.nodirectory&quot;);
-            }
-            else
-            {
-                showMessage(&quot;file.nofile&quot;);
-            }
+            showMessage(EMPTY);
         }
         return result;
     }
 
-    public boolean verifyCreateOK()
-    {
-        String chosenPath = filetxt.getText();
-
-        // Expand unix home reference
-        if (chosenPath.startsWith(&quot;~&quot;))
-        {
-            String home = System.getProperty(&quot;user.home&quot;);
-            chosenPath = home + chosenPath.substring(1);
-        }
-
-        // Normalize the path
-        File path = new File(chosenPath).getAbsoluteFile();
-        chosenPath = path.toString();
-
-        filetxt.setText(chosenPath);
-
-        if (!path.exists())
-        {
-            if (!parent.emitNotificationFeedback(parent.getI18nStringForClass(&quot;createdir&quot;,
-                    &quot;TargetPanel&quot;)
-                    + &quot;\n&quot; + chosenPath)) return false;
-        }
-
-        // We assume, that we would install something into this dir
-        if (!isWriteable())
-        {
-            parent.emitError(parentFrame.langpack.getString(&quot;installer.error&quot;), parent
-                    .getI18nStringForClass(&quot;notwritable&quot;, &quot;TargetPanel&quot;));
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * This method determines whether the chosen dir is writeable or not.
-     * 
-     * @return whether the chosen dir is writeable or not
-     */
-    public boolean isWriteable()
+    protected boolean _validate(File file)
     {
-        File existParent = IoHelper.existingParent(new File(filetxt.getText()));
-        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(&quot;izWrTe&quot;, &quot;.tmp&quot;, existParent);
-                tmpFile.deleteOnExit();
-            }
-            catch (IOException e)
-            {
-                Debug.trace(e.toString());
-                return false;
-            }
-            return true;
-        }
-        return existParent.canWrite();
+        return file.isFile();
     }
 
     public boolean isAllowEmptyInput()
@@ -307,18 +232,4 @@ public class FileInputField extends JPanel implements ActionListener, FocusListe
     {
         this.allowEmpty = allowEmpty;
     }
-
-    public void focusGained(FocusEvent e)
-    {
-        // TODO Auto-generated method stub
-
-    }
-
-    public void focusLost(FocusEvent e)
-    {
-        if (e.getSource() == this.filetxt)
-        {
-
-        }
-    }
 }</diff>
      <filename>src/lib/com/izforge/izpack/panels/FileInputField.java</filename>
    </modified>
    <modified>
      <diff>@@ -570,7 +570,7 @@ public class UserInputPanel extends IzPanel implements ActionListener, ItemListe
         if ((variable == null) || (variable.length() == 0)) { return; }
 
         boolean allowEmptyValue = false;
-        boolean mustExist = true;
+        boolean mustExist = true, create = true;
 
         List&lt;ValidatorContainer&gt; validatorConfig;
         IXMLElement element = field.getFirstChildNamed(SPEC);
@@ -618,6 +618,7 @@ public class UserInputPanel extends IzPanel implements ActionListener, ItemListe
                     .parseBoolean(element.getAttribute(&quot;allowEmptyValue&quot;, &quot;false&quot;));
 
             mustExist = Boolean.parseBoolean(element.getAttribute(&quot;mustExist&quot;, &quot;true&quot;));
+            create = Boolean.parseBoolean(element.getAttribute(&quot;create&quot;, &quot;false&quot;));
         }
         validatorConfig = analyzeValidator(field);
 
@@ -635,9 +636,9 @@ public class UserInputPanel extends IzPanel implements ActionListener, ItemListe
         TwoColumnConstraints constraints2 = new TwoColumnConstraints();
         constraints2.position = TwoColumnConstraints.EAST;
 
-        FileInputField fileInput = new FileInputField(this, idata, true, mustExist, set, size,
-                validatorConfig);
-
+        FileInputField fileInput = new DirInputField(this, idata, true, set, size,
+                validatorConfig, mustExist, create);
+        
         fileInput.setAllowEmptyInput(allowEmptyValue);
 
         UIElement dirUiElement = new UIElement();
@@ -878,7 +879,7 @@ public class UserInputPanel extends IzPanel implements ActionListener, ItemListe
         TwoColumnConstraints constraints2 = new TwoColumnConstraints();
         constraints2.position = TwoColumnConstraints.EAST;
 
-        FileInputField fileInputField = new FileInputField(this, idata, false, true, set, size,
+        FileInputField fileInputField = new FileInputField(this, idata, false, set, size,
                 validatorConfig, filter, filterdesc);
 
         fileInputField.setAllowEmptyInput(allowEmptyValue);</diff>
      <filename>src/lib/com/izforge/izpack/panels/UserInputPanel.java</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>d3fb293706c817728c853416390715e0bfa8fd24</id>
    </parent>
  </parents>
  <author>
    <name>afflux</name>
    <email>afflux@7d736ef5-cfd4-0310-9c9a-b52d5c14b761</email>
  </author>
  <url>http://github.com/jponge/izpack/commit/569586e4c32446f3177d9c46f93443e5f53153d3</url>
  <id>569586e4c32446f3177d9c46f93443e5f53153d3</id>
  <committed-date>2009-10-06T07:50:25-07:00</committed-date>
  <authored-date>2009-10-06T07:50:25-07:00</authored-date>
  <message>IZPACK-465: clean up FileInputField (added subclass DirInputField), added 'create' attribute for dir fields

git-svn-id: https://svn.codehaus.org/izpack/izpack-src/trunk@2864 7d736ef5-cfd4-0310-9c9a-b52d5c14b761</message>
  <tree>8a778b30fb894ac3b186d53e7d22cffe0f90d920</tree>
  <committer>
    <name>afflux</name>
    <email>afflux@7d736ef5-cfd4-0310-9c9a-b52d5c14b761</email>
  </committer>
</commit>
