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.tools.generators;
010:
011: import com.completex.objective.components.log.Log;
012: import com.completex.objective.components.log.impl.PrimitiveLogImpl;
013: import com.completex.objective.components.log.adapter.StdOutputLogAdapter;
014: import com.completex.objective.components.persistency.ColumnType;
015: import com.completex.objective.components.persistency.JavaToMetaTypeImpl;
016: import com.completex.objective.components.persistency.MetaColumn;
017: import com.completex.objective.components.persistency.MetaTable;
018: import com.completex.objective.components.persistency.MetaNaturalKey;
019: import com.completex.objective.components.persistency.ForeignKeys;
020: import com.completex.objective.components.persistency.meta.MetaModel;
021: import com.completex.objective.components.persistency.meta.adapter.ModelLoaderAdapter;
022: import com.completex.objective.components.sdl.reader.SdlReader;
023: import com.completex.objective.components.sdl.reader.impl.SdlReaderImpl;
024: import com.completex.objective.util.PropertyMap;
025: import com.completex.objective.util.StringUtil;
026: import freemarker.template.Template;
027: import freemarker.template.TemplateException;
028:
029: import java.io.*;
030: import java.sql.SQLException;
031: import java.util.*;
032:
033: /**
034: * Args[0]: persistent-object-config.properties
035: * Args[1]: env.properties
036: *
037: * @author Gennady Krizhevsky
038: */
039: public class PersistentObjectGenerator implements MetaModelsExtractor {
040:
041: private static final String CLASS_BEAN_TEMPLATE = "ftl/persistent-object-bean.ftl";
042: private static final String DEFAULT_INTF_TEMPLATE = "ftl/persistent-interface.ftl";
043: private static final String DEFAULT_META_ASSEMBLY_CLASS_TEMPLATE = "ftl/meta-model-assembly.ftl";
044:
045: private Log logger = StdOutputLogAdapter.newLogInstance();
046: protected LifeCycleControllerGenerator lifeCycleControllerGenerator;
047: protected SdlReader sdlReader = new SdlReaderImpl();
048:
049: private static Map TYPE_2_JAVA = new LinkedHashMap();
050:
051: {
052: for (int i = 0; i < ColumnType.getColumnTypes().length; i++) {
053: registerType(ColumnType.getColumnTypes()[i]);
054: }
055: }
056:
057: public static final String INTERNAL_DESC_PATH = "intern_path"; // Internal descriptor file path
058: public static final String EXTERNAL_DESC_PATH = "extern_path"; // External descriptor file path
059: public static final String OUT_DIR = "out_dir"; // Top level directory for generated classes
060: public static final String TAG_PACKAGE = "package";
061: public static final String PACKAGE = TAG_PACKAGE; // Package
062: public static final String TEMPLATE_PATH = "template_path"; // Package
063: public static final String FILTER_PATTERN = "filter_pattern";
064: public static final String CLASS_PREFIX = "class_prefix";
065: public static final String CLASS_SUFFIX = "class_suffix";
066: public static final String GENERATE_INTERFACES = "generate_interfaces";
067: public static final String GENERATE_LIFE_CYCLE_CTL = "generate_life_cycle_ctl";
068: public static final String CTL_PREFIX = LifeCycleControllerGenerator.CTL_PREFIX;
069: public static final String CTL_SUFFIX = LifeCycleControllerGenerator.CTL_SUFFIX;
070: public static final String LIFE_CYCLE_CTL = "life_cycle_ctl";
071: public static final String GENERATE_BEAN = "generate_bean";
072:
073: public static final String TAG_META_ASSEMBLY_CLASS_PREFIX = "meta_assembly_class_prefix";
074: public static final String TAG_META_ASSEMBLY_CLASS_SUFFIX = "meta_assembly_class_suffix";
075: public static final String TAG_META_ASSEMBLY_TEMPLATE_PATH = "meta_assembly_template_path";
076:
077: public static final String GENERIC = "generic";
078: public static final String CLASSES = "classes";
079: public static final String DEBUG = "debug";
080: public static final String TAG_INTERFACES = "interfaces";
081: public static final String TAG_GENERATE_TO_STRING = "generateToString";
082: public static final String TAG_INTERFACE_NAME = "interfaceName";
083: public static final String INTERFACES = TAG_INTERFACES;
084:
085: private String coreMetaAssemblyClassName = "META_MODEL_ASSEMBLY";
086: public static final String COL_PREFIX = "COL_";
087: public static final String TCOL_PREFIX = "TCOL_";
088: public static final String ICOL_PREFIX = "ICOL_";
089: public static final String JDBC_TYPE_PREFIX = "JDBC_TYPE_";
090: public static final String TAG_CLASS_NAME = "className";
091: public static final String TAG_IMPORTS = "imports";
092: protected boolean debug;
093:
094: public PersistentObjectGenerator() {
095: registerExtraTypes();
096: }
097:
098: public ExtractStruct extractMetaModels(String propertiesPath)
099: throws Exception {
100: return extractMetaModels(propertiesPath, null);
101: }
102:
103: public ExtractStruct extractMetaModels(String propertiesPath,
104: Properties env) throws Exception {
105: Map properties = extractProperties(propertiesPath, sdlReader,
106: env);
107: LineStructBlock[] blocks = initializeFromSdl(properties);
108: ExtractStruct extractStruct = new ExtractStruct(this , blocks);
109: extractMetaModels(blocks, extractStruct);
110: return extractStruct;
111: }
112:
113: private void extractMetaModels(LineStructBlock[] blocks,
114: ExtractStruct extractStruct) throws Exception {
115: MetaModel[] metaModels = new MetaModel[blocks.length];
116: for (int i = 0; i < blocks.length; i++) {
117: metaModels[i] = setup(blocks[i].classStruct.inFilePath,
118: blocks[i].classStruct.exFilePath,
119: blocks[i].classStruct.filterPattern);
120: }
121: extractStruct.setMetaModels(metaModels);
122: verifyModels(metaModels, extractStruct);
123: }
124:
125: public void process(String propertiesPath, String envPath)
126: throws Exception {
127: PropertyMap env = env(envPath);
128: Map properties = extractProperties(propertiesPath, sdlReader,
129: env);
130: process(properties, env);
131: }
132:
133: protected static PropertyMap env(String envPath) throws IOException {
134: return envPath == null ? null : PropertyMap
135: .createAndLoad(envPath);
136: }
137:
138: public void process(Map properties) throws Exception {
139: process(properties, null);
140: }
141:
142: public void process(Map properties, Properties env)
143: throws Exception {
144: LineStructBlock[] blocks = initializeFromSdl(properties);
145: ExtractStruct extractStruct = new ExtractStruct(this , blocks);
146: extractMetaModels(blocks, extractStruct);
147: MetaModel[] metaModels = extractStruct.getMetaModels();
148: for (int i = 0; i < metaModels.length; i++) {
149: process(metaModels[i], blocks[i]);
150: logger.debug("Block [" + i + "] done");
151: }
152: }
153:
154: protected void verifyModels(MetaModel[] metaModels,
155: ExtractStruct extractStruct) {
156: HashSet aliases = new HashSet();
157: for (int i = 0; i < metaModels.length; i++) {
158: MetaModel metaModel = metaModels[i];
159: for (MetaModel.MetaTableIterator iterator = metaModel
160: .tableIterator(); iterator.hasNext();) {
161: MetaTable metaTable = iterator.nextMetaTable();
162: if (!aliases.contains(metaTable.getTableAlias())) {
163: aliases.add(metaTable.getTableAlias());
164: } else {
165: throw new IllegalArgumentException(
166: "Duplicate table alias: "
167: + metaTable.getTableAlias());
168: }
169: if (extractStruct != null) {
170: extractStruct.putEntry(metaTable.getTableAlias(),
171: new ExtractStructEntry(new Integer(i),
172: metaTable));
173: }
174: }
175: }
176: aliases.clear();
177: }
178:
179: protected void registerType(ColumnType type) {
180: String className = type.getValueClassName();
181:
182: if (ColumnType.contains(type)) {
183: className = type.getValueClassSimpleName();
184: }
185:
186: TYPE_2_JAVA.put(type, className);
187: }
188:
189: protected void unregisterType(ColumnType type) {
190: TYPE_2_JAVA.remove(type);
191: }
192:
193: private LineStructBlock[] initializeFromSdl(Map properties)
194: throws Exception {
195: PropertyMap propertyMap = PropertyMap.toPropertyMap(properties);
196: PropertyMap generic = PropertyMap
197: .toPropertyMap((Map) propertyMap.get(GENERIC, true));
198: PropertyMap classes = PropertyMap
199: .toPropertyMap((Map) propertyMap.get(CLASSES, true));
200: PropertyMap interfaces = PropertyMap
201: .toPropertyMap((Map) propertyMap.get(INTERFACES));
202: LineStruct classStruct = toLineStruct(generic, classes);
203: LineStruct intfStruct = null;
204: if (classStruct.generateInterfaces) {
205: intfStruct = toLineStruct(generic, interfaces);
206: }
207:
208: return new LineStructBlock(classStruct, intfStruct, propertyMap)
209: .splitBlocks();
210: }
211:
212: public Map extractProperties(String propertiesPath)
213: throws IOException {
214: return extractProperties(propertiesPath, sdlReader);
215: }
216:
217: public static Map extractProperties(String propertiesPath,
218: SdlReader sdlReader) throws IOException {
219: return extractProperties(propertiesPath, sdlReader, null);
220: }
221:
222: public static Map extractProperties(String propertiesPath,
223: SdlReader sdlReader, Properties env) throws IOException {
224: Map map = (Map) sdlReader.read(new FileReader(propertiesPath));
225: return PropertyMap.resolveParameters(map, env);
226: }
227:
228: private LineStruct toLineStruct(PropertyMap generic,
229: PropertyMap classes) {
230: LineStruct lineStruct = new LineStruct();
231: lineStruct.inFilePath = generic.getProperty(INTERNAL_DESC_PATH,
232: true);
233: lineStruct.exFilePath = generic.getProperty(EXTERNAL_DESC_PATH,
234: true);
235:
236: lineStruct.generateInterfaces = generic
237: .getBoolean(GENERATE_INTERFACES);
238: lineStruct.generateLifeCycleCtl = generic
239: .getBoolean(GENERATE_LIFE_CYCLE_CTL);
240: lineStruct.generateBean = generic.getBoolean(GENERATE_BEAN,
241: Boolean.FALSE, true);
242: lineStruct.genericImports = generic.getProperty(TAG_IMPORTS);
243: lineStruct.debug = generic.getBoolean(DEBUG);
244: debug = generic.getBoolean(DEBUG);
245: if (logger instanceof PrimitiveLogImpl) {
246: ((PrimitiveLogImpl) logger).setDebugEnabled(debug);
247: }
248:
249: lineStruct.metaAssemblyClassPrefix = generic.getProperty(
250: TAG_META_ASSEMBLY_CLASS_PREFIX, "");
251: lineStruct.metaAssemblyClassSuffix = generic.getProperty(
252: TAG_META_ASSEMBLY_CLASS_SUFFIX, "");
253: lineStruct.metaAssemblyTemplatePath = generic
254: .getProperty(TAG_META_ASSEMBLY_TEMPLATE_PATH);
255:
256: lineStruct.outputPath = classes.getProperty(OUT_DIR, true);
257: lineStruct.packageName = classes.getProperty(PACKAGE, true);
258: lineStruct.templatePath = classes.getProperty(TEMPLATE_PATH);
259: lineStruct.filterPattern = classes.getProperty(FILTER_PATTERN);
260: lineStruct.classPrefix = classes.getProperty(CLASS_PREFIX, "");
261: lineStruct.classSuffix = classes
262: .getProperty(CLASS_SUFFIX, null);
263: lineStruct.implements String = classes.getProperty("implements");
264: lineStruct.specificImports = classes.getProperty(TAG_IMPORTS);
265:
266: return lineStruct;
267: }
268:
269: public MetaModel setup(String inFilePath, String exFilePath,
270: String filterPattern) throws Exception, SQLException {
271: Reader internalFileReader = new BufferedReader(new FileReader(
272: inFilePath));
273: Reader externalFileReader = new BufferedReader(new FileReader(
274: exFilePath));
275: JavaToMetaTypeImpl javaToMetaType = new JavaToMetaTypeImpl();
276: ModelLoaderAdapter modelFileLoaderAdapter = new ModelLoaderAdapter(
277: new ModelLoaderAdapter.InternalFileModelLoaderAdapter(
278: internalFileReader, filterPattern),
279: new ModelLoaderAdapter.ExternalFileModelLoaderAdapter(
280: externalFileReader, filterPattern),
281: javaToMetaType, logger);
282: return modelFileLoaderAdapter.load(null);
283: }
284:
285: public void process(MetaModel model, LineStructBlock block)
286: throws Exception, TemplateException {
287: generateClasses(model, block);
288: generateInterfaces(model, block);
289: generateLifeCtl(block);
290: }
291:
292: private void generateLifeCtl(LineStructBlock block)
293: throws Exception {
294: LineStruct classStruct = block.classStruct;
295: if (classStruct.generateLifeCycleCtl) {
296: PropertyMap properties = new PropertyMap();
297: lifeCycleControllerGenerator = new LifeCycleControllerGenerator();
298: properties.put(
299: LifeCycleControllerGenerator.INTERNAL_DESC_PATH,
300: classStruct.inFilePath);
301: properties.put(
302: LifeCycleControllerGenerator.EXTERNAL_DESC_PATH,
303: classStruct.exFilePath);
304: properties.put(LifeCycleControllerGenerator.OUT_DIR,
305: classStruct.outputPath);
306: properties.put(LifeCycleControllerGenerator.PACKAGE,
307: classStruct.packageName);
308: properties.put(LifeCycleControllerGenerator.FILTER_PATTERN,
309: classStruct.filterPattern);
310: properties.put(LifeCycleControllerGenerator.CLASS_PREFIX,
311: classStruct.classPrefix);
312: properties.put(LifeCycleControllerGenerator.CLASS_SUFFIX,
313: classStruct.classSuffix);
314: properties
315: .put(
316: LifeCycleControllerGenerator.PERSISTENT_CLASS_PACKAGE,
317: classStruct.packageName);
318:
319: //
320: // See if there is ctl specific config:
321: //
322: PropertyMap ctlConfig = block.getPropertyMap()
323: .getPropertyMap(LIFE_CYCLE_CTL);
324: if (ctlConfig != null) {
325: String ctlPrefix = ctlConfig.getProperty(CTL_PREFIX);
326: String ctlSuffix = ctlConfig.getProperty(CTL_SUFFIX);
327: if (ctlPrefix != null) {
328: properties.put(CTL_PREFIX, ctlPrefix);
329: }
330: if (ctlSuffix != null) {
331: properties.put(CTL_SUFFIX, ctlSuffix);
332: }
333: }
334:
335: lifeCycleControllerGenerator.process(properties);
336: }
337: }
338:
339: protected void generateClasses(MetaModel model,
340: LineStructBlock block) throws IOException,
341: TemplateException {
342:
343: LineStruct classStruct = block.classStruct;
344: LineStruct intfStruct = block.intfStruct;
345:
346: String outputDir = FileUtil.makePath(classStruct.packageName,
347: classStruct.outputPath);
348:
349: // String classTemplate = classStruct.generateBean ? CLASS_BEAN_TEMPLATE : CLASS_TEMPLATE;
350: String classTemplate = CLASS_BEAN_TEMPLATE;
351: Template template = getTemplate(classStruct.templatePath,
352: classTemplate, debug);
353: Map metaAssemblyTemplateModel = new LinkedHashMap();
354: Template metaAssemblyTemplate = getTemplate(
355: classStruct.metaAssemblyTemplatePath,
356: DEFAULT_META_ASSEMBLY_CLASS_TEMPLATE, debug);
357:
358: ArrayList persistentObjects = new ArrayList();
359: String metaAssemblyClassName = javaName(
360: coreMetaAssemblyClassName,
361: classStruct.metaAssemblyClassPrefix,
362: classStruct.metaAssemblyClassSuffix, true);
363: metaAssemblyTemplateModel.put("metaAssemblyClassName",
364: metaAssemblyClassName);
365: metaAssemblyTemplateModel.put("persistentObjects",
366: persistentObjects);
367: metaAssemblyTemplateModel.put(TAG_PACKAGE,
368: classStruct.packageName);
369:
370: printGeneratedIn(outputDir);
371:
372: for (Iterator it = model.tableIterator(); it.hasNext();) {
373: Map.Entry entry = (Map.Entry) it.next();
374: logger.debug("Processing Class ENTRY "
375: + entry.getClass().getName());
376: // logger.debug("Processing Class ENTRY " + entry);
377: MetaTable table = (MetaTable) entry.getValue();
378:
379: if (table.isExclude()) {
380: logger.debug("Skipping table [" + table + "]");
381: continue;
382: } else {
383: logger.debug("Processing table [" + table + "]");
384: }
385:
386: Map templateModel = prepareClassTableTemplateMap(table,
387: classStruct, intfStruct);
388: String className = (String) templateModel
389: .get(TAG_CLASS_NAME);
390: persistentObjects.add(className);
391: // FK
392:
393: logger.debug("outputDir = " + outputDir + "; table = "
394: + table.getTableAlias());
395:
396: String classFileName = className + ".java";
397: Writer writer = new FileWriter(new File(outputDir,
398: classFileName));
399: template.process(templateModel, writer);
400: writer.flush();
401: writer.close();
402: printGeneratedClassFileInfo(classFileName);
403: }
404:
405: Writer writer = new FileWriter(new File(outputDir,
406: metaAssemblyClassName + ".java"));
407: metaAssemblyTemplate.process(metaAssemblyTemplateModel, writer);
408: writer.flush();
409: writer.close();
410: println("GENERATED META_ASSEMBY FILE IN " + outputDir);
411: }
412:
413: protected static void printGeneratedClassFileInfo(
414: String classFileName) {
415: CompositePoGenerator.printGeneratedClassFileInfo(classFileName);
416: }
417:
418: protected static void printGeneratedClassFileInfo(
419: String classFileName, String outputDir) {
420: CompositePoGenerator.printGeneratedClassFileInfo(classFileName,
421: outputDir);
422: }
423:
424: protected static void printGeneratedIn(String outputDir) {
425: CompositePoGenerator.printGeneratedIn(outputDir);
426: }
427:
428: public Map prepareClassTableTemplateMap(MetaTable table,
429: LineStruct classStruct, LineStruct intfStruct) {
430: Date timestamp = new Date();
431: Map templateModel = new LinkedHashMap();
432: boolean mainPattern = isClassMainPattern(table);
433: // String className = javaName(table.getTableAlias(), classStruct.classPrefix, classStruct.classSuffix, true, mainPattern);
434: String className = classOrInterfaceName(table, mainPattern,
435: classStruct);
436: templateModel.put(TAG_PACKAGE, classStruct.packageName);
437: templateModel.put("timestamp", timestamp);
438: templateModel.put(TAG_CLASS_NAME, className);
439: ArrayList imports = new ArrayList();
440: if (classStruct.generateInterfaces) {
441: String interfaceName = classOrInterfaceName(table,
442: mainPattern, intfStruct);
443: imports.add(intfStruct.packageName + "." + interfaceName);
444: }
445:
446: //
447: // Add generis & specific imports:
448: //
449: addToImports(classStruct.genericImports, imports);
450: addToImports(classStruct.specificImports, imports);
451:
452: templateModel.put(TAG_IMPORTS, imports);
453: String tableConst = javaConstName("TABLE_", table
454: .getTableAlias());
455: templateModel.put("tableNameConst", tableConst);
456: templateModel.put("tableName", table.getTableName());
457: templateModel.put("tableAlias", NameHelper
458: .parseExactAlias(table.getTableAlias()));
459:
460: templateModel.put("keySize", new Integer(table.keySize()));
461: String interfaces = classStruct.generateInterfaces ? classOrInterfaceName(
462: table, true, intfStruct)
463: : "";
464: String comma = StringUtil.isEmpty(interfaces) ? "" : ", ";
465: if (classStruct.implements String != null
466: && classStruct.implements String.trim().length() > 0) {
467: interfaces += comma + classStruct.implements String;
468: }
469: if (interfaces.length() > 0) {
470: templateModel.put(TAG_INTERFACES, interfaces + " ");
471: }
472: templateModel.put("generateInterfaces",
473: classStruct.generateInterfaces + "");
474:
475: if (table.getPrimaryKey() != null) {
476: ArrayList pkVars = new ArrayList(table.getPrimaryKey()
477: .size());
478: String pkArgs = "";
479: for (int i = 0; i < table.getPrimaryKey().size(); i++) {
480: comma = i == 0 ? "" : ", ";
481: int pkIndex = ((Integer) table.getPrimaryKey().get(i))
482: .intValue();
483: String varName = javaName(table.getColumn(pkIndex)
484: .getColumnAlias(), null, null, false);
485:
486: String varType = javaType(table.getColumn(pkIndex)
487: .getType());
488: HashMap pkVar = new HashMap();
489: pkVar.put("varName", varName);
490: pkVar.put("varType", varType);
491: pkVars.add(pkVar);
492: pkArgs += comma + varType + " " + varName;
493: }
494: templateModel.put("pkVars", pkVars);
495: templateModel.put("pkArgs", pkArgs);
496: }
497:
498: //
499: // Add foreign keys:
500: //
501: ForeignKeys foreignKeys = table.getForeignKeys();
502: Set foreignKeysTableNamesSet = foreignKeys.keySet();
503: templateModel.put("foreignKeys", foreignKeys);
504: templateModel.put("foreignKeysTableNamesSet",
505: foreignKeysTableNamesSet);
506:
507: MetaNaturalKey naturalKey = table.getNaturalKey();
508: String tagNaturalKey = MetaTable.TAG_NATURAL_KEY;
509: templateModel.put(tagNaturalKey, naturalKey);
510:
511: List columns = new ArrayList(table.size());
512: HashMap columnMap = new HashMap();
513: templateModel.put("columns", columns);
514: templateModel.put("columnMap", columnMap);
515: int realIndex = 0;
516: for (int i = 0; i < table.size(); i++) {
517: MetaColumn metaColumn = table.getColumn(i);
518: if (metaColumn.isExclude()) {
519: logger.debug("Skipping column [" + metaColumn + "]");
520: continue;
521: } else {
522: logger.debug("Processing column [" + metaColumn + "]");
523: }
524: Map column = new LinkedHashMap();
525: String propertyName = javaName(metaColumn.getColumnAlias(),
526: null, null, false);
527: column.put("javaName", propertyName);
528: ColumnType columnType = metaColumn.getType();
529: addOneToImports(columnType, imports);
530: column.put("javaType", javaType(columnType));
531: column.put("jdbcType", String.valueOf(metaColumn
532: .getJdbcType()));
533: boolean primitive = ColumnType.isPrimitive(metaColumn
534: .getType());
535: column.put("primitive", primitive + "");
536: String object2primitive = null;
537: String primitive2object = null;
538: String primitiveCast = null;
539: if (primitive) {
540: if (ColumnType.isNumeric(columnType)) {
541: object2primitive = "Number2" + javaType(columnType);
542: primitive2object = javaType(metaColumn.getType())
543: + "2Number";
544: primitiveCast = "Number";
545:
546: } else if (ColumnType.BOOLEAN_PRIMITIVE
547: .equals(columnType)) {
548: object2primitive = "Boolean2boolean";
549: primitive2object = "boolean2Boolean";
550: primitiveCast = "Boolean";
551: } else {
552: throw new UnsupportedOperationException(
553: "Unsupported columnType for primitive: "
554: + metaColumn.getType());
555: }
556: if (columnType.getValueClass() == double.class) {
557: column.put("compareFuncName", "Double.compare");
558: column.put("isDoublePrimitive", Boolean.TRUE);
559: } else if (columnType.getValueClass() == long.class) {
560: column.put("isLongPrimitive", Boolean.TRUE);
561: } else if (columnType.getValueClass() == boolean.class) {
562: column.put("isBooleanPrimitive", Boolean.TRUE);
563: }
564: }
565: column.put("getOrIs", getOrIs(metaColumn));
566: column.put("primitiveCast", primitiveCast);
567: column.put("object2primitive", object2primitive);
568: column.put("primitive2object", primitive2object);
569: column.put("columnName", metaColumn.getColumnName());
570: column.put("columnNameConst", javaConstName(COL_PREFIX,
571: metaColumn.getColumnAlias()));
572: column.put("tColumnName", table.getTableName() + "."
573: + metaColumn.getColumnName());
574: column.put("tColumnNameConst", javaConstName(TCOL_PREFIX,
575: metaColumn.getColumnAlias()));
576: column.put("columnAlias", parseColumnAlias(metaColumn));
577: column.put("columnIndexConst", javaConstName(ICOL_PREFIX,
578: metaColumn.getColumnAlias()));
579: column.put("jdbcTypeConst", javaConstName(JDBC_TYPE_PREFIX,
580: metaColumn.getColumnAlias()));
581: // column.put("columnIndex", metaColumn.getColumnIndex() + "");
582: column.put("columnIndex", realIndex + "");
583: String typeString;
584: if (ColumnType.contains(metaColumn.getType())) {
585: typeString = "ColumnType."
586: + metaColumn.getType().getName().toUpperCase();
587: } else {
588: typeString = "new "
589: + metaColumn.getType().getClass().getName()
590: + "()";
591: }
592: column.put("type", typeString);
593: column.put("primaryKey", metaColumn.isPrimaryKey() + "");
594: column.put("required", metaColumn.isRequired() + "");
595: column.put("optimisticLock", metaColumn.isOptimisticLock()
596: + "");
597: column.put("columnSize", metaColumn.getColumnSize() + "");
598: column.put("remarks", metaColumn.getRemarks() == null ? ""
599: : metaColumn.getRemarks());
600: column.put("decimalDigits", metaColumn.getDecimalDigits()
601: + "");
602: column.put("autoGenerated", metaColumn.isAutoGenerated()
603: + "");
604: column.put("autoIncrement", metaColumn.isAutoIncrement()
605: + "");
606: String generatorClassName = metaColumn
607: .getGeneratorClassName();
608: column.put("generatorClassName", generatorClassName);
609: ArrayList staticAttributes = new ArrayList();
610: column.put("staticAttributes", staticAttributes);
611: Map map = metaColumn.getGeneratorStaticAttributes();
612: if (map != null) {
613: for (Iterator iter = map.keySet().iterator(); iter
614: .hasNext();) {
615: Object key = iter.next();
616: Object value = map.get(key);
617: HashMap staticAttribute = new HashMap();
618: staticAttribute.put("key", key);
619: staticAttribute.put("value", value);
620: staticAttributes.add(staticAttribute);
621: }
622: }
623: columns.add(column);
624: columnMap.put(metaColumn.getColumnName(), column);
625: realIndex++;
626: }
627: templateModel.put("asize", "" + realIndex);
628: return templateModel;
629: }
630:
631: private void addOneToImports(ColumnType columnType,
632: ArrayList imports) {
633: if (!ColumnType.isPrimitive(columnType)) {
634: String toImport = columnType.getValueClassName() == null ? null
635: : columnType.getValueClassName();
636: if (toImport != null && !toImport.startsWith("java.lang")
637: && (toImport.indexOf('.') > 0)) {
638: addOneToImports(toImport, imports);
639: }
640: }
641: }
642:
643: private String parseColumnAlias(MetaColumn metaColumn) {
644: return NameHelper.parseExactAlias(metaColumn.getColumnAlias());
645: }
646:
647: private void addToImports(String extraImports, ArrayList imports) {
648: if (!StringUtil.isEmpty(extraImports)) {
649: String[] genImports = extraImports.split(",");
650: for (int i = 0; i < genImports.length; i++) {
651: String toImport = genImports[i].trim();
652: addOneToImports(toImport, imports);
653: }
654: }
655: }
656:
657: private void addOneToImports(String toImport, ArrayList imports) {
658: if (!imports.contains(toImport)) {
659: imports.add(toImport);
660: }
661: }
662:
663: private Template getTemplate(String templatePath,
664: String defaultTemplateFileName, boolean debug)
665: throws IOException {
666: return TemplateHelper.getTemplate(templatePath,
667: defaultTemplateFileName, this .getClass(), debug);
668: }
669:
670: private void generateInterfaces(MetaModel model,
671: LineStructBlock block) throws IOException,
672: TemplateException {
673: if (!block.classStruct.generateInterfaces) {
674: return;
675: }
676: LineStruct intfStruct = block.intfStruct;
677:
678: String outputDir = FileUtil.makePath(intfStruct.packageName,
679: intfStruct.outputPath);
680:
681: Template template = getTemplate(intfStruct.templatePath,
682: DEFAULT_INTF_TEMPLATE, debug);
683:
684: printGeneratedIn(outputDir);
685:
686: for (Iterator it = model.tableIterator(); it.hasNext();) {
687: Map.Entry entry = (Map.Entry) it.next();
688: logger.debug("Processing Interface ENTRY "
689: + entry.getClass().getName());
690: MetaTable table = (MetaTable) entry.getValue();
691: if (table.isExclude()) {
692: logger.debug("Skipping table [" + table + "]");
693: continue;
694: } else {
695: logger.debug("Processing table [" + table + "]");
696: }
697:
698: String className = classOrInterfaceName(table, intfStruct);
699: Map tableModel = prepareInterfaceTableMap(table, intfStruct);
700: // FK
701:
702: logger.debug("outputDir = " + outputDir + "; table = "
703: + table.getTableAlias());
704:
705: String classFileName = className + ".java";
706: Writer writer = new FileWriter(new File(outputDir,
707: classFileName));
708: template.process(tableModel, writer);
709: writer.flush();
710: writer.close();
711: printGeneratedClassFileInfo(classFileName);
712: }
713: }
714:
715: protected static void println(String s) {
716: System.out.println(s);
717: }
718:
719: public Map prepareInterfaceTableMap(MetaTable table,
720: LineStruct intfStruct) {
721: String className = classOrInterfaceName(table, intfStruct);
722: Date timestamp = new Date();
723: Map tableModel = new LinkedHashMap();
724: tableModel.put(TAG_PACKAGE, intfStruct.packageName);
725: tableModel.put("timestamp", timestamp);
726: tableModel.put(TAG_CLASS_NAME, className);
727: tableModel.put(TAG_INTERFACE_NAME, className);
728: tableModel.put("extends", intfStruct.parentClass == null ? ""
729: : "extends " + intfStruct.parentClass);
730: tableModel.put("classPrefix", intfStruct.classPrefix);
731: tableModel.put("classSuffix", intfStruct.classSuffix);
732: ArrayList imports = new ArrayList();
733: tableModel.put(TAG_IMPORTS, imports);
734: String tableConst = javaConstName("TABLE_", table
735: .getTableAlias());
736: tableModel.put("tableNameConst", tableConst);
737: tableModel.put("tableName", table.getTableName());
738: tableModel.put("tableAlias", NameHelper.parseExactAlias(table
739: .getTableAlias()));
740: tableModel.put("keySize", new Integer(table.keySize()));
741:
742: if (table.getPrimaryKey() != null) {
743: ArrayList pkVars = new ArrayList(table.getPrimaryKey()
744: .size());
745: String pkArgs = "";
746: for (int i = 0; i < table.getPrimaryKey().size(); i++) {
747: String comma = i == 0 ? "" : ", ";
748: int pkIndex = ((Integer) table.getPrimaryKey().get(i))
749: .intValue();
750: String varName = javaName(parseColumnAlias(table
751: .getColumn(pkIndex)), null, null, false);
752: String varType = javaType(table.getColumn(pkIndex)
753: .getType());
754: HashMap pkVar = new HashMap();
755: pkVar.put("varName", varName);
756: pkVar.put("varType", varType);
757: pkVars.add(pkVar);
758: pkArgs += comma + varType + " " + varName;
759: }
760: tableModel.put("pkVars", pkVars);
761: tableModel.put("pkArgs", pkArgs);
762: }
763:
764: List columns = new ArrayList(table.size());
765: tableModel.put("columns", columns);
766: int realIndex = 0;
767: for (int i = 0; i < table.size(); i++) {
768: MetaColumn metaColumn = table.getColumn(i);
769: if (metaColumn.isExclude()) {
770: String pk = metaColumn.isPrimaryKey() ? "primary key "
771: : "";
772: logger.debug("Skipping " + pk + "column [" + metaColumn
773: + "]");
774: continue;
775: } else {
776: logger.debug("Processing column [" + metaColumn + "]");
777: }
778:
779: Map column = new LinkedHashMap();
780: column.put("getOrIs", getOrIs(metaColumn));
781: column.put("javaName", javaName(
782: metaColumn.getColumnAlias(), null, null, false));
783: column.put("javaType", javaType(metaColumn.getType()));
784: column.put("columnName", metaColumn.getColumnName());
785: column.put("columnNameConst", javaConstName(COL_PREFIX,
786: metaColumn.getColumnAlias()));
787: column.put("tColumnName", table.getTableName() + "."
788: + metaColumn.getColumnName());
789: column.put("tColumnNameConst", javaConstName(TCOL_PREFIX,
790: metaColumn.getColumnAlias()));
791: column.put("columnAlias", parseColumnAlias(metaColumn));
792: column.put("columnIndexConst", javaConstName(ICOL_PREFIX,
793: metaColumn.getColumnAlias()));
794: // column.put("columnIndex", metaColumn.getColumnIndex() + "");
795: column.put("columnIndex", realIndex + "");
796: column.put("type", metaColumn.getType().getName()
797: .toUpperCase());
798: column.put("primaryKey", metaColumn.isPrimaryKey() + "");
799: column.put("required", metaColumn.isRequired() + "");
800: column.put("optimisticLock", metaColumn.isOptimisticLock()
801: + "");
802: column.put("columnSize", metaColumn.getColumnSize() + "");
803: column.put("decimalDigits", metaColumn.getDecimalDigits()
804: + "");
805: column.put("autoGenerated", metaColumn.isAutoGenerated()
806: + "");
807: String generatorClassName = metaColumn
808: .getGeneratorClassName();
809: column.put("generatorClassName", generatorClassName);
810: ArrayList staticAttributes = new ArrayList();
811: column.put("staticAttributes", staticAttributes);
812: Map map = metaColumn.getGeneratorStaticAttributes();
813: if (map != null) {
814: for (Iterator iter = map.keySet().iterator(); iter
815: .hasNext();) {
816: Object key = iter.next();
817: Object value = map.get(key);
818: HashMap staticAttribute = new HashMap();
819: staticAttribute.put("key", key);
820: staticAttribute.put("value", value);
821: staticAttributes.add(staticAttribute);
822: }
823: }
824: columns.add(column);
825: realIndex++;
826: }
827: tableModel.put("asize", "" + realIndex);
828: return tableModel;
829: }
830:
831: static boolean isClassMainPattern(MetaTable table) {
832: String name = table == null ? "" : table.getTableAlias();
833: return isClassMainPattern(name);
834: }
835:
836: static boolean isClassMainPattern(String name) {
837: return StringUtil.isEmpty(name)
838: || NameHelper.isMainPattern(name);
839: }
840:
841: static String classOrInterfaceName(String coreName,
842: LineStruct intfStruct) {
843: return classOrInterfaceName(coreName,
844: isClassMainPattern(coreName), intfStruct);
845: }
846:
847: static String classOrInterfaceName(MetaTable table,
848: LineStruct intfStruct) {
849: return classOrInterfaceName(table.getTableAlias(), intfStruct);
850: }
851:
852: static String classOrInterfaceName(MetaTable table,
853: boolean mainPattern, LineStruct intfStruct) {
854: return classOrInterfaceName(table.getTableAlias(), mainPattern,
855: intfStruct);
856: }
857:
858: static String classOrInterfaceName(String coreName,
859: boolean mainPattern, LineStruct intfStruct) {
860: return NameHelper.javaName(coreName, intfStruct.classPrefix,
861: intfStruct.classSuffix, true, mainPattern);
862: }
863:
864: public String javaType(ColumnType type) {
865:
866: String javaType = (String) TYPE_2_JAVA.get(type);
867: if (javaType == null) {
868: javaType = type.getValueClassName();
869: }
870: return javaType;
871: }
872:
873: public static String javaName(String name, String prefix,
874: String suffix, boolean calitalizeFirstChar) {
875: return NameHelper.javaName(name, prefix, suffix,
876: calitalizeFirstChar);
877: }
878:
879: public static String getOrIs(MetaColumn column) {
880: return ColumnType.isBooleanPrimitive(column.getType()) ? "is"
881: : "get";
882: }
883:
884: public static String lowerFirstChar(String name) {
885: // return NameHelper.lowerFirstChar(name);
886: return NameHelper.decapitalizeField(name);
887: }
888:
889: public static String javaConstName(String prefix, String name) {
890: return NameHelper.javaConstName(prefix, name);
891: }
892:
893: static boolean isMixedCase(String name) {
894: return NameHelper.isMixedCase(name);
895: }
896:
897: //
898: //
899: // Util classes
900: //
901: //
902:
903: public static Map getType2JavaMap() {
904: return TYPE_2_JAVA;
905: }
906:
907: protected void registerExtraTypes() {
908: }
909:
910: public Log getLogger() {
911: return logger;
912: }
913:
914: public void setLogger(Log logger) {
915: this .logger = logger;
916: }
917:
918: /**
919: * @param args
920: * @throws Exception
921: */
922: public static void main(String[] args) throws Exception {
923: if (args.length < 1) {
924: println("Usage: [po-generator] <persistent-object-config.properties> <env.properties>\n"
925: + " where <persistent-object-config.properties> - required configuration file path;\n"
926: + " <env.properties> - optional token resolution file path.");
927: System.exit(1);
928: }
929: println("STARTED GENERATION ...");
930:
931: PersistentObjectGenerator generator = new PersistentObjectGenerator();
932:
933: String envPath = args.length > 1 ? args[1] : null;
934: generator.process(args[0], envPath);
935:
936: println("FINISHED GENERATION");
937: }
938:
939: }
|