[IC] - Apontando para IzPack fork no nexus.

     - Correcoes de bugs serao mantidas no nexus
     local ate serem integradas no projeto principal.
Bug 1025: Uninstaller window title is not internationalized.

Workaround:

--- a/izpack-uninstaller/src/main/java/com/izforge/izpack/uninstaller/gui/UninstallerFrame.java
+++ b/izpack-uninstaller/src/main/java/com/izforge/izpack/uninstaller/gui/UninstallerFrame.java
@@ -130,7 +130,7 @@ public class UninstallerFrame extends JFrame
     public UninstallerFrame(Destroyer destroyer, InstallLog log, Housekeeper housekeeper, Messages messages)
             throws Exception
     {
-        super("IzPack - Uninstaller");
+        super(messages.get("uninstaller.uninstall"));
         this.destroyer = destroyer;
         this.log = log;
         this.housekeeper = housekeeper;

Link: http://jira.codehaus.org/browse/IZPACK-1025
Bug 1026: No font family definition on SummaryPanel's textArea (JEditorPane).

There's no font-family definition on SummaryPanel HTML content.
The default html font differs from the default font in the panels.
This html content can be found in class SummaryProcessor.java

Workaround:

--- a/izpack-installer/src/main/java/com/izforge/izpack/installer/util/SummaryProcessor.java
+++ b/izpack-installer/src/main/java/com/izforge/izpack/installer/util/SummaryProcessor.java
@@ -53,8 +53,8 @@ public class SummaryProcessor
         buffer.append("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n").append(
                 "<html>\n" + "<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">" +
                         "<head>\n<STYLE TYPE=\"text/css\" media=screen,print>\n").append(
-                "h1{\n  font-size: 100%;\n  margin: 1em 0 0 0;\n  padding: 0;\n}\n").append(
-                "div.body {\n  font-size: 100%;\n  margin: 0mm 2mm 0  8mm;\n  padding: 0;\n}\n")
+                "h1{\n  font-size: 100%;\n  margin: 1em 0 0 0;\n  padding: 0;\n  font-family: \"Arial\";}\n").append(
+                "div.body {\n  font-size: 100%;\n  margin: 0mm 2mm 0  8mm;\n  padding: 0;\n  font-family: \"Arial\";}\n")
                 .append("</STYLE>\n</head>\n<body>\n");
         HTML_HEADER = buffer.toString();
     }

Link: https://jira.codehaus.org/browse/IZPACK-1026
Bug 1027: Wrong font on InstallationGroupPanel's description field.

InstallationGroupPanel's description field is using a wrong/unnecessary and it's not using the default font family.

Workaround:

--- a/izpack-panel/src/main/java/com/izforge/izpack/panels/installationgroup/InstallationGroupPanel.java
+++ b/izpack-panel/src/main/java/com/izforge/izpack/panels/installationgroup/InstallationGroupPanel.java
@@ -317,7 +317,7 @@ public class InstallationGroupPanel extends IzPanel
         descriptionField.setEditable(false);
         descriptionField.setOpaque(false);
         descriptionField.setText("<b>Install group description text</b>");
-        descriptionField.setContentType("text/html");
+        descriptionField.setFont(getControlTextFont());
         descriptionField.setBorder(
                 new TitledBorder(getString("PacksPanel.description")));
         gridBagConstraints = new java.awt.GridBagConstraints();

Link: https://jira.codehaus.org/browse/IZPACK-1027
Bug 1028: ShortcutPanel "defaultName" variables are replaced only at the first time.

Variables used on ShortcutPanel to set "defaultName" are being replaced only at the first time the panel is shown.

Steps to reproduce the bug:

- in you "shortcuts.xml", put something like: <programGroup defaultName="$SOME_VARIABLE"...;

- the value of $SOME_VARIABLE must be conditionally set in any kind of panel BEFORE ShortcutPanel;
- after you reach ShortcutPanel, use "previous" button to go back to the panel that changes the value of $SOME_VARIABLE;
- when you reach ShortcutPanel again, the default name will still show the previous (outdated) value of $SOME_VARIABLE.

Workaround:

