View Javadoc

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.jaggenerator.*;
21  import com.finalist.jag.util.TemplateString;
22  
23  import javax.swing.*;
24  import java.util.Iterator;
25  import java.util.List;
26  import java.util.ArrayList;
27  
28  /***
29   *
30   * @author  m.oconnor, r. ekkelenkamp
31   */
32  public class RelationPanel extends javax.swing.JPanel {
33     private static final String ONE_TO_ONE = "one to one";
34     private static final String ONE_TO_MANY = "one to many";
35     private static final String MANY_TO_ONE = "many to one";   
36     private Relation model;
37     private boolean constructed = false;
38  
39     /***
40      * Creates new form RelationPanel
41      *
42      * @param relation The Relation that this object views.
43      * @param waitForInitSignal if <code>true</code> delay initialisation until notified.
44      */
45     public RelationPanel(Relation relation, final boolean waitForInitSignal) {
46        model = relation;
47        initComponents();
48        if (waitForInitSignal) {
49           new Thread("RelationPanel(" + model.getName() + ")") {
50              public void run() {
51                 initValues(true);
52              }
53           }.start();
54        } else {
55           initValues(false);
56        }
57     }
58  
59     public void initValues(boolean waitForInitSignal) {
60        constructed = false;
61        final boolean initFromXML = !JagGenerator.isDatabaseConnected();
62        nameField.setText(model.getName());
63  
64        //init list of selected tables (excluding local table)
65        foreignTableCombo.removeAllItems();
66        List tableList = null;
67        if (initFromXML) {
68           tableList = new ArrayList();
69           tableList.add(model.getForeignTable());
70           foreignTableCombo.setEditable(true);
71        } else {
72           foreignTableCombo.setEditable(false);
73           tableList = DatabaseUtils.getTables();
74        }
75  
76        Iterator tables = tableList.iterator();
77        while (tables.hasNext()) {
78           String tableName = (String) tables.next();
79           TemplateString localTableName = model.getLocalEntity().getLocalTableName();
80           if (tableName != null && localTableName != null &&  !tableName.equals(localTableName.toString())) {
81              foreignTableCombo.addItem(tableName);
82           }
83        }
84        foreignTableCombo.setSelectedItem(model.getForeignTable());
85  
86        initColumnsList();
87  
88        //cardinalityCombo.addItem(ONE_TO_ONE);
89        cardinalityCombo.addItem(MANY_TO_ONE);
90        cardinalityCombo.setSelectedItem(MANY_TO_ONE);
91        /*
92         * Currently only Many to one is supported.
93        if (model.isTargetMultiple()) {
94           cardinalityCombo.setSelectedItem(MANY_TO_ONE);
95        } else {
96           cardinalityCombo.setSelectedItem(ONE_TO_ONE);
97        }
98         */
99        if (model.isBidirectional()) {
100          bidirectionalCheckbox.setSelected(true);
101       } else {
102          bidirectionalCheckbox.setSelected(false);         
103       }
104 
105       if (waitForInitSignal) {
106          synchronized(this) {
107             try {
108                //wait for the local-side entity to finish being constructed before finishing off..
109                wait();
110                updateFieldsCombo();
111 
112             } catch (InterruptedException e) {
113                e.printStackTrace();
114             }
115          }
116       } else {
117          updateFieldsCombo();
118       }
119 
120       //initially the field referred to by this relation might not be aware it's a foreign key - make it so..
121       Iterator parentFields = model.getLocalEntity().getFields().iterator();
122       while (parentFields.hasNext()) {
123          Field field = (Field) parentFields.next();
124          if (field.getName().toString().equals(fkFieldCombo.getSelectedItem())) {
125             field.setForeignKey(true);
126          }
127       }
128 
129       constructed = true;
130    }
131 
132 
133    /***
134     * Sometimes it is necessary to force an update of the relation name in the view
135     * from the model.  This method does that!
136     * @param relationName the new name.
137     */
138    public void setName(String relationName) {
139       nameField.setText(relationName);
140    }
141 
142    public void updateFieldName(String oldName, String newName) {
143       Object selected = fkFieldCombo.getSelectedItem();
144       ArrayList contents = new ArrayList();
145       for (int i = 0; i < fkFieldCombo.getModel().getSize(); i++) {
146          Object field = fkFieldCombo.getModel().getElementAt(i);
147          if (field.equals(oldName)) {
148             contents.add(newName);
149             if (selected.equals(field)) {
150                selected = newName;
151             }
152          } else {
153             contents.add(field);
154          }
155       }
156 
157       fkFieldCombo.removeAllItems();
158       Iterator newList = contents.iterator();
159       while (newList.hasNext()) {
160          Object o = newList.next();
161          fkFieldCombo.addItem(o);
162       }
163       fkFieldCombo.setSelectedItem(selected);
164    }
165 
166    private void updateFieldsCombo() {
167       //init list of fields from local entity bean
168       fkFieldCombo.removeAllItems();
169       Iterator fields = model.getLocalEntity().getFields().iterator();
170       while (fields.hasNext()) {
171          Field field = (Field) fields.next();
172          fkFieldCombo.addItem(field.getName().toString());
173          if (field.getName().equals(model.getFieldName())) {
174             fkFieldCombo.setSelectedItem(field.getName().toString());
175          }
176       }
177    }
178 
179    private void initColumnsList() {
180       foreignPkCombo.removeAllItems();
181       String selectedTable = (String) foreignTableCombo.getSelectedItem();
182       List columnsList = null;
183       if (JagGenerator.isDatabaseConnected()) {
184          columnsList = DatabaseUtils.getColumns(selectedTable);
185       }
186       if (columnsList == null || columnsList.isEmpty()) {
187          foreignPkCombo.addItem(model.getForeignColumn());
188          foreignPkCombo.setEditable(true);
189       } else {
190          foreignPkCombo.setEditable(false);
191          Iterator columns = columnsList.iterator();
192          while (columns.hasNext()) {
193             Column column = (Column) columns.next();
194             foreignPkCombo.addItem(column.getName());
195             if (column.isPrimaryKey()) {
196                foreignPkCombo.setSelectedItem(column.getName());
197             }
198          }
199       }
200    }
201 
202    private void formPropertyChange() {
203       if (constructed) {
204          model.setName(nameField.getText());
205          String oldFkField = model.getFieldName().toString();
206          String newFkField = getTextFromJComboBox(fkFieldCombo);
207          model.setFieldName(newFkField);
208          if (oldFkField != null && !oldFkField.equals(newFkField)) {
209             JagGenerator.setForeignKeyInField(model.getLocalEntity().getLocalTableName().toString(), newFkField);
210          }
211          model.setForeignTable(getTextFromJComboBox(foreignTableCombo));
212          model.setForeignColumn(getTextFromJComboBox(foreignPkCombo));
213          model.setForeignPkFieldName(Utils.format(getTextFromJComboBox(foreignPkCombo)));
214          model.setTargetMultiple(MANY_TO_ONE.equals(getTextFromJComboBox(cardinalityCombo)));
215          model.setBidirectional(bidirectionalCheckbox.getSelectedObjects() != null);
216       }
217       JagGenerator.stateChanged(false);
218    }
219 
220 
221    /*** This method is called from within the constructor to
222     * initialize the form.
223     * WARNING: Do NOT modify this code. The content of this method is
224     * always regenerated by the Form Editor.
225     */
226     private void initComponents() {//GEN-BEGIN:initComponents
227         jLabel1 = new javax.swing.JLabel();
228         nameField = new javax.swing.JTextField();
229         nameLabel = new javax.swing.JLabel();
230         fkFieldLabel = new javax.swing.JLabel();
231         foreignTableCombo = new javax.swing.JComboBox();
232         foreignTableLabel = new javax.swing.JLabel();
233         fkFieldCombo = new javax.swing.JComboBox();
234         foreignPkLabel = new javax.swing.JLabel();
235         foreignPkCombo = new javax.swing.JComboBox();
236         bidirectionalCheckbox = new javax.swing.JCheckBox();
237         cardinalityLabel = new javax.swing.JLabel();
238         cardinalityCombo = new javax.swing.JComboBox();
239 
240         setLayout(null);
241 
242         addMouseListener(new java.awt.event.MouseAdapter() {
243             public void mouseExited(java.awt.event.MouseEvent evt) {
244                 formMouseExited(evt);
245             }
246         });
247 
248         jLabel1.setFont(new java.awt.Font("Arial", 0, 12));
249         jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
250         jLabel1.setText("- relation -");
251         add(jLabel1);
252         jLabel1.setBounds(110, 20, 380, 15);
253 
254         nameField.addFocusListener(new java.awt.event.FocusAdapter() {
255             public void focusLost(java.awt.event.FocusEvent evt) {
256                 nameFieldFocusLost(evt);
257             }
258         });
259 
260         add(nameField);
261         nameField.setBounds(190, 70, 260, 20);
262 
263         nameLabel.setFont(new java.awt.Font("Dialog", 0, 12));
264         nameLabel.setText("relation name:");
265         nameLabel.setToolTipText("The name used internally to represent this (end of the) relation.");
266         add(nameLabel);
267         nameLabel.setBounds(20, 70, 120, 20);
268 
269         fkFieldLabel.setFont(new java.awt.Font("Dialog", 0, 12));
270         fkFieldLabel.setText("foreign key field:");
271         add(fkFieldLabel);
272         fkFieldLabel.setBounds(20, 100, 120, 20);
273 
274         foreignTableCombo.addActionListener(new java.awt.event.ActionListener() {
275             public void actionPerformed(java.awt.event.ActionEvent evt) {
276                 foreignTableComboActionPerformed(evt);
277             }
278         });
279         foreignTableCombo.addFocusListener(new java.awt.event.FocusAdapter() {
280             public void focusLost(java.awt.event.FocusEvent evt) {
281                 foreignTableComboFocusLost(evt);
282             }
283         });
284 
285         add(foreignTableCombo);
286         foreignTableCombo.setBounds(190, 160, 260, 23);
287 
288         foreignTableLabel.setFont(new java.awt.Font("Dialog", 0, 12));
289         foreignTableLabel.setText("foreign table:");
290         add(foreignTableLabel);
291         foreignTableLabel.setBounds(20, 160, 120, 20);
292 
293         fkFieldCombo.addActionListener(new java.awt.event.ActionListener() {
294             public void actionPerformed(java.awt.event.ActionEvent evt) {
295                 fkFieldComboActionPerformed(evt);
296             }
297         });
298 
299         add(fkFieldCombo);
300         fkFieldCombo.setBounds(190, 100, 260, 23);
301 
302         foreignPkLabel.setFont(new java.awt.Font("Dialog", 0, 12));
303         foreignPkLabel.setText("foreign table's primary key:");
304         add(foreignPkLabel);
305         foreignPkLabel.setBounds(20, 190, 160, 20);
306 
307         foreignPkCombo.addActionListener(new java.awt.event.ActionListener() {
308             public void actionPerformed(java.awt.event.ActionEvent evt) {
309                 foreignPkComboActionPerformed(evt);
310             }
311         });
312         foreignPkCombo.addFocusListener(new java.awt.event.FocusAdapter() {
313             public void focusLost(java.awt.event.FocusEvent evt) {
314                 foreignPkComboFocusLost(evt);
315             }
316         });
317 
318         add(foreignPkCombo);
319         foreignPkCombo.setBounds(190, 190, 260, 23);
320 
321         bidirectionalCheckbox.setFont(new java.awt.Font("Dialog", 0, 12));
322         bidirectionalCheckbox.setText("bi-directional relationship?");
323         add(bidirectionalCheckbox);
324         bidirectionalCheckbox.setBounds(20, 280, 190, 25);
325 
326         cardinalityLabel.setFont(new java.awt.Font("Dialog", 0, 12));
327         cardinalityLabel.setText("cardinality:");
328         add(cardinalityLabel);
329         cardinalityLabel.setBounds(20, 250, 160, 20);
330 
331         cardinalityCombo.addActionListener(new java.awt.event.ActionListener() {
332             public void actionPerformed(java.awt.event.ActionEvent evt) {
333                 cardinalityComboActionPerformed(evt);
334             }
335         });
336 
337         add(cardinalityCombo);
338         cardinalityCombo.setBounds(190, 250, 260, 23);
339 
340     }//GEN-END:initComponents
341 
342     private void cardinalityComboActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cardinalityComboActionPerformed
343         // TODO add your handling code here:
344     }//GEN-LAST:event_cardinalityComboActionPerformed
345 
346     private void foreignPkComboFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_foreignPkComboFocusLost
347       formPropertyChange();
348       JagGenerator.stateChanged(false);
349     }//GEN-LAST:event_foreignPkComboFocusLost
350 
351     private void foreignTableComboFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_foreignTableComboFocusLost
352       formPropertyChange();
353       JagGenerator.stateChanged(false);
354     }//GEN-LAST:event_foreignTableComboFocusLost
355 
356    private void fkFieldComboActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fkFieldComboActionPerformed
357       formPropertyChange();
358    }//GEN-LAST:event_fkFieldComboActionPerformed
359 
360    private void formMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseExited
361       //this is necessary to make sure the field currenlty having focus
362       //is synched with the panel when the File > Save menu is selected.
363       formPropertyChange();
364    }//GEN-LAST:event_formMouseExited
365 
366    private void foreignPkComboActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_foreignPkComboActionPerformed
367       formPropertyChange();
368    }//GEN-LAST:event_foreignPkComboActionPerformed
369 
370    private void nameFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_nameFieldFocusLost
371       formPropertyChange();
372       JagGenerator.stateChanged(true);
373    }//GEN-LAST:event_nameFieldFocusLost
374 
375    private void foreignTableComboActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_foreignTableComboActionPerformed
376       evt = null;
377       formPropertyChange();
378       initColumnsList();
379       JagGenerator.stateChanged(false);
380    }//GEN-LAST:event_foreignTableComboActionPerformed
381 
382    private String getTextFromJComboBox(JComboBox combo) {
383       String a = (String) combo.getEditor().getItem();
384       String b = (String) combo.getSelectedItem();
385       return combo.isEditable() ? a : b;
386    }
387 
388     // Variables declaration - do not modify//GEN-BEGIN:variables
389     private javax.swing.JCheckBox bidirectionalCheckbox;
390     private javax.swing.JComboBox cardinalityCombo;
391     private javax.swing.JLabel cardinalityLabel;
392     private javax.swing.JComboBox fkFieldCombo;
393     private javax.swing.JLabel fkFieldLabel;
394     private javax.swing.JComboBox foreignPkCombo;
395     private javax.swing.JLabel foreignPkLabel;
396     private javax.swing.JComboBox foreignTableCombo;
397     private javax.swing.JLabel foreignTableLabel;
398     private javax.swing.JLabel jLabel1;
399     private javax.swing.JTextField nameField;
400     private javax.swing.JLabel nameLabel;
401     // End of variables declaration//GEN-END:variables
402 
403 }