Source Code Cross Referenced for Wizard.java in  » IDE-Netbeans » nbi » org » netbeans » installer » wizard » 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 » IDE Netbeans » nbi » org.netbeans.installer.wizard 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         * 
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         * 
0006:         * The contents of this file are subject to the terms of either the GNU General
0007:         * Public License Version 2 only ("GPL") or the Common Development and Distribution
0008:         * License("CDDL") (collectively, the "License"). You may not use this file except in
0009:         * compliance with the License. You can obtain a copy of the License at
0010:         * http://www.netbeans.org/cddl-gplv2.html or nbbuild/licenses/CDDL-GPL-2-CP. See the
0011:         * License for the specific language governing permissions and limitations under the
0012:         * License.  When distributing the software, include this License Header Notice in
0013:         * each file and include the License file at nbbuild/licenses/CDDL-GPL-2-CP.  Sun
0014:         * designates this particular file as subject to the "Classpath" exception as
0015:         * provided by Sun in the GPL Version 2 section of the License file that
0016:         * accompanied this code. If applicable, add the following below the License Header,
0017:         * with the fields enclosed by brackets [] replaced by your own identifying
0018:         * information: "Portions Copyrighted [year] [name of copyright owner]"
0019:         * 
0020:         * Contributor(s):
0021:         * 
0022:         * The Original Software is NetBeans. The Initial Developer of the Original Software
0023:         * is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun Microsystems, Inc. All
0024:         * Rights Reserved.
0025:         * 
0026:         * If you wish your version of this file to be governed by only the CDDL or only the
0027:         * GPL Version 2, indicate your decision by adding "[Contributor] elects to include
0028:         * this software in this distribution under the [CDDL or GPL Version 2] license." If
0029:         * you do not indicate a single choice of license, a recipient has the option to
0030:         * distribute your version of this file under either the CDDL, the GPL Version 2 or
0031:         * to extend the choice of license to its licensees as provided above. However, if
0032:         * you add GPL Version 2 code and therefore, elected the GPL Version 2 license, then
0033:         * the option applies only if the new code is made subject to such option by the
0034:         * copyright holder.
0035:         */
0036:
0037:        package org.netbeans.installer.wizard;
0038:
0039:        import java.io.File;
0040:        import java.io.IOException;
0041:        import java.lang.reflect.InvocationTargetException;
0042:        import java.util.LinkedList;
0043:        import java.util.List;
0044:        import javax.swing.SwingUtilities;
0045:        import javax.xml.XMLConstants;
0046:        import javax.xml.parsers.DocumentBuilderFactory;
0047:        import javax.xml.parsers.ParserConfigurationException;
0048:        import javax.xml.validation.Schema;
0049:        import javax.xml.validation.SchemaFactory;
0050:        import org.netbeans.installer.utils.helper.PropertyContainer;
0051:        import org.netbeans.installer.utils.helper.UiMode;
0052:        import org.netbeans.installer.wizard.components.WizardComponent;
0053:        import org.netbeans.installer.utils.ErrorManager;
0054:        import org.netbeans.installer.utils.FileProxy;
0055:        import org.netbeans.installer.utils.ResourceUtils;
0056:        import org.netbeans.installer.utils.UiUtils;
0057:        import org.netbeans.installer.utils.XMLUtils;
0058:        import org.netbeans.installer.utils.exceptions.DownloadException;
0059:        import org.netbeans.installer.utils.exceptions.InitializationException;
0060:        import org.netbeans.installer.utils.exceptions.ParseException;
0061:        import org.netbeans.installer.utils.helper.FinishHandler;
0062:        import org.netbeans.installer.utils.helper.Context;
0063:        import org.netbeans.installer.wizard.containers.WizardContainer;
0064:        import org.netbeans.installer.wizard.containers.SwingFrameContainer;
0065:        import org.w3c.dom.Document;
0066:        import org.w3c.dom.Element;
0067:        import org.xml.sax.SAXException;
0068:
0069:        /**
0070:         * This is the main class of the NBI Wizard framework. It represents the wizard as
0071:         * a whole.
0072:         *
0073:         * <p>
0074:         * The wizard serves a the main source of the data input by the user. It is
0075:         * organized as a series of pages, each either informing the user about something
0076:         * or displaying an input field. The input validation also happens here.
0077:         *
0078:         * <p>
0079:         * The wizard is a singleton in some sense, i.e. only one instance of {@link Wizard}
0080:         * can be created directly, via the {@link #getInstance()} method. All other
0081:         * instances that may be created during the course of wizard's workflow will be the
0082:         * so-called child wizards.
0083:         *
0084:         * <p>
0085:         * The wizard operates over a list of {@link WizardComponent}s. In order to add
0086:         * "depth", the user needs to create sub-wizards which would have their own
0087:         * sequences of components, but will appear as a single component to the parent
0088:         * wizard. This effect can be obtained via the
0089:         * {@link org.netbeans.installer.wizard.components.WizardSequence} component.
0090:         *
0091:         * <p>
0092:         * Context. Each wizard can have an associated context. A {@link Context} is a
0093:         * simple collection of objects which can be fetched by their class. The context is
0094:         * assigned to a wizard at runtime, thus it is possible to switch contexts basing
0095:         * on some conditions. The context is intended to be read-only, though it is
0096:         * possible to add new objects to it. The most common usecase for a context would
0097:         * be passing an instance of an object to all the components of a wizard.
0098:         *
0099:         * <p>
0100:         * Property container. Since the princial use case for a wizard is collecting some
0101:         * user input, the values entered by the user need to be stored somewhere. For this
0102:         * purpose a wizard has an associated {@link PropertyContainer}. It serves as a
0103:         * storage for the user-entered strings.
0104:         *
0105:         * <p>
0106:         * The root wizard instance will load its list of components from an URI defined in
0107:         * the system property {@link #COMPONENTS_INSTANCE_URI_PROPERTY}, if the property is
0108:         * not set, then it falls back to the {@link #DEFAULT_COMPONENTS_INSTANCE_URI}. For
0109:         * child wizards, created with one of the
0110:         * {@link #createSubWizard(List,int)} methods, expect that their lists of components
0111:         * will be passed in directly. The list of components can be constructed using the
0112:         * {@link #loadWizardComponents(String)} method.
0113:         *
0114:         * @author Kirill Sorokin
0115:         * @since 1.0
0116:         */
0117:        public class Wizard {
0118:            /////////////////////////////////////////////////////////////////////////////////
0119:            // Static
0120:            /**
0121:             * The instance of the root wizard.
0122:             */
0123:            private static Wizard instance;
0124:
0125:            /**
0126:             * URI which points to the list of components for the root wizard instance.
0127:             */
0128:            private static String componentsInstanceUri;
0129:
0130:            /**
0131:             * URI which points to the XML Schema which will be used to validate the list
0132:             * of wizard components stored in XML format.
0133:             */
0134:            private static String componentsSchemaUri;
0135:
0136:            /**
0137:             * Returns the instance of the root {@link Wizard}. If the instance does not
0138:             * exist - it is created and all system properties that make sense for the
0139:             * {@link Wizard} are parsed: {@link #COMPONENTS_INSTANCE_URI_PROPERTY} and
0140:             * {@link #COMPONENTS_SCHEMA_URI_PROPERTY}.
0141:             *
0142:             * @return The instance of the root {@link Wizard}.
0143:             */
0144:            public static synchronized Wizard getInstance() {
0145:                if (instance == null) {
0146:                    // initialize uri for root wizard's components list
0147:                    if (System.getProperty(COMPONENTS_INSTANCE_URI_PROPERTY) != null) {
0148:                        componentsInstanceUri = System
0149:                                .getProperty(COMPONENTS_INSTANCE_URI_PROPERTY);
0150:                    } else {
0151:                        componentsInstanceUri = DEFAULT_COMPONENTS_INSTANCE_URI;
0152:                    }
0153:
0154:                    // initialize uri for components list xml schema
0155:                    if (System.getProperty(COMPONENTS_SCHEMA_URI_PROPERTY) != null) {
0156:                        componentsSchemaUri = System
0157:                                .getProperty(COMPONENTS_SCHEMA_URI_PROPERTY);
0158:                    } else {
0159:                        componentsSchemaUri = DEFAULT_COMPONENTS_SCHEMA_URI;
0160:                    }
0161:
0162:                    // create the root wizard and load its components
0163:                    instance = new Wizard();
0164:                    try {
0165:                        instance.components = loadWizardComponents(componentsInstanceUri);
0166:                    } catch (InitializationException e) {
0167:                        ErrorManager.notifyCritical(ResourceUtils.getString(
0168:                                Wizard.class,
0169:                                RESOURCE_FAILED_TO_CREATE_INSTANCE), e);
0170:                    }
0171:                }
0172:
0173:                return instance;
0174:            }
0175:
0176:            /**
0177:             * Loads the list of {@link WizardComponent} from an XML file identified by its
0178:             * URI. The URI can be of any scheme supported by the
0179:             * {@link org.netbeans.installer.downloader.DownloadManager}.
0180:             *
0181:             * @param componentsUri URI of the XML file which contains the list of
0182:             *      {@link WizardComponent}s.
0183:             * @return The list of {@link WizardComponent} defined in the XML file.
0184:             * @throws org.netbeans.installer.utils.exceptions.InitializationException If an
0185:             *      error occurs during loading of the list.
0186:             */
0187:            public static List<WizardComponent> loadWizardComponents(
0188:                    final String componentsUri) throws InitializationException {
0189:                return loadWizardComponents(componentsUri, Wizard.class
0190:                        .getClassLoader());
0191:            }
0192:
0193:            /**
0194:             * Loads the list of {@link WizardComponent} from an XML file identified by its
0195:             * URI and using the specified {@link ClassLoader} to load the components'
0196:             * classes. The URI can be of any scheme supported by the
0197:             * {@link org.netbeans.installer.downloader.DownloadManager}.
0198:             *
0199:             * @param componentsUri URI of the XML file which contains the list of
0200:             *      {@link WizardComponent}.
0201:             * @param classLoader Instance of {@link ClassLoader} which should be used for
0202:             *      loading the components' classes.
0203:             * @return The list of {@link WizardComponent} defined in the XML file.
0204:             * @throws org.netbeans.installer.utils.exceptions.InitializationException If an
0205:             *      error occurs during loading of the list.
0206:             */
0207:            public static List<WizardComponent> loadWizardComponents(
0208:                    final String componentsUri, final ClassLoader classLoader)
0209:                    throws InitializationException {
0210:                try {
0211:                    final File schemaFile = FileProxy.getInstance().getFile(
0212:                            componentsSchemaUri, classLoader, true);
0213:                    final File componentsFile = FileProxy.getInstance()
0214:                            .getFile(componentsUri, classLoader, true);
0215:
0216:                    final Schema schema = SchemaFactory.newInstance(
0217:                            XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(
0218:                            schemaFile);
0219:
0220:                    final DocumentBuilderFactory factory = DocumentBuilderFactory
0221:                            .newInstance();
0222:                    try {
0223:                        factory.setSchema(schema);
0224:                    } catch (UnsupportedOperationException e) {
0225:                        // if the parser does not support schemas, let it be -- we can do
0226:                        // without it anyway -- just log it and proceed
0227:                        ErrorManager.notifyDebug(ResourceUtils.getString(
0228:                                Wizard.class,
0229:                                RESOURCE_PARSER_UNSUPPORTS_SCHEMAS, factory
0230:                                        .getClass()), e);
0231:                    }
0232:                    factory.setNamespaceAware(true);
0233:
0234:                    final Document document = factory.newDocumentBuilder()
0235:                            .parse(componentsFile);
0236:
0237:                    return loadWizardComponents(document.getDocumentElement(),
0238:                            classLoader);
0239:                } catch (DownloadException e) {
0240:                    throw new InitializationException(ResourceUtils.getString(
0241:                            Wizard.class, RESOURCE_FAILED_TO_LOAD_COMPONENTS,
0242:                            componentsUri, classLoader), e);
0243:                } catch (ParserConfigurationException e) {
0244:                    throw new InitializationException(ResourceUtils.getString(
0245:                            Wizard.class, RESOURCE_FAILED_TO_LOAD_COMPONENTS,
0246:                            componentsUri, classLoader), e);
0247:                } catch (SAXException e) {
0248:                    throw new InitializationException(ResourceUtils.getString(
0249:                            Wizard.class, RESOURCE_FAILED_TO_LOAD_COMPONENTS,
0250:                            componentsUri, classLoader), e);
0251:                } catch (IOException e) {
0252:                    throw new InitializationException(ResourceUtils.getString(
0253:                            Wizard.class, RESOURCE_FAILED_TO_LOAD_COMPONENTS,
0254:                            componentsUri, classLoader), e);
0255:                }
0256:            }
0257:
0258:            // private //////////////////////////////////////////////////////////////////////
0259:            /**
0260:             * Loads the list of {@link WizardComponent} from the DOM tree identified by its
0261:             * root {@link Element} using the specified {@link ClassLoader} to load the
0262:             * components' classes.
0263:             *
0264:             * @param element Root of the DOM tree from which to load the list.
0265:             * @param classLoader Instance of {@link ClassLoader} which should be used for
0266:             *      loading the components' classes.
0267:             * @return The list of {@link WizardComponent} defined in the DOM tree.
0268:             * @throws org.netbeans.installer.utils.exceptions.InitializationException If an
0269:             *      error occurs during loading of the list.
0270:             */
0271:            private static List<WizardComponent> loadWizardComponents(
0272:                    final Element element, final ClassLoader classLoader)
0273:                    throws InitializationException {
0274:                final List<WizardComponent> components = new LinkedList<WizardComponent>();
0275:
0276:                for (Element child : XMLUtils.getChildren(element,
0277:                        TAG_COMPONENT)) {
0278:                    components.add(loadWizardComponent(child, classLoader));
0279:                }
0280:
0281:                return components;
0282:            }
0283:
0284:            /**
0285:             * Loads a single {@link WizardComponent} from a DOM {@link Element} using the
0286:             * specified {@link ClassLoader} to load the component's class.
0287:             *
0288:             * @param element DOM {@link Element} from which the component's data should be
0289:             *      loaded.
0290:             * @param classLoader Instance of {@link ClassLoader} which should be used for
0291:             *      loading the component's class.
0292:             * @return The loaded {@link WizardComponent}.
0293:             * @throws org.netbeans.installer.utils.exceptions.InitializationException If an
0294:             *      error occurs during loading of the component.
0295:             */
0296:            private static WizardComponent loadWizardComponent(
0297:                    final Element element, final ClassLoader classLoader)
0298:                    throws InitializationException {
0299:                final WizardComponent component;
0300:
0301:                try {
0302:                    component = (WizardComponent) classLoader.loadClass(
0303:                            element.getAttribute(ATTRIBUTE_CLASS))
0304:                            .newInstance();
0305:
0306:                    Element child = XMLUtils.getChild(element, TAG_COMPONENTS);
0307:                    if (child != null) {
0308:                        component.addChildren(loadWizardComponents(child,
0309:                                classLoader));
0310:                    }
0311:
0312:                    child = XMLUtils.getChild(element, TAG_PROPERTIES);
0313:                    if (child != null) {
0314:                        component.getProperties().putAll(
0315:                                XMLUtils.parseNbiProperties(child));
0316:                    }
0317:                } catch (ParseException e) {
0318:                    throw new InitializationException(ResourceUtils.getString(
0319:                            Wizard.class, RESOURCE_FAILED_TO_LOAD_COMPONENT,
0320:                            element, classLoader), e);
0321:                } catch (ClassNotFoundException e) {
0322:                    throw new InitializationException(ResourceUtils.getString(
0323:                            Wizard.class, RESOURCE_FAILED_TO_LOAD_COMPONENT,
0324:                            element, classLoader), e);
0325:                } catch (IllegalAccessException e) {
0326:                    throw new InitializationException(ResourceUtils.getString(
0327:                            Wizard.class, RESOURCE_FAILED_TO_LOAD_COMPONENT,
0328:                            element, classLoader), e);
0329:                } catch (InstantiationException e) {
0330:                    throw new InitializationException(ResourceUtils.getString(
0331:                            Wizard.class, RESOURCE_FAILED_TO_LOAD_COMPONENT,
0332:                            element, classLoader), e);
0333:                }
0334:
0335:                return component;
0336:            }
0337:
0338:            /////////////////////////////////////////////////////////////////////////////////
0339:            // Instance
0340:            /**
0341:             * List of the {@link WizardComponent} over which the {@link Wizard} should
0342:             * iterate.
0343:             */
0344:            private List<WizardComponent> components;
0345:
0346:            /**
0347:             * Container which should display the UI of the wizard.
0348:             */
0349:            private WizardContainer container;
0350:
0351:            /**
0352:             * Storage for the user input in the panels of the wizard.
0353:             */
0354:            private PropertyContainer propertyContainer;
0355:
0356:            /**
0357:             * {@link Wizard}'s {@link Context}.
0358:             */
0359:            private Context context;
0360:
0361:            /**
0362:             * {@link ClassLoader} that should be used by the wizard. E.g. for loading
0363:             * resources.
0364:             */
0365:            private ClassLoader classLoader;
0366:
0367:            /**
0368:             * Index of the currently active component.
0369:             */
0370:            private int index;
0371:
0372:            /**
0373:             * Parent of the {@link Wizard}. It is <code>null</code> if the current
0374:             * {@link Wizard} is the root one.
0375:             */
0376:            private Wizard parent;
0377:
0378:            /**
0379:             * Handler of the <code>cancel</code> and <code>finish</code> requests which
0380:             * happen either by user request or as part of the normal wizard work flow.
0381:             */
0382:            private FinishHandler finishHandler;
0383:
0384:            /**
0385:             * Specifies whether the wizard is opened in blocking mode. If it is, the
0386:             * opening method {@link #openBlocking()} will not return intil the wizard is
0387:             * closed from another thread.
0388:             */
0389:            private boolean blocking;
0390:
0391:            // constructors /////////////////////////////////////////////////////////////////
0392:            /**
0393:             * Default constructor. Performs initialization of the basic properties, which,
0394:             * however, is not enough for normal operation - the list of
0395:             * {@link WizardComponent} is not initialized.
0396:             */
0397:            public Wizard() {
0398:                this .index = -1;
0399:                this .context = new Context();
0400:                this .classLoader = getClass().getClassLoader();
0401:
0402:                this .blocking = false;
0403:            }
0404:
0405:            /**
0406:             * Constructs a new instance of {@link Wizard} with the given parent. Most of
0407:             * the properties of the new instance are inherited from the parent.
0408:             *
0409:             * @param parent Parent {@link Wizard}.
0410:             */
0411:            public Wizard(final Wizard parent) {
0412:                this ();
0413:
0414:                this .parent = parent;
0415:                if (this .parent != null) {
0416:                    this .container = parent.container;
0417:
0418:                    this .propertyContainer = parent.propertyContainer;
0419:                    this .context = new Context(parent.context);
0420:                    this .classLoader = parent.classLoader;
0421:
0422:                    this .finishHandler = parent.finishHandler;
0423:                }
0424:            }
0425:
0426:            /**
0427:             * Constructs a new instance of {@link Wizard} with the given parent, list of
0428:             * {@link WizardComponent} and inital index of the active component.
0429:             *
0430:             * @param parent Parent {@link Wizard}.
0431:             * @param components List of {@link WizardComponent}s over which the wizard
0432:             *      should iterate.
0433:             * @param index Initial index of the active component.
0434:             */
0435:            public Wizard(final Wizard parent,
0436:                    final List<WizardComponent> components, int index) {
0437:                this (parent);
0438:
0439:                this .components = components;
0440:                this .index = index;
0441:            }
0442:
0443:            /**
0444:             * Constructs a new instance of {@link Wizard} with the given parent, list of
0445:             * {@link WizardComponent}, inital index of the active component, properties
0446:             * container and classloader.
0447:             *
0448:             * @param parent Parent {@link Wizard}.
0449:             * @param components List of {@link WizardComponent} over which the wizard
0450:             *      should iterate.
0451:             * @param index Initial index of the active component.
0452:             * @param propertyContainer {@link PropertyContainer} which should be used by
0453:             *      the wizard.
0454:             * @param classLoader {@link ClassLoader} which should be used by the wizard.
0455:             */
0456:            public Wizard(final Wizard parent,
0457:                    final List<WizardComponent> components, final int index,
0458:                    final PropertyContainer propertyContainer,
0459:                    final ClassLoader classLoader) {
0460:                this (parent, components, index);
0461:
0462:                this .propertyContainer = propertyContainer;
0463:                this .classLoader = classLoader;
0464:            }
0465:
0466:            // wizard lifecycle control methods /////////////////////////////////////////////
0467:            /**
0468:             * Opens the wizard. Depending on the current UI mode, an appropriate
0469:             * {@link WizardContainer} is chosen, initialized and set to be visible. No
0470:             * wizard container is created if the UI Mode is {@link UiMode#SILENT}.
0471:             *
0472:             * <p>
0473:             * If the current wizard is not the root one - the parent's {@link #open()}
0474:             * method is called.
0475:             */
0476:            public void open() {
0477:                // if a parent exists, ask it - it knows better
0478:                if (parent != null) {
0479:                    parent.open();
0480:                    return;
0481:                }
0482:
0483:                // init the look and feel
0484:                try {
0485:                    UiUtils.initializeLookAndFeel();
0486:                } catch (InitializationException e) {
0487:                    ErrorManager.notifyWarning(e.getMessage(), e.getCause());
0488:                }
0489:
0490:                // then create the container according to the current UI mode
0491:                switch (UiMode.getCurrentUiMode()) {
0492:                case SWING:
0493:                    container = new SwingFrameContainer();
0494:
0495:                    try {
0496:                        SwingUtilities.invokeAndWait(new Runnable() {
0497:                            public void run() {
0498:                                Thread.currentThread()
0499:                                        .setUncaughtExceptionHandler(
0500:                                                ErrorManager
0501:                                                        .getExceptionHandler());
0502:                            }
0503:                        });
0504:                    } catch (InvocationTargetException e) {
0505:                        ErrorManager.notifyDebug(ResourceUtils.getString(
0506:                                Wizard.class,
0507:                                RESOURCE_FAILED_TO_ATTACH_ERROR_HANDLER), e);
0508:                    } catch (InterruptedException e) {
0509:                        ErrorManager.notifyDebug(ResourceUtils.getString(
0510:                                Wizard.class,
0511:                                RESOURCE_FAILED_TO_ATTACH_ERROR_HANDLER), e);
0512:                    }
0513:
0514:                    SwingUtilities.invokeLater(new Runnable() {
0515:                        public void run() {
0516:                            container.setVisible(true);
0517:                        }
0518:                    });
0519:                    break;
0520:                case SILENT:
0521:                    // we don't have to initialize anything for silent mode
0522:                    break;
0523:                default:
0524:                    ErrorManager.notifyCritical(ResourceUtils.getString(
0525:                            Wizard.class, RESOURCE_UNKNOWN_UI_MODE, UiMode
0526:                                    .getCurrentUiMode()));
0527:                }
0528:
0529:                next();
0530:            }
0531:
0532:            /**
0533:             * Opens the wizard in a blocking mode. As opposed to {@link #open()}, this
0534:             * method will not return the wizard is closed from another thread.
0535:             *
0536:             * @see #open()
0537:             */
0538:            public void openBlocking() {
0539:                this .blocking = true;
0540:
0541:                open();
0542:
0543:                while (blocking) {
0544:                    try {
0545:                        wait();
0546:                    } catch (InterruptedException e) {
0547:                        ErrorManager.notifyDebug(ResourceUtils.getString(
0548:                                Wizard.class, RESOURCE_INTERRUPTED), e);
0549:                    }
0550:                }
0551:            }
0552:
0553:            /**
0554:             * Closes the wizard. The current {@link WizardContainer} is hidden and
0555:             * deinitialized. No real action is taken if the UI mode is
0556:             * {@link UiMode#SILENT}.
0557:             *
0558:             * <p>
0559:             * If the current wizard is not the ro  ot one - the parent's {@link #close()}
0560:             * method is called.
0561:             */
0562:            public void close() {
0563:                // if a parent exists, ask it - it knows better
0564:                if (parent != null) {
0565:                    parent.close();
0566:                    return;
0567:                }
0568:
0569:                switch (UiMode.getCurrentUiMode()) {
0570:                case SWING:
0571:                    // if the container has not yet been initialized -- we do not need to
0572:                    // do anything with it
0573:                    if (container != null) {
0574:                        container.setVisible(false);
0575:                    }
0576:                    break;
0577:                case SILENT:
0578:                    // we don't have to initialize anything for silent mode
0579:                    break;
0580:                default:
0581:                    ErrorManager.notifyCritical(ResourceUtils.getString(
0582:                            Wizard.class, RESOURCE_UNKNOWN_UI_MODE, UiMode
0583:                                    .getCurrentUiMode()));
0584:                }
0585:
0586:                if (blocking) {
0587:                    blocking = false;
0588:                    notifyAll();
0589:                }
0590:            }
0591:
0592:            // component flow control methods ///////////////////////////////////////////////
0593:            /**
0594:             * Proceeds to the next element in the wizard. If the next element is not
0595:             * available and the current wizard instance is the root one, then the wizard is
0596:             * considered to be at the last element and the wizard's
0597:             * {@link FinishHandler#finish()} is called.
0598:             *
0599:             * <p>
0600:             * If the current wizard is not the root instance and there is no next component,
0601:             * then the parent wizard's {@link #next()} method is called.
0602:             */
0603:            public void next() {
0604:                final WizardComponent component = getNext();
0605:
0606:                // if there is no next component in the current wizard, try to delegate
0607:                // the call to the parent wizard, and if there is no parent wizard... finish
0608:                // the sequence, and call the finish handler
0609:                if (component != null) {
0610:                    index = components.indexOf(component);
0611:
0612:                    component.setWizard(this );
0613:                    component.initialize();
0614:
0615:                    switch (UiMode.getCurrentUiMode()) {
0616:                    case SWING:
0617:                        if (component.getWizardUi() != null) {
0618:                            container.updateWizardUi(component.getWizardUi());
0619:                        }
0620:                        break;
0621:                    case SILENT:
0622:                        // nothing special should be done for silent mode
0623:                        break;
0624:                    default:
0625:                        ErrorManager.notifyCritical(ResourceUtils.getString(
0626:                                Wizard.class, RESOURCE_UNKNOWN_UI_MODE, UiMode
0627:                                        .getCurrentUiMode()));
0628:                    }
0629:
0630:                    System.setProperty(CURRENT_COMPONENT_CLASSNAME_PROPERTY,
0631:                            component.getClass().getName());
0632:
0633:                    component.executeForward();
0634:                } else if (parent != null) {
0635:                    parent.next();
0636:                } else {
0637:                    finishHandler.finish();
0638:                }
0639:            }
0640:
0641:            /**
0642:             * Moves to the previous element in the wizard. If the previous component is not
0643:             * available and the current wizard instance is the root one a critical error is
0644:             * shown and the application terminates.
0645:             *
0646:             * <p>
0647:             * If the current wizard is not the root one and there is no previous component
0648:             * in the current sequence, the parent's {@link #previous()} method is called.
0649:             */
0650:            public void previous() {
0651:                final WizardComponent component = getPrevious();
0652:
0653:                // if there is no previous component in the current wizard, try to delegate
0654:                // the call to the parent wizard, and if there is no parent wizard... we
0655:                // should be here in the first place
0656:                if (component != null) {
0657:                    index = components.indexOf(component);
0658:
0659:                    component.setWizard(this );
0660:                    component.initialize();
0661:
0662:                    switch (UiMode.getCurrentUiMode()) {
0663:                    case SWING:
0664:                        if (component.getWizardUi() != null) {
0665:                            container.updateWizardUi(component.getWizardUi());
0666:                        }
0667:                        break;
0668:                    case SILENT:
0669:                        ErrorManager.notifyCritical(ResourceUtils.getString(
0670:                                Wizard.class,
0671:                                RESOURCE_CANNOT_MOVE_BACKWARD_SILENT));
0672:                        break;
0673:                    default:
0674:                        ErrorManager.notifyCritical(ResourceUtils.getString(
0675:                                Wizard.class, RESOURCE_UNKNOWN_UI_MODE, UiMode
0676:                                        .getCurrentUiMode()));
0677:                    }
0678:
0679:                    System.setProperty(CURRENT_COMPONENT_CLASSNAME_PROPERTY,
0680:                            component.getClass().getName());
0681:
0682:                    component.executeBackward();
0683:                } else if (parent != null) {
0684:                    parent.previous();
0685:                } else {
0686:                    ErrorManager.notifyCritical(ResourceUtils.getString(
0687:                            Wizard.class,
0688:                            RESOURCE_CANNOT_MOVE_BACKWARD_AT_FIRST));
0689:                }
0690:            }
0691:
0692:            // informational methods ////////////////////////////////////////////////////////
0693:            /**
0694:             * Checks whether there is exists a component which can be reached using the
0695:             * {@link #next()} method. This method checks both the components of the
0696:             * current wizard and the parent one.
0697:             *
0698:             * @return <code>true</code> is there is a next element, <code>false</code>
0699:             *      otherwise.
0700:             */
0701:            public boolean hasNext() {
0702:                // if there is no next component in the current wizard, we should check the
0703:                // parent wizard if it has one
0704:                return (getNext() != null)
0705:                        || ((parent != null) && parent.hasNext());
0706:            }
0707:
0708:            /**
0709:             * Checks whether there is exists a component which can be reached using the
0710:             * {@link #previous()} method. This method checks both the components of the
0711:             * current wizard and the parent one.
0712:             *
0713:             * @return <code>true</code> is there is a previous element, <code>false</code>
0714:             *      otherwise.
0715:             */
0716:            public boolean hasPrevious() {
0717:                // if current component is a point of no return - we cannot move backwards,
0718:                // i.e. there is no previous component
0719:                if ((getCurrent() != null) && getCurrent().isPointOfNoReturn()) {
0720:                    return false;
0721:                }
0722:
0723:                for (int i = index - 1; i > -1; i--) {
0724:                    final WizardComponent component = components.get(i);
0725:
0726:                    // if the component can be executed backward it is the previous one
0727:                    if (component.canExecuteBackward()) {
0728:                        return true;
0729:                    }
0730:
0731:                    // if the currently examined component is a point of no return and it
0732:                    // cannot be executed (since we passed the previous statement) - we have
0733:                    // no previous component
0734:                    if (component.isPointOfNoReturn()) {
0735:                        return false;
0736:                    }
0737:                }
0738:
0739:                // if we got this far, there is not previous component in the current wizard,
0740:                // but no points of no return we encountered either. thus we should ask the
0741:                // parent wizard if it has a previous component
0742:                return (parent != null) && parent.hasPrevious();
0743:            }
0744:
0745:            // getters/setters //////////////////////////////////////////////////////////////
0746:            /**
0747:             * Returns the index of the currently active component.
0748:             *
0749:             * @return Index of the currently active component.
0750:             */
0751:            public int getIndex() {
0752:                return index;
0753:            }
0754:
0755:            /**
0756:             * Returns the {@link WizardContainer} which is used by this {@link Wizard}
0757:             * instance.
0758:             *
0759:             * @return {@link WizardContainer} which is used by this {@link Wizard}
0760:             *      instance.
0761:             */
0762:            public WizardContainer getContainer() {
0763:                return container;
0764:            }
0765:
0766:            /**
0767:             * Gets the value of the property with the given name. This method in turn calls
0768:             * the {@link PropertyContainer#getProperty(String)} method on the property
0769:             * container used by this wizard instance.
0770:             *
0771:             * @param name Name of the property whose value should be obtained.
0772:             * @return Value of the specified property, or <code>null</code> is the property
0773:             *      with the given name does not exist.
0774:             */
0775:            public String getProperty(final String name) {
0776:                return propertyContainer.getProperty(name);
0777:            }
0778:
0779:            /**
0780:             * Sets the value of the property with the given name to the given value. This
0781:             * method in turn calls the {@link PropertyContainer#setProperty(String,String)}
0782:             * method on the property container used by this wizard instance.
0783:             *
0784:             * @param name Name of the property whose value should be set.
0785:             * @param value New value for the property.
0786:             */
0787:            public void setProperty(final String name, final String value) {
0788:                propertyContainer.setProperty(name, value);
0789:            }
0790:
0791:            /**
0792:             * Returns the {@link Context} of this {@link Wizard} instance.
0793:             *
0794:             * @return {@link Context} of this {@link Wizard} instance.
0795:             */
0796:            public Context getContext() {
0797:                return context;
0798:            }
0799:
0800:            /**
0801:             * Returns the {@link ClassLoader} used by this {@link Wizard} instance.
0802:             *
0803:             * @return {@link ClassLoader} used by this {@link Wizard} instance.
0804:             */
0805:            public ClassLoader getClassLoader() {
0806:                return classLoader;
0807:            }
0808:
0809:            /**
0810:             * Returns the {@link FinishHandler} used by this {@link Wizard} instance.
0811:             *
0812:             * @return {@link FinishHandler} used by this {@link Wizard} instance.
0813:             */
0814:            public FinishHandler getFinishHandler() {
0815:                return finishHandler;
0816:            }
0817:
0818:            /**
0819:             * Sets the {@link FinishHandler} which should be used by this {@link Wizard}
0820:             * instance.
0821:             *
0822:             *
0823:             * @param finishHandler {@link FinishHandler} which should be used by this
0824:             *      {@link Wizard} instance.
0825:             */
0826:            public void setFinishHandler(final FinishHandler finishHandler) {
0827:                this .finishHandler = finishHandler;
0828:            }
0829:
0830:            // factory methods for children /////////////////////////////////////////////////
0831:            /**
0832:             * Creates a new child (or sub-) wizard with the given list of
0833:             * {@link WizardComponent}s and the initial index of the active component.
0834:             *
0835:             * @param components List of {@link WizardComponent}s over which the child
0836:             *      wizard should iterate.
0837:             * @param index Initial index of the active component.
0838:             * @return New child (sub-) wizard.
0839:             */
0840:            public Wizard createSubWizard(
0841:                    final List<WizardComponent> components, final int index) {
0842:                return new Wizard(this , components, index);
0843:            }
0844:
0845:            /**
0846:             * Creates a new child (or sub-) wizard with the given list of
0847:             * {@link WizardComponent}s, initial index of the active component, property
0848:             * container and class loader.
0849:             *
0850:             * @param components List of {@link WizardComponent}s over which the child
0851:             *      wizard should iterate.
0852:             * @param index Initial index of the active component.
0853:             * @param propertyContainer {@link PropertyContainer} which should be used by
0854:             *      the child wizard.
0855:             * @param classLoader {@link ClassLoader} which should be used by the child
0856:             *      wizard.
0857:             * @return New child (sub-) wizard.
0858:             */
0859:            public Wizard createSubWizard(
0860:                    final List<WizardComponent> components, final int index,
0861:                    final PropertyContainer propertyContainer,
0862:                    final ClassLoader classLoader) {
0863:                return new Wizard(this , components, index, propertyContainer,
0864:                        classLoader);
0865:            }
0866:
0867:            // private //////////////////////////////////////////////////////////////////////
0868:            /**
0869:             * Returns the currently active {@link WizardComponent}.
0870:             *
0871:             * @return Currently active {@link WizardComponent}, or <code>null</code> if the
0872:             *      index of the active component is outside the list size.
0873:             */
0874:            private WizardComponent getCurrent() {
0875:                if ((index > -1) && (index < components.size())) {
0876:                    return components.get(index);
0877:                } else {
0878:                    return null;
0879:                }
0880:            }
0881:
0882:            /**
0883:             * Returns the previous component in the <b>current</b> wizard's components
0884:             * list.
0885:             *
0886:             * @return Previous {@link WizardComponent} or <code>null</code> if there is no
0887:             *      previous component.
0888:             */
0889:            private WizardComponent getPrevious() {
0890:                // if current component is a point of no return - we cannot move backwards,
0891:                // i.e. there is no previous component
0892:                if ((getCurrent() != null) && getCurrent().isPointOfNoReturn()) {
0893:                    return null;
0894:                }
0895:
0896:                for (int i = index - 1; i > -1; i--) {
0897:                    final WizardComponent component = components.get(i);
0898:
0899:                    // if the component can be executed backward it is the previous one
0900:                    if (component.canExecuteBackward()) {
0901:                        return component;
0902:                    }
0903:
0904:                    // if the currently examined component is a point of no return and it
0905:                    // cannot be executed (since we passed the previous statement) - we have
0906:                    // no previous component
0907:                    if (component.isPointOfNoReturn()) {
0908:                        return null;
0909:                    }
0910:                }
0911:
0912:                // if we reached the before-first index and yet could not find a previous
0913:                // component, then there is no previous component
0914:                return null;
0915:            }
0916:
0917:            /**
0918:             * Returns the next component in the <b>current</b> wizard's components
0919:             * list.
0920:             *
0921:             * @return Next {@link WizardComponent} or <code>null</code> if there is no
0922:             *      next component.
0923:             */
0924:            private WizardComponent getNext() {
0925:                for (int i = index + 1; i < components.size(); i++) {
0926:                    final WizardComponent component = components.get(i);
0927:
0928:                    // if the component can be executed forward it is the next one
0929:                    if (component.canExecuteForward()) {
0930:                        return component;
0931:                    }
0932:                }
0933:
0934:                // if we reached the after-last index and yet could not find a next
0935:                // component, then there is no next component
0936:                return null;
0937:            }
0938:
0939:            /////////////////////////////////////////////////////////////////////////////////
0940:            // Constants
0941:            /**
0942:             * Name of the system property which is expected to contain the URI which points
0943:             * to the XML file with the list of components for the root wizard.
0944:             */
0945:            public static final String COMPONENTS_INSTANCE_URI_PROPERTY = "nbi.wizard.components.instance.uri"; // NOI18N
0946:
0947:            /**
0948:             * Default URI which points to the XML file with the list of components for the
0949:             * root wizard.
0950:             */
0951:            public static final String DEFAULT_COMPONENTS_INSTANCE_URI = FileProxy.RESOURCE_SCHEME_PREFIX
0952:                    + "org/netbeans/installer/wizard/wizard-components.xml"; // NOI18N
0953:
0954:            /**
0955:             * Name of the system property which is expected to contain the URI which points
0956:             * to the XML schema which defines the format for the serialized list of wizard
0957:             * components.
0958:             */
0959:            public static final String COMPONENTS_SCHEMA_URI_PROPERTY = "nbi.wizard.components.schema.uri"; // NOI18N
0960:
0961:            /**
0962:             * Default URI which points to the XML schema which defines the format for the
0963:             * serialized list of wizard components.
0964:             */
0965:            public static final String DEFAULT_COMPONENTS_SCHEMA_URI = FileProxy.RESOURCE_SCHEME_PREFIX
0966:                    + "org/netbeans/installer/wizard/wizard-components.xsd"; // NOI18N
0967:
0968:            /**
0969:             * Name of the XML tag which describes a list of components.
0970:             */
0971:            public static final String TAG_COMPONENTS = "components"; // NOI18N
0972:
0973:            /**
0974:             * Name of the XML tag which describes an individual component.
0975:             */
0976:            public static final String TAG_COMPONENT = "component"; // NOI18N
0977:
0978:            /**
0979:             * Name of the XMl tag which describes the properties of a component.
0980:             */
0981:            public static final String TAG_PROPERTIES = "properties"; // NOI18N
0982:
0983:            /**
0984:             * Name of the XML attribute which contains the classname of a component.
0985:             */
0986:            public static final String ATTRIBUTE_CLASS = "class"; // NOI18N
0987:
0988:            /**
0989:             * Name of the system property which will be set when a component executes. Its
0990:             * value will be the fully qualified class name of the component.
0991:             */
0992:            public static final String CURRENT_COMPONENT_CLASSNAME_PROPERTY = "nbi.wizard.current.component.classname"; // NOI18N
0993:
0994:            // private //////////////////////////////////////////////////////////////////////
0995:            /**
0996:             * Name of a resource bundle entry.
0997:             */
0998:            private static final String RESOURCE_FAILED_TO_CREATE_INSTANCE = "W.error.failed.to.create.instance"; // NOI18N
0999:
1000:            /**
1001:             * Name of a resource bundle entry.
1002:             */
1003:            private static final String RESOURCE_FAILED_TO_LOAD_COMPONENTS = "W.error.failed.to.load.components"; // NOI18N
1004:
1005:            /**
1006:             * Name of a resource bundle entry.
1007:             */
1008:            private static final String RESOURCE_FAILED_TO_LOAD_COMPONENT = "W.error.failed.to.load.component"; // NOI18N
1009:
1010:            /**
1011:             * Name of a resource bundle entry.
1012:             */
1013:            private static final String RESOURCE_FAILED_TO_ATTACH_ERROR_HANDLER = "W.error.failed.to.attach.error.handler"; // NOI18N
1014:
1015:            /**
1016:             * Name of a resource bundle entry.
1017:             */
1018:            private static final String RESOURCE_CANNOT_MOVE_BACKWARD_SILENT = "W.error.cannot.move.backward.silent"; // NOI18N
1019:
1020:            /**
1021:             * Name of a resource bundle entry.
1022:             */
1023:            private static final String RESOURCE_UNKNOWN_UI_MODE = "W.error.unknown.ui.mode"; // NOI18N
1024:
1025:            /**
1026:             * Name of a resource bundle entry.
1027:             */
1028:            private static final String RESOURCE_CANNOT_MOVE_BACKWARD_AT_FIRST = "W.error.cannot.move.backward.at.first"; // NOI18N
1029:
1030:            /**
1031:             * Name of a resource bundle entry.
1032:             */
1033:            private static final String RESOURCE_PARSER_UNSUPPORTS_SCHEMAS = "W.error.parser.unsupports.schemas";//NOI18N
1034:
1035:            /**
1036:             * Name of a resource bundle entry.
1037:             */
1038:            private static final String RESOURCE_INTERRUPTED = "W.error.interrupted";//NOI18N
1039:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.