--- a/izpack-panel/src/main/java/com/izforge/izpack/panels/shortcut/ShortcutPanel.java
+++ b/izpack-panel/src/main/java/com/izforge/izpack/panels/shortcut/ShortcutPanel.java
@@ -334,6 +334,14 @@ public class ShortcutPanel extends IzPanel implements ActionListener, ListSelect
     {
         if (shortcutPanelLogic != null)
         {
+            try {
+                shortcutPanelLogic.createAndRegisterShortcutsBugFix();
+                if (programGroup != null) {
+                    programGroup.setText(shortcutPanelLogic.getSuggestedProgramGroup());
+                }
+            } catch ( Exception exc ) {
+                throw new RuntimeException(exc.getMessage(), exc);
+            }
             if (!initialised)
             {
                 initialised = true;

--- a/izpack-panel/src/main/java/com/izforge/izpack/panels/shortcut/ShortcutPanelLogic.java
+++ b/izpack-panel/src/main/java/com/izforge/izpack/panels/shortcut/ShortcutPanelLogic.java
@@ -361,6 +361,18 @@ public class ShortcutPanelLogic implements CleanupClient
         addToUninstaller();
     }

+    public void createAndRegisterShortcutsBugFix() throws Exception
+    {
+        String groupName = this.groupName;
+        boolean createShortcuts = this.createShortcuts;
+        boolean createDesktopShortcuts = this.createDesktopShortcuts;
+        readShortcutSpec();  // need to re-read the specs now as variable replacement needs to be done
+        analyzeShortcutSpec();
+        this.groupName = groupName;
+        this.createShortcuts = createShortcuts;
+        this.createDesktopShortcuts = createDesktopShortcuts;
+    }
+

Link: https://jira.codehaus.org/browse/IZPACK-1028
Ajuste layout (linha acima dos botões previous/next/quit).

Pequeno ajuste no layout: remoção do caractere espaço "hard coded" após o valor da chave
"installer.madewith" no text usado junto a linha inferior (acima dos botões).

Com este espaço eliminado, é possível redefinr o valor da chave "installer.madewith" no
arquivo de mensagens customizado e utilizar uma String em branco, sem impacto no layout
(o caractere de espaço existente gerava um espaçamento indesejado nessas situações).

Este ajuste foi necessário para NÃO exibir o nome do produto IzPack nas telas do instalador.
Verificou-se não ser necessário exibir nenhuma informação neste lugar, por isso foi necessário
eliminar o caractere espaço.

Workaround:

--- a/izpack-installer/src/main/java/com/izforge/izpack/installer/gui/InstallerFrame.java
+++ b/izpack-installer/src/main/java/com/izforge/izpack/installer/gui/InstallerFrame.java
@@ -339,7 +339,7 @@ public class InstallerFrame extends JFrame implements InstallerView
         JPanel navPanel = new JPanel();
         navPanel.setLayout(new BoxLayout(navPanel, BoxLayout.X_AXIS));
         TitledBorder border = BorderFactory.createTitledBorder(
-                new EtchedLineBorder(), messages.get("installer.madewith") + " ",
+                new EtchedLineBorder(), messages.get("installer.madewith"),
                 TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, new Font("Dialog", Font.PLAIN, 10));
         navPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8), border));
Impedir erro quando se trata de atualização de uma instalação com IzPack 4.x.

Ajuste para não gerar exceção quando a este instalador (IzPack 5.x) está sendo usado
para atualizar uma instalação gerada com uma versão antiga do IzPack (4.x ou inferior).

Não é necessário nenhum tratamento adicional, basta ignorar o erro.

Workaround:

--- a/izpack-installer/src/main/java/com/izforge/izpack/installer/unpacker/UnpackerBase.java
+++ b/izpack-installer/src/main/java/com/izforge/izpack/installer/unpacker/UnpackerBase.java
@@ -1114,18 +1114,23 @@ public abstract class UnpackerBase implements IUnpacker
             FileInputStream fin = new FileInputStream(installationInfo);
             ObjectInputStream oin = new ObjectInputStream(fin);

-            List<Pack> packs;
+            List<Pack> packs = null;
             try
             {
                 packs = (List<Pack>) oin.readObject();
             }
             catch (Exception exception)
             {
-                throw new InstallerException("Failed to read previous installation information", exception);
+                // exception if old information is from IzPack 4.x
+                // there's no need to raise an error in such situation
+                // one can simply ignore it
             }
-            for (Pack pack : packs)
+            if ( packs != null )
             {
-                installedPacks.add(pack);
+                for (Pack pack : packs)
+                {
+                    installedPacks.add(pack);
+                }
             }
             FileUtils.close(oin);
             FileUtils.close(fin);

Segundo workaround:

Outra maneira de contornar esta situação sem a alteração de código mostrada acima, é deletar o arquivo
.installationinformation existente na pasta de instalação do produto atual.
Não exibir mensagem de sucesso em caso de erro no ProcessPanel.

Foi adicionada a seguinte verificação final no último painel da instalação:

- o conteúdo do arquivo de log principal será lido;
- se o arquivo conter a String "BUILD FAILED" será considerado situação de "não sucesso";
- nesse caso, será exibida uma mensagem informativa, exibindo o nome deste arquivo de log
e um link para o usuário abrir o arquivo e verificar manualmente.

A alteração em ProcessPanelWorker.java é apenas para gravar como uma variável do IzPack
o nome do arquivo de log, já que este é gerado dinamicamente e formado por uma parte aleatória.

Workaround:

--- a/izpack-panel/src/main/java/com/izforge/izpack/panels/finish/FinishConsolePanel.java
+++ b/izpack-panel/src/main/java/com/izforge/izpack/panels/finish/FinishConsolePanel.java
@@ -45,6 +45,7 @@ import com.izforge.izpack.installer.console.ConsolePanelAutomationHelper;
 import com.izforge.izpack.installer.container.provider.AutomatedPanelsProvider;
 import com.izforge.izpack.installer.panel.PanelView;
 import com.izforge.izpack.util.Console;
+import com.izforge.izpack.util.FileUtil;
 import com.izforge.izpack.util.PlatformModelMatcher;
 import com.izforge.izpack.util.file.FileUtils;

@@ -109,6 +110,14 @@ public class FinishConsolePanel extends AbstractConsolePanel
             generateAutoInstallScript(installData, console);
         }

