KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectstyle > cayenne > modeler > editor > DataMapView


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.editor;
57
58 import java.awt.BorderLayout JavaDoc;
59 import java.awt.event.ActionEvent JavaDoc;
60 import java.awt.event.ActionListener JavaDoc;
61 import java.util.Arrays JavaDoc;
62 import java.util.Iterator JavaDoc;
63
64 import javax.swing.DefaultComboBoxModel JavaDoc;
65 import javax.swing.JButton JavaDoc;
66 import javax.swing.JCheckBox JavaDoc;
67 import javax.swing.JComboBox JavaDoc;
68 import javax.swing.JLabel JavaDoc;
69 import javax.swing.JPanel JavaDoc;
70 import javax.swing.JTextField JavaDoc;
71
72 import org.objectstyle.cayenne.access.DataDomain;
73 import org.objectstyle.cayenne.access.DataNode;
74 import org.objectstyle.cayenne.conf.Configuration;
75 import org.objectstyle.cayenne.map.DataMap;
76 import org.objectstyle.cayenne.map.ObjEntity;
77 import org.objectstyle.cayenne.map.event.DataMapEvent;
78 import org.objectstyle.cayenne.map.event.DataNodeEvent;
79 import org.objectstyle.cayenne.map.event.EntityEvent;
80 import org.objectstyle.cayenne.modeler.Application;
81 import org.objectstyle.cayenne.modeler.ProjectController;
82 import org.objectstyle.cayenne.modeler.dialog.datamap.PackageUpdateController;
83 import org.objectstyle.cayenne.modeler.dialog.datamap.SchemaUpdateController;
84 import org.objectstyle.cayenne.modeler.dialog.datamap.SuperclassUpdateController;
85 import org.objectstyle.cayenne.modeler.event.DataMapDisplayEvent;
86 import org.objectstyle.cayenne.modeler.event.DataMapDisplayListener;
87 import org.objectstyle.cayenne.modeler.pref.DataMapDefaults;
88 import org.objectstyle.cayenne.modeler.util.CayenneWidgetFactory;
89 import org.objectstyle.cayenne.modeler.util.CellRenderers;
90 import org.objectstyle.cayenne.modeler.util.Comparators;
91 import org.objectstyle.cayenne.modeler.util.ProjectUtil;
92 import org.objectstyle.cayenne.modeler.util.TextAdapter;
93 import org.objectstyle.cayenne.project.ApplicationProject;
94 import org.objectstyle.cayenne.util.Util;
95 import org.objectstyle.cayenne.validation.ValidationException;
96
97 import com.jgoodies.forms.builder.DefaultFormBuilder;
98 import com.jgoodies.forms.layout.FormLayout;
99
100 /**
101  * Panel for editing a DataMap.
102  */

