KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectstyle > cayenne > modeler > action > ImportEOModelAction


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
57 package org.objectstyle.cayenne.modeler.action;
58
59 import java.awt.Component JavaDoc;
60 import java.awt.HeadlessException JavaDoc;
61 import java.awt.event.ActionEvent JavaDoc;
62 import java.io.File JavaDoc;
63 import java.util.ArrayList JavaDoc;
64 import java.util.Collection JavaDoc;
65 import java.util.Iterator JavaDoc;
66 import java.util.Map JavaDoc;
67
68 import javax.swing.JDialog JavaDoc;
69 import javax.swing.JFileChooser JavaDoc;
70 import javax.swing.filechooser.FileFilter JavaDoc;
71
72 import org.apache.commons.collections.CollectionUtils;
73 import org.apache.log4j.Level;
74 import org.apache.log4j.Logger;
75 import org.objectstyle.cayenne.access.DataDomain;
76 import org.objectstyle.cayenne.access.DataNode;
77 import org.objectstyle.cayenne.conf.DriverDataSourceFactory;
78 import org.objectstyle.cayenne.conf.JNDIDataSourceFactory;
79 import org.objectstyle.cayenne.conn.DataSourceInfo;
80 import org.objectstyle.cayenne.dba.DbAdapter;
81 import org.objectstyle.cayenne.map.DataMap;
82 import org.objectstyle.cayenne.map.Entity;
83 import org.objectstyle.cayenne.map.event.DataNodeEvent;
84 import org.objectstyle.cayenne.map.event.EntityEvent;
85 import org.objectstyle.cayenne.query.Query;
86 import org.objectstyle.cayenne.map.event.QueryEvent;
87 import org.objectstyle.cayenne.modeler.AdapterMapping;
88 import org.objectstyle.cayenne.modeler.Application;
89 import org.objectstyle.cayenne.modeler.ProjectController;
90 import org.objectstyle.cayenne.modeler.dialog.ErrorDebugDialog;
91 import org.objectstyle.cayenne.modeler.event.DataMapDisplayEvent;
92 import org.objectstyle.cayenne.modeler.event.DataNodeDisplayEvent;
93 import org.objectstyle.cayenne.modeler.pref.FSPath;
94 import org.objectstyle.cayenne.modeler.util.CayenneAction;
95 import org.objectstyle.cayenne.modeler.util.FileFilters;
96 import org.objectstyle.cayenne.project.NamedObjectFactory;
97 import org.objectstyle.cayenne.project.ProjectDataSource;
98 import org.objectstyle.cayenne.project.ProjectPath;
99 import org.objectstyle.cayenne.wocompat.EOModelProcessor;
100
101 /**
102  * Action handler for WebObjects EOModel import function.
103  *
104  * @author Andrei Adamchik
105  */

