KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > finalist > jaggenerator > modules > Relation


1 /* Copyright (C) 2003 Finalist IT Group
2  *
3  * This file is part of JAG - the Java J2EE Application Generator
4  *
5  * JAG is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  * JAG is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  * You should have received a copy of the GNU General Public License
14  * along with JAG; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  */

17
18 package com.finalist.jaggenerator.modules;
19
20 import com.finalist.jag.util.TemplateString;
21 import com.finalist.jaggenerator.ForeignKey;
22 import com.finalist.jaggenerator.JagGenerator;
23 import com.finalist.jaggenerator.Utils;
24 import org.w3c.dom.Document JavaDoc;
25 import org.w3c.dom.Element JavaDoc;
26 import org.w3c.dom.NodeList JavaDoc;
27
28 import javax.swing.*;
29 import javax.swing.tree.DefaultMutableTreeNode JavaDoc;
30
31
32 /**
33  * This class models a container-managed relation. A Relation maintains three views: a DefaultMutableTreeNode,
34  * an XML view and a Swing JPanel. Unfortunately this class is kind of a Model, View and Controller rolled into one,
35  * but that's just the way JagBeans have been designed...
36  * <p/>
37  * The relation data is initially generated using foreign key information read from a database table (or just
38  * filled in by hand from the GUI).
39  *
40  * @author Michael O'Connor - Finalist IT Group
41  */

