Source Code Cross Referenced for UserInputPanel.java in  » Installer » IzPack » com » izforge » izpack » panels » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Installer » IzPack » com.izforge.izpack.panels 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * IzPack - Copyright 2001-2008 Julien Ponge, All Rights Reserved.
0003:         * 
0004:         * http://izpack.org/
0005:         * http://izpack.codehaus.org/
0006:         * 
0007:         * Copyright 2002 Elmar Grom
0008:         * 
0009:         * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
0010:         * in compliance with the License. You may obtain a copy of the License at
0011:         * 
0012:         * http://www.apache.org/licenses/LICENSE-2.0
0013:         * 
0014:         * Unless required by applicable law or agreed to in writing, software distributed under the License
0015:         * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
0016:         * or implied. See the License for the specific language governing permissions and limitations under
0017:         * the License.
0018:         */
0019:
0020:        package com.izforge.izpack.panels;
0021:
0022:        import java.awt.Color;
0023:        import java.awt.Font;
0024:        import java.awt.event.ActionEvent;
0025:        import java.awt.event.ActionListener;
0026:        import java.io.File;
0027:        import java.io.InputStream;
0028:        import java.text.MessageFormat;
0029:        import java.util.HashMap;
0030:        import java.util.HashSet;
0031:        import java.util.Iterator;
0032:        import java.util.Map;
0033:        import java.util.StringTokenizer;
0034:        import java.util.Vector;
0035:
0036:        import javax.swing.BorderFactory;
0037:        import javax.swing.ButtonGroup;
0038:        import javax.swing.ImageIcon;
0039:        import javax.swing.JButton;
0040:        import javax.swing.JCheckBox;
0041:        import javax.swing.JComboBox;
0042:        import javax.swing.JComponent;
0043:        import javax.swing.JFileChooser;
0044:        import javax.swing.JLabel;
0045:        import javax.swing.JOptionPane;
0046:        import javax.swing.JPanel;
0047:        import javax.swing.JPasswordField;
0048:        import javax.swing.JRadioButton;
0049:        import javax.swing.JTextField;
0050:        import javax.swing.event.DocumentEvent;
0051:        import javax.swing.event.DocumentListener;
0052:        import javax.swing.filechooser.FileFilter;
0053:        import javax.swing.text.BadLocationException;
0054:        import javax.swing.text.Document;
0055:
0056:        import net.n3.nanoxml.NonValidator;
0057:        import net.n3.nanoxml.StdXMLParser;
0058:        import net.n3.nanoxml.StdXMLReader;
0059:        import net.n3.nanoxml.XMLElement;
0060:        import net.n3.nanoxml.XMLBuilderFactory;
0061:
0062:        import com.izforge.izpack.LocaleDatabase;
0063:        import com.izforge.izpack.Pack;
0064:        import com.izforge.izpack.Panel;
0065:        import com.izforge.izpack.gui.ButtonFactory;
0066:        import com.izforge.izpack.gui.LabelFactory;
0067:        import com.izforge.izpack.gui.TwoColumnConstraints;
0068:        import com.izforge.izpack.gui.TwoColumnLayout;
0069:        import com.izforge.izpack.installer.InstallData;
0070:        import com.izforge.izpack.installer.InstallerFrame;
0071:        import com.izforge.izpack.installer.IzPanel;
0072:        import com.izforge.izpack.installer.ResourceManager;
0073:        import com.izforge.izpack.rules.RulesEngine;
0074:        import com.izforge.izpack.util.Debug;
0075:        import com.izforge.izpack.util.MultiLineLabel;
0076:        import com.izforge.izpack.util.OsConstraint;
0077:        import com.izforge.izpack.util.OsVersion;
0078:        import com.izforge.izpack.util.VariableSubstitutor;
0079:        import java.util.ArrayList;
0080:        import java.util.List;
0081:
0082:        /*---------------------------------------------------------------------------*/
0083:        /**
0084:         * This panel is designed to collect user input during the installation process. The panel is
0085:         * initially blank and is populated with input elements based on the XML specification in a resource
0086:         * file.
0087:         * 
0088:         * 
0089:         * @version 0.0.1 / 10/19/02
0090:         * @author getDirectoryCreated
0091:         */
0092:        /*---------------------------------------------------------------------------*/
0093:        /*
0094:         * $ @design
0095:         * 
0096:         * Each field is specified in its own node, containing attributes and data. When this class is
0097:         * instantiated, the specification is read and analyzed. Each field node is processed based on its
0098:         * type. An specialized member function is called for each field type that creates the necessary UI
0099:         * elements. All UI elements are stored in the uiElements vector. Elements are packaged in an object
0100:         * array that must follow this pattern:
0101:         * 
0102:         * index 0 - a String object, that specifies the field type. This is identical to the string used to
0103:         * identify the field type in the XML file. index 1 - a String object that contains the variable
0104:         * name for substitution. index 2 - the constraints object that should be used for positioning the
0105:         * UI element index 3 - the UI element itself index 4 - a Vector containg a list of pack for which
0106:         * the item should be created. This is used by buildUI() to decide if the item should be added to
0107:         * the UI.
0108:         * 
0109:         * In some cases additional entries are used. The use depends on the specific needs of the type of
0110:         * input field.
0111:         * 
0112:         * When the panel is activated, the method buildUI() walks the list of UI elements adds them to the
0113:         * panel together with the matching constraint.
0114:         * 
0115:         * When an attempt is made to move on to another panel, the method readInput() walks the list of UI
0116:         * elements again and calls specialized methods that know how to read the user input from each of
0117:         * the UI elemnts and set the associated varaible.
0118:         * 
0119:         * The actual variable substitution is not performed by this panel but by the variable substitutor.
0120:         * 
0121:         * To Do: ------ * make sure all header documentation is complete and correct
0122:         * --------------------------------------------------------------------------
0123:         */
0124:        public class UserInputPanel extends IzPanel implements  ActionListener {
0125:
0126:            // ------------------------------------------------------------------------
0127:            // Constant Definitions
0128:            // ------------------------------------------------------------------------
0129:
0130:            // The constants beginning with 'POS_' define locations in the object arrays
0131:            // that used to hold all information for the individual fields. Some data is
0132:            // not required for all field types. If this happens withing the array, that
0133:            // location must be padded with 'null'. At the end of the array it can be
0134:            // omitted. The data stored in this way is in most cases only known by
0135:            // convention between the add and the associated read method. the following
0136:            // positions are also used by other service methods in this class and must
0137:            // not be used for other purposes:
0138:            // - POS_DISPLAYED
0139:            // - POS_TYPE
0140:            // - POS_CONSTRAINTS
0141:            // - POS_PACKS
0142:
0143:            /**
0144:             * 
0145:             */
0146:            private static final long serialVersionUID = 3257850965439886129L;
0147:
0148:            private static final int POS_DISPLAYED = 0;
0149:
0150:            private static final int POS_TYPE = 1;
0151:
0152:            private static final int POS_VARIABLE = 2;
0153:
0154:            private static final int POS_CONSTRAINTS = 3;
0155:
0156:            private static final int POS_FIELD = 4;
0157:
0158:            private static final int POS_PACKS = 5;
0159:
0160:            private static final int POS_OS = 6;
0161:
0162:            private static final int POS_TRUE = 7;
0163:
0164:            private static final int POS_FALSE = 8;
0165:
0166:            private static final int POS_MESSAGE = 9;
0167:
0168:            private static final int POS_GROUP = 10;
0169:
0170:            protected static final String ICON_KEY = "icon";
0171:
0172:            /** The name of the XML file that specifies the panel layout */
0173:            private static final String SPEC_FILE_NAME = "userInputSpec.xml";
0174:
0175:            private static final String LANG_FILE_NAME = "userInputLang.xml";
0176:
0177:            /** how the spec node for a specific panel is identified */
0178:            private static final String NODE_ID = "panel";
0179:
0180:            private static final String FIELD_NODE_ID = "field";
0181:
0182:            private static final String INSTANCE_IDENTIFIER = "order";
0183:            protected static final String PANEL_IDENTIFIER = "id";
0184:
0185:            private static final String TYPE = "type";
0186:
0187:            private static final String DESCRIPTION = "description";
0188:
0189:            private static final String VARIABLE = "variable";
0190:
0191:            private static final String TEXT = "txt";
0192:
0193:            private static final String KEY = "id";
0194:
0195:            private static final String SPEC = "spec";
0196:
0197:            private static final String SET = "set";
0198:
0199:            private static final String REVALIDATE = "revalidate";
0200:
0201:            private static final String TOPBUFFER = "topBuffer";
0202:
0203:            private static final String TRUE = "true";
0204:
0205:            private static final String FALSE = "false";
0206:
0207:            private static final String ALIGNMENT = "align";
0208:
0209:            private static final String LEFT = "left";
0210:
0211:            private static final String CENTER = "center";
0212:
0213:            private static final String RIGHT = "right";
0214:
0215:            private static final String TOP = "top";
0216:
0217:            private static final String ITALICS = "italic";
0218:
0219:            private static final String BOLD = "bold";
0220:
0221:            private static final String SIZE = "size";
0222:
0223:            private static final String VALIDATOR = "validator";
0224:
0225:            private static final String PROCESSOR = "processor";
0226:
0227:            private static final String CLASS = "class";
0228:
0229:            private static final String FIELD_LABEL = "label";
0230:
0231:            private static final String TITLE_FIELD = "title";
0232:
0233:            private static final String TEXT_FIELD = "text";
0234:
0235:            private static final String TEXT_SIZE = "size";
0236:
0237:            private static final String STATIC_TEXT = "staticText";
0238:
0239:            private static final String COMBO_FIELD = "combo";
0240:
0241:            private static final String COMBO_CHOICE = "choice";
0242:
0243:            private static final String COMBO_VALUE = "value";
0244:
0245:            private static final String RADIO_FIELD = "radio";
0246:
0247:            private static final String RADIO_CHOICE = "choice";
0248:
0249:            private static final String RADIO_VALUE = "value";
0250:
0251:            private static final String SPACE_FIELD = "space";
0252:
0253:            private static final String DIVIDER_FIELD = "divider";
0254:
0255:            private static final String CHECK_FIELD = "check";
0256:
0257:            private static final String RULE_FIELD = "rule";
0258:
0259:            private static final String RULE_LAYOUT = "layout";
0260:
0261:            private static final String RULE_SEPARATOR = "separator";
0262:
0263:            private static final String RULE_RESULT_FORMAT = "resultFormat";
0264:
0265:            private static final String RULE_PLAIN_STRING = "plainString";
0266:
0267:            private static final String RULE_DISPLAY_FORMAT = "displayFormat";
0268:
0269:            private static final String RULE_SPECIAL_SEPARATOR = "specialSeparator";
0270:
0271:            private static final String RULE_ENCRYPTED = "processed";
0272:
0273:            private static final String RULE_PARAM_NAME = "name";
0274:
0275:            private static final String RULE_PARAM_VALUE = "value";
0276:
0277:            private static final String RULE_PARAM = "param";
0278:
0279:            private static final String PWD_FIELD = "password";
0280:
0281:            private static final String PWD_INPUT = "pwd";
0282:
0283:            private static final String PWD_SIZE = "size";
0284:
0285:            private static final String SEARCH_FIELD = "search";
0286:
0287:            private static final String FILE_FIELD = "file";
0288:
0289:            private static final String DIR_FIELD = "dir";
0290:
0291:            // internal value for the button used to trigger autodetection
0292:            private static final String SEARCH_BUTTON_FIELD = "autodetect";
0293:
0294:            private static final String SEARCH_CHOICE = "choice";
0295:
0296:            private static final String SEARCH_FILENAME = "filename";
0297:
0298:            private static final String SEARCH_RESULT = "result";
0299:
0300:            private static final String SEARCH_VALUE = "value";
0301:
0302:            private static final String SEARCH_TYPE = "type";
0303:
0304:            private static final String SEARCH_FILE = "file";
0305:
0306:            private static final String SEARCH_DIRECTORY = "directory";
0307:
0308:            private static final String SEARCH_PARENTDIR = "parentdir";
0309:
0310:            private static final String SEARCH_CHECKFILENAME = "checkfilename";
0311:
0312:            private static final String SELECTEDPACKS = "createForPack"; // renamed
0313:
0314:            private static final String UNSELECTEDPACKS = "createForUnselectedPack"; // new
0315:
0316:            protected static final String ATTRIBUTE_CONDITIONID_NAME = "conditionid";
0317:
0318:            protected static final String VARIABLE_NODE = "variable";
0319:
0320:            protected static final String ATTRIBUTE_VARIABLE_NAME = "name";
0321:
0322:            protected static final String ATTRIBUTE_VARIABLE_VALUE = "value";
0323:
0324:            // node
0325:
0326:            private static final String NAME = "name";
0327:
0328:            private static final String OS = "os";
0329:
0330:            private static final String FAMILY = "family";
0331:
0332:            private static final String FIELD_BUTTON = "button";
0333:
0334:            // ------------------------------------------------------------------------
0335:            // Variable Declarations
0336:            // ------------------------------------------------------------------------
0337:            private static int instanceCount = 0;
0338:
0339:            protected int instanceNumber = 0;
0340:
0341:            /**
0342:             * If there is a possibility that some UI elements will not get added we can not allow to go
0343:             * back to the PacksPanel, because the process of building the UI is not reversable. This
0344:             * variable keeps track if any packs have been defined and will be used to make a decision for
0345:             * locking the 'previous' button.
0346:             */
0347:            private boolean packsDefined = false;
0348:
0349:            private InstallerFrame parentFrame;
0350:
0351:            /** The parsed result from reading the XML specification from the file */
0352:            private XMLElement spec;
0353:
0354:            private boolean haveSpec = false;
0355:
0356:            /** Holds the references to all of the UI elements */
0357:            private Vector<Object[]> uiElements = new Vector<Object[]>();
0358:
0359:            /** Holds the references to all radio button groups */
0360:            private Vector<ButtonGroup> buttonGroups = new Vector<ButtonGroup>();
0361:
0362:            /** Holds the references to all password field groups */
0363:            private Vector<PasswordGroup> passwordGroups = new Vector<PasswordGroup>();
0364:
0365:            /**
0366:             * used for temporary storage of references to password groups that have already been read in a
0367:             * given read cycle.
0368:             */
0369:            private Vector passwordGroupsRead = new Vector();
0370:
0371:            /** Used to track search fields. Contains SearchField references. */
0372:            private Vector<SearchField> searchFields = new Vector<SearchField>();
0373:
0374:            /** Holds all user inputs for use in automated installation */
0375:            private Vector<TextValuePair> entries = new Vector<TextValuePair>();
0376:
0377:            private LocaleDatabase langpack = null;
0378:
0379:            // Used for dynamic controls to skip content validation unless the user
0380:            // really clicks "Next"
0381:            private boolean validating = true;
0382:
0383:            /*--------------------------------------------------------------------------*/
0384:            // This method can be used to search for layout problems. If this class is
0385:            // compiled with this method uncommented, the layout guides will be shown
0386:            // on the panel, making it possible to see if all components are placed
0387:            // correctly.
0388:            /*--------------------------------------------------------------------------*/
0389:            // public void paint (Graphics graphics)
0390:            // {
0391:            // super.paint (graphics);
0392:            // layout.showRules ((Graphics2D)graphics, Color.red);
0393:            // }
0394:            /*--------------------------------------------------------------------------*/
0395:            /**
0396:             * Constructs a <code>UserInputPanel</code>.
0397:             * 
0398:             * @param parent reference to the application frame
0399:             * @param installData shared information about the installation
0400:             */
0401:            /*--------------------------------------------------------------------------*/
0402:            public UserInputPanel(InstallerFrame parent, InstallData installData) {
0403:                super (parent, installData);
0404:                instanceNumber = instanceCount++;
0405:                this .parentFrame = parent;
0406:            }
0407:
0408:            protected void init() {
0409:
0410:                TwoColumnLayout layout;
0411:                super .removeAll();
0412:                uiElements.clear();
0413:
0414:                // ----------------------------------------------------
0415:                // get a locale database
0416:                // ----------------------------------------------------
0417:                try {
0418:                    // this.langpack = parent.langpack;
0419:
0420:                    String resource = LANG_FILE_NAME + "_" + idata.localeISO3;
0421:                    this .langpack = new LocaleDatabase(ResourceManager
0422:                            .getInstance().getInputStream(resource));
0423:                } catch (Throwable exception) {
0424:                }
0425:
0426:                // ----------------------------------------------------
0427:                // read the specifications
0428:                // ----------------------------------------------------
0429:                try {
0430:                    readSpec();
0431:                } catch (Throwable exception) {
0432:                    // log the problem
0433:                    exception.printStackTrace();
0434:                }
0435:
0436:                // ----------------------------------------------------
0437:                // Set the topBuffer from the attribute. topBuffer=0 is useful
0438:                // if you don't want your panel to be moved up and down during
0439:                // dynamic validation (showing and hiding components within the
0440:                // same panel)
0441:                // ----------------------------------------------------
0442:                int topbuff = 25;
0443:                try {
0444:                    topbuff = Integer.parseInt(spec.getAttribute(TOPBUFFER));
0445:                } catch (Exception ex) {
0446:                } finally {
0447:                    layout = new TwoColumnLayout(10, 5, 30, topbuff,
0448:                            TwoColumnLayout.LEFT);
0449:                }
0450:                setLayout(layout);
0451:
0452:                if (!haveSpec) {
0453:                    // return if we could not read the spec. further
0454:                    // processing will only lead to problems. In this
0455:                    // case we must skip the panel when it gets activated.
0456:                    return;
0457:                }
0458:
0459:                // refresh variables specified in spec
0460:                updateVariables();
0461:
0462:                // ----------------------------------------------------
0463:                // process all field nodes. Each field node is analyzed
0464:                // for its type, then an appropriate memeber function
0465:                // is called that will create the correct UI elements.
0466:                // ----------------------------------------------------
0467:                Vector<XMLElement> fields = spec
0468:                        .getChildrenNamed(FIELD_NODE_ID);
0469:
0470:                for (int i = 0; i < fields.size(); i++) {
0471:                    XMLElement field = fields.elementAt(i);
0472:                    String attribute = field.getAttribute(TYPE);
0473:                    String conditionid = field
0474:                            .getAttribute(ATTRIBUTE_CONDITIONID_NAME);
0475:                    if (conditionid != null) {
0476:                        // check if condition is fulfilled
0477:                        if (!this .parent.getRules().isConditionTrue(
0478:                                conditionid, idata.getVariables())) {
0479:                            continue;
0480:                        }
0481:                    }
0482:                    if (attribute != null) {
0483:                        if (attribute.equals(RULE_FIELD)) {
0484:                            addRuleField(field);
0485:                        } else if (attribute.equals(TEXT_FIELD)) {
0486:                            addTextField(field);
0487:                        } else if (attribute.equals(COMBO_FIELD)) {
0488:                            addComboBox(field);
0489:                        } else if (attribute.equals(RADIO_FIELD)) {
0490:                            addRadioButton(field);
0491:                        } else if (attribute.equals(PWD_FIELD)) {
0492:                            addPasswordField(field);
0493:                        } else if (attribute.equals(SPACE_FIELD)) {
0494:                            addSpace(field);
0495:                        } else if (attribute.equals(DIVIDER_FIELD)) {
0496:                            addDivider(field);
0497:                        } else if (attribute.equals(CHECK_FIELD)) {
0498:                            addCheckBox(field);
0499:                        } else if (attribute.equals(STATIC_TEXT)) {
0500:                            addText(field);
0501:                        } else if (attribute.equals(TITLE_FIELD)) {
0502:                            addTitle(field);
0503:                        } else if (attribute.equals(SEARCH_FIELD)) {
0504:                            addSearch(field);
0505:                        } else if (attribute.equals(FILE_FIELD)) {
0506:                            addFileField(field);
0507:                        } else if (attribute.equals(DIR_FIELD)) {
0508:                            addDirectoryField(field);
0509:                        }
0510:                    }
0511:                }
0512:            }
0513:
0514:            private void addDirectoryField(XMLElement field) {
0515:                Vector<XMLElement> forPacks = field
0516:                        .getChildrenNamed(SELECTEDPACKS);
0517:                Vector<XMLElement> forOs = field.getChildrenNamed(OS);
0518:
0519:                JLabel label;
0520:                String set;
0521:                int size;
0522:
0523:                String filter = null;
0524:                String filterdesc = null;
0525:
0526:                String variable = field.getAttribute(VARIABLE);
0527:                if ((variable == null) || (variable.length() == 0)) {
0528:                    return;
0529:                }
0530:
0531:                XMLElement element = field.getFirstChildNamed(SPEC);
0532:                if (element == null) {
0533:                    Debug.trace("Error: no spec element defined in file field");
0534:                    return;
0535:                } else {
0536:                    label = new JLabel(getText(element));
0537:                    // ----------------------------------------------------
0538:                    // extract the specification details
0539:                    // ----------------------------------------------------
0540:                    set = element.getAttribute(SET);
0541:                    if (set == null) {
0542:                        set = idata.getVariable(variable);
0543:                        if (set == null) {
0544:                            set = "";
0545:                        }
0546:                    } else {
0547:                        if (set != null && !"".equals(set)) {
0548:                            VariableSubstitutor vs = new VariableSubstitutor(
0549:                                    idata.getVariables());
0550:                            set = vs.substitute(set, null);
0551:                        }
0552:                    }
0553:
0554:                    try {
0555:                        size = Integer
0556:                                .parseInt(element.getAttribute(TEXT_SIZE));
0557:                    } catch (Throwable exception) {
0558:                        size = 1;
0559:                    }
0560:
0561:                    filter = element.getAttribute("fileext");
0562:                    if (filter == null) {
0563:                        filter = "";
0564:                    }
0565:                    filterdesc = element.getAttribute("fileextdesc");
0566:                    if (filterdesc == null) {
0567:                        filterdesc = "";
0568:                    }
0569:                    // internationalize it
0570:                    filterdesc = idata.langpack.getString(filterdesc);
0571:                }
0572:
0573:                final JTextField filetxt = new JTextField(set, size);
0574:                filetxt.setCaretPosition(0);
0575:
0576:                TwoColumnConstraints constraints = new TwoColumnConstraints();
0577:                constraints.position = TwoColumnConstraints.WEST;
0578:
0579:                uiElements.add(new Object[] { null, FIELD_LABEL, null,
0580:                        constraints, label, forPacks, forOs });
0581:
0582:                TwoColumnConstraints constraints2 = new TwoColumnConstraints();
0583:                constraints2.position = TwoColumnConstraints.EAST;
0584:
0585:                // TODO: use separate key for button text
0586:                JButton button = ButtonFactory.createButton(idata.langpack
0587:                        .getString("UserInputPanel.search.browse"),
0588:                        idata.buttonsHColor);
0589:                button.addActionListener(new ActionListener() {
0590:                    public void actionPerformed(ActionEvent e) {
0591:                        System.out.println("Show dirchooser");
0592:                        JFileChooser filechooser = new JFileChooser();
0593:                        filechooser
0594:                                .setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
0595:
0596:                        if (filechooser.showOpenDialog(parentFrame) == JFileChooser.APPROVE_OPTION) {
0597:                            filetxt.setText(filechooser.getSelectedFile()
0598:                                    .getAbsolutePath());
0599:                        }
0600:                    }
0601:                });
0602:                JPanel panel = new JPanel();
0603:                panel.add(filetxt);
0604:                panel.add(button);
0605:                uiElements.add(new Object[] { null, DIR_FIELD, variable,
0606:                        constraints2, panel, forPacks, forOs });
0607:
0608:            }
0609:
0610:            private void addFileField(XMLElement field) {
0611:                Vector<XMLElement> forPacks = field
0612:                        .getChildrenNamed(SELECTEDPACKS);
0613:                Vector<XMLElement> forOs = field.getChildrenNamed(OS);
0614:
0615:                JLabel label;
0616:                String set;
0617:                int size;
0618:
0619:                String filter = null;
0620:                String filterdesc = null;
0621:
0622:                String variable = field.getAttribute(VARIABLE);
0623:                if ((variable == null) || (variable.length() == 0)) {
0624:                    return;
0625:                }
0626:
0627:                XMLElement element = field.getFirstChildNamed(SPEC);
0628:                if (element == null) {
0629:                    Debug.trace("Error: no spec element defined in file field");
0630:                    return;
0631:                } else {
0632:                    label = new JLabel(getText(element));
0633:                    // ----------------------------------------------------
0634:                    // extract the specification details
0635:                    // ----------------------------------------------------
0636:                    set = element.getAttribute(SET);
0637:                    if (set == null) {
0638:                        set = idata.getVariable(variable);
0639:                        if (set == null) {
0640:                            set = "";
0641:                        }
0642:                    } else {
0643:                        if (set != null && !"".equals(set)) {
0644:                            VariableSubstitutor vs = new VariableSubstitutor(
0645:                                    idata.getVariables());
0646:                            set = vs.substitute(set, null);
0647:                        }
0648:                    }
0649:
0650:                    try {
0651:                        size = Integer
0652:                                .parseInt(element.getAttribute(TEXT_SIZE));
0653:                    } catch (Throwable exception) {
0654:                        size = 1;
0655:                    }
0656:
0657:                    filter = element.getAttribute("fileext");
0658:                    if (filter == null) {
0659:                        filter = "";
0660:                    }
0661:                    filterdesc = element.getAttribute("fileextdesc");
0662:                    if (filterdesc == null) {
0663:                        filterdesc = "";
0664:                    }
0665:                    // internationalize it
0666:                    filterdesc = idata.langpack.getString(filterdesc);
0667:                }
0668:
0669:                final JTextField filetxt = new JTextField(set, size);
0670:                filetxt.setCaretPosition(0);
0671:
0672:                TwoColumnConstraints constraints = new TwoColumnConstraints();
0673:                constraints.position = TwoColumnConstraints.WEST;
0674:
0675:                uiElements.add(new Object[] { null, FIELD_LABEL, null,
0676:                        constraints, label, forPacks, forOs });
0677:
0678:                TwoColumnConstraints constraints2 = new TwoColumnConstraints();
0679:                constraints2.position = TwoColumnConstraints.EAST;
0680:
0681:                final UserInputFileFilter uiff = new UserInputFileFilter();
0682:                uiff.setFileExt(filter);
0683:                uiff.setFileExtDesc(filterdesc);
0684:
0685:                // TODO: use separate key for button text
0686:                JButton button = ButtonFactory.createButton(idata.langpack
0687:                        .getString("UserInputPanel.search.browse"),
0688:                        idata.buttonsHColor);
0689:                button.addActionListener(new ActionListener() {
0690:                    public void actionPerformed(ActionEvent e) {
0691:                        System.out.println("Show filechooser");
0692:                        JFileChooser filechooser = new JFileChooser();
0693:                        filechooser
0694:                                .setFileSelectionMode(JFileChooser.FILES_ONLY);
0695:                        filechooser.setFileFilter(uiff);
0696:
0697:                        if (filechooser.showOpenDialog(parentFrame) == JFileChooser.APPROVE_OPTION) {
0698:                            filetxt.setText(filechooser.getSelectedFile()
0699:                                    .getAbsolutePath());
0700:                        }
0701:                    }
0702:                });
0703:                JPanel panel = new JPanel();
0704:                panel.add(filetxt);
0705:                panel.add(button);
0706:                uiElements.add(new Object[] { null, FILE_FIELD, variable,
0707:                        constraints2, panel, forPacks, forOs });
0708:            }
0709:
0710:            protected void updateUIElements() {
0711:                boolean updated = false;
0712:                VariableSubstitutor vs = new VariableSubstitutor(idata
0713:                        .getVariables());
0714:
0715:                for (int i = 0; i < uiElements.size(); i++) {
0716:                    Object[] element = uiElements.get(i);
0717:                    if (element[POS_VARIABLE] == null) {
0718:                        continue;
0719:                    }
0720:                    String value = idata
0721:                            .getVariable((String) element[POS_VARIABLE]);
0722:
0723:                    if (RADIO_FIELD.equals(element[POS_TYPE])) {
0724:                        // we have a radio field, which should be updated
0725:                        JRadioButton choice = (JRadioButton) element[POS_FIELD];
0726:                        if (value == null) {
0727:                            continue;
0728:                        }
0729:                        if (value.equals(element[POS_TRUE])) {
0730:                            choice.setSelected(true);
0731:                        } else {
0732:                            choice.setSelected(false);
0733:                        }
0734:                        element[POS_FIELD] = choice;
0735:                    } else if (TEXT_FIELD.equals(element[POS_TYPE])) {
0736:                        // update TextField
0737:                        TextInputField textf = (TextInputField) element[POS_FIELD];
0738:
0739:                        if (value == null) {
0740:                            value = textf.getText();
0741:                        }
0742:                        textf.setText(vs.substitute(value, null));
0743:                        element[POS_FIELD] = textf;
0744:                    } else if (CHECK_FIELD.equals(element[POS_TYPE])) {
0745:                        // TODO: HAS TO BE IMPLEMENTED
0746:                    } else if (SEARCH_FIELD.equals(element[POS_TYPE])) {
0747:                        // TODO: HAS TO BE IMPLEMENTED
0748:                    } else if (RULE_FIELD.equals(element[POS_TYPE])) {
0749:
0750:                        RuleInputField rulef = (RuleInputField) element[POS_FIELD];
0751:                        // System.out.println("RuleInputField: " + value);
0752:                        if (value == null) {
0753:                            value = rulef.getText();
0754:                        }
0755:                    } else if (FIELD_BUTTON.equals(element[POS_TYPE])) {
0756:                        // nothing to do
0757:                    }
0758:                    // overwrite entry;
0759:                    uiElements.set(i, element);
0760:                    updated = true;
0761:                }
0762:                if (updated) {
0763:                    // super.removeAll();
0764:                    super .invalidate();
0765:                    // buildUI();
0766:                }
0767:            }
0768:
0769:            /*--------------------------------------------------------------------------*/
0770:            /**
0771:             * Indicates wether the panel has been validated or not. The installer won't let the user go
0772:             * further through the installation process until the panel is validated. Default behavior is to
0773:             * return true.
0774:             * 
0775:             * @return A boolean stating wether the panel has been validated or not.
0776:             */
0777:            /*--------------------------------------------------------------------------*/
0778:            public boolean isValidated() {
0779:                return readInput();
0780:            }
0781:
0782:            /*--------------------------------------------------------------------------*/
0783:            /**
0784:             * This method is called when the panel becomes active.
0785:             */
0786:            /*--------------------------------------------------------------------------*/
0787:            public void panelActivate() {
0788:                this .init();
0789:
0790:                if (spec == null) {
0791:                    // TODO: translate
0792:                    emitError(
0793:                            "User input specification could not be found.",
0794:                            "The specification for the user input panel could not be found. Please contact the packager.");
0795:                    parentFrame.skipPanel();
0796:                }
0797:                // update UI with current values of associated variables
0798:                updateUIElements();
0799:                Vector<XMLElement> forPacks = spec
0800:                        .getChildrenNamed(SELECTEDPACKS);
0801:                Vector<XMLElement> forUnselectedPacks = spec
0802:                        .getChildrenNamed(UNSELECTEDPACKS);
0803:                Vector<XMLElement> forOs = spec.getChildrenNamed(OS);
0804:
0805:                if (!itemRequiredFor(forPacks)
0806:                        || !itemRequiredForUnselected(forUnselectedPacks)
0807:                        || !itemRequiredForOs(forOs)) {
0808:                    parentFrame.skipPanel();
0809:                    return;
0810:                }
0811:                if (!haveSpec) {
0812:                    parentFrame.skipPanel();
0813:                    return;
0814:                }
0815:                // if (uiBuilt)
0816:                // {
0817:                // return;
0818:                // }
0819:
0820:                buildUI();
0821:                //need a validation, else ui is scrambled
0822:
0823:                this .setSize(this .getMaximumSize().width,
0824:                        this .getMaximumSize().height);
0825:                validate();
0826:                if (packsDefined) {
0827:                    parentFrame.lockPrevButton();
0828:                }
0829:            }
0830:
0831:            /*--------------------------------------------------------------------------*/
0832:            /**
0833:             * Asks the panel to set its own XML data that can be brought back for an automated installation
0834:             * process. Use it as a blackbox if your panel needs to do something even in automated mode.
0835:             * 
0836:             * @param panelRoot The XML root element of the panels blackbox tree.
0837:             */
0838:            /*--------------------------------------------------------------------------*/
0839:            public void makeXMLData(XMLElement panelRoot) {
0840:                Map<String, String> entryMap = new HashMap<String, String>();
0841:
0842:                for (int i = 0; i < entries.size(); i++) {
0843:                    TextValuePair pair = entries.elementAt(i);
0844:                    entryMap.put(pair.toString(), pair.getValue());
0845:                }
0846:
0847:                new UserInputPanelAutomationHelper(entryMap).makeXMLData(idata,
0848:                        panelRoot);
0849:            }
0850:
0851:            /*--------------------------------------------------------------------------*/
0852:            /**
0853:             * Builds the UI and makes it ready for display
0854:             */
0855:            /*--------------------------------------------------------------------------*/
0856:            private void buildUI() {
0857:                Object[] uiElement;
0858:
0859:                for (int i = 0; i < uiElements.size(); i++) {
0860:                    uiElement = uiElements.elementAt(i);
0861:
0862:                    if (itemRequiredFor((Vector<XMLElement>) uiElement[POS_PACKS])
0863:                            && itemRequiredForOs((Vector<XMLElement>) uiElement[POS_OS])) {
0864:                        try {
0865:                            if (uiElement[POS_DISPLAYED] == null
0866:                                    || "false".equals(uiElement[POS_DISPLAYED]
0867:                                            .toString())) {
0868:                                add((JComponent) uiElement[POS_FIELD],
0869:                                        uiElement[POS_CONSTRAINTS]);
0870:                            }
0871:
0872:                            uiElement[POS_DISPLAYED] = true;
0873:                            uiElements.remove(i);
0874:                            uiElements.add(i, uiElement);
0875:                        } catch (Throwable exception) {
0876:                            System.out
0877:                                    .println("Internal format error in field: "
0878:                                            + uiElement[POS_TYPE].toString()); // !!! logging
0879:                        }
0880:                    } else {
0881:                        try {
0882:                            if (uiElement[POS_DISPLAYED] != null
0883:                                    && "true".equals(uiElement[POS_DISPLAYED]
0884:                                            .toString())) {
0885:                                remove((JComponent) uiElement[POS_FIELD]);
0886:                            }
0887:                        } catch (Throwable exception) {
0888:                            System.out
0889:                                    .println("Internal format error in field: "
0890:                                            + uiElement[POS_TYPE].toString()); // !!! logging
0891:                        }
0892:                        uiElement[POS_DISPLAYED] = false;
0893:                        uiElements.remove(i);
0894:                        uiElements.add(i, uiElement);
0895:                    }
0896:                }
0897:            }
0898:
0899:            /*--------------------------------------------------------------------------*/
0900:            /**
0901:             * Reads the input data from all UI elements and sets the associated variables.
0902:             * 
0903:             * @return <code>true</code> if the operation is successdul, otherwise <code>false</code>.
0904:             */
0905:            /*--------------------------------------------------------------------------*/
0906:            private boolean readInput() {
0907:                boolean success;
0908:                String fieldType = null;
0909:                Object[] field = null;
0910:
0911:                passwordGroupsRead.clear();
0912:                // ----------------------------------------------------
0913:                // cycle through all but the password fields and read
0914:                // their contents
0915:                // ----------------------------------------------------
0916:                for (int i = 0; i < uiElements.size(); i++) {
0917:                    field = uiElements.elementAt(i);
0918:
0919:                    if ((field != null) && ((Boolean) field[POS_DISPLAYED])) {
0920:                        fieldType = (String) (field[POS_TYPE]);
0921:
0922:                        // ------------------------------------------------
0923:                        if (fieldType.equals(RULE_FIELD)) {
0924:                            success = readRuleField(field);
0925:                            if (!success) {
0926:                                return (false);
0927:                            }
0928:                        }
0929:
0930:                        // ------------------------------------------------
0931:                        if (fieldType.equals(PWD_FIELD)) {
0932:                            success = readPasswordField(field);
0933:                            if (!success) {
0934:                                return (false);
0935:                            }
0936:                        }
0937:
0938:                        // ------------------------------------------------
0939:                        else if (fieldType.equals(TEXT_FIELD)) {
0940:                            success = readTextField(field);
0941:                            if (!success) {
0942:                                return (false);
0943:                            }
0944:                        }
0945:
0946:                        // ------------------------------------------------
0947:                        else if (fieldType.equals(COMBO_FIELD)) {
0948:                            success = readComboBox(field);
0949:                            if (!success) {
0950:                                return (false);
0951:                            }
0952:                        }
0953:
0954:                        // ------------------------------------------------
0955:                        else if (fieldType.equals(RADIO_FIELD)) {
0956:                            success = readRadioButton(field);
0957:                            if (!success) {
0958:                                return (false);
0959:                            }
0960:                        }
0961:
0962:                        // ------------------------------------------------
0963:                        else if (fieldType.equals(CHECK_FIELD)) {
0964:                            success = readCheckBox(field);
0965:                            if (!success) {
0966:                                return (false);
0967:                            }
0968:                        } else if (fieldType.equals(SEARCH_FIELD)) {
0969:                            success = readSearch(field);
0970:                            if (!success) {
0971:                                return (false);
0972:                            }
0973:                        } else if (fieldType.equals(FILE_FIELD)) {
0974:                            success = readFileField(field);
0975:                            if (!success) {
0976:                                return (false);
0977:                            }
0978:                        } else if (fieldType.equals(DIR_FIELD)) {
0979:                            success = readDirectoryField(field);
0980:                            if (!success) {
0981:                                return (false);
0982:                            }
0983:                        }
0984:                    }
0985:                }
0986:
0987:                return (true);
0988:            }
0989:
0990:            private boolean readDirectoryField(Object[] field) {
0991:                try {
0992:                    JPanel panel = (JPanel) field[POS_FIELD];
0993:                    JTextField textf = (JTextField) panel.getComponent(0);
0994:                    String file = textf.getText();
0995:                    if (file != null) {
0996:                        File ffile = new File(file);
0997:                        if (ffile.isDirectory()) {
0998:                            idata.setVariable((String) field[POS_VARIABLE],
0999:                                    file);
1000:                            entries.add(new TextValuePair(
1001:                                    (String) field[POS_VARIABLE], file));
1002:                            return true;
1003:                        } else {
1004:                            showMessage("dir.notdirectory");
1005:                            return false;
1006:                        }
1007:                    } else {
1008:                        showMessage("dir.nodirectory");
1009:                        return false;
1010:                    }
1011:                } catch (Exception e) {
1012:                    if (Debug.stackTracing()) {
1013:                        Debug.trace(e);
1014:                    }
1015:                    return false;
1016:                }
1017:            }
1018:
1019:            private void showMessage(String messageType) {
1020:                JOptionPane.showMessageDialog(parent,
1021:                        parent.langpack.getString("UserInputPanel."
1022:                                + messageType + ".message"), parent.langpack
1023:                                .getString("UserInputPanel." + messageType
1024:                                        + ".caption"),
1025:                        JOptionPane.WARNING_MESSAGE);
1026:            }
1027:
1028:            private boolean readFileField(Object[] field) {
1029:                try {
1030:                    JPanel panel = (JPanel) field[POS_FIELD];
1031:                    JTextField textf = (JTextField) panel.getComponent(0);
1032:                    String file = textf.getText();
1033:                    if (file != null) {
1034:                        File ffile = new File(file);
1035:                        if (ffile.isFile()) {
1036:                            idata.setVariable((String) field[POS_VARIABLE],
1037:                                    file);
1038:                            entries.add(new TextValuePair(
1039:                                    (String) field[POS_VARIABLE], file));
1040:                            return true;
1041:                        } else {
1042:                            showMessage("file.notfile");
1043:                            return false;
1044:                        }
1045:                    } else {
1046:                        showMessage("file.nofile");
1047:                        return false;
1048:                    }
1049:                } catch (Exception e) {
1050:                    if (Debug.stackTracing()) {
1051:                        Debug.trace(e);
1052:                    }
1053:                    return false;
1054:                }
1055:            }
1056:
1057:            /*--------------------------------------------------------------------------*/
1058:            /**
1059:             * Reads the XML specification for the panel layout. The result is stored in spec.
1060:             * 
1061:             * @exception Exception for any problems in reading the specification
1062:             */
1063:            /*--------------------------------------------------------------------------*/
1064:            private void readSpec() throws Exception {
1065:                InputStream input = null;
1066:                XMLElement data;
1067:                Vector<XMLElement> specElements;
1068:                String attribute;
1069:                String panelattribute;
1070:                String instance = Integer.toString(instanceNumber);
1071:
1072:                String panelid = null;
1073:                Panel p = this .getMetadata();
1074:                if (p != null) {
1075:                    panelid = p.getPanelid();
1076:                }
1077:                try {
1078:                    input = parentFrame.getResource(SPEC_FILE_NAME);
1079:                } catch (Exception exception) {
1080:                    haveSpec = false;
1081:                    return;
1082:                }
1083:                if (input == null) {
1084:                    haveSpec = false;
1085:                    return;
1086:                }
1087:
1088:                // initialize the parser
1089:                StdXMLParser parser = new StdXMLParser();
1090:                parser.setBuilder(XMLBuilderFactory.createXMLBuilder());
1091:                parser.setValidator(new NonValidator());
1092:                parser.setReader(new StdXMLReader(input));
1093:
1094:                // get the data
1095:                data = (XMLElement) parser.parse();
1096:
1097:                // extract the spec to this specific panel instance
1098:                if (data.hasChildren()) {
1099:                    specElements = data.getChildrenNamed(NODE_ID);
1100:                    for (int i = 0; i < specElements.size(); i++) {
1101:                        data = specElements.elementAt(i);
1102:                        attribute = data.getAttribute(INSTANCE_IDENTIFIER);
1103:                        panelattribute = data.getAttribute(PANEL_IDENTIFIER);
1104:
1105:                        if (((attribute != null) && instance.equals(attribute))
1106:                                || ((panelattribute != null)
1107:                                        && (panelid != null) && (panelid
1108:                                        .equals(panelattribute)))) {
1109:                            // use the current element as spec
1110:                            spec = data;
1111:                            // close the stream
1112:                            input.close();
1113:                            haveSpec = true;
1114:                            return;
1115:                        }
1116:                    }
1117:
1118:                    haveSpec = false;
1119:                    return;
1120:                }
1121:
1122:                haveSpec = false;
1123:            }
1124:
1125:            /*--------------------------------------------------------------------------*/
1126:            /**
1127:             * Adds the title to the panel. There can only be one title, if mutiple titles are defined, they
1128:             * keep overwriting what has already be defined, so that the last definition is the one that
1129:             * prevails.
1130:             * 
1131:             * @param spec a <code>XMLElement</code> containing the specification for the title.
1132:             */
1133:            /*--------------------------------------------------------------------------*/
1134:            private void addTitle(XMLElement spec) {
1135:                String title = getText(spec);
1136:                boolean italic = getBoolean(spec, ITALICS, false);
1137:                boolean bold = getBoolean(spec, BOLD, false);
1138:                float multiplier = getFloat(spec, SIZE, 2.0f);
1139:                int justify = getAlignment(spec);
1140:
1141:                String icon = getIconName(spec);
1142:
1143:                if (title != null) {
1144:                    JLabel label = null;
1145:                    ImageIcon imgicon = null;
1146:                    try {
1147:                        imgicon = parent.icons.getImageIcon(icon);
1148:                        label = LabelFactory.create(title, imgicon,
1149:                                JLabel.TRAILING, true);
1150:                    } catch (Exception e) {
1151:                        Debug.trace("Icon " + icon
1152:                                + " not found in icon list. " + e.getMessage());
1153:                        label = LabelFactory.create(title);
1154:                    }
1155:                    Font font = label.getFont();
1156:                    float size = font.getSize();
1157:                    int style = 0;
1158:
1159:                    if (bold) {
1160:                        style += Font.BOLD;
1161:                    }
1162:                    if (italic) {
1163:                        style += Font.ITALIC;
1164:                    }
1165:
1166:                    font = font.deriveFont(style, (size * multiplier));
1167:                    label.setFont(font);
1168:                    label.setAlignmentX(0);
1169:
1170:                    TwoColumnConstraints constraints = new TwoColumnConstraints();
1171:                    constraints.align = justify;
1172:                    constraints.position = TwoColumnConstraints.NORTH;
1173:
1174:                    add(label, constraints);
1175:                }
1176:            }
1177:
1178:            protected String getIconName(XMLElement element) {
1179:                if (element == null) {
1180:                    return (null);
1181:                }
1182:
1183:                String key = element.getAttribute(ICON_KEY);
1184:                String text = null;
1185:                if ((key != null) && (langpack != null)) {
1186:                    try {
1187:                        text = langpack.getString(key);
1188:                    } catch (Throwable exception) {
1189:                        text = null;
1190:                    }
1191:                }
1192:
1193:                return (text);
1194:            }
1195:
1196:            /*--------------------------------------------------------------------------*/
1197:            /**
1198:             * Adds a rule field to the list of UI elements.
1199:             * 
1200:             * @param spec a <code>XMLElement</code> containing the specification for the rule field.
1201:             */
1202:            /*--------------------------------------------------------------------------*/
1203:            private void addRuleField(XMLElement spec) {
1204:                Vector<XMLElement> forPacks = spec
1205:                        .getChildrenNamed(SELECTEDPACKS);
1206:                Vector<XMLElement> forOs = spec.getChildrenNamed(OS);
1207:                XMLElement element = spec.getFirstChildNamed(SPEC);
1208:                String variable = spec.getAttribute(VARIABLE);
1209:                RuleInputField field = null;
1210:                JLabel label;
1211:                String layout;
1212:                String set;
1213:                String separator;
1214:                String format;
1215:                String validator = null;
1216:                String message = null;
1217:                boolean hasParams = false;
1218:                String paramName = null;
1219:                String paramValue = null;
1220:                HashMap<String, String> validateParamMap = null;
1221:                Vector<XMLElement> validateParams = null;
1222:                String processor = null;
1223:                int resultFormat = RuleInputField.DISPLAY_FORMAT;
1224:
1225:                // ----------------------------------------------------
1226:                // extract the specification details
1227:                // ----------------------------------------------------
1228:                if (element != null) {
1229:                    label = new JLabel(getText(element));
1230:                    layout = element.getAttribute(RULE_LAYOUT);
1231:                    set = element.getAttribute(SET);
1232:
1233:                    // retrieve value of variable if not specified
1234:                    // (does not work here because of special format for set attribute)
1235:                    // if (set == null)
1236:                    // {
1237:                    // set = idata.getVariable (variable);
1238:                    // }
1239:
1240:                    separator = element.getAttribute(RULE_SEPARATOR);
1241:                    format = element.getAttribute(RULE_RESULT_FORMAT);
1242:
1243:                    if (format != null) {
1244:                        if (format.equals(RULE_PLAIN_STRING)) {
1245:                            resultFormat = RuleInputField.PLAIN_STRING;
1246:                        } else if (format.equals(RULE_DISPLAY_FORMAT)) {
1247:                            resultFormat = RuleInputField.DISPLAY_FORMAT;
1248:                        } else if (format.equals(RULE_SPECIAL_SEPARATOR)) {
1249:                            resultFormat = RuleInputField.SPECIAL_SEPARATOR;
1250:                        } else if (format.equals(RULE_ENCRYPTED)) {
1251:                            resultFormat = RuleInputField.ENCRYPTED;
1252:                        }
1253:                    }
1254:                }
1255:                // ----------------------------------------------------
1256:                // if there is no specification element, return without
1257:                // doing anything.
1258:                // ----------------------------------------------------
1259:                else {
1260:                    return;
1261:                }
1262:
1263:                // ----------------------------------------------------
1264:                // get the description and add it to the list of UI
1265:                // elements if it exists.
1266:                // ----------------------------------------------------
1267:                element = spec.getFirstChildNamed(DESCRIPTION);
1268:                addDescription(element, forPacks, forOs);
1269:
1270:                // ----------------------------------------------------
1271:                // get the validator and processor if they are defined
1272:                // ----------------------------------------------------
1273:                element = spec.getFirstChildNamed(VALIDATOR);
1274:                if (element != null) {
1275:                    validator = element.getAttribute(CLASS);
1276:                    message = getText(element);
1277:                    // ----------------------------------------------------------
1278:                    // check and see if we have any parameters for this validator.
1279:                    // If so, then add them to validateParamMap.
1280:                    // ----------------------------------------------------------
1281:                    validateParams = element.getChildrenNamed(RULE_PARAM);
1282:                    if (validateParams != null && validateParams.size() > 0) {
1283:                        hasParams = true;
1284:
1285:                        if (validateParamMap == null)
1286:                            validateParamMap = new HashMap<String, String>();
1287:
1288:                        for (XMLElement validateParam : validateParams) {
1289:                            element = validateParam;
1290:                            paramName = element.getAttribute(RULE_PARAM_NAME);
1291:                            paramValue = element.getAttribute(RULE_PARAM_VALUE);
1292:                            validateParamMap.put(paramName, paramValue);
1293:                        }
1294:
1295:                    }
1296:
1297:                }
1298:
1299:                element = spec.getFirstChildNamed(PROCESSOR);
1300:                if (element != null) {
1301:                    processor = element.getAttribute(CLASS);
1302:                }
1303:
1304:                // ----------------------------------------------------
1305:                // create an instance of RuleInputField based on the
1306:                // extracted specifications, then add it to the list
1307:                // of UI elements.
1308:                // ----------------------------------------------------
1309:                if (hasParams) {
1310:                    field = new RuleInputField(layout, set, separator,
1311:                            validator, validateParamMap, processor,
1312:                            resultFormat, getToolkit(), idata);
1313:                } else {
1314:                    field = new RuleInputField(layout, set, separator,
1315:                            validator, processor, resultFormat, getToolkit(),
1316:                            idata);
1317:
1318:                }
1319:                TwoColumnConstraints constraints = new TwoColumnConstraints();
1320:                constraints.position = TwoColumnConstraints.WEST;
1321:
1322:                uiElements.add(new Object[] { null, FIELD_LABEL, null,
1323:                        constraints, label, forPacks, forOs });
1324:
1325:                TwoColumnConstraints constraints2 = new TwoColumnConstraints();
1326:                constraints2.position = TwoColumnConstraints.EAST;
1327:
1328:                uiElements.add(new Object[] { null, RULE_FIELD, variable,
1329:                        constraints2, field, forPacks, forOs, null, null,
1330:                        message });
1331:            }
1332:
1333:            /*--------------------------------------------------------------------------*/
1334:            /**
1335:             * Reads the data from the rule input field and sets the associated variable.
1336:             * 
1337:             * @param field the object array that holds the details of the field.
1338:             * 
1339:             * @return <code>true</code> if there was no problem reading the data or if there was an
1340:             * irrecovarable problem. If there was a problem that can be corrected by the operator, an error
1341:             * dialog is popped up and <code>false</code> is returned.
1342:             */
1343:            /*--------------------------------------------------------------------------*/
1344:            private boolean readRuleField(Object[] field) {
1345:                RuleInputField ruleField = null;
1346:                String variable = null;
1347:                String message = null;
1348:
1349:                try {
1350:                    ruleField = (RuleInputField) field[POS_FIELD];
1351:                    variable = (String) field[POS_VARIABLE];
1352:                    message = (String) field[POS_MESSAGE];
1353:                } catch (Throwable exception) {
1354:                    return (true);
1355:                }
1356:                if ((variable == null) || (ruleField == null)) {
1357:                    return (true);
1358:                }
1359:
1360:                boolean success = !validating || ruleField.validateContents();
1361:                if (!success) {
1362:                    showWarningMessageDialog(parentFrame, message);
1363:                    return (false);
1364:                }
1365:
1366:                idata.setVariable(variable, ruleField.getText());
1367:                entries.add(new TextValuePair(variable, ruleField.getText()));
1368:                return (true);
1369:            }
1370:
1371:            /*--------------------------------------------------------------------------*/
1372:            /**
1373:             * Adds a text field to the list of UI elements
1374:             * 
1375:             * @param spec a <code>XMLElement</code> containing the specification for the text field.
1376:             */
1377:            /*--------------------------------------------------------------------------*/
1378:            private void addTextField(XMLElement spec) {
1379:                Vector<XMLElement> forPacks = spec
1380:                        .getChildrenNamed(SELECTEDPACKS);
1381:                Vector<XMLElement> forOs = spec.getChildrenNamed(OS);
1382:                XMLElement element = spec.getFirstChildNamed(SPEC);
1383:                JLabel label;
1384:                String set;
1385:                int size;
1386:                HashMap<String, String> validateParamMap = null;
1387:                Vector<XMLElement> validateParams = null;
1388:                String validator = null;
1389:                String message = null;
1390:                boolean hasParams = false;
1391:                TextInputField inputField;
1392:
1393:                String variable = spec.getAttribute(VARIABLE);
1394:                if ((variable == null) || (variable.length() == 0)) {
1395:                    return;
1396:                }
1397:
1398:                // ----------------------------------------------------
1399:                // extract the specification details
1400:                // ----------------------------------------------------
1401:                if (element != null) {
1402:                    label = new JLabel(getText(element));
1403:                    set = element.getAttribute(SET);
1404:                    if (set == null) {
1405:                        set = idata.getVariable(variable);
1406:                        if (set == null) {
1407:                            set = "";
1408:                        }
1409:                    } else {
1410:                        if (set != null && !"".equals(set)) {
1411:                            VariableSubstitutor vs = new VariableSubstitutor(
1412:                                    idata.getVariables());
1413:                            set = vs.substitute(set, null);
1414:                        }
1415:                    }
1416:
1417:                    try {
1418:                        size = Integer
1419:                                .parseInt(element.getAttribute(TEXT_SIZE));
1420:                    } catch (Throwable exception) {
1421:                        size = 1;
1422:                    }
1423:                }
1424:                // ----------------------------------------------------
1425:                // if there is no specification element, return without
1426:                // doing anything.
1427:                // ----------------------------------------------------
1428:                else {
1429:                    return;
1430:                }
1431:
1432:                // ----------------------------------------------------
1433:                // get the validator if was defined
1434:                // ----------------------------------------------------
1435:                element = spec.getFirstChildNamed(VALIDATOR);
1436:                if (element != null) {
1437:                    validator = element.getAttribute(CLASS);
1438:                    message = getText(element);
1439:                    // ----------------------------------------------------------
1440:                    // check and see if we have any parameters for this validator.
1441:                    // If so, then add them to validateParamMap.
1442:                    // ----------------------------------------------------------
1443:                    validateParams = element.getChildrenNamed(RULE_PARAM);
1444:                    if (validateParams != null && validateParams.size() > 0) {
1445:                        hasParams = true;
1446:
1447:                        if (validateParamMap == null)
1448:                            validateParamMap = new HashMap<String, String>();
1449:
1450:                        for (XMLElement validateParam : validateParams) {
1451:                            element = validateParam;
1452:                            String paramName = element
1453:                                    .getAttribute(RULE_PARAM_NAME);
1454:                            String paramValue = element
1455:                                    .getAttribute(RULE_PARAM_VALUE);
1456:                            validateParamMap.put(paramName, paramValue);
1457:                        }
1458:
1459:                    }
1460:
1461:                }
1462:
1463:                // ----------------------------------------------------
1464:                // get the description and add it to the list UI
1465:                // elements if it exists.
1466:                // ----------------------------------------------------
1467:                element = spec.getFirstChildNamed(DESCRIPTION);
1468:                addDescription(element, forPacks, forOs);
1469:
1470:                // ----------------------------------------------------
1471:                // construct the UI element and add it to the list
1472:                // ----------------------------------------------------
1473:                if (hasParams) {
1474:                    inputField = new TextInputField(set, size, validator,
1475:                            validateParamMap);
1476:                } else {
1477:                    inputField = new TextInputField(set, size, validator);
1478:                }
1479:
1480:                TwoColumnConstraints constraints = new TwoColumnConstraints();
1481:                constraints.position = TwoColumnConstraints.WEST;
1482:
1483:                uiElements.add(new Object[] { null, FIELD_LABEL, null,
1484:                        constraints, label, forPacks, forOs });
1485:
1486:                TwoColumnConstraints constraints2 = new TwoColumnConstraints();
1487:                constraints2.position = TwoColumnConstraints.EAST;
1488:
1489:                uiElements.add(new Object[] { null, TEXT_FIELD, variable,
1490:                        constraints2, inputField, forPacks, forOs, null, null,
1491:                        message });
1492:            }
1493:
1494:            /*--------------------------------------------------------------------------*/
1495:            /**
1496:             * Reads data from the text field and sets the associated variable.
1497:             * 
1498:             * @param field the object array that holds the details of the field.
1499:             * 
1500:             * @return <code>true</code> if there was no problem reading the data or if there was an
1501:             * irrecovarable problem. If there was a problem that can be corrected by the operator, an error
1502:             * dialog is popped up and <code>false</code> is returned.
1503:             */
1504:            /*--------------------------------------------------------------------------*/
1505:            private boolean readTextField(Object[] field) {
1506:                TextInputField textField = null;
1507:                String variable = null;
1508:                String value = null;
1509:                String message = null;
1510:
1511:                try {
1512:                    textField = (TextInputField) field[POS_FIELD];
1513:                    variable = (String) field[POS_VARIABLE];
1514:                    message = (String) field[POS_MESSAGE];
1515:                    value = textField.getText();
1516:                } catch (Throwable exception) {
1517:                    return (true);
1518:                }
1519:                if ((variable == null) || (value == null)) {
1520:                    return (true);
1521:                }
1522:
1523:                // validate the input
1524:                boolean success = textField.validateContents();
1525:                if (!success) {
1526:                    showWarningMessageDialog(parentFrame, message);
1527:                    return (false);
1528:                }
1529:
1530:                idata.setVariable(variable, value);
1531:                entries.add(new TextValuePair(variable, value));
1532:                return (true);
1533:            }
1534:
1535:            /*--------------------------------------------------------------------------*/
1536:            /**
1537:             * Adds a combo box to the list of UI elements. <br>
1538:             * This is a complete example of a valid XML specification
1539:             * 
1540:             * <pre>
1541:             *   
1542:             *    
1543:             *     
1544:             *      &lt;field type=&quot;combo&quot; variable=&quot;testVariable&quot;&gt;
1545:             *        &lt;description text=&quot;Description for the combo box&quot; id=&quot;a key for translated text&quot;/&gt;
1546:             *        &lt;spec text=&quot;label&quot; id=&quot;key for the label&quot;/&gt;
1547:             *          &lt;choice text=&quot;choice 1&quot; id=&quot;&quot; value=&quot;combo box 1&quot;/&gt;
1548:             *          &lt;choice text=&quot;choice 2&quot; id=&quot;&quot; value=&quot;combo box 2&quot; set=&quot;true&quot;/&gt;
1549:             *          &lt;choice text=&quot;choice 3&quot; id=&quot;&quot; value=&quot;combo box 3&quot;/&gt;
1550:             *          &lt;choice text=&quot;choice 4&quot; id=&quot;&quot; value=&quot;combo box 4&quot;/&gt;
1551:             *        &lt;/spec&gt;
1552:             *      &lt;/field&gt;
1553:             *      
1554:             *     
1555:             *    
1556:             * </pre>
1557:             * 
1558:             * @param spec a <code>XMLElement</code> containing the specification for the combo box.
1559:             */
1560:            /*--------------------------------------------------------------------------*/
1561:            private void addComboBox(XMLElement spec) {
1562:                Vector<XMLElement> forPacks = spec
1563:                        .getChildrenNamed(SELECTEDPACKS);
1564:                Vector<XMLElement> forOs = spec.getChildrenNamed(OS);
1565:                XMLElement element = spec.getFirstChildNamed(SPEC);
1566:                String variable = spec.getAttribute(VARIABLE);
1567:                TextValuePair listItem = null;
1568:                JComboBox field = new JComboBox();
1569:                JLabel label;
1570:
1571:                boolean userinput = false; // is there already user input?
1572:                // ----------------------------------------------------
1573:                // extract the specification details
1574:                // ----------------------------------------------------
1575:                if (element != null) {
1576:                    label = new JLabel(getText(element));
1577:
1578:                    Vector<XMLElement> choices = element
1579:                            .getChildrenNamed(COMBO_CHOICE);
1580:
1581:                    if (choices == null) {
1582:                        return;
1583:                    }
1584:                    // get current value of associated variable
1585:                    String currentvariablevalue = idata.getVariable(variable);
1586:                    if (currentvariablevalue != null) {
1587:                        // there seems to be user input
1588:                        userinput = true;
1589:                    }
1590:                    for (int i = 0; i < choices.size(); i++) {
1591:                        String processorClass = (choices.elementAt(i))
1592:                                .getAttribute("processor");
1593:
1594:                        if (processorClass != null
1595:                                && !"".equals(processorClass)) {
1596:                            String choiceValues = "";
1597:                            try {
1598:                                choiceValues = ((Processor) Class.forName(
1599:                                        processorClass).newInstance())
1600:                                        .process(null);
1601:                            } catch (Throwable t) {
1602:                                t.printStackTrace();
1603:                            }
1604:                            String set = (choices.elementAt(i))
1605:                                    .getAttribute(SET);
1606:                            if (set == null) {
1607:                                set = "";
1608:                            }
1609:                            if (set != null && !"".equals(set)) {
1610:                                VariableSubstitutor vs = new VariableSubstitutor(
1611:                                        idata.getVariables());
1612:                                set = vs.substitute(set, null);
1613:                            }
1614:
1615:                            StringTokenizer tokenizer = new StringTokenizer(
1616:                                    choiceValues, ":");
1617:                            int counter = 0;
1618:                            while (tokenizer.hasMoreTokens()) {
1619:                                String token = tokenizer.nextToken();
1620:                                listItem = new TextValuePair(token, token);
1621:                                field.addItem(listItem);
1622:                                if (set.equals(token)) {
1623:                                    field
1624:                                            .setSelectedIndex(field
1625:                                                    .getItemCount() - 1);
1626:                                }
1627:                                counter++;
1628:                            }
1629:                        } else {
1630:                            String value = (choices.elementAt(i))
1631:                                    .getAttribute(COMBO_VALUE);
1632:                            listItem = new TextValuePair(getText(choices
1633:                                    .elementAt(i)), value);
1634:                            field.addItem(listItem);
1635:                            if (userinput) {
1636:                                // is the current value identical to the value associated with this element
1637:                                if ((value != null) && (value.length() > 0)
1638:                                        && (currentvariablevalue.equals(value))) {
1639:                                    // select it
1640:                                    field.setSelectedIndex(i);
1641:                                }
1642:                                // else do nothing
1643:                            } else {
1644:                                // there is no user input
1645:                                String set = (choices.elementAt(i))
1646:                                        .getAttribute(SET);
1647:                                if (set != null) {
1648:                                    if (set != null && !"".equals(set)) {
1649:                                        VariableSubstitutor vs = new VariableSubstitutor(
1650:                                                idata.getVariables());
1651:                                        set = vs.substitute(set, null);
1652:                                    }
1653:                                    if (set.equals(TRUE)) {
1654:                                        field.setSelectedIndex(i);
1655:                                    }
1656:                                }
1657:                            }
1658:                        }
1659:
1660:                    }
1661:                }
1662:                // ----------------------------------------------------
1663:                // if there is no specification element, return without
1664:                // doing anything.
1665:                // ----------------------------------------------------
1666:                else {
1667:                    return;
1668:                }
1669:
1670:                // ----------------------------------------------------
1671:                // get the description and add it to the list of UI
1672:                // elements if it exists.
1673:                // ----------------------------------------------------
1674:                element = spec.getFirstChildNamed(DESCRIPTION);
1675:                addDescription(element, forPacks, forOs);
1676:
1677:                TwoColumnConstraints constraints = new TwoColumnConstraints();
1678:                constraints.position = TwoColumnConstraints.WEST;
1679:
1680:                uiElements.add(new Object[] { null, FIELD_LABEL, null,
1681:                        constraints, label, forPacks, forOs });
1682:
1683:                TwoColumnConstraints constraints2 = new TwoColumnConstraints();
1684:                constraints2.position = TwoColumnConstraints.EAST;
1685:
1686:                uiElements.add(new Object[] { null, COMBO_FIELD, variable,
1687:                        constraints2, field, forPacks, forOs });
1688:            }
1689:
1690:            /*--------------------------------------------------------------------------*/
1691:            /**
1692:             * Reads the content of the combobox field and substitutes the associated variable.
1693:             * 
1694:             * @param field the object array that holds the details of the field.
1695:             * 
1696:             * @return <code>true</code> if there was no problem reading the data or if there was an
1697:             * irrecovarable problem. If there was a problem that can be corrected by the operator, an error
1698:             * dialog is popped up and <code>false</code> is returned.
1699:             */
1700:            /*--------------------------------------------------------------------------*/
1701:            private boolean readComboBox(Object[] field) {
1702:                String variable;
1703:                String value;
1704:                JComboBox comboBox;
1705:
1706:                try {
1707:                    variable = (String) field[POS_VARIABLE];
1708:                    comboBox = (JComboBox) field[POS_FIELD];
1709:                    value = ((TextValuePair) comboBox.getSelectedItem())
1710:                            .getValue();
1711:                } catch (Throwable exception) {
1712:                    return true;
1713:                }
1714:                if ((variable == null) || (value == null)) {
1715:                    return true;
1716:                }
1717:
1718:                idata.setVariable(variable, value);
1719:                entries.add(new TextValuePair(variable, value));
1720:                return true;
1721:            }
1722:
1723:            /*--------------------------------------------------------------------------*/
1724:            /**
1725:             * Adds a radio button set to the list of UI elements. <br>
1726:             * This is a complete example of a valid XML specification
1727:             * 
1728:             * <pre>
1729:             *   
1730:             *    
1731:             *     
1732:             *      &lt;field type=&quot;radio&quot; variable=&quot;testVariable&quot;&gt;
1733:             *        &lt;description text=&quot;Description for the radio buttons&quot; id=&quot;a key for translated text&quot;/&gt;
1734:             *        &lt;spec text=&quot;label&quot; id=&quot;key for the label&quot;/&gt;
1735:             *          &lt;choice text=&quot;radio 1&quot; id=&quot;&quot; value=&quot;&quot;/&gt;
1736:             *          &lt;choice text=&quot;radio 2&quot; id=&quot;&quot; value=&quot;&quot; set=&quot;true&quot;/&gt;
1737:             *          &lt;choice text=&quot;radio 3&quot; id=&quot;&quot; value=&quot;&quot;/&gt;
1738:             *          &lt;choice text=&quot;radio 4&quot; id=&quot;&quot; value=&quot;&quot;/&gt;
1739:             *          &lt;choice text=&quot;radio 5&quot; id=&quot;&quot; value=&quot;&quot;/&gt;
1740:             *        &lt;/spec&gt;
1741:             *      &lt;/field&gt;
1742:             *      
1743:             *     
1744:             *    
1745:             * </pre>
1746:             * 
1747:             * @param spec a <code>XMLElement</code> containing the specification for the radio button
1748:             * set.
1749:             */
1750:            /*--------------------------------------------------------------------------*/
1751:            private void addRadioButton(XMLElement spec) {
1752:                Vector<XMLElement> forPacks = spec
1753:                        .getChildrenNamed(SELECTEDPACKS);
1754:                Vector<XMLElement> forOs = spec.getChildrenNamed(OS);
1755:                String variable = spec.getAttribute(VARIABLE);
1756:                String value = null;
1757:
1758:                XMLElement element = null;
1759:                ButtonGroup group = new ButtonGroup();
1760:
1761:                TwoColumnConstraints constraints = new TwoColumnConstraints();
1762:                constraints.position = TwoColumnConstraints.BOTH;
1763:                constraints.indent = true;
1764:                constraints.stretch = true;
1765:
1766:                // ----------------------------------------------------
1767:                // get the description and add it to the list of UI
1768:                // elements if it exists.
1769:                // ----------------------------------------------------
1770:                element = spec.getFirstChildNamed(DESCRIPTION);
1771:                addDescription(element, forPacks, forOs);
1772:
1773:                // ----------------------------------------------------
1774:                // extract the specification details
1775:                // ----------------------------------------------------
1776:                element = spec.getFirstChildNamed(SPEC);
1777:
1778:                if (element != null) {
1779:                    Vector<XMLElement> choices = element
1780:                            .getChildrenNamed(RADIO_CHOICE);
1781:
1782:                    if (choices == null) {
1783:                        return;
1784:                    }
1785:
1786:                    // --------------------------------------------------
1787:                    // process each choice element
1788:                    // --------------------------------------------------
1789:                    for (int i = 0; i < choices.size(); i++) {
1790:                        JRadioButton choice = new JRadioButton();
1791:                        choice.setText(getText(choices.elementAt(i)));
1792:                        String causesValidataion = (choices.elementAt(i))
1793:                                .getAttribute(REVALIDATE);
1794:                        if (causesValidataion != null
1795:                                && causesValidataion.equals("yes"))
1796:                            choice.addActionListener(this );
1797:                        value = ((choices.elementAt(i))
1798:                                .getAttribute(RADIO_VALUE));
1799:
1800:                        group.add(choice);
1801:
1802:                        String set = (choices.elementAt(i)).getAttribute(SET);
1803:                        // in order to properly initialize dependent controls
1804:                        // we must set this variable now
1805:                        if (idata.getVariable(variable) == null)
1806:                            if (set != null)
1807:                                idata.setVariable(variable, value);
1808:                        if (set != null) {
1809:                            if (set != null && !"".equals(set)) {
1810:                                VariableSubstitutor vs = new VariableSubstitutor(
1811:                                        idata.getVariables());
1812:                                set = vs.substitute(set, null);
1813:                            }
1814:                            if (set.equals(TRUE)) {
1815:                                choice.setSelected(true);
1816:                            }
1817:                        }
1818:
1819:                        buttonGroups.add(group);
1820:                        uiElements.add(new Object[] { null, RADIO_FIELD,
1821:                                variable, constraints, choice, forPacks, forOs,
1822:                                value, null, null, group });
1823:                    }
1824:                }
1825:            }
1826:
1827:            /*--------------------------------------------------------------------------*/
1828:            /**
1829:             * Reads the content of the radio button field and substitutes the associated variable.
1830:             * 
1831:             * @param field the object array that holds the details of the field.
1832:             * 
1833:             * @return <code>true</code> if there was no problem reading the data or if there was an
1834:             * irrecovarable problem. If there was a problem that can be corrected by the operator, an error
1835:             * dialog is popped up and <code>false</code> is returned.
1836:             */
1837:            /*--------------------------------------------------------------------------*/
1838:            private boolean readRadioButton(Object[] field) {
1839:                String variable = null;
1840:                String value = null;
1841:                JRadioButton button = null;
1842:
1843:                try {
1844:                    button = (JRadioButton) field[POS_FIELD];
1845:
1846:                    if (!button.isSelected()) {
1847:                        return (true);
1848:                    }
1849:
1850:                    variable = (String) field[POS_VARIABLE];
1851:                    value = (String) field[POS_TRUE];
1852:                } catch (Throwable exception) {
1853:                    return (true);
1854:                }
1855:
1856:                idata.setVariable(variable, value);
1857:                entries.add(new TextValuePair(variable, value));
1858:                return (true);
1859:            }
1860:
1861:            /*--------------------------------------------------------------------------*/
1862:            /**
1863:             * Adds one or more password fields to the list of UI elements. <br>
1864:             * This is a complete example of a valid XML specification
1865:             * 
1866:             * <pre>
1867:             *   
1868:             *    
1869:             *     
1870:             *      &lt;field type=&quot;password&quot; variable=&quot;testVariable&quot;&gt;
1871:             *        &lt;description align=&quot;left&quot; txt=&quot;Please enter your password&quot; id=&quot;a key for translated text&quot;/&gt;
1872:             *        &lt;spec&gt;
1873:             *          &lt;pwd txt=&quot;Password&quot; id=&quot;key for the label&quot; size=&quot;10&quot; set=&quot;&quot;/&gt;
1874:             *          &lt;pwd txt=&quot;Retype password&quot; id=&quot;another key for the label&quot; size=&quot;10&quot; set=&quot;&quot;/&gt;
1875:             *        &lt;/spec&gt;
1876:             *        &lt;validator class=&quot;com.izforge.sample.PWDValidator&quot; txt=&quot;Both versions of the password must match&quot; id=&quot;key for the error text&quot;/&gt;
1877:             *        &lt;processor class=&quot;com.izforge.sample.PWDEncryptor&quot;/&gt;
1878:             *      &lt;/field&gt;
1879:             *      
1880:             * </pre>
1881:             * Additionally, parameters and multiple validators can be used to provide
1882:             * separate validation and error messages for each case.
1883:             * <pre>
1884:             *     
1885:             *    &lt;field type=&quot;password&quot; align=&quot;left&quot; variable=&quot;keystore.password&quot;&gt;
1886:             *      &lt;spec&gt;
1887:             *        &lt;pwd txt=&quot;Keystore Password:&quot; size=&quot;25&quot; set=&quot;&quot;/&gt;
1888:             *        &lt;pwd txt=&quot;Retype Password:&quot; size=&quot;25&quot; set=&quot;&quot;/&gt;
1889:             *      &lt;/spec&gt;
1890:             *      &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;
1891:             *      &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;
1892:             *        &lt;param name=&quot;keystoreFile&quot; value=&quot;${existing.ssl.keystore}&quot;/&gt;
1893:             *        &lt;param name=&quot;keystoreType&quot; value=&quot;JKS&quot;/&gt;
1894:             *        &lt;param name=&quot;keystoreAlias&quot; value=&quot;${keystore.key.alias}&quot;/&gt;
1895:             *      &lt;/validator&gt;
1896:             *    &lt;/field&gt;
1897:             *      
1898:             * </pre>
1899:             * 
1900:             * @param spec a <code>XMLElement</code> containing the specification for the set of password
1901:             * fields.
1902:             */
1903:            /*--------------------------------------------------------------------------*/
1904:            private void addPasswordField(XMLElement spec) {
1905:                Vector<XMLElement> forPacks = spec
1906:                        .getChildrenNamed(SELECTEDPACKS);
1907:                Vector<XMLElement> forOs = spec.getChildrenNamed(OS);
1908:                String variable = spec.getAttribute(VARIABLE);
1909:                String message = null;
1910:                String processor = null;
1911:                XMLElement element = null;
1912:                PasswordGroup group = null;
1913:                int size = 0;
1914:                // For multiple validator support
1915:                Vector<XMLElement> validatorsElem = null;
1916:                List<ValidatorContainer> validatorsList = new ArrayList<ValidatorContainer>();
1917:                int vsize = 0;
1918:
1919:                // ----------------------------------------------------
1920:                // get the description and add it to the list of UI
1921:                // elements if it exists.
1922:                // ----------------------------------------------------
1923:                element = spec.getFirstChildNamed(DESCRIPTION);
1924:                addDescription(element, forPacks, forOs);
1925:
1926:                // ----------------------------------------------------
1927:                // get the validator and processor if they are defined
1928:                // ----------------------------------------------------
1929:
1930:                validatorsElem = spec.getChildrenNamed(VALIDATOR);
1931:                if (validatorsElem != null && validatorsElem.size() > 0) {
1932:                    vsize = validatorsElem.size();
1933:                    for (int i = 0; i < vsize; i++) {
1934:                        element = validatorsElem.get(i);
1935:                        String validator = element.getAttribute(CLASS);
1936:                        message = getText(element);
1937:                        HashMap<String, String> validateParamMap = new HashMap<String, String>();
1938:                        // ----------------------------------------------------------
1939:                        // check and see if we have any parameters for this validator.
1940:                        // If so, then add them to validateParamMap.
1941:                        // ----------------------------------------------------------
1942:                        Vector<XMLElement> validateParams = element
1943:                                .getChildrenNamed(RULE_PARAM);
1944:                        if (validateParams != null && validateParams.size() > 0) {
1945:                            Iterator<XMLElement> iter = validateParams
1946:                                    .iterator();
1947:                            while (iter.hasNext()) {
1948:                                element = iter.next();
1949:                                String paramName = element
1950:                                        .getAttribute(RULE_PARAM_NAME);
1951:                                String paramValue = element
1952:                                        .getAttribute(RULE_PARAM_VALUE);
1953:                                // System.out.println("Adding parameter: "+paramName+"="+paramValue);
1954:                                validateParamMap.put(paramName, paramValue);
1955:                            }
1956:                        }
1957:                        validatorsList.add(new ValidatorContainer(validator,
1958:                                message, validateParamMap));
1959:                    }
1960:                }
1961:
1962:                element = spec.getFirstChildNamed(PROCESSOR);
1963:                if (element != null) {
1964:                    processor = element.getAttribute(CLASS);
1965:                }
1966:
1967:                group = new PasswordGroup(idata, validatorsList, processor);
1968:
1969:                // ----------------------------------------------------
1970:                // extract the specification details
1971:                // ----------------------------------------------------
1972:                element = spec.getFirstChildNamed(SPEC);
1973:
1974:                if (element != null) {
1975:                    Vector<XMLElement> inputs = element
1976:                            .getChildrenNamed(PWD_INPUT);
1977:
1978:                    if (inputs == null) {
1979:                        return;
1980:                    }
1981:
1982:                    // --------------------------------------------------
1983:                    // process each input field
1984:                    // --------------------------------------------------
1985:                    XMLElement fieldSpec;
1986:                    for (int i = 0; i < inputs.size(); i++) {
1987:                        fieldSpec = inputs.elementAt(i);
1988:                        String set = fieldSpec.getAttribute(SET);
1989:                        if (set != null && !"".equals(set)) {
1990:                            VariableSubstitutor vs = new VariableSubstitutor(
1991:                                    idata.getVariables());
1992:                            set = vs.substitute(set, null);
1993:                        }
1994:                        JLabel label = new JLabel(getText(fieldSpec));
1995:                        try {
1996:                            size = Integer.parseInt(fieldSpec
1997:                                    .getAttribute(PWD_SIZE));
1998:                        } catch (Throwable exception) {
1999:                            size = 1;
2000:                        }
2001:
2002:                        // ----------------------------------------------------
2003:                        // construct the UI element and add it to the list
2004:                        // ----------------------------------------------------
2005:                        JPasswordField field = new JPasswordField(set, size);
2006:                        field.setCaretPosition(0);
2007:
2008:                        TwoColumnConstraints constraints = new TwoColumnConstraints();
2009:                        constraints.position = TwoColumnConstraints.WEST;
2010:
2011:                        uiElements.add(new Object[] { null, FIELD_LABEL, null,
2012:                                constraints, label, forPacks, forOs });
2013:
2014:                        TwoColumnConstraints constraints2 = new TwoColumnConstraints();
2015:                        constraints2.position = TwoColumnConstraints.EAST;
2016:
2017:                        // Removed message to support pulling from multiple validators
2018:                        uiElements.add(new Object[] { null, PWD_FIELD,
2019:                                variable, constraints2, field, forPacks, forOs,
2020:                                null, null, null, group });
2021:                        // Original
2022:                        //        uiElements.add(new Object[]{null, PWD_FIELD, variable, constraints2, field,
2023:                        //          forPacks, forOs, null, null, message, group
2024:                        //        });
2025:                        group.addField(field);
2026:                    }
2027:                }
2028:
2029:                passwordGroups.add(group);
2030:            }
2031:
2032:            /*--------------------------------------------------------------------------*/
2033:            /**
2034:             * Reads the content of the password field and substitutes the associated variable.
2035:             * 
2036:             * @param field a password group that manages one or more passord fields.
2037:             * 
2038:             * @return <code>true</code> if there was no problem reading the data or if there was an
2039:             * irrecovarable problem. If there was a problem that can be corrected by the operator, an error
2040:             * dialog is popped up and <code>false</code> is returned.
2041:             */
2042:            /*--------------------------------------------------------------------------*/
2043:            private boolean readPasswordField(Object[] field) {
2044:                PasswordGroup group = null;
2045:                String variable = null;
2046:                String message = null;
2047:
2048:                try {
2049:                    group = (PasswordGroup) field[POS_GROUP];
2050:                    variable = (String) field[POS_VARIABLE];
2051:                    // Removed to support grabbing the message from multiple validators
2052:                    // message = (String) field[POS_MESSAGE];
2053:                } catch (Throwable exception) {
2054:                    return (true);
2055:                }
2056:                if ((variable == null) || (passwordGroupsRead.contains(group))) {
2057:                    return (true);
2058:                }
2059:                passwordGroups.add(group);
2060:
2061:                //boolean success = !validating || group.validateContents();
2062:                boolean success = !validating;
2063:
2064:                // Use each validator to validate contents
2065:                if (!success) {
2066:                    int size = group.validatorSize();
2067:                    // System.out.println("Found "+(size)+" validators");
2068:                    for (int i = 0; i < size; i++) {
2069:                        success = group.validateContents(i);
2070:                        if (!success) {
2071:                            JOptionPane
2072:                                    .showMessageDialog(
2073:                                            parentFrame,
2074:                                            group.getValidatorMessage(i),
2075:                                            parentFrame.langpack
2076:                                                    .getString("UserInputPanel.error.caption"),
2077:                                            JOptionPane.WARNING_MESSAGE);
2078:                            break;
2079:                        }
2080:                    }
2081:                }
2082:
2083:                //    // Changed to show messages for each validator
2084:                //    if (!success) {
2085:                //      JOptionPane.showMessageDialog(parentFrame, message, parentFrame.langpack.getString("UserInputPanel.error.caption"), JOptionPane.WARNING_MESSAGE);
2086:                //      return (false);
2087:                //    }
2088:
2089:                if (success) {
2090:                    idata.setVariable(variable, group.getPassword());
2091:                    entries
2092:                            .add(new TextValuePair(variable, group
2093:                                    .getPassword()));
2094:                }
2095:                return success;
2096:            }
2097:
2098:            /*--------------------------------------------------------------------------*/
2099:            /**
2100:             * Adds a chackbox to the list of UI elements.
2101:             * 
2102:             * @param spec a <code>XMLElement</code> containing the specification for the checkbox.
2103:             */
2104:            /*--------------------------------------------------------------------------*/
2105:            private void addCheckBox(XMLElement spec) {
2106:                Vector<XMLElement> forPacks = spec
2107:                        .getChildrenNamed(SELECTEDPACKS);
2108:                Vector<XMLElement> forOs = spec.getChildrenNamed(OS);
2109:                String label = "";
2110:                String set = null;
2111:                String trueValue = null;
2112:                String falseValue = null;
2113:                String variable = spec.getAttribute(VARIABLE);
2114:                String causesValidataion = null;
2115:                XMLElement detail = spec.getFirstChildNamed(SPEC);
2116:
2117:                if (variable == null) {
2118:                    return;
2119:                }
2120:
2121:                if (detail != null) {
2122:                    label = getText(detail);
2123:                    set = detail.getAttribute(SET);
2124:                    trueValue = detail.getAttribute(TRUE);
2125:                    falseValue = detail.getAttribute(FALSE);
2126:                    causesValidataion = detail.getAttribute(REVALIDATE);
2127:                    String value = idata.getVariable(variable);
2128:                    if (value != null) {
2129:                        set = value;
2130:                    }
2131:                }
2132:
2133:                JCheckBox checkbox = new JCheckBox(label);
2134:
2135:                if (causesValidataion != null
2136:                        && causesValidataion.equals("yes"))
2137:                    checkbox.addActionListener(this );
2138:                idata.setVariable(variable, set);
2139:
2140:                if (set != null) {
2141:                    if (set != null && !"".equals(set)) {
2142:                        VariableSubstitutor vs = new VariableSubstitutor(idata
2143:                                .getVariables());
2144:                        set = vs.substitute(set, null);
2145:                    }
2146:                    if (set.equals(FALSE)) {
2147:                        checkbox.setSelected(false);
2148:                    }
2149:                    if (set.equals(TRUE)) {
2150:                        checkbox.setSelected(true);
2151:                    }
2152:                }
2153:
2154:                // ----------------------------------------------------
2155:                // get the description and add it to the list of UI
2156:                // elements if it exists.
2157:                // ----------------------------------------------------
2158:                XMLElement element = spec.getFirstChildNamed(DESCRIPTION);
2159:                addDescription(element, forPacks, forOs);
2160:
2161:                TwoColumnConstraints constraints = new TwoColumnConstraints();
2162:                constraints.position = TwoColumnConstraints.BOTH;
2163:                constraints.stretch = true;
2164:                constraints.indent = true;
2165:
2166:                uiElements.add(new Object[] { null, CHECK_FIELD, variable,
2167:                        constraints, checkbox, forPacks, forOs, trueValue,
2168:                        falseValue });
2169:            }
2170:
2171:            /*--------------------------------------------------------------------------*/
2172:            /**
2173:             * Reads the content of the checkbox field and substitutes the associated variable.
2174:             * 
2175:             * @param field the object array that holds the details of the field.
2176:             * 
2177:             * @return <code>true</code> if there was no problem reading the data or if there was an
2178:             * irrecovarable problem. If there was a problem that can be corrected by the operator, an error
2179:             * dialog is popped up and <code>false</code> is returned.
2180:             */
2181:            /*--------------------------------------------------------------------------*/
2182:            private boolean readCheckBox(Object[] field) {
2183:                String variable = null;
2184:                String trueValue = null;
2185:                String falseValue = null;
2186:                JCheckBox box = null;
2187:
2188:                try {
2189:                    box = (JCheckBox) field[POS_FIELD];
2190:                    variable = (String) field[POS_VARIABLE];
2191:                    trueValue = (String) field[POS_TRUE];
2192:                    if (trueValue == null) {
2193:                        trueValue = "";
2194:                    }
2195:
2196:                    falseValue = (String) field[POS_FALSE];
2197:                    if (falseValue == null) {
2198:                        falseValue = "";
2199:                    }
2200:                } catch (Throwable exception) {
2201:                    return (true);
2202:                }
2203:
2204:                if (box.isSelected()) {
2205:                    idata.setVariable(variable, trueValue);
2206:                    entries.add(new TextValuePair(variable, trueValue));
2207:                } else {
2208:                    idata.setVariable(variable, falseValue);
2209:                    entries.add(new TextValuePair(variable, falseValue));
2210:                }
2211:
2212:                return (true);
2213:            }
2214:
2215:            /*--------------------------------------------------------------------------*/
2216:            /**
2217:             * Adds a search field to the list of UI elements.
2218:             * <p>
2219:             * This is a complete example of a valid XML specification
2220:             * 
2221:             * <pre>
2222:             *   
2223:             *    
2224:             *     
2225:             *      &lt;field type=&quot;search&quot; variable=&quot;testVariable&quot;&gt;
2226:             *        &lt;description text=&quot;Description for the search field&quot; id=&quot;a key for translated text&quot;/&gt;
2227:             *        &lt;spec text=&quot;label&quot; id=&quot;key for the label&quot; filename=&quot;the_file_to_search&quot; result=&quot;directory&quot; /&gt; &lt;!-- values for result: directory, file --&gt;
2228:             *          &lt;choice dir=&quot;directory1&quot; set=&quot;true&quot; /&gt; &lt;!-- default value --&gt;
2229:             *          &lt;choice dir=&quot;dir2&quot; /&gt;
2230:             *        &lt;/spec&gt;
2231:             *      &lt;/field&gt;
2232:             *      
2233:             *     
2234:             *    
2235:             * </pre>
2236:             * 
2237:             * @param spec a <code>XMLElement</code> containing the specification for the search field
2238:             */
2239:            /*--------------------------------------------------------------------------*/
2240:            private void addSearch(XMLElement spec) {
2241:                Vector<XMLElement> forPacks = spec
2242:                        .getChildrenNamed(SELECTEDPACKS);
2243:                Vector<XMLElement> forOs = spec.getChildrenNamed(OS);
2244:                XMLElement element = spec.getFirstChildNamed(SPEC);
2245:                String variable = spec.getAttribute(VARIABLE);
2246:                String filename = null;
2247:                String check_filename = null;
2248:                int search_type = 0;
2249:                int result_type = 0;
2250:                JComboBox combobox = new JComboBox();
2251:                JLabel label = null;
2252:
2253:                // System.out.println ("adding search combobox, variable "+variable);
2254:
2255:                // allow the user to enter something
2256:                combobox.setEditable(true);
2257:
2258:                // ----------------------------------------------------
2259:                // extract the specification details
2260:                // ----------------------------------------------------
2261:                if (element != null) {
2262:                    label = new JLabel(getText(element));
2263:
2264:                    // search type is optional (default: file)
2265:                    search_type = SearchField.TYPE_FILE;
2266:
2267:                    String search_type_str = element.getAttribute(SEARCH_TYPE);
2268:
2269:                    if (search_type_str != null) {
2270:                        if (search_type_str.equals(SEARCH_FILE)) {
2271:                            search_type = SearchField.TYPE_FILE;
2272:                        } else if (search_type_str.equals(SEARCH_DIRECTORY)) {
2273:                            search_type = SearchField.TYPE_DIRECTORY;
2274:                        }
2275:                    }
2276:
2277:                    // result type is mandatory too
2278:                    String result_type_str = element
2279:                            .getAttribute(SEARCH_RESULT);
2280:
2281:                    if (result_type_str == null) {
2282:                        return;
2283:                    } else if (result_type_str.equals(SEARCH_FILE)) {
2284:                        result_type = SearchField.RESULT_FILE;
2285:                    } else if (result_type_str.equals(SEARCH_DIRECTORY)) {
2286:                        result_type = SearchField.RESULT_DIRECTORY;
2287:                    } else if (result_type_str.equals(SEARCH_PARENTDIR)) {
2288:                        result_type = SearchField.RESULT_PARENTDIR;
2289:                    } else {
2290:                        return;
2291:                    }
2292:
2293:                    // might be missing - null is okay
2294:                    filename = element.getAttribute(SEARCH_FILENAME);
2295:
2296:                    check_filename = element.getAttribute(SEARCH_CHECKFILENAME);
2297:
2298:                    Vector<XMLElement> choices = element
2299:                            .getChildrenNamed(SEARCH_CHOICE);
2300:
2301:                    if (choices == null) {
2302:                        return;
2303:                    }
2304:
2305:                    for (int i = 0; i < choices.size(); i++) {
2306:                        XMLElement choice_el = choices.elementAt(i);
2307:
2308:                        if (!OsConstraint.oneMatchesCurrentSystem(choice_el))
2309:                            continue;
2310:
2311:                        String value = choice_el.getAttribute(SEARCH_VALUE);
2312:
2313:                        combobox.addItem(value);
2314:
2315:                        String set = (choices.elementAt(i)).getAttribute(SET);
2316:                        if (set != null) {
2317:                            if (set != null && !"".equals(set)) {
2318:                                VariableSubstitutor vs = new VariableSubstitutor(
2319:                                        idata.getVariables());
2320:                                set = vs.substitute(set, null);
2321:                            }
2322:                            if (set.equals(TRUE)) {
2323:                                combobox.setSelectedIndex(i);
2324:                            }
2325:                        }
2326:                    }
2327:                }
2328:                // ----------------------------------------------------
2329:                // if there is no specification element, return without
2330:                // doing anything.
2331:                // ----------------------------------------------------
2332:                else {
2333:                    return;
2334:                }
2335:
2336:                // ----------------------------------------------------
2337:                // get the description and add it to the list of UI
2338:                // elements if it exists.
2339:                // ----------------------------------------------------
2340:                element = spec.getFirstChildNamed(DESCRIPTION);
2341:                addDescription(element, forPacks, forOs);
2342:
2343:                TwoColumnConstraints westconstraint1 = new TwoColumnConstraints();
2344:                westconstraint1.position = TwoColumnConstraints.WEST;
2345:
2346:                uiElements.add(new Object[] { null, FIELD_LABEL, null,
2347:                        westconstraint1, label, forPacks, forOs });
2348:
2349:                TwoColumnConstraints eastconstraint1 = new TwoColumnConstraints();
2350:                eastconstraint1.position = TwoColumnConstraints.EAST;
2351:
2352:                StringBuffer tooltiptext = new StringBuffer();
2353:
2354:                if ((filename != null) && (filename.length() > 0)) {
2355:                    tooltiptext
2356:                            .append(MessageFormat
2357:                                    .format(
2358:                                            parentFrame.langpack
2359:                                                    .getString("UserInputPanel.search.location"),
2360:                                            new Object[] { new String[] { filename } }));
2361:                }
2362:
2363:                boolean showAutodetect = (check_filename != null)
2364:                        && (check_filename.length() > 0);
2365:                if (showAutodetect) {
2366:                    tooltiptext
2367:                            .append(MessageFormat
2368:                                    .format(
2369:                                            parentFrame.langpack
2370:                                                    .getString("UserInputPanel.search.location.checkedfile"),
2371:                                            new Object[] { new String[] { check_filename } }));
2372:                }
2373:
2374:                if (tooltiptext.length() > 0)
2375:                    combobox.setToolTipText(tooltiptext.toString());
2376:
2377:                uiElements.add(new Object[] { null, SEARCH_FIELD, variable,
2378:                        eastconstraint1, combobox, forPacks, forOs });
2379:
2380:                JPanel buttonPanel = new JPanel();
2381:                buttonPanel.setLayout(new com.izforge.izpack.gui.FlowLayout(
2382:                        com.izforge.izpack.gui.FlowLayout.LEADING));
2383:
2384:                JButton autodetectButton = ButtonFactory.createButton(
2385:                        parentFrame.langpack
2386:                                .getString("UserInputPanel.search.autodetect"),
2387:                        idata.buttonsHColor);
2388:                autodetectButton.setVisible(showAutodetect);
2389:
2390:                autodetectButton.setToolTipText(parentFrame.langpack
2391:                        .getString("UserInputPanel.search.autodetect.tooltip"));
2392:
2393:                buttonPanel.add(autodetectButton);
2394:
2395:                JButton browseButton = ButtonFactory.createButton(
2396:                        parentFrame.langpack
2397:                                .getString("UserInputPanel.search.browse"),
2398:                        idata.buttonsHColor);
2399:
2400:                buttonPanel.add(browseButton);
2401:
2402:                TwoColumnConstraints eastonlyconstraint = new TwoColumnConstraints();
2403:                eastonlyconstraint.position = TwoColumnConstraints.EASTONLY;
2404:
2405:                uiElements.add(new Object[] { null, SEARCH_BUTTON_FIELD, null,
2406:                        eastonlyconstraint, buttonPanel, forPacks, forOs });
2407:
2408:                searchFields.add(new SearchField(filename, check_filename,
2409:                        parentFrame, combobox, autodetectButton, browseButton,
2410:                        search_type, result_type));
2411:            }
2412:
2413:            /*--------------------------------------------------------------------------*/
2414:            /**
2415:             * Reads the content of the search field and substitutes the associated variable.
2416:             * 
2417:             * @param field the object array that holds the details of the field.
2418:             * 
2419:             * @return <code>true</code> if there was no problem reading the data or if there was an
2420:             * irrecovarable problem. If there was a problem that can be corrected by the operator, an error
2421:             * dialog is popped up and <code>false</code> is returned.
2422:             */
2423:            /*--------------------------------------------------------------------------*/
2424:            private boolean readSearch(Object[] field) {
2425:                String variable = null;
2426:                String value = null;
2427:                JComboBox comboBox = null;
2428:
2429:                try {
2430:                    variable = (String) field[POS_VARIABLE];
2431:                    comboBox = (JComboBox) field[POS_FIELD];
2432:                    for (int i = 0; i < this .searchFields.size(); ++i) {
2433:                        SearchField sf = this .searchFields.elementAt(i);
2434:                        if (sf.belongsTo(comboBox)) {
2435:                            value = sf.getResult();
2436:                            break;
2437:                        }
2438:                    }
2439:                } catch (Throwable exception) {
2440:                    return (true);
2441:                }
2442:                if ((variable == null) || (value == null)) {
2443:                    return (true);
2444:                }
2445:
2446:                idata.setVariable(variable, value);
2447:                entries.add(new TextValuePair(variable, value));
2448:                return (true);
2449:            }
2450:
2451:            /*--------------------------------------------------------------------------*/
2452:            /**
2453:             * Adds text to the list of UI elements
2454:             * 
2455:             * @param spec a <code>XMLElement</code> containing the specification for the text.
2456:             */
2457:            /*--------------------------------------------------------------------------*/
2458:            private void addText(XMLElement spec) {
2459:                Vector<XMLElement> forPacks = spec
2460:                        .getChildrenNamed(SELECTEDPACKS);
2461:                Vector<XMLElement> forOs = spec.getChildrenNamed(OS);
2462:
2463:                addDescription(spec, forPacks, forOs);
2464:            }
2465:
2466:            /*--------------------------------------------------------------------------*/
2467:            /**
2468:             * Adds a dummy field to the list of UI elements to act as spacer.
2469:             * 
2470:             * @param spec a <code>XMLElement</code> containing other specifications. At present this
2471:             * information is not used but might be in future versions.
2472:             */
2473:            /*--------------------------------------------------------------------------*/
2474:            private void addSpace(XMLElement spec) {
2475:                Vector<XMLElement> forPacks = spec
2476:                        .getChildrenNamed(SELECTEDPACKS);
2477:                Vector<XMLElement> forOs = spec.getChildrenNamed(OS);
2478:                JPanel panel = new JPanel();
2479:
2480:                TwoColumnConstraints constraints = new TwoColumnConstraints();
2481:                constraints.position = TwoColumnConstraints.BOTH;
2482:                constraints.stretch = true;
2483:
2484:                uiElements.add(new Object[] { null, SPACE_FIELD, null,
2485:                        constraints, panel, forPacks, forOs });
2486:            }
2487:
2488:            /*--------------------------------------------------------------------------*/
2489:            /**
2490:             * Adds a dividing line to the list of UI elements act as separator.
2491:             * 
2492:             * @param spec a <code>XMLElement</code> containing additional specifications.
2493:             */
2494:            /*--------------------------------------------------------------------------*/
2495:            private void addDivider(XMLElement spec) {
2496:                Vector<XMLElement> forPacks = spec
2497:                        .getChildrenNamed(SELECTEDPACKS);
2498:                Vector<XMLElement> forOs = spec.getChildrenNamed(OS);
2499:                JPanel panel = new JPanel();
2500:                String alignment = spec.getAttribute(ALIGNMENT);
2501:
2502:                if (alignment != null) {
2503:                    if (alignment.equals(TOP)) {
2504:                        panel.setBorder(BorderFactory.createMatteBorder(1, 0,
2505:                                0, 0, Color.gray));
2506:                    } else {
2507:                        panel.setBorder(BorderFactory.createMatteBorder(0, 0,
2508:                                1, 0, Color.gray));
2509:                    }
2510:                } else {
2511:                    panel.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0,
2512:                            Color.gray));
2513:                }
2514:
2515:                TwoColumnConstraints constraints = new TwoColumnConstraints();
2516:                constraints.position = TwoColumnConstraints.BOTH;
2517:                constraints.stretch = true;
2518:
2519:                uiElements.add(new Object[] { null, DIVIDER_FIELD, null,
2520:                        constraints, panel, forPacks, forOs });
2521:            }
2522:
2523:            /*--------------------------------------------------------------------------*/
2524:            /**
2525:             * Adds a description to the list of UI elements.
2526:             * 
2527:             * @param spec a <code>XMLElement</code> containing the specification for the description.
2528:             */
2529:            /*--------------------------------------------------------------------------*/
2530:            private void addDescription(XMLElement spec,
2531:                    Vector<XMLElement> forPacks, Vector<XMLElement> forOs) {
2532:                String description;
2533:                TwoColumnConstraints constraints = new TwoColumnConstraints();
2534:                constraints.position = TwoColumnConstraints.BOTH;
2535:                constraints.stretch = true;
2536:
2537:                if (spec != null) {
2538:                    description = getText(spec);
2539:
2540:                    // if we have a description, add it to the UI elements
2541:                    if (description != null) {
2542:                        String alignment = spec.getAttribute(ALIGNMENT);
2543:                        // FIX needed: where do we use this variable at all? i dont think so... 
2544:                        int justify = MultiLineLabel.LEFT;
2545:
2546:                        if (alignment != null) {
2547:                            if (alignment.equals(LEFT)) {
2548:                                justify = MultiLineLabel.LEFT;
2549:                            } else if (alignment.equals(CENTER)) {
2550:                                justify = MultiLineLabel.CENTER;
2551:                            } else if (alignment.equals(RIGHT)) {
2552:                                justify = MultiLineLabel.RIGHT;
2553:                            }
2554:                        }
2555:
2556:                        javax.swing.JTextPane label = new javax.swing.JTextPane();
2557:
2558:                        // Not editable, but still selectable.
2559:                        label.setEditable(false);
2560:
2561:                        // If html tags are present enable html rendering, otherwise the JTextPane
2562:                        // looks exactly like MultiLineLabel.
2563:                        if (description.startsWith("<html>")
2564:                                && description.endsWith("</html>"))
2565:                            label.setContentType("text/html");
2566:                        label.setText(description);
2567:
2568:                        // Background color and font to match the label's.
2569:                        label.setBackground(javax.swing.UIManager
2570:                                .getColor("label.backgroud"));
2571:                        label.setMargin(new java.awt.Insets(3, 0, 3, 0));
2572:                        // workaround to cut out layout problems
2573:                        label.getPreferredSize();
2574:                        // end of workaround.
2575:
2576:                        uiElements.add(new Object[] { null, DESCRIPTION, null,
2577:                                constraints, label, forPacks, forOs });
2578:                    }
2579:                }
2580:            }
2581:
2582:            /*--------------------------------------------------------------------------*/
2583:            /**
2584:             * Retrieves the value of a boolean attribute. If the attribute is found and the values equals
2585:             * the value of the constant <code>TRUE</code> then true is returned. If it equals
2586:             * <code>FALSE</code> the false is returned. In all other cases, including when the attribute
2587:             * is not found, the default value is returned.
2588:             * 
2589:             * @param element the <code>XMLElement</code> to search for the attribute.
2590:             * @param attribute the attribute to search for
2591:             * @param defaultValue the default value to use if the attribute does not exist or a illegal
2592:             * value was discovered.
2593:             * 
2594:             * @return <code>true</code> if the attribute is found and the value equals the the constant
2595:             * <code>TRUE</code>. <<code> if the
2596:             *            attribute is <code>FALSE</code>. In all other cases the
2597:             *            default value is returned.
2598:             */
2599:            /*--------------------------------------------------------------------------*/
2600:            private boolean getBoolean(XMLElement element, String attribute,
2601:                    boolean defaultValue) {
2602:                boolean result = defaultValue;
2603:
2604:                if ((attribute != null) && (attribute.length() > 0)) {
2605:                    String value = element.getAttribute(attribute);
2606:
2607:                    if (value != null) {
2608:                        if (value.equals(TRUE)) {
2609:                            result = true;
2610:                        } else if (value.equals(FALSE)) {
2611:                            result = false;
2612:                        }
2613:                    }
2614:                }
2615:
2616:                return (result);
2617:            }
2618:
2619:            /*--------------------------------------------------------------------------*/
2620:            /**
2621:             * Retrieves the value of an integer attribute. If the attribute is not found or the value is
2622:             * non-numeric then the default value is returned.
2623:             * 
2624:             * @param element the <code>XMLElement</code> to search for the attribute.
2625:             * @param attribute the attribute to search for
2626:             * @param defaultValue the default value to use in case the attribute does not exist.
2627:             * 
2628:             * @return the value of the attribute. If the attribute is not found or the content is not a
2629:             * legal integer, then the default value is returned.
2630:             */
2631:            /*--------------------------------------------------------------------------*/
2632:            // private int getInt(XMLElement element, String attribute, int defaultValue)
2633:            // {
2634:            // int result = defaultValue;
2635:            //
2636:            // if ((attribute != null) && (attribute.length() > 0))
2637:            // {
2638:            // try
2639:            // {
2640:            // result = Integer.parseInt(element.getAttribute(attribute));
2641:            // }
2642:            // catch (Throwable exception)
2643:            // {}
2644:            // }
2645:            //
2646:            // return (result);
2647:            // }
2648:            /*--------------------------------------------------------------------------*/
2649:            /**
2650:             * Retrieves the value of a floating point attribute. If the attribute is not found or the value
2651:             * is non-numeric then the default value is returned.
2652:             * 
2653:             * @param element the <code>XMLElement</code> to search for the attribute.
2654:             * @param attribute the attribute to search for
2655:             * @param defaultValue the default value to use in case the attribute does not exist.
2656:             * 
2657:             * @return the value of the attribute. If the attribute is not found or the content is not a
2658:             * legal integer, then the default value is returned.
2659:             */
2660:            /*--------------------------------------------------------------------------*/
2661:            private float getFloat(XMLElement element, String attribute,
2662:                    float defaultValue) {
2663:                float result = defaultValue;
2664:
2665:                if ((attribute != null) && (attribute.length() > 0)) {
2666:                    try {
2667:                        result = Float.parseFloat(element
2668:                                .getAttribute(attribute));
2669:                    } catch (Throwable exception) {
2670:                    }
2671:                }
2672:
2673:                return (result);
2674:            }
2675:
2676:            /*--------------------------------------------------------------------------*/
2677:            /**
2678:             * Extracts the text from an <code>XMLElement</code>. The text must be defined in the
2679:             * resource file under the key defined in the <code>id</code> attribute or as value of the
2680:             * attribute <code>text</code>.
2681:             * 
2682:             * @param element the <code>XMLElement</code> from which to extract the text.
2683:             * 
2684:             * @return The text defined in the <code>XMLElement</code>. If no text can be located,
2685:             * <code>null</code> is returned.
2686:             */
2687:            /*--------------------------------------------------------------------------*/
2688:            private String getText(XMLElement element) {
2689:                if (element == null) {
2690:                    return (null);
2691:                }
2692:
2693:                String key = element.getAttribute(KEY);
2694:                String text = null;
2695:
2696:                if ((key != null) && (langpack != null)) {
2697:                    try {
2698:                        text = langpack.getString(key);
2699:                    } catch (Throwable exception) {
2700:                        text = null;
2701:                    }
2702:                }
2703:
2704:                // if there is no text in the description, then
2705:                // we were unable to retrieve it form the resource.
2706:                // In this case try to get the text directly from
2707:                // the XMLElement
2708:                if (text == null) {
2709:                    text = element.getAttribute(TEXT);
2710:                }
2711:
2712:                // try to parse the text, and substitute any variable it finds
2713:                VariableSubstitutor vs = new VariableSubstitutor(idata
2714:                        .getVariables());
2715:
2716:                return (vs.substitute(text, null));
2717:            }
2718:
2719:            /*--------------------------------------------------------------------------*/
2720:            /**
2721:             * Retreives the alignment setting for the <code>XMLElement</code>. The default value in case
2722:             * the <code>ALIGNMENT</code> attribute is not found or the value is illegal is
2723:             * <code>TwoColumnConstraints.LEFT</code>.
2724:             * 
2725:             * @param element the <code>XMLElement</code> from which to extract the alignment setting.
2726:             * 
2727:             * @return the alignement setting for the <code>XMLElement</code>. The value is either
2728:             * <code>TwoColumnConstraints.LEFT</code>, <code>TwoColumnConstraints.CENTER</code> or
2729:             * <code>TwoColumnConstraints.RIGHT</code>.
2730:             * 
2731:             * @see com.izforge.izpack.gui.TwoColumnConstraints
2732:             */
2733:            /*--------------------------------------------------------------------------*/
2734:            private int getAlignment(XMLElement element) {
2735:                int result = TwoColumnConstraints.LEFT;
2736:
2737:                String value = element.getAttribute(ALIGNMENT);
2738:
2739:                if (value != null) {
2740:                    if (value.equals(LEFT)) {
2741:                        result = TwoColumnConstraints.LEFT;
2742:                    } else if (value.equals(CENTER)) {
2743:                        result = TwoColumnConstraints.CENTER;
2744:                    } else if (value.equals(RIGHT)) {
2745:                        result = TwoColumnConstraints.RIGHT;
2746:                    }
2747:                }
2748:
2749:                return (result);
2750:            }
2751:
2752:            /**
2753:             * Verifies if an item is required for the operating system the installer executed. The
2754:             * configuration for this feature is: <br/> &lt;os family="unix"/&gt; <br>
2755:             * <br>
2756:             * <b>Note:</b><br>
2757:             * If the list of the os is empty then <code>true</code> is always returnd.
2758:             * 
2759:             * @param os The <code>Vector</code> of <code>String</code>s. containing the os names
2760:             * 
2761:             * @return <code>true</code> if the item is required for the os, otherwise returns
2762:             * <code>false</code>.
2763:             */
2764:            public boolean itemRequiredForOs(Vector<XMLElement> os) {
2765:                if (os.size() == 0) {
2766:                    return true;
2767:                }
2768:
2769:                for (int i = 0; i < os.size(); i++) {
2770:                    String family = (os.elementAt(i)).getAttribute(FAMILY);
2771:                    boolean match = false;
2772:
2773:                    if ("windows".equals(family)) {
2774:                        match = OsVersion.IS_WINDOWS;
2775:                    } else if ("mac".equals(family)) {
2776:                        match = OsVersion.IS_OSX;
2777:                    } else if ("unix".equals(family)) {
2778:                        match = OsVersion.IS_UNIX;
2779:                    }
2780:                    if (match) {
2781:                        return true;
2782:                    }
2783:                }
2784:                return false;
2785:            }
2786:
2787:            /*--------------------------------------------------------------------------*/
2788:            /**
2789:             * Verifies if an item is required for any of the packs listed. An item is required for a pack
2790:             * in the list if that pack is actually selected for installation. <br>
2791:             * <br>
2792:             * <b>Note:</b><br>
2793:             * If the list of selected packs is empty then <code>true</code> is always returnd. The same
2794:             * is true if the <code>packs</code> list is empty.
2795:             * 
2796:             * @param packs a <code>Vector</code> of <code>String</code>s. Each of the strings denotes
2797:             * a pack for which an item should be created if the pack is actually installed.
2798:             * 
2799:             * @return <code>true</code> if the item is required for at least one pack in the list,
2800:             * otherwise returns <code>false</code>.
2801:             */
2802:            /*--------------------------------------------------------------------------*/
2803:            /*
2804:             * $ @design
2805:             * 
2806:             * The information about the installed packs comes from InstallData.selectedPacks. This assumes
2807:             * that this panel is presented to the user AFTER the PacksPanel.
2808:             * --------------------------------------------------------------------------
2809:             */
2810:            private boolean itemRequiredFor(Vector<XMLElement> packs) {
2811:
2812:                String selected;
2813:                String required;
2814:
2815:                if (packs.size() == 0) {
2816:                    return (true);
2817:                }
2818:
2819:                // ----------------------------------------------------
2820:                // We are getting to this point if any packs have been
2821:                // specified. This means that there is a possibility
2822:                // that some UI elements will not get added. This
2823:                // means that we can not allow to go back to the
2824:                // PacksPanel, because the process of building the
2825:                // UI is not reversable.
2826:                // ----------------------------------------------------
2827:                // packsDefined = true;
2828:
2829:                // ----------------------------------------------------
2830:                // analyze if the any of the packs for which the item
2831:                // is required have been selected for installation.
2832:                // ----------------------------------------------------
2833:                for (int i = 0; i < idata.selectedPacks.size(); i++) {
2834:                    selected = ((Pack) idata.selectedPacks.get(i)).name;
2835:
2836:                    for (int k = 0; k < packs.size(); k++) {
2837:                        required = (packs.elementAt(k)).getAttribute(NAME, "");
2838:                        if (selected.equals(required)) {
2839:                            return (true);
2840:                        }
2841:                    }
2842:                }
2843:
2844:                return (false);
2845:            }
2846:
2847:            /*--------------------------------------------------------------------------*/
2848:            /**
2849:             * Verifies if an item is required for any of the packs listed. An item is required for a pack
2850:             * in the list if that pack is actually NOT selected for installation. <br>
2851:             * <br>
2852:             * <b>Note:</b><br>
2853:             * If the list of selected packs is empty then <code>true</code> is always returnd. The same
2854:             * is true if the <code>packs</code> list is empty.
2855:             * 
2856:             * @param packs a <code>Vector</code> of <code>String</code>s. Each of the strings denotes
2857:             * a pack for which an item should be created if the pack is actually installed.
2858:             * 
2859:             * @return <code>true</code> if the item is required for at least one pack in the list,
2860:             * otherwise returns <code>false</code>.
2861:             */
2862:            /*--------------------------------------------------------------------------*/
2863:            /*
2864:             * $ @design
2865:             * 
2866:             * The information about the installed packs comes from InstallData.selectedPacks. This assumes
2867:             * that this panel is presented to the user AFTER the PacksPanel.
2868:             * --------------------------------------------------------------------------
2869:             */
2870:            private boolean itemRequiredForUnselected(Vector<XMLElement> packs) {
2871:
2872:                String selected;
2873:                String required;
2874:
2875:                if (packs.size() == 0) {
2876:                    return (true);
2877:                }
2878:
2879:                // ----------------------------------------------------
2880:                // analyze if the any of the packs for which the item
2881:                // is required have been selected for installation.
2882:                // ----------------------------------------------------
2883:                for (int i = 0; i < idata.selectedPacks.size(); i++) {
2884:                    selected = ((Pack) idata.selectedPacks.get(i)).name;
2885:
2886:                    for (int k = 0; k < packs.size(); k++) {
2887:                        required = (packs.elementAt(k)).getAttribute(NAME, "");
2888:                        if (selected.equals(required)) {
2889:                            return (false);
2890:                        }
2891:                    }
2892:                }
2893:
2894:                return (true);
2895:            }
2896:
2897:            // ----------- Inheritance stuff -----------------------------------------
2898:            /**
2899:             * Returns the uiElements.
2900:             * 
2901:             * @return Returns the uiElements.
2902:             */
2903:            protected Vector<Object[]> getUiElements() {
2904:                return uiElements;
2905:            }
2906:
2907:            // --------------------------------------------------------------------------
2908:            // Inner Classes
2909:            // --------------------------------------------------------------------------
2910:
2911:            /*---------------------------------------------------------------------------*/
2912:            /**
2913:             * This class can be used to associate a text string and a (text) value.
2914:             */
2915:            /*---------------------------------------------------------------------------*/
2916:            private static class TextValuePair {
2917:
2918:                private String text = "";
2919:
2920:                private String value = "";
2921:
2922:                /*--------------------------------------------------------------------------*/
2923:                /**
2924:                 * Constructs a new Text/Value pair, initialized with the text and a value.
2925:                 * 
2926:                 * @param text the text that this object should represent
2927:                 * @param value the value that should be associated with this object
2928:                 */
2929:                /*--------------------------------------------------------------------------*/
2930:                public TextValuePair(String text, String value) {
2931:                    this .text = text;
2932:                    this .value = value;
2933:                }
2934:
2935:                /*--------------------------------------------------------------------------*/
2936:                /**
2937:                 * Sets the text
2938:                 * 
2939:                 * @param text the text for this object
2940:                 */
2941:                /*--------------------------------------------------------------------------*/
2942:                public void setText(String text) {
2943:                    this .text = text;
2944:                }
2945:
2946:                /*--------------------------------------------------------------------------*/
2947:                /**
2948:                 * Sets the value of this object
2949:                 * 
2950:                 * @param value the value for this object
2951:                 */
2952:                /*--------------------------------------------------------------------------*/
2953:                public void setValue(String value) {
2954:                    this .value = value;
2955:                }
2956:
2957:                /*--------------------------------------------------------------------------*/
2958:                /**
2959:                 * This method returns the text that was set for the object
2960:                 * 
2961:                 * @return the object's text
2962:                 */
2963:                /*--------------------------------------------------------------------------*/
2964:                public String toString() {
2965:                    return (text);
2966:                }
2967:
2968:                /*--------------------------------------------------------------------------*/
2969:                /**
2970:                 * This method returns the value that was associated with this object
2971:                 * 
2972:                 * @return the object's value
2973:                 */
2974:                /*--------------------------------------------------------------------------*/
2975:                public String getValue() {
2976:                    return (value);
2977:                }
2978:            }
2979:
2980:            /*---------------------------------------------------------------------------*/
2981:            /**
2982:             * This class encapsulates a lot of search field functionality.
2983:             * 
2984:             * A search field supports searching directories and files on the target system. This is a
2985:             * helper class to manage all data belonging to a search field.
2986:             */
2987:            /*---------------------------------------------------------------------------*/
2988:
2989:            private class SearchField implements  ActionListener {
2990:
2991:                /** used in constructor - we search for a directory. */
2992:                public static final int TYPE_DIRECTORY = 1;
2993:
2994:                /** used in constructor - we search for a file. */
2995:                public static final int TYPE_FILE = 2;
2996:
2997:                /** used in constructor - result of search is the directory. */
2998:                public static final int RESULT_DIRECTORY = 1;
2999:
3000:                /** used in constructor - result of search is the whole file name. */
3001:                public static final int RESULT_FILE = 2;
3002:
3003:                /** used in constructor - result of search is the parent directory. */
3004:                public static final int RESULT_PARENTDIR = 3;
3005:
3006:                private String filename = null;
3007:
3008:                private String checkFilename = null;
3009:
3010:                private JButton autodetectButton = null;
3011:
3012:                private JButton browseButton = null;
3013:
3014:                private JComboBox pathComboBox = null;
3015:
3016:                private int searchType = TYPE_DIRECTORY;
3017:
3018:                private int resultType = RESULT_DIRECTORY;
3019:
3020:                private InstallerFrame parent = null;
3021:
3022:                /*---------------------------------------------------------------------------*/
3023:                /**
3024:                 * Constructor - initializes the object, adds it as action listener to the "autodetect"
3025:                 * button.
3026:                 * 
3027:                 * @param filename the name of the file to search for (might be null for searching
3028:                 * directories)
3029:                 * @param checkFilename the name of the file to check when searching for directories (the
3030:                 * checkFilename is appended to a found directory to figure out whether it is the right
3031:                 * directory)
3032:                 * @param combobox the <code>JComboBox</code> holding the list of choices; it should be
3033:                 * editable and contain only Strings
3034:                 * @param autobutton the autodetection button for triggering autodetection
3035:                 * @param browsebutton the browse button to look for the file
3036:                 * @param search_type what to search for - TYPE_FILE or TYPE_DIRECTORY
3037:                 * @param result_type what to return as the result - RESULT_FILE or RESULT_DIRECTORY or
3038:                 * RESULT_PARENTDIR
3039:                 */
3040:                /*---------------------------------------------------------------------------*/
3041:                public SearchField(String filename, String checkFilename,
3042:                        InstallerFrame parent, JComboBox combobox,
3043:                        JButton autobutton, JButton browsebutton,
3044:                        int search_type, int result_type) {
3045:                    this .filename = filename;
3046:                    this .checkFilename = checkFilename;
3047:                    this .parent = parent;
3048:                    this .autodetectButton = autobutton;
3049:                    this .browseButton = browsebutton;
3050:                    this .pathComboBox = combobox;
3051:                    this .searchType = search_type;
3052:                    this .resultType = result_type;
3053:
3054:                    this .autodetectButton.addActionListener(this );
3055:                    this .browseButton.addActionListener(this );
3056:
3057:                    /*
3058:                     * add DocumentListener to manage nextButton if user enters input
3059:                     */
3060:                    ((JTextField) this .pathComboBox.getEditor()
3061:                            .getEditorComponent()).getDocument()
3062:                            .addDocumentListener(new DocumentListener() {
3063:                                public void changedUpdate(DocumentEvent e) {
3064:                                    checkNextButtonState();
3065:                                }
3066:
3067:                                public void insertUpdate(DocumentEvent e) {
3068:                                    checkNextButtonState();
3069:                                }
3070:
3071:                                public void removeUpdate(DocumentEvent e) {
3072:                                    checkNextButtonState();
3073:                                }
3074:
3075:                                private void checkNextButtonState() {
3076:                                    Document doc = ((JTextField) pathComboBox
3077:                                            .getEditor().getEditorComponent())
3078:                                            .getDocument();
3079:                                    try {
3080:                                        if (pathMatches(doc.getText(0, doc
3081:                                                .getLength())))
3082:                                            getInstallerFrame()
3083:                                                    .unlockNextButton(false);
3084:                                        else
3085:                                            getInstallerFrame()
3086:                                                    .lockNextButton();
3087:                                    } catch (BadLocationException e) {/*ignore, it not happens*/
3088:                                    }
3089:                                }
3090:                            });
3091:
3092:                    autodetect();
3093:                }
3094:
3095:                /**
3096:                 * convenient method
3097:                 */
3098:                private InstallerFrame getInstallerFrame() {
3099:                    return parent;
3100:                }
3101:
3102:                /**
3103:                 * Check whether the given combobox belongs to this searchfield. This is used when reading
3104:                 * the results.
3105:                 */
3106:                public boolean belongsTo(JComboBox combobox) {
3107:                    return (this .pathComboBox == combobox);
3108:                }
3109:
3110:                /** check whether the given path matches */
3111:                private boolean pathMatches(String path) {
3112:                    if (path != null) { // Make sure, path is not null
3113:                        // System.out.println ("checking path " + path);
3114:
3115:                        File file = null;
3116:
3117:                        if ((this .filename == null)
3118:                                || (this .searchType == TYPE_DIRECTORY)) {
3119:                            file = new File(path);
3120:                        } else {
3121:                            file = new File(path, this .filename);
3122:                        }
3123:
3124:                        if (file.exists()) {
3125:
3126:                            if (((this .searchType == TYPE_DIRECTORY) && (file
3127:                                    .isDirectory()))
3128:                                    || ((this .searchType == TYPE_FILE) && (file
3129:                                            .isFile()))) {
3130:                                // no file to check for
3131:                                if (this .checkFilename == null)
3132:                                    return true;
3133:
3134:                                file = new File(file, this .checkFilename);
3135:
3136:                                return file.exists();
3137:                            }
3138:
3139:                        }
3140:
3141:                        // System.out.println (path + " did not match");
3142:                    } // end if
3143:                    return false;
3144:                }
3145:
3146:                /** perform autodetection */
3147:                public boolean autodetect() {
3148:                    Vector<String> items = new Vector<String>();
3149:
3150:                    /*
3151:                     * Check if the user has entered data into the ComboBox and add it to the Itemlist
3152:                     */
3153:                    String selected = (String) this .pathComboBox
3154:                            .getSelectedItem();
3155:                    if (selected == null) {
3156:                        parent.lockNextButton();
3157:                        return false;
3158:                    }
3159:                    boolean found = false;
3160:                    for (int x = 0; x < this .pathComboBox.getItemCount(); x++) {
3161:                        if (this .pathComboBox.getItemAt(x).equals(selected)) {
3162:                            found = true;
3163:                        }
3164:                    }
3165:                    if (!found) {
3166:                        // System.out.println("Not found in Itemlist");
3167:                        this .pathComboBox.addItem(this .pathComboBox
3168:                                .getSelectedItem());
3169:                    }
3170:
3171:                    // Checks whether a placeholder item is in the combobox
3172:                    // and resolve the pathes automatically:
3173:                    // /usr/lib/* searches all folders in usr/lib to find
3174:                    // /usr/lib/*/lib/tools.jar
3175:                    for (int i = 0; i < this .pathComboBox.getItemCount(); ++i) {
3176:                        String path = (String) this .pathComboBox.getItemAt(i);
3177:
3178:                        if (path.endsWith("*")) {
3179:                            path = path.substring(0, path.length() - 1);
3180:                            File dir = new File(path);
3181:
3182:                            if (dir.isDirectory()) {
3183:                                File[] subdirs = dir.listFiles();
3184:                                for (File subdir : subdirs) {
3185:                                    String search = subdir.getAbsolutePath();
3186:                                    if (this .pathMatches(search)) {
3187:                                        items.add(search);
3188:                                    }
3189:                                }
3190:                            }
3191:                        } else {
3192:                            if (this .pathMatches(path)) {
3193:                                items.add(path);
3194:                            }
3195:                        }
3196:                    }
3197:                    // Make the enties in the vector unique
3198:                    items = new Vector<String>(new HashSet<String>(items));
3199:
3200:                    // Now clear the combobox and add the items out of the newly
3201:                    // generated vector
3202:                    this .pathComboBox.removeAllItems();
3203:                    VariableSubstitutor vs = new VariableSubstitutor(idata
3204:                            .getVariables());
3205:                    for (String item : items) {
3206:                        this .pathComboBox.addItem(vs.substitute(item, "plain"));
3207:                    }
3208:
3209:                    // loop through all items
3210:                    for (int i = 0; i < this .pathComboBox.getItemCount(); ++i) {
3211:                        String path = (String) this .pathComboBox.getItemAt(i);
3212:
3213:                        if (this .pathMatches(path)) {
3214:                            this .pathComboBox.setSelectedIndex(i);
3215:                            parent.unlockNextButton();
3216:                            return true;
3217:                        }
3218:
3219:                    }
3220:
3221:                    // if the user entered something else, it's not listed as an item
3222:                    if (this .pathMatches((String) this .pathComboBox
3223:                            .getSelectedItem())) {
3224:                        parent.unlockNextButton();
3225:                        return true;
3226:                    }
3227:                    parent.lockNextButton();
3228:                    return false;
3229:                }
3230:
3231:                /*--------------------------------------------------------------------------*/
3232:                /**
3233:                 * This is called if one of the buttons has been pressed.
3234:                 * 
3235:                 * It checks, which button caused the action and acts accordingly.
3236:                 */
3237:                /*--------------------------------------------------------------------------*/
3238:                public void actionPerformed(ActionEvent event) {
3239:                    // System.out.println ("autodetection button pressed.");
3240:
3241:                    if (event.getSource() == this .autodetectButton) {
3242:                        if (!autodetect())
3243:                            showMessageDialog(
3244:                                    parent,
3245:                                    "UserInputPanel.search.autodetect.failed.message",
3246:                                    "UserInputPanel.search.autodetect.failed.caption",
3247:                                    JOptionPane.WARNING_MESSAGE);
3248:                    } else if (event.getSource() == this .browseButton) {
3249:                        JFileChooser chooser = new JFileChooser();
3250:
3251:                        if (this .resultType != TYPE_FILE)
3252:                            chooser
3253:                                    .setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
3254:
3255:                        int result = chooser.showOpenDialog(this .parent);
3256:
3257:                        if (result == JFileChooser.APPROVE_OPTION) {
3258:                            File f = chooser.getSelectedFile();
3259:
3260:                            this .pathComboBox.setSelectedItem(f
3261:                                    .getAbsolutePath());
3262:
3263:                            // use any given directory directly
3264:                            if (this .resultType != TYPE_FILE
3265:                                    && !this .pathMatches(f.getAbsolutePath())) {
3266:                                showMessageDialog(
3267:                                        parent,
3268:                                        "UserInputPanel.search.wrongselection.message",
3269:                                        "UserInputPanel.search.wrongselection.caption",
3270:                                        JOptionPane.WARNING_MESSAGE);
3271:
3272:                            }
3273:                        }
3274:
3275:                    }
3276:
3277:                    // we don't care for anything more here - getResult() does the rest
3278:                }
3279:
3280:                /*--------------------------------------------------------------------------*/
3281:                /**
3282:                 * Return the result of the search according to result type.
3283:                 * 
3284:                 * Sometimes, the whole path of the file is wanted, sometimes only the directory where the
3285:                 * file is in, sometimes the parent directory.
3286:                 * 
3287:                 * @return null on error
3288:                 */
3289:                /*--------------------------------------------------------------------------*/
3290:                public String getResult() {
3291:                    String item = (String) this .pathComboBox.getSelectedItem();
3292:                    if (item != null)
3293:                        item = item.trim();
3294:                    String path = item;
3295:
3296:                    File f = new File(item);
3297:
3298:                    if (!f.isDirectory()) {
3299:                        path = f.getParent();
3300:                    }
3301:
3302:                    // path now contains the final content of the combo box
3303:                    if (this .resultType == RESULT_DIRECTORY) {
3304:                        return path;
3305:                    } else if (this .resultType == RESULT_FILE) {
3306:                        if (this .filename != null) {
3307:                            return path + File.separatorChar + this .filename;
3308:                        } else {
3309:                            return item;
3310:                        }
3311:                    } else if (this .resultType == RESULT_PARENTDIR) {
3312:                        File dir = new File(path);
3313:                        return dir.getParent();
3314:                    }
3315:
3316:                    return null;
3317:                }
3318:
3319:            } // private class SearchFile
3320:
3321:            protected void updateVariables() {
3322:                /**
3323:                 * Look if there are new variables defined
3324:                 */
3325:                Vector<XMLElement> variables = spec
3326:                        .getChildrenNamed(VARIABLE_NODE);
3327:                RulesEngine rules = parent.getRules();
3328:
3329:                VariableSubstitutor vs = new VariableSubstitutor(idata
3330:                        .getVariables());
3331:                for (int i = 0; i < variables.size(); i++) {
3332:                    XMLElement variable = variables.elementAt(i);
3333:                    String vname = variable
3334:                            .getAttribute(ATTRIBUTE_VARIABLE_NAME);
3335:                    String vvalue = variable
3336:                            .getAttribute(ATTRIBUTE_VARIABLE_VALUE);
3337:
3338:                    if (vvalue == null) {
3339:                        // try to read value element
3340:                        if (variable.hasChildren()) {
3341:                            XMLElement value = variable
3342:                                    .getFirstChildNamed("value");
3343:                            vvalue = value.getContent();
3344:                        }
3345:                    }
3346:
3347:                    String conditionid = variable
3348:                            .getAttribute(ATTRIBUTE_CONDITIONID_NAME);
3349:                    if (conditionid != null) {
3350:                        // check if condition for this variable is fulfilled
3351:                        if (!rules.isConditionTrue(conditionid, idata
3352:                                .getVariables())) {
3353:                            continue;
3354:                        }
3355:                    }
3356:                    // are there any OS-Constraints?
3357:                    if (OsConstraint.oneMatchesCurrentSystem(variable)) {
3358:                        if (vname == null) {
3359:                        } else {
3360:                            // vname is given
3361:                            if (vvalue != null) {
3362:                                // try to substitute variables in value field
3363:                                vvalue = vs.substitute(vvalue, null);
3364:                                // to cut out circular references
3365:                                idata.setVariable(vname, "");
3366:                                vvalue = vs.substitute(vvalue, null);
3367:                            }
3368:                            // try to set variable
3369:                            idata.setVariable(vname, vvalue);
3370:
3371:                            // for save this variable to be used later by Automation Helper
3372:                            entries.add(new TextValuePair(vname, vvalue));
3373:                        }
3374:                    }
3375:                }
3376:            }
3377:
3378:            // Repaint all controls and validate them agains the current variables
3379:            public void actionPerformed(ActionEvent e) {
3380:                validating = false;
3381:                readInput();
3382:                panelActivate();
3383:                validating = true;
3384:            }
3385:
3386:            /*--------------------------------------------------------------------------*/
3387:            /**
3388:             * Show localized message dialog basing on given parameters.
3389:             * 
3390:             * @param parentFrame The parent frame.
3391:             * @param message The message to print out in dialog box.
3392:             * @param caption The caption of dialog box.
3393:             * @param messageType The message type (JOptionPane.*_MESSAGE)
3394:             */
3395:            /*--------------------------------------------------------------------------*/
3396:            private void showMessageDialog(InstallerFrame parentFrame,
3397:                    String message, String caption, int messageType) {
3398:                String localizedMessage = langpack.getString(message);
3399:                if ("".equals(localizedMessage)) {
3400:                    localizedMessage = message;
3401:                }
3402:                JOptionPane.showMessageDialog(parentFrame, localizedMessage,
3403:                        caption, messageType);
3404:            }
3405:
3406:            /*--------------------------------------------------------------------------*/
3407:            /**
3408:             * Show localized warning message dialog basing on given parameters.
3409:             * 
3410:             * @param parentFrame parent frame.
3411:             * @param message the message to print out in dialog box.
3412:             */
3413:            /*--------------------------------------------------------------------------*/
3414:            private void showWarningMessageDialog(InstallerFrame parentFrame,
3415:                    String message) {
3416:                showMessageDialog(parentFrame, message, parentFrame.langpack
3417:                        .getString("UserInputPanel.error.caption"),
3418:                        JOptionPane.WARNING_MESSAGE);
3419:            }
3420:
3421:        } // public class UserInputPanel
3422:
3423:        /*---------------------------------------------------------------------------*/
3424:        class UserInputFileFilter extends FileFilter {
3425:            String fileext = "";
3426:            String description = "";
3427:
3428:            public void setFileExt(String fileext) {
3429:                this .fileext = fileext;
3430:            }
3431:
3432:            public void setFileExtDesc(String desc) {
3433:                this .description = desc;
3434:            }
3435:
3436:            public boolean accept(File pathname) {
3437:                if (pathname.isDirectory()) {
3438:                    return true;
3439:                } else {
3440:                    return pathname.getAbsolutePath().endsWith(this .fileext);
3441:                }
3442:            }
3443:
3444:            public String getDescription() {
3445:                return this.description;
3446:            }
3447:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.