001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.etl.project.anttasks;
042:
043: import java.io.ByteArrayOutputStream;
044: import java.io.File;
045: import java.io.FileOutputStream;
046: import java.io.BufferedReader;
047: import java.io.FileReader;
048: import java.util.HashMap;
049: import java.util.Iterator;
050: import java.util.List;
051: import java.util.Map;
052: import javax.xml.parsers.DocumentBuilderFactory;
053: import javax.xml.transform.OutputKeys;
054: import javax.xml.transform.Transformer;
055: import javax.xml.transform.TransformerFactory;
056: import javax.xml.transform.dom.DOMSource;
057: import javax.xml.transform.stream.StreamResult;
058: import org.w3c.dom.Element;
059: import org.w3c.dom.Node;
060: import org.netbeans.modules.etl.codegen.DBConnectionDefinitionTemplate;
061: import org.netbeans.modules.etl.codegen.ETLCodegenUtil;
062: import org.netbeans.modules.etl.codegen.ETLProcessFlowGenerator;
063: import org.netbeans.modules.etl.codegen.ETLProcessFlowGeneratorFactory;
064: import org.netbeans.modules.etl.codegen.impl.InternalDBMetadata;
065: import com.sun.etl.engine.ETLEngine;
066: import org.netbeans.modules.etl.model.impl.ETLDefinitionImpl;
067: import org.netbeans.modules.etl.utils.ETLDeploymentConstants;
068: import org.netbeans.modules.sql.framework.common.jdbc.SQLDBConnectionDefinition;
069: import org.netbeans.modules.sql.framework.model.SQLDBModel;
070: import org.netbeans.modules.sql.framework.model.SQLDefinition;
071: import org.netbeans.modules.sql.framework.model.impl.SQLDefinitionImpl;
072: import org.netbeans.modules.sql.framework.model.SQLDBTable;
073: import com.sun.sql.framework.utils.StringUtil;
074: import com.sun.sql.framework.utils.XmlUtil;
075: import com.sun.sql.framework.exception.BaseException;
076:
077: /**
078: *
079: */
080: public class EngineFileGenerator {
081:
082: private FileOutputStream fos = null;
083: /*
084: * hold a map of db oids to connection def
085: */
086: private HashMap connDefs = new HashMap();
087: /*
088: * Holds a map of unique IDs (DB OID + port type [either "-Source" or
089: * "-Target"]) to InternalDBMetadata instances which hold CME-level
090: * parameters such as directory location of flatfiles and whether dynamic
091: * file name resolution is in effect.
092: */
093: private Map internalDBConfigParams = new HashMap();
094: /*
095: * Holds a map of DB OIDs to corresponding connection pool names.
096: *
097: */
098: private Map dbNamePoolNameMap = new HashMap();
099: private DBConnectionDefinitionTemplate connectionDefnTemplate;
100: private String collabName;
101: Map dbCatalogOverrideMapMap = new HashMap();
102: Map dbSchemaOverrideMapMap = new HashMap();
103:
104: public EngineFileGenerator() {
105: try {
106: this .connectionDefnTemplate = new DBConnectionDefinitionTemplate();
107: } catch (Exception e) {
108: e.printStackTrace();
109: }
110: }
111:
112: public void generateEngine(File etlFile, File buildDir)
113: throws Exception {
114:
115: String etlFileName = etlFile.getName().substring(0,
116: etlFile.getName().indexOf(".etl"));
117: String engineFile = buildDir + "/" + etlFileName
118: + "_engine.xml";
119:
120: DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
121: Element root = f.newDocumentBuilder().parse(etlFile)
122: .getDocumentElement();
123:
124: ETLDefinitionImpl def = new ETLDefinitionImpl();
125: def.parseXML(root);
126: collabName = def.getDisplayName();
127:
128: SQLDefinition sqlDefinition = def.getSQLDefinition();
129: SQLDefinition defn = checkForDeploymentProperties(etlFile,
130: etlFileName);
131: if (defn != null) {
132: System.out
133: .print("Synchronizing the configuration with Design time.");
134: defn = compareAndSync(sqlDefinition, defn, true);
135: sqlDefinition = compareAndSync(sqlDefinition, defn, false);
136: System.out
137: .println("Synchronization completed successfully");
138: }
139: populateConnectionDefinitions(sqlDefinition);
140: sqlDefinition
141: .overrideCatalogNamesForDb(dbCatalogOverrideMapMap);
142: sqlDefinition.overrideSchemaNamesForDb(dbSchemaOverrideMapMap);
143: ETLProcessFlowGenerator flowGen = ETLProcessFlowGeneratorFactory
144: .getCollabFlowGenerator(sqlDefinition, true);
145: flowGen.setWorkingFolder(sqlDefinition.getDBWorkingFolder());
146: flowGen.setInstanceDBName(sqlDefinition.getDbInstanceName());
147: flowGen.setInstanceDBFolder(ETLCodegenUtil
148: .getEngineInstanceWorkingFolder(sqlDefinition
149: .getDBWorkingFolder(), sqlDefinition
150: .getDbInstanceName()));
151: //flowGen.setInstanceDBFolder(ETLCodegenUtil.getEngineInstanceWorkingFolder());
152: flowGen.setMonitorDBName(def.getDisplayName());
153: flowGen.setMonitorDBFolder(ETLCodegenUtil.getMonitorDBDir(def
154: .getDisplayName(),
155: ETLDeploymentConstants.PARAM_APP_DATAROOT));
156:
157: if (connDefs.isEmpty()) {
158: // TODO change the logic to read connDefs from env, now keep it same
159: // a design time
160: flowGen.applyConnectionDefinitions(false);
161: } else {
162: flowGen.applyConnectionDefinitions(connDefs,
163: this .dbNamePoolNameMap, internalDBConfigParams);
164: }
165: ETLEngine engine = flowGen.getScript();
166:
167: sqlDefinition.clearOverride(true, true);
168:
169: String engineContent = engine.toXMLString();
170:
171: fos = new FileOutputStream(engineFile);
172: FileUtil.copy(engineContent.getBytes("UTF-8"), fos);
173: fos.flush();
174: fos.close();
175: }
176:
177: private SQLDefinition checkForDeploymentProperties(File etlFile,
178: String etlFileName) {
179: SQLDefinition sqlDefn = null;
180: String confPath = etlFile.getAbsolutePath()
181: + "\\..\\..\\nbproject\\config\\";
182: confPath = confPath + etlFileName + ".conf";
183: System.out.println("Checking for configuration file for "
184: + etlFileName + ".etl");
185: File confFile = new File(confPath);
186: if (confFile.exists()) {
187: System.out.println("Found configuration file for "
188: + etlFileName + ".etl");
189: sqlDefn = getConfigData(confFile);
190: System.out
191: .println("Parsing the content of the configuration file for "
192: + etlFileName + ".etl");
193: } else {
194: System.out
195: .println("Configuration file not found. Using Design time configurations.");
196: }
197: return sqlDefn;
198: }
199:
200: public SQLDefinition compareAndSync(SQLDefinition srcDefn,
201: SQLDefinition tgtDefn, boolean isSource) {
202: // sync the Models.
203: Iterator it = null;
204: if (isSource) {
205: it = srcDefn.getSourceDatabaseModels().iterator();
206: } else {
207: it = srcDefn.getTargetDatabaseModels().iterator();
208: }
209: while (it.hasNext()) {
210: boolean exists = false;
211: SQLDBModel match = null;
212: SQLDBModel srcModel = (SQLDBModel) it.next();
213: Iterator confIterator = null;
214: if (isSource) {
215: confIterator = tgtDefn.getSourceDatabaseModels()
216: .iterator();
217: } else {
218: confIterator = tgtDefn.getTargetDatabaseModels()
219: .iterator();
220: }
221: while (confIterator.hasNext()) {
222: SQLDBModel tgtModel = (SQLDBModel) confIterator.next();
223: if (tgtModel.getModelName().equals(
224: srcModel.getModelName())) {
225: exists = true;
226: match = tgtModel;
227: break;
228: }
229: }
230: if (exists) {
231: try {
232: tgtDefn.removeObject(match);
233: match = syncTables(srcModel, match);
234: tgtDefn.addObject(match);
235: } catch (BaseException ex) {
236: // ignore
237: }
238: } else {
239: try {
240: tgtDefn.addObject(srcModel);
241: } catch (BaseException ex) {
242: // ignore
243: }
244: }
245: }
246: return tgtDefn;
247: }
248:
249: private SQLDBModel syncTables(SQLDBModel srcModel,
250: SQLDBModel tgtModel) {
251: Iterator it = srcModel.getTables().iterator();
252: while (it.hasNext()) {
253: boolean exists = false;
254: SQLDBTable srcTbl = (SQLDBTable) it.next();
255: Iterator confIterator = tgtModel.getTables().iterator();
256: while (confIterator.hasNext()) {
257: SQLDBTable tgtTbl = (SQLDBTable) confIterator.next();
258: if (tgtTbl.getName().equals(srcTbl.getName())) {
259: exists = true;
260: break;
261: }
262: }
263: if (!exists) {
264: tgtModel.addTable(srcTbl);
265: }
266: }
267: return tgtModel;
268: }
269:
270: public SQLDefinition getConfigData(File configFile) {
271: org.w3c.dom.Node rootNode = null;
272: SQLDefinition sqlDefn = null;
273: try {
274: Element element = XmlUtil.loadXMLFile(new BufferedReader(
275: new FileReader(configFile)));
276: rootNode = (org.w3c.dom.Node) element;
277: } catch (Exception ex) {
278: //ignore
279: }
280: if (rootNode != null) {
281: org.w3c.dom.Node sqlNode = rootNode.getFirstChild();
282: try {
283: sqlDefn = new SQLDefinitionImpl((Element) sqlNode);
284: } catch (Exception ex) {
285: sqlDefn = null;
286: }
287: }
288: return sqlDefn;
289: }
290:
291: private void populateConnectionDefinitions(SQLDefinition def) {
292: List srcDbmodels = def.getSourceDatabaseModels();
293: Iterator iterator = srcDbmodels.iterator();
294: while (iterator.hasNext()) {
295: initMetaData(iterator, "source");
296: }
297:
298: List trgDbmodels = def.getTargetDatabaseModels();
299: iterator = trgDbmodels.iterator();
300: while (iterator.hasNext()) {
301: initMetaData(iterator, "target");
302: }
303:
304: //System.out.println(connDefs);
305: //System.out.println(dbNamePoolNameMap);
306: //System.out.println(internalDBConfigParams);
307: connDefs.size();
308: dbNamePoolNameMap.size();
309: }
310:
311: /**
312: * @param iterator
313: * @param string
314: */
315: @SuppressWarnings(value="unchecked")
316: private void initMetaData(Iterator iterator, String dbtable) {
317:
318: SQLDBModel element = (SQLDBModel) iterator.next();
319: String oid = getSQDBModelOid(element);
320: if (oid == null) {
321: // support older version of DBModel
322: return;
323: }
324: SQLDBConnectionDefinition originalConndef = (SQLDBConnectionDefinition) element
325: .getConnectionDefinition();
326:
327: if (originalConndef.getDriverClass().equals(
328: "org.axiondb.jdbc.AxionDriver")) {
329: SQLDBConnectionDefinition conndefTemplate = this .connectionDefnTemplate
330: .getDBConnectionDefinition("STCDBADAPTER");
331: SQLDBConnectionDefinition conndef = (SQLDBConnectionDefinition) conndefTemplate
332: .cloneObject();
333:
334: setConnectionParams(conndef);
335:
336: String key = originalConndef.getName() + "-" + dbtable;
337: conndef.setName(key);
338: connDefs.put(key, conndef);
339: dbNamePoolNameMap.put(oid, key);
340: // TODO all the parameters for InternalDBMetadata comes from collab
341: InternalDBMetadata dbMetadata = new InternalDBMetadata(
342: "c:\\temp", false, key);
343: internalDBConfigParams.put(oid, dbMetadata);
344: } else {
345: // jdbc connection
346: SQLDBConnectionDefinition conndef = originalConndef;
347: String key = originalConndef.getName() + "-" + dbtable;
348: conndef.setName(key);
349: connDefs.put(key, conndef);
350: dbNamePoolNameMap.put(oid, key);
351: // TODO all the parameters for InternalDBMetadata comes from collab
352: //InternalDBMetadata dbMetadata = new InternalDBMetadata("c:\\temp", false, key);
353: //internalDBConfigParams.put(oid, dbMetadata);
354: }
355: }
356:
357: /**
358: * @param conndef
359: */
360: @SuppressWarnings(value="unchecked")
361: private void setConnectionParams(SQLDBConnectionDefinition conndef) {
362: String metadataDir = ETLCodegenUtil
363: .getEngineInstanceWorkingFolder();
364: Map connectionParams = new HashMap();
365: connectionParams.put(
366: DBConnectionDefinitionTemplate.KEY_DATABASE_NAME,
367: collabName);
368: connectionParams.put(
369: DBConnectionDefinitionTemplate.KEY_METADATA_DIR,
370: metadataDir);
371:
372: conndef.setConnectionURL(StringUtil.replace(conndef
373: .getConnectionURL(), connectionParams));
374: }
375:
376: /**
377: * @param element
378: * @return
379: */
380: private String getSQDBModelOid(SQLDBModel element) {
381: if (element.getAttribute("refKey") == null) {
382: return null;
383: }
384: String oid = (String) element.getAttribute("refKey")
385: .getAttributeValue();
386: return oid;
387: }
388:
389: public static void main(String[] args) {
390: String etlFile = args[0];
391:
392: File f = new File(etlFile);
393: File buildDir = new File(args[1]);
394: EngineFileGenerator g = new EngineFileGenerator();
395:
396: try {
397: g.generateEngine(f, buildDir);
398: } catch (Exception e) {
399: e.printStackTrace();
400: }
401: }
402:
403: public static String toXml(Node node, String encoding,
404: boolean omitXMLDeclaration) {
405: String ret = null;
406: ByteArrayOutputStream baos = new ByteArrayOutputStream();
407: try {
408: Transformer trans = TransformerFactory.newInstance()
409: .newTransformer();
410: trans.setOutputProperty(OutputKeys.ENCODING, encoding);
411: trans.setOutputProperty(OutputKeys.INDENT, "yes");
412: trans.setOutputProperty(
413: "{http://xml.apache.org/xslt}indent-amount", "4");
414: trans.setOutputProperty(OutputKeys.METHOD, "xml");
415: trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,
416: omitXMLDeclaration ? "yes" : "no");
417: trans
418: .transform(new DOMSource(node), new StreamResult(
419: baos));
420: ret = baos.toString(encoding);
421: // mLogger.debug("ret: " + ret);
422: } catch (Exception e) {
423: e.printStackTrace();
424: }
425: return ret;
426: }
427: }
|