+        String tempLogFile = installData.getVariable("tempLogFile");
+        final String tempLogFilePath = installData.getInstallPath() + File.separator + tempLogFile;
+        boolean caseInSensitiveSearch = true;
+        boolean errorFound = FileUtil.fileContains(tempLogFilePath , "BUILD FAILED", caseInSensitiveSearch);
+        if (errorFound) {
+            installData.setInstallSuccess(false);
+        }
+
         if (installData.isInstallSuccess())
         {
             console.println("Installation was successful");
@@ -117,6 +126,9 @@ public class FinishConsolePanel extends AbstractConsolePanel
         else
         {
             console.println("Install Failed!!!");
+            console.println("The installation might not have completely succeeded! Check the file:");
+            console.println();
+            console.println(tempLogFilePath);
         }
         return true;
     }

--- a/izpack-panel/src/main/java/com/izforge/izpack/panels/simplefinish/SimpleFinishPanel.java
+++ b/izpack-panel/src/main/java/com/izforge/izpack/panels/simplefinish/SimpleFinishPanel.java
@@ -19,6 +19,10 @@

 package com.izforge.izpack.panels.simplefinish;

+import java.awt.Cursor;
+import java.awt.Desktop;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
 import java.io.File;

 import javax.swing.JLabel;
@@ -33,6 +37,7 @@ import com.izforge.izpack.installer.data.GUIInstallData;
 import com.izforge.izpack.installer.data.UninstallDataWriter;
 import com.izforge.izpack.installer.gui.InstallerFrame;
 import com.izforge.izpack.installer.gui.IzPanel;
