0001: package com.completex.objective.tools.generators;
0002:
0003: import com.completex.objective.components.log.Log;
0004: import com.completex.objective.components.log.impl.PrimitiveLogImpl;
0005: import com.completex.objective.components.log.adapter.StdOutputLogAdapter;
0006: import com.completex.objective.components.persistency.type.CollectionFactory;
0007: import com.completex.objective.components.persistency.type.ArrayListCollectionFactory;
0008: import com.completex.objective.components.persistency.type.AbstractListCollectionFactory;
0009: import com.completex.objective.components.persistency.meta.MetaObjectModel;
0010: import com.completex.objective.components.persistency.meta.MetaModel;
0011: import com.completex.objective.components.persistency.meta.MetaObjectReference;
0012: import com.completex.objective.components.persistency.meta.MetaRef;
0013: import com.completex.objective.components.persistency.meta.MetaComplex;
0014: import com.completex.objective.components.persistency.meta.MetaComplexChild;
0015: import com.completex.objective.components.persistency.meta.MetaMultipleResultFactory;
0016: import com.completex.objective.components.persistency.meta.Referencing;
0017: import com.completex.objective.components.persistency.meta.MetaCompound;
0018: import com.completex.objective.components.persistency.meta.MetaCompoundChild;
0019: import com.completex.objective.components.persistency.meta.adapter.ModelLoaderAdapter;
0020: import com.completex.objective.components.persistency.MetaTable;
0021: import com.completex.objective.components.persistency.Link;
0022: import com.completex.objective.components.persistency.ForeignKeys;
0023: import com.completex.objective.components.persistency.ForeignKeyEntries;
0024: import com.completex.objective.components.persistency.ForeignKeyEntry;
0025: import com.completex.objective.components.persistency.ColumnType;
0026: import com.completex.objective.components.persistency.MetaColumn;
0027: import com.completex.objective.components.sdl.reader.SdlReader;
0028: import com.completex.objective.components.sdl.reader.impl.SdlReaderImpl;
0029: import com.completex.objective.util.PropertyMap;
0030: import com.completex.objective.util.StringUtil;
0031:
0032: import java.util.*;
0033: import java.io.IOException;
0034: import java.io.FileReader;
0035: import java.io.Writer;
0036: import java.io.FileWriter;
0037: import java.io.File;
0038:
0039: import freemarker.template.TemplateException;
0040: import freemarker.template.Template;
0041:
0042: /**
0043: * @author Gennady Krizhevsky
0044: */
0045: public class CompositePoGenerator {
0046:
0047: protected static final CollectionFactory DEFAULT_COLLECTION_FACTORY = new ArrayListCollectionFactory();
0048: private static final String CLASS_BEAN_TEMPLATE = "ftl/complex-po-bean.ftl";
0049: private static final String INTERFACE_TEMPLATE = "ftl/complex-po-interface.ftl";
0050:
0051: private Log logger = StdOutputLogAdapter.newInfoLogInstance();
0052: protected SdlReader sdlReader = new SdlReaderImpl();
0053:
0054: public static final String CMP_CONFIG_PATH = "cmp_config_path"; // Composite object generator config path;
0055: public static final String PO_CONFIG_PATH = "po_config_path"; // Persistent object generator config path
0056: public static final String CMP_DESC_PATH = "cmp_desc_path"; // Complex descriptor file path
0057: public static final String OUT_DIR = "out_dir"; // Top level directory for generated classes
0058: public static final String TAG_PACKAGE = "package";
0059: public static final String PACKAGE = TAG_PACKAGE; // Package
0060: public static final String FILTER_PATTERN = "filter_pattern";
0061: public static final String GENERATE_TO_STRING = "generate_to_string";
0062: public static final String GENERATE_INTERFACES = "generate_interfaces";
0063: public static final String GENERATE_BEAN = "generate_bean";
0064: public static final String GENERIC = "generic";
0065: public static final String CLASSES = "classes";
0066: public static final String INTERFACES = "interfaces";
0067: public static final String CLASS_PREFIX = "class_prefix";
0068: public static final String CLASS_SUFFIX = "class_suffix";
0069: public static final String PARENT_CLASS = "parent_class";
0070:
0071: private MetaModelsExtractor metaModelsExtractor = new PersistentObjectGenerator();
0072:
0073: private MetaObjectModel metaObjectModel;
0074: private MetaModelsExtractor.ExtractStruct extractStruct;
0075: // Indicates if it is required to generate intterfaces
0076: private boolean generateIntefaces;
0077: public static final String CPX_CHILD_PREFIX = "CPX_CHILD_";
0078: public static final String CPD_CHILD_PREFIX = "CPD_CHILD_";
0079: public static final String COLLECTION_FACTORY_SUFFIX = "_COLLECTION_FACTORY";
0080: public static final String TAG_INTERFACE_NAME = PersistentObjectGenerator.TAG_INTERFACE_NAME;
0081: public static final String TAG_CLASS_NAME = "className";
0082: public static final String CLASS_NAME = "class_name";
0083:
0084: private PropertyMap allPropertyMap;
0085: public static final String GENERATE_MAPPER = "generate_mapper";
0086: private static final String DEBUG = "debug";
0087: protected boolean debug;
0088:
0089: public CompositePoGenerator() {
0090: }
0091:
0092: public MetaObjectModel getMetaObjectModel() {
0093: return metaObjectModel;
0094: }
0095:
0096: public MetaModelsExtractor.ExtractStruct getExtractStruct() {
0097: return extractStruct;
0098: }
0099:
0100: public boolean isGenerateIntefaces() {
0101: return generateIntefaces;
0102: }
0103:
0104: public void setGenerateIntefaces(boolean generateIntefaces) {
0105: this .generateIntefaces = generateIntefaces;
0106: }
0107:
0108: /**
0109: * This is where things happen
0110: *
0111: * @param propertiesPath
0112: * @throws Exception
0113: */
0114: public void process(String propertiesPath) throws Exception {
0115: process(propertiesPath, null);
0116: }
0117:
0118: public void process(String propertiesPath, String envPath)
0119: throws Exception {
0120: PropertyMap env = PersistentObjectGenerator.env(envPath);
0121: Map map = extractProperties(propertiesPath, env);
0122: process(map, env);
0123: }
0124:
0125: public void process(Map map) throws Exception {
0126: process(map, null);
0127: }
0128:
0129: public void process(Map map, Properties env) throws Exception {
0130: LineStructBlock lineStructBlock = initializeExtractStruct(map,
0131: env);
0132: //
0133: // Let's load complex model:
0134: //
0135: loadMetaObjectModel(lineStructBlock.classStruct.cmpDescPath);
0136: process(lineStructBlock);
0137: }
0138:
0139: public void process(LineStructBlock lineStructBlock)
0140: throws Exception {
0141: //
0142: // Genarate stuff:
0143: //
0144:
0145: // Classes:
0146: if (getMetaObjectModel() != null) {
0147: generateClasses(getMetaObjectModel(), lineStructBlock);
0148: }
0149: postGenerateClasses(getMetaObjectModel(), lineStructBlock);
0150:
0151: // Interfaces:
0152: if (getMetaObjectModel() != null) {
0153: if (isGenerateIntefaces()) {
0154: generateInterfaces(getMetaObjectModel(),
0155: lineStructBlock);
0156: }
0157: }
0158: if (isGenerateIntefaces()) {
0159: postGenerateInterfaces(getMetaObjectModel(),
0160: lineStructBlock);
0161: }
0162:
0163: // After all:
0164: postGenerateAll(getMetaObjectModel(), lineStructBlock);
0165: }
0166:
0167: protected void postGenerateAll(MetaObjectModel metaObjectModel,
0168: LineStructBlock lineStructBlock) throws IOException,
0169: TemplateException {
0170: }
0171:
0172: protected void postGenerateInterfaces(
0173: MetaObjectModel metaObjectModel,
0174: LineStructBlock lineStructBlock) throws IOException,
0175: TemplateException {
0176: }
0177:
0178: protected void postGenerateClasses(MetaObjectModel metaObjectModel,
0179: LineStructBlock block) throws IOException,
0180: TemplateException {
0181: MetaModelsExtractor.ExtractStruct localExtractStruct = extractStruct;
0182:
0183: Set entryKeys = localExtractStruct.getEntryKeys();
0184: for (Iterator iterator = entryKeys.iterator(); iterator
0185: .hasNext();) {
0186: String key = (String) iterator.next();
0187: MetaModelsExtractor.ExtractStructEntry entry = localExtractStruct
0188: .getEntry(key);
0189: getLogger().debug(
0190: "entry [" + key + "] used ? : " + entry.isUsed());
0191: }
0192: }
0193:
0194: protected LineStructBlock initializeExtractStruct(Map map,
0195: Properties env) throws Exception {
0196: LineStructBlock lineStructBlock = initializeFromSdl(map);
0197: this .extractStruct = metaModelsExtractor.extractMetaModels(
0198: lineStructBlock.classStruct.poConfigPath, env);
0199: return lineStructBlock;
0200: }
0201:
0202: protected void loadMetaObjectModel(String complexModelPath)
0203: throws IOException {
0204: FileReader fileReader = new FileReader(complexModelPath);
0205: Map map = (Map) sdlReader.read(fileReader);
0206: PropertyMap metaObjectModelMap = PropertyMap.toPropertyMap(map);
0207: fileReader.close();
0208: metaObjectModel = new MetaObjectModel(metaObjectModelMap);
0209: }
0210:
0211: protected LineStructBlock initializeFromSdl(Map properties)
0212: throws IOException {
0213: PropertyMap propertyMap = PropertyMap.toPropertyMap(properties);
0214: this .allPropertyMap = propertyMap;
0215: boolean validatePoProperties = true;
0216: LineStruct classStruct = toLineStruct(propertyMap, false,
0217: validatePoProperties);
0218: setGenerateIntefaces(classStruct.generateInterfaces);
0219: LineStruct intfStruct = null;
0220: if (isGenerateIntefaces()) {
0221: intfStruct = toLineStruct(propertyMap, true,
0222: validatePoProperties);
0223: }
0224:
0225: return new LineStructBlock(classStruct, intfStruct);
0226: }
0227:
0228: protected PropertyMap getAllPropertyMap() {
0229: return allPropertyMap;
0230: }
0231:
0232: protected LineStruct toLineStruct(PropertyMap propertyMap,
0233: boolean interfaces, boolean validatePoProperties)
0234: throws IOException {
0235: PropertyMap generic = PropertyMap
0236: .toPropertyMap((Map) propertyMap.get(GENERIC, true));
0237: PropertyMap classes;
0238: if (interfaces) {
0239: classes = PropertyMap.toPropertyMap((Map) propertyMap
0240: .get(INTERFACES));
0241: } else {
0242: classes = PropertyMap.toPropertyMap((Map) propertyMap.get(
0243: CLASSES, true));
0244: }
0245: LineStruct classStruct = toLineStruct(generic, classes,
0246: interfaces, validatePoProperties);
0247: return classStruct;
0248: }
0249:
0250: protected LineStruct toLineStruct(PropertyMap generic,
0251: PropertyMap classes, boolean interfaces,
0252: boolean validatePoProperties) throws IOException {
0253: LineStruct lineStruct = null;
0254: if (classes != null && !classes.isEmpty()) {
0255: lineStruct = new LineStruct();
0256: lineStruct.poConfigPath = generic.getProperty(
0257: PO_CONFIG_PATH, validatePoProperties);
0258: lineStruct.cmpDescPath = generic.getProperty(CMP_DESC_PATH,
0259: validatePoProperties);
0260:
0261: lineStruct.generateInterfaces = generic
0262: .getBoolean(GENERATE_INTERFACES);
0263: lineStruct.generateToString = generic
0264: .getBoolean(GENERATE_TO_STRING);
0265: lineStruct.generateBean = generic.getBoolean(GENERATE_BEAN,
0266: Boolean.FALSE, true);
0267: lineStruct.generateMapper = generic.getBoolean(
0268: GENERATE_MAPPER, Boolean.FALSE, true);
0269: lineStruct.genericImports = generic.getProperty("imports");
0270: lineStruct.debug = generic.getBoolean(DEBUG);
0271: debug = generic.getBoolean(DEBUG);
0272: if (logger instanceof PrimitiveLogImpl) {
0273: ((PrimitiveLogImpl) logger)
0274: .setDebugEnabled(lineStruct.debug);
0275: }
0276:
0277: lineStruct.outputPath = classes.getProperty(OUT_DIR, true);
0278: lineStruct.packageName = classes.getProperty(PACKAGE, true);
0279: lineStruct.filterPattern = classes
0280: .getProperty(FILTER_PATTERN);
0281: lineStruct.interfaces = classes.getProperty("implements");
0282: lineStruct.specificImports = classes.getProperty("imports");
0283: lineStruct.classPrefix = classes.getProperty(CLASS_PREFIX);
0284: lineStruct.classSuffix = classes.getProperty(CLASS_SUFFIX);
0285: lineStruct.parentClass = classes.getProperty(PARENT_CLASS);
0286: }
0287: return lineStruct;
0288: }
0289:
0290: public Map extractProperties(String propertiesPath)
0291: throws IOException {
0292: return extractProperties(propertiesPath, null);
0293: }
0294:
0295: // public Map extractProperties(String propertiesPath, String envPath) throws IOException {
0296: // return PersistentObjectGenerator.extractProperties(propertiesPath, sdlReader, PersistentObjectGenerator.env(envPath));
0297: // }
0298:
0299: public Map extractProperties(String propertiesPath, Properties env)
0300: throws IOException {
0301: return PersistentObjectGenerator.extractProperties(
0302: propertiesPath, sdlReader, env);
0303: }
0304:
0305: protected MetaModel loadModelFromFile(
0306: ModelLoaderAdapter modelFileLoaderAdapter) throws Exception {
0307: logger.info("loadModelFromFile started");
0308:
0309: MetaModel model = modelFileLoaderAdapter.load(null);
0310: logger.info("loadModelFromFile ended");
0311:
0312: return model;
0313: }
0314:
0315: protected void generateClasses(MetaObjectModel metaObjectModel,
0316: LineStructBlock block) throws IOException,
0317: TemplateException, ClassNotFoundException,
0318: IllegalAccessException, InstantiationException {
0319: String templateName = getDefaultClassTemplatePath();
0320: LineStruct lineStruct = block.classStruct;
0321: LineStruct intfLineStruct = block.intfStruct;
0322: //
0323: // Cycle through references :
0324: //
0325: populateClassTemplate(metaObjectModel, lineStruct,
0326: intfLineStruct, templateName);
0327: }
0328:
0329: protected String getDefaultClassTemplatePath() {
0330: return CLASS_BEAN_TEMPLATE;
0331: }
0332:
0333: protected String getDefaultInterfaceTemplatePath() {
0334: return INTERFACE_TEMPLATE;
0335: }
0336:
0337: protected void generateInterfaces(MetaObjectModel metaObjectModel,
0338: LineStructBlock block) throws IOException,
0339: TemplateException, ClassNotFoundException,
0340: IllegalAccessException, InstantiationException {
0341: String templateName = getDefaultInterfaceTemplatePath();
0342: LineStruct lineStruct = block.intfStruct;
0343: if (block.intfStruct == null) {
0344: throw new IllegalArgumentException(
0345: "Cannot generate interfaces since interface configuration is empty. "
0346: + "Usually it would indicate that 'interfaces' section is missing in composite persistent object config file.");
0347: }
0348: //
0349: // Cycle through references :
0350: //
0351: populateInterfaceTemplate(metaObjectModel, lineStruct,
0352: templateName);
0353: }
0354:
0355: private void populateClassTemplate(MetaObjectModel metaObjectModel,
0356: LineStruct classLineStruct, LineStruct intfLineStruct,
0357: String templateName) throws ClassNotFoundException,
0358: InstantiationException, IllegalAccessException,
0359: IOException, TemplateException {
0360: String outputDir = FileUtil
0361: .makePath(classLineStruct.packageName,
0362: classLineStruct.outputPath);
0363: Template template = getTemplate(null, templateName);
0364:
0365: printGeneratedIn(outputDir);
0366:
0367: Date timestamp = new Date();
0368: for (MetaObjectModel.MetaObjectReferenceIterator it = metaObjectModel
0369: .iterator(); it.hasNext();) {
0370: MetaObjectReference metaObjectReference = it
0371: .nextMetaObjectReference();
0372: String objectKey = it.getKey();
0373: if (objectKey == null) {
0374: throw new IllegalArgumentException(
0375: "BUG: objectKey == null");
0376: }
0377:
0378: ArrayList imports = new ArrayList();
0379: String className = className(metaObjectReference,
0380: objectKey, classLineStruct);
0381: String interfaceName = null;
0382: if (classLineStruct.generateInterfaces) {
0383: interfaceName = interfaceName(metaObjectReference,
0384: objectKey, intfLineStruct);
0385: }
0386: String interfaces = interfaceName;
0387: if (interfaces == null) {
0388: if (classLineStruct.interfaces != null) {
0389: interfaces = classLineStruct.interfaces;
0390: }
0391: } else {
0392: if (classLineStruct.interfaces != null) {
0393: interfaces += ", " + classLineStruct.interfaces;
0394: }
0395: }
0396: MetaRef metaBase = metaObjectReference.getBase();
0397: logger.debug("Generating class "
0398: + metaObjectReference.getClassName());
0399: //
0400: // If MetaBase className is not null - use it, otherwise - try to get it by ref
0401: //
0402: ClassStruct baseClassStruct = getParentClassName(
0403: metaObjectReference, metaObjectModel, objectKey,
0404: classLineStruct, intfLineStruct);
0405: String baseName = baseClassStruct.getClassName();
0406: getLogger().debug("baseClassNameByDependency: " + baseName);
0407:
0408: Map templateObjectReference = metaObjectReference.toMap();
0409: // boolean root = isRoot(metaObjectReference, metaObjectModel, objectKey, classLineStruct, intfLineStruct);
0410: boolean root = baseClassStruct.isRoot();
0411:
0412: getLogger().debug(
0413: "Class: " + className + " ; is root ? " + root);
0414:
0415: templateObjectReference.put(
0416: PersistentObjectGenerator.TAG_INTERFACES,
0417: interfaces);
0418: templateObjectReference.put(
0419: PersistentObjectGenerator.TAG_PACKAGE,
0420: classLineStruct.packageName);
0421: templateObjectReference.put("timestamp", timestamp);
0422: templateObjectReference.put(
0423: PersistentObjectGenerator.TAG_IMPORTS, imports);
0424: populateIfEmpty(templateObjectReference,
0425: PersistentObjectGenerator.TAG_CLASS_NAME, className);
0426: templateObjectReference.put(
0427: PersistentObjectGenerator.TAG_GENERATE_TO_STRING,
0428: new Boolean(classLineStruct.generateToString));
0429:
0430: templateObjectReference.put("baseName", baseName);
0431: MetaTable parentTable = metaTableByRef(metaBase,
0432: metaObjectModel, new HashSet());
0433: templateObjectReference.put("keySize", new Integer(
0434: parentTable.keySize()));
0435: populatePks(parentTable, templateObjectReference);
0436:
0437: processComplexClass(metaObjectReference,
0438: templateObjectReference, metaObjectModel, imports,
0439: parentTable, className, objectKey, classLineStruct,
0440: intfLineStruct);
0441: processCompoundClass(metaObjectReference,
0442: templateObjectReference, metaObjectModel,
0443: objectKey, classLineStruct, intfLineStruct);
0444:
0445: logger.debug("outputDir = " + outputDir + "; className = "
0446: + className);
0447: String classFileName = className + ".java";
0448: Writer writer = new FileWriter(new File(outputDir,
0449: classFileName));
0450: processClassTemplate(template, templateObjectReference,
0451: metaObjectReference, metaObjectModel,
0452: extractStruct, root, writer, true);
0453: writer.flush();
0454: writer.close();
0455: printGeneratedClassFileInfo(classFileName);
0456: }
0457: }
0458:
0459: protected void processClassTemplate(Template template,
0460: Map templateObjectReference,
0461: MetaObjectReference metaObjectReference,
0462: MetaObjectModel metaObjectModel,
0463: MetaModelsExtractor.ExtractStruct extractStruct,
0464: boolean root, Writer writer, boolean generateClasses)
0465: throws TemplateException, IOException {
0466: processClassTemplate0(template, templateObjectReference, writer);
0467: }
0468:
0469: protected void processClassTemplate0(Template template,
0470: Map templateObjectReference, Writer writer)
0471: throws TemplateException, IOException {
0472: template.process(templateObjectReference, writer);
0473: }
0474:
0475: protected ClassStruct getParentClassName(
0476: MetaObjectReference metaObjectReference,
0477: MetaObjectModel metaObjectModel, String objectKey,
0478: LineStruct classLineStruct, LineStruct intfLineStruct) {
0479: return baseClassNameByDependency(metaObjectReference,
0480: metaObjectReference, metaObjectModel, objectKey);
0481: }
0482:
0483: protected ClassStruct getParentInterfaceName(
0484: MetaObjectReference metaObjectReference,
0485: MetaObjectModel metaObjectModel, String objectKey,
0486: LineStruct classLineStruct, LineStruct intfLineStruct) {
0487: return baseInterfaceNameByDependency(metaObjectReference,
0488: metaObjectReference, metaObjectModel, objectKey);
0489: }
0490:
0491: private void populateIfEmpty(Map templateObjectReference,
0492: String someName, String interfaceName) {
0493: if (templateObjectReference.containsKey(someName)
0494: || templateObjectReference.get(someName) == null) {
0495: templateObjectReference.put(someName, interfaceName);
0496: }
0497: }
0498:
0499: protected void populateInterfaceTemplate(
0500: MetaObjectModel metaObjectModel, LineStruct lineStruct,
0501: String templateName) throws ClassNotFoundException,
0502: InstantiationException, IllegalAccessException,
0503: IOException, TemplateException {
0504: String outputDir = FileUtil.makePath(lineStruct.packageName,
0505: lineStruct.outputPath);
0506: Date timestamp = new Date();
0507: Template template = getTemplate(null, templateName);
0508: printGeneratedIn(outputDir);
0509: for (MetaObjectModel.MetaObjectReferenceIterator it = metaObjectModel
0510: .iterator(); it.hasNext();) {
0511: MetaObjectReference metaObjectReference = it
0512: .nextMetaObjectReference();
0513: String objectKey = it.getKey();
0514: if (objectKey == null) {
0515: throw new IllegalArgumentException(
0516: "BUG: objectKey == null");
0517: }
0518: ArrayList imports = new ArrayList();
0519: String interfaceName = interfaceName(metaObjectReference,
0520: objectKey, lineStruct);
0521: MetaRef metaBase = metaObjectReference.getBase();
0522: logger.debug("Generating interface " + interfaceName);
0523: //
0524: // If MetaBase className is not null - use it, otherwise - try to get it by ref
0525: //
0526: ClassStruct baseClassStructOld = baseInterfaceNameByDependency(
0527: metaObjectReference, metaObjectReference,
0528: metaObjectModel, objectKey);
0529: String baseNameOld = baseClassStructOld.getClassName();
0530: ClassStruct baseClassStruct = getParentInterfaceName(
0531: metaObjectReference, metaObjectModel, objectKey,
0532: lineStruct, lineStruct);
0533: String baseName = baseClassStruct.getClassName();
0534: getLogger().debug(
0535: "Intf baseClassNameByDependency: " + baseName
0536: + "; baseNameOld = " + baseNameOld);
0537:
0538: Map templateObjectReference = metaObjectReference.toMap();
0539: boolean root = baseClassStruct.isRoot();
0540: // boolean root = isRoot(metaObjectReference, metaObjectModel, objectKey, lineStruct, lineStruct);
0541: templateObjectReference.put(TAG_PACKAGE,
0542: lineStruct.packageName);
0543: templateObjectReference.put("timestamp", timestamp);
0544: templateObjectReference.put(
0545: PersistentObjectGenerator.TAG_IMPORTS, imports);
0546: templateObjectReference.put("baseName", baseName);
0547: populateIfEmpty(templateObjectReference,
0548: TAG_INTERFACE_NAME, interfaceName);
0549:
0550: MetaTable parentTable = metaTableByRef(metaBase,
0551: metaObjectModel, new HashSet());
0552: templateObjectReference.put("keySize", new Integer(
0553: parentTable.keySize()));
0554: populatePks(parentTable, templateObjectReference);
0555:
0556: processComplexInterface(metaObjectReference,
0557: templateObjectReference, metaObjectModel, imports,
0558: parentTable, interfaceName, objectKey, lineStruct);
0559: processCompoundInterface(metaObjectReference,
0560: templateObjectReference, metaObjectModel,
0561: objectKey, lineStruct);
0562:
0563: getLogger().debug(
0564: "outputDir = " + outputDir + "; interfaceName = "
0565: + interfaceName);
0566: String classFileName = interfaceName + ".java";
0567: Writer writer = new FileWriter(new File(outputDir,
0568: classFileName));
0569: // processClassTemplate0(template, templateObjectReference, writer);
0570: processClassTemplate(template, templateObjectReference,
0571: metaObjectReference, metaObjectModel,
0572: extractStruct, root, writer, false);
0573: writer.flush();
0574: writer.close();
0575: printGeneratedClassFileInfo(classFileName);
0576: }
0577: }
0578:
0579: protected String className(MetaObjectReference metaObjectReference,
0580: String objectKey, LineStruct lineStruct) {
0581: String className;
0582: if (metaObjectReference.getClassName() != null) {
0583: className = metaObjectReference.getClassName();
0584: } else if (objectKey != null) {
0585: boolean mainPattern = isMainPattern(objectKey);
0586: String classPrefix = lineStruct.classPrefix;
0587: String classSuffix = lineStruct.classSuffix;
0588: className = javaName(objectKey, classPrefix, classSuffix,
0589: true, mainPattern);
0590: } else {
0591: throw new IllegalArgumentException(
0592: "Cannot derive class name since both className and object key are null");
0593: }
0594: return className;
0595: }
0596:
0597: protected String interfaceName(
0598: MetaObjectReference metaObjectReference, String objectKey,
0599: LineStruct lineStruct) {
0600: String className = null;
0601: if (metaObjectReference.getInterfaceName() != null) {
0602: className = metaObjectReference.getInterfaceName();
0603: } else if (objectKey != null) {
0604: boolean mainPattern = isMainPattern(objectKey);
0605: className = javaName(objectKey, lineStruct.classPrefix,
0606: lineStruct.classSuffix, true, mainPattern);
0607: } else {
0608: throw new IllegalArgumentException(
0609: "Cannot derive interface name since both className and object key are null");
0610: }
0611: return className;
0612: }
0613:
0614: protected void processComplex(
0615: MetaObjectReference metaObjectReference,
0616: Map templateObjectReference,
0617: MetaObjectModel metaObjectModel, ArrayList imports,
0618: MetaTable parentTable, String parentClassName,
0619: boolean classes, String objectKey,
0620: LineStruct classLineStruct, LineStruct intfLineStruct)
0621: throws ClassNotFoundException, InstantiationException,
0622: IllegalAccessException {
0623: MetaComplex metaComplex = metaObjectReference.getComplex();
0624: if (metaComplex == null || metaComplex.getChildren() == null) {
0625: return;
0626: }
0627:
0628: int childCount = 0;
0629: Set complexChildrenKeySet = metaComplex.getChildren().keySet();
0630: templateObjectReference.put("complexChildrenKeySet",
0631: complexChildrenKeySet);
0632: Map complexChildren = metaComplex.getChildren();
0633: Map complexMap = (Map) templateObjectReference
0634: .get(MetaObjectReference.TAG_COMPLEX);
0635: Map complexChildrenMap = (Map) complexMap
0636: .get(MetaComplex.TAG_COMPLEX_CHILDREN);
0637: ComplexChildHandler handler = new ComplexChildHandler(
0638: metaObjectReference, extractStruct, metaObjectModel,
0639: objectKey, classes);
0640: for (Iterator iterator = complexChildrenMap.keySet().iterator(); iterator
0641: .hasNext(); childCount++) {
0642: String key = (String) iterator.next();
0643: MetaComplexChild child = (MetaComplexChild) complexChildren
0644: .get(key);
0645: Link.RelationshipType relationshipType = child
0646: .getRelationshipType();
0647: MetaRef metaRef = child.getBase();
0648: Map childMap = (Map) complexChildrenMap.get(key);
0649:
0650: String constName = javaConstName(CPX_CHILD_PREFIX, key);
0651: childMap.put("constName", constName);
0652: childMap.put("lazyRetrieval", String
0653: .valueOf(child.isLazy()));
0654: childMap.put("cascadeInsert", String.valueOf(child
0655: .isCascadeInsert()));
0656: childMap.put("cascadeUpdate", String.valueOf(child
0657: .isCascadeUpdate()));
0658: childMap.put("cascadeDelete", String.valueOf(child
0659: .isCascadeDelete()));
0660: childMap.put("insertBeforeParent", String.valueOf(child
0661: .isInsertBeforeParent()));
0662: if (child.getInlineMode() != null) {
0663: childMap.put("inlineMode", "Link."
0664: + child.getInlineMode().toUpperCase()
0665: + "_JOIN_MODE");
0666: }
0667: String childName = child.getName();
0668: Object mappedChildName = childMap.get("name");
0669: if (mappedChildName == null) {
0670: throw new RuntimeException(
0671: "childMap.get(name) == null) for constName = "
0672: + constName);
0673: }
0674: //
0675: // Resolve dependency & put child type:
0676: //
0677: // ${child.type} ${child.typedName};
0678: //
0679: // For type the logic is : if there is class - use it, oterwise - resolve:
0680: //
0681: handler.handleChild(key, child);
0682: String childClassName = handler.getBaseName();
0683: LineStruct childLineStruct = resolveChildLineStruct(
0684: handler, intfLineStruct, classLineStruct);
0685: String childInterfaceName = resolveChildInterfaceName(
0686: metaObjectReference, child, metaObjectModel,
0687: childClassName, key, childLineStruct);
0688:
0689: childMap.put(TAG_INTERFACE_NAME, childInterfaceName);
0690: String type = childInterfaceName;
0691: childMap.put(TAG_CLASS_NAME, childClassName);
0692: childMap.put("getterName", "getFirstChildObject");
0693:
0694: boolean mixedCase = isMixedCase(child.getName());
0695:
0696: String typedName = typedName(childName, mixedCase,
0697: relationshipType);
0698: //
0699: // In case one-to-many relationship - replace type with corresponding collection:
0700: //
0701: if (relationshipType == Link.ONE_TO_MANY) {
0702: if (!childMap
0703: .containsKey(MetaComplexChild.TAG_MULTIPLE_RESULT_FACTORY)) {
0704: childMap
0705: .put(
0706: MetaComplexChild.TAG_MULTIPLE_RESULT_FACTORY,
0707: null);
0708: }
0709: MetaMultipleResultFactory multipleResultFactory = child
0710: .getMultipleResultFactory();
0711: String multipleResultFactoryClassName;
0712: if (multipleResultFactory == null
0713: || multipleResultFactory.getClassName() == null
0714: || multipleResultFactory.getClassName().trim()
0715: .length() == 0) {
0716: logger
0717: .debug("No multipleResultFactory provided - using default one : with "
0718: + DEFAULT_COLLECTION_FACTORY
0719: .getClass().getName());
0720: multipleResultFactoryClassName = DEFAULT_COLLECTION_FACTORY
0721: .getClass().getName();
0722: multipleResultFactory = new MetaMultipleResultFactory(
0723: multipleResultFactoryClassName);
0724: childMap
0725: .put(
0726: MetaComplexChild.TAG_MULTIPLE_RESULT_FACTORY,
0727: multipleResultFactory.toMap());
0728: } else {
0729: multipleResultFactoryClassName = multipleResultFactory
0730: .getClassName();
0731: }
0732: String constructorArgs = buildConstructorArgs(multipleResultFactory);
0733: Map multipleResultFactoryMap = (Map) childMap
0734: .get(MetaComplexChild.TAG_MULTIPLE_RESULT_FACTORY);
0735: multipleResultFactoryMap.put(
0736: MetaMultipleResultFactory.TAG_CONSTRUCTOR_ARGS,
0737: constructorArgs);
0738: Class multiClass = Class
0739: .forName(multipleResultFactoryClassName);
0740: type = resolveType(multiClass, imports, type);
0741: childMap.put("getterName", "getChildObject");
0742: multipleResultFactoryMap.put(TAG_CLASS_NAME,
0743: multipleResultFactoryClassName);
0744: String collectionFactoryConst = javaConstName("", key
0745: + "CollectionFactory");
0746: multipleResultFactoryMap.put("constName",
0747: collectionFactoryConst);
0748: String collectionImpl = resolveCollectionImpl(
0749: multiClass, imports);
0750: multipleResultFactoryMap.put("collectionImpl",
0751: collectionImpl);
0752: } else {
0753: Object multipleResFac = childMap
0754: .get(MetaComplexChild.TAG_MULTIPLE_RESULT_FACTORY);
0755: if (multipleResFac != null) {
0756: throw new IllegalArgumentException(
0757: "Multiple result factory is defined for not one_to_may relationship");
0758: }
0759: }
0760: childMap.put("type", type);
0761: childMap.put("typedName", typedName);
0762: childMap.put("cpxIndex", String.valueOf(childCount));
0763: childMap.put("cpxIndexName", javaConstName("CPX_INDEX_",
0764: key));
0765: childMap.put("cpxIndexValue", String.valueOf(childCount));
0766: //
0767: // Find the table to create a link:
0768: //
0769: MetaModelsExtractor.ExtractStructEntry entry = extractStructEntryByRef(
0770: metaRef, metaObjectModel, new HashSet());
0771: if (entry == null) {
0772: throw new NullPointerException(
0773: "Cannot find entry by ref : " + metaRef);
0774: }
0775: MetaTable childTable = entry.getMetaTable();
0776: if (childTable == null) {
0777: throw new IllegalArgumentException(
0778: "Cannot find child table by reference : "
0779: + metaRef);
0780: }
0781: //
0782: // Now we have both parent & child tables, we can create a link between them:
0783: //
0784: ForeignKeys parentForeignKeys = parentTable
0785: .getForeignKeys();
0786: ForeignKeys childForeignKeys = childTable.getForeignKeys();
0787:
0788: ArrayList parentIndexConsts = new ArrayList();
0789: ArrayList childIndexConsts = new ArrayList();
0790: if (isReversedInsertOrder(parentTable, childTable)) {
0791: //
0792: // This is "reversed" case - child inserted before parent
0793: //
0794: childMap.put("insertBeforeParent", "true");
0795: populateIndexConsts(parentForeignKeys, childTable,
0796: parentTable, childClassName, parentClassName,
0797: childIndexConsts, parentIndexConsts);
0798:
0799: } else if (childForeignKeys != null) {
0800: //
0801: // This is a "normal" case - child inserted after parent
0802: //
0803: populateIndexConsts(childForeignKeys, parentTable,
0804: childTable, parentClassName, childClassName,
0805: parentIndexConsts, childIndexConsts);
0806: } else {
0807: println("Both parent & child foreign keys found for tables parent ["
0808: + parentTable.getTableName()
0809: + "], child ["
0810: + childTable.getTableName()
0811: + "]. Only parent ones will be used");
0812: //
0813: // This is a "normal" case - child inserted after parent
0814: //
0815: populateIndexConsts(childForeignKeys, parentTable,
0816: childTable, parentClassName, childClassName,
0817: parentIndexConsts, childIndexConsts);
0818: }
0819: childMap.put("parentIndexConsts", parentIndexConsts);
0820: childMap.put("childIndexConsts", childIndexConsts);
0821: }
0822: }
0823:
0824: protected LineStruct resolveChildLineStruct(
0825: ComplexChildHandler handler, LineStruct intfLineStruct,
0826: LineStruct classLineStruct) {
0827: return handler.isInterface() ? intfLineStruct : classLineStruct;
0828: }
0829:
0830: protected String resolveCollectionImpl(Class multiClass,
0831: ArrayList imports) throws IllegalAccessException,
0832: InstantiationException {
0833: String type = null;
0834: if (CollectionFactory.class.isAssignableFrom(multiClass)) {
0835: AbstractListCollectionFactory factory = (AbstractListCollectionFactory) multiClass
0836: .newInstance();
0837: Object instance = factory.newCollection();
0838: if (instance instanceof ArrayList) {
0839: type = addArrayListImpl(imports);
0840: } else if (instance instanceof LinkedList) {
0841: imports.add("java.util.LinkedList");
0842: type = "LinkedList";
0843: } else if (instance instanceof List) {
0844: type = addArrayListImpl(imports);
0845: } else if (instance instanceof HashSet) {
0846: imports.add("java.util.HashSet");
0847: type = "HashSet";
0848: } else if (instance instanceof LinkedHashSet) {
0849: imports.add("java.util.LinkedHashSet");
0850: type = "LinkedHashSet";
0851: } else if (instance instanceof Set) {
0852: imports.add("java.util.HashSet");
0853: type = "HashSet";
0854: } else if (instance instanceof HashMap) {
0855: imports.add("java.util.HashMap");
0856: type = "HashMap";
0857: } else if (instance instanceof LinkedHashMap) {
0858: imports.add("java.util.LinkedHashMap");
0859: type = "LinkedHashMap";
0860: } else if (instance instanceof Map) {
0861: imports.add("java.util.HashMap");
0862: type = "HashMap";
0863: } else {
0864: type = addArrayListImpl(imports);
0865: }
0866: } else {
0867: type = addArrayListImpl(imports);
0868: }
0869: return type;
0870: }
0871:
0872: private String addArrayListImpl(ArrayList imports) {
0873: imports.add("java.util.ArrayList");
0874: return "ArrayList";
0875: }
0876:
0877: protected String resolveType(Class multiClass, ArrayList imports,
0878: String type) throws InstantiationException,
0879: IllegalAccessException {
0880: if (CollectionFactory.class.isAssignableFrom(multiClass)) {
0881: AbstractListCollectionFactory factory = (AbstractListCollectionFactory) multiClass
0882: .newInstance();
0883: CollectionFactory nullClass = factory
0884: .nullCollectionFactory();
0885: Object instance = nullClass.newCollection();
0886: type = resolveType(instance, imports);
0887: }
0888: return type;
0889: }
0890:
0891: protected String buildConstructorArgs(
0892: MetaMultipleResultFactory multipleResultFactory) {
0893: String constructorArgs = "";
0894: if (multipleResultFactory.getConstructorArgs() != null) {
0895: for (int i = 0; i < multipleResultFactory
0896: .getConstructorArgs().size(); i++) {
0897: String s = (String) multipleResultFactory
0898: .getConstructorArgs().get(i);
0899: String comma = i == 0 ? "" : ", ";
0900: constructorArgs += comma + s;
0901: }
0902: }
0903: return constructorArgs;
0904: }
0905:
0906: protected String resolveType(Object instance, ArrayList imports) {
0907: String type;
0908: if (instance instanceof List) {
0909: imports.add("java.util.List");
0910: type = "List";
0911: } else if (instance instanceof Set) {
0912: imports.add("java.util.Set");
0913: type = "Set";
0914: } else if (instance instanceof Map) {
0915: imports.add("java.util.Map");
0916: type = "Map";
0917: } else {
0918: imports.add("java.util.Collection");
0919: type = "Collection";
0920: }
0921: return type;
0922: }
0923:
0924: /**
0925: * Returns true if one of the "parent link" foreign keys coincides with
0926: * one of the "child link"
0927: * primary keys
0928: *
0929: * @param parentTable
0930: * @param childTable
0931: * @return true if isReversedInsertOrder
0932: */
0933: protected boolean isReversedInsertOrder(MetaTable parentTable,
0934: MetaTable childTable) {
0935: ForeignKeys parentForeignKeys = parentTable.getForeignKeys();
0936: if (parentForeignKeys == null || parentForeignKeys.isEmpty()) {
0937: return false;
0938: }
0939:
0940: boolean tableNameFound = false;
0941: for (Iterator it = parentForeignKeys.keySet().iterator(); it
0942: .hasNext();) {
0943: String key = (String) it.next();
0944: if (key.equals(childTable.getTableName())) {
0945: tableNameFound = true;
0946: ForeignKeyEntries fkEntries = (ForeignKeyEntries) parentForeignKeys
0947: .get(key);
0948: for (int i = 0; i < fkEntries.size(); i++) {
0949: ForeignKeyEntry fkEntry = (ForeignKeyEntry) fkEntries
0950: .get(i);
0951: int[] pkIndices = childTable.toPrimaryKeyIndeces();
0952: boolean columnFound = false;
0953: for (int j = 0; j < pkIndices.length; j++) {
0954: int pkIndex = pkIndices[j];
0955: String columnName = childTable.getColumn(
0956: pkIndex).getColumnName();
0957: String foreignColumnName = fkEntry
0958: .getForeignColumn();
0959: if (foreignColumnName.equals(columnName)) {
0960: columnFound = true;
0961: break;
0962: }
0963: }
0964: if (!columnFound) {
0965: return false;
0966: }
0967: }
0968: }
0969: }
0970: return tableNameFound;
0971: }
0972:
0973: protected String typedName(String childName, boolean mixedCase,
0974: Link.RelationshipType relationshipType) {
0975: String typedName = javaName(childName, null, null, false,
0976: !mixedCase);
0977: if (relationshipType == Link.ONE_TO_MANY) {
0978: typedName = typedName.endsWith("s") ? typedName : typedName
0979: + "s";
0980: }
0981: return typedName;
0982: }
0983:
0984: protected String resolveChildInterfaceName(
0985: MetaObjectReference metaObjectReference, Referencing child,
0986: MetaObjectModel metaObjectModel, String childClassName,
0987: String objectKey, LineStruct childLineStruct) {
0988:
0989: String childInterfaceName = childClassName;
0990: if (isGenerateIntefaces()) {
0991: CompositePoGenerator.ClassStruct baseClassStruct = baseInterfaceNameByDependency(
0992: metaObjectReference, child, metaObjectModel,
0993: objectKey);
0994: childInterfaceName = baseClassStruct.getClassName();
0995: }
0996: if (childInterfaceName == null) {
0997: logger.warn("Cannot get interface name by metaRef ["
0998: + metaObjectReference.getBase()
0999: + "] - using class one");
1000: childInterfaceName = childClassName;
1001: }
1002: return childInterfaceName;
1003: }
1004:
1005: protected void processComplexClass(
1006: MetaObjectReference metaObjectReference,
1007: Map templateObjectReference,
1008: MetaObjectModel metaObjectModel, ArrayList imports,
1009: MetaTable parentTable, String parentClassName,
1010: String objectKey, LineStruct classLineStruct,
1011: LineStruct intfLineStruct) throws ClassNotFoundException,
1012: InstantiationException, IllegalAccessException {
1013: processComplex(metaObjectReference, templateObjectReference,
1014: metaObjectModel, imports, parentTable, parentClassName,
1015: true, objectKey, classLineStruct, intfLineStruct);
1016: }
1017:
1018: protected void processComplexInterface(
1019: MetaObjectReference metaObjectReference,
1020: Map templateObjectReference,
1021: MetaObjectModel metaObjectModel, ArrayList imports,
1022: MetaTable parentTable, String parentClassName,
1023: String objectKey, LineStruct lineStruct)
1024: throws ClassNotFoundException, InstantiationException,
1025: IllegalAccessException {
1026: processComplex(metaObjectReference, templateObjectReference,
1027: metaObjectModel, imports, parentTable, parentClassName,
1028: false, objectKey, lineStruct, lineStruct);
1029: }
1030:
1031: protected void processCompound(
1032: MetaObjectReference metaObjectReference,
1033: Map templateObjectReference,
1034: MetaObjectModel metaObjectModel, boolean classes,
1035: String objectKey, LineStruct classLineStruct,
1036: LineStruct intfLineStruct) {
1037:
1038: MetaCompound metaCompound = metaObjectReference.getCompound();
1039: if (metaCompound == null || metaCompound.getChildren() == null) {
1040: return;
1041: }
1042:
1043: CompoundChildHandler handler = new CompoundChildHandler(
1044: metaObjectReference, extractStruct, metaObjectModel,
1045: objectKey, classes);
1046:
1047: int childCount = 0;
1048: Set compoundChildrenKeySet = metaCompound.getChildren()
1049: .keySet();
1050: templateObjectReference.put("compoundChildrenKeySet",
1051: compoundChildrenKeySet);
1052: Map compoundChildren = metaCompound.getChildren();
1053:
1054: String extInterfaces = "";
1055: Map compoundMap = (Map) templateObjectReference
1056: .get(MetaObjectReference.TAG_COMPOUND);
1057: compoundMap.put("overRideParent", Boolean.valueOf(handler
1058: .isOverRideParent()));
1059: Map compoundChildrenMap = (Map) compoundMap
1060: .get(MetaCompound.TAG_COMPOUND_CHILDREN);
1061: for (Iterator iterator = compoundChildrenMap.keySet()
1062: .iterator(); iterator.hasNext(); childCount++) {
1063: String key = (String) iterator.next();
1064: MetaCompoundChild child = (MetaCompoundChild) compoundChildren
1065: .get(key);
1066:
1067: handler.handleChild(key, child, compoundChildrenMap,
1068: compoundChildren);
1069:
1070: MetaRef metaRef = child.getBase();
1071: Map childMap = (Map) compoundChildrenMap.get(key);
1072:
1073: String constName = javaConstName(CPD_CHILD_PREFIX, key);
1074: childMap.put("constName", constName);
1075: childMap.put("factoryConstName", javaConstName(
1076: "CPD_FACTORY_", key));
1077: childMap.put("cascadeInsert", String.valueOf(child
1078: .isCascadeInsert()));
1079: childMap.put("cascadeDelete", String.valueOf(child
1080: .isCascadeDelete()));
1081: if (childMap.get("name") == null) {
1082: throw new RuntimeException(
1083: "childMap.get(name) == null) for constName = "
1084: + constName);
1085: }
1086: //
1087: // Resolve dependency & put child type:
1088: //
1089: // ${child.type} ${child.typedName};
1090: //
1091: // For type the logic is : if there is class - use it, oterwise - resolve:
1092: //
1093: boolean containmentIs = child.getContainmentType() == MetaCompoundChild.CONTAINMENT_IS;
1094:
1095: String childClassName = handler.getBaseName();
1096: String childInterfaceName = resolveChildInterfaceName(
1097: metaObjectReference, child, metaObjectModel,
1098: childClassName, objectKey, classLineStruct);
1099: childMap.put(TAG_INTERFACE_NAME, childInterfaceName);
1100: childMap.put(TAG_CLASS_NAME, childClassName);
1101: childMap.put("getterName", "getFirstChildObject");
1102: Map baseTemplate = handler.getBaseTemplate();
1103: childMap.put("base", baseTemplate);
1104: addCompoundExtraImports(baseTemplate,
1105: templateObjectReference);
1106:
1107: if (containmentIs) {
1108: String comma = childCount > 0 ? ", " : "";
1109: extInterfaces += comma + childInterfaceName;
1110: }
1111:
1112: boolean mixedCase = isMixedCase(child.getName());
1113: String typedName = typedName(child.getName(), mixedCase,
1114: Link.ONE_TO_ONE);
1115: childMap.put("type", childInterfaceName);
1116: childMap.put("typedName", typedName);
1117: childMap.put("cpxIndex", String.valueOf(childCount));
1118: childMap.put("cpxIndexName", javaName(NameHelper
1119: .capitalizeFirstChar(key), "cpdIndex", null, false,
1120: isMainPattern(key)));
1121: childMap.put("cpxIndexValue", String.valueOf(childCount));
1122: //
1123: // Find the table to create a link:
1124: //
1125: MetaModelsExtractor.ExtractStructEntry entry = extractStructEntryByRef(
1126: metaRef, metaObjectModel, new HashSet());
1127: if (entry == null) {
1128: throw new NullPointerException(
1129: "Cannot find entry by ref : " + metaRef);
1130: }
1131: MetaTable childTable = entry.getMetaTable();
1132: if (childTable == null) {
1133: throw new IllegalArgumentException(
1134: "Cannot find child table by reference : "
1135: + metaRef);
1136: }
1137: //
1138: // Now we have both parent & child tables, we can create a link between them:
1139: //
1140: ArrayList parentIndexConsts = new ArrayList();
1141: ArrayList childIndexConsts = new ArrayList();
1142:
1143: childMap.put("parentIndexConsts", parentIndexConsts);
1144: childMap.put("childIndexConsts", childIndexConsts);
1145: }
1146: templateObjectReference.put("extInterfaces", extInterfaces);
1147: }
1148:
1149: protected void addCompoundExtraImports(Map baseTemplate,
1150: Map templateObjectReference) {
1151: if (baseTemplate != null) {
1152: List imports = getImports(templateObjectReference);
1153: List extraImports = getImports(baseTemplate);
1154: for (int i = 0; i < extraImports.size(); i++) {
1155: String entry = (String) extraImports.get(i);
1156: if (!imports.contains(entry)) {
1157: imports.add(entry);
1158: }
1159: }
1160: }
1161: }
1162:
1163: protected List getImports(Map templateObjectReference) {
1164: return (List) templateObjectReference
1165: .get(PersistentObjectGenerator.TAG_IMPORTS);
1166: }
1167:
1168: protected void processCompoundClass(
1169: MetaObjectReference metaObjectReference,
1170: Map templateObjectReference,
1171: MetaObjectModel metaObjectModel, String objectKey,
1172: LineStruct classLineStruct, LineStruct intfLineStruct) {
1173: processCompound(metaObjectReference, templateObjectReference,
1174: metaObjectModel, true, objectKey, classLineStruct,
1175: intfLineStruct);
1176: }
1177:
1178: protected void processCompoundInterface(
1179: MetaObjectReference metaObjectReference,
1180: Map templateObjectReference,
1181: MetaObjectModel metaObjectModel, String objectKey,
1182: LineStruct childLineStruct) {
1183: processCompound(metaObjectReference, templateObjectReference,
1184: metaObjectModel, false, objectKey, childLineStruct,
1185: childLineStruct);
1186: }
1187:
1188: protected void populateIndexConsts(ForeignKeys foreignKeys,
1189: MetaTable parentTable, MetaTable childTable,
1190: String parentClassName, String childClassName,
1191: ArrayList parentIndexConsts, ArrayList childIndexConsts) {
1192: ForeignKeyEntries foreignKeyList = (ForeignKeyEntries) foreignKeys
1193: .get(parentTable.getTableName());
1194: if (foreignKeyList == null) {
1195: throw new IllegalArgumentException(
1196: "Cannot populateIndexConsts with null foreignKeyList for "
1197: + " parentTable "
1198: + parentTable.getTableName()
1199: + "; childTable "
1200: + childTable.getTableName()
1201: + "; solution - create forign key in database "
1202: + "and regenerate descriptors or populate foreign key values manually in external descriptor");
1203: }
1204: for (int i = 0; i < foreignKeyList.size(); i++) {
1205: ForeignKeyEntry foreignKey = (ForeignKeyEntry) foreignKeyList
1206: .get(i);
1207: String localColumn = foreignKey.getLocalColumn();
1208: String localColumnAlias = childTable.getColumn(localColumn)
1209: .getColumnAlias();
1210: String foreignColumn = foreignKey.getForeignColumn();
1211: String foreignColumnAlias = parentTable.getColumn(
1212: foreignColumn).getColumnAlias();
1213: String childIndexConst = fullConstName(childClassName,
1214: localColumnAlias);
1215: String parentIndexConst = fullConstName(parentClassName,
1216: foreignColumnAlias);
1217: parentIndexConsts.add(parentIndexConst);
1218: childIndexConsts.add(childIndexConst);
1219: }
1220: }
1221:
1222: protected String fullConstName(String className, String columnName) {
1223: return className
1224: + "."
1225: + javaConstName(PersistentObjectGenerator.ICOL_PREFIX,
1226: columnName);
1227: }
1228:
1229: protected MetaModelsExtractor.ExtractStructEntry extractStructEntryByRef(
1230: MetaRef metaRef, MetaObjectModel metaObjectModel, Set seen) {
1231: seen.add(metaRef.getName());
1232: // Try to find MetaObjectReference by refName in metaObjectModel & use its className:
1233: MetaObjectReference refReference = metaObjectModel
1234: .getMetaObjectReference(metaRef.getName());
1235: if (refReference != null) {
1236: //
1237: // this is not a leaf - try again
1238: //
1239: if (!seen.contains(refReference.getBase().getName())) {
1240: seen.add(refReference.getBase().getName());
1241: } else {
1242: String name = refReference.getBase().getName();
1243: throw new IllegalArgumentException(
1244: "Circular dependency on : "
1245: + name
1246: + ". Tip: if you have table alias in your basic external descriptor named the same as key in the "
1247: + "composite one ("
1248: + name
1249: + ") - rename the composite key to make it unique, and use 'className' attribute to specify the desired name of the "
1250: + "generated composite class.");
1251: }
1252: metaRef = refReference.getBase();
1253: return extractStructEntryByRef(metaRef, metaObjectModel,
1254: seen);
1255: } else {
1256: //
1257: // this is a leaf:
1258: //
1259: //
1260: // We did not find the reference in metaObjectModel,
1261: // let's try to find it in metaTableAliasMap:
1262: //
1263: MetaModelsExtractor.ExtractStructEntry extractStructEntry = extractStruct
1264: .getEntry(metaRef.getName());
1265: if (extractStructEntry != null) {
1266: //
1267: // Now we have all the data to generate name of the base class:
1268: //
1269: return extractStructEntry;
1270: } else {
1271: throw new IllegalArgumentException(
1272: "Insufficient or incorrect data to build class base name for "
1273: + "metaBase " + metaRef
1274: + "; check the base name");
1275: }
1276: }
1277: }
1278:
1279: protected MetaTable metaTableByRef(MetaRef metaRef,
1280: MetaObjectModel metaObjectModel, Set seen) {
1281: MetaModelsExtractor.ExtractStructEntry entry = extractStructEntryByRef(
1282: metaRef, metaObjectModel, seen);
1283: return entry == null ? null : entry.getMetaTable();
1284: }
1285:
1286: protected ClassStruct baseClassNameByDependency(
1287: MetaObjectReference metaObjectReference, Referencing child,
1288: MetaObjectModel metaObjectModel, String objectKey) {
1289: BaseExtractHandler handler = new BaseExtractHandler(
1290: metaObjectReference, extractStruct, metaObjectModel,
1291: objectKey, true);
1292: String baseName = handler.extractBase(child);
1293: return new ClassStruct(baseName, handler.isRoot());
1294: }
1295:
1296: protected ClassStruct baseInterfaceNameByDependency(
1297: MetaObjectReference metaObjectReference, Referencing child,
1298: MetaObjectModel metaObjectModel, String objectKey) {
1299: BaseExtractHandler handler = new BaseExtractHandler(
1300: metaObjectReference, extractStruct, metaObjectModel,
1301: objectKey, false);
1302: String baseName = handler.extractBase(child);
1303: return new ClassStruct(baseName, handler.isRoot());
1304: }
1305:
1306: protected static boolean isMainPattern(MetaTable metaTable) {
1307: return NameHelper.isMainPattern(metaTable.getTableAlias());
1308: }
1309:
1310: protected boolean isMainPattern(String name) {
1311: return NameHelper.isMainPattern(name);
1312: }
1313:
1314: protected void populatePks(MetaTable table, Map templateModel) {
1315: if (table.getPrimaryKey() != null) {
1316: ArrayList pkVars = new ArrayList(table.getPrimaryKey()
1317: .size());
1318: String pkArgs = "";
1319: pkArgs = populatePks(table, pkVars, pkArgs);
1320: String pkVarArgs = "";
1321: for (int i = 0; i < pkVars.size(); i++) {
1322: String comma = i == 0 ? "" : ", ";
1323: HashMap hashMap = (HashMap) pkVars.get(i);
1324: pkVarArgs += comma + hashMap.get("varName");
1325: }
1326: templateModel.put("pkVars", pkVars);
1327: templateModel.put("pkArgs", pkArgs);
1328: templateModel.put("pkVarArgs", pkVarArgs);
1329: }
1330: }
1331:
1332: protected String populatePks(MetaTable table, ArrayList pkVars,
1333: String pkArgs) {
1334: for (int i = 0; i < table.getPrimaryKey().size(); i++) {
1335: String comma = i == 0 ? "" : ", ";
1336: int pkIndex = ((Integer) table.getPrimaryKey().get(i))
1337: .intValue();
1338: String varName = javaName(table.getColumn(pkIndex)
1339: .getColumnAlias(), null, null, false);
1340:
1341: String varType = javaType(table.getColumn(pkIndex)
1342: .getType());
1343: HashMap pkVar = new HashMap();
1344: pkVar.put("varName", varName);
1345: pkVar.put("varType", varType);
1346: pkVars.add(pkVar);
1347: pkArgs += comma + varType + " " + varName;
1348:
1349: }
1350: return pkArgs;
1351: }
1352:
1353: protected void addToImports(String extraImports, ArrayList imports) {
1354: if (!StringUtil.isEmpty(extraImports)) {
1355: String[] genImports = extraImports.split(",");
1356: for (int i = 0; i < genImports.length; i++) {
1357: String toImport = genImports[i].trim();
1358: if (!imports.contains(toImport)) {
1359: imports.add(toImport);
1360: }
1361: }
1362: }
1363: }
1364:
1365: protected Template getTemplate(String templatePath,
1366: String defaultTemplateFileName) throws IOException {
1367: return TemplateHelper.getTemplate(templatePath,
1368: defaultTemplateFileName, this .getClass(), debug);
1369: }
1370:
1371: public String javaType(ColumnType type) {
1372: return metaModelsExtractor.javaType(type);
1373: }
1374:
1375: public static String javaName(String name, String prefix,
1376: String suffix, boolean calitalizeFirstChar) {
1377: String endName = NameHelper.javaName(name, prefix, suffix,
1378: calitalizeFirstChar, true);
1379: return endName;
1380: }
1381:
1382: public static String getOrIs(MetaColumn column) {
1383: return ColumnType.isBoolean(column.getType()) ? "is" : "get";
1384: }
1385:
1386: public static String javaName(String name, String prefix,
1387: String suffix, boolean calitalizeFirstChar,
1388: boolean mainPattern) {
1389: String endName = NameHelper.javaName(name, prefix, suffix,
1390: calitalizeFirstChar, mainPattern);
1391: return endName;
1392: }
1393:
1394: public static String lowerFirstChar(String name) {
1395: // return NameHelper.lowerFirstChar(name);
1396: return NameHelper.decapitalizeField(name);
1397: }
1398:
1399: public static String javaConstName(String prefix, String name) {
1400: return NameHelper.javaConstName(prefix, name);
1401: }
1402:
1403: static boolean isMixedCase(String name) {
1404: return NameHelper.isMixedCase(name);
1405: }
1406:
1407: protected static void println(String s) {
1408: System.out.println(s);
1409: }
1410:
1411: protected static void printGeneratedClassFileInfo(
1412: String classFileName) {
1413: printGeneratedClassFileInfo(classFileName, null);
1414: }
1415:
1416: protected static void printGeneratedClassFileInfo(
1417: String classFileName, String outputDir) {
1418: if (outputDir != null) {
1419: println("GENERATED CLASS FILE " + classFileName + " IN "
1420: + outputDir);
1421: } else {
1422: println(" " + classFileName);
1423: }
1424: }
1425:
1426: protected static void printGeneratedIn(String outputDir) {
1427: println("GENERATED IN " + outputDir + " directory:");
1428: }
1429:
1430: //
1431: //
1432: // Util classes
1433: //
1434: //
1435: protected static class LineStruct implements Cloneable {
1436: String parentClass;
1437: String poConfigPath;
1438: String cmpDescPath;
1439: String outputPath;
1440: String packageName;
1441: String filterPattern;
1442: String interfaces;
1443: boolean generateToString;
1444: boolean generateInterfaces;
1445: boolean generateBean = true;
1446: boolean generateMapper = true;
1447: String genericImports;
1448: String specificImports;
1449: String classPrefix;
1450: String classSuffix;
1451:
1452: LineStruct relatedLineStruct;
1453: boolean debug;
1454:
1455: public Object clone() throws CloneNotSupportedException {
1456: return super .clone();
1457: }
1458: }
1459:
1460: static class LineStructBlock implements Cloneable {
1461: LineStruct classStruct;
1462: LineStruct intfStruct;
1463:
1464: public LineStructBlock(LineStruct classStruct,
1465: LineStruct intfStruct) {
1466: this .classStruct = classStruct;
1467: this .intfStruct = intfStruct;
1468: }
1469:
1470: public Object clone() throws CloneNotSupportedException {
1471: LineStructBlock block = (LineStructBlock) super .clone();
1472: block.classStruct = (LineStruct) classStruct.clone();
1473: block.intfStruct = (LineStruct) intfStruct.clone();
1474: return block;
1475: }
1476: }
1477:
1478: public Log getLogger() {
1479: return logger;
1480: }
1481:
1482: public void setLogger(Log logger) {
1483: this .logger = logger;
1484: }
1485:
1486: /**
1487: * @param args
1488: * @throws Exception
1489: */
1490: public static void main(String[] args) throws Exception {
1491: if (args.length < 1) {
1492: println("Usage: [composite-po-generator] <composite-po-config.sdl> <env.properties>\n"
1493: + " where <composite-po-config.sdl> - required configuration file path;\n"
1494: + " <env.properties> - optional token resolution file path.");
1495: System.exit(1);
1496: }
1497: println("STARTED GENERATION ...");
1498:
1499: CompositePoGenerator generator = new CompositePoGenerator();
1500:
1501: String arg = args[0];
1502: String envPath = args.length > 1 ? args[1] : null;
1503: generator.process(arg, envPath);
1504:
1505: println("FINISHED GENERATION");
1506: }
1507:
1508: protected class ClassStruct {
1509: String className;
1510: boolean root;
1511:
1512: public ClassStruct(String className, boolean root) {
1513: this .className = className;
1514: this .root = root;
1515: }
1516:
1517: public String getClassName() {
1518: return className;
1519: }
1520:
1521: public void setClassName(String className) {
1522: this .className = className;
1523: }
1524:
1525: public boolean isRoot() {
1526: return root;
1527: }
1528:
1529: public void setRoot(boolean root) {
1530: this.root = root;
1531: }
1532: }
1533:
1534: }
|