001: /**
002: Transformation - Transformations in Octopus Loader.
003: Copyright (C) 2002-2004 Together
004: This library is free software; you can redistribute it and/or
005: modify it under the terms of the GNU Lesser General Public
006: License as published by the Free Software Foundation; either
007: version 2.1 of the License, or (at your option) any later version.
008: This library is distributed in the hope that it will be useful,
009: but WITHOUT ANY WARRANTY; without even the implied warranty of
010: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
011: Lesser General Public License for more details.
012: You should have received a copy of the GNU Lesser General Public
013: License along with this library; if not, write to the Free Software
014: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
015: Transformation.java
016: Date: 05.04.2004.
017: @version 1.0
018: @author: Zoran Milakovic zoran@prozone.co.yu
019: @author: Milosevic Sinisa sinisa@prozone.co.yu
020: */package org.webdocwf.util.loader.transformation;
021:
022: import java.lang.reflect.Constructor;
023: import java.sql.Connection;
024: import java.sql.ResultSet;
025: import java.sql.SQLException;
026: import java.sql.Statement;
027: import java.util.ArrayList;
028: import java.util.List;
029: import java.util.Vector;
030:
031: import org.w3c.dom.Element;
032: import org.w3c.dom.Node;
033: import org.w3c.dom.NodeList;
034: import org.webdocwf.util.loader.ConfigReader;
035: import org.webdocwf.util.loader.LoaderException;
036: import org.webdocwf.util.loader.OctopusXMLUtil;
037: import org.webdocwf.util.loader.logging.Logger;
038:
039: /**
040: *
041: * Transformation - transformations in Octopus Loader.
042: */
043: public class Transformation {
044:
045: private String transformationName;
046: private String transformationClassName;
047: private String transformatorConfigName;
048:
049: private Vector sourceColumnNames = new Vector();
050:
051: private List transformationTargetColumns = new ArrayList();
052:
053: private Transformer transformer;
054: private Logger logger;
055: private JavaScriptEvaluator jsEvaluator;
056: private Element transformationDocFragment;
057:
058: public Transformation(String name, String className,
059: String configString, Element doc) throws Exception {
060:
061: this .transformationName = name;
062: this .transformationClassName = className;
063: this .transformatorConfigName = configString;
064: this .transformationDocFragment = doc;
065: String javaScriptExpression = "";
066:
067: NodeList childNodes = this .transformationDocFragment
068: .getElementsByTagName("javaScript");
069: if (childNodes.item(0) != null) {
070: javaScriptExpression = childNodes.item(0).getFirstChild()
071: .getNodeValue();
072: }
073: try {
074: init();
075: if (javaScriptExpression != "") {
076: //instantiate JavaScriptEvaluator for transformation with javaScript
077: jsEvaluator = new JavaScriptEvaluator();
078: jsEvaluator.setExpression(javaScriptExpression);
079: jsEvaluator.setVariableNames(this .sourceColumnNames);
080: this .transformer = (Transformer) jsEvaluator;
081: } else {
082: //instantiate transformer
083: Class transformatorClass = Class
084: .forName(this .transformationClassName);
085: Class[] ArgClassArray = new Class[] {};
086: Object[] ArgObject = new Object[] {};
087: Constructor transConstructor = transformatorClass
088: .getDeclaredConstructor(ArgClassArray);
089: this .transformer = (Transformer) (transConstructor
090: .newInstance(ArgObject));
091: }
092: if (transformatorConfigName != null
093: && this .transformer != null) {
094: this .transformer.configure(transformatorConfigName);
095: }
096:
097: } catch (Exception e) {
098: throw new LoaderException("Error during transformation!", e);
099: }
100: }
101:
102: public Transformation(String name, String className, Element doc)
103: throws Exception {
104: new Transformation(name, className, null, doc);
105: }
106:
107: /**
108: * This method set logger object
109: */
110: public void setLogger(Logger logger) {
111: if (this .transformer instanceof JavaScriptEvaluator) {
112: jsEvaluator.setLogger(logger);
113: } else {
114: this .logger = logger;
115: }
116:
117: }
118:
119: private void init() {
120: initSourceColumns();
121: initTargetColumns();
122: }
123:
124: /**
125: * @param doc represents Object document
126: * @param importJob represents current import job
127: */
128: private void initSourceColumns() {
129: //ZK change this because of problem with reading xml file, because of method importValue which reads all data from <importDefinition>tag
130: if (this .transformationDocFragment != null) {
131: this .sourceColumnNames = OctopusXMLUtil
132: .importValueForTransform(
133: this .transformationDocFragment,
134: "sourceColumn", "name");
135: }
136: }
137:
138: private void initTargetColumns() {
139: Vector targetColumnNames = OctopusXMLUtil
140: .importValueForTransform(
141: this .transformationDocFragment, "targetColumn",
142: "name");
143: Vector targetTableNames = OctopusXMLUtil
144: .importValueForTransform(
145: this .transformationDocFragment, "targetColumn",
146: "tableName");
147: Vector targetTableIDs = OctopusXMLUtil.importValueForTransform(
148: this .transformationDocFragment, "targetColumn",
149: "tableID");
150: Vector targetValueModes = OctopusXMLUtil
151: .importValueForTransform(
152: this .transformationDocFragment, "targetColumn",
153: "valueMode");
154: for (int i = 0; i < targetColumnNames.size(); i++) {
155: this .transformationTargetColumns
156: .add(new TransformationTargetColumn(
157: (String) targetColumnNames.get(i),
158: (String) targetTableNames.get(i),
159: (String) targetTableIDs.get(i),
160: (String) targetValueModes.get(i)));
161: }
162:
163: }
164:
165: /**
166: * Returns Vector with source column names
167: * @return vector
168: */
169: public Vector getSourceColumnNames() {
170: return this .sourceColumnNames;
171: }
172:
173: /**
174: * Returns Vector with target column names
175: * @return vector
176: */
177: public Vector getTargetColumnNames() {
178: Vector retVal = new Vector();
179: for (int i = 0; i < this .transformationTargetColumns.size(); i++) {
180: retVal
181: .add(((TransformationTargetColumn) this .transformationTargetColumns
182: .get(i)).getName());
183: }
184: return retVal;
185: }
186:
187: /**
188: * Returns Vector with target column names
189: * @param index logical table index
190: * @return vector
191: */
192: public Vector getTargetColumnNames(int index) {
193: Vector retVal = new Vector();
194: for (int i = 0; i < this .transformationTargetColumns.size(); i++) {
195: if (((TransformationTargetColumn) this .transformationTargetColumns
196: .get(i)).getTableID().equals(String.valueOf(index)))
197: retVal
198: .add(((TransformationTargetColumn) this .transformationTargetColumns
199: .get(i)).getName());
200: }
201:
202: return retVal;
203: }
204:
205: /**
206: * Returns Vector with target column types
207: * @param index logical table index
208: * @return vector
209: */
210: public Vector getTargetColumnTypes(int index) {
211: Vector retVal = new Vector();
212: for (int i = 0; i < this .transformationTargetColumns.size(); i++) {
213: if (((TransformationTargetColumn) this .transformationTargetColumns
214: .get(i)).getTableID().equals(String.valueOf(index)))
215: retVal
216: .add(((TransformationTargetColumn) this .transformationTargetColumns
217: .get(i)).getType());
218: // else
219: // retVal.add(null);
220: }
221: return retVal;
222: }
223:
224: /**
225: * Returns Vector with target column types on ordered places, and
226: * add null if in this place logic table is different than specified
227: * @param index logical table index
228: * @return vector
229: */
230: public Vector getOrderedTargetColumnTypes(int index) {
231: Vector retVal = new Vector();
232: for (int i = 0; i < this .transformationTargetColumns.size(); i++) {
233: if (((TransformationTargetColumn) this .transformationTargetColumns
234: .get(i)).getTableID().equals(String.valueOf(index)))
235: retVal
236: .add(((TransformationTargetColumn) this .transformationTargetColumns
237: .get(i)).getType());
238: else
239: retVal.add(null);
240: }
241: return retVal;
242: }
243:
244: /**
245: * Returns Vector with target value modes
246: * @param index logical table index
247: * @return vector
248: */
249: public Vector getTargetValueModes(int index) {
250: Vector retVal = new Vector();
251: for (int i = 0; i < this .transformationTargetColumns.size(); i++) {
252: if (((TransformationTargetColumn) this .transformationTargetColumns
253: .get(i)).getTableID().equals(String.valueOf(index)))
254: retVal
255: .add(((TransformationTargetColumn) this .transformationTargetColumns
256: .get(i)).getValueMode());
257: }
258: return retVal;
259: }
260:
261: /**
262: * Returns Vector with target key column names
263: * @param index logical table index
264: * @return vector
265: */
266: public Vector getTargetKeyColumnNames(int index) {
267: Vector retVal = new Vector();
268: for (int i = 0; i < this .transformationTargetColumns.size(); i++) {
269: if (((TransformationTargetColumn) this .transformationTargetColumns
270: .get(i)).getTableID().equals(String.valueOf(index))) {
271: if (((TransformationTargetColumn) this .transformationTargetColumns
272: .get(i)).getValueMode().equals("Key"))
273: retVal
274: .add(((TransformationTargetColumn) this .transformationTargetColumns
275: .get(i)).getName());
276: }
277: }
278: return retVal;
279: }
280:
281: /**
282: * Returns Vector with target column names for specified table
283: * @param tableName name of table
284: * @return vector
285: */
286: public Vector getTargetColumnNames(String tableName) {
287: Vector retVal = new Vector();
288: for (int i = 0; i < this .transformationTargetColumns.size(); i++) {
289: if (((TransformationTargetColumn) this .transformationTargetColumns
290: .get(i)).getTableName().equals(tableName))
291: retVal
292: .add(((TransformationTargetColumn) this .transformationTargetColumns
293: .get(i)).getName());
294: }
295: return retVal;
296: }
297:
298: /**
299: * Returns Vector with target key column names
300: * @return vector
301: */
302: public Vector getTargetKeyColumnNames() {
303: Vector retVal = new Vector();
304: for (int i = 0; i < this .transformationTargetColumns.size(); i++) {
305: if (((TransformationTargetColumn) this .transformationTargetColumns
306: .get(i)).getValueMode().equals("Key"))
307: retVal
308: .add(((TransformationTargetColumn) this .transformationTargetColumns
309: .get(i)).getName());
310: }
311: return retVal;
312: }
313:
314: /**
315: * Returns Vector with target value mode
316: * @return vector
317: */
318: public Vector getTargetValueMode() {
319: Vector retVal = new Vector();
320: for (int i = 0; i < this .transformationTargetColumns.size(); i++) {
321: retVal
322: .add(((TransformationTargetColumn) this .transformationTargetColumns
323: .get(i)).getValueMode());
324: }
325: return retVal;
326: }
327:
328: /**
329: * Returns Vector with target column types
330: * @return vector
331: */
332: // public Vector getTargetColumnTypes() {
333: // Vector retVal = new Vector();
334: // for(int i = 0; i < this.transformationTargetColumns.size(); i++) {
335: // retVal.add( ((TransformationTargetColumn)this.transformationTargetColumns.get(i)).getValueMode() );
336: // }
337: // return retVal;
338: // }
339:
340: /**
341: * This method read value of sub counter parameter
342: * @param sourceValues values to transform
343: * @return vector transformed values
344: * @throws SQLException
345: */
346: public Vector transformValues(Vector sourceValues) throws Exception {
347: Vector results = new Vector();
348: try {
349: results.addAll(this .transformer
350: .transformValue(sourceValues));
351: } catch (Exception except) {
352: throw except;
353: }
354: return results;
355:
356: }
357:
358: /**
359: * This method returns transformation name
360: * @return String which represents transformation name
361: */
362: public String getName() {
363: return this .transformationName;
364: }
365:
366: /**
367: * Method transformationColumnTypes is used to put types of transformation columns into
368: * global vector sorted in target tables. If there is an error, Exception
369: * "SQLException" or "NullPointerException" is thrown.
370: * @param c Connection to target database.
371: * @param firstColumn is first column
372: * @param columnsSuportedTarget is true if driver for target database supports getColumns method
373: * @param configReaderTarget is ConfigReader object for target database
374: * @throws SQLException Constructs an SQLException object with a reason.
375: * @throws NullPointerException Constructs a NullPointerException with the specified detail message.
376: */
377: public void transformationColumnTypes(Connection c,
378: int firstColumn, boolean columnsSuportedTarget,
379: ConfigReader configReaderTarget) throws SQLException,
380: NullPointerException {
381: int iCnt = 0;
382: try {
383: List tableNames = this .getTargetTableNames();
384: for (int k = 0; k < tableNames.size(); k++) {
385: Vector columnNames = this
386: .getTargetColumnNames(tableNames.get(k)
387: .toString());
388: Statement stmtTrans = c.createStatement();
389: //Vector typs = new Vector();
390: Vector subTyps = new Vector();
391: String strQuery = "select ";
392: ResultSet rsetTrans = null;
393: if (columnNames.size() != 0) {
394: for (int i = 0; i < columnNames.size(); i++) {
395: strQuery += columnNames.get(i).toString()
396: + ", ";
397: }
398: strQuery = strQuery.substring(0,
399: strQuery.length() - 2);
400: strQuery += " from " + tableNames.get(k).toString();
401: if (columnsSuportedTarget) {
402: rsetTrans = c.getMetaData().getColumns(
403: c.getCatalog(), null,
404: tableNames.get(k).toString(), "%");
405: String columnName = "";
406: String columnType = "";
407: while (rsetTrans.next()) {
408: columnName = rsetTrans
409: .getString(3 + firstColumn);
410: columnType = rsetTrans
411: .getString(5 + firstColumn);
412: for (int j = 0; j < columnNames.size(); j++) {
413: if (columnNames.get(j).toString()
414: .equalsIgnoreCase(columnName)) {
415: this .setType(tableNames.get(k)
416: .toString(), columnNames
417: .get(j).toString(),
418: columnType);
419: //typs.add(columnType);
420: }
421: }
422: }
423: } else {//TODO ZK ADDED stmtConstant.setMaxRows(1). Place this as parameter in conf file, like maxRowsSuported
424: if (configReaderTarget.getMaxRowsSupported()) {
425: stmtTrans.setMaxRows(1);
426: }
427: rsetTrans = stmtTrans.executeQuery(strQuery);
428: for (int j = 0; j < columnNames.size(); j++) {
429: this .setType(tableNames.get(k).toString(),
430: columnNames.get(j).toString(),
431: rsetTrans.getMetaData()
432: .getColumnTypeName(
433: j + firstColumn));
434: //typs.add(rsetConstant.getMetaData().getColumnTypeName(j + firstColumn));
435: }
436: }
437: rsetTrans.close();
438: }
439: stmtTrans.close();
440: }
441: // this.hmTargetColumnTypes.addAll(typs);
442: } catch (SQLException ex) {
443: throw ex;
444: } catch (NullPointerException ex) {
445: throw ex;
446: }
447: }
448:
449: public List getTargetTableNames() {
450: List retVal = new ArrayList();
451: Element transformation = this .transformationDocFragment;
452: NodeList nodeList = transformation.getChildNodes();
453: String tableName = "";
454: for (int i = 0; i < nodeList.getLength(); i++) {
455: if (nodeList.item(i).getNodeType() != Node.ELEMENT_NODE)
456: continue;
457: if (!nodeList.item(i).getNodeName().equals("targetColumns"))
458: continue;
459: Element targetColumns = (Element) nodeList.item(i);
460: NodeList targetColumnElements = targetColumns
461: .getElementsByTagName("targetColumn");
462: for (int j = 0; j < targetColumnElements.getLength(); j++) {
463: Element targetColumn = (Element) targetColumnElements
464: .item(j);
465: tableName = targetColumn.getAttribute("tableName");
466: if (!retVal.contains(tableName))
467: retVal.add(tableName);
468: }
469: }
470: return retVal;
471: }
472:
473: public String getTargetTableID() {
474: Element transformation = this .transformationDocFragment;
475: NodeList nodeList = transformation.getChildNodes();
476: for (int i = 0; i < nodeList.getLength(); i++) {
477: if (nodeList.item(i).getNodeType() != Node.ELEMENT_NODE)
478: continue;
479: if (!nodeList.item(i).getNodeName().equals("targetColumns"))
480: continue;
481: Element targetColumns = (Element) nodeList.item(i);
482: Element targetColumn = (Element) targetColumns
483: .getElementsByTagName("targetColumn").item(0);
484: return targetColumn.getAttribute("tableID");
485: }
486: return null;
487: }
488:
489: private void setType(String tableName, String columnName,
490: String type) {
491: for (int i = 0; i < this .transformationTargetColumns.size(); i++) {
492: if (((TransformationTargetColumn) this .transformationTargetColumns
493: .get(i)).getTableName().equals(tableName)
494: && ((TransformationTargetColumn) this .transformationTargetColumns
495: .get(i)).getName().equals(columnName))
496: ((TransformationTargetColumn) this .transformationTargetColumns
497: .get(i)).setType(type);
498: }
499: }
500:
501: /**
502: * This method reset all variables
503: */
504: public void reset() {
505: this .sourceColumnNames = new Vector();
506: this .transformationTargetColumns = new ArrayList();
507: }
508:
509: public void release() throws Exception {
510: this.transformer.release();
511: }
512: }
|