+import com.izforge.izpack.util.FileUtil;

 /**
  * The simple finish panel class.
@@ -86,6 +91,15 @@ public class SimpleFinishPanel extends IzPanel
      */
     public void panelActivate()
     {
+
+        String tempLogFile = installData.getVariable("tempLogFile");
+        final String tempLogFilePath = installData.getInstallPath() + File.separator + tempLogFile;
+        boolean caseInSensitiveSearch = true;
+        boolean errorFound = FileUtil.fileContains(tempLogFilePath , "BUILD FAILED", caseInSensitiveSearch);
+        if (errorFound) {
+            this.installData.setInstallSuccess(false);
+        }
+
         parent.lockNextButton();
         parent.lockPrevButton();
         parent.setQuitButtonText(getString("FinishPanel.done"));
@@ -118,6 +132,34 @@ public class SimpleFinishPanel extends IzPanel
         {
             add(LabelFactory.create(getString("FinishPanel.fail"),
                                     parent.getIcons().get("stop"), LEADING));
+            add(IzPanelLayout.createVerticalStrut(5));
+            add(LabelFactory.create(getString("FinishPanel.fail.check.file"), null, LEADING), NEXT_LINE);
+            JLabel tempLogFileLabel = LabelFactory.create("<HTML><BODY><A HREF='#'>"+tempLogFile+"</A></BODY></HTML>", null, LEADING);
+            tempLogFileLabel.setToolTipText(tempLogFilePath);
+            tempLogFileLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+            tempLogFileLabel.addMouseListener( new MouseListener() {
+                @Override
+                public void mouseReleased(MouseEvent e) {
+                }
+                @Override
+                public void mousePressed(MouseEvent e) {
+                }
+                @Override
+                public void mouseExited(MouseEvent e) {
+                }
+                @Override
+                public void mouseEntered(MouseEvent e) {
+                }
+                @Override
+                public void mouseClicked(MouseEvent e) {
+                    try {
+                        Desktop.getDesktop().open(new File(tempLogFilePath));
+                    } catch (Exception exc) {
+                        throw new RuntimeException(exc.getMessage(), exc);
+                    }
+                }
+            });
+            add(tempLogFileLabel, NEXT_LINE);
         }
         getLayoutHelper().completeLayout(); // Call, or call not?
         log.informUser();

--- a/izpack-panel/src/main/java/com/izforge/izpack/panels/process/ProcessPanelWorker.java
+++ b/izpack-panel/src/main/java/com/izforge/izpack/panels/process/ProcessPanelWorker.java
@@ -317,6 +317,7 @@ public class ProcessPanelWorker implements Runnable
             {
                 File tempLogFile = File.createTempFile("Install_" + identifier + "_", ".log",
                                                        new File(logfiledir));
+                idata.setVariable("tempLogFile", tempLogFile.getName());
                 logfile = new PrintWriter(new FileOutputStream(tempLogFile), true);
             }
             catch (IOException e)
Validação do caminho de instalação informado e teste de instalação antiga.

Adicionada validação no caminho informado pelo usuário para a instalação.

Foram implementados os seguintes critérios:

- apenas caminhos absolutos são permitidos;
- caminho em branco não é mais permitido;
- validação sintática de acordo com a plataforma. Por exemplo, em Windows, um
caminho do tipo "cc:\" será considerado inválido.

Além disso, foi eliminada a restrição em relação a versãoes antigas do instalador: o método
"isIncompatibleInstallation(String)" irá sempre retornar false, ou seja, nenhuma instalação
será bloqueada por se tratar de um update em cima de uma versão antiga do IzPack.

Workaround:

--- a/izpack-panel/src/main/java/com/izforge/izpack/panels/path/PathInputPanel.java
+++ b/izpack-panel/src/main/java/com/izforge/izpack/panels/path/PathInputPanel.java
@@ -39,6 +39,7 @@ import com.izforge.izpack.gui.log.Log;
 import com.izforge.izpack.installer.data.GUIInstallData;
 import com.izforge.izpack.installer.gui.InstallerFrame;
 import com.izforge.izpack.installer.gui.IzPanel;
+import com.izforge.izpack.panels.target.TargetPanelHelper;
 import com.izforge.izpack.util.IoHelper;
 import com.izforge.izpack.util.Platforms;

@@ -172,12 +173,18 @@ public class PathInputPanel extends IzPanel implements ActionListener
     {
         String path = getPath();

-        if (path.length() == 0 && !checkEmptyPath())
+        if (path.length() == 0 /*&& !checkEmptyPath()*/)
         {
+            emitError(getString("installer.error"), getI18nStringForClass("empty_target_is_forbidden", "TargetPanel"));
             // Empty path disallowed
             return false;
         }

+        if ( !TargetPanelHelper.isValidPath(installData, path) ) {
+            emitError(getString("installer.error") + " - " + getString("UserInputPanel.dir.notdirectory.caption"), getString(getI18nStringForClass("dir.nodirectory.message", "UserInputPanel")));
+            return false;
+        }
+
         // Normalize the path
         File file = new File(path).getAbsoluteFile();
         pathSelectionPanel.setPath(file.toString());

--- a/izpack-panel/src/main/java/com/izforge/izpack/panels/target/TargetConsolePanel.java
+++ b/izpack-panel/src/main/java/com/izforge/izpack/panels/target/TargetConsolePanel.java
@@ -109,6 +109,12 @@ public class TargetConsolePanel extends AbstractConsolePanel implements ConsoleP
             }
             else if (!path.isEmpty())
             {
+                if ( !TargetPanelHelper.isValidPath(installData, path) ) {
+                    console.println(installData.getMessages().get("installer.error") + ": "
+                        + installData.getMessages().get("UserInputPanel.dir.notdirectory.caption") + ". "
+                        + installData.getMessages().get("UserInputPanel.dir.nodirectory.message"));
+                    return run(installData, console);
+                }
                 File selectedDir = new File(path);
                 if (selectedDir.exists() && selectedDir.isDirectory() && selectedDir.list().length > 0)
                 {

--- a/izpack-panel/src/main/java/com/izforge/izpack/panels/target/TargetPanelHelper.java
+++ b/izpack-panel/src/main/java/com/izforge/izpack/panels/target/TargetPanelHelper.java
@@ -26,10 +26,13 @@ import java.util.Collections;
 import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;

 import com.izforge.izpack.api.data.InstallData;
 import com.izforge.izpack.api.data.Pack;
 import com.izforge.izpack.util.Platform;
+import com.izforge.izpack.util.Platform.Name;
 import com.izforge.izpack.util.file.FileUtils;

@@ -105,39 +108,7 @@ public class TargetPanelHelper
     @SuppressWarnings("unchecked")
     public static boolean isIncompatibleInstallation(String dir)
     {
-        boolean result = false;
-        File file = new File(dir, InstallData.INSTALLATION_INFORMATION);
-        if (file.exists())
-        {
-            FileInputStream input = null;
-            ObjectInputStream objectInput = null;
-            try
-            {
-                input = new FileInputStream(file);
-                objectInput = new ObjectInputStream(input);
-                List<Object> packs = (List<Object>) objectInput.readObject();
-                for (Object pack : packs)
-                {
-                    if (!(pack instanceof Pack))
-                    {
-                        return true;
-                    }
-                }
-            }
-            catch (Throwable exception)
-            {
-                logger.log(Level.FINE, "Installation information at path=" + file.getPath()
-                        + " failed to deserialize", exception);
-                result = true;
-            }
-            finally
-            {
-                FileUtils.close(objectInput);
-                FileUtils.close(input);
-            }
-        }
-
-        return result;
+        return false; // always compatible!!!
     }

--- a/izpack-panel/src/main/java/com/izforge/izpack/panels/target/TargetPanelHelper.java
+++ b/izpack-panel/src/main/java/com/izforge/izpack/panels/target/TargetPanelHelper.java
@@ -26,10 +26,13 @@ import java.util.Collections;
 import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;

 import com.izforge.izpack.api.data.InstallData;
 import com.izforge.izpack.api.data.Pack;
 import com.izforge.izpack.util.Platform;
+import com.izforge.izpack.util.Platform.Name;
 import com.izforge.izpack.util.file.FileUtils;

@@ -199,4 +202,15 @@ public class TargetPanelHelper
         }
         return path;
     }
+
+    public static boolean isValidPath(InstallData installData, String path) {
+        Pattern p;
+        if (installData.getPlatform().isA(Name.WINDOWS)) {
+            p = Pattern.compile("[a-zA-z]:\\\\.*");
+        } else {
+            p = Pattern.compile("/.*");
+        }
+        Matcher m = p.matcher(path);
+        return m.matches();
+    }
 }

--- a/izpack-panel/src/test/java/com/izforge/izpack/panels/target/TargetConsolePanelTest.java
+++ b/izpack-panel/src/test/java/com/izforge/izpack/panels/target/TargetConsolePanelTest.java
@@ -22,7 +22,6 @@ package com.izforge.izpack.panels.target;

 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;

 import java.io.File;
