/******************************************************************************* * Copyright (c) 2004, 2007 IBM Corporation and Cambridge Semantics Incorporated. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * File: $Source: /cvsroot/slrp/common/com.ibm.adtech.jdbc.utils/src/com/ibm/adtech/jdbc/utils/opgen/ant/CompositionTask.java,v $ * Created by: Joe Betz * Created on: 9/30/2005 * Revision: $Id: CompositionTask.java 176 2007-07-31 14:22:30Z mroy $ * * Contributors: * IBM Corporation - initial API and implementation * Cambridge Semantics Incorporated - Fork to Anzo *******************************************************************************/ package org.openanzo.jdbc.opgen.ant; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.StringWriter; import java.io.Writer; import java.security.InvalidParameterException; import java.text.DateFormat; import java.util.Calendar; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Vector; import java.util.regex.Pattern; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.FactoryConfigurationError; import javax.xml.parsers.ParserConfigurationException; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.Task; import org.apache.tools.ant.taskdefs.MatchingTask; import org.apache.tools.ant.types.FileSet; import org.openanzo.jdbc.opgen.RdbStatement; import org.openanzo.jdbc.opgen.RdbStatementSet; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.xml.sax.SAXException; /** * An ant task to reads in rdb statements (SQL, DDL, etc.) from files (as specified in the ant file) and composes Anzo SQL Files (i.e. DB2.sql) as well as * generates java rdb statement wrapper files. * * @author Joe Betz * */ public class CompositionTask extends MatchingTask { List<PSTask> psTasks = new Vector<PSTask>(); List<DDLTask> ddlTasks = new Vector<DDLTask>(); File destinationFile; private String outputFormat; /** * Create a new composition task */ public CompositionTask() { } /** * Add a ddl task to this task * * @param ddlTask * to add */ public void addDDL(DDLTask ddlTask) { this.ddlTasks.add(ddlTask); } /** * Add a preparedStatement task to this task * * @param ps * preparedStatement task to add */ public void addPreparedStatements(PSTask ps) { this.psTasks.add(ps); } /** * Set the destination file * * @param destinationFile * to which this sql is written */ public void setDestdir(File destinationFile) { this.destinationFile = destinationFile; } @Override public void execute() throws BuildException { writeSQL(); } private void writeSQL() throws FactoryConfigurationError { try { Writer writer = null; if (destinationFile == null) { writer = new StringWriter(); } else { writer = new OutputStreamWriter(new FileOutputStream(destinationFile), "UTF-8"); } writer.write("#*******************************************************************************\n"); writer.write("# Copyright (c) 2004, 2007 IBM Corporation and Cambridge Semantics Incorporated.\n"); writer.write("# All rights reserved. This program and the accompanying materials\n"); writer.write("# are made available under the terms of the Eclipse Public License v1.0\n"); writer.write("# which accompanies this distribution, and is available at\n"); writer.write("# http://www.eclipse.org/legal/epl-v10.html\n"); writer.write("# \n"); writer.write("# File: $Source: /cvsroot/slrp/common/com.ibm.adtech.jdbc.utils/src/com/ibm/adtech/jdbc/utils/opgen/ant/CompositionTask.java,v $\n"); writer.write("# Created by: Generated by Composition Ant Task\n"); writer.write("# Created on: " + DateFormat.getDateInstance(DateFormat.SHORT).format(Calendar.getInstance().getTime()) + "\n"); writer.write("# Revision: $Id: CompositionTask.java 176 2007-07-31 14:22:30Z mroy $\n"); writer.write("# \n"); writer.write("# Contributors:\n"); writer.write("# IBM Corporation - initial API and implementation\n"); writer.write("#*******************************************************************************\n"); writer.write("#\n"); writer.write("#\n"); for (Iterator<DDLTask> iter = ddlTasks.iterator(); iter.hasNext();) { DDLTask task = iter.next(); task.write(writer, outputFormat); } for (Iterator<PSTask> iter = psTasks.iterator(); iter.hasNext();) { PSTask task = iter.next(); task.write(writer, outputFormat); } writer.flush(); writer.close(); } catch (Exception e) { throw new BuildException(e); } } /** * Set the outputStream for this task * * @param outputFormat * for this task */ public void setOutputFormat(String outputFormat) { this.outputFormat = outputFormat; } /** * Set the output format for this task * * @return the output format for this task */ public String getOutputFormat() { return outputFormat; } /** * Provides file listings of prepared statements. * * @author Joe Betz * */ public static class PSTask extends Task { List<FileSet> fileSets = new Vector<FileSet>(); String javaClass; String destBase; String rethrowExceptionName = "org.openanzo.jdbc.utils.RdbException"; private boolean excludeNamespace = false; private boolean rethrowSQLException = false; /** * Add a fileset to this task * * @param fileSet * to add */ public void addFileset(FileSet fileSet) { fileSets.add(fileSet); } /** * Set the type of exception to use in generated code * * @param rethrowExceptionName * type of exception to use in generated code */ public void setException(String rethrowExceptionName) { this.rethrowExceptionName = rethrowExceptionName; } /** * Get the files that make up the fileset for this task * * @return the files that make up the fileset for this task */ public List<FileSet> getFiles() { return fileSets; } /** * Set the name for the class * * @param javaClass * the name for the class */ public void setJavaClass(String javaClass) { this.javaClass = javaClass; } /** * Get the name for the class * * @return the name for the class */ public String getJavaClass() { return javaClass; } /** * Set the destination directory * * @param destBase * the destination directory */ public void setDestBase(String destBase) { this.destBase = destBase; } /** * Get the destination directory * * @return the destination directory */ public String getDestBase() { return destBase; } @Override public void execute() { } /** * Write out the transformed SQL file * * @param writer * output writer used to write file * @param outputFormat * format of output file * @throws FileNotFoundException * @throws IOException * @throws ParserConfigurationException * @throws FactoryConfigurationError * @throws SAXException */ public void write(Writer writer, String outputFormat) throws FileNotFoundException, IOException, ParserConfigurationException, FactoryConfigurationError, SAXException { Map<String, String> map = new HashMap<String, String>(); for (Iterator<FileSet> setIter = getFiles().iterator(); setIter.hasNext();) { FileSet set = setIter.next(); DirectoryScanner ds = set.getDirectoryScanner(getProject()); String files[] = ds.getIncludedFiles(); String base = ds.getBasedir().getAbsolutePath(); for (int i = 0; i < files.length; i++) { String filename = files[i]; String file = base + "/" + filename; map.putAll(getXmlSqlStatements(filename, file)); generateXmlSqlWrappers(filename, file); } } for (Map.Entry<String, String> entry : map.entrySet()) { writer.write(entry.getKey()); writer.write("="); writer.write(entry.getValue()); writer.write("\n"); } } /** * Get the set of SQL statements from a file * * @param filename * name of file to generate * @param file * file containing input * @return map of statements to their text * @throws FileNotFoundException * @throws IOException * @throws ParserConfigurationException * @throws FactoryConfigurationError * @throws SAXException */ private Map<String, String> getXmlSqlStatements(String filename, String file) throws FileNotFoundException, IOException, ParserConfigurationException, FactoryConfigurationError, SAXException { Map<String, String> map = new HashMap<String, String>(); DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); File f = new File(file); Document document = builder.parse(f.toURI().toString()); Element el = document.getDocumentElement(); String sqlPackageName; if (isExcludeNamespace()) { sqlPackageName = ""; } else { sqlPackageName = filename.replaceFirst("\\.sql$", ""); } RdbStatementSet preparedStatements = new RdbStatementSet(sqlPackageName, el); for (RdbStatement preparedStatement : preparedStatements.getList()) { String text = Pattern.compile("([\\s]+)").matcher(preparedStatement.getSql()).replaceAll(" ").trim(); text = Pattern.compile(";\\z").matcher(text).replaceAll(""); map.put(preparedStatement.getQualifiedName(), text); } return map; } private void generateXmlSqlWrappers(String filename, String file) throws FileNotFoundException, IOException, ParserConfigurationException, FactoryConfigurationError, SAXException { DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); File f = new File(file); Document document = builder.parse(f.toURI().toString()); Element el = document.getDocumentElement(); String sqlPackageName; if (isExcludeNamespace()) { sqlPackageName = ""; } else { sqlPackageName = filename.replaceFirst("\\.sql$", ""); } RdbStatementSet preparedStatements = new RdbStatementSet(sqlPackageName, el); if (destBase != null || javaClass != null) { if (destBase == null) throw new InvalidParameterException("javaclass set on 'preparedstatements' task so destbase must be set."); if (javaClass == null) throw new InvalidParameterException("destbase set on 'preparedstatements' task so javaclass must be set."); int lastDot = javaClass.lastIndexOf("."); String packageName = javaClass.substring(0, lastDot); String className = javaClass.substring(lastDot + 1, javaClass.length()); String path = destBase + packageName.replace('.', '/'); new File(path).mkdirs(); String fileName = path + "/" + className + ".java"; File destFile = new File(fileName); preparedStatements.writeJavaStub(destFile, className, packageName, rethrowExceptionName, rethrowSQLException); } } /** * Set whether to exclude the namespace of the sql statements * * @param excludeNamespace * whether to exclude the namespace of the sql statements */ public void setExcludeNamespace(boolean excludeNamespace) { this.excludeNamespace = excludeNamespace; } /** * Return true if parser should ignore the namespce of the sql statements * * @return true if parser should ignore the namespce of the sql statements */ public boolean isExcludeNamespace() { return excludeNamespace; } /** * Set if SQL exceptions should be rethrown or wrapped * * @param rethrowSQLException * if SQL exceptions should be rethrown or wrapped */ public void setRethrowSQLException(boolean rethrowSQLException) { this.rethrowSQLException = rethrowSQLException; } /** * Get if SQL exceptions should be rethrown or wrapped * * @return true if SQL exceptions should be rethrown, else wrapped */ public boolean isRethrowSQLException() { return rethrowSQLException; } } }