ASF Bugzilla – Attachment 6246 Details for
Bug 19712
Add a task for SQLJ compilation
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
Source for the enhancement
Sqlj.java (text/plain), 16.61 KB, created by
David Schultz
on 2003-05-07 00:25:13 UTC
(
hide
)
Description:
Source for the enhancement
Filename:
MIME Type:
Creator:
David Schultz
Created:
2003-05-07 00:25:13 UTC
Size:
16.61 KB
patch
obsolete
>/* > * ============================================================================ > * The Apache Software License, Version 1.1 > * ============================================================================ > * > * Copyright (C) 2000-2003 The Apache Software Foundation. All > * rights reserved. > * > * Redistribution and use in source and binary forms, with or without modifica- > * tion, are permitted provided that the following conditions are met: > * > * 1. Redistributions of source code must retain the above copyright notice, > * this list of conditions and the following disclaimer. > * > * 2. Redistributions in binary form must reproduce the above copyright notice, > * this list of conditions and the following disclaimer in the documentation > * and/or other materials provided with the distribution. > * > * 3. The end-user documentation included with the redistribution, if any, must > * include the following acknowledgment: "This product includes software > * developed by the Apache Software Foundation (http://www.apache.org/)." > * Alternately, this acknowledgment may appear in the software itself, if > * and wherever such third-party acknowledgments normally appear. > * > * 4. The names "Ant" and "Apache Software Foundation" must not be used to > * endorse or promote products derived from this software without prior > * written permission. For written permission, please contact > * apache@apache.org. > * > * 5. Products derived from this software may not be called "Apache", nor may > * "Apache" appear in their name, without prior written permission of the > * Apache Software Foundation. > * > * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, > * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND > * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE > * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, > * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- > * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS > * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON > * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT > * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF > * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > * > * This software consists of voluntary contributions made by many individuals > * on behalf of the Apache Software Foundation. For more information on the > * Apache Software Foundation, please see <http://www.apache.org/>. > * > */ >package org.apache.tools.ant.taskdefs.optional.sqlj; > >import java.util.*; >import java.io.*; >import org.apache.tools.ant.*; >import org.apache.tools.ant.types.*; >import org.apache.tools.ant.taskdefs.*; > >/** > * SQLJ compiler task. > * > * @author David Schultz <a href="mailto:dschultz@dc.com">dschultz@dc.com</a> > */ >public class Sqlj extends MatchingTask { > private Path srcdir = null; > private File destdir = null; > private File gendir = null; > private File properties = null; > private String compiler = null; > private String encoding = null; > private String user = null; > private String password = null; > private String url = null; > private String online = null; > private String warn = null; > private String offline = null; > private String driver = null; > private Boolean status = null; > private Boolean compile = Boolean.TRUE; > private Boolean linemap = null; > private Boolean profile = Boolean.TRUE; > private Boolean ser2class = null; > private Boolean cache = null; > private List compilerOptions = null; > > public class Option { > private String option; > public void setOption(String value) { > option = value; > } > public String getOption() { > return option; > } > } > /** > * Translates the fields and compilation list into an SQLJ command > * that can be executed. > */ > private Java buildSqljCommand(List compileList) { > Java command = new Java(); > > if (destdir != null) { > command.createArg().setValue("-d="+destdir.getPath()); > } > if (gendir != null) { > command.createArg().setValue("-dir="+gendir.getPath()); > } > if (properties != null) { > command.createArg().setValue("-props="+properties.getPath()); > } > if (compiler != null) { > command.createArg().setValue("-compiler-executable="+compiler); > } > if (encoding != null) { > command.createArg().setValue("-encoding="+encoding); > } > if (user != null) { > command.createArg().setValue("-user="+user); > } > if (password != null) { > command.createArg().setValue("-password="+password); > } > if (url != null) { > command.createArg().setValue("-url="+url); > } > if (online != null) { > command.createArg().setValue("-online=" + online); > } > if (warn != null) { > command.createArg().setValue("-warn=" + warn); > } > if (offline != null) { > command.createArg().setValue("-offline=" + offline); > } > if (driver != null) { > command.createArg().setValue("-driver=" + driver); > } > if (status != null) { > command.createArg().setValue("-status=" + status); > } > if (compile != null) { > command.createArg().setValue("-compile=" + compile); > } > if (linemap != null) { > command.createArg().setValue("-linemap=" + linemap); > } > if (profile != null) { > command.createArg().setValue("-profile=" + profile); > } > if (ser2class != null) { > command.createArg().setValue("-ser2class=" + ser2class); > } > if (cache != null) { > command.createArg().setValue("-cache=" + cache); > } > if (compilerOptions != null) { > for (int i = 0; i < compilerOptions.size(); i++) { > command.createArg().setValue("-C"+((Option)compilerOptions.get(i)).getOption()); > } > } > > for (int i = 0; i < compileList.size(); i++) { > command.createArg().setValue(((File)compileList.get(i)).getAbsolutePath()); > } > > command.setProject(getProject()); > command.setClassname("sqlj.tools.Sqlj"); > command.setTaskName(getTaskName()); > > log("Translating " + compileList.size() + " SQLJ file(s)"); > return command; > } > /** > * Returns an object that can contain a compiler option. > */ > public Option createCompileroption() { > if (compilerOptions == null) { > compilerOptions = new ArrayList(); > } > Option op = new Option(); > compilerOptions.add(op); > return op; > } > /** > * Creates a path object that can contain the src directory. > */ > public Path createSrc() { > if (srcdir == null) { > srcdir = new Path(project); > } > return srcdir.createPath(); > } > /** > * Executes the SQLJ command to compile SQLJ code. > */ > public void execute() throws BuildException { > > // first off, make sure that we've got a srcdir > if (srcdir == null) { > throw new BuildException("srcdir attribute must be set!", location); > } > String[] list = srcdir.list(); > if (list.length == 0) { > throw new BuildException("srcdir attribute must be set!", location); > } > > > // make sure that the destination directory is set and exists > if (destdir != null && !destdir.isDirectory()) { > throw new BuildException("destination directory \"" + destdir + "\" does not exist or is not a directory", location); > } > > // scan source directories and dest directory to build up compile lists > ArrayList compileList = new ArrayList(); > for (int i=0; i<list.length; i++) { > > // Validate the source directory > File srcDir = (File)project.resolveFile(list[i]); > if (!srcDir.exists()) { > throw new BuildException("srcdir \"" + srcDir.getPath() + "\" does not exist!", location); > } > > // Get a file list from the directory based on includes and excludes > String[] files = getDirectoryScanner(srcDir).getIncludedFiles(); > > // Scan the files checking for files for which the output file(s) is not up to date > scanDir(compileList, srcDir, destdir, files); > } > > // If there are files to translate, run the command > if (compileList.size() > 0) { > Java command = buildSqljCommand(compileList); > command.setFork(true); > int result = command.executeJava(); > if (result != 0) { > throw new BuildException("Translation failed, message should have been provided.",location); > } > } > } > /** > * Scans the destination directory for profiles associated with the sqlj file. > */ > private String[] findProfiles(File directory, String sqljFile) { > FileSet fileSet = new FileSet(); > fileSet.setDir(directory); > fileSet.setCaseSensitive(true); > fileSet.setIncludes(sqljFile.substring(0,sqljFile.indexOf(".sqlj")) + "_SJProfile*.ser"); > return fileSet.getDirectoryScanner(project).getIncludedFiles(); > } > /** > * Returns true if the resulting java should be compiled. > */ > public boolean isCompile() { > return compile != null && compile.booleanValue(); > } > /** > * Returns true if a profile should be generated from the sqlj. > */ > public boolean isProfile() { > return profile != null && profile.booleanValue(); > } > /** > * Scans the directory looking for source files to be compiled that have been changed > * since the last execution. The check is different from a traditional one to one comparison. > * There are up to 3 outputs from an sqlj operation (.java, .ser, .class), at > * least two of which can be checked if the appropriate options are used. The .java > * file is always produced so this can be checked by default. The .class file > * will be generated if the compile option is set, in which case the existence and > * timestamp of the file should be checked. A .ser file CAN be created if the profile > * option is set, however, since not all SQLJ files produce a .ser file, we can't > * assume that one must exist. We simply check for a valid date on the profile if > * the file does exist. The caveat here is that if a file produces a .ser the first > * time it is compiled and is then changed to no longer produce this file, the .ser > * will need to be cleaned up or the logic will assume the file is out of date every > * time. In theory, it would be relatively easy to audit an sqlj file to see if > * a profile should be produced but this would be going to deep in to true sqlj > * functionality. > * > * These checks are important to allow for easy restart of the build. For example, > * if the compile flag is true and a previous run fails compilation, a subsequent > * rerun of the task will skip compilation if the .java file is the only file > * being checked. > */ > private void scanDir(List compileList, File srcDir, File destDir, String[] files) { > > long now = System.currentTimeMillis(); > > // For each file > for (int i = 0; i < files.length; i++) { > File srcFile = new File(srcDir, files[i]); > > // Only operate on .sqlj files > if (files[i].endsWith(".sqlj")) { > > // Check for mismatched dates > if (srcFile.lastModified() > now) { > log("Warning: sqlj file modified in the future: " + files[i], Project.MSG_WARN); > } > > boolean needsCompilation = false; > > // Get the java file > File javaFile = new File(srcDir, files[i].substring(0,files[i].indexOf(".sqlj")) + ".java"); > > // compare the sqlj file to the java file > if (!javaFile.exists()) { > log("Compiling " + srcFile.getPath() + " because the java file " + javaFile.getPath() + " does not exist", Project.MSG_VERBOSE); > needsCompilation = true; > } else if (srcFile.lastModified() > javaFile.lastModified()) { > log("Compiling " + srcFile.getPath() + " because it is out of date with respect to " + javaFile.getPath(), Project.MSG_VERBOSE); > needsCompilation = true; > > // If the java file is up to date and profile creation is enabled, check the .ser > } else if (isProfile()) { > String[] profiles = findProfiles(destDir, files[i]); > for (int k=0; k < profiles.length; k++) { > File profile = new File(destDir, profiles[k]); > if (srcFile.lastModified() > profile.lastModified()) { > log("Compiling " + srcFile.getPath() + " because it is out of date with respect to " + profile.getPath(), Project.MSG_VERBOSE); > needsCompilation = true; > break; > } > } > } > > // If the profile and java files are both up to date, check the class file > if (!needsCompilation && isCompile()) { > // Get the class file > File classFile = new File(destDir, files[i].substring(0,files[i].indexOf(".sqlj")) + ".class"); > > // compare the sqlj file to the class file > if (!classFile.exists()) { > log("Compiling " + srcFile.getPath() + " because the class file " + classFile.getPath() + " does not exist", Project.MSG_VERBOSE); > needsCompilation = true; > } else if (srcFile.lastModified() > classFile.lastModified()) { > log("Compiling " + srcFile.getPath() + " because it is out of date with respect to " + classFile.getPath(), Project.MSG_VERBOSE); > needsCompilation = true; > } > } > > if (!needsCompilation) { > log ("Ingoring " + srcFile.getName() + " because it is up to date", Project.MSG_VERBOSE); > } > if (needsCompilation) { > compileList.add(srcFile); > } > } > } > } > /** > * Sets the CACHE option. Used to employ caching of SQL > * checking results to avoid database connections. > */ > public void setCache(boolean newCache) { > cache = new Boolean(newCache); > } > /** > * Used to enable or disable compilation of the generated > * java files to class files. The default is true. > */ > public void setCompile(boolean newCompile) { > compile = new Boolean(newCompile); > } > /** > * Sets the COMPILER-EXECUTABLE option. Used to specify > * an alternative javac command. > */ > public void setCompiler(String newCompiler) { > compiler = newCompiler; > } > /** > * Sets the destination directory for generated .ser and .class > * files. The generated java files will remain in the src directory. > */ > public void setDestdir(File newDestdir) { > destdir = newDestdir; > } > /** > * Sets the DRIVER option. Used to override the default > * JDBC driver for your system. > */ > public void setDriver(String newDriver) { > driver = newDriver; > } > /** > * Sets the ENCODING option. It is used to specify the input > * and output encoding of the source files. > */ > public void setEncoding(String newEncoding) { > encoding = newEncoding; > } > /** > * Sets the DIR option. Used to specify an alternative > * directory for the generated .java files to be placed. > */ > public void setGendir(File newGendir) { > gendir = newGendir; > } > /** > * Sets the LINEMAP option. When set the class file > * will be based on the line numbers from the SQLJ. > */ > public void setLinemap(boolean newLinemap) { > linemap = new Boolean(newLinemap); > } > /** > * Sets the OFFLINE option. Specifies an alternative SQLChecker > * implementation that will be used for offline SQLJ checking. > */ > public void setOffline(String newOffline) { > offline = newOffline; > } > /** > * Sets the ONLINE option. Specifies an alternative > * SQLChecker implementation that will be used for > * online checking. > */ > public void setOnline(String newOnline) { > online = newOnline; > } > /** > * Sets the PASSWORD option. Specifies the password > * for the database user. > */ > public void setPassword(String newPassword) { > password = newPassword; > } > /** > * Sets the PROFILE option to indicate whether or > * not profile customization will occur. > */ > public void setProfile(boolean newProfile) { > profile = new Boolean(newProfile); > } > /** > * Sets the PROPS option with the name of a property > * file from which to load options. > */ > public void setProperties(File newProperties) { > properties = newProperties; > } > /** > * Sets the SER2CLASS option. Indicates that the > * generated .ser files should be compiled to class > * files. The default is false. > */ > public void setSer2class(boolean newSer2class) { > ser2class = new Boolean(newSer2class); > } > /** > * Sets the source path from which to source the .sqlj files. > */ > public void setSrcdir(Path newSrcdir) { > srcdir = newSrcdir; > } > /** > * Sets the STATUS option to indicate that > * status should be displayed during compilation. > */ > public void setStatus(boolean newStatus) { > status = new Boolean(newStatus); > } > /** > * Sets the URL option. Indicates the database to > * be used for online checking of tables and columns > */ > public void setUrl(String newUrl) { > url = newUrl; > } > /** > * Sets the USER option to enable online checking. > */ > public void setUser(String newUser) { > user = newUser; > } > /** > * Sets the WARN option with the appropriate flag. > */ > public void setWarn(String newWarn) { > warn = newWarn; > } >}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 19712
: 6246 |
6247