@@ -104,7 +103,7 @@ public class TargetConsolePanelTest
         assertTrue(console.scriptCompleted());

         // verify that the install path wasn't set
-        assertNull(installData.getInstallPath());
+        /* assertNull(installData.getInstallPath()); */

         // run the panel, selecting "goodDir"
         console.addScript("TargetPanel.2", goodDir.getAbsolutePath(), "1");
@@ -134,7 +133,7 @@ public class TargetConsolePanelTest
         properties.setProperty(InstallData.INSTALL_PATH, badDir.getAbsolutePath());

         TargetConsolePanel panel = new TargetConsolePanel(null);
-        assertFalse(panel.run(installData, properties));
+        /* assertFalse(panel.run(installData, properties)); */

         properties.setProperty(InstallData.INSTALL_PATH, goodDir.getAbsolutePath());
         assertTrue(panel.run(installData, properties));

--- a/izpack-panel/src/test/java/com/izforge/izpack/panels/target/TargetPanelAutomationTest.java
+++ b/izpack-panel/src/test/java/com/izforge/izpack/panels/target/TargetPanelAutomationTest.java
@@ -22,7 +22,6 @@ package com.izforge.izpack.panels.target;

 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;

 import java.io.File;
 import java.io.IOException;
@@ -96,7 +95,7 @@ public class TargetPanelAutomationTest
         {
             TargetPanelTestHelper.createBadInstallationInfo(badDir);
             panel.runAutomated(installData, badPath);
-            fail("Expected runAutomated() to fail");
+            /* fail("Expected runAutomated() to fail"); */
         }
         catch (InstallerException expected)
         {

--- a/izpack-panel/src/test/java/com/izforge/izpack/panels/target/TargetPanelHelperTest.java
+++ b/izpack-panel/src/test/java/com/izforge/izpack/panels/target/TargetPanelHelperTest.java
@@ -182,6 +182,6 @@ public class TargetPanelHelperTest
         objStream = new ObjectOutputStream(stream);
         objStream.writeObject(new Integer(1));
         objStream.close();
-        assertTrue(TargetPanelHelper.isIncompatibleInstallation(dir.getPath()));
+        /* assertTrue(TargetPanelHelper.isIncompatibleInstallation(dir.getPath())); */
     }
 }
Bug 1022: Chaves i18n faltantes e customizações.

Adicionadas chaves faltantes no idioma italiando e adicionadas chaves customizadas
(italiando e inglês). A questão das chaves faltantes foi relatada no Jira do projeto
(ver link abaixo).

Link: https://jira.codehaus.org/browse/IZPACK-1022

--- a/izpack-core/src/main/resources/com/izforge/izpack/bin/langpacks/installer/eng.xml
+++ b/izpack-core/src/main/resources/com/izforge/izpack/bin/langpacks/installer/eng.xml
@@ -93,6 +93,8 @@
     <str id="TargetPanel.browse" txt="Browse..."/>
     <str id="TargetPanel.warn"
          txt="The directory already exists! Are you sure you want to install here and possibly overwrite existing files?"/>
+    <str id="TargetPanel.empty_target_is_forbidden"
+         txt="You have not specified a target location! Please choose a directory!"/>
     <str id="TargetPanel.empty_target"
          txt="You have not specified a target location! Is this correct?"/>
     <str id="TargetPanel.createdir" txt="The target directory will be created: "/>
@@ -120,6 +122,7 @@

     <!-- PacksPanel strings -->
     <str id="PacksPanel.info" txt="Select the packs you want to install:"/>
+    <str id="PacksPanel.error" txt="Select the packs you want to install!"/>
     <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: "/>
@@ -156,6 +159,8 @@
     <str id="FinishPanel.success" txt="Installation has completed successfully."/>
     <str id="FinishPanel.done" txt="Done"/>
     <str id="FinishPanel.fail" txt="Installation has failed!"/>
+    <str id="FinishPanel.fail.check.file" txt="The installation might not have completely succeeded! Check the file:"/>
+
     <str id="FinishPanel.uninst.info" txt="An uninstaller program has been created in: "/>
     <str id="FinishPanel.auto" txt="Generate an automatic installation script"/>
     <str id="FinishPanel.auto.tip"

--- a/izpack-core/src/main/resources/com/izforge/izpack/bin/langpacks/installer/ita.xml
+++ b/izpack-core/src/main/resources/com/izforge/izpack/bin/langpacks/installer/ita.xml
@@ -50,6 +50,7 @@
     <str id="installer.step" txt="Step"/>
     <str id="installer.of" txt="di"/>
     <str id="installer.Message" txt="Messaggio"/>
+    <str id="installer.uninstall.writefailed" txt="Impossibile scrivere le informazioni di disinstallazione."/>

     <!-- Uninstaller specific strings -->
     <str id="uninstaller.warning" txt="Verranno disinstallate la(e) applicazione(i) selezionate!"/>
@@ -90,10 +91,14 @@
     <str id="TargetPanel.browse" txt="Sfoglia..."/>
     <str id="TargetPanel.warn"
          txt="Questa cartella esiste già! Siete sicuri di usare questa cartella ed eventualmente sostituire i file esistenti?"/>
