KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jcorporate > expresso > services > controller > configuration > CreateSettingsWizard


1 package com.jcorporate.expresso.services.controller.configuration;
2
3 /* ====================================================================
4  * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
5  *
6  * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by Jcorporate Ltd.
23  * (http://www.jcorporate.com/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. "Jcorporate" and product names such as "Expresso" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written permission,
30  * please contact info@jcorporate.com.
31  *
32  * 5. Products derived from this software may not be called "Expresso",
33  * or other Jcorporate product names; nor may "Expresso" or other
34  * Jcorporate product names appear in their name, without prior
35  * written permission of Jcorporate Ltd.
36  *
37  * 6. No product derived from this software may compete in the same
38  * market space, i.e. framework, without prior written permission
39  * of Jcorporate Ltd. For written permission, please contact
40  * partners@jcorporate.com.
41  *
42  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
43  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
44  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
45  * DISCLAIMED. IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
46  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
47  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
48  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
49  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
50  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
51  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
52  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53  * SUCH DAMAGE.
54  * ====================================================================
55  *
56  * This software consists of voluntary contributions made by many
57  * individuals on behalf of the Jcorporate Ltd. Contributions back
58  * to the project(s) are encouraged when you make modifications.
59  * Please send them to support@jcorporate.com. For more information
60  * on Jcorporate Ltd. and its products, please see
61  * <http://www.jcorporate.com/>.
62  *
63  * Portions of this software are based upon other open source
64  * products and are subject to their respective licenses.
65  */

66
67 import com.jcorporate.expresso.core.cache.DefaultCacheManager;
68 import com.jcorporate.expresso.core.controller.ControllerException;
69 import com.jcorporate.expresso.core.controller.ControllerRequest;
70 import com.jcorporate.expresso.core.controller.ControllerResponse;
71 import com.jcorporate.expresso.core.controller.ErrorCollection;
72 import com.jcorporate.expresso.core.controller.NonHandleableException;
73 import com.jcorporate.expresso.core.controller.SecureIfSetController;
74 import com.jcorporate.expresso.core.controller.State;
75 import com.jcorporate.expresso.core.controller.Transition;
76 import com.jcorporate.expresso.core.misc.StringUtil;
77 import com.jcorporate.expresso.core.security.CryptoManager;
78 import com.jcorporate.expresso.kernel.DataContext;
79 import com.jcorporate.expresso.kernel.RootContainerInterface;
80 import com.jcorporate.expresso.kernel.digester.ComponentConfig;
81 import com.jcorporate.expresso.kernel.digester.ExpressoServicesConfig;
82 import com.jcorporate.expresso.kernel.management.ComponentFactory;
83 import com.jcorporate.expresso.kernel.management.ExpressoRuntimeMap;
84 import com.jcorporate.expresso.kernel.util.ClassLocator;
85 import com.jcorporate.expresso.services.controller.WizardFormStack;
86 import org.apache.log4j.Logger;
87
88 /**
89  * Wizard-style controller that helps to create a blank set of settings
90  * for the Expresso Runtime.
91  *
92  * @author Michael Rimov
93  * @version $Revision: 1.8 $ on $Date: 2004/11/17 20:48:17 $
94  */