42 public class Relation extends DefaultMutableTreeNode JavaDoc implements JagBean {
43
44     private String JavaDoc name = "new relation";
45     private String JavaDoc fieldName;
46     private String JavaDoc targetName;
47     private String JavaDoc foreignTable;
48     private String JavaDoc foreignPkFieldName;
49     private String JavaDoc foreignColumn;
50     private String JavaDoc localColumn;
51     private RelationPanel panelView;
52     private Field fieldObject;
53     private Field foreignPkField;
54     private Entity localEntity;
55     private boolean targetMultiple = true; //not yet implemented
56
private boolean bidirectional = false; //not yet implemented
57

58     /**
59      * Constructs a new Relation from scratch.
60      *
61      * @param localEntity the parent entity bean on the local side of this relation.
62      */

63     public Relation(Entity localEntity) {
64         this.localEntity = localEntity;
65         panelView = new RelationPanel(this, false);
66     }
67
68     /**
69      * Constructs a Relation from a ForeignKey object.
70      *
71      * @param localEntity the parent entity bean on the local side of this relation.
72      * @param fk the foreign key.
73      */

74     public Relation(Entity localEntity, ForeignKey fk) {
75         this(localEntity, fk, true);
76     }
77
78     /**
79      * Constructs a Relation from a ForeignKey object.
80      *
81      * @param localEntity the parent entity bean on the local side of this relation.
82      * @param fk the foreign key.
83      * @param waitForInitSignal if <code>true</code> panel delays initialisation until notified.
84      */

85     public Relation(Entity localEntity, ForeignKey fk, boolean waitForInitSignal) {
86         this.localEntity = localEntity;
87         String JavaDoc thisTable = Utils.format(localEntity.getLocalTableName().toString());
88         String JavaDoc thatTable = Utils.format(fk.getPkTableName());
89         name = thisTable + '-' + thatTable;
90         targetName = thatTable + '-' + thisTable;
91         foreignTable = fk.getPkTableName();
92         fieldName = fk.getFkName() == null ? Utils.format(fk.getFkColumnName()) : fk.getFkName();
93
94         foreignPkFieldName = Utils.format(fk.getPkColumnName());
95         foreignColumn = fk.getPkColumnName();
96         localColumn = fk.getFkColumnName();
97         panelView = new RelationPanel(this, waitForInitSignal);
98
99
100     }
101
102
103     /**
104      * (Re-)Constructs a Relation from an XML element.
105      *
106      * @param localEntity the parent entity bean on the local side of this relation.
107      * @param el the XML element.
108      */

109     public Relation(Entity localEntity, Element JavaDoc el) {
110         this.localEntity = localEntity;
111         NodeList JavaDoc nl = el.getElementsByTagName("module-data");
112
113         for (int i = 0; i < nl.getLength(); i++) {
114             Element JavaDoc child = (Element JavaDoc) nl.item(i);
115             String JavaDoc attName = child.getAttribute("name");
116             String JavaDoc value = null;
117             if (child.getFirstChild() != null) {
118                 value = child.getFirstChild().getNodeValue();
119             }
120             if (value != null) {
121                 if (attName.equalsIgnoreCase("name")) {
122                     name = value;
123                     continue;
124                 }
125                 if (attName.equalsIgnoreCase("field-name")) {
126                     fieldName = Utils.firstToLowerCase(value);
127                     continue;
128                 }
129                 if (attName.equalsIgnoreCase("target-name")) {
130                     targetName = value;
131                     continue;
132                 }
133                 if (attName.equalsIgnoreCase("target-multiple")) {
134                     targetMultiple = "true".equals(value.trim().toLowerCase());
135                     continue;
136                 }
137                 if (attName.equalsIgnoreCase("bidirectional")) {
138                     bidirectional = "true".equals(value.trim().toLowerCase());
139                     continue;
140                 }
141                 if (attName.equalsIgnoreCase("field")) { //for backwards compatibility (pre v.2.3)
142
fieldName = Utils.firstToLowerCase(value);
143                     continue;
144                 }
145                 if (attName.equalsIgnoreCase("foreign-table")) {
146                     foreignTable = value;
147                     continue;
148                 }
149                 if (attName.equalsIgnoreCase("foreign-column")) {
150                     foreignColumn = value;
151                     continue;
152                 }
153                 if (attName.equalsIgnoreCase("local-column")) {
154                     localColumn = value;
155                     continue;
156                 }
157                 if (attName.equalsIgnoreCase("foreign-field")) {
158                     foreignPkFieldName = value;
159                     continue;
160                 }
161             }
162         }
163
164         panelView = new RelationPanel(this, true);
165     }
166
167
168     public String JavaDoc getRefName() {
169         return name;
170     }
171
172     /**
173      * Gets the Swing JPanel view of this relation.
174      *
175      * @return the JPanel.
176      */

177     public JPanel getPanel() {
178         return panelView;
179     }
180
181     /**
182      * Creates the XML view of this relation and appends it as a new child to the specified XML element.
183      *
184      * @param parent the XML element to become parent to this relation child.
185      */

186     public void getXML(Element JavaDoc parent) {
187         Document JavaDoc doc = parent.getOwnerDocument();
188         Element JavaDoc newModule = doc.createElement("module-data");
189         newModule.setAttribute("name", "relation");
190
191         newModule.appendChild(createElement(doc, "name", name));
192         newModule.appendChild(createElement(doc, "field-name", fieldName));
193         newModule.appendChild(createElement(doc, "local-column", localColumn));
194         newModule.appendChild(createElement(doc, "target-name", targetName));
195         newModule.appendChild(createElement(doc, "target-multiple", "" + targetMultiple));
196         newModule.appendChild(createElement(doc, "bidirectional", "" + bidirectional));
197         newModule.appendChild(createElement(doc, "foreign-table", foreignTable));
198         newModule.appendChild(createElement(doc, "foreign-column", foreignColumn));
199         newModule.appendChild(createElement(doc, "foreign-field", foreignPkFieldName));
200
201         parent.appendChild(newModule);
202     }
203
204     /**
205      * Gets 'name' : the name of this relation.
206      *
207      * @return name
208      */

209     public String JavaDoc getName() {
210         return name;
211     }
212
213     public void setName(String JavaDoc name) {
214         this.name = name;
215         panelView.setName(name);
216     }
217
218     /**
219      * Gets the name of the imported foreign key field in the parent entity bean on the 'local' side of this relation.
220      *
221      * @return field
222      */

223     public TemplateString getFieldName() {
224         return new TemplateString(fieldName);
225     }
226
227     public void setFieldName(String JavaDoc fieldName) {
228         this.fieldName = Utils.firstToLowerCase(fieldName);
229     }
230
231     /**
232      * Gets 'targetName' : the name given to the reciprocal end of this relation (if it is bidirectional).
233      *
234      * @return targetName
235      */

236     public String JavaDoc getTargetName() {
237         return targetName;
238     }
239
240     public void setTargetName(String JavaDoc targetName) {
241         this.targetName = targetName;
242     }
243
244     /**
245      * Gets 'targetMultiple' : whether or not this relation maps to multiple entities at the 'foreign' end.
246      *
247      * @return targetMultiple
248      */

249     public boolean isTargetMultiple() {
250         return targetMultiple;
251     }
252
253     public void setTargetMultiple(boolean targetMultiple) {
254         this.targetMultiple = targetMultiple;
255     }
256
257     /**
258      * Gets 'bidirectional' : whether or not this relation is also navigable the other way round.
259      *
260      * @return bidirectional
261      */

262     public boolean isBidirectional() {
263         return bidirectional;
264     }
265
266     public void setBidirectional(boolean bidirectional) {
267         this.bidirectional = bidirectional;
268     }
269
270     /**
271      * Gets 'foreignTable' : the name of the table at the other end of the relation.
272      *
273      * @return foreignTable
274      */

275     public String JavaDoc getForeignTable() {
276         return foreignTable;
277     }
278
279     public void setForeignTable(String JavaDoc foreignTable) {
280         this.foreignTable = foreignTable;
281     }
282
283     /**
284      * Gets the name of the exported primary key field at the other end of the relation.
285      *
286      * @return foreignPkFieldName
287      */

288     public TemplateString getForeignPkFieldName() {
289         return new TemplateString(foreignPkFieldName);
290     }
291
292     public void setForeignPkFieldName(String JavaDoc foreignField) {
293         this.foreignPkFieldName = foreignField;
294     }
295
296     public Field getForeignPkField() {
297         return foreignPkField;
298     }
299
300     public void setForeignPkField(Field foreignPkField) {
301         this.foreignPkField = foreignPkField;
302     }
303
304     /**
305      * Gets 'foreignColumn' : the name of the primary key column at the other end of the relation.
306      *
307      * @return foreignTable
308      */

309     public String JavaDoc getForeignColumn() {
310         return foreignColumn;
311     }
312
313     public void setForeignColumn(String JavaDoc foreignColumn) {
314         this.foreignColumn = foreignColumn;
315     }
316
317     /**
318      * Gets 'localColumn' : the name of the column at the local end of the relation.
319      *
320      * @return String with local column.
321      */

322     public String JavaDoc getLocalColumn() {
323         return localColumn;
324     }
325
326     public void setLocalColumn(String JavaDoc localColumn) {
327         this.localColumn = localColumn;
328     }
329
330     /**
331      * Gets the Entity object that this Relation relates to.
332      *
333      * @return Entity
334      */

335     public Entity getRelatedEntity() {
336         return JagGenerator.getEntityByTableName(foreignTable);
337     }
338
339     /**
340      * The relation is a many to many relation if the related entity is an assocation table.
341      *
342      * @return string with 'true' if the relation is a many to many relation. 'false' if not.
343      */

344     public String JavaDoc isManyToManyRelation() {
345         return getRelatedEntity().getIsAssociationEntity();
346     }
347
348     public String JavaDoc toString() {
349         return name; // the name used to display this relation in the tree view.
350
}
351
352     public void setFkField(Field field) {
353         fieldObject = field;
354     }
355
356     public Field getFkField() {
357         return fieldObject;
358     }
359
360     public Entity getLocalEntity() {
361         return localEntity;
362     }
363
364     /**
365      * RelationPanels can't finish initialising themselves until the local-side entity is completely generated
366      * (until all the entity's fields are generated). Call this method to wake up the sleeping initialisers.
367      */

368     public void notifyLocalEntityIsComplete() {
369         synchronized (panelView) {
370             panelView.notifyAll();
371         }
372     }
373
374
375     public void notifyFieldNameChanged(String JavaDoc oldName, String JavaDoc text) {
376         panelView.updateFieldName(oldName, text);
377     }
378
379     private Element JavaDoc createElement(Document JavaDoc doc, String JavaDoc name, String JavaDoc value) {
380         Element JavaDoc newElement = doc.createElement("module-data");
381         newElement.setAttribute("name", name);
382         if (value != null) {
383             newElement.appendChild(doc.createTextNode(value));
384         }
385         return newElement;
386    }
387
388 }
Popular Tags