KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectstyle > cayenne > modeler > Application


1 /* ====================================================================
2  *
3  * The ObjectStyle Group Software License, version 1.1
4  * ObjectStyle Group - http://objectstyle.org/
5  *
6  * Copyright (c) 2002-2005, Andrei (Andrus) Adamchik and individual authors
7  * of the software. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution, if any,
22  * must include the following acknowlegement:
23  * "This product includes software developed by independent contributors
24  * and hosted on ObjectStyle Group web site (http://objectstyle.org/)."
25  * Alternately, this acknowlegement may appear in the software itself,
26  * if and wherever such third-party acknowlegements normally appear.
27  *
28  * 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse
29  * or promote products derived from this software without prior written
30  * permission. For written permission, email
31  * "andrus at objectstyle dot org".
32  *
33  * 5. Products derived from this software may not be called "ObjectStyle"
34  * or "Cayenne", nor may "ObjectStyle" or "Cayenne" appear in their
35  * names without prior written permission.
36  *
37  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40  * DISCLAIMED. IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
41  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48  * SUCH DAMAGE.
49  * ====================================================================
50  *
51  * This software consists of voluntary contributions made by many
52  * individuals and hosted on ObjectStyle Group web site. For more
53  * information on the ObjectStyle Group, please see
54  * <http://objectstyle.org/>.
55  */

56 package org.objectstyle.cayenne.modeler;
57
58 import java.awt.Dialog JavaDoc;
59 import java.awt.Frame JavaDoc;
60 import java.awt.Window JavaDoc;
61 import java.io.File JavaDoc;
62 import java.util.Collection JavaDoc;
63
64 import javax.swing.ActionMap JavaDoc;
65 import javax.swing.JFrame JavaDoc;
66 import javax.swing.JOptionPane JavaDoc;
67 import javax.swing.JRootPane JavaDoc;
68
69 import org.apache.commons.collections.CollectionUtils;
70 import org.apache.commons.collections.Transformer;
71 import org.objectstyle.cayenne.modeler.action.AboutAction;
72 import org.objectstyle.cayenne.modeler.action.ConfigurePreferencesAction;
73 import org.objectstyle.cayenne.modeler.action.CreateAttributeAction;
74 import org.objectstyle.cayenne.modeler.action.CreateDataMapAction;
75 import org.objectstyle.cayenne.modeler.action.CreateDbEntityAction;
76 import org.objectstyle.cayenne.modeler.action.CreateDerivedDbEntityAction;
77 import org.objectstyle.cayenne.modeler.action.CreateDomainAction;
78 import org.objectstyle.cayenne.modeler.action.CreateNodeAction;
79 import org.objectstyle.cayenne.modeler.action.CreateObjEntityAction;
80 import org.objectstyle.cayenne.modeler.action.CreateProcedureAction;
81 import org.objectstyle.cayenne.modeler.action.CreateProcedureParameterAction;
82 import org.objectstyle.cayenne.modeler.action.CreateQueryAction;
83 import org.objectstyle.cayenne.modeler.action.CreateRelationshipAction;
84 import org.objectstyle.cayenne.modeler.action.DbEntitySyncAction;
85 import org.objectstyle.cayenne.modeler.action.DerivedEntitySyncAction;
86 import org.objectstyle.cayenne.modeler.action.ExitAction;
87 import org.objectstyle.cayenne.modeler.action.GenerateClassesAction;
88 import org.objectstyle.cayenne.modeler.action.GenerateDBAction;
89 import org.objectstyle.cayenne.modeler.action.ImportDataMapAction;
90 import org.objectstyle.cayenne.modeler.action.ImportDBAction;
91 import org.objectstyle.cayenne.modeler.action.ImportEOModelAction;
92 import org.objectstyle.cayenne.modeler.action.NavigateBackwardAction;
93 import org.objectstyle.cayenne.modeler.action.NavigateForwardAction;
94 import org.objectstyle.cayenne.modeler.action.NewProjectAction;
95 import org.objectstyle.cayenne.modeler.action.ObjEntitySyncAction;
96 import org.objectstyle.cayenne.modeler.action.OpenProjectAction;
97 import org.objectstyle.cayenne.modeler.action.ProjectAction;
98 import org.objectstyle.cayenne.modeler.action.RemoveAction;
99 import org.objectstyle.cayenne.modeler.action.RemoveAttributeAction;
100 import org.objectstyle.cayenne.modeler.action.RemoveProcedureParameterAction;
101 import org.objectstyle.cayenne.modeler.action.RemoveRelationshipAction;
102 import org.objectstyle.cayenne.modeler.action.RevertAction;
103 import org.objectstyle.cayenne.modeler.action.SaveAction;
104 import org.objectstyle.cayenne.modeler.action.SaveAsAction;
105 import org.objectstyle.cayenne.modeler.action.ValidateAction;
106 import org.objectstyle.cayenne.modeler.util.CayenneAction;
107 import org.objectstyle.cayenne.modeler.util.CayenneDialog;
108 import org.objectstyle.cayenne.pref.Domain;
109 import org.objectstyle.cayenne.pref.DomainPreference;
110 import org.objectstyle.cayenne.pref.HSQLEmbeddedPreferenceEditor;
111 import org.objectstyle.cayenne.pref.HSQLEmbeddedPreferenceService;
112 import org.objectstyle.cayenne.pref.PreferenceService;
113 import org.objectstyle.cayenne.project.CayenneUserDir;
114 import org.objectstyle.cayenne.project.Project;
115 import org.objectstyle.cayenne.swing.BindingFactory;
116 import org.scopemvc.controller.basic.ViewContext;
117 import org.scopemvc.controller.swing.SwingContext;
118 import org.scopemvc.core.View;
119 import org.scopemvc.util.UIStrings;
120 import org.scopemvc.view.swing.SwingView;
121
122 /**
123  * A main modeler application class that provides a number of services to the Modeler
124  * components. Configuration properties:
125  * <ul>
126  * <li>cayenne.modeler.application.name - name of the application, 'CayenneModeler' is
127  * default. Used to locate prerferences domain among other things.</li>
128  * <li>cayenne.modeler.pref.version - a version of the preferences DB schema. Default is
129  * "1.1".</li>
130  * </ul>
131  *
132  * @author Andrei Adamchik
133  */

