View Javadoc

1   //$Id: Column.java,v 1.20 2007/10/19 10:43:36 kameleono Exp $
2   
3   package net.sourceforge.sql2java;
4   
5   import java.sql.Types;
6   import java.text.ParseException;
7   import java.text.SimpleDateFormat;
8   import java.util.Calendar;
9   import java.util.Date;
10  import java.util.List;
11  import java.util.Random;
12  import java.util.Vector;
13  
14  public class Column implements Cloneable {
15      // List of possible mapped types.
16      public static final int M_ARRAY = 0;
17      public static final int M_BIGDECIMAL = 1;
18      public static final int M_BOOLEAN = 2;
19      public static final int M_BYTES = 3;
20      public static final int M_CLOB = 4;
21      public static final int M_SQLDATE =5 ;
22      public static final int M_UTILDATE =6 ;
23      public static final int M_DOUBLE = 7;
24      public static final int M_FLOAT = 8;
25      public static final int M_BLOB = 9;
26      public static final int M_INTEGER = 10;
27      public static final int M_LONG = 11;
28      public static final int M_REF = 12;
29      public static final int M_STRING =13 ;
30      public static final int M_TIME = 14;
31      public static final int M_TIMESTAMP = 15;
32      public static final int M_URL = 16;
33      public static final int M_OBJECT = 17;
34      public static final int M_CALENDAR = 18; // moscac 2007-08-09 
35  
36      private String catalog, schema, tableName, name, remarks, defaultValue;
37      private int size, decDigits, radix, nullable, ordinal;
38      private short type;
39      private boolean isPrimaryKey;
40      private String strCheckingType = "";
41      private Database db;
42      private List foreignKeys = new Vector();
43      private List importedKeys = new Vector();
44  
45      /**
46       */
47      public String toString()
48      {
49      	return 	  "\n --------- " + tableName + "." + name + " --------- "
50  				+ "\n schema        = " + schema
51  				+ "\n tableName     = " + tableName
52  				+ "\n catalog       = " + catalog
53  				+ "\n remarks       = " + remarks
54  				+ "\n defaultValue  = " + defaultValue
55  				+ "\n decDigits     = " + decDigits
56  				+ "\n radix         = " + radix
57  				+ "\n nullable      = " + nullable
58  				+ "\n ordinal       = " + ordinal
59  				+ "\n size          = " + size
60  				+ "\n type          = " + type + " "
61  				+ "\n isPrimaryKey  = " + (isPrimaryKey ? "true":"false");
62      }
63  
64      public void setCheckingType(String strValue){this.strCheckingType = strValue;}
65      public String getCheckingType(){return strCheckingType; }
66      public void setDatabase(Database db) { this.db = db; }
67      public void setCatalog(String catalog) { this.catalog = catalog; }
68      public void setSchema(String schema) { this.schema = schema; }
69      public void setTableName(String tableName) { this.tableName = tableName; }
70      public void setName(String name) { this.name = (null == name)?"":name.replaceAll("\\W", ""); }	// filter out non-identifier chars
71      public void setType(short type) { this.type = type; }
72      public void setSize(int size) { this.size = size; }
73      public void setDecimalDigits(int decDigits) { this.decDigits = decDigits; }
74      public void setRadix(int radix) { this.radix = radix; }
75      public void setNullable(int nullable) { this.nullable = nullable; }
76      public void setRemarks(String remarks) {
77          if (remarks!=null) {
78              this.remarks = remarks.replaceAll("/\\*", "SLASH*").replaceAll("\\*/", "*SLASH");
79          }
80      }
81      public void setDefaultValue(String defaultValue) { this.defaultValue = defaultValue; }
82      public void setOrdinalPosition(int ordinal) { this.ordinal = ordinal; }
83      public void isPrimaryKey(boolean isKey) { this.isPrimaryKey = isKey; }
84  
85      public String getCatalog() { return catalog; }
86      public String getSchema() { return schema; }
87      public String getTableName() { return tableName; }
88      public String getName() { return name; }
89      public short getType() { return type; }
90      public int getSize() { return size; }
91      public int getDecimalDigits() { return decDigits; }
92      public int getRadix() { return radix; }
93      public int getNullable() { return nullable; }
94      public String getNullableAsString() { return (getNullable() != 0 ? "nullable" : "null not allowed"); }
95      public int getOrdinalPosition() { return ordinal; }
96      public boolean isPrimaryKey() { return isPrimaryKey; }
97      public String getFullName() { return tableName + "." + getName(); }
98      public String getConstName() { return getName().toUpperCase(); }
99  
100     public Object clone() throws CloneNotSupportedException {
101         return super.clone();
102     }
103 
104     private void tuoe() {
105         throw new UnsupportedOperationException("Not supported yet: "+ getTableName() + "." + getName() + " " + getJavaTypeAsTypeName());
106     }
107 
108     private void tiae() {
109         throw new IllegalArgumentException("No primary type associated: " + getTableName() + "." + getName() );
110     }
111 
112     /**
113      * return internal type for the current column
114      */
115     public int getMappedType() {
116         switch(getType()) {
117         case Types.ARRAY: return M_ARRAY;
118         case Types.BIGINT : return M_LONG;
119         case Types.BINARY : return M_BYTES;
120         case Types.BIT : return M_BOOLEAN;
121         case Types.BLOB : return M_BLOB;
122         case Types.BOOLEAN : return M_BOOLEAN;
123         case Types.CHAR : return M_STRING;
124         case Types.CLOB : return M_CLOB;
125         case Types.DATALINK : return M_URL;
126         case Types.DATE :
127             if (CodeWriter.dateClassName.equals("java.util.Date")) return M_UTILDATE;
128             if (CodeWriter.dateClassName.equals("java.sql.Date")) return M_SQLDATE;
129             if (CodeWriter.dateClassName.equals("java.util.Calendar")) return M_CALENDAR; // moscac 2007-08-09 
130             tuoe();
131         case Types.DECIMAL : return getDecimalDigits() > 0 ? M_BIGDECIMAL : M_LONG;
132         case Types.DISTINCT : return M_OBJECT;
133         case Types.DOUBLE : return M_DOUBLE;
134         case Types.FLOAT : return M_DOUBLE;
135         case Types.INTEGER :return M_INTEGER;
136         case Types.JAVA_OBJECT : return M_OBJECT;
137         case Types.LONGVARBINARY :return M_BYTES;
138         case Types.LONGVARCHAR : return M_STRING;
139 
140 //        case Types.NULL : return M_NULL;
141 
142         case Types.NUMERIC : return getDecimalDigits() > 0 ? M_BIGDECIMAL : M_LONG;
143         case Types.OTHER : return M_OBJECT;
144         case Types.REAL : return M_FLOAT;
145         case Types.REF : return M_REF;
146         case Types.SMALLINT :return M_INTEGER;
147         case Types.STRUCT : return M_OBJECT;
148         case Types.TIME :
149             if (CodeWriter.timeClassName.equals("java.util.Date")) return M_UTILDATE;
150             if (CodeWriter.timeClassName.equals("java.sql.Time")) return M_TIME;
151             if (CodeWriter.timeClassName.equals("java.util.Calendar")) return M_CALENDAR; // moscac 2007-08-09 
152             tuoe();
153         case Types.TIMESTAMP :
154             if (CodeWriter.timestampClassName.equals("java.util.Date")) return M_UTILDATE;
155             if (CodeWriter.timestampClassName.equals("java.sql.Timestamp")) return M_TIMESTAMP;
156             if (CodeWriter.timestampClassName.equals("java.util.Calendar")) return M_CALENDAR; // moscac 2007-08-09 
157             tuoe();
158         case Types.TINYINT :return M_INTEGER;
159         case Types.VARBINARY :return M_BYTES;
160         case Types.VARCHAR :return M_STRING;
161         default:tuoe();
162         }
163         return -1;
164     }
165 
166     // Convernient helpers:
167     public String getQuerySetMethod() {
168         switch(getType()) {
169         case Types.ARRAY: return "setArray";
170         case Types.BIGINT : return "setBigDecimal";
171         case Types.BINARY : return "setBytes";
172         case Types.BIT : return "setBoolean";
173         case Types.BLOB : return "setBlob";
174         case Types.BOOLEAN : return "setBoolean";
175         case Types.CHAR : return "setString";
176         case Types.CLOB : return "setClob";
177         case Types.DATALINK : return "setURL";
178         case Types.DATE : return "setDate";
179         case Types.DECIMAL : return getDecimalDigits() > 0 ? "setBigDecimal" : "setLong";
180         case Types.DISTINCT : return "setObject";
181         case Types.DOUBLE : return "setDouble";
182         case Types.FLOAT : return "setDouble";
183         case Types.INTEGER :return "setInt";
184         case Types.JAVA_OBJECT : return "setObject";
185         case Types.LONGVARBINARY :return "setBytes";
186         case Types.LONGVARCHAR : return "setString";
187 
188 //        case Types.NULL : return M_NULL;
189 
190         case Types.NUMERIC : return getDecimalDigits() > 0 ? "setBigDecimal" : "setLong";
191         case Types.OTHER : return "setObject";
192         case Types.REAL : return "setFloat";
193         case Types.REF : return "setRef";
194         case Types.SMALLINT :return "setInt";
195         case Types.STRUCT : return "setObject";
196         case Types.TIME :
197             if (CodeWriter.timeClassName.equals("java.util.Date")) return "setDate";
198             if (CodeWriter.timeClassName.equals("java.sql.Time")) return "setTime";
199             tuoe();
200         case Types.TIMESTAMP :
201             if (CodeWriter.timestampClassName.equals("java.util.Date")) return "setDate";
202             if (CodeWriter.timestampClassName.equals("java.sql.Timestamp")) return "setTimestamp";
203             tuoe();
204         case Types.TINYINT :return "setInt";
205         case Types.VARBINARY :return "setBytes";
206         case Types.VARCHAR :return "setString";
207         default:tuoe();
208         }
209         return "setObject";
210     }
211 
212     /**
213      * return the java type of the current column
214      */
215     public String getJavaType()
216     {
217         switch (getMappedType())
218         {
219         case M_ARRAY: return "Array";
220         case M_BIGDECIMAL: return "java.math.BigDecimal";
221         case M_BOOLEAN: return "Boolean";
222         case M_BYTES: return "byte[]";
223         case M_CLOB: return "Clob";
224         case M_SQLDATE: return "java.sql.Date";
225         case M_UTILDATE: return "java.util.Date";
226         case M_DOUBLE: return "Double";
227         case M_FLOAT: return "Float";
228         case M_INTEGER: return "Integer";
229         case M_LONG: return "Long";
230         case M_REF: return "Ref";
231         case M_STRING: return "String";
232         case M_TIME: return "java.sql.Time";
233         case M_TIMESTAMP: return "java.sql.Timestamp";
234         case M_URL: return "java.net.URL";
235         case M_OBJECT: return "Object";
236         case M_CALENDAR : return "java.util.Calendar"; // moscac 2007-08-09  
237         }
238         return null;
239     }
240 
241     /**
242      * does this column has a primary java type like short, boolean instead of Integer and Boolean ?
243      */
244     public boolean hasPrimaryType()
245     {
246         return (getJavaPrimaryType() != null);
247     }
248 
249     /**
250      * return the primary java type of the current column
251      * return null if no java primary type is available
252      */
253     public String getJavaPrimaryType() throws IllegalArgumentException
254     {
255         int decimalDigits = getDecimalDigits();
256         if ((type == Types.DECIMAL || type == Types.NUMERIC) && decimalDigits == 0) {
257             if (size == 1) {
258                 return "boolean";
259             }
260             else if (size < 3) {
261                 return "byte";
262             }
263             else if (size < 5) {
264                 return "short";
265             }
266             else if (size < 10) {
267                 return "int";
268             }
269             else if (size < 19) {
270                 return "long";
271             }
272             else {
273                 // return "java.math.BigDecimal";
274             }
275         }
276         switch (getMappedType())
277         {
278             case M_BOOLEAN: return "boolean";
279             case M_SQLDATE: return "long";
280             case M_UTILDATE: return "long";
281             case M_DOUBLE: return "double";
282             case M_FLOAT: return "float";
283             case M_INTEGER: return "int";
284             case M_LONG: return "long";
285             case M_TIME: return "long";
286             case M_TIMESTAMP: return "long";
287             default:break;
288         }
289         return null;
290     }
291 
292     /**
293      * return the string representation of the column type
294      */
295     public String getJavaTypeAsTypeName()
296     {
297         switch (getType())
298         {
299         case Types.ARRAY:          return "Types.ARRAY";
300         case Types.BIGINT :        return "Types.BIGINT";
301         case Types.BINARY :        return "Types.BINARY";
302         case Types.BIT :           return "Types.BIT";
303         case Types.BLOB :          return "Types.BLOB";
304         case Types.BOOLEAN :       return "Types.BOOLEAN";
305         case Types.CHAR :          return "Types.CHAR";
306         case Types.CLOB :          return "Types.CLOB";
307         case Types.DATALINK :      return "Types.DATALINK";
308         case Types.DATE :          return "Types.DATE";
309         case Types.DECIMAL :       return "Types.DECIMAL";
310         case Types.DISTINCT :      return "Types.DISTINCT";
311         case Types.DOUBLE :        return "Types.DOUBLE";
312         case Types.FLOAT :         return "Types.FLOAT";
313         case Types.INTEGER :       return "Types.INTEGER";
314         case Types.JAVA_OBJECT :   return "Types.JAVA_OBJECT";
315         case Types.LONGVARBINARY : return "Types.LONGVARBINARY";
316         case Types.LONGVARCHAR :   return "Types.LONGVARCHAR";
317         case Types.NULL :          return "Types.NULL";
318         case Types.NUMERIC :       return "Types.NUMERIC";
319         case Types.OTHER :         return "Types.OTHER";
320         case Types.REAL :          return "Types.REAL";
321         case Types.REF :           return "Types.REF";
322         case Types.SMALLINT :      return "Types.SMALLINT";
323         case Types.STRUCT :        return "Types.STRUCT";
324         case Types.TIME :          return "Types.TIME";
325         case Types.TIMESTAMP :     return "Types.TIMESTAMP";
326         case Types.TINYINT :       return "Types.TINYINT";
327         case Types.VARBINARY :     return "Types.VARBINARY";
328         case Types.VARCHAR :       return "Types.VARCHAR";
329         }
330         return "unkown SQL type " + getType();
331     }
332 
333     /**
334      * is this column numeric ?
335      */
336     public boolean isColumnNumeric()
337     {
338         switch (getMappedType())
339         {
340         case M_DOUBLE:  // fall through
341         case M_FLOAT:   // fall through
342         case M_INTEGER: // fall through
343         case M_LONG: return true;
344         default: return false;
345         }
346     }
347 
348     /**
349      * is this column a string ?
350      */
351     public boolean isString()
352     {
353 		if (getMappedType() == M_STRING)
354 		    return true;
355         return false;
356     }
357 
358     public boolean isDate()
359     {
360         switch(getMappedType())
361         {
362         case M_UTILDATE:
363         case M_TIME:
364         case M_TIMESTAMP: return true;
365         default:
366             return false;
367         }
368     }
369 
370     // moscac 2007-08-09
371     public boolean isCalendar() {
372     	return (getMappedType() == M_CALENDAR); 
373     }
374 
375     /**
376      * does this type has a compareTo method ?
377      */
378     public boolean hasCompareTo() throws Exception
379     {
380         switch(getMappedType())
381         {
382         case M_ARRAY: return false;
383         case M_BIGDECIMAL: return true;
384         case M_BOOLEAN: return false; // USE EQUALS INSTEAD
385         case M_BYTES: return false;
386         case M_CLOB: return false;
387         case M_SQLDATE: return true;
388         case M_UTILDATE: return true;
389         case M_DOUBLE: return true;
390         case M_FLOAT: return true;
391         case M_INTEGER: return true;
392         case M_LONG: return true;
393         case M_REF: return false;
394         case M_STRING: return true;
395         case M_TIME: return true;
396         case M_TIMESTAMP: return true;
397         case M_URL: return false;
398         case M_OBJECT: return false;
399         default: return false;
400         }
401     }
402 
403     /**
404      * does this type can use equal instead of the compareTo method ?
405      */
406     public boolean useEqualsInSetter() throws Exception
407     {
408         switch(getMappedType())
409         {
410         case M_BOOLEAN: return true;
411         default: return false;
412         }
413     }
414 
415     /**
416      * return the resultSet get method for a given position
417      * the assumption is that the resultset variable is called rs
418      */
419     public String getResultSetMethodObject(String pos)
420     {
421         return getResultSetMethodObject("rs", pos);
422     }
423 
424     public String getResultSetMethodObject(String resultSet, String pos)
425     {
426         switch (getMappedType())
427         {
428         case M_ARRAY: return resultSet + ".getArray(" + pos + ")";
429         case M_LONG : return CodeWriter.MGR_CLASS + ".getLong(" + resultSet + ", "+pos+")";
430         case M_BYTES : return resultSet + ".getBytes(" + pos + ")";
431         case M_BLOB : return resultSet + ".getBlob("+pos+")";
432         case M_BOOLEAN :  return CodeWriter.MGR_CLASS + ".getBoolean(" + resultSet +  ", "+pos+")";
433         case M_STRING : return resultSet + ".getString(" + pos + ")";
434         case M_CLOB : return resultSet + ".getClob("+pos+")";
435         case M_URL : return resultSet + ".getURL("+pos+")";
436         case M_BIGDECIMAL : return resultSet + ".getBigDecimal(" + pos + ")";
437         case M_DOUBLE : return CodeWriter.MGR_CLASS + ".getDouble(" + resultSet + ", "+pos+")";
438         case M_FLOAT :  return CodeWriter.MGR_CLASS + ".getFloat(" + resultSet + ", "+pos+")";
439         case M_INTEGER : return CodeWriter.MGR_CLASS + ".getInteger(" + resultSet + ", "+pos+")";
440 
441         case M_OBJECT : return resultSet + ".getObject("+pos+")";
442         case M_REF : return resultSet + ".getRef("+pos+")";
443         case M_SQLDATE : return resultSet + ".getDate(" + pos + ")";
444         case M_TIME :return resultSet + ".getTime(" + pos + ")";
445         case M_TIMESTAMP :return resultSet + ".getTimestamp(" + pos + ")";
446         case M_UTILDATE :
447             switch(getType()) {
448             case Types.TIME:  return resultSet + ".getTime(" + pos + ")";
449             case Types.TIMESTAMP: return resultSet + ".getTimestamp(" + pos + ")";
450             case Types.DATE: return resultSet + ".getDate(" + pos + ")";
451             }
452         case M_CALENDAR : return CodeWriter.MGR_CLASS + ".getCalendar(" + resultSet + ", " + pos + ")"; // moscac 2007-08-09  
453         default:tuoe();
454         }
455         return null;
456     }
457 
458 
459     /**
460      * Maps the SQL type for the column to a "set" method to call on
461      * the PreparedStatement.
462      * <br>
463      * This is used when generating Manager classes. There are some
464      * variations in how different databases may deal with this, so you
465      * might look at the OracleManagerWriter to see how you might have
466      * to override this method for your particular database.
467      *
468      * @param var Java code that represents how we'll get access to the
469      *            value to set. You should be able to use this value
470      *            verbatim. Check out the source to this method to
471      *            see what we mean.
472      * @param pos The position to pass as the first argument of the set
473      *            method. You will be able to use this verbatim too.
474      * @return    The string to write into the generated Manager .java file.
475      */
476     public String getPreparedStatementMethod(String var,int pos)
477     {
478       return getPreparedStatementMethod(var, Integer.toString(pos));
479     }
480 
481     public String getPreparedStatementMethod(String var, String pos)
482     {
483     	StringBuffer sb = new StringBuffer();
484     	sb.append("if (")
485     			.append(var)
486     			.append(" == null) ps.setNull(")
487     			.append(pos)
488     			.append(", ")
489     			.append(getJavaTypeAsTypeName())
490     			.append("); else ");
491     	String end = pos + ", " + var + ");";
492         switch(getMappedType())
493         {
494         case M_ARRAY: return sb.append("ps.setArray(").append(end).toString();
495         case M_LONG: return sb.append("Manager.setLong(ps, ").append(end).toString();
496         case M_BYTES: return sb.append("ps.setBytes(").append(end).toString();
497         case M_BLOB : return sb.append("ps.setBlob(").append(end).toString();
498         case M_BOOLEAN : return sb.append("Manager.setBoolean(ps, ").append(end).toString();
499         case M_STRING:return sb.append("ps.setString(").append(end).toString();
500         case M_CLOB : return sb.append("ps.setClob(").append(end).toString();
501         case M_URL : return sb.append("ps.setURL(").append(end).toString();
502         case M_BIGDECIMAL: return sb.append("ps.setBigDecimal(").append(end).toString();
503         case M_DOUBLE:  return sb.append("Manager.setDouble(ps, ").append(end).toString();
504         case M_INTEGER:  return sb.append("Manager.setInteger(ps, ").append(end).toString();
505         case M_OBJECT : return sb.append("ps.setObject(").append(end).toString();
506         case M_FLOAT:  return sb.append("Manager.setFloat(ps, ").append(end).toString();
507         case M_SQLDATE: return sb.append("ps.setDate(").append(end).toString();
508         case M_TIME: return sb.append("ps.setTime(").append(end).toString();
509         case M_TIMESTAMP: return sb.append("ps.setTimestamp(").append(end).toString();
510         case M_UTILDATE:
511             switch(getType()) {
512             case Types.TIMESTAMP: return sb.append("ps.setTimestamp(").append(pos).append(", new java.sql.Timestamp(").append(var).append(".getTime()));").toString();
513             case Types.DATE: return sb.append("ps.setDate(").append(pos).append(", new java.sql.Date(").append(var).append(".getTime()));").toString();
514             case Types.TIME: return sb.append("ps.setTime(").append(pos).append(", new java.sql.Time(").append(var).append(".getTime()));").toString();
515             default: return null;
516             }
517         case M_CALENDAR: return sb.append("Manager.setCalendar(ps, ").append(end).toString(); // moscac 2007-08-09
518         case M_REF: return "ps.setRef(" + end;
519         default: return "ps.setObject(" + end;
520         }
521     }
522 
523     /**
524      * method to convert the given string into the internal java representation
525      */
526 	public String getStringConvertionMethod()
527 	{
528 		switch (getMappedType())
529 		{
530         case M_BIGDECIMAL: return "new java.math.BigDecimal";
531         case M_BOOLEAN: return "new Boolean";
532         case M_SQLDATE: return "new java.sql.Date";
533         case M_DOUBLE: return "new Double";
534         case M_FLOAT: return "new Float";
535         case M_INTEGER: return "new Integer";
536         case M_LONG: return "new Long";
537         case M_STRING: return "";
538         case M_TIME:
539         case M_TIMESTAMP:
540         case M_UTILDATE:
541                 if (CodeWriter.dateClassName.equals("java.util.GregorianCalendar"))
542         			return "GregorianDate";
543         		else
544         			return "Manager.getDateFromString";
545         case M_URL:
546         case M_OBJECT:
547         case M_REF:
548         case M_ARRAY:
549         case M_BYTES:
550         case M_CLOB:
551         default:
552             System.err.println(" unknown mapped type " + getMappedType() + " (" + getType() + ") for " + getFullName());
553             return "";
554 		}
555 	}
556 
557     /*
558      * get the default widget name for the current column
559      */
560 	public String getDefaultWidget()
561 	{
562 	    if (isForeignKey())
563 	        return "SelectWidget";
564         if (isString() && (getSize() > 200 || getSize() == -1))
565             return "TextAreaWidget";
566 
567 		switch (getMappedType())
568 		{
569         case M_BOOLEAN: return "BooleanWidget";
570         case M_TIME:
571         case M_TIMESTAMP:
572         case M_UTILDATE:
573         case M_SQLDATE: return "DateWidget";
574         case M_BIGDECIMAL:
575         case M_DOUBLE:
576         case M_FLOAT:
577         case M_INTEGER:
578         case M_LONG: return "NumericWidget";
579         case M_URL:
580         case M_OBJECT:
581         case M_REF:
582         case M_ARRAY:
583         case M_BYTES:
584         case M_CLOB:
585         case M_STRING: return "InputWidget";
586         default:
587             System.err.println("type unknown for " + getFullName());
588             return "";
589 		}
590 	}
591 
592     public boolean isVersion()
593     {
594 	if (CodeWriter.optimisticLockType.equalsIgnoreCase("timestamp") == false)
595 	    return false;
596 	if (getName().equalsIgnoreCase(CodeWriter.optimisticLockColumn) == false)
597 	    return false;
598         if (getMappedType()==Column.M_LONG || getMappedType()==Column.M_STRING)
599 	    return true;
600 	return false;
601     }
602 
603     public Table getTable()
604     {
605         return db.getTable(getTableName());
606     }
607 
608     public void addForeignKey(Column col)
609     {
610         foreignKeys.add(col);
611         getTable().addForeignKey(this);
612     }
613 
614     public List getForeignKeys()
615     {
616         return foreignKeys;
617     }
618 
619     public void addImportedKey(Column col)
620     {
621         importedKeys.add(col);
622         getTable().addImportedKey(col);
623     }
624 
625     public List getImportedKeys()
626     {
627         return importedKeys;
628     }
629 
630     public int countImportedKeys()
631     {
632         return importedKeys.size();
633     }
634 
635     public boolean isImportedKey()
636     {
637         if (countImportedKeys() > 0)
638             return true;
639         return false;
640     }
641 
642     public Column getForeignColumn()
643     {
644         return (Column)foreignKeys.get(0);
645     }
646 
647     public int countForeignKeys()
648     {
649         return foreignKeys.size();
650     }
651 
652     public boolean isForeignKey()
653     {
654         if (countForeignKeys() > 0)
655             return true;
656         return false;
657     }
658 
659     public String getPropertyTag()
660     {
661         return (getTableName() + "." + getName()).toLowerCase();
662     }
663 
664     public String getDefaultRules()
665     {
666         String rule = "";
667 		if (getNullable() == 0 && isPrimaryKey() == false)
668 			rule = rule + " nullnotallowed";
669 		else
670 			rule = rule + " nullallowed";
671 		if (getType() == Types.DATE || getType() == Types.TIMESTAMP)
672 			rule = rule + " dateformat";
673         return rule;
674     }
675 
676     /**
677      * is this column described to be in the given type ?
678      * check in sql2java.properties the table.[TABLENAME].in.[TYPE].exclude & table.[TABLENAME].in.[TYPE].include
679      */
680     public boolean columnFor(String webElement)
681     {
682         String includeProperty = ConfigHelper.getXPathProperty("//table[@name='" + getTableName() + "']/frontend/" + webElement, "include");
683         String excludeProperty = ConfigHelper.getXPathProperty("//table[@name='" + getTableName() + "']/frontend/" + webElement, "exclude");
684         String[] exclude = CodeWriter.getExplodedString(excludeProperty);
685         String[] include = CodeWriter.getExplodedString(includeProperty);
686         if (exclude.length == 0 && include.length == 0)
687             return getDefaultIncludeFor(webElement);
688         if (Main.isInArray(include, getName()))
689             return true;
690         if (Main.isInArray(exclude, getName()))
691             return false;
692         if (include.length == 0)
693             return true;
694         return false;
695     }
696 
697     /**
698      * some columns with certain names should be by default
699      * discarded such as timestamp, optimistic, id and so on ...
700      */
701     public boolean getDefaultIncludeFor(String webElement)
702     {
703         return true;
704     }
705 
706     public String getDefaultValue()
707     {
708         // if specified in XML take over
709         String xmlDefaultValue = ConfigHelper.getColumnProperty(getTableName(), getName(), "defaultValue");
710         if (xmlDefaultValue != null && !"".equals(xmlDefaultValue))
711             return xmlDefaultValue;
712         if (null != defaultValue) {
713             if (isColumnNumeric()) {
714                 try {
715                     double value = Double.parseDouble(defaultValue);
716                     return defaultValue + "; // " + String.valueOf(value);
717                 } catch (NumberFormatException nfe) {
718                     return "0; // " + defaultValue;
719                 }
720             } else if (isDate()) {
721                 try {
722                     Date date = SimpleDateFormat.getInstance().parse(defaultValue);
723                     return defaultValue + "; // " + SimpleDateFormat.getInstance().format(date);
724                 } catch (ParseException pe) {
725                     return "null; // " + defaultValue;
726                 }
727             }
728         }
729         return defaultValue==null?"":defaultValue;
730     }
731 
732     public String getRemarks()
733     {
734         // if specified in XML take over
735         String xmlDefaultValue = ConfigHelper.getColumnProperty(getTableName(), getName(), "description");
736         if (xmlDefaultValue != null && !"".equals(xmlDefaultValue))
737             return xmlDefaultValue;
738         return remarks==null?"":remarks;
739     }
740 
741     public String getJavaName()
742     {
743         return convertName(getName());
744     }
745 
746 
747     private static Random rand = new Random();
748     public String getSampleData()
749     {
750         if (getNullable() > 1 && rand.nextInt(20) == 10)
751             return "";
752         if (isColumnNumeric())
753             return "" + rand.nextInt(100);
754         if (isDate())
755 	{
756 	    Calendar rightNow = Calendar.getInstance();
757 	    rightNow.set(2000 + rand.nextInt(20), 1+rand.nextInt(12), 1 + rand.nextInt(28), rand.nextInt(23) , rand.nextInt(60), rand.nextInt(60));
758 	    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
759 	    return dateFormat.format(rightNow.getTime());
760 	}
761 
762         return StringUtilities.getSampleString(getSize());
763     }
764 
765     private String escape(String s) {
766         return StringUtilities.escape(s);
767     }
768 
769     private String escape() {
770         return escape(this.getName());
771     }
772 
773     public String convertName(String columnName) {
774         return StringUtilities.convertName(columnName, true);
775     }
776 
777     public String convertName(Column col) {
778         return convertName(col.getName());
779     }
780 
781 	public String convertName() {
782         return convertName(this.name);
783     }
784 
785     public String getImportedKeyVarName() {
786         return convertName(escape() + "_collection");
787     }
788 
789     public String getGetMethod() {
790         return convertName("get_" + escape());
791     }
792 
793     public String getSetMethod() {
794         return convertName("set_" + escape());
795     }
796 
797     public String getModifiedMethod() {
798         return convertName("is_" + escape() + "_modified");
799     }
800 
801     public String getInitializedMethod() {
802         return convertName("is_" + escape() + "_initialized");
803     }
804 
805     public String getWidgetMethod() {
806         return convertName("get_" + escape() + "_widget");
807     }
808 
809     public String getVarName()  {
810         return convertName(escape());
811     }
812 
813     public String getModifiedVarName() {
814         return getVarName() + "_is_modified"; // already escaped
815     }
816 
817     public String getInitializedVarName() {
818         return getVarName() + "_is_initialized";// already escaped
819     }
820 
821     public String getImportedKeyModifiedVarName() {
822         return getVarName() + "_collection_is_modified"; // already escaped
823     }
824 
825     public String getImportedKeyInitializedVarName() {
826         return getVarName() + "_collection_is_initialized";// already escaped
827     }
828 
829     public String getImportedKeyInitializedMethod() {
830         return convertName("is_" + escape() + "_collection_initialized");
831     }
832 
833     public String getImportedKeyGetMethod() {
834         return convertName("get_" + escape() + "_collection");
835     }
836 
837     public String getImportedKeyAddMethod() {
838         return convertName("add_" + escape() + "");
839     }
840 
841     public String getImportedKeySetMethod() {
842         return convertName("set_" + escape() + "_collection");
843     }
844 
845     public String getImportedKeyModifiedMethod() {
846         return convertName("is_" + escape() + "_collection_modified");
847     }
848 
849     public String getForeignKeyVarName() {
850         return convertName(escape() + "_object");
851     }
852 
853     public String getForeignKeyModifiedVarName() {
854         return getVarName() + "_object_is_modified"; // already escaped
855     }
856 
857     public String getForeignKeyInitializedVarName() {
858         return getVarName() + "_object_is_initialized";// already escaped
859     }
860 
861     public String getForeignKeyInitializedMethod() {
862         return convertName("is_" + escape() + "_object_initialized");
863     }
864 
865     public String getForeignKeyGetMethod(String  col) {
866         return convertName("get_" + escape() + "_object");
867     }
868 
869     public String getForeignKeySetMethod(String  col) {
870         return convertName("set_" + escape() + "_object");
871     }
872 
873     public String getForeignKeyModifiedMethod(String  col) {
874         return convertName("is_" + escape() + "_object_modified");
875     }
876 
877 }