001: package com.completex.objective.tools.generators;
002:
003: import com.completex.objective.components.persistency.meta.MetaObjectReference;
004: import com.completex.objective.components.persistency.meta.MetaObjectModel;
005: import com.completex.objective.components.persistency.meta.Referencing;
006: import com.completex.objective.components.persistency.MetaTable;
007: import com.completex.objective.components.persistency.MetaColumn;
008: import com.completex.objective.components.persistency.ColumnType;
009: import com.completex.objective.components.persistency.Link;
010: import com.completex.objective.util.StringUtil;
011: import com.completex.objective.util.PropertyMap;
012:
013: import java.util.Map;
014: import java.util.List;
015: import java.util.Set;
016: import java.util.Iterator;
017: import java.util.ArrayList;
018: import java.util.LinkedHashMap;
019: import java.util.HashMap;
020: import java.io.Writer;
021: import java.io.IOException;
022: import java.io.FileWriter;
023: import java.io.File;
024:
025: import freemarker.template.Template;
026: import freemarker.template.TemplateException;
027:
028: /**
029: * @author Gennady Krizhevsky
030: */
031: public class CompositeBeanGenerator extends CompositePoGenerator {
032:
033: private static final String CLASS_BEAN_TEMPLATE = "ftl/bean-object.ftl";
034: private static final String INTERFACE_TEMPLATE = "ftl/bean-interface.ftl";
035: protected static final String TAG_BASIC_OBJECT = "basicObject";
036:
037: private static final String DEFAULT_BEAN_PO_MAPPER_TEMPLATE = "ftl/bean-po-mapper.ftl";
038:
039: private LinkedHashMap classMap = new LinkedHashMap();
040: public static final String DEFAULT_BEAN_TO_PO_MAPPER_CLASS = "DefaultBeanToPoMapper";
041: public static final String MAPPER = "mapper";
042:
043: private String mapperClassName = DEFAULT_BEAN_TO_PO_MAPPER_CLASS;
044:
045: protected String getDefaultClassTemplatePath() {
046: return CLASS_BEAN_TEMPLATE;
047: }
048:
049: protected String getDefaultInterfaceTemplatePath() {
050: return INTERFACE_TEMPLATE;
051: }
052:
053: protected String getDefaultBeanPoMapperTemplatePath() {
054: return DEFAULT_BEAN_PO_MAPPER_TEMPLATE;
055: }
056:
057: protected LineStructBlock initializeFromSdl(Map properties)
058: throws IOException {
059: LineStructBlock block = super .initializeFromSdl(properties);
060: PropertyMap allPropertyMap = getAllPropertyMap();
061: PropertyMap mapperProperties = allPropertyMap
062: .getPropertyMap(MAPPER);
063: if (mapperProperties != null && !mapperProperties.isEmpty()) {
064: mapperClassName = mapperProperties.getProperty(CLASS_NAME,
065: DEFAULT_BEAN_TO_PO_MAPPER_CLASS);
066: }
067: return block;
068: }
069:
070: protected LineStruct toLineStruct(PropertyMap propertyMap,
071: boolean interfaces, boolean validatePoProperties)
072: throws IOException {
073: PropertyMap generic = PropertyMap
074: .toPropertyMap((Map) propertyMap.get(GENERIC, true));
075: PropertyMap classes;
076: if (interfaces) {
077: classes = PropertyMap.toPropertyMap((Map) propertyMap
078: .get(INTERFACES));
079: } else {
080: classes = PropertyMap.toPropertyMap((Map) propertyMap.get(
081: CLASSES, true));
082: }
083:
084: String cpmConfigPath = generic.getProperty(CMP_CONFIG_PATH);
085: String poConfigPath = generic.getProperty(PO_CONFIG_PATH);
086: if (cpmConfigPath == null && poConfigPath == null) {
087: throw new IllegalArgumentException(
088: "One of the following propeties is required: "
089: + PO_CONFIG_PATH + " or " + CMP_CONFIG_PATH);
090: }
091:
092: LineStruct classStruct = super .toLineStruct(generic, classes,
093: interfaces, false);
094: classStruct.relatedLineStruct = toRelatedLineStruct(generic,
095: interfaces, true);
096:
097: if (classStruct.relatedLineStruct != null) {
098: classStruct.cmpDescPath = classStruct.relatedLineStruct.cmpDescPath;
099: classStruct.poConfigPath = classStruct.relatedLineStruct.poConfigPath;
100: } else {
101: if (poConfigPath == null) {
102: throw new RuntimeException(
103: "<<<BUGL>>> poConfigPath value is null");
104: }
105: classStruct.poConfigPath = poConfigPath;
106: }
107: return classStruct;
108: }
109:
110: protected LineStruct toRelatedLineStruct(PropertyMap generic,
111: boolean interfaces, boolean validatePoProperties)
112: throws IOException {
113: LineStruct lineStruct = null;
114: String cpmConfigPath = generic.getProperty(CMP_CONFIG_PATH);
115: if (cpmConfigPath != null) {
116: PropertyMap cmpProperties = new PropertyMap();
117: cmpProperties.loadSdl(cpmConfigPath);
118: lineStruct = super .toLineStruct(cmpProperties, interfaces,
119: validatePoProperties);
120: }
121: return lineStruct;
122: }
123:
124: protected void loadMetaObjectModel(String complexModelPath)
125: throws IOException {
126: if (complexModelPath != null) {
127: super .loadMetaObjectModel(complexModelPath);
128: }
129: }
130:
131: protected String className(MetaObjectReference metaObjectReference,
132: String objectKey, LineStruct lineStruct) {
133: LineStruct relatedLineStruct = lineStruct.relatedLineStruct;
134: String shortClassNameBefore = super .className(
135: metaObjectReference, objectKey, relatedLineStruct);
136: String shortClassNameAfter = resolveFixes(shortClassNameBefore,
137: lineStruct);
138:
139: String packageNameBefore = relatedLineStruct.packageName;
140: String packageNameAfter = lineStruct.packageName;
141: String classNameBefore = fullClassPath(packageNameBefore,
142: shortClassNameBefore);
143: String classNameAfter = fullClassPath(packageNameAfter,
144: shortClassNameAfter);
145: getLogger().debug(
146: "classNameBefore = " + classNameBefore
147: + "; classNameAfter = " + classNameAfter);
148:
149: classMapPut(classNameBefore, classNameAfter);
150:
151: return shortClassNameAfter;
152: }
153:
154: private String fullClassPath(String packageNameBefore,
155: String classNameBefore) {
156: classNameBefore = packageNameBefore + "." + classNameBefore;
157: return classNameBefore;
158: }
159:
160: private void classMapPut(String classNameBefore,
161: String classNameAfter) {
162: classMap.put(classNameAfter, classNameBefore);
163: }
164:
165: protected LinkedHashMap getClassMap() {
166: return classMap;
167: }
168:
169: protected String interfaceName(
170: MetaObjectReference metaObjectReference, String objectKey,
171: LineStruct lineStruct) {
172: String className = super .interfaceName(metaObjectReference,
173: objectKey, lineStruct);
174: String name = resolveFixes(className, lineStruct);
175: return name;
176: }
177:
178: protected LineStruct resolveChildLineStruct(
179: ComplexChildHandler handler, LineStruct intfLineStruct,
180: LineStruct classLineStruct) {
181: return isGenerateIntefaces() ? intfLineStruct : classLineStruct;
182: }
183:
184: protected String resolveChildInterfaceName(
185: MetaObjectReference metaObjectReference, Referencing child,
186: MetaObjectModel metaObjectModel, String childClassName,
187: String objectKey, LineStruct childLineStruct) {
188: String className = super .resolveChildInterfaceName(
189: metaObjectReference, child, metaObjectModel,
190: childClassName, objectKey, childLineStruct);
191:
192: className = StringUtil.shortClassName(className);
193: className = resolveFixes(className, childLineStruct);
194: getLogger().debug(
195: "resolveChildInterfaceName: className = " + className);
196:
197: return className;
198: }
199:
200: protected ClassStruct getParentClassName(
201: MetaObjectReference metaObjectReference,
202: MetaObjectModel metaObjectModel, String objectKey,
203: LineStruct classLineStruct, LineStruct intfLineStruct) {
204:
205: BaseExtractHandler handler = new BaseExtractHandler(
206: metaObjectReference, getExtractStruct(),
207: metaObjectModel, objectKey, true);
208: String parentClassName = handler
209: .extractBase(metaObjectReference);
210: boolean root = handler.isRoot();
211:
212: getLogger().debug(
213: "Old parentClassName = " + parentClassName
214: + "; is root ? " + root);
215: if (parentClassName != null && !root) {
216: parentClassName = resolveFixes(parentClassName,
217: classLineStruct);
218: return new ClassStruct(parentClassName, root);
219: } else {
220: return new ClassStruct(classLineStruct.parentClass, root);
221: }
222: }
223:
224: protected ClassStruct getParentInterfaceName(
225: MetaObjectReference metaObjectReference,
226: MetaObjectModel metaObjectModel, String objectKey,
227: LineStruct classLineStruct, LineStruct intfLineStruct) {
228:
229: BaseExtractHandler handler = new BaseExtractHandler(
230: metaObjectReference, getExtractStruct(),
231: metaObjectModel, objectKey, false);
232: String parentClassName = handler
233: .extractBase(metaObjectReference);
234: boolean root = handler.isRoot();
235:
236: getLogger().debug(
237: "Old parentInterfaceName = " + parentClassName
238: + "; is root ? " + root);
239: if (parentClassName != null && !root) {
240: parentClassName = resolveFixes(parentClassName,
241: intfLineStruct);
242: return new ClassStruct(parentClassName, root);
243: } else {
244: return new ClassStruct(intfLineStruct.parentClass, root);
245: }
246: }
247:
248: protected String resolveFixes(String className,
249: LineStruct lineStruct) {
250: String name = NameHelper.addPrefixAndSuffix(className,
251: lineStruct.classPrefix, lineStruct.classSuffix);
252: return name;
253: }
254:
255: protected String typedName(String childName, boolean mixedCase,
256: Link.RelationshipType relationshipType) {
257: return super .typedName(childName, mixedCase, relationshipType);
258: }
259:
260: protected void addCompoundExtraImports(Map baseTemplate,
261: Map templateObjectReference) {
262: //
263: }
264:
265: protected void processClassTemplate(Template template,
266: Map templateObjectReference,
267: MetaObjectReference metaObjectReference,
268: MetaObjectModel metaObjectModel,
269: MetaModelsExtractor.ExtractStruct extractStruct,
270: boolean root, Writer writer, boolean classesGeneratingStage)
271: throws TemplateException, IOException {
272: BaseExtractHandler handler = new BaseExtractHandler(
273: metaObjectReference, extractStruct, metaObjectModel,
274: null, classesGeneratingStage);
275: Map basicObject = handler
276: .extractChildBaseTemplate(metaObjectReference.getBase());
277: if (templateObjectReference.containsKey(TAG_BASIC_OBJECT)) {
278: throw new RuntimeException(TAG_BASIC_OBJECT
279: + " is already defined");
280: }
281: MetaModelsExtractor.ExtractStructEntry baseEntry = handler
282: .getBaseEntry();
283: baseEntry.setUsed(true);
284:
285: addBaseImports(templateObjectReference, baseEntry, handler);
286:
287: if (root) {
288: templateObjectReference.put(TAG_BASIC_OBJECT, basicObject);
289: }
290:
291: super .processClassTemplate(template, templateObjectReference,
292: metaObjectReference, metaObjectModel, extractStruct,
293: root, writer, classesGeneratingStage);
294:
295: }
296:
297: protected void addBaseImports(Map templateObjectReference,
298: MetaModelsExtractor.ExtractStructEntry baseEntry,
299: BaseExtractHandler handler) {
300: List imports = getImports(templateObjectReference);
301: MetaTable baseMetaTable = baseEntry.getMetaTable();
302:
303: for (int i = 0; i < baseMetaTable.size(); i++) {
304: MetaColumn column = baseMetaTable.getColumn(i);
305: ColumnType type = column.getType();
306: Class valueClass = type.getValueClass();
307: if (valueClass != null) {
308: Package aPackage = valueClass.getPackage();
309: if (aPackage != null) {
310: if (!"java.lang".equals(aPackage.getName())
311: && !imports.contains(valueClass.getName())) {
312: imports.add(valueClass.getName());
313: }
314: }
315: }
316: }
317: }
318:
319: protected void postGenerateClasses(MetaObjectModel metaObjectModel,
320: LineStructBlock block) throws IOException,
321: TemplateException {
322: MetaModelsExtractor.ExtractStruct localExtractStruct = getExtractStruct();
323: localExtractStruct.resetExcludeColumns();
324: LineStruct classLineStruct = block.classStruct;
325:
326: String templateName = getDefaultClassTemplatePath();
327: String outputDir = FileUtil
328: .makePath(classLineStruct.packageName,
329: classLineStruct.outputPath);
330: Template template = getTemplate(null, templateName);
331:
332: printGeneratedIn(outputDir);
333:
334: Set entryKeys = localExtractStruct.getEntryKeys();
335: for (Iterator iterator = entryKeys.iterator(); iterator
336: .hasNext();) {
337: String key = (String) iterator.next();
338: MetaModelsExtractor.ExtractStructEntry entry = localExtractStruct
339: .getEntry(key);
340: getLogger().debug(
341: "entry [" + key + "] used ? : " + entry.isUsed());
342:
343: if (!entry.isUsed()) {
344: BaseExtractHandler handler = new BaseExtractHandler(
345: null, localExtractStruct, metaObjectModel,
346: null, true);
347:
348: Map templateMap = handler.extractChildBaseTemplate(key);
349: String shortClassNameBefore = (String) templateMap
350: .get(PersistentObjectGenerator.TAG_CLASS_NAME);
351: String shortClassNameAfter = resolveFixes(
352: shortClassNameBefore, classLineStruct);
353:
354: String classNameBefore = fullClassPath(entry
355: .getBaseClassPackageName(),
356: shortClassNameBefore);
357: String classNameAfter = fullClassPath(
358: classLineStruct.packageName,
359: shortClassNameAfter);
360: getLogger().debug(
361: "(2) classNameBefore = " + classNameBefore
362: + "; classNameAfter = "
363: + classNameAfter);
364: classMapPut(classNameBefore, classNameAfter);
365:
366: templateMap.put(
367: PersistentObjectGenerator.TAG_CLASS_NAME,
368: shortClassNameAfter);
369: templateMap.put(TAG_BASIC_OBJECT, templateMap);
370: templateMap.put(PersistentObjectGenerator.TAG_PACKAGE,
371: classLineStruct.packageName);
372: templateMap.put(
373: PersistentObjectGenerator.TAG_INTERFACES,
374: classLineStruct.interfaces);
375: templateMap
376: .put(
377: PersistentObjectGenerator.TAG_GENERATE_TO_STRING,
378: Boolean
379: .valueOf(classLineStruct.generateToString));
380: addBaseImports(templateMap, entry, handler);
381:
382: String classFileName = shortClassNameAfter + ".java";
383: Writer writer = new FileWriter(new File(outputDir,
384: classFileName));
385: processClassTemplate0(template, templateMap, writer);
386: writer.flush();
387: writer.close();
388: printGeneratedClassFileInfo(classFileName);
389: }
390: }
391: }
392:
393: protected void postGenerateAll(MetaObjectModel metaObjectModel,
394: LineStructBlock block) throws IOException,
395: TemplateException {
396: generateMapper(block);
397: }
398:
399: protected void generateMapper(LineStructBlock block)
400: throws IOException, TemplateException {
401:
402: getLogger().debug("classMap: " + classMap);
403: LineStruct classLineStruct = block.classStruct;
404: if (!classLineStruct.generateMapper) {
405: return;
406: }
407: LineStruct relatedLineStruct = classLineStruct.relatedLineStruct;
408: Map templateMap = new HashMap();
409: String className = mapperClassName;
410: templateMap.put(TAG_CLASS_NAME, className);
411: templateMap.put(TAG_PACKAGE, classLineStruct.packageName);
412: LinkedHashMap classMap = getClassMap();
413: LinkedHashMap methodMap = new LinkedHashMap();
414: for (Iterator it = classMap.keySet().iterator(); it.hasNext();) {
415: Object key = it.next();
416: String value = (String) classMap.get(key);
417: value = StringUtil.shortClassName(value);
418: methodMap.put(key, value);
419: }
420: templateMap.put("methodMap", methodMap);
421: templateMap.put("classMap", classMap);
422: templateMap.put("mapperKeySet", classMap.keySet());
423: String templateName = getDefaultBeanPoMapperTemplatePath();
424: String outputDir = FileUtil
425: .makePath(classLineStruct.packageName,
426: classLineStruct.outputPath);
427: Template template = getTemplate(null, templateName);
428:
429: String classFileName = className + ".java";
430: Writer writer = new FileWriter(new File(outputDir,
431: classFileName));
432: processClassTemplate0(template, templateMap, writer);
433: writer.flush();
434: writer.close();
435:
436: printGeneratedClassFileInfo(classFileName, outputDir);
437: }
438:
439: protected void postGenerateInterfaces(
440: MetaObjectModel metaObjectModel, LineStructBlock block)
441: throws IOException, TemplateException {
442: MetaModelsExtractor.ExtractStruct localExtractStruct = getExtractStruct();
443: localExtractStruct.resetExcludeColumns();
444: LineStruct intfLineStruct = block.intfStruct;
445: String templateName = getDefaultInterfaceTemplatePath();
446: String outputDir = FileUtil.makePath(
447: intfLineStruct.packageName, intfLineStruct.outputPath);
448: Template template = getTemplate(null, templateName);
449: printGeneratedIn(outputDir);
450: Set entryKeys = localExtractStruct.getEntryKeys();
451: for (Iterator iterator = entryKeys.iterator(); iterator
452: .hasNext();) {
453: String key = (String) iterator.next();
454: MetaModelsExtractor.ExtractStructEntry entry = localExtractStruct
455: .getEntry(key);
456: getLogger().debug(
457: "entry [" + key + "] used ? : " + entry.isUsed());
458:
459: if (!entry.isUsed()) {
460: BaseExtractHandler handler = new BaseExtractHandler(
461: null, localExtractStruct, metaObjectModel,
462: null, false);
463:
464: Map templateMap = handler.extractChildBaseTemplate(key);
465: String className = (String) templateMap
466: .get(PersistentObjectGenerator.TAG_CLASS_NAME);
467: String interfaceName = (String) templateMap
468: .get(TAG_INTERFACE_NAME);
469:
470: className = resolveFixes(className, intfLineStruct);
471: templateMap.put(
472: PersistentObjectGenerator.TAG_CLASS_NAME,
473: className);
474: templateMap.put(TAG_INTERFACE_NAME, className);
475: templateMap.put(TAG_BASIC_OBJECT, templateMap);
476: templateMap.put(PersistentObjectGenerator.TAG_PACKAGE,
477: intfLineStruct.packageName);
478: templateMap.put(
479: PersistentObjectGenerator.TAG_INTERFACES,
480: intfLineStruct.interfaces);
481: ArrayList imports = new ArrayList();
482: addBaseImports(templateMap, entry, handler);
483: templateMap.put(PersistentObjectGenerator.TAG_IMPORTS,
484: imports);
485:
486: String classFileName = className + ".java";
487: Writer writer = new FileWriter(new File(outputDir,
488: classFileName));
489: processClassTemplate0(template, templateMap, writer);
490: writer.flush();
491: writer.close();
492: printGeneratedClassFileInfo(classFileName);
493: }
494: }
495: }
496:
497: /**
498: * @param args
499: * @throws Exception
500: */
501: public static void main(String[] args) throws Exception {
502: if (args.length < 1) {
503: println("Usage: [composite-bean-generator] <bean-config.sdl> <env.properties>\n"
504: + " where <bean-config.sdl> - required configuration file path;\n"
505: + " <env.properties> - optional token resolution file path.");
506: System.exit(1);
507: }
508:
509: println("STARTED GENERATION ...");
510:
511: CompositeBeanGenerator generator = new CompositeBeanGenerator();
512:
513: String arg = args[0];
514: String envPath = args.length > 1 ? args[1] : null;
515: generator.process(arg, envPath);
516:
517: println("FINISHED GENERATION");
518: }
519:
520: }
|