134 public class Application {
135
136     public static final String JavaDoc PREFERENCES_VERSION = "1.1";
137     public static final String JavaDoc PREFERENCES_DB_SUBDIRECTORY = "prefs";
138     public static final String JavaDoc PREFERENCES_MAP_PACKAGE = "pref";
139     public static final String JavaDoc APPLICATION_NAME_PROPERTY = "cayenne.modeler.application.name";
140     public static final String JavaDoc PREFERENCES_VERSION_PROPERTY = "cayenne.modeler.pref.version";
141     
142
143     public static final String JavaDoc DEFAULT_APPLICATION_NAME = "CayenneModeler";
144
145     // TODO: implement cleaner IoC approach to avoid using this singleton...
146
protected static Application instance;
147
148     protected FileClassLoadingService modelerClassLoader;
149     protected HSQLEmbeddedPreferenceService preferenceService;
150     protected CayenneModelerController frameController;
151     protected ActionMap JavaDoc actionMap;
152     protected File JavaDoc initialProject;
153     protected String JavaDoc name;
154     protected String JavaDoc preferencesDB;
155     protected BindingFactory bindingFactory;
156     protected AdapterMapping adapterMapping;
157
158     public static Application getInstance() {
159         return instance;
160     }
161
162     // static methods that should probabaly go away eventually...
163

164     public static CayenneModelerFrame getFrame() {
165         return (CayenneModelerFrame) getInstance().getFrameController().getView();
166     }
167
168     public static Project getProject() {
169         return getInstance().getFrameController().getProjectController().getProject();
170     }
171
172     public Application(File JavaDoc initialProject) {
173         this.initialProject = initialProject;
174
175         // configure startup settings
176
String JavaDoc configuredName = System.getProperty(APPLICATION_NAME_PROPERTY);
177         this.name = (configuredName != null) ? configuredName : DEFAULT_APPLICATION_NAME;
178
179         String JavaDoc subdir = System.getProperty(PREFERENCES_VERSION_PROPERTY);
180
181         if (subdir == null) {
182             subdir = PREFERENCES_VERSION;
183         }
184
185         File JavaDoc dbDir = new File JavaDoc(CayenneUserDir
186                 .getInstance()
187                 .resolveFile(PREFERENCES_DB_SUBDIRECTORY), subdir);
188         dbDir.mkdirs();
189         this.preferencesDB = new File JavaDoc(dbDir, "db").getAbsolutePath();
190     }
191
192     public String JavaDoc getName() {
193         return name;
194     }
195
196     public ClassLoadingService getClassLoadingService() {
197         return modelerClassLoader;
198     }
199     
200     public AdapterMapping getAdapterMapping() {
201         return adapterMapping;
202     }
203
204     /**
205      * Returns an action for key.
206      */

207     public CayenneAction getAction(String JavaDoc key) {
208         return (CayenneAction) actionMap.get(key);
209     }
210
211     /**
212      * Returns Application ActionMap.
213      */

214     public ActionMap JavaDoc getActionMap() {
215         return actionMap;
216     }
217
218     /**
219      * Returns controller for the main frame.
220      */

221     public CayenneModelerController getFrameController() {
222         return frameController;
223     }
224
225     /**
226      * Starts the application.
227      */

228     public void startup() {
229         // init subsystems
230
initPreferences();
231         initClassLoader();
232         initActions();
233         this.bindingFactory = new BindingFactory();
234         this.adapterMapping = new AdapterMapping();
235
236         // ...Scope
237

238         // TODO: this will go away if switch away from Scope
239
// force Scope to use CayenneModeler properties
240
UIStrings.setPropertiesName(ModelerConstants.DEFAULT_MESSAGE_BUNDLE);
241         ViewContext.clearThreadContext();
242
243         // ...create main frame
244
this.frameController = new CayenneModelerController(this, initialProject);
245
246         // update Scope to work nicely with main frame
247
ViewContext.setGlobalContext(new ModelerContext(frameController.getFrame()));
248
249         // open up
250
frameController.startupAction();
251     }
252
253     public BindingFactory getBindingFactory() {
254         return bindingFactory;
255     }
256
257     /**
258      * Returns Application preferences service.
259      */

260     public PreferenceService getPreferenceService() {
261         return preferenceService;
262     }
263
264     /**
265      * Returns top preferences Domain for the application.
266      */

267     public Domain getPreferenceDomain() {
268         return getPreferenceService().getDomain(getName(), true);
269     }
270
271     /**
272      * Reinitializes ModelerClassLoader from preferences.
273      */

274     public void initClassLoader() {
275         FileClassLoadingService classLoader = new FileClassLoadingService();
276
277         // init from preferences...
278
Domain classLoaderDomain = getPreferenceDomain().getSubdomain(
279                 FileClassLoadingService.class);
280
281         Collection JavaDoc details = classLoaderDomain.getPreferences();
282         if (details.size() > 0) {
283
284             // transform preference to file...
285
Transformer transformer = new Transformer() {
286
287                 public Object JavaDoc transform(Object JavaDoc object) {
288                     DomainPreference pref = (DomainPreference) object;
289                     return new File JavaDoc(pref.getKey());
290                 }
291             };
292
293             classLoader.setPathFiles(CollectionUtils.collect(details, transformer));
294         }
295
296         this.modelerClassLoader = classLoader;
297     }
298
299     protected void initPreferences() {
300         HSQLEmbeddedPreferenceService service = new HSQLEmbeddedPreferenceService(
301                 preferencesDB,
302                 PREFERENCES_MAP_PACKAGE,
303                 getName());
304         service.stopOnShutdown();
305         this.preferenceService = service;
306         this.preferenceService.startService();
307
308         // test service
309
getPreferenceDomain();
310     }
311
312     protected void initActions() {
313         // build action map
314
actionMap = new ActionMap JavaDoc();
315
316         registerAction(new ProjectAction(this));
317         registerAction(new NewProjectAction(this)).setAlwaysOn(true);
318         registerAction(new OpenProjectAction(this)).setAlwaysOn(true);
319         registerAction(new ImportDataMapAction(this));
320         registerAction(new SaveAction(this));
321         registerAction(new SaveAsAction(this));
322         registerAction(new RevertAction(this));
323         registerAction(new ValidateAction(this));
324         registerAction(new RemoveAction(this));
325         registerAction(new CreateDomainAction(this));
326         registerAction(new CreateNodeAction(this));
327         registerAction(new CreateDataMapAction(this));
328         registerAction(new GenerateClassesAction(this));
329         registerAction(new CreateObjEntityAction(this));
330         registerAction(new CreateDbEntityAction(this));
331         registerAction(new CreateDerivedDbEntityAction(this));
332         registerAction(new CreateProcedureAction(this));
333         registerAction(new CreateProcedureParameterAction(this));
334         registerAction(new RemoveProcedureParameterAction(this));
335         registerAction(new CreateQueryAction(this));
336         registerAction(new CreateAttributeAction(this));
337         registerAction(new RemoveAttributeAction(this));
338         registerAction(new CreateRelationshipAction(this));
339         registerAction(new RemoveRelationshipAction(this));
340         registerAction(new DbEntitySyncAction(this));
341         registerAction(new ObjEntitySyncAction(this));
342         registerAction(new DerivedEntitySyncAction(this));
343         registerAction(new ImportDBAction(this));
344         registerAction(new ImportEOModelAction(this));
345         registerAction(new GenerateDBAction(this));
346         registerAction(new AboutAction(this)).setAlwaysOn(true);
347         registerAction(new ConfigurePreferencesAction(this)).setAlwaysOn(true);
348         registerAction(new ExitAction(this)).setAlwaysOn(true);
349         registerAction(new NavigateBackwardAction(this)).setAlwaysOn(true);
350         registerAction(new NavigateForwardAction(this)).setAlwaysOn(true);
351     }
352
353     private CayenneAction registerAction(CayenneAction action) {
354         actionMap.put(action.getKey(), action);
355         return action;
356     }
357
358     static final class PreferencesDelegate implements
359             HSQLEmbeddedPreferenceEditor.Delegate {
360
361         static final String JavaDoc message = "Preferences Database is locked by another application. "
362                 + "Do you want to remove the lock?";
363         static final String JavaDoc failureMessage = "Failed to remove database lock. "
364                 + "Preferences will we saved for this session only.";
365
366         static final HSQLEmbeddedPreferenceEditor.Delegate sharedInstance = new PreferencesDelegate();
367
368         public boolean deleteMasterLock(File JavaDoc lock) {
369             int result = JOptionPane.showConfirmDialog(null, message);
370             if (result == JOptionPane.YES_OPTION || result == JOptionPane.OK_OPTION) {
371                 if (!lock.delete()) {
372                     JOptionPane.showMessageDialog(null, failureMessage);
373                     return false;
374                 }
375             }
376
377             return true;
378         }
379     }
380
381     final class ModelerContext extends SwingContext {
382
383         JFrame JavaDoc frame;
384
385         public ModelerContext(JFrame JavaDoc frame) {
386             this.frame = frame;
387         }
388
389         protected void showViewInPrimaryWindow(SwingView view) {
390         }
391
392         /**
393          * Creates closeable dialogs.
394          */

395         protected void showViewInDialog(SwingView inView) {
396             // NOTE:
397
// copied from superclass, except that JDialog is substituted for
398
// CayenneDialog
399
// Keep in mind when upgrading Scope to the newer versions.
400

401             // Make a JDialog to contain the view.
402
Window JavaDoc parentWindow = getDefaultParentWindow();
403
404             final CayenneDialog dialog;
405             if (parentWindow instanceof Dialog JavaDoc) {
406                 dialog = new CayenneDialog((Dialog JavaDoc) parentWindow);
407             }
408             else {
409                 dialog = new CayenneDialog((Frame JavaDoc) parentWindow);
410             }
411
412             // Set title, modality, resizability
413
if (inView.getTitle() != null) {
414                 dialog.setTitle(inView.getTitle());
415             }
416             if (inView.getDisplayMode() == SwingView.MODAL_DIALOG) {
417                 dialog.setModal(true);
418             }
419             else {
420                 dialog.setModal(false);
421             }
422             dialog.setResizable(inView.isResizable());
423
424             setupWindow(dialog.getRootPane(), inView, true);
425             dialog.toFront();
426         }
427
428         /**
429          * Overrides super implementation to allow using Scope together with normal Swing
430          * code that CayenneModeler already has.
431          */

432         public JRootPane JavaDoc findRootPaneFor(View view) {
433             JRootPane JavaDoc pane = super.findRootPaneFor(view);
434
435             if (pane != null) {
436                 return pane;
437             }
438
439             if (((SwingView) view).getDisplayMode() != SwingView.PRIMARY_WINDOW) {
440                 return pane;
441             }
442
443             return frame.getRootPane();
444         }
445
446         protected Window JavaDoc getDefaultParentWindow() {
447             return frame;
448         }
449     }
450 }
Popular Tags