+    <str id="TargetPanel.empty_target_is_forbidden"
+         txt="Non è stato specificato il percorso di destinazione! Selezionare una cartella!"/>
     <str id="TargetPanel.empty_target" txt="Non è stato specificato il percorso di destinazione! Continuare?"/>
     <str id="TargetPanel.createdir" txt="Verrà creata la cartella: "/>
     <str id="TargetPanel.nodir" txt="Questa non è una cartella! Selezionare una cartella!"/>
     <str id="TargetPanel.notwritable" txt="Quasta cartella non è scrivibile! Selezionare un'altra cartella!"/>
+    <str id="TargetPanel.incompatibleInstallation"
+         txt="Installazione Incompatibile rilevato. Disinstallarlo prima, o scegliere un'altra directory per l'installazione."/>

     <str id="JDKPathPanel.extendedIntro"
          txt="Il programma installato richiede una JDK di versione compresa tra ${JDKPathPanel.minVersion} e ${JDKPathPanel.maxVersion}. Una Java Runtime Environment (JRE) non è sufficiente."/>
@@ -107,6 +112,7 @@
          txt="Il registro di Windows contiene un percorso non valido per questa JDK. Volete usare comunque questa JDK?"/>

     <str id="PacksPanel.info" txt="Scegliere i componenti da installare:"/>
+    <str id="PacksPanel.error" txt="Scegliere i componenti da installare!"/>
     <str id="PacksPanel.tip" txt="Nota: i componenti in grigio sono obbligatori."/>
     <str id="PacksPanel.space" txt="Spazio totale necessario: "/>
     <str id="PacksPanel.description" txt="Descrizione"/>
@@ -305,4 +311,7 @@
     <str id="InstallationGroupPanel.colNameSize" txt="Dimensione"/>

     <str id="debug.changevariable" txt="modifica valore"/>
+
+    <str id="data.validation.error.title" txt="Convalida non riuscita"/>
+    <str id="data.validation.warning.title" txt="Convalida non riuscita - installazione permanente"/>
 </izpack:langpack>
Apontando o projeto para o repositório 'third-party'
Commit inicial da versão 5.0.0-rc3-SNAPSHOT do projeto "izpack".
Melhorias atributos tag "pack":
 - criado atributo "readonly" para a difinição dos pacotes;
 - suporte a valores variáveis (IzPack variable ou conditional) para
   os atributos de pacote "required", "preselected" e "readonly".

--- a/izpack-api/src/main/java/com/izforge/izpack/api/data/Pack.java
+++ b/izpack-api/src/main/java/com/izforge/izpack/api/data/Pack.java
@@ -110,6 +110,19 @@ public class Pack implements Serializable
     private boolean required;

     /**
+     * Original value for attribute "required" from "install-script.xml".
+     *
+     * How it works:
+     * Every time a panel is switched, the boolean value "required" will be revaluated based on this String original definition:
+     * <ul>
+     *      <li>if "yes"/"true" or "no"/"false", it will be converted to a boolean (it's a constant);</li>
+     *      <li>if starts with $ or ${}, it will be evaluated as a IzPack variable;</li>
+     *      <li>otherwise, it will be evaluated as a IzPack condition.</li>
+     * </ul>
+     */
+    private String requiredExpr;
+
+    /**
      * The size of the pack. This may include reserved space, independent of the size of the files.
      */
     private long size;
@@ -125,6 +138,37 @@ public class Pack implements Serializable
     private boolean preselected;

     /**
+     * Original value for attribute "preselected" from "install-script.xml".
+     *
+     * How it works:
+     * Every time a panel is switched, the boolean value "preselected" will be revaluated based on this String original definition:
+     * <ul>
+     *      <li>if "yes"/"true" or "no"/"false", it will be converted to a boolean (it's a constant);</li>
+     *      <li>if starts with $ or ${}, it will be evaluated as a IzPack variable;</li>
+     *      <li>otherwise, it will be evaluated as a IzPack condition.</li>
+     * </ul>
+     */
+    private String preselectedExpr;
+
+    /**
+     * Determines if the pack should be read only.
+     */
+    private boolean readonly;
+
+    /**
+     * Original value for attribute "readonly" from "install-script.xml".
+     *
+     * How it works:
+     * Every time a panel is switched, the boolean value "readonly" will be revaluated based on this String original definition:
+     * <ul>
+     *      <li>if "yes"/"true" or "no"/"false", it will be converted to a boolean (it's a constant);</li>
+     *      <li>if starts with $ or ${}, it will be evaluated as a IzPack variable;</li>
+     *      <li>otherwise, it will be evaluated as a IzPack condition.</li>
+     * </ul>
+     */
+    private String readonlyExpr;
+
+    /**
      * Parent pack name. May be {@code null}
      */
     private String parent;
@@ -336,6 +380,15 @@ public class Pack implements Serializable
         return required;
     }

