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.adapter.StdOutputLogAdapter;
013: import com.completex.objective.components.log.impl.PrimitiveLogImpl;
014: import com.completex.objective.components.persistency.JavaToMetaTypeImpl;
015: import com.completex.objective.components.persistency.MetaColumn;
016: import com.completex.objective.components.persistency.connect.ConnectionManager;
017: import com.completex.objective.components.persistency.connect.impl.ConnectionManagerImpl;
018: import com.completex.objective.components.persistency.meta.MetaModel;
019: import com.completex.objective.components.persistency.meta.ModelLoader;
020: import com.completex.objective.components.persistency.meta.ModelLoaderPlugin;
021: import com.completex.objective.components.persistency.meta.ModelStorerPlugin;
022: import com.completex.objective.components.persistency.meta.adapter.ModelLoaderAdapter;
023: import com.completex.objective.components.persistency.meta.adapter.ModelStorerAdapter;
024: import com.completex.objective.components.persistency.meta.impl.UdtBaseModelLoaderPlugin;
025: import com.completex.objective.components.sdl.reader.SdlReader;
026: import com.completex.objective.components.sdl.reader.impl.SdlReaderImpl;
027: import com.completex.objective.util.PropertyMap;
028:
029: import java.io.*;
030: import java.sql.Connection;
031: import java.sql.SQLException;
032: import java.util.*;
033:
034: /**
035: * Under construction
036: *
037: * @author Gennady Krizhevsky
038: */
039: public class ComplexPoDescriptorGenerator {
040:
041: private static SdlReader sdlReader = new SdlReaderImpl();
042: private static final Log logger = StdOutputLogAdapter
043: .newLogInstance();
044: private Connection connection;
045: private ConnectionManager connections;
046: private ModelLoaderAdapter modelLoaderAdapter;
047: private ModelStorerAdapter modelStorerAdapter;
048: private ModelTransformer[] transformers;
049: private UserDefinedTypeModelTransformer[] udtTransformers;
050:
051: protected MetaColumn.GeneratorStruct creationDateStruct;
052: protected MetaColumn.GeneratorStruct lastUpdatedStruct;
053: protected static final String INTERNAL_DESC_FILE = "cpx_internal_desc_file"; // Internal descriptor file path
054: protected static final String EXTERNAL_DESC_FILE = "cpx_external_desc_file"; // External descriptor file path
055: protected static final String OUT_DIR = "out_dir"; // Top level directory for generated classes
056: protected static final String USER = "user";
057: protected static final String URL = "url";
058: protected static final String PASSWORD = "password";
059: protected static final String DRIVER = "driver";
060: protected static final String SCHEMA = "schema";
061: protected static final String CATALOG = "catalog";
062: protected static final String FILTER_PATTERN = "filter_pattern";
063: protected static final String REQUIRED_PASSWORD = "required_password";
064: protected static final String USE_PRIMITIVES = "use_primitives";
065: protected static final String USE_PRIMITIVES_FOR_NOT_NULL_NUMBERS = "use_primitives_for_required";
066: protected static final String CHAR1_BOOLEAN = "char1boolean";
067: protected static final String LAST_UPDATED_NAMES = "last_updated_names";
068: protected static final String CREATION_DATE_NAMES = "creation_date_names";
069: protected static final String FORCE_INTERNAL_FROM_FILE = "force_internal_from_file";
070: protected static final String PLUGINS_CONFIG_PATH = "plugins_config_path";
071: public static final String DEBUG = "debug";
072: private boolean debug;
073:
074: public ComplexPoDescriptorGenerator() {
075: }
076:
077: public ComplexPoDescriptorGenerator(String propertiesPath)
078: throws IOException, IllegalAccessException,
079: ClassNotFoundException, InstantiationException {
080: setup(propertiesPath);
081: }
082:
083: public void dispose() {
084: try {
085: connection.close();
086: } catch (SQLException e) {
087: // Do nothing
088: }
089: }
090:
091: public ComplexPoDescriptorGenerator(InputStream inputStream)
092: throws IOException, IllegalAccessException,
093: InstantiationException, ClassNotFoundException {
094: setup(inputStream);
095: }
096:
097: public void setup(String propertiesPath) throws IOException,
098: IllegalAccessException, InstantiationException,
099: ClassNotFoundException {
100: if (propertiesPath == null) {
101: throw new IllegalArgumentException("propertiesPath is null");
102: }
103: InputStream inputStream = new FileInputStream(propertiesPath);
104: setup(inputStream);
105: }
106:
107: public void setup(final InputStream inputStream)
108: throws IOException, ClassNotFoundException,
109: IllegalAccessException, InstantiationException {
110: PropertyMap propertyMap = new PropertyMap();
111: propertyMap.load(inputStream);
112: setup(propertyMap);
113: }
114:
115: protected void setup(PropertyMap propertyMap) throws IOException,
116: ClassNotFoundException, InstantiationException,
117: IllegalAccessException {
118: modifyProperties(propertyMap);
119: String user = propertyMap.getProperty(USER, true);
120: boolean requiredPassword = propertyMap
121: .getBoolean(REQUIRED_PASSWORD);
122: final String driver = propertyMap.getProperty(DRIVER, true);
123: String url = propertyMap.getProperty(URL, true);
124: final String password = propertyMap.getProperty(PASSWORD,
125: requiredPassword);
126: final String creationDateNames = propertyMap
127: .getProperty(CREATION_DATE_NAMES);
128: final String lastUpdatedNames = propertyMap
129: .getProperty(LAST_UPDATED_NAMES);
130: creationDateStruct = toGeneratorStruct(creationDateNames);
131: lastUpdatedStruct = toGeneratorStruct(lastUpdatedNames);
132: debug = propertyMap.getBoolean(DEBUG);
133: if (logger instanceof PrimitiveLogImpl) {
134: ((PrimitiveLogImpl) logger).setDebugEnabled(debug);
135: }
136:
137: connections = new ConnectionManagerImpl(driver, url, user,
138: password);
139: connection = connections.createConnection();
140:
141: String outDir = propertyMap.getProperty(OUT_DIR, true);
142: String internalFileName = propertyMap.getProperty(
143: INTERNAL_DESC_FILE, true);
144: String externalFileName = propertyMap.getProperty(
145: EXTERNAL_DESC_FILE, true);
146: String schema = propertyMap.getProperty(SCHEMA);
147: String catalog = propertyMap.getProperty(CATALOG);
148: String filterPattern = propertyMap.getProperty(FILTER_PATTERN);
149: boolean usePrimitives = propertyMap.getBoolean(USE_PRIMITIVES);
150: boolean usePrimitivesForNotNulNumbers = propertyMap
151: .getBoolean(USE_PRIMITIVES_FOR_NOT_NULL_NUMBERS);
152: boolean char1boolean = propertyMap.getBoolean(CHAR1_BOOLEAN,
153: Boolean.FALSE, true);
154: boolean forceInternalFromFile = propertyMap
155: .getBoolean(FORCE_INTERNAL_FROM_FILE);
156:
157: File externalFile = new File(outDir + "/" + externalFileName);
158: ModelLoaderAdapter.ExternalFileModelLoaderAdapter externalFileModelLoader = null;
159: if (externalFile.exists()) {
160: Reader externalFileReader = new BufferedReader(
161: new FileReader(externalFile));
162: externalFileModelLoader = new ModelLoaderAdapter.ExternalFileModelLoaderAdapter(
163: externalFileReader, filterPattern);
164: }
165:
166: ModelLoaderAdapter.DatabaseModelLoaderAdapter databaseModelLoaderAdapter = new ModelLoaderAdapter.DatabaseModelLoaderAdapter(
167: schema, catalog, filterPattern, connection, logger);
168:
169: ModelLoaderAdapter.InternalFileModelLoaderAdapter internalFileModelLoader = null;
170: File internalFile = new File(outDir + "/" + internalFileName);
171: if (forceInternalFromFile) {
172: if (internalFile.exists()) {
173: Reader internalFileReader = new BufferedReader(
174: new FileReader(internalFile));
175: internalFileModelLoader = new ModelLoaderAdapter.InternalFileModelLoaderAdapter(
176: internalFileReader, filterPattern);
177: } else {
178: throw new FileNotFoundException("File not found : "
179: + internalFile.getAbsolutePath());
180: }
181: }
182:
183: JavaToMetaTypeImpl javaToMetaType = new JavaToMetaTypeImpl(
184: usePrimitives, usePrimitivesForNotNulNumbers,
185: char1boolean);
186: ModelLoader internalLoader = databaseModelLoaderAdapter;
187: if (internalFileModelLoader != null) {
188: internalLoader = internalFileModelLoader;
189: }
190: modelLoaderAdapter = new ModelLoaderAdapter(internalLoader,
191: externalFileModelLoader, javaToMetaType,
192: creationDateStruct, lastUpdatedStruct, logger);
193:
194: modelStorerAdapter = new ModelStorerAdapter(outDir,
195: internalFileName, externalFileName);
196: //
197: // Plugins setup:
198: //
199: Map pluginsConfig = setupPlugins(propertyMap);
200: //
201: //
202: //
203: setupTransformers(pluginsConfig);
204: //
205: // Transformers setup:
206: //
207: setupUdtTransformers(pluginsConfig);
208:
209: System.out.println("GENERATED FILES IN " + outDir);
210: }
211:
212: private void setupTransformers(Map map)
213: throws ClassNotFoundException, IllegalAccessException,
214: InstantiationException {
215: ModelTransformer[] transformers = null;
216: PropertyMap configPropertyMap = PropertyMap.toPropertyMap(map);
217: if (configPropertyMap != null) {
218: PropertyMap config = configPropertyMap
219: .getPropertyMap(ModelTransformer.KEY);
220: if (config != null) {
221: List transformerMaps = config.getList("transformers");
222: if (transformerMaps != null
223: && transformerMaps.size() > 0) {
224: transformers = new ModelTransformer[transformerMaps
225: .size()];
226: for (int i = 0; i < transformerMaps.size(); i++) {
227: PropertyMap transformerConfig = PropertyMap
228: .toPropertyMap(((Map) transformerMaps
229: .get(i)));
230: String className = transformerConfig
231: .getProperty("class", true);
232: Class clazz = Class.forName(className);
233: transformers[i] = (ModelTransformer) clazz
234: .newInstance();
235: transformers[i].configure(transformerConfig
236: .getPropertyMap("config"));
237: }
238: }
239: }
240: }
241: this .transformers = transformers;
242: }
243:
244: private void setupUdtTransformers(Map udtMap)
245: throws ClassNotFoundException, IllegalAccessException,
246: InstantiationException {
247: UserDefinedTypeModelTransformer[] transformers = null;
248: PropertyMap configPropertyMap = PropertyMap
249: .toPropertyMap(udtMap);
250: if (configPropertyMap != null) {
251: PropertyMap config = configPropertyMap
252: .getPropertyMap(UdtBaseModelLoaderPlugin.PLUGIN_KEY);
253: if (config != null) {
254: List transformerMaps = config.getList("transformers");
255: if (transformerMaps != null
256: && transformerMaps.size() > 0) {
257: transformers = new UserDefinedTypeModelTransformer[transformerMaps
258: .size()];
259: for (int i = 0; i < transformerMaps.size(); i++) {
260: PropertyMap transformerConfig = PropertyMap
261: .toPropertyMap(((Map) transformerMaps
262: .get(i)));
263: String className = transformerConfig
264: .getProperty("class", true);
265: Class clazz = Class.forName(className);
266: transformers[i] = (UserDefinedTypeModelTransformer) clazz
267: .newInstance();
268: transformers[i].configure(transformerConfig
269: .getPropertyMap("config"));
270: }
271: }
272: }
273: }
274: udtTransformers = transformers;
275: }
276:
277: private Map setupPlugins(PropertyMap propertyMap)
278: throws IOException, ClassNotFoundException,
279: InstantiationException, IllegalAccessException {
280: Map map = null;
281: String pluginsConfigPath = propertyMap
282: .getProperty(PLUGINS_CONFIG_PATH);
283: if (pluginsConfigPath != null) {
284: map = (Map) sdlReader
285: .read(new FileReader(pluginsConfigPath));
286: setupPlugins0(map);
287: }
288: return map;
289: }
290:
291: private void setupPlugins0(Map map) throws ClassNotFoundException,
292: InstantiationException, IllegalAccessException, IOException {
293: PropertyMap configPropertyMap = PropertyMap.toPropertyMap(map);
294: //
295: // Register plugins:
296: //
297: for (Iterator it = configPropertyMap.keySet().iterator(); it
298: .hasNext();) {
299: String key = (String) it.next();
300: PropertyMap config = configPropertyMap.getPropertyMap(key,
301: true);
302: //
303: // Loader:
304: //
305: PropertyMap loaderConfig = config.getPropertyMap("loader");
306: if (loaderConfig != null) {
307: String classString = loaderConfig.getProperty("class",
308: true);
309: Class loaderClass = Class.forName(classString);
310: ModelLoaderPlugin loaderPlugin = (ModelLoaderPlugin) loaderClass
311: .newInstance();
312: modelLoaderAdapter.registerPlugin(loaderPlugin);
313: PropertyMap pluginConfig = loaderConfig
314: .getPropertyMap("config");
315: loaderPlugin.configure(pluginConfig);
316: if (loaderPlugin.needsConnection()) {
317: loaderPlugin.setConnection(connection);
318: }
319: }
320: //
321: // Storer:
322: //
323: PropertyMap storerConfig = config.getPropertyMap("storer");
324: if (storerConfig != null) {
325: String classString = storerConfig.getProperty("class",
326: true);
327: Class storerClass = Class.forName(classString);
328: ModelStorerPlugin storerPlugin = (ModelStorerPlugin) storerClass
329: .newInstance();
330: modelStorerAdapter.registerPlugin(storerPlugin);
331: PropertyMap pluginConfig = storerConfig
332: .getPropertyMap("config");
333: storerPlugin.configure(pluginConfig);
334: }
335: }
336: }
337:
338: private MetaColumn.GeneratorStruct toGeneratorStruct(
339: final String dateNames) {
340: MetaColumn.GeneratorStruct datesStruct = null;
341: if (dateNames != null && dateNames.trim().length() > 0) {
342: String[] names = dateNames.trim().split(",");
343: LinkedHashSet set = new LinkedHashSet(Arrays.asList(names));
344: datesStruct = new MetaColumn.GeneratorStruct(set);
345: }
346: return datesStruct;
347: }
348:
349: public void modifyProperties(Properties properties) {
350: }
351:
352: public Connection getConnection() {
353: boolean closed = true;
354: try {
355: if (!connection.isClosed()) {
356: closed = false;
357: }
358: } catch (SQLException e) {
359: // Do nothing
360: }
361: return closed ? connections.createConnection() : connection;
362: }
363:
364: public MetaModel loadModel() throws Exception {
365: logger.info("Load Model started");
366: MetaModel model = null;
367: try {
368: model = modelLoaderAdapter.load(null);
369: } finally {
370: logger.info("Load Model ended, model size = "
371: + (model == null ? "0" : model.size() + ""));
372: }
373: return model;
374: }
375:
376: public void storeModel(MetaModel model) throws Exception {
377: logger.info("Store Model started");
378: try {
379: modelStorerAdapter.store(model);
380: } finally {
381: logger.info("Store Model ended");
382: }
383: }
384:
385: public MetaModel generate() throws Exception {
386: MetaModel model = loadModel();
387: transformModel(model);
388: // logger.info(model);
389: storeModel(model);
390: return model;
391: }
392:
393: private void transformModel(MetaModel model) {
394: getLogger().info("Transform model started");
395: try {
396: if (transformers != null) {
397: for (int i = 0; i < transformers.length; i++) {
398: transformers[i].transformModel(model);
399: }
400: }
401:
402: if (udtTransformers != null) {
403: for (int i = 0; i < udtTransformers.length; i++) {
404: udtTransformers[i].transformModel(model
405: .getUserDefinedTypeMetaModel());
406: }
407: }
408: } finally {
409: getLogger().info("Transform model ended");
410: }
411:
412: }
413:
414: public static Log getLogger() {
415: return logger;
416: }
417:
418: public static void main(String[] args) throws Exception {
419: if (args.length < 1) {
420: System.out
421: .println("ERROR: PersistentDescriptorGenerator has to have one command line parameter - <descritor.properties> ");
422: System.exit(1);
423: }
424: ComplexPoDescriptorGenerator generator = new ComplexPoDescriptorGenerator(
425: args[0]);
426: generator.generate();
427: generator.dispose();
428: }
429: }
|