KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectstyle > cayenne > modeler > editor > datanode > DataNodeEditor


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.datanode;
57
58 import java.awt.Component JavaDoc;
59 import java.awt.event.ComponentAdapter JavaDoc;
60 import java.awt.event.ComponentEvent JavaDoc;
61 import java.util.Collection JavaDoc;
62 import java.util.HashMap JavaDoc;
63 import java.util.Iterator JavaDoc;
64 import java.util.Map JavaDoc;
65
66 import javax.swing.DefaultComboBoxModel JavaDoc;
67
68 import org.objectstyle.cayenne.access.DataDomain;
69 import org.objectstyle.cayenne.access.DataNode;
70 import org.objectstyle.cayenne.conf.Configuration;
71 import org.objectstyle.cayenne.conf.DBCPDataSourceFactory;
72 import org.objectstyle.cayenne.conf.DriverDataSourceFactory;
73 import org.objectstyle.cayenne.conf.JNDIDataSourceFactory;
74 import org.objectstyle.cayenne.dba.DbAdapter;
75 import org.objectstyle.cayenne.dba.JdbcAdapter;
76 import org.objectstyle.cayenne.map.event.DataNodeEvent;
77 import org.objectstyle.cayenne.modeler.ProjectController;
78 import org.objectstyle.cayenne.modeler.dialog.pref.PreferenceDialog;
79 import org.objectstyle.cayenne.modeler.event.DataNodeDisplayEvent;
80 import org.objectstyle.cayenne.modeler.event.DataNodeDisplayListener;
81 import org.objectstyle.cayenne.modeler.pref.DBConnectionInfo;
82 import org.objectstyle.cayenne.modeler.util.CayenneController;
83 import org.objectstyle.cayenne.modeler.util.DbAdapterInfo;
84 import org.objectstyle.cayenne.modeler.util.ProjectUtil;
85 import org.objectstyle.cayenne.project.ApplicationProject;
86 import org.objectstyle.cayenne.swing.BindingBuilder;
87 import org.objectstyle.cayenne.swing.BindingDelegate;
88 import org.objectstyle.cayenne.swing.ObjectBinding;
89 import org.objectstyle.cayenne.validation.ValidationException;
90
91 /**
92  * @author Andrei Adamchik
93  */