103 public class DataMapView extends JPanel JavaDoc {
104
105     protected ProjectController eventController;
106
107     protected TextAdapter name;
108     protected JLabel JavaDoc location;
109     protected JComboBox JavaDoc nodeSelector;
110     protected TextAdapter defaultSchema;
111     protected TextAdapter defaultPackage;
112     protected TextAdapter defaultSuperclass;
113     protected JCheckBox JavaDoc defaultLockType;
114     protected JButton JavaDoc updateDefaultSchema;
115     protected JButton JavaDoc updateDefaultPackage;
116     protected JButton JavaDoc updateDefaultSuperclass;
117     protected JButton JavaDoc updateDefaultLockType;
118
119     public DataMapView(ProjectController eventController) {
120         this.eventController = eventController;
121
122         initView();
123         initController();
124     }
125
126     private void initView() {
127         // create widgets
128
name = new TextAdapter(new JTextField JavaDoc()) {
129
130             protected void updateModel(String JavaDoc text) {
131                 setDataMapName(text);
132             }
133         };
134
135         location = CayenneWidgetFactory.createLabel("");
136         nodeSelector = CayenneWidgetFactory.createComboBox();
137         nodeSelector.setRenderer(CellRenderers.listRendererWithIcons());
138
139         updateDefaultSchema = new JButton JavaDoc("Update...");
140         defaultSchema = new TextAdapter(new JTextField JavaDoc()) {
141
142             protected void updateModel(String JavaDoc text) {
143                 setDefaultSchema(text);
144             }
145         };
146
147         updateDefaultPackage = new JButton JavaDoc("Update...");
148         defaultPackage = new TextAdapter(new JTextField JavaDoc()) {
149
150             protected void updateModel(String JavaDoc text) {
151                 setDefaultPackage(text);
152             }
153         };
154
155         updateDefaultSuperclass = new JButton JavaDoc("Update...");
156         defaultSuperclass = new TextAdapter(new JTextField JavaDoc()) {
157
158             protected void updateModel(String JavaDoc text) {
159                 setDefaultSuperclass(text);
160             }
161         };
162
163         updateDefaultLockType = new JButton JavaDoc("Update");
164         defaultLockType = new JCheckBox JavaDoc();
165
166         // assemble
167
FormLayout layout = new FormLayout(
168                 "right:max(50dlu;pref), 3dlu, fill:max(110dlu;pref), 3dlu, fill:90",
169                 "");
170         DefaultFormBuilder builder = new DefaultFormBuilder(layout);
171         builder.setDefaultDialogBorder();
172
173         builder.appendSeparator("DataMap Configuration");
174         builder.append("DataMap Name:", name.getComponent(), 3);
175         builder.append("File:", location, 3);
176         builder.append("DataNode:", nodeSelector, 3);
177
178         builder.appendSeparator("Entity Defaults");
179         builder.append(
180                 "DB Schema:",
181                 defaultSchema.getComponent(),
182                 updateDefaultSchema);
183         builder.append(
184                 "Java Package:",
185                 defaultPackage.getComponent(),
186                 updateDefaultPackage);
187         builder.append(
188                 "DataObject Superclass:",
189                 defaultSuperclass.getComponent(),
190                 updateDefaultSuperclass);
191         builder.append("Optimistic Locking:", defaultLockType, updateDefaultLockType);
192
193         this.setLayout(new BorderLayout JavaDoc());
194         add(builder.getPanel(), BorderLayout.CENTER);
195     }
196
197     private void initController() {
198         eventController.addDataMapDisplayListener(new DataMapDisplayListener() {
199
200             public void currentDataMapChanged(DataMapDisplayEvent e) {
201                 DataMap map = e.getDataMap();
202                 if (map != null) {
203                     initFromModel(map);
204                 }
205             }
206         });
207
208         nodeSelector.addActionListener(new ActionListener JavaDoc() {
209
210             public void actionPerformed(ActionEvent JavaDoc e) {
211                 setDataNode();
212             }
213         });
214
215         defaultLockType.addActionListener(new ActionListener JavaDoc() {
216
217             public void actionPerformed(ActionEvent JavaDoc e) {
218                 setDefaultLockType(defaultLockType.isSelected()
219                         ? ObjEntity.LOCK_TYPE_OPTIMISTIC
220                         : ObjEntity.LOCK_TYPE_NONE);
221             }
222         });
223
224         updateDefaultSchema.addActionListener(new ActionListener JavaDoc() {
225
226             public void actionPerformed(ActionEvent JavaDoc e) {
227                 updateDefaultSchema();
228             }
229         });
230
231         updateDefaultPackage.addActionListener(new ActionListener JavaDoc() {
232
233             public void actionPerformed(ActionEvent JavaDoc e) {
234                 updateDefaultPackage();
235             }
236         });
237
238         updateDefaultSuperclass.addActionListener(new ActionListener JavaDoc() {
239
240             public void actionPerformed(ActionEvent JavaDoc e) {
241                 updateDefaultSuperclass();
242             }
243         });
244
245         updateDefaultLockType.addActionListener(new ActionListener JavaDoc() {
246
247             public void actionPerformed(ActionEvent JavaDoc e) {
248                 updateDefaultLockType();
249             }
250         });
251     }
252
253     /**
254      * Updates the view from the current model state. Invoked when a currently displayed
255      * ObjEntity is changed.
256      */

257     private void initFromModel(DataMap map) {
258         name.setText(map.getName());
259         String JavaDoc locationText = map.getLocation();
260         location.setText((locationText != null) ? locationText : "(no file)");
261
262         // rebuild data node list
263
Object JavaDoc nodes[] = eventController.getCurrentDataDomain().getDataNodes().toArray();
264
265         // add an empty item to the front
266
Object JavaDoc[] objects = new Object JavaDoc[nodes.length + 1];
267         // objects[0] = null;
268

269         // now add the entities
270
if (nodes.length > 0) {
271             Arrays.sort(nodes, Comparators.getNamedObjectComparator());
272             System.arraycopy(nodes, 0, objects, 1, nodes.length);
273         }
274
275         DefaultComboBoxModel JavaDoc model = new DefaultComboBoxModel JavaDoc(objects);
276
277         // find selected node
278
for (int i = 0; i < nodes.length; i++) {
279             DataNode node = (DataNode) nodes[i];
280             if (node.getDataMaps().contains(map)) {
281                 model.setSelectedItem(node);
282                 break;
283             }
284         }
285
286         nodeSelector.setModel(model);
287
288         // init default fields
289
defaultLockType.setSelected(map.getDefaultLockType() != ObjEntity.LOCK_TYPE_NONE);
290         defaultPackage.setText(map.getDefaultPackage());
291         defaultSchema.setText(map.getDefaultSchema());
292         defaultSuperclass.setText(map.getDefaultSuperclass());
293     }
294
295     void setDefaultLockType(int lockType) {
296         DataMap dataMap = eventController.getCurrentDataMap();
297
298         if (dataMap == null) {
299             return;
300         }
301
302         int oldType = dataMap.getDefaultLockType();
303         if (oldType == lockType) {
304             return;
305         }
306
307         dataMap.setDefaultLockType(lockType);
308         eventController.fireDataMapEvent(new DataMapEvent(this, dataMap));
309     }
310
311     void setDefaultPackage(String JavaDoc newDefaultPackage) {
312         DataMap dataMap = eventController.getCurrentDataMap();
313
314         if (dataMap == null) {
315             return;
316         }
317
318         if (newDefaultPackage != null && newDefaultPackage.trim().length() == 0) {
319             newDefaultPackage = null;
320         }
321
322         String JavaDoc oldPackage = dataMap.getDefaultPackage();
323         if (Util.nullSafeEquals(newDefaultPackage, oldPackage)) {
324             return;
325         }
326
327         dataMap.setDefaultPackage(newDefaultPackage);
328         
329         // update class generation preferences
330
eventController.getDataMapPreferences().setSuperclassPackage(
331                 newDefaultPackage,
332                 DataMapDefaults.DEFAULT_SUPERCLASS_PACKAGE);
333         
334         
335         eventController.fireDataMapEvent(new DataMapEvent(this, dataMap));
336     }
337
338     void setDefaultSchema(String JavaDoc newSchema) {
339         DataMap dataMap = eventController.getCurrentDataMap();
340
341         if (dataMap == null) {
342             return;
343         }
344
345         if (newSchema != null && newSchema.trim().length() == 0) {
346             newSchema = null;
347         }
348
349         String JavaDoc oldSchema = dataMap.getDefaultSchema();
350         if (Util.nullSafeEquals(newSchema, oldSchema)) {
351             return;
352         }
353
354         dataMap.setDefaultSchema(newSchema);
355         eventController.fireDataMapEvent(new DataMapEvent(this, dataMap));
356     }
357
358     void setDefaultSuperclass(String JavaDoc newSuperclass) {
359         DataMap dataMap = eventController.getCurrentDataMap();
360
361         if (dataMap == null) {
362             return;
363         }
364
365         if (newSuperclass != null && newSuperclass.trim().length() == 0) {
366             newSuperclass = null;
367         }
368
369         String JavaDoc oldSuperclass = dataMap.getDefaultSuperclass();
370         if (Util.nullSafeEquals(newSuperclass, oldSuperclass)) {
371             return;
372         }
373
374         dataMap.setDefaultSuperclass(newSuperclass);
375         eventController.fireDataMapEvent(new DataMapEvent(this, dataMap));
376     }
377
378     void setDataMapName(String JavaDoc newName) {
379         if (newName == null || newName.trim().length() == 0) {
380             throw new ValidationException("Enter name for DataMap");
381         }
382
383         DataMap map = eventController.getCurrentDataMap();
384
385         // search for matching map name across domains, as currently they have to be
386
// unique globally
387
Configuration config = ((ApplicationProject) Application.getProject())
388                 .getConfiguration();
389
390         DataMap matchingMap = null;
391
392         Iterator JavaDoc it = config.getDomains().iterator();
393         while (it.hasNext()) {
394             DataDomain domain = (DataDomain) it.next();
395             DataMap nextMap = domain.getMap(newName);
396
397             if (nextMap == map) {
398                 continue;
399             }
400
401             if (nextMap != null) {
402                 matchingMap = nextMap;
403                 break;
404             }
405         }
406
407         if (matchingMap != null) {
408
409             // there is an entity with the same name
410
throw new ValidationException("There is another DataMap named '"
411                     + newName
412                     + "'. Use a different name.");
413         }
414
415         // completely new name, set new name for domain
416
DataMapDefaults pref = eventController.getDataMapPreferences();
417         DataMapEvent e = new DataMapEvent(this, map, map.getName());
418         ProjectUtil.setDataMapName(eventController.getCurrentDataDomain(), map, newName);
419         pref.rename(newName);
420         eventController.fireDataMapEvent(e);
421     }
422
423     void setDataNode() {
424         DataNode node = (DataNode) nodeSelector.getSelectedItem();
425         DataMap map = eventController.getCurrentDataMap();
426
427         // no change?
428
if (node != null && node.getDataMaps().contains(map)) {
429             return;
430         }
431
432         boolean hasChanges = false;
433
434         // unlink map from any nodes
435
Iterator JavaDoc nodes = eventController.getCurrentDataDomain().getDataNodes().iterator();
436
437         while (nodes.hasNext()) {
438             DataNode nextNode = (DataNode) nodes.next();
439
440             // Theoretically only one node may contain a datamap at each given time.
441
// Being paranoid, we will still scan through all.
442
if (nextNode != node && nextNode.getDataMaps().contains(map)) {
443                 nextNode.removeDataMap(map.getName());
444
445                 // announce DataNode change
446
eventController.fireDataNodeEvent(new DataNodeEvent(this, nextNode));
447
448                 hasChanges = true;
449             }
450         }
451
452         // link to a selected node
453
if (node != null) {
454             node.addDataMap(map);
455             hasChanges = true;
456
457             // announce DataNode change
458
eventController.fireDataNodeEvent(new DataNodeEvent(this, node));
459         }
460
461         if (hasChanges) {
462             // TODO: maybe reindexing is an overkill in the modeler?
463
eventController.getCurrentDataDomain().reindexNodes();
464         }
465     }
466
467     void updateDefaultSchema() {
468         DataMap dataMap = eventController.getCurrentDataMap();
469
470         if (dataMap == null) {
471             return;
472         }
473
474         if (dataMap.getDbEntities().size() > 0 || dataMap.getProcedures().size() > 0) {
475             new SchemaUpdateController(eventController, dataMap).startup();
476         }
477     }
478
479     void updateDefaultSuperclass() {
480         DataMap dataMap = eventController.getCurrentDataMap();
481
482         if (dataMap == null) {
483             return;
484         }
485
486         if (dataMap.getObjEntities().size() > 0) {
487             new SuperclassUpdateController(eventController, dataMap).startup();
488         }
489     }
490
491     void updateDefaultPackage() {
492         DataMap dataMap = eventController.getCurrentDataMap();
493
494         if (dataMap == null) {
495             return;
496         }
497
498         if (dataMap.getObjEntities().size() > 0) {
499             new PackageUpdateController(eventController, dataMap).startup();
500         }
501     }
502
503     void updateDefaultLockType() {
504         DataMap dataMap = eventController.getCurrentDataMap();
505
506         if (dataMap == null) {
507             return;
508         }
509
510         if (dataMap.getObjEntities().size() > 0) {
511             int defaultLockType = dataMap.getDefaultLockType();
512
513             Iterator JavaDoc it = dataMap.getObjEntities().iterator();
514             while (it.hasNext()) {
515                 ObjEntity entity = (ObjEntity) it.next();
516                 if (defaultLockType != entity.getDeclaredLockType()) {
517                     entity.setDeclaredLockType(defaultLockType);
518
519                     // any way to batch events, a big change will flood the app with
520
// entity events..?
521
eventController.fireDbEntityEvent(new EntityEvent(this, entity));
522                 }
523             }
524         }
525     }
526 }
Popular Tags