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.jaggenerator.validation.StrutsValidation;
22  import com.finalist.jag.util.TemplateString;
23  
24  import javax.swing.*;
25  import javax.swing.tree.*;
26  
27  import org.w3c.dom.*;
28  
29  import java.util.HashSet;
30  import java.util.ArrayList;
31  import java.util.Iterator;
32  import java.util.List;
33  
34  /***
35   *
36   * @author  hillie
37   */
38  public class Field extends DefaultMutableTreeNode implements JagBean {
39     private StrutsValidation validations = new StrutsValidation();
40     private Relation relation;
41     private Entity parentEntity;
42     private boolean previousRequiredState;
43     private String oldName;
44     private static final ArrayList jdbcTypes = new ArrayList();
45     private boolean nullable = true;
46  
47     /*** Static set of classes for which the UniqueIdGenerator is able to generate primary keys. */
48     private final static HashSet autogeneratablePrimaryKeyClasses = new HashSet();
49     static {
50        autogeneratablePrimaryKeyClasses.add("java.lang.Byte");
51        autogeneratablePrimaryKeyClasses.add("java.lang.Double");
52        autogeneratablePrimaryKeyClasses.add("java.lang.Integer");
53        autogeneratablePrimaryKeyClasses.add("java.lang.Long");
54        autogeneratablePrimaryKeyClasses.add("java.lang.Short");
55        autogeneratablePrimaryKeyClasses.add("java.lang.String");
56  
57        java.lang.reflect.Field[] fields = java.sql.Types.class.getDeclaredFields();
58        for (int i = 0; i < fields.length; i++) {
59           jdbcTypes.add(fields[i].getName());
60        }
61     }
62  
63  
64     /*** Creates new form BeanForm */
65     public Field(Entity parent, Column column) {
66        parentEntity = parent;
67        try {
68           init();
69           String name = Utils.format(column.getName());
70           nullable = column.isNullable();
71           nameText.setText(name);
72           oldName = name;
73           typeText.setText(getType(column));
74           columnNameText.setText(column.getName());
75           sqlTypeText.setText(getSqlType(column));
76           jdbcTypeComboBox.setSelectedItem(getJdbcType(column));
77           setPrimaryKey(column.isPrimaryKey());
78           if (primaryKeyCheckBox.isSelected()) {
79              autoGeneratedCheckBox.setSelected(isPkClassIsAutogeneratable());
80           }
81           requiredCheckBox.setSelected(!nullable);
82           regenerateValidations();
83  
84        } catch (Exception e) {
85           e.printStackTrace();
86        }
87     }
88  
89  
90     /*** Use for building up the entity field gui component */
91     public Field(Entity parent, Element el) {
92        parentEntity = parent;
93        try {
94           init();
95           NodeList nl = el.getElementsByTagName("module-data");
96  
97           for (int i = 0; i < nl.getLength(); i++) {
98              Element child = (Element) nl.item(i);
99              String attName = child.getAttribute("name");
100             String value = null;
101             if (child.getFirstChild() != null)
102                value = child.getFirstChild().getNodeValue();
103             if (value != null) {
104                if (attName.equalsIgnoreCase("name")) {
105                   nameText.setText(value);
106                   oldName = value;
107                   continue;
108                }
109                if (attName.equalsIgnoreCase("type")) {
110                   typeText.setText(value);
111                   continue;
112                }
113                if (attName.equalsIgnoreCase("column-name")) {
114                   columnNameText.setText(value);
115                   continue;
116                }
117                if (attName.equalsIgnoreCase("required")) {
118                   requiredCheckBox.setSelected("true".equalsIgnoreCase(value));
119                   nullable = !requiredCheckBox.isSelected();
120                   continue;
121                }
122                if (attName.equalsIgnoreCase("sql-type")) {
123                   sqlTypeText.setText(value);
124                   continue;
125                }
126                if (attName.equalsIgnoreCase("jdbc-type")) {
127                   jdbcTypeComboBox.setSelectedItem(value);
128                   continue;
129                }
130                if (attName.equalsIgnoreCase("primary-key")) {
131                   // Don't use the setPrimaryKey method for non-primary keys,
132                   // since it will overrule the required and auto-primary key settings.
133                   if ("true".equalsIgnoreCase(value)) {
134                     setPrimaryKey(true);
135                   } else {
136                     primaryKeyCheckBox.setSelected(false);
137                   }
138                   continue;
139                }
140                if (attName.equalsIgnoreCase("auto-primary-key")) {
141                   autoGeneratedCheckBox.setSelected("true".equalsIgnoreCase(value)
142                         && isPkClassIsAutogeneratable());
143                   continue;
144                }
145                if (attName.equalsIgnoreCase("foreign-key")) {
146                   setForeignKey("true".equalsIgnoreCase(value.trim()));
147                   continue;
148                }
149                if (attName.equalsIgnoreCase("validation-depends")) {
150                   if (value != null) {
151                      validations.setDependsList(value);
152                      validationDependsText.setText(value);
153                   } else {
154                      validationDependsText.setText("");
155                   }
156                   continue;
157                }
158                if (attName.equalsIgnoreCase("validation-xml")) {
159                   if (value != null) {
160                      validations.setXml(value);
161                      validationXMLTextArea.setText(value);
162                   } else {
163                      validationXMLTextArea.setText("");
164                   }
165                   continue;
166                }
167             }
168          }
169 
170       } catch (Exception e) {
171          e.printStackTrace();
172       }
173    }
174 
175 
176    public String toString() {
177       return nameText.getText();
178    }
179 
180    public JPanel getPanel() {
181       return panel;
182    }
183 
184    public void getXML(Element el) {
185       Document doc = el.getOwnerDocument();
186       Element module = doc.createElement("module-data");
187       module.setAttribute("name", "field");
188 
189       Element name = doc.createElement("module-data");
190       name.setAttribute("name", "name");
191       if (nameText.getText() != null) {
192         if (nameText.getText() != null) {
193             name.appendChild(doc.createTextNode(nameText.getText()));
194         }
195       }
196       module.appendChild(name);
197 
198       Element type = doc.createElement("module-data");
199       type.setAttribute("name", "type");
200       if (typeText.getText() != null) {
201         type.appendChild(doc.createTextNode(typeText.getText()));
202       }
203       module.appendChild(type);
204 
205       Element columnName = doc.createElement("module-data");
206       columnName.setAttribute("name", "column-name");
207       if (columnNameText.getText() != null) {
208         columnName.appendChild(doc.createTextNode(columnNameText.getText()));
209       }
210       module.appendChild(columnName);
211 
212 
213       Element required = doc.createElement("module-data");
214       required.setAttribute("name", "required");
215       required.appendChild(doc.createTextNode(Boolean.toString(requiredCheckBox.isSelected())));
216       module.appendChild(required);
217 
218 
219       Element sqlType = doc.createElement("module-data");
220       sqlType.setAttribute("name", "sql-type");
221       if (sqlTypeText.getText() != null) {
222         sqlType.appendChild(doc.createTextNode(sqlTypeText.getText()));
223       }
224       module.appendChild(sqlType);
225 
226       Element jdbcType = doc.createElement("module-data");
227       jdbcType.setAttribute("name", "jdbc-type");
228       jdbcType.appendChild(doc.createTextNode(jdbcTypeComboBox.getSelectedItem().toString()));
229       module.appendChild(jdbcType);
230 
231       Element primaryKey = doc.createElement("module-data");
232       primaryKey.setAttribute("name", "primary-key");
233       primaryKey.appendChild(doc.createTextNode(Boolean.toString(primaryKeyCheckBox.isSelected())));
234       module.appendChild(primaryKey);
235 
236       Element autoPrimary = doc.createElement("module-data");
237       autoPrimary.setAttribute("name", "auto-primary-key");
238       autoPrimary.appendChild(doc.createTextNode(Boolean.toString(autoGeneratedCheckBox.isSelected())));
239       module.appendChild(autoPrimary);
240 
241       Element foreignKey = doc.createElement("module-data");
242       foreignKey.setAttribute("name", "foreign-key");
243       foreignKey.appendChild(doc.createTextNode("" + isForeignKey()));
244       module.appendChild(foreignKey);
245 
246       regenerateValidations();
247 
248       Element validationDepends = doc.createElement("module-data");
249       validationDepends.setAttribute("name", "validation-depends");
250       if (validationDependsText.getText() != null) {
251         validationDepends.appendChild(doc.createTextNode(validationDependsText.getText()));
252       }
253       module.appendChild(validationDepends);
254 
255       Element validationXml = doc.createElement("module-data");
256       validationXml.setAttribute("name", "validation-xml");
257       if (validationXMLTextArea.getText() != null) {
258         validationXml.appendChild(doc.createTextNode(validationXMLTextArea.getText()));
259       }
260       module.appendChild(validationXml);
261 
262       el.appendChild(module);
263    }
264 
265    public TemplateString getSqlType() {
266       return new TemplateString(sqlTypeText.getText());
267    }
268 
269    public void setSqlType(String text) {
270       sqlTypeText.setText(text);
271    }
272 
273    public TemplateString getJdbcType() {
274       return new TemplateString(jdbcTypeComboBox.getSelectedItem().toString());
275    }
276 
277    public void setJdbcType(String text) {
278       jdbcTypeComboBox.setSelectedItem(text);
279    }
280 
281    public TemplateString getPrimaryKey() {
282       return new TemplateString(Boolean.toString(primaryKeyCheckBox.isSelected()));
283    }
284 
285    public TemplateString getForeignKey() {
286       return new TemplateString(Boolean.toString(isForeignKey()));
287    }
288 
289    public String getValidationDepends() {
290       if (validationDependsText.getText() == null) {
291           return "";
292       } else {
293         return validationDependsText.getText();
294       }
295    }
296 
297    public String getValidationXml() {
298       return validationXMLTextArea.getText();
299    }
300 
301    public String getType(Column column) {
302       String sqlType = column.getSqlType().toUpperCase();
303       int scale = column.getScale();
304       int precision = column.getPrecision();
305       if (sqlType == null)
306          return "";
307       if (sqlType.equals("DATE"))
308          return "java.sql.Date";
309        if (sqlType.equals("BOOL"))
310           return "java.lang.Boolean";
311       if (sqlType.equals("FLOAT"))
312          return "java.lang.Float";
313       if (sqlType.equals("DOUBLE"))
314          return "java.lang.Double";
315       if (sqlType.equals("FLOAT(7)"))
316          return "java.lang.Float";
317       if (sqlType.equals("FLOAT8"))
318          return "java.lang.Double";
319       if (contains(sqlType, "NUMERIC") || contains(sqlType, "NUMERIC"))
320          return "java.math.BigDecimal";
321       if (sqlType.equals("BYTEA")) {
322          System.out.println("Mapping the BYTEA binary type to java.sql.Blob. JAG has no support for binary fields.");
323          return "java.sql.Blob";
324       }
325       if ((sqlType.indexOf("TIMESTAMP") != -1) || (sqlType.indexOf("DATETIME") != -1))
326          return "java.sql.Timestamp";
327       if (sqlType.equals("TIME"))
328          return "java.sql.Time";
329       if (contains(sqlType, "TINYINT"))
330          return "java.lang.Byte";
331       if (contains(sqlType, "SMALLINT"))
332          return "java.lang.Short";
333       if (contains(sqlType, "BIGINT"))
334          return "java.lang.Long";
335       if (contains(sqlType, "DECIMAL"))
336          return "java.math.BigDecimal";
337       if (contains(sqlType, "BLOB"))
338          return "java.sql.Blob";
339 
340       if (sqlType.equals("NUMBER") || sqlType.equals("INT") ||
341             sqlType.equals("YEAR") ||
342             sqlType.indexOf("INT") > -1) {
343          if (scale == 0) {
344             if (precision == 0) {
345                // this is the case for pseudo columns
346                // like sequences, count(*) etc.
347                // by convention, let's convert them to Integer
348                return "java.lang.Integer";
349             }
350             if (precision <= 2) {
351                //let it be a byte
352                //
353                return "java.lang.Integer";
354             }
355             if (precision <= 5) {
356                return "java.lang.Integer";
357             }
358             if (precision <= 9) {
359                //let it be an int
360                return "java.lang.Integer";
361             }
362             if (precision <= 18) {
363                if (sqlType.indexOf("INT") != -1) {
364                   return "java.lang.Integer";
365                }
366                //let it be a long
367                return "java.lang.Long";
368             } else {
369                return "java.math.BigDecimal";
370             }
371          }
372          if (precision + scale <= 12) {
373             //return "java.lang.Float";
374             return "java.math.BigDecimal";
375          }
376          if (precision + scale <= 64) {
377             return "java.lang.Double";
378          } else {
379             return "java.math.BigDecimal";
380          }
381       }
382 
383       if (sqlType.indexOf("CHAR") > -1) {
384          return "java.lang.String";
385       }
386       if (sqlType.indexOf("TEXT") > -1) {
387          return "java.lang.String";
388       }
389       System.out.println("unknown sql type: " + sqlType + " Map it to a String.");
390       return "java.lang.String";
391    }
392 
393    public String getJdbcType(Column column) {
394       String sqlType = column.getSqlType().toUpperCase();
395       int scale = column.getScale();
396       int precision = column.getPrecision();
397       if (sqlType == null)
398          return "";
399 
400       if (sqlType.equals("NUMERIC") || sqlType.equals("TINYINT") || sqlType.equals("SMALLINT") ||
401             sqlType.equals("DOUBLE") || sqlType.equals("TIMESTAMP") || sqlType.equals("FLOAT") ||
402             sqlType.equals("DATE") || sqlType.equals("TIME") || contains(sqlType, "BIGINT") ||
403             sqlType.equals("DECIMAL"))
404          return sqlType;
405 
406       if (contains(sqlType, "CHAR")) {
407          return "VARCHAR";
408       }
409       if (contains(sqlType, "TEXT")) {
410          return "VARCHAR";
411       }
412       if (sqlType.equals("DATETIME"))
413          return "TIMESTAMP";
414       // Postgress specific:
415       if (sqlType.equals("FLOAT(7)"))
416          return "FLOAT";
417       // Postgress specific:
418       if (sqlType.equals("FLOAT8"))
419          return "DOUBLE";
420       if (sqlType.equals("BYTEA"))
421          return "VARBINARY";
422       if (contains(sqlType, "BLOB")) {
423          return "BLOB";
424       }
425 
426       if (sqlType.equals("NUMBER") || contains(sqlType, "INT") || sqlType.equals("YEAR")) {
427          if (scale == 0) {
428             if (precision == 0) {
429                // this is the case for pseudo columns
430                // like sequences, count(*) etc.
431                // by convention, let's convert them to Integer
432                return "INTEGER";
433             }
434             if (precision <= 5) {
435                //let it be a byte
436                return "INTEGER";
437             }
438             if (precision <= 9) {
439                //let it be an int
440                return "INTEGER";
441             }
442             if (precision <= 18) {
443                if (sqlType.indexOf("INT") != -1) {
444                   return "INTEGER";
445                }
446                //let it be a long
447                return "BIGINT";
448             }
449          }
450          if (precision + scale <= 12) {
451             return "DECIMAL";
452          }
453          if (precision + scale <= 64) {
454             return "DOUBLE";
455          }
456       }
457 
458       return "JAVA_OBJECT";
459    }
460 
461    public String getSqlType(Column column) {
462       String sqlType = column.getSqlType().toUpperCase();
463       int scale = column.getScale();
464       int precision = column.getPrecision();
465       int length = column.getLength();
466       if (sqlType == null)
467          return "";
468       if (sqlType.equals("NUMBER") || sqlType.equals("DOUBLE") || contains(sqlType, "INT") ||
469             sqlType.equals("YEAR") || sqlType.equals("FLOAT") || sqlType.equals("DECIMAL")) {
470          if (precision > 0) {
471             sqlType = sqlType + "(" + precision;
472             if (scale != 0) {
473                sqlType = sqlType + ", " + scale;
474             }
475             sqlType = sqlType + ")";
476          }
477          return sqlType;
478       }
479       if (sqlType.indexOf("CHAR") > -1) {
480          if (length > 0) {
481             return sqlType + "(" + length + ")";
482          }
483       }
484       return sqlType;
485    }
486 
487    public String getRefName() {
488       return null;
489    }
490 
491    /***
492     * Indicates whether the field is part of the primary key.
493     *
494     * @return <code>true</code> if the field is part of the primary key
495     */
496    public boolean isPrimaryKey() {
497       return primaryKeyCheckBox.isSelected();
498    }
499 
500 
501    public boolean getHasAutoGenPrimaryKey() {
502       return autoGeneratedCheckBox.isSelected();
503    }
504 
505    public void setHasAutoGenPrimaryKey(boolean value) {
506       autoGeneratedCheckBox.setSelected(value);
507    }
508 
509    /***
510     * Setter for this field, which specifies whether or not this Field is a foreign key field within its table.
511     * @param foreignKey
512     */
513    public void setForeignKey(boolean foreignKey) {
514       foreignKeyCheckBox.setSelected(foreignKey);
515    }
516 
517    public boolean isForeignKey() {
518       return foreignKeyCheckBox.isSelected();
519    }
520 
521    /***
522     * Returns the class that represents the primary key type
523     *
524     * @return the class that represents the primary key type
525     */
526    public String getType() {
527       return typeText.getText();
528    }
529 
530    /***
531     * Set the field type
532     * @param text type.
533     */
534    public void setType(String text) {
535       typeText.setText(text);
536    }
537 
538    /***
539     * Returns the name of the field
540     *
541     * @return the name of the field.
542     */
543    public TemplateString getName() {
544       return new TemplateString(nameText.getText());
545    }
546 
547    /***
548     * Sets the name of the field
549     *
550     * @param name the name of the field.
551     */
552    public void setName(String name) {
553       oldName = nameText.getText();
554       nameText.setText(name);
555    }
556 
557    public String getColumnName() {
558       return columnNameText.getText();
559    }
560 
561    /***
562     * Gets the relation, if this field represents a container-managed relation field in its parent entity bean.
563     * @return the Relation object, or <code>null</code> if this field doesn't represent a relation.
564     */
565    public Relation getRelation() {
566       return relation;
567    }
568 
569    public void setRelation(Relation relation) {
570       this.relation = relation;
571    }
572 
573    public boolean isRelation() {
574       return relation != null;
575    }
576 
577    /***
578     * Make the nullable field available.
579     *
580     * @return true if the field is nullable.
581     */
582    public boolean isNullable() {
583       return nullable;
584    }
585    /***
586     *
587     * Return true if the field is required, so nullable is true.
588     *
589     * @return true if the field is required.
590     */
591    public boolean isRequired() {
592       return !nullable;
593    }
594 
595 
596    /***
597     * Return the size of a sql type in case it is a string type. Otherwise return null.
598     * @return
599     */
600    public String getSize() {
601       TemplateString theType = getSqlType();
602       if (theType == null) {
603          return null;
604       }
605       List parameters = StrutsValidation.getParams(getSqlType().toString());
606       if (getSqlType().toString().indexOf("CHAR") != -1 && !parameters.isEmpty()) {
607          return (String) parameters.get(0);
608       }
609       return null;
610    }
611 
612 
613    /***
614     * Regenerates the Struts validations for this field.
615     */
616    public void regenerateValidations() {
617       validations = new StrutsValidation(sqlTypeText.getText(),
618             jdbcTypeComboBox.getSelectedItem().toString(), enforceRequiredValidation());
619       if (validations.getDependsList() != null) {
620          validationDependsText.setText(validations.getDependsList());
621       } else {
622          validationDependsText.setText("");
623       }
624       if (validations.getXml() != null) {
625          validationXMLTextArea.setText(validations.getXml());
626       } else {
627          validationXMLTextArea.setText("");
628       }
629    }
630 
631 
632    private boolean enforceRequiredValidation() {
633       //primary key fields are always 'required' (can't be null), but in the webapp we only validate this
634       //if the pk field isn't auto-generated.
635       return getHasAutoGenPrimaryKey() ? false : requiredCheckBox.isSelected();
636    }
637 
638    /***
639     * A heap of things happen when you set a field as primary key - keep them all here!
640     * @param value
641     */
642    public void setPrimaryKey(boolean value) {
643       primaryKeyCheckBox.setSelected(value);
644       autoGeneratedCheckBox.setEnabled(value);
645       requiredCheckBox.setEnabled(!value);
646       if (value) {
647          previousRequiredState = requiredCheckBox.isSelected();
648          requiredCheckBox.setSelected(true);
649       } else {
650          requiredCheckBox.setSelected(previousRequiredState);
651       }
652    }
653 
654    public boolean isPkClassIsAutogeneratable() {
655       String primaryKeyClass = typeText.getText();
656       return autogeneratablePrimaryKeyClasses.contains(primaryKeyClass);
657    }
658 
659    private void init() {
660       initComponents();
661       Iterator types = jdbcTypes.iterator();
662       while (types.hasNext()) {
663          String jdbcType = (String) types.next();
664          jdbcTypeComboBox.addItem(jdbcType);
665       }
666    }
667 
668    /*** This method is called from within the constructor to
669     * initialize the form.
670     * WARNING: Do NOT modify this code. The content of this method is
671     * always regenerated by the Form Editor.
672     */
673     // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
674     private void initComponents() {
675         panel = new javax.swing.JPanel();
676         nameLabel = new javax.swing.JLabel();
677         typeLabel = new javax.swing.JLabel();
678         columnNameLabel = new javax.swing.JLabel();
679         sqlTypeLabel = new javax.swing.JLabel();
680         jdbcTypeLabel = new javax.swing.JLabel();
681         nameText = new javax.swing.JTextField();
682         typeText = new javax.swing.JTextField();
683         columnNameText = new javax.swing.JTextField();
684         sqlTypeText = new javax.swing.JTextField();
685         jPanel1 = new javax.swing.JPanel();
686         validationDependsText = new javax.swing.JTextField();
687         validationXMLScrollPane = new javax.swing.JScrollPane();
688         validationXMLTextArea = new javax.swing.JTextArea();
689         validationXMLLabel = new javax.swing.JLabel();
690         validationDependsLabel = new javax.swing.JLabel();
691         regenerateButton = new javax.swing.JButton();
692         jdbcTypeComboBox = new javax.swing.JComboBox();
693         checkboxPanel2 = new javax.swing.JPanel();
694         autoGeneratedCheckBox = new javax.swing.JCheckBox();
695         requiredCheckBox = new javax.swing.JCheckBox();
696         checkboxPanel1 = new javax.swing.JPanel();
697         primaryKeyCheckBox = new javax.swing.JCheckBox();
698         foreignKeyCheckBox = new javax.swing.JCheckBox();
699 
700         panel.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());
701 
702         nameLabel.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
703         nameLabel.setText("Name: ");
704         panel.add(nameLabel, new org.netbeans.lib.awtextra.AbsoluteConstraints(20, 10, 90, -1));
705 
706         typeLabel.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
707         typeLabel.setText("Type: ");
708         panel.add(typeLabel, new org.netbeans.lib.awtextra.AbsoluteConstraints(20, 40, 90, -1));
709 
710         columnNameLabel.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
711         columnNameLabel.setText("Column name: ");
712         panel.add(columnNameLabel, new org.netbeans.lib.awtextra.AbsoluteConstraints(20, 70, 90, -1));
713 
714         sqlTypeLabel.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
715         sqlTypeLabel.setText("SQL-type: ");
716         panel.add(sqlTypeLabel, new org.netbeans.lib.awtextra.AbsoluteConstraints(20, 100, 90, -1));
717 
718         jdbcTypeLabel.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
719         jdbcTypeLabel.setText("JDBC-type: ");
720         panel.add(jdbcTypeLabel, new org.netbeans.lib.awtextra.AbsoluteConstraints(20, 130, 90, -1));
721 
722         nameText.addFocusListener(new java.awt.event.FocusAdapter() {
723             public void focusLost(java.awt.event.FocusEvent evt) {
724                 nameTextFocusLost(evt);
725             }
726         });
727 
728         panel.add(nameText, new org.netbeans.lib.awtextra.AbsoluteConstraints(120, 10, 260, -1));
729 
730         typeText.addFocusListener(new java.awt.event.FocusAdapter() {
731             public void focusLost(java.awt.event.FocusEvent evt) {
732                 typeTextFocusLost(evt);
733             }
734         });
735 
736         panel.add(typeText, new org.netbeans.lib.awtextra.AbsoluteConstraints(120, 40, 260, -1));
737 
738         columnNameText.addFocusListener(new java.awt.event.FocusAdapter() {
739             public void focusLost(java.awt.event.FocusEvent evt) {
740                 columnNameTextFocusLost(evt);
741             }
742         });
743 
744         panel.add(columnNameText, new org.netbeans.lib.awtextra.AbsoluteConstraints(120, 70, 260, -1));
745 
746         sqlTypeText.addFocusListener(new java.awt.event.FocusAdapter() {
747             public void focusLost(java.awt.event.FocusEvent evt) {
748                 sqlTypeTextFocusLost(evt);
749             }
750         });
751 
752         panel.add(sqlTypeText, new org.netbeans.lib.awtextra.AbsoluteConstraints(120, 100, 260, -1));
753 
754         jPanel1.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());
755 
756         jPanel1.setBorder(new javax.swing.border.TitledBorder("Struts validations:"));
757         validationDependsText.setColumns(46);
758         validationDependsText.addFocusListener(new java.awt.event.FocusAdapter() {
759             public void focusLost(java.awt.event.FocusEvent evt) {
760                 validationDependsTextFocusLost(evt);
761             }
762         });
763 
764         jPanel1.add(validationDependsText, new org.netbeans.lib.awtextra.AbsoluteConstraints(90, 30, 290, -1));
765 
766         validationXMLTextArea.setColumns(48);
767         validationXMLTextArea.setFont(new java.awt.Font("Lucida Console", 0, 10));
768         validationXMLTextArea.setRows(6);
769         validationXMLTextArea.addFocusListener(new java.awt.event.FocusAdapter() {
770             public void focusLost(java.awt.event.FocusEvent evt) {
771                 validationXMLTextAreaFocusLost(evt);
772             }
773         });
774 
775         validationXMLScrollPane.setViewportView(validationXMLTextArea);
776 
777         jPanel1.add(validationXMLScrollPane, new org.netbeans.lib.awtextra.AbsoluteConstraints(90, 59, -1, 90));
778 
779         validationXMLLabel.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
780         validationXMLLabel.setText("Validation XML: ");
781         jPanel1.add(validationXMLLabel, new org.netbeans.lib.awtextra.AbsoluteConstraints(-20, 60, 110, 20));
782 
783         validationDependsLabel.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
784         validationDependsLabel.setText("Validations: ");
785         jPanel1.add(validationDependsLabel, new org.netbeans.lib.awtextra.AbsoluteConstraints(-20, 30, 110, -1));
786 
787         regenerateButton.setText("Regenerate validations");
788         regenerateButton.setEnabled(false);
789         regenerateButton.addActionListener(new java.awt.event.ActionListener() {
790             public void actionPerformed(java.awt.event.ActionEvent evt) {
791                 regenerateButtonActionPerformed(evt);
792             }
793         });
794 
795         jPanel1.add(regenerateButton, new org.netbeans.lib.awtextra.AbsoluteConstraints(240, 170, -1, -1));
796 
797         panel.add(jPanel1, new org.netbeans.lib.awtextra.AbsoluteConstraints(30, 240, 400, 200));
798 
799         jdbcTypeComboBox.addActionListener(new java.awt.event.ActionListener() {
800             public void actionPerformed(java.awt.event.ActionEvent evt) {
801                 jdbcTypeComboBoxActionPerformed(evt);
802             }
803         });
804 
805         panel.add(jdbcTypeComboBox, new org.netbeans.lib.awtextra.AbsoluteConstraints(120, 130, 260, -1));
806 
807         checkboxPanel2.setLayout(new java.awt.BorderLayout());
808 
809         autoGeneratedCheckBox.setText("Auto-generated primary key:");
810         autoGeneratedCheckBox.setEnabled(false);
811         autoGeneratedCheckBox.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
812         autoGeneratedCheckBox.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT);
813         autoGeneratedCheckBox.addActionListener(new java.awt.event.ActionListener() {
814             public void actionPerformed(java.awt.event.ActionEvent evt) {
815                 autoGeneratedCheckBoxActionPerformed(evt);
816             }
817         });
818 
819         checkboxPanel2.add(autoGeneratedCheckBox, java.awt.BorderLayout.SOUTH);
820 
821         requiredCheckBox.setText("Required (not nullable):");
822         requiredCheckBox.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
823         requiredCheckBox.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT);
824         requiredCheckBox.setMaximumSize(new java.awt.Dimension(186, 24));
825         requiredCheckBox.setMinimumSize(new java.awt.Dimension(186, 24));
826         requiredCheckBox.setPreferredSize(new java.awt.Dimension(186, 24));
827         requiredCheckBox.addActionListener(new java.awt.event.ActionListener() {
828             public void actionPerformed(java.awt.event.ActionEvent evt) {
829                 requiredCheckBoxActionPerformed(evt);
830             }
831         });
832 
833         checkboxPanel2.add(requiredCheckBox, java.awt.BorderLayout.NORTH);
834 
835         panel.add(checkboxPanel2, new org.netbeans.lib.awtextra.AbsoluteConstraints(220, 170, 190, 50));
836 
837         checkboxPanel1.setLayout(new java.awt.BorderLayout());
838 
839         primaryKeyCheckBox.setText("Primary key:");
840         primaryKeyCheckBox.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT);
841         primaryKeyCheckBox.addActionListener(new java.awt.event.ActionListener() {
842             public void actionPerformed(java.awt.event.ActionEvent evt) {
843                 primaryKeyCheckBoxActionPerformed(evt);
844             }
845         });
846 
847         checkboxPanel1.add(primaryKeyCheckBox, java.awt.BorderLayout.NORTH);
848 
849         foreignKeyCheckBox.setText("Foreign key:");
850         foreignKeyCheckBox.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT);
851         foreignKeyCheckBox.addActionListener(new java.awt.event.ActionListener() {
852             public void actionPerformed(java.awt.event.ActionEvent evt) {
853                 foreignKeyCheckBoxActionPerformed(evt);
854             }
855         });
856 
857         checkboxPanel1.add(foreignKeyCheckBox, java.awt.BorderLayout.SOUTH);
858 
859         panel.add(checkboxPanel1, new org.netbeans.lib.awtextra.AbsoluteConstraints(60, 170, 160, 50));
860 
861     }
862     // </editor-fold>//GEN-END:initComponents
863 
864     private void jdbcTypeComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jdbcTypeComboBoxActionPerformed
865       JagGenerator.stateChanged(false);
866       regenerateButton.setEnabled(true);
867     }//GEN-LAST:event_jdbcTypeComboBoxActionPerformed
868 
869    private void autoGeneratedCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_autoGeneratedCheckBoxActionPerformed
870       if (autoGeneratedCheckBox.isSelected() && !isPkClassIsAutogeneratable()) {
871          JagGenerator.logToConsole("Can't autogenerate primary keys with class type '" + typeText.getText() + "'!");
872          autoGeneratedCheckBox.setSelected(false);
873       }
874    }//GEN-LAST:event_autoGeneratedCheckBoxActionPerformed
875 
876    private void regenerateButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_regenerateButtonActionPerformed
877       regenerateValidations();
878       regenerateButton.setEnabled(false);
879    }//GEN-LAST:event_regenerateButtonActionPerformed
880 
881    private void requiredCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_requiredCheckBoxActionPerformed
882       JagGenerator.stateChanged(false);
883       regenerateButton.setEnabled(true);
884    }//GEN-LAST:event_requiredCheckBoxActionPerformed
885 
886    private void validationXMLTextAreaFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_validationXMLTextAreaFocusLost
887       JagGenerator.stateChanged(false);
888    }//GEN-LAST:event_validationXMLTextAreaFocusLost
889 
890    private void validationDependsTextFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_validationDependsTextFocusLost
891       JagGenerator.stateChanged(false);
892    }//GEN-LAST:event_validationDependsTextFocusLost
893 
894    private void foreignKeyCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_foreignKeyCheckBoxActionPerformed
895       JagGenerator.stateChanged(false);
896       regenerateButton.setEnabled(true);
897    }//GEN-LAST:event_foreignKeyCheckBoxActionPerformed
898 
899    private void primaryKeyCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_primaryKeyCheckBoxActionPerformed
900       boolean checked = primaryKeyCheckBox.isSelected();
901       setPrimaryKey(checked);
902 
903       //tell the parent entity bean that its primary key status has changed..
904       if (checked) {
905          parentEntity.setPrimaryKey(this);
906       } else {
907          parentEntity.unsetPrimaryKey(this);
908       }
909 
910       JagGenerator.stateChanged(false);
911       regenerateButton.setEnabled(true);
912    }//GEN-LAST:event_primaryKeyCheckBoxActionPerformed
913 
914    private void sqlTypeTextFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_sqlTypeTextFocusLost
915       JagGenerator.stateChanged(false);
916       regenerateButton.setEnabled(true);
917    }//GEN-LAST:event_sqlTypeTextFocusLost
918 
919    private void columnNameTextFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_columnNameTextFocusLost
920       JagGenerator.stateChanged(false);
921    }//GEN-LAST:event_columnNameTextFocusLost
922 
923    private void typeTextFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_typeTextFocusLost
924       JagGenerator.stateChanged(false);
925    }//GEN-LAST:event_typeTextFocusLost
926 
927    private void nameTextFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_nameTextFocusLost
928       if (!nameText.getText().equals(oldName)) {
929          parentEntity.notifyRelationsThatFieldNameChanged(oldName, nameText.getText());
930          oldName = nameText.getText();
931       }
932       JagGenerator.stateChanged(true);
933    }//GEN-LAST:event_nameTextFocusLost
934 
935    private boolean contains(String s, String sub) {
936       return s.indexOf(sub) > -1;
937    }
938 
939     // Variables declaration - do not modify//GEN-BEGIN:variables
940     public javax.swing.JCheckBox autoGeneratedCheckBox;
941     private javax.swing.JPanel checkboxPanel1;
942     private javax.swing.JPanel checkboxPanel2;
943     private javax.swing.JLabel columnNameLabel;
944     private javax.swing.JTextField columnNameText;
945     public javax.swing.JCheckBox foreignKeyCheckBox;
946     private javax.swing.JPanel jPanel1;
947     private javax.swing.JComboBox jdbcTypeComboBox;
948     private javax.swing.JLabel jdbcTypeLabel;
949     private javax.swing.JLabel nameLabel;
950     private javax.swing.JTextField nameText;
951     private javax.swing.JPanel panel;
952     public javax.swing.JCheckBox primaryKeyCheckBox;
953     private javax.swing.JButton regenerateButton;
954     public javax.swing.JCheckBox requiredCheckBox;
955     private javax.swing.JLabel sqlTypeLabel;
956     private javax.swing.JTextField sqlTypeText;
957     private javax.swing.JLabel typeLabel;
958     private javax.swing.JTextField typeText;
959     private javax.swing.JLabel validationDependsLabel;
960     public javax.swing.JTextField validationDependsText;
961     private javax.swing.JLabel validationXMLLabel;
962     private javax.swing.JScrollPane validationXMLScrollPane;
963     private javax.swing.JTextArea validationXMLTextArea;
964     // End of variables declaration//GEN-END:variables
965 }
966