+    public String getRequiredExpr()
+    {
+        return requiredExpr;
+    }
+
+    public void setRequired(boolean required) {
+        this.required = required;
+    }
+
     /**
      * Determines if the pack should be preselected for installation.
      *
@@ -346,6 +399,17 @@ public class Pack implements Serializable
         this.preselected = preselected;
     }

+
+    /**
+     * Determines if the pack should be read only.
+     *
+     * @param preselected if {@code true}, the pack should be read only
+     */
+    public void setReadonly(boolean readonly)
+    {
+        this.readonly = readonly;
+    }
+
     /**
      * Determines if the pack should be preselected for installation.
      *
@@ -356,6 +420,26 @@ public class Pack implements Serializable
         return preselected;
     }

+    public String getPreselectedExpr()
+    {
+        return preselectedExpr;
+    }
+
+    /**
+     * Determines if the pack should be read only.
+     *
+     * @return {@code true} if the pack should be read only
+     */
+    public boolean isReadonly()
+    {
+        return readonly;
+    }
+
+    public String getReadonlyExpr()
+    {
+        return readonlyExpr;
+    }
+
     /**
      * Determines if pack files are stored outside of the installation packages.
      *
@@ -640,4 +724,16 @@ public class Pack implements Serializable
         }
     }

+    public void setRequiredExpr(String requiredExpr) {
+        this.requiredExpr = requiredExpr;
+    }
+
+    public void setPreselectedExpr(String preselectedExpr) {
+        this.preselectedExpr = preselectedExpr;
+    }
+
+    public void setReadonlyExpr(String readonlyExpr) {
+        this.readonlyExpr = readonlyExpr;
+    }
+
 }

--- a/izpack-compiler/src/main/java/com/izforge/izpack/compiler/CompilerConfig.java
+++ b/izpack-compiler/src/main/java/com/izforge/izpack/compiler/CompilerConfig.java
@@ -743,10 +743,13 @@ public class CompilerConfig extends Thread

             boolean loose = Boolean.parseBoolean(packElement.getAttribute("loose", "false"));
             String description = xmlCompilerHelper.requireChildNamed(packElement, "description").getContent();
-            boolean required = xmlCompilerHelper.requireYesNoAttribute(packElement, "required");
+            boolean required = xmlCompilerHelper.requireYesNoAttributeDynamic(packElement, "required");
             String group = packElement.getAttribute("group");
             String installGroups = packElement.getAttribute("installGroups");
             String excludeGroup = packElement.getAttribute("excludeGroup");
+            String requiredExpr = packElement.getAttribute("required");
+            String preselectedExpr = packElement.getAttribute("preselected");
+            String readonlyExpr = packElement.getAttribute("readonly");
             boolean uninstall = "yes".equalsIgnoreCase(packElement.getAttribute("uninstall", "yes"));
             long size = xmlCompilerHelper.getLong(packElement, "size", 0);
             String parent = packElement.getAttribute("parent");
@@ -830,6 +833,10 @@ public class CompilerConfig extends Thread
                 pack.addValidator(type.getName());
             }

+            pack.setRequiredExpr(requiredExpr);
+            pack.setPreselectedExpr(preselectedExpr);
+            pack.setReadonlyExpr(readonlyExpr);
+
             // We add the pack
             packager.addPack(pack);
         }

--- a/izpack-compiler/src/main/java/com/izforge/izpack/compiler/helper/XmlCompilerHelper.java
+++ b/izpack-compiler/src/main/java/com/izforge/izpack/compiler/helper/XmlCompilerHelper.java
@@ -133,6 +133,12 @@ public class XmlCompilerHelper
         return validateYesNoAttribute(element, attribute, null);
     }

+    public boolean requireYesNoAttributeDynamic(IXMLElement element, String attribute)
+            throws CompilerException
+    {
+        return validateYesNoAttribute(element, attribute, false);
+    }
+
     /**
      * Call getAttribute on an element, producing a meaningful warning if not "yes" or "no". If the
      * 'element' or 'attribute' are null, the default value is returned.

--- a/izpack-installer/src/main/java/com/izforge/izpack/installer/console/ConsoleInstallAction.java
+++ b/izpack-installer/src/main/java/com/izforge/izpack/installer/console/ConsoleInstallAction.java
@@ -23,6 +23,7 @@ package com.izforge.izpack.installer.console;

 import com.izforge.izpack.api.data.InstallData;
 import com.izforge.izpack.installer.data.UninstallDataWriter;
+import com.izforge.izpack.installer.gui.InstallerFrame;
 import com.izforge.izpack.util.Console;

 /**
@@ -61,6 +62,7 @@ public class ConsoleInstallAction extends AbstractInstallAction
     public boolean run(ConsolePanelView panel)
     {
         ConsolePanel view = panel.getView();
+        InstallerFrame.revaluateDynamicAttributes(getInstallData());
         return view.run(getInstallData(), console);
     }

--- a/izpack-installer/src/main/java/com/izforge/izpack/installer/console/ConsoleInstaller.java
+++ b/izpack-installer/src/main/java/com/izforge/izpack/installer/console/ConsoleInstaller.java
@@ -35,6 +35,7 @@ import com.izforge.izpack.api.exception.IzPackException;
 import com.izforge.izpack.installer.base.InstallerBase;
 import com.izforge.izpack.installer.bootstrap.Installer;
 import com.izforge.izpack.installer.data.UninstallDataWriter;
+import com.izforge.izpack.installer.gui.InstallerFrame;
 import com.izforge.izpack.installer.requirement.RequirementsChecker;
 import com.izforge.izpack.util.Console;
 import com.izforge.izpack.util.Housekeeper;

--- a/izpack-installer/src/main/java/com/izforge/izpack/installer/gui/InstallerFrame.java
+++ b/izpack-installer/src/main/java/com/izforge/izpack/installer/gui/InstallerFrame.java
@@ -68,7 +68,9 @@ import com.izforge.izpack.api.adaptator.IXMLElement;
 import com.izforge.izpack.api.adaptator.IXMLWriter;
 import com.izforge.izpack.api.adaptator.impl.XMLWriter;
 import com.izforge.izpack.api.data.Info;
+import com.izforge.izpack.api.data.InstallData;
 import com.izforge.izpack.api.data.LocaleDatabase;
+import com.izforge.izpack.api.data.Pack;
 import com.izforge.izpack.api.data.Panel;
 import com.izforge.izpack.api.data.Variables;
 import com.izforge.izpack.api.event.ProgressListener;
@@ -535,6 +537,9 @@ public class InstallerFrame extends JFrame implements InstallerView
      */
     protected void switchPanel(IzPanelView newPanel, IzPanelView oldPanel)
     {
+
+        revaluateDynamicAttributes(newPanel.getInstallData());
+
         int oldIndex = (oldPanel != null) ? oldPanel.getIndex() : -1;
         logger.fine("Switching panel, old index is " + oldIndex);

@@ -629,6 +634,37 @@ public class InstallerFrame extends JFrame implements InstallerView
         }
     }

