001: /**
002: * Objective Database Abstraction Layer (ODAL)
003: * Copyright (c) 2004, The ODAL Development Group
004: * All rights reserved.
005: * For definition of the ODAL Development Group please refer to LICENCE.txt file
006: *
007: * Distributable under LGPL license.
008: * See terms of license at gnu.org.
009: */package com.completex.objective.components.persistency;
010:
011: import com.completex.objective.components.persistency.key.AutoKeyGenerator;
012: import com.completex.objective.components.persistency.key.impl.AbstractSimpleSequenceKeyGenerator;
013: import com.completex.objective.components.persistency.type.TypeHandler;
014: import com.completex.objective.components.OdalRuntimeException;
015: import com.completex.objective.util.StringUtil;
016: import com.completex.objective.util.TypeUtil;
017:
018: import java.util.HashMap;
019: import java.util.LinkedHashMap;
020: import java.util.LinkedHashSet;
021: import java.util.Map;
022: import java.util.Set;
023:
024: /**
025: * @author Gennady Krizhevsky
026: */
027: public class MetaColumn implements ModelConsts, Cloneable,
028: DescriptorMappable {
029:
030: protected static final Set DEFAULT_LAST_UPDATED_NAMES = new LinkedHashSet();
031:
032: static {
033: DEFAULT_LAST_UPDATED_NAMES.add("LAST_UPDATED");
034: }
035:
036: protected static final GeneratorStruct DEFAULT_LAST_UPDATED_GENERATOR_STRUCT = new GeneratorStruct(
037: DEFAULT_LAST_UPDATED_NAMES, true);
038:
039: protected static final Set DEFAULT_CREATION_DATE_NAMES = new LinkedHashSet();
040:
041: static {
042: DEFAULT_CREATION_DATE_NAMES.add("CREATION_DATE");
043: }
044:
045: protected static final GeneratorStruct DEFAULT_CREATION_DATE_GENERATOR_STRUCT = new GeneratorStruct(
046: DEFAULT_CREATION_DATE_NAMES, true);
047:
048: // This property is used only for code generation:
049: protected int columnIndex = -1;
050: protected String columnName;
051: protected String columnAlias;
052: protected boolean isPrimaryKey;
053: protected boolean isRequired;
054: protected boolean optimisticLock;
055: protected String remarks;
056: protected String defaultValue;
057: protected int decimalDigits;
058: protected int columnSize;
059: protected boolean exclude;
060: protected boolean transformed;
061:
062: protected GeneratorStruct lastUpdatedNames = DEFAULT_LAST_UPDATED_GENERATOR_STRUCT;
063: protected GeneratorStruct creationDateNames = DEFAULT_CREATION_DATE_GENERATOR_STRUCT;
064:
065: protected MetaTable table;
066: protected ColumnType type;
067: protected String typeName;
068: protected TypeHandler typeHandler;
069: protected int jdbcType;
070: // If this field is generated by the database
071: protected boolean autoIncrement;
072: /**
073: * Key generator portion:
074: * keyGenerator={
075: * databaseGenerated = FALSE
076: * # if databaseGenerated = TRUE then class/staticAttributes/dynamicAttributes -
077: * # unnecessary or will be ignored;
078: * # if databaseGenerated = FALSE class MUST be populated
079: * class=com.completex.objective.components.persistency.key.impl.SimpleSequenceKeyGeneratorImpl
080: * staticAttributes = {name=TEST_MASTER_SEQ}
081: * }
082: */
083: protected boolean autoGenerated;
084: protected String generatorClassName;
085: protected Map generatorStaticAttributes = new LinkedHashMap(0);
086: private AutoKeyGenerator keyGenerator;
087: public static final int INDENT = 20;
088: public static final int INDENT_2 = 25;
089:
090: public MetaColumn() {
091: }
092:
093: public MetaColumn(MetaTable table) {
094: this .table = table;
095: }
096:
097: public MetaColumn(String columnName, MetaTable table) {
098: this .columnName = columnName;
099: this .table = table;
100: }
101:
102: public MetaColumn(int columnIndex, String columnName,
103: String columnAlias, MetaTable table) {
104: this .columnIndex = columnIndex;
105: this .columnName = columnName;
106: this .columnAlias = columnAlias;
107: this .table = table;
108: }
109:
110: /**
111: * Creates and sets AutoKeyGenerator out of generator class name
112: */
113: public void initializeKeyGenerator() {
114: if (autoGenerated && keyGenerator == null) {
115: if (generatorClassName != null) {
116: this .keyGenerator = newAutoKeyGenerator(generatorClassName);
117: } else {
118: throw new IllegalArgumentException(
119: "generatorClassName is null for column " + this );
120: }
121: }
122: this .keyGenerator
123: .setStaticParameters(generatorStaticAttributes);
124: }
125:
126: /**
127: * @param keyGenerator AutoKeyGenerator
128: */
129: public void setKeyGenerator(AutoKeyGenerator keyGenerator) {
130: this .keyGenerator = keyGenerator;
131: }
132:
133: /**
134: * @return AutoKeyGenerator
135: */
136: public AutoKeyGenerator getKeyGenerator() {
137: return keyGenerator;
138: }
139:
140: private AutoKeyGenerator newAutoKeyGenerator(String className) {
141: try {
142: Object obj = Class.forName(className).newInstance();
143: return (AutoKeyGenerator) obj;
144: } catch (Throwable e) {
145: throw new OdalRuntimeException(
146: "Cannot get new instance of AutoKeyGenerator by class name "
147: + className, e);
148: }
149: }
150:
151: /**
152: * Returns true is this is optimistic lock column
153: *
154: * @return true is this is optimistic lock column
155: */
156: public boolean isOptimisticLock() {
157: return optimisticLock;
158: }
159:
160: /**
161: * Sets optimisticLock true if this is optimistic lock column
162: *
163: * @param optimisticLock true if this is optimistic lock column
164: */
165: public void setOptimisticLock(boolean optimisticLock) {
166: this .optimisticLock = optimisticLock;
167: }
168:
169: /**
170: * Returns JDBC typeName
171: *
172: * @return JDBC typeName
173: */
174: public String getTypeName() {
175: return typeName;
176: }
177:
178: /**
179: * Sets JDBC typeName
180: *
181: * @param typeName JDBC typeName
182: */
183: public void setTypeName(String typeName) {
184: this .typeName = typeName;
185: }
186:
187: /**
188: * Returns database table name
189: *
190: * @return database table name
191: */
192: public String getTableName() {
193: return table == null ? null : table.getTableName();
194: }
195:
196: /**
197: * Sets table database table name
198: *
199: * @param table database table name
200: */
201: public void setTable(MetaTable table) {
202: this .table = table;
203: }
204:
205: /**
206: * Returns decimal digits for numeric column
207: *
208: * @return decimal digits for numeric column
209: */
210: public int getDecimalDigits() {
211: return decimalDigits;
212: }
213:
214: /**
215: * Sets decimal digits for numeric column
216: *
217: * @param decimalDigits ecimal digits for numeric column
218: */
219: public void setDecimalDigits(int decimalDigits) {
220: this .decimalDigits = decimalDigits;
221: }
222:
223: /**
224: * Returns column size for string column
225: *
226: * @return column size for string column
227: */
228: public int getColumnSize() {
229: return columnSize;
230: }
231:
232: /**
233: * Sets column size for string column
234: *
235: * @param columnSize column size for string column
236: */
237: public void setColumnSize(int columnSize) {
238: this .columnSize = columnSize;
239: }
240:
241: /**
242: * Returns 0-based column index
243: *
244: * @return 0-based column index
245: */
246: public int getColumnIndex() {
247: return columnIndex;
248: }
249:
250: /**
251: * Sets 0-based column index
252: *
253: * @param columnIndex 0-based column index
254: */
255: public void setColumnIndex(int columnIndex) {
256: this .columnIndex = columnIndex;
257: }
258:
259: /**
260: * Returns column name as it is in database table
261: *
262: * @return column name as it is in database table
263: */
264: public String getColumnName() {
265: return columnName;
266: }
267:
268: /**
269: * Sets column name as it is in database table
270: *
271: * @param columnName column name as it is in database table
272: */
273: public void setColumnName(String columnName) {
274: this .columnName = columnName;
275: }
276:
277: /**
278: * Returns column alias that is used as a base for getters and setters of generated persistent objects
279: *
280: * @return column alias that is used as a base for getters and setters of generated persistent objects
281: */
282: public String getColumnAlias() {
283: return columnAlias == null ? columnName : columnAlias;
284: }
285:
286: /**
287: * Sets column alias that is used as a base for getters and setters of generated persistent objects
288: *
289: * @param columnAlias column alias that is used as a base for getters and setters of generated persistent objects
290: */
291: public void setColumnAlias(String columnAlias) {
292: this .columnAlias = columnAlias;
293: }
294:
295: /**
296: * Returns true if this column is part of primary key
297: *
298: * @return true if this column is part of primary key
299: */
300: public boolean isPrimaryKey() {
301: return isPrimaryKey;
302: }
303:
304: /**
305: * Sets true if this column is part of primary key
306: *
307: * @param primaryKey true if this column is part of primary key
308: */
309: public void setPrimaryKey(boolean primaryKey) {
310: isPrimaryKey = primaryKey;
311: }
312:
313: /**
314: * Returns true if this column value is required
315: *
316: * @return true if this column value is required
317: */
318: public boolean isRequired() {
319: return isRequired;
320: }
321:
322: /**
323: * Sets true if this column value is required
324: *
325: * @param required true if this column value is required
326: */
327: public void setRequired(boolean required) {
328: isRequired = required;
329: }
330:
331: /**
332: * Returns JDBC column remarks
333: *
334: * @return JDBC column remarks
335: */
336: public String getRemarks() {
337: return remarks;
338: }
339:
340: /**
341: * Sets JDBC column remarks
342: *
343: * @param remarks JDBC column remarks
344: */
345: public void setRemarks(String remarks) {
346: this .remarks = remarks;
347: }
348:
349: /**
350: * Returns JDBC column default value
351: *
352: * @return JDBC column default value
353: */
354: public String getDefaultValue() {
355: return defaultValue;
356: }
357:
358: /**
359: * Sets JDBC column default value
360: *
361: * @param defaultValue JDBC column default value
362: */
363: public void setDefaultValue(String defaultValue) {
364: this .defaultValue = defaultValue;
365: }
366:
367: /**
368: * Returns column type
369: *
370: * @return column type
371: * @see ColumnType
372: */
373: public ColumnType getType() {
374: return type;
375: }
376:
377: /**
378: * Sets column type
379: *
380: * @param type column type
381: * @see ColumnType
382: */
383: public void setType(ColumnType type) {
384: this .type = type;
385: }
386:
387: /**
388: * Returns JDBC column type
389: *
390: * @return JDBC column type
391: * @see java.sql.Types
392: */
393: public int getJdbcType() {
394: return jdbcType;
395: }
396:
397: /**
398: * Sets JDBC column type
399: *
400: * @param jdbcType JDBC column type
401: */
402: public void setJdbcType(int jdbcType) {
403: this .jdbcType = jdbcType;
404: }
405:
406: /**
407: * Column type handler is optional - if not set default one for this ColumnType will be used
408: *
409: * @return TypeHandler column type handler
410: * @see TypeHandler
411: */
412: public TypeHandler getTypeHandler() {
413: return typeHandler;
414: }
415:
416: /**
417: * Column type handler is optional - if not set default one for this ColumnType will be used
418: *
419: * @param typeHandler column type handler
420: * @see TypeHandler
421: */
422: public void setTypeHandler(TypeHandler typeHandler) {
423: this .typeHandler = typeHandler;
424: }
425:
426: /**
427: * Returns value generator class name for this column
428: *
429: * @return value generator class name for this column
430: */
431: public String getGeneratorClassName() {
432: return generatorClassName;
433: }
434:
435: /**
436: * Sets value generator class name for this column
437: *
438: * @param generatorClassName value generator class name for this column
439: */
440: public void setGeneratorClassName(String generatorClassName) {
441: this .generatorClassName = generatorClassName;
442: }
443:
444: /**
445: * Returns true if value generator is to be used for this column
446: *
447: * @return true if value generator is to be used for this column
448: */
449: public boolean isAutoGenerated() {
450: return autoGenerated;
451: }
452:
453: /**
454: * Sets true if value generator is to be used for this column
455: *
456: * @param autoGenerated true if value generator is to be used for this column
457: */
458: public void setAutoGenerated(boolean autoGenerated) {
459: this .autoGenerated = autoGenerated;
460: }
461:
462: /**
463: * Returns value generator parameters that are statically set in geneterated persistent object
464: *
465: * @return value generator parameters that are statically set in geneterated persistent object
466: */
467: public Map getGeneratorStaticAttributes() {
468: return generatorStaticAttributes;
469: }
470:
471: /**
472: * Sets value generator parameters that are statically set in geneterated persistent object
473: *
474: * @param generatorStaticAttributes value generator parameters that are statically set in geneterated persistent object
475: */
476: public void setGeneratorStaticAttributes(
477: Map generatorStaticAttributes) {
478: this .generatorStaticAttributes = generatorStaticAttributes;
479: }
480:
481: /**
482: * Returns true if this column is auto incremented by database
483: *
484: * @return true if this column is auto incremented by database
485: */
486: public boolean isAutoIncrement() {
487: return autoIncrement;
488: }
489:
490: /**
491: * Sets true if this column is auto incremented by database
492: *
493: * @param autoIncrement true if this column is auto incremented by database
494: */
495: public void setAutoIncrement(boolean autoIncrement) {
496: this .autoIncrement = autoIncrement;
497: }
498:
499: /**
500: * Returns names of columns that are supposed to have last updated value generator by default
501: *
502: * @see GeneratorStruct
503: * @return names of columns that are supposed to have last updated value generator by default
504: */
505: public GeneratorStruct getLastUpdatedNames() {
506: return lastUpdatedNames;
507: }
508:
509: /**
510: * Sets names of columns that are supposed to have last updated value generator by default if not set yet
511: *
512: * @see GeneratorStruct
513: * @param lastUpdatedNames names of columns that are supposed to have last updated value generator by default if not set yet
514: */
515: public void setLastUpdatedNames(GeneratorStruct lastUpdatedNames) {
516: if (lastUpdatedNames != null) {
517: this .lastUpdatedNames = lastUpdatedNames;
518: }
519: }
520:
521: /**
522: * Returns names of columns that are supposed to have creation date value generator by default
523: *
524: * @see GeneratorStruct
525: * @return names of columns that are supposed to have creation date value generator by default
526: */
527: public GeneratorStruct getCreationDateNames() {
528: return creationDateNames;
529: }
530:
531: /**
532: * Sets names of columns that are supposed to have creation date value generator by default if not set yet
533: *
534: * @see GeneratorStruct
535: * @param creationDateNames names of columns that are supposed to have creation date value generator by default if not set yet
536: */
537: public void setCreationDateNames(GeneratorStruct creationDateNames) {
538: if (creationDateNames != null) {
539: this .creationDateNames = creationDateNames;
540: }
541: }
542:
543: /**
544: * Returns true if this column has to excluded from generated persistent object
545: *
546: * @return true if this column has to excluded from generated persistent object
547: */
548: public boolean isExclude() {
549: return exclude;
550: }
551:
552: /**
553: * Sets true if this column has to excluded from generated persistent object
554: *
555: * @param exclude true if this column has to excluded from generated persistent object
556: */
557: public void setExclude(boolean exclude) {
558: this .exclude = exclude;
559: }
560:
561: /**
562: * Returns true if this column is transformed meaning that in subsequent transformations it will be skipped
563: *
564: * @return true if this column is transformed meaning that in subsequent transformations it will be skipped
565: */
566: public boolean isTransformed() {
567: return transformed;
568: }
569:
570: /**
571: * Sets true if this column is transformed meaning that in subsequent transformations it will be skipped
572: *
573: * @param transformed true if this column is transformed meaning that in subsequent transformations it will be skipped
574: */
575: public void setTransformed(boolean transformed) {
576: this .transformed = transformed;
577: }
578:
579: /**
580: * Returns true if the column either part of Primary Key or Optimistic Lock
581: *
582: * @return true if the column either part of Primary Key or Optimistic Lock
583: */
584: public boolean isKey() {
585: return isPrimaryKey() || isOptimisticLock();
586: }
587:
588: /**
589: * Returns true if the column either part of Primary Key or Optimistic Lock. If column is null returns false.
590: *
591: * @param column
592: * @return true if the column either part of Primary Key or Optimistic Lock. If column is null returns false.
593: */
594: public static boolean isKey(MetaColumn column) {
595: return column != null && column.isKey();
596: }
597:
598: /**
599: * Returns fully qualified column name - prepended by table name and period. If table is null for this column - only
600: * column name itself is returned
601: *
602: * @return fully qualified column name - prepended by table name and period. If table is null for this column - only
603: * column name itself is returned
604: */
605: public String getFullColumnName() {
606: if (table != null) {
607: String tableName = table.getTableName();
608: String columnName = getColumnName();
609: return getFullColumnName(tableName, columnName);
610: } else {
611: return getColumnName();
612: }
613: }
614:
615: public static String getFullColumnName(String tableName,
616: String columnName) {
617: return new StringBuffer().append(tableName).append(".").append(
618: columnName).toString();
619: }
620:
621: /**
622: * @see DescriptorMappable
623: */
624: public Map toExternalMap() {
625: final Map columnMap = new LinkedHashMap();
626: try {
627: columnMap.put(COLUMN_NAME_TAG, columnName);
628: columnMap.put(COLUMN_ALIAS_TAG,
629: columnAlias == null ? columnName : columnAlias);
630: String typeName = ColumnType.contains(type.getName()) ? type
631: .getName()
632: : type.getClass().getName();
633: columnMap.put(DATA_TYPE_TAG, typeName);
634: columnMap.put(OPTIMISTIC_LOCK_TAG, Boolean
635: .valueOf(optimisticLock));
636: columnMap.put(EXCLUDE_TAG, Boolean.valueOf(exclude));
637: columnMap
638: .put(TRANSFORMED_TAG, Boolean.valueOf(transformed));
639: Map keyGeneratorMap;
640: if (autoGenerated) {
641: keyGeneratorMap = new LinkedHashMap();
642: keyGeneratorMap.put(KEY_GENERATOR_CLASS_NAME_TAG,
643: generatorClassName);
644: keyGeneratorMap.put(KEY_GENERATOR_STATIC_ATTRS_TAG,
645: generatorStaticAttributes);
646: columnMap.put(KEY_GENERATOR_TAG, keyGeneratorMap);
647: } else if (isPrimaryKey && table.keySize() == 1
648: && !autoIncrement) {
649: extrapolatePrimaryKey(columnMap);
650: } else if (lastUpdatedNames.getNames().contains(columnName)) {
651: extrapolateLastUpdated(columnMap, lastUpdatedNames
652: .isAsComment());
653: } else if (creationDateNames.getNames()
654: .contains(columnName)) {
655: extrapolateCreatedDate(columnMap, creationDateNames
656: .isAsComment());
657: }
658:
659: } catch (RuntimeException e) {
660: System.err.println("problem with Column " + columnName);
661: throw e;
662: }
663:
664: return columnMap;
665: }
666:
667: /**
668: * @see DescriptorMappable
669: */
670: public void fromExternalMap(Map columnMap) {
671: try {
672: columnAlias = (String) columnMap.get(COLUMN_ALIAS_TAG);
673: columnName = columnName != null ? columnName
674: : (String) columnMap.get(COLUMN_NAME_TAG);
675: String typeValue = (String) columnMap.get(DATA_TYPE_TAG);
676: if (ColumnType.contains(typeValue)) {
677: type = ColumnType.toColumnType((String) columnMap
678: .get(DATA_TYPE_TAG));
679: } else {
680: try {
681: Object o = Class.forName(typeValue).newInstance();
682: type = (ColumnType) o;
683: } catch (ClassNotFoundException e) {
684: throw new RuntimeException("Class not found: "
685: + typeValue, e);
686: } catch (IllegalAccessException e) {
687: throw new RuntimeException(
688: "IllegalAccessException for class: "
689: + typeValue, e);
690: } catch (InstantiationException e) {
691: throw new RuntimeException(
692: "Cannot instantiate class: " + typeValue, e);
693: }
694: }
695:
696: exclude = extractBoolean(columnMap, EXCLUDE_TAG);
697: transformed = extractBoolean(columnMap, TRANSFORMED_TAG);
698: Map keyGeneratorMap = (Map) columnMap
699: .get(KEY_GENERATOR_TAG);
700: if (keyGeneratorMap != null) {
701: generatorClassName = (String) keyGeneratorMap
702: .get(KEY_GENERATOR_CLASS_NAME_TAG);
703: generatorStaticAttributes = (Map) keyGeneratorMap
704: .get(KEY_GENERATOR_STATIC_ATTRS_TAG);
705: autoGenerated = true;
706: }
707: optimisticLock = extractBoolean(columnMap,
708: OPTIMISTIC_LOCK_TAG);
709: } catch (RuntimeException e) {
710: System.err.println("problem with Column " + columnName);
711: throw e;
712: }
713: }
714:
715: /**
716: * @see DescriptorMappable
717: */
718: public Map toInternalMap() {
719: final Map columnMap = new LinkedHashMap();
720: columnMap.put(COLUMN_NAME_TAG, columnName);
721: columnMap.put(COLUMN_INDEX_TAG, new Integer(columnIndex));
722: columnMap.put(IS_PRIMARY_KEY_TAG, String.valueOf(isPrimaryKey));
723: columnMap.put(IS_REQUIRED_TAG, String.valueOf(isRequired));
724: columnMap.put(REMARKS_TAG, remarks);
725: columnMap.put(DEFAULT_VALUE_TAG, defaultValue);
726: columnMap.put(COLUMN_SIZE_TAG, new Integer(columnSize));
727: columnMap.put(DECIMAL_DIGITS_TAG, new Integer(decimalDigits));
728: columnMap
729: .put(AUTO_INCREMENT_TAG, String.valueOf(autoIncrement));
730: columnMap.put(JDBC_TYPE_TAG, new Integer(jdbcType));
731: columnMap.put(TYPE_NAME_TAG, typeName);
732:
733: return columnMap;
734: }
735:
736: /**
737: * @see DescriptorMappable
738: */
739: public void fromInternalMap(Map columnMap) {
740: columnName = (String) columnMap.get(COLUMN_NAME_TAG);
741: columnIndex = extractInt(columnMap, COLUMN_INDEX_TAG);
742: isPrimaryKey = extractBoolean(columnMap, IS_PRIMARY_KEY_TAG);
743: isRequired = extractBoolean(columnMap, IS_REQUIRED_TAG);
744: remarks = (String) columnMap.get(REMARKS_TAG);
745: defaultValue = (String) columnMap.get(DEFAULT_VALUE_TAG);
746: columnSize = extractInt(columnMap, COLUMN_SIZE_TAG);
747: decimalDigits = extractInt(columnMap, DECIMAL_DIGITS_TAG);
748: autoIncrement = extractBoolean(columnMap, AUTO_INCREMENT_TAG);
749: jdbcType = extractInt(columnMap, JDBC_TYPE_TAG);
750: typeName = (String) columnMap.get(TYPE_NAME_TAG);
751: }
752:
753: private void extrapolateCreatedDate(final Map columnMap,
754: boolean asComment) {
755: String generatorName = "com.completex.objective.components.persistency.key.impl.CreatedDateGenerator";
756: addDateGeneratorClause(asComment, generatorName, columnMap);
757: }
758:
759: private void extrapolateLastUpdated(final Map columnMap,
760: boolean asComment) {
761: String generatorName = "com.completex.objective.components.persistency.key.impl.LastUpdatedDateGenerator";
762: addDateGeneratorClause(asComment, generatorName, columnMap);
763: }
764:
765: private void addDateGeneratorClause(boolean asComment,
766: String generatorName, final Map columnMap) {
767: if (asComment) {
768: String keyGeneratorMapString = line(0, " {")
769: + line(INDENT_2, "# "
770: + KEY_GENERATOR_CLASS_NAME_TAG + "="
771: + generatorName) + line0(INDENT, "# }");
772: columnMap.put("# " + KEY_GENERATOR_TAG,
773: keyGeneratorMapString);
774: } else {
775: HashMap map = new HashMap();
776: map.put(KEY_GENERATOR_CLASS_NAME_TAG, generatorName);
777: columnMap.put(KEY_GENERATOR_TAG, map);
778: }
779: }
780:
781: private void extrapolatePrimaryKey(final Map columnMap) {
782: if (!autoIncrement) {
783: String keyGeneratorMapString = line(0, " {")
784: + line(
785: INDENT_2,
786: "# "
787: + KEY_GENERATOR_CLASS_NAME_TAG
788: + "=com.completex.objective.components.persistency.key.impl.SimpleSequenceKeyGeneratorImpl")
789: + line(
790: INDENT_2,
791: "# "
792: + KEY_GENERATOR_STATIC_ATTRS_TAG
793: + "="
794: + "{"
795: + AbstractSimpleSequenceKeyGenerator.SEQ_KEY
796: + "=" + table.getTableName()
797: + "_SEQ" + "}")
798: + line0(INDENT, "# }");
799: columnMap.put("# " + KEY_GENERATOR_TAG,
800: keyGeneratorMapString);
801: }
802: }
803:
804: /**
805: * Returns indented line terminated by EOL characters
806: *
807: * @param indent number of spaces in line indentation
808: * @param line line
809: * @return indented line
810: */
811: static String line(int indent, String line) {
812: return StringUtil.indent(indent, line + EOL);
813: }
814:
815: /**
816: * Returns indented line not terminated by EOL characters
817: *
818: * @param indent number of spaces in line indentation
819: * @param line line
820: * @return indented line
821: */
822: static String line0(int indent, String line) {
823: return StringUtil.indent(indent, line);
824: }
825:
826: private static int extractInt(Map map, String key) {
827: return MetaTable.extractInt(map, key);
828: }
829:
830: private static boolean extractBoolean(Map map, String key) {
831: return MetaTable.extractBoolean(map, key);
832: }
833:
834: /**
835: * For ColumnType.CHAR types right pads
836: * the value stored in String with spaces to the length of
837: * this MetaColumn. For other types returns object itself
838: *
839: * @param value
840: * @return For ColumnType.CHAR types value right padded
841: * with spaces to the length of this MetaColumn. For other types - object itself
842: */
843: public Object v2c(Object value) {
844: if (ColumnType.CHAR == type) {
845: String string = (String) value;
846: return TypeUtil.rpad(string, columnSize);
847: } else {
848: return value;
849: }
850: }
851:
852: public String toString() {
853: return "{columnName = " + columnName + "; columnAlias = "
854: + columnAlias + "; columnIndex = " + columnIndex
855: + "; remarks = " + remarks + "; isPrimaryKey = "
856: + isPrimaryKey + "; type = " + type + "; jdbcType = "
857: + jdbcType + "; columnSize = " + columnSize
858: + "; decimalDigits = " + decimalDigits
859: + "; optimisticLock = " + optimisticLock
860: + "; autoGenerated = " + autoGenerated
861: + "; generatorClassName = " + generatorClassName
862: + "; generatorStaticAttributes = "
863: + generatorStaticAttributes + "}";
864: }
865:
866: /**
867: * Returns shallow copy of this column
868: *
869: * @return shallow copy of this column
870: * @throws CloneNotSupportedException
871: */
872: public Object clone() throws CloneNotSupportedException {
873: return super .clone();
874: }
875:
876: public MetaColumn cloneSafe() {
877: try {
878: return (MetaColumn) clone();
879: } catch (CloneNotSupportedException e) {
880: throw new OdalRuntimePersistencyException(
881: "Cannot clone MetaColumn", e);
882: }
883: }
884:
885: /**
886: * Utility structure
887: */
888: public static class GeneratorStruct {
889: private Set names;
890: private boolean asComment;
891:
892: public GeneratorStruct(Set names) {
893: if (names == null) {
894: throw new IllegalArgumentException(
895: "GeneratorStruct names == null");
896: }
897: this .names = names;
898: }
899:
900: public GeneratorStruct(Set names, boolean asComment) {
901: this .names = names;
902: this .asComment = asComment;
903: }
904:
905: public Set getNames() {
906: return names;
907: }
908:
909: public boolean isAsComment() {
910: return asComment;
911: }
912: }
913:
914: }
|