UpdateTaskpublic class UpdateTask extends org.apache.tools.ant.Task This is the implementation for the Ant task .
This task updates J2EE components previously deployed in the J2EE 1.4 SDK and
Sun ONE Application Server 8. The following components may be updated:
- Enterprise application (EAR file)
- Web application (WAR file)
- Enterprise Java Bean (EJB-JAR file)
- Enterprise connector (RAR file)
The name of this task as used in build.xml will be sun-appserv-update.
This task uses ear/jar/war tasks from the user's Ant project
to find the contents of the components to be updated.
The attributes of this task are:
file="REQUIRED"
domain="OPTIONAL" (default: "domain1")
TODO: what if ear/jar/war task is called with dynamically changing property?
TODO: if XML desc changed, automatically reassemble and redeploy app ??
TODO: what if deployment changes XML descs (e.g. adds default values) ?? |
Fields Summary |
---|
private static final boolean | debug | private String | file | private String | sunonehome | private String | domain | private ArrayList | fromFiles | private ArrayList | toFiles | LocalStringsManager | lsm |
Methods Summary |
---|
private void | compareAndCopy(java.io.File fromDir, java.lang.String[] srcFiles, java.io.File toDir, java.lang.String prefix, java.lang.String fullpath)Compare last modified timestamps of srcFiles in fromDir with the
timestamps in toDir, copy if fromDir file has later timestamp.
if ( prefix != null && !prefix.equals("") ) {
toDir = new File(toDir, prefix);
}
for ( int i=0; i<srcFiles.length; i++ ) {
String srcFile = srcFiles[i];
if ( debug ) {
System.out.println("In compareAndCopy, fromDir = " + fromDir
+ " srcFile = " + srcFile + " toDir = " + toDir
+ " prefix = " + prefix + " fullpath = " + fullpath);
}
File from = new File(fromDir, srcFile);
File to;
if ( fullpath != null && !fullpath.equals("") ) {
to = new File(toDir, fullpath);
}
else {
to = new File(toDir, srcFile);
}
if ( from.lastModified() > to.lastModified() ) {
fromFiles.add(from);
toFiles.add(to);
}
}
| private void | copyFile(java.io.File from, java.io.File to)
System.out.println("Copying file " + from + " to " + to);
FileInputStream in = null;
FileOutputStream out = null;
try {
if ( !to.exists() ) {
if ( !to.getParentFile().exists() ) {
// create all parent dirs
to.getParentFile().mkdirs();
}
to.createNewFile();
}
in = new FileInputStream(from);
out = new FileOutputStream(to);
byte[] buffer = new byte[8 * 1024];
int count = 0;
while ( (count = in.read(buffer, 0, buffer.length)) != -1 ) {
out.write(buffer, 0, count);
}
} catch ( Exception ex ) {
throw new RuntimeException(lsm.getString("UnableToCopy", new Object[] {from}), ex);
} finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch ( Exception ex ) {}
}
| public void | execute()Execute the task.
if ( file == null || file.equals("") ) {
throw new BuildException(lsm.getString("AttributeFileNoProvided"));
}
try {
if ( sunonehome == null ) {
// figure out sunonehome from sun-appserv-ant.jar
ClassLoader cl = this.getClass().getClassLoader();
URL url = cl.getResource(
"org/apache/tools/ant/taskdefs/defaults.properties");
String path = new File(url.getFile()).getPath();
// path is like "<SUNONE_HOME>/lib/sun-appserv-ant.jar...."
// remove any file: prefix
if ( path.indexOf("file:") != -1 ) {
path = path.substring(5);
}
// remove the /lib/sun-appserv-ant.jar.... suffix.
int jarIndex = path.indexOf("sun-appserv-ant.jar");
sunonehome = path.substring(0, jarIndex - 5);
}
System.out.println(lsm.getString("UpdateMessage", new Object[] {file, sunonehome, domain}));
// Get the ear/jar/war task that created this app from the project
Jar[] creatorTasks = findCreatorTasks(file);
if ( creatorTasks == null ) {
throw new BuildException(lsm.getString("UnableToCreateArchive", new Object[] {file}));
}
if ( debug ) {
System.out.println(lsm.getString("TaskThatCreatedArchive", new Object[] {file}));
}
// Initialize list of files to be copied
fromFiles = new ArrayList();
toFiles = new ArrayList();
// Phase 1: make list of files to be copied
String sep = File.separator;
String appsDirName = sunonehome + sep + "domains" + sep +
domain + sep + "applications";
String appname = getAppNameFromFile(file);
String deployedDir;
if ( file.endsWith(".ear") ) {
// The app directory is like
// domains/domain1/server/applications/j2ee-apps/appname
String j2eeAppsDir = appsDirName + sep + "j2ee-apps";
deployedDir = j2eeAppsDir + File.separator + appname;
// Get JAR/WAR/RAR modules in this EAR
String[] moduleFiles = getModuleFiles(creatorTasks, file);
// Call updateModule for each module in the EAR
for ( int i=0; i<moduleFiles.length; i++ ) {
String modFile = moduleFiles[i];
// Get the task that created this module
Jar[] modCreatorTasks = findCreatorTasks(modFile);
if ( modCreatorTasks == null ) {
System.err.println(lsm.getString("UnableToFindTask", new Object[] {modFile}));
continue;
}
// Get the dir where module is deployed
String modName = getAppNameFromFile(modFile);
String modDeployedDir;
if ( modFile.endsWith(".war") ) {
modDeployedDir = deployedDir + sep + modName + "_war";
}
else if ( modFile.endsWith(".jar") ) {
modDeployedDir = deployedDir + sep + modName + "_jar";
}
else if ( modFile.endsWith(".rar") ) {
modDeployedDir = deployedDir + sep + modName + "_rar";
}
else if ( modFile.equals(file) ) {
modDeployedDir = deployedDir;
}
else {
System.err.println(lsm.getString("InvalidModule", new Object[] {modFile}));
continue;
}
updateModule(modCreatorTasks, modDeployedDir);
}
}
else {
// A standalone JAR/WAR module, the directory is
// domains/domain1/server/applications/j2ee-modules.
// XXX Dir will be named j2ee-web-modules, j2ee-ejb-modules,
// j2ee-rar-modules based on latest S1AS file layout proposal.
String modulesDir = appsDirName + sep + "j2ee-modules";
deployedDir = modulesDir + sep + appname;
updateModule(creatorTasks, deployedDir);
}
// Phase 2: copy files
if ( fromFiles.size() > 0 ) {
for ( int i=0; i<fromFiles.size(); i++ ) {
copyFile((File)fromFiles.get(i), (File)toFiles.get(i));
}
// Touch the .reload file in deployedDir to cause reload.
File reload = new File(deployedDir, ".reload");
if ( !reload.createNewFile() ) {
reload.setLastModified(System.currentTimeMillis());
}
System.out.println(lsm.getString("AplicationUpdated"));
}
else {
System.out.println(lsm.getString("FilesUpdateToDate"));
}
} catch ( Exception ex ) {
System.err.println(lsm.getString("UpdateError"));
if ( debug )
ex.printStackTrace();
throw new BuildException(ex);
}
| private org.apache.tools.ant.taskdefs.Jar[] | findCreatorTasks(java.lang.String file)Search all Ant targets in this project for the ear/jar/war tasks
that created the given archive file.
if ( debug ) {
System.err.println("In findCreatorTasks for file " + file
+ " canonical path is " + new File(file).getCanonicalPath());
}
Hashtable targets = project.getTargets();
Enumeration e = targets.elements();
ArrayList creators = new ArrayList();
while ( e.hasMoreElements() ) {
Target t = (Target)e.nextElement();
Task[] tasks = t.getTasks();
// For Ant 1.6.2: initialize UnknownElements so that the
// actual Jar tasks are created.
for ( int i=0; i<tasks.length; i++ ) {
if ( tasks[i] instanceof org.apache.tools.ant.UnknownElement ) {
try {
tasks[i].maybeConfigure();
} catch ( Exception ex ) {
// Ignore.
}
}
}
tasks = t.getTasks();
for ( int i=0; i<tasks.length; i++ ) {
// Note: Ear and War are subclasses of Jar
if ( tasks[i] instanceof org.apache.tools.ant.taskdefs.Jar ) {
Jar task = (Jar)tasks[i];
// make sure that attributes are set on the task
try {
task.maybeConfigure();
} catch ( Exception ex ) {
// Ignore.
}
//if ( debug ) {
// System.err.println("Checking task that created "
// + task.getDestFile());
//}
// check if this task created our archive file.
if ( task.getDestFile() != null
&& task.getDestFile().getCanonicalPath().equals(
new File(file).getCanonicalPath()) ) {
creators.add(task);
}
}
}
}
if ( creators.size() == 0 ) {
return null;
}
else {
return (Jar[])creators.toArray(new Jar[creators.size()]);
}
| private java.lang.String | getAppNameFromFile(java.lang.String file)Get the name of the J2EE application from the archive file.
String appname = file.substring(0, file.length()-4); // remove .ext
if ( appname.lastIndexOf(File.separator) != -1 ) {
appname = appname.substring(appname.lastIndexOf(File.separator)+1);
}
return appname;
| private java.util.ArrayList | getFilesets(org.apache.tools.ant.taskdefs.Jar[] tasks)Get the list of filesets that describe the contents of the archive
created by the task.
try {
// The Zip class has a private filesets field, and the
// MatchingTask class has a protected field fileset. Get them using
// reflection because theres no getter methods for them :-(
// No problems till the current Ant 1.6.1.
Class zipClass = Class.forName("org.apache.tools.ant.taskdefs.Zip");
Field filesetsField = zipClass.getDeclaredField("filesets");
filesetsField.setAccessible(true);
Field basedirField = zipClass.getDeclaredField("baseDir");
basedirField.setAccessible(true);
Class mtClass = Class.forName(
"org.apache.tools.ant.taskdefs.MatchingTask");
Field filesetField = mtClass.getDeclaredField("fileset");
filesetField.setAccessible(true);
ArrayList filesets = new ArrayList();
for ( int i=0; i<tasks.length; i++ ) {
// get the nested fileset elements of the task
Vector fs = (Vector)filesetsField.get(tasks[i]);
filesets.addAll(fs);
// get the implicit fileset of the task
FileSet implFileset = (FileSet)filesetField.get(tasks[i]);
File baseDir = (File)basedirField.get(tasks[i]);
if ( implFileset != null && baseDir != null ) {
FileSet fileset = (FileSet)implFileset.clone();
fileset.setDir(baseDir);
filesets.add(fileset);
}
}
return filesets;
} catch ( Exception ex ) {
throw (BuildException)(new BuildException().initCause(ex));
}
| private java.lang.String[] | getModuleFiles(org.apache.tools.ant.taskdefs.Jar[] earTasks, java.lang.String earFile)Return an array of JAR/WAR/RAR modules in the earFile.
// Get the filesets of the EAR
ArrayList filesets = getFilesets(earTasks);
// Iterate over each fileset
ArrayList modules = new ArrayList();
for ( int i=0; i<filesets.size(); i++ ) {
FileSet fs = (FileSet)filesets.get(i);
// If an invalid fileset, ignore it
if ( !fs.getDir(getProject()).exists() )
continue;
// get list of files from FileSet
DirectoryScanner ds = fs.getDirectoryScanner(getProject());
File fromDir = fs.getDir(getProject());
String[] files = ds.getIncludedFiles();
for ( int j=0; j<files.length; j++ ) {
String f = files[j];
if ( f.endsWith(".jar") || f.endsWith(".war")
|| f.endsWith(".rar") ) {
modules.add(new File(fromDir, f).toString());
}
}
}
modules.add(earFile);
return (String[])modules.toArray(new String[modules.size()]);
| public void | setDomain(java.lang.String domain)Set the name of the domain where this app is deployed (default: domain1).
this.domain = domain;
| public void | setFile(java.lang.String file)Set the application/module name.
// file may have the wrong separator char, "new File(..)" fixes it
this.file = new File(file).getPath();
| private void | updateModule(org.apache.tools.ant.taskdefs.Jar[] creatorTasks, java.lang.String deployedDir)Update contents of the module in the appserver's repository.
try {
File deployedDirFile = new File(deployedDir);
if ( !deployedDirFile.exists() ) {
System.err.println(lsm.getString("ModuleDoesNotExist", new Object[] {file}));
return;
}
// Get the filesets of the archive from the jar/war Task.
ArrayList filesets = getFilesets(creatorTasks);
// Iterate over each fileset
for ( int i=0; i<filesets.size(); i++ ) {
FileSet fs = (FileSet)filesets.get(i);
// If an invalid fileset, ignore it
if ( !fs.getDir(getProject()).exists() )
continue;
// get list of files from FileSet
DirectoryScanner ds = fs.getDirectoryScanner(getProject());
File fromDir = fs.getDir(getProject());
String[] srcFiles = ds.getIncludedFiles();
String prefix = "";
String fullpath = "";
if ( fs instanceof ZipFileSet ) {
ZipFileSet zfs = (ZipFileSet)fs;
// Below calls to getPrefix and getFullpath work only
// on Ant 1.6.2 and higher.
String tmpPrefix = zfs.getPrefix(getProject());
String tmpFullpath = zfs.getFullpath(getProject());
if ( tmpPrefix != null && !tmpPrefix.equals("") ) {
prefix = tmpPrefix;
}
else if ( tmpFullpath != null && !tmpFullpath.equals("") ) {
// This means the fileset contains a single file
// which is at the exact location of fullpath.
fullpath = tmpFullpath;
}
// XXX support src attr of ZipFileSet
// XXX support zipgroupfileset.
}
// For EAR files, only update stuff in META-INF
if ( file.endsWith(".ear") ) {
if ( fullpath.equals("META-INF/application.xml")
|| prefix.startsWith("META-INF") ) {
compareAndCopy(fromDir, srcFiles,
deployedDirFile, prefix, fullpath);
}
}
else {
compareAndCopy(fromDir, srcFiles,
deployedDirFile, prefix, fullpath);
}
}
} catch ( Exception ex ) {
System.err.println(lsm.getString("UpdateError"));
if ( debug )
ex.printStackTrace();
throw new BuildException(ex);
}
|
|