94 public class DataNodeEditor extends CayenneController {
95
96     protected static final String JavaDoc NO_LOCAL_DATA_SOURCE = "Select DataSource for Local Work...";
97
98     final static String JavaDoc[] standardDataSourceFactories = new String JavaDoc[] {
99             DriverDataSourceFactory.class.getName(),
100             JNDIDataSourceFactory.class.getName(), DBCPDataSourceFactory.class.getName()
101     };
102
103     protected DataNodeView view;
104     protected DataNode node;
105     protected Map JavaDoc datasourceEditors;
106
107     protected Map JavaDoc localDataSources;
108
109     protected DataSourceEditor defaultSubeditor;
110
111     protected BindingDelegate nodeChangeProcessor;
112     protected ObjectBinding[] bindings;
113     protected ObjectBinding localDataSourceBinding;
114
115     public DataNodeEditor(ProjectController parent) {
116         super(parent);
117
118         this.datasourceEditors = new HashMap JavaDoc();
119         this.view = new DataNodeView();
120         this.localDataSources = new HashMap JavaDoc();
121
122         this.nodeChangeProcessor = new BindingDelegate() {
123
124             public void modelUpdated(
125                     ObjectBinding binding,
126                     Object JavaDoc oldValue,
127                     Object JavaDoc newValue) {
128
129                 DataNodeEvent e = new DataNodeEvent(DataNodeEditor.this, node);
130                 if (binding != null && binding.getView() == view.getDataNodeName()) {
131                     e.setOldName(oldValue != null ? oldValue.toString() : null);
132                 }
133
134                 ((ProjectController) getParent()).fireDataNodeEvent(e);
135             }
136         };
137
138         this.defaultSubeditor = new CustomDataSourceEditor(parent, nodeChangeProcessor);
139
140         initController();
141     }
142
143     // ======= properties
144

145     public Component JavaDoc getView() {
146         return view;
147     }
148
149     public DataNode getNode() {
150         return node;
151     }
152
153     public void setNode(DataNode node) {
154         this.node = node;
155     }
156
157     public String JavaDoc getAdapterName() {
158         // fix no adapter case... does it ever happen now? (it used to when an empty
159
// string
160
// was typed)
161
if (node != null && node.getAdapter() == null) {
162             node.setAdapter(new JdbcAdapter());
163         }
164
165         return (node != null) ? node.getAdapter().getClass().getName() : null;
166     }
167
168     public void setAdapterName(String JavaDoc name) {
169         if (node == null) {
170             return;
171         }
172
173         if (name == null) {
174             // simply ignore null name
175
return;
176         }
177
178         try {
179             Class JavaDoc adapterClass = getApplication()
180                     .getClassLoadingService()
181                     .loadClass(name);
182             node.setAdapter((DbAdapter) adapterClass.newInstance());
183         }
184         catch (Throwable JavaDoc ex) {
185             throw new ValidationException("Unknown DbAdapter: " + name);
186         }
187     }
188
189     public String JavaDoc getFactoryName() {
190         return (node != null) ? node.getDataSourceFactory() : null;
191     }
192
193     public void setFactoryName(String JavaDoc factoryName) {
194         if (node != null) {
195             node.setDataSourceFactory(factoryName);
196             showDataSourceSubview(factoryName);
197         }
198     }
199
200     public String JavaDoc getNodeName() {
201         return (node != null) ? node.getName() : null;
202     }
203
204     public void setNodeName(String JavaDoc newName) {
205         if (node == null) {
206             return;
207         }
208
209         // validate...
210
if (newName == null) {
211             throw new ValidationException("Empty DataNode Name");
212         }
213
214         ProjectController parent = (ProjectController) getParent();
215         Configuration config = ((ApplicationProject) parent.getProject())
216                 .getConfiguration();
217
218         DataNode matchingNode = null;
219
220         Iterator JavaDoc it = config.getDomains().iterator();
221         while (it.hasNext()) {
222             DataDomain domain = (DataDomain) it.next();
223             DataNode nextNode = domain.getNode(newName);
224
225             if (nextNode == node) {
226                 continue;
227             }
228
229             if (nextNode != null) {
230                 matchingNode = nextNode;
231                 break;
232             }
233         }
234
235         if (matchingNode != null) {
236             // there is an entity with the same name
237
throw new ValidationException("There is another DataNode named '"
238                     + newName
239                     + "'. Use a different name.");
240         }
241
242         // passed validation, set value...
243

244         // TODO: fixme....there is a slight chance that domain is different than the one
245
// cached node belongs to
246
ProjectUtil.setDataNodeName(parent.getCurrentDataDomain(), node, newName);
247     }
248
249     // ======== other stuff
250

251     protected void initController() {
252         view.getDataSourceDetail().add(defaultSubeditor.getView(), "default");
253
254         view.getAdapters().setEditable(true);
255         view.getFactories().setEditable(true);
256
257         // init combo box choices
258
view.getAdapters().setModel(
259                 new DefaultComboBoxModel JavaDoc(DbAdapterInfo.getStandardAdapters()));
260         view.getFactories().setModel(
261                 new DefaultComboBoxModel JavaDoc(standardDataSourceFactories));
262
263         // init listeners
264
((ProjectController) getParent())
265                 .addDataNodeDisplayListener(new DataNodeDisplayListener() {
266
267                     public void currentDataNodeChanged(DataNodeDisplayEvent e) {
268                         refreshView(e.getDataNode());
269                     }
270                 });
271
272         getView().addComponentListener(new ComponentAdapter JavaDoc() {
273
274             public void componentShown(ComponentEvent JavaDoc e) {
275                 refreshView(getNode() != null
276                         ? getNode()
277                         : ((ProjectController) getParent()).getCurrentDataNode());
278             }
279         });
280
281         BindingBuilder builder = new BindingBuilder(
282                 getApplication().getBindingFactory(),
283                 this);
284
285         localDataSourceBinding = builder.bindToComboSelection(
286                 view.getLocalDataSources(),
287                 "parent.dataNodePreferences.localDataSource",
288                 NO_LOCAL_DATA_SOURCE);
289
290         // use delegate for the rest of them
291

292         builder.setDelegate(nodeChangeProcessor);
293
294         bindings = new ObjectBinding[3];
295         bindings[0] = builder.bindToTextField(view.getDataNodeName(), "nodeName");
296         bindings[1] = builder.bindToComboSelection(view.getFactories(), "factoryName");
297         bindings[2] = builder.bindToComboSelection(view.getAdapters(), "adapterName");
298
299         // one way bindings
300
builder
301                 .bindToAction(
302                         view.getConfigLocalDataSources(),
303                         "dataSourceConfigAction()");
304     }
305
306     public void dataSourceConfigAction() {
307         PreferenceDialog prefs = new PreferenceDialog(this);
308         prefs.showDataSourceEditorAction(view.getLocalDataSources().getSelectedItem());
309         prefs.startupAction();
310
311         refreshLocalDataSources();
312     }
313
314     protected void refreshLocalDataSources() {
315         localDataSources.clear();
316
317         Collection JavaDoc sources = getApplication().getPreferenceDomain().getDetails(
318                 DBConnectionInfo.class);
319
320         int len = sources.size();
321         Object JavaDoc[] keys = new Object JavaDoc[len + 1];
322
323         // a slight chance that a real datasource is called NO_LOCAL_DATA_SOURCE...
324
keys[0] = NO_LOCAL_DATA_SOURCE;
325         Iterator JavaDoc it = sources.iterator();
326         for (int i = 1; i <= len; i++) {
327             DBConnectionInfo info = (DBConnectionInfo) it.next();
328             keys[i] = info.getKey();
329             localDataSources.put(keys[i], info);
330         }
331
332         view.getLocalDataSources().setModel(new DefaultComboBoxModel JavaDoc(keys));
333         localDataSourceBinding.updateView();
334     }
335
336     /**
337      * Reinitializes widgets to display selected DataNode.
338      */

339     protected void refreshView(DataNode node) {
340         this.node = node;
341
342         if (node == null) {
343             getView().setVisible(false);
344             return;
345         }
346
347         refreshLocalDataSources();
348
349         getView().setVisible(true);
350         for (int i = 0; i < bindings.length; i++) {
351             bindings[i].updateView();
352         }
353
354         showDataSourceSubview(getFactoryName());
355     }
356
357     /**
358      * Selects a subview for a currently selected DataSource factory.
359      */

360     protected void showDataSourceSubview(String JavaDoc factoryName) {
361         DataSourceEditor c = (DataSourceEditor) datasourceEditors.get(factoryName);
362
363         // create subview dynamically...
364
if (c == null) {
365
366             if (DriverDataSourceFactory.class.getName().equals(factoryName)) {
367                 c = new JDBCDataSourceEditor(
368                         (ProjectController) getParent(),
369                         nodeChangeProcessor);
370             }
371             else if (JNDIDataSourceFactory.class.getName().equals(factoryName)) {
372                 c = new JNDIDataSourceEditor(
373                         (ProjectController) getParent(),
374                         nodeChangeProcessor);
375             }
376             else if (DBCPDataSourceFactory.class.getName().equals(factoryName)) {
377                 c = new DBCPDataSourceEditor(
378                         (ProjectController) getParent(),
379                         nodeChangeProcessor);
380             }
381             else {
382                 // special case - no detail view, just show it and bail..
383
defaultSubeditor.setNode(getNode());
384                 view.getDataSourceDetailLayout().show(
385                         view.getDataSourceDetail(),
386                         "default");
387                 return;
388             }
389
390             datasourceEditors.put(factoryName, c);
391             view.getDataSourceDetail().add(c.getView(), factoryName);
392
393             // this is needed to display freshly added panel...
394
view.getDataSourceDetail().getParent().validate();
395         }
396
397         // this will refresh subview...
398
c.setNode(getNode());
399
400         // display the right subview...
401
view.getDataSourceDetailLayout().show(view.getDataSourceDetail(), factoryName);
402     }
403
404 }
Popular Tags