+    public static void revaluateDynamicAttributes(InstallData installData) {
+        List<Pack> packs = installData.getAllPacks();
+        // System.out.println("\nswitchPanel new: " + newPanel.getPanel().getClassName() + " ("+packs.size() + " packs) [");
+        for (Pack pack : packs) {
+            // System.out.println(String.format("\tpack: %1$-25s req? %2$-25s pre? %3$-25s", pack.getLangPackId(), pack.isRequired(), pack.isPreselected()));
+            pack.setRequired(parseYesNoDynamic(pack.getRequiredExpr(), installData));
+            if (pack.getExcludeGroup() == null) {
+                pack.setPreselected(parseYesNoDynamic(pack.getPreselectedExpr(), installData));
+            }
+            pack.setReadonly(parseYesNoDynamic(pack.getReadonlyExpr(), installData));
+            // System.out.println(String.format("\t      %1$-20s orig req? %2$-20s orig pre? %3$-25s", "", pack.getRequiredExpr(), pack.getPreselectedExpr()));
+            // System.out.println(String.format("\t      %1$-20s  new req? %2$-20s  new pre? %3$-25s", "", pack.isRequired(), pack.isPreselected()));
+        }
+        // System.out.println("]");
+    }
+
+    private static boolean parseYesNoDynamic(String expr, InstallData installData) {
+        if (expr == null) {
+            return false;
+        } else if (expr.equalsIgnoreCase("yes") || expr.equalsIgnoreCase("true")) {
+            return true;
+        } else if (expr.equalsIgnoreCase("no") || expr.equalsIgnoreCase("false")) {
+            return false;
+        } else if (expr.startsWith("${") && expr.endsWith("}")) {
+            return Boolean.parseBoolean(installData.getVariable(expr).substring(2, expr.length() - 1));
+        } else if (expr.startsWith("$")) {
+            return Boolean.parseBoolean(installData.getVariable(expr).substring(1));
+        }
+        return installData.getRules().getCondition(expr).isTrue();
+    }
+
     /**
      * Centers a window on screen.
      *

--- a/izpack-installer/src/main/java/com/izforge/izpack/installer/panel/AbstractPanelView.java
+++ b/izpack-installer/src/main/java/com/izforge/izpack/installer/panel/AbstractPanelView.java
@@ -537,4 +537,8 @@ public abstract class AbstractPanelView<T> implements PanelView<T>
         return message;
     }

+    public InstallData getInstallData() {
+        return this.installData;
+    }
+
 }
\ No newline at end of file

index 465e7c0..341800e 100755
--- a/izpack-panel/src/main/java/com/izforge/izpack/panels/packs/PacksPanelBase.java
+++ b/izpack-panel/src/main/java/com/izforge/izpack/panels/packs/PacksPanelBase.java
@@ -961,7 +961,7 @@ public abstract class PacksPanelBase extends IzPanel implements PacksPanelInterf
      *
      * @param row the row
      */
-    private void togglePack(int row)
+    protected void togglePack(int row)
     {
         Integer checked = (Integer) packsModel.getValueAt(row, 0);
         checked = (checked <= 0) ? 1 : 0;

--- a/izpack-util/src/main/java/com/izforge/izpack/data/PackInfo.java
+++ b/izpack-util/src/main/java/com/izforge/izpack/data/PackInfo.java
@@ -363,4 +363,17 @@ public class PackInfo implements Serializable
     {
         pack.addValidator(validatorClassName);
     }
+
+    public void setRequiredExpr(String requiredExpr) {
+        pack.setRequiredExpr(requiredExpr);
+    }
+
+    public void setPreselectedExpr(String preselectedExpr) {
+        pack.setPreselectedExpr(preselectedExpr);
+    }
+
+    public void setReadonlyExpr(String readonlyExpr) {
+        pack.setReadonlyExpr(readonlyExpr);
+    }
+
 }