95
96 public class CreateSettingsWizard extends SecureIfSetController {
97
98     private static final Logger log = Logger.getLogger(CreateSettingsWizard.class);
99
100     public static final String JavaDoc RUNTIME_KEY = CreateSettingsWizard.class.getName() + ".runtime_key";
101
102
103     public static final String JavaDoc SETTINGS_BEAN_KEY = "createWizard";
104
105     public static final String JavaDoc SERVICES_CONFIG_KEY = CreateSettingsWizard.class.getName() + ".service_config";
106
107     public CreateSettingsWizard() {
108         State s = new State("start", "Start");
109         this.addState(s);
110         this.setInitialState("start");
111
112         s = new State("runtimeName", "Runtime Name");
113         this.addState(s);
114
115         s = new State("processRuntimeName", "Process Runtime Name");
116         this.addState(s);
117
118         s = new State("promptDBSettings", "Prompt Database Settings");
119         this.addState(s);
120
121         s = new State("processDBSettings", "Process Database Settings");
122         this.addState(s);
123
124         s = new State("promptJNDISettings", "Prompt JNDI Settings");
125         this.addState(s);
126
127         s = new State("processJNDISettings", "Process JNDI Settings");
128         this.addState(s);
129
130         s = new State("readDatabaseNotes", "Read Database Notes");
131         this.addState(s);
132
133         s = new State("promptTestSettings", "Prompt Test Settings");
134         this.addState(s);
135
136
137         s = new State("testSettings", "Test Settings");
138         this.addState(s);
139
140
141         s = new State("promptInstallExpresso", "Prompt Install Expresso");
142         this.addState(s);
143
144         s = new State("installExpresso", "Prompt Install Expresso");
145         this.addState(s);
146
147         s = new State("promptFinished", "Prompt Finished");
148         this.addState(s);
149
150         s = new State("saveFileLocal", "Save File Local");
151         this.addState(s);
152
153         s = new State("viewFile", "View File Remotely");
154         this.addState(s);
155
156         s = new State("complete", "Complete System");
157         this.addState(s);
158
159     }
160
161
162     /**
163      * Initialize Wizard and prepare runtime state.
164      *
165      * @param request The <code>ControllerRequest</code> object
166      * @param response The <code>ControllerResponse</code> object
167      * @throws ControllerException upon error.
168      * @throws NonHandleableException upon fatal error.
169      */

170     protected void runStartState(ControllerRequest request,
171                                  ControllerResponse response) throws ControllerException, NonHandleableException {
172
173
174 // WizardFormStack.getInstance(request).reset();
175
WizardFormStack.getInstance(request).processNewState(this, request, response);
176
177         //We initialize with a new rci.
178
RootContainerInterface rci = this.getRootContainerInterface(request);
179         ExpressoServicesConfig esc = new ExpressoServicesConfig();
180         rci.setExpressoServicesConfig(esc);
181         this.persistExpressoServices(request, esc);
182
183         Transition t = new Transition("runtimeName", this);
184         t.setName("next");
185         t.setLabel("Next >");
186         response.add(t);
187     }
188
189
190     /**
191      * Prompt for a runtime name
192      *
193      * @param request The <code>ControllerRequest</code> object
194      * @param response The <code>ControllerResponse</code> object
195      * @throws ControllerException upon error.
196      * @throws NonHandleableException upon fatal error.
197      */

198     protected void runRuntimeNameState(ControllerRequest request,
199                                        ControllerResponse response) throws ControllerException, NonHandleableException {
200         WizardFormStack.getInstance(request).processNewState(this, request, response);
201
202         Transition t = new Transition("processRuntimeName", this);
203         t.setName("next");
204         t.setLabel("Next >");
205         response.add(t);
206         response.add(WizardFormStack.getInstance(request).getPreviousTransition());
207     }
208
209
210     /**
211      * Process and validates the input of the runtime state. IT then creates some
212      * blank components that are needed for a basic configuration such as a default
213      * context and a persistence manager.
214      *
215      * @param request The <code>ControllerRequest</code> object
216      * @param response The <code>ControllerResponse</code> object
217      * @throws ControllerException upon error.
218      * @throws NonHandleableException upon fatal error.
219      */

220     protected void runProcessRuntimeNameState(ControllerRequest request,
221                                               ControllerResponse response) throws ControllerException,
222             NonHandleableException {
223
224         ErrorCollection ec = new ErrorCollection();
225         CreateSettingsBean bean = this.getSettingsBean(request);
226         if (bean.getRuntimeName() == null || bean.getRuntimeName().length() == 0) {
227             ec.addError("Runtime name must be a non-null value with no special XML escape characters in it.");
228         }
229
230         if (StringUtil.notNull(bean.getTempFileLocation()).length() == 0) {
231             ec.addError("Expresso temp locationmust be a valid directory location on the server.");
232         } else {
233             String JavaDoc seedLoc = bean.getTempFileLocation();
234             java.io.File JavaDoc f = new java.io.File JavaDoc(seedLoc);
235             if (f == null) {
236                 ec.addError("'" + bean.getTempFileLocation() + "' appears to be an invalid path name");
237             } else if (!f.isDirectory()) {
238                 ec.addError("Random seed location must be a directory.");
239             }
240         }
241
242         if (bean.isUseStrongEncryption()) {
243             try {
244                 ClassLocator.loadClass("org.bouncycastle.jce.provider.BouncyCastleProvider");
245             } catch (ClassNotFoundException JavaDoc ex) {
246                 ec.addError("Could not locate the BouncyCastle cryptographic" +
247                         " provider in your classpath. If you wish to use Strong Cryptography, " +
248                         "you will need to isntall the BouncyCastle provider before proceeding");
249             }
250         }
251
252         if (StringUtil.notNull(bean.getSecretKey()).length() < 12) {
253             ec.addError("The secret key should be > 12 characters, and preferably > 36 characters");
254         }
255
256         if (ec.getErrorCount() > 0) {
257             response.saveErrors(ec);
258             this.transition("runtimeName", request, response);
259             return;
260         }
261
262         try {
263             //
264
//Create root container
265
//
266
RootContainerInterface rci = this.getRootContainerInterface(request);
267
268             ComponentFactory cf = ComponentFactory.getInstance();
269
270             cf.initComponent(rci);
271             ComponentConfig rootConfig = cf.constructDefaultConfig(rci);
272             rci.getMetaData().setName(bean.getRuntimeName());
273             cf.configureComponent(rootConfig, rci);
274
275             //
276
//Create Default Data Context
277
//
278
DataContext context = new com.jcorporate.expresso.kernel.DataContext();
279             rci.getContainerImplementation().addComponent(context);
280             cf.initComponent(context);
281             context.getMetaData().setName("default");
282
283             ComponentConfig contextConfig = cf.constructDefaultConfig(context);
284             contextConfig.setProperty("ContextDescription", "Default Database");
285             cf.configureComponent(contextConfig, context);
286
287
288             //
289
//Create and configure CryptoManager
290
//
291
CryptoManager cryptoManager = new com.jcorporate.expresso.core.security.CryptoManager();
292             rci.getContainerImplementation().addComponent(cryptoManager);
293             cf.initComponent(cryptoManager);
294
295             ComponentConfig cryptoConfig = cf.constructDefaultConfig(cryptoManager);
296             if (bean.isUseStrongEncryption()) {
297                 cryptoConfig.setProperty("StrongCrypto", "true");
298             }
299
300             cryptoConfig.setProperty("CryptoKey", bean.getSecretKey());
301             cryptoConfig.setProperty("RandomSeed", bean.getTempFileLocation());
302             cf.configureComponent(cryptoConfig, cryptoManager);
303
304
305             //
306
//Create and configure CacheManager
307
//
308
if (bean.isUseCaching()) {
309                 DefaultCacheManager cacheManager = new DefaultCacheManager();
310                 context.getContainerImplementation().addComponent(cacheManager);
311                 cf.initComponent(cacheManager);
312                 ComponentConfig cacheManagerConfig = cf.constructDefaultConfig(cacheManager);
313                 cf.configureComponent(cacheManagerConfig, cacheManager);
314             }
315         } catch (com.jcorporate.expresso.kernel.exception.ConfigurationException ex) {
316             log.error("Error creating default components", ex);
317             response.addError("Unable to create default components. See log for details");
318             this.transition("runtimeName", request, response);
319         } catch (com.jcorporate.expresso.kernel.exception.ChainedException ex) {
320             log.error("Error creating CryptoManager", ex);
321             response.addError("Unable to create default components. See log for details");
322             this.transition("runtimeName", request, response);
323         }
324
325
326         Transition t = new Transition("promptDBSettings", this);
327         t.redirectTransition(request, response);
328     }
329
330     /**
331      * @param request The <code>ControllerRequest</code> object
332      * @param response The <code>ControllerResponse</code> object
333      * @throws ControllerException upon error.
334      * @throws NonHandleableException upon fatal error.
335      */

336     protected void runPromptDBSettingsState(ControllerRequest request,
337                                             ControllerResponse response) throws ControllerException,
338             NonHandleableException {
339
340         WizardFormStack.getInstance(request).processNewState(this, request, response);
341         Transition t = new Transition("processDBSettings", this);
342         t.setName("next");
343         t.setLabel("Next >");
344         response.add(t);
345         response.add(WizardFormStack.getInstance(request).getPreviousTransition());
346         response.add(new Transition("readDatabaseNotes", this));
347     }
348
349     /**
350      * Processes and validates the DB Settings.
351      *
352      * @param request The <code>ControllerRequest</code> object
353      * @param response The <code>ControllerResponse</code> object
354      * @throws ControllerException upon error.
355      * @throws NonHandleableException upon fatal error.
356      */

357     protected void runProcessDBSettingsState(ControllerRequest request,
358                                              ControllerResponse response) throws ControllerException,
359             NonHandleableException {
360
361         CreateSettingsBean bean = this.getSettingsBean(request);
362
363         ErrorCollection ec = new ErrorCollection();
364
365         if (StringUtil.notNull(bean.getDatabaseURL()).length() == 0 && !bean.isUseJNDI()) {
366             ec.addError("Database URL must not be blank if not using JNDI");
367         }
368
369         if (StringUtil.notNull(bean.getLoginName()).length() == 0 && !bean.isUseJNDI()) {
370             ec.addError("Login Name must not be blank if not using JNDI");
371         }
372
373         if (StringUtil.notNull(bean.getPassword()).length() == 0 && !bean.isUseJNDI()) {
374             ec.addError("Password must not be blank if not using JNDI");
375         }
376
377         if (StringUtil.notNull(bean.getDbConfig()).length() == 0) {
378             ec.addError("You must set a database configuration");
379         }
380
381         if (ec.getErrorCount() > 0) {
382             response.saveErrors(ec);
383             transition("promptDBSettings", request, response);
384             return;
385         }
386
387         if (bean.isUseJNDI() == true) {
388             Transition t = new Transition("promptJNDISettings", this);
389             t.redirectTransition(request, response);
390             return;
391         } else {
392             Transition t = new Transition("promptTestSettings", this);
393             t.redirectTransition(request, response);
394             return;
395         }
396
397     }
398
399     /**
400      * @param request The <code>ControllerRequest</code> object
401      * @param response The <code>ControllerResponse</code> object
402      * @throws ControllerException upon error.
403      * @throws NonHandleableException upon fatal error.
404      */

405     protected void runPromptJNDISettingsState(ControllerRequest request,
406                                               ControllerResponse response) throws ControllerException,
407             NonHandleableException {
408
409     }
410
411     /**
412      * @param request The <code>ControllerRequest</code> object
413      * @param response The <code>ControllerResponse</code> object
414      * @throws ControllerException upon error.
415      * @throws NonHandleableException upon fatal error.
416      */

417     protected void runProcessJNDISettingsState(ControllerRequest request,
418                                                ControllerResponse response) throws ControllerException,
419             NonHandleableException {
420
421     }
422
423
424     /**
425      * @param request The <code>ControllerRequest</code> object
426      * @param response The <code>ControllerResponse</code> object
427      * @throws ControllerException upon error.
428      * @throws NonHandleableException upon fatal error.
429      */

430     protected void runReadDatabaseNotesState(ControllerRequest request,
431                                              ControllerResponse response) throws ControllerException,
432             NonHandleableException {
433
434     }
435
436     /**
437      * @param request The <code>ControllerRequest</code> object
438      * @param response The <code>ControllerResponse</code> object
439      * @throws ControllerException upon error.
440      * @throws NonHandleableException upon fatal error.
441      */

442     protected void runPromptTestSettingsState(ControllerRequest request,
443                                               ControllerResponse response) throws ControllerException,
444             NonHandleableException {
445
446     }
447
448
449     /**
450      * @param request The <code>ControllerRequest</code> object
451      * @param response The <code>ControllerResponse</code> object
452      * @throws ControllerException upon error.
453      * @throws NonHandleableException upon fatal error.
454      */

455     protected void runTestSettingsState(ControllerRequest request,
456                                         ControllerResponse response) throws ControllerException,
457             NonHandleableException {
458
459     }
460
461
462     /**
463      * @param request The <code>ControllerRequest</code> object
464      * @param response The <code>ControllerResponse</code> object
465      * @throws ControllerException upon error.
466      * @throws NonHandleableException upon fatal error.
467      */

468     protected void runPromptInstallExpressoState(ControllerRequest request,
469                                                  ControllerResponse response) throws ControllerException,
470             NonHandleableException {
471
472     }
473
474
475     /**
476      * @param request The <code>ControllerRequest</code> object
477      * @param response The <code>ControllerResponse</code> object
478      * @throws ControllerException upon error.
479      * @throws NonHandleableException upon fatal error.
480      */

481     protected void runInstallExpressoState(ControllerRequest request,
482                                            ControllerResponse response) throws ControllerException,
483             NonHandleableException {
484
485     }
486
487
488     /**
489      * @param request The <code>ControllerRequest</code> object
490      * @param response The <code>ControllerResponse</code> object
491      * @throws ControllerException upon error.
492      * @throws NonHandleableException upon fatal error.
493      */

494     protected void runPromptFinishedState(ControllerRequest request,
495                                           ControllerResponse response) throws ControllerException,
496             NonHandleableException {
497
498     }
499
500
501     /**
502      * @param request The <code>ControllerRequest</code> object
503      * @param response The <code>ControllerResponse</code> object
504      * @throws ControllerException upon error.
505      * @throws NonHandleableException upon fatal error.
506      */

507     protected void runSaveFileLocalState(ControllerRequest request,
508                                          ControllerResponse response) throws ControllerException,
509             NonHandleableException {
510
511     }
512
513     /**
514      * @param request The <code>ControllerRequest</code> object
515      * @param response The <code>ControllerResponse</code> object
516      * @throws ControllerException upon error.
517      * @throws NonHandleableException upon fatal error.
518      */

519     protected void runViewFileState(ControllerRequest request,
520                                     ControllerResponse response) throws ControllerException, NonHandleableException {
521
522     }
523
524     /**
525      * @param request The <code>ControllerRequest</code> object
526      * @param response The <code>ControllerResponse</code> object
527      * @throws ControllerException upon error.
528      * @throws NonHandleableException upon fatal error.
529      */

530     protected void runCompleteState(ControllerRequest request,
531                                     ControllerResponse response) throws ControllerException, NonHandleableException {
532
533         RootContainerInterface rci = getRootContainerInterface(request);
534         ExpressoRuntimeMap.registerRuntime(rci.getExpressoServicesConfig().getName(), rci);
535         request.getSession().removePersistentAttribute(RUNTIME_KEY);
536     }
537
538     /**
539      * Retrieve the root container interface for what we're configuring. If none exists
540      * in the system yet, clear it.
541      *
542      * @param request the ControllerRequest object
543      * @return a RootContainerInterface
544      * @throws ControllerException upon error
545      */

546     private RootContainerInterface getRootContainerInterface(ControllerRequest request) throws ControllerException {
547         RootContainerInterface rci = (RootContainerInterface) request.getSession().getPersistentAttribute(RUNTIME_KEY);
548         if (rci == null) {
549             try {
550                 rci = ComponentFactory.getInstance().constructRootContainer();
551             } catch (com.jcorporate.expresso.kernel.exception.ConfigurationException ex) {
552                 log.error("Unable to construct root of the new expresso runtime", ex);
553                 throw new ControllerException("Unable to construct root of the new expresso runtime.", ex);
554             }
555             request.getSession().setPersistentAttribute(RUNTIME_KEY, rci);
556         }
557
558         return rci;
559     }
560
561
562     private void persistExpressoServices(ControllerRequest request, ExpressoServicesConfig config) throws ControllerException {
563         //We save the expresso services config into the session because the root container
564
//doesn't keeps config info as a weak reference, so we need a real reference somewhere
565
//to keep from losing configuration. At least this will keep a system running
566
//until the config file is installed and the system rebooted.
567
request.getSession().setPersistentAttribute(SERVICES_CONFIG_KEY, config);
568     }
569
570     private CreateSettingsBean getSettingsBean(ControllerRequest request) throws ControllerException {
571         CreateSettingsBean rci = (CreateSettingsBean) request.getSession().getPersistentAttribute(SETTINGS_BEAN_KEY);
572         if (rci == null) {
573             rci = new CreateSettingsBean();
574             request.getSession().setPersistentAttribute(SETTINGS_BEAN_KEY, rci);
575         }
576
577         return rci;
578     }
579
580
581 }
Popular Tags