106 public class ImportEOModelAction extends CayenneAction {
107
108     private static final Logger logObj = Logger.getLogger(ImportEOModelAction.class);
109
110     public static String JavaDoc getActionName() {
111         return "Import EOModel";
112     }
113
114     protected JFileChooser JavaDoc eoModelChooser;
115
116     public ImportEOModelAction(Application application) {
117         super(getActionName(), application);
118     }
119     
120     public String JavaDoc getIconName() {
121         return "icon-eomodel.gif";
122     }
123
124     public void performAction(ActionEvent JavaDoc event) {
125         importEOModel();
126     }
127
128     /**
129      * Allows user to select an EOModel, then imports it as a DataMap.
130      */

131     protected void importEOModel() {
132         JFileChooser JavaDoc fileChooser = getEOModelChooser();
133         int status = fileChooser.showOpenDialog(Application.getFrame());
134
135         if (status == JFileChooser.APPROVE_OPTION) {
136
137             // save preferences
138
FSPath lastDir = getApplication()
139                     .getFrameController()
140                     .getLastEOModelDirectory();
141             lastDir.updateFromChooser(fileChooser);
142
143             File JavaDoc file = fileChooser.getSelectedFile();
144             if (file.isFile()) {
145                 file = file.getParentFile();
146             }
147
148             DataMap currentMap = getProjectController().getCurrentDataMap();
149
150             try {
151                 String JavaDoc path = file.getCanonicalPath();
152
153                 EOModelProcessor processor = new EOModelProcessor();
154
155                 // load DataNode if we are not merging with an existing map
156
if (currentMap == null) {
157                     loadDataNode(processor.loadModeIndex(path));
158                 }
159
160                 // load DataMap
161
DataMap map = processor.loadEOModel(path);
162                 addDataMap(map, currentMap);
163
164             }
165             catch (Exception JavaDoc ex) {
166                 logObj.log(Level.INFO, "EOModel Loading Exception", ex);
167                 ErrorDebugDialog.guiException(ex);
168             }
169
170         }
171     }
172
173     protected void loadDataNode(Map JavaDoc eomodelIndex) {
174         // if this is JDBC or JNDI node and connection dictionary is specified, load a
175
// DataNode, otherwise ignore it (meaning that pre 5.* EOModels will not have a
176
// node).
177

178         String JavaDoc adapter = (String JavaDoc) eomodelIndex.get("adaptorName");
179         Map JavaDoc connection = (Map JavaDoc) eomodelIndex.get("connectionDictionary");
180
181         if (adapter != null && connection != null) {
182             CreateNodeAction nodeBuilder = (CreateNodeAction) getApplication().getAction(
183                     CreateNodeAction.getActionName());
184
185             // this should make created node current, resulting in the new map being added
186
// to the node automatically once it is loaded
187
DataNode node = nodeBuilder.buildDataNode();
188
189             // configure node...
190
if ("JNDI".equalsIgnoreCase(adapter)) {
191                 node.setDataSourceFactory(JNDIDataSourceFactory.class.getName());
192                 node.setDataSourceLocation((String JavaDoc) connection.get("serverUrl"));
193             }
194             else {
195                 // guess adapter from plugin or driver
196
AdapterMapping adapterDefaults = getApplication().getAdapterMapping();
197                 String JavaDoc cayenneAdapter = adapterDefaults.adapterForEOFPluginOrDriver(
198                         (String JavaDoc) connection.get("plugin"),
199                         (String JavaDoc) connection.get("driver"));
200                 if (cayenneAdapter != null) {
201                     try {
202                         Class JavaDoc adapterClass = getApplication()
203                                 .getClassLoadingService()
204                                 .loadClass(cayenneAdapter);
205                         node.setAdapter((DbAdapter) adapterClass.newInstance());
206                     }
207                     catch (Throwable JavaDoc ex) {
208                         // ignore...
209
}
210                 }
211
212                 node.setDataSourceFactory(DriverDataSourceFactory.class.getName());
213
214                 DataSourceInfo dsi = ((ProjectDataSource) node.getDataSource())
215                         .getDataSourceInfo();
216                 
217                 
218                 
219                 dsi.setDataSourceUrl(keyAsString(connection, "URL"));
220                 dsi.setJdbcDriver(keyAsString(connection, "driver"));
221                 dsi.setPassword(keyAsString(connection, "password"));
222                 dsi.setUserName(keyAsString(connection, "username"));
223             }
224
225             // send events after the node creation is complete
226
getProjectController().fireDataNodeEvent(
227                     new DataNodeEvent(this, node, DataNodeEvent.ADD));
228             getProjectController().fireDataNodeDisplayEvent(
229                     new DataNodeDisplayEvent(this, getProjectController()
230                             .getCurrentDataDomain(), node));
231         }
232     }
233     
234     // CAY-246 - if user name or password is all numeric, it will
235
// be returned as number, so we can't cast dictionary keys to String
236
private String JavaDoc keyAsString(Map JavaDoc map, String JavaDoc key) {
237         Object JavaDoc value = map.get(key);
238         return (value != null) ? value.toString() : null;
239     }
240
241     /**
242      * Returns <code>true</code> if path contains a DataDomain object.
243      */

244     public boolean enableForPath(ProjectPath path) {
245         if (path == null) {
246             return false;
247         }
248
249         return path.firstInstanceOf(DataDomain.class) != null;
250     }
251
252     /**
253      * Adds DataMap into the project.
254      */

255     protected void addDataMap(DataMap map, DataMap currentMap) {
256
257         ProjectController mediator = getProjectController();
258
259         if (currentMap != null) {
260             // merge with existing map... have to memorize map state before and after
261
// to do the right events
262

263             Collection JavaDoc originalOE = new ArrayList JavaDoc(currentMap.getObjEntities());
264             Collection JavaDoc originalDE = new ArrayList JavaDoc(currentMap.getDbEntities());
265             Collection JavaDoc originalQueries = new ArrayList JavaDoc(currentMap.getQueries());
266
267             currentMap.mergeWithDataMap(map);
268             map = currentMap;
269
270             // postprocess changes
271
Collection JavaDoc newOE = new ArrayList JavaDoc(currentMap.getObjEntities());
272             Collection JavaDoc newDE = new ArrayList JavaDoc(currentMap.getDbEntities());
273             Collection JavaDoc newQueries = new ArrayList JavaDoc(currentMap.getQueries());
274
275             EntityEvent entityEvent = new EntityEvent(Application.getFrame(), null);
276             QueryEvent queryEvent = new QueryEvent(Application.getFrame(), null);
277
278             Collection JavaDoc addedOE = CollectionUtils.subtract(newOE, originalOE);
279             Iterator JavaDoc it = addedOE.iterator();
280             while (it.hasNext()) {
281                 Entity e = (Entity) it.next();
282                 entityEvent.setEntity(e);
283                 entityEvent.setId(EntityEvent.ADD);
284                 mediator.fireObjEntityEvent(entityEvent);
285             }
286
287             Collection JavaDoc removedOE = CollectionUtils.subtract(originalOE, newOE);
288             it = removedOE.iterator();
289             while (it.hasNext()) {
290                 Entity e = (Entity) it.next();
291                 entityEvent.setEntity(e);
292                 entityEvent.setId(EntityEvent.REMOVE);
293                 mediator.fireObjEntityEvent(entityEvent);
294             }
295
296             Collection JavaDoc addedDE = CollectionUtils.subtract(newDE, originalDE);
297             it = addedDE.iterator();
298             while (it.hasNext()) {
299                 Entity e = (Entity) it.next();
300                 entityEvent.setEntity(e);
301                 entityEvent.setId(EntityEvent.ADD);
302                 mediator.fireDbEntityEvent(entityEvent);
303             }
304
305             Collection JavaDoc removedDE = CollectionUtils.subtract(originalDE, newDE);
306             it = removedDE.iterator();
307             while (it.hasNext()) {
308                 Entity e = (Entity) it.next();
309                 entityEvent.setEntity(e);
310                 entityEvent.setId(EntityEvent.REMOVE);
311                 mediator.fireDbEntityEvent(entityEvent);
312             }
313             
314             // queries
315
Collection JavaDoc addedQueries = CollectionUtils.subtract(newQueries, originalQueries);
316             it = addedQueries.iterator();
317             while (it.hasNext()) {
318                 Query q = (Query) it.next();
319                 queryEvent.setQuery(q);
320                 queryEvent.setId(QueryEvent.ADD);
321                 mediator.fireQueryEvent(queryEvent);
322             }
323
324             Collection JavaDoc removedQueries = CollectionUtils.subtract(originalQueries, newQueries);
325             it = removedQueries.iterator();
326             while (it.hasNext()) {
327                 Query q = (Query) it.next();
328                 queryEvent.setQuery(q);
329                 queryEvent.setId(QueryEvent.REMOVE);
330                 mediator.fireQueryEvent(queryEvent);
331             }
332
333             mediator.fireDataMapDisplayEvent(new DataMapDisplayEvent(Application
334                     .getFrame(), map, mediator.getCurrentDataDomain(), mediator
335                     .getCurrentDataNode()));
336         }
337         else {
338             // fix DataMap name, as there maybe a map with the same name already
339
DataDomain domain = mediator.getCurrentDataDomain();
340             map.setName(NamedObjectFactory.createName(DataMap.class, domain, map
341                     .getName()));
342
343             // side effect of this operation is that if a node was created, this DataMap
344
// will be linked with it...
345
mediator.addDataMap(Application.getFrame(), map);
346         }
347     }
348
349     /**
350      * Returns EOModel chooser.
351      */

352     public JFileChooser JavaDoc getEOModelChooser() {
353
354         if (eoModelChooser == null) {
355             eoModelChooser = new EOModelChooser("Select EOModel");
356         }
357
358         FSPath lastDir = getApplication().getFrameController().getLastEOModelDirectory();
359         lastDir.updateChooser(eoModelChooser);
360
361         return eoModelChooser;
362     }
363
364     /**
365      * Custom file chooser that will pop up again if a bad directory is selected.
366      */

367     class EOModelChooser extends JFileChooser JavaDoc {
368
369         protected FileFilter JavaDoc selectFilter;
370         protected JDialog JavaDoc cachedDialog;
371
372         public EOModelChooser(String JavaDoc title) {
373             super.setFileFilter(FileFilters.getEOModelFilter());
374             super.setDialogTitle(title);
375             super.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
376
377             this.selectFilter = FileFilters.getEOModelSelectFilter();
378         }
379
380         public int showOpenDialog(Component JavaDoc parent) {
381             int status = super.showOpenDialog(parent);
382             if (status != JFileChooser.APPROVE_OPTION) {
383                 cachedDialog = null;
384                 return status;
385             }
386
387             // make sure invalid directory is not selected
388
File JavaDoc file = this.getSelectedFile();
389             if (selectFilter.accept(file)) {
390                 cachedDialog = null;
391                 return JFileChooser.APPROVE_OPTION;
392             }
393             else {
394                 if (file.isDirectory()) {
395                     this.setCurrentDirectory(file);
396                 }
397
398                 return this.showOpenDialog(parent);
399             }
400         }
401
402         protected JDialog JavaDoc createDialog(Component JavaDoc parent) throws HeadlessException JavaDoc {
403
404             if (cachedDialog == null) {
405                 cachedDialog = super.createDialog(parent);
406             }
407             return cachedDialog;
408         }
409     }
410 }
Popular Tags