/* ====================================================================
*
* The ObjectStyle Group Software License, Version 1.0
*
* Copyright (c) 2002 -2004 The ObjectStyle Group
* and individual authors of the software. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, 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 acknowlegement:
* "This product includes software developed by the
* ObjectStyle Group (http://objectstyle.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "ObjectStyle Group" and "Cayenne"
* must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact andrus@objectstyle.org.
*
* 5. Products derived from this software may not be called "ObjectStyle"
* nor may "ObjectStyle" appear in their names without prior written
* permission of the ObjectStyle Group.
*
* 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 OBJECTSTYLE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 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 ObjectStyle Group. For more
* information on the ObjectStyle Group, please see
* <http://objectstyle.org/>.
*
*/
package org.objectstyle.woproject.ant;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Chmod;
import org.apache.tools.ant.taskdefs.Copy;
import org.apache.tools.ant.taskdefs.Jar;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.PatternSet;
import org.apache.tools.ant.types.ZipFileSet;
import org.apache.tools.ant.types.selectors.FilenameSelector;
import org.objectstyle.woenvironment.env.WOBuildPropertiesNotFoundException;
import org.objectstyle.woenvironment.env.WOEnvironment;
/**
* Ant task to build WebObjects application. For detailed instructions go to the
* <a href="../../../../../ant/woapplication.html">manual page </a>.
*
*
* @ant.task category="packaging"
*
* @author Emily Bache
* @author Andrei Adamchik
*/
public class WOApplication extends WOTask {
protected List<FrameworkSet> frameworkSets = new ArrayList<FrameworkSet>();
protected List<OtherClasspathSet> otherClasspathSets = new ArrayList<OtherClasspathSet>();
private WOEnvironment woEnvironment;
// was "gu+x"
protected String chmod = "750";
protected String jvmOptions = "";
protected String jvm = "java";
protected String jdb = "jdb";
protected String jdbOptions = "";
// web.xml stuff
protected boolean webXML = false;
protected String webXML_WOROOT = null;
protected String webXML_LOCALROOT = null;
protected String webXML_WOAINSTALLROOT = null;
protected String webXML_WOAppMode = null;
protected String webXML_WOtaglib = null;
protected String webXML_CustomContent = null;
protected String startupScriptName = null;
protected String frameworksBaseURL = null;
protected boolean trueWar = false;
@Override
public void release() {
super.release();
frameworkSets = null;
otherClasspathSets = null;
woEnvironment = null;
}
public void setTrueWar(boolean trueWar) {
this.trueWar = trueWar;
}
public boolean isTrueWar() {
return trueWar;
}
@Override
public String getPrincipalClass() {
String aPrincipalClass = super.getPrincipalClass();
if (aPrincipalClass == null || aPrincipalClass.length() == 0) {
aPrincipalClass = "Application";
}
return aPrincipalClass;
}
/**
* Runs WOApplication task. Main worker method that would validate all task
* settings and create a WOApplication.
*/
@Override
public void execute() throws BuildException {
super.execute();
validateAttributes();
log("Installing " + name + " in " + destDir);
createDirectories();
if (hasClasses()) {
jarClasses();
}
if (hasSources()) {
jarSources();
}
if (hasLib()) {
copyLibs();
}
if (hasResources()) {
copyResources();
}
if (hasWs()) {
copyWsresources();
}
if (hasEmbeddedFrameworks()) {
copyEmbeddedFrameworks();
}
if (hasEmbeddedOtherClasspaths()) {
copyEmbeddedOtherClasspaths();
}
// create all needed scripts
AppFormat appFormat = new AppFormat(this);
if (appFormat.processTemplates()) {
// chmod UNIX scripts
chmodScripts();
}
appFormat.release();
frameworkSets = new ArrayList<FrameworkSet>();
otherClasspathSets = new ArrayList<OtherClasspathSet>();
woEnvironment = null;
this.release();
}
/**
* Sets executable flag for all scripts. This is required on UNIX/Mac
* platforms. On Windows this action is simply ignored.
*/
protected void chmodScripts() throws BuildException {
if (System.getProperty("os.name").toLowerCase().indexOf("win") < 0) {
File dir = null;
FileSet fs = null;
Chmod aChmod = null;
try {
dir = taskDir();
super.log("chmod scripts in " + dir, Project.MSG_VERBOSE);
fs = new FileSet();
fs.setDir(dir);
fs.createInclude().setName("**/" + name);
if (startupScriptName != null) {
fs.createInclude().setName("**/" + startupScriptName);
}
fs.createInclude().setName("**/*.sh");
aChmod = this.getSubtaskFactory().getChmod();
aChmod.setPerm(this.getChmod());
aChmod.addFileset(fs);
aChmod.execute();
}
finally {
dir = null;
fs = null;
aChmod = null;
}
}
else {
super.log("'" + System.getProperty("os.name") + "' is some kind of windows, skipping chmod.");
}
}
/**
* Method copyEmbeddedFrameworks.
*
* @throws BuildException
*/
protected void copyEmbeddedFrameworks() throws BuildException {
if (this.trueWar) {
Jar jar = new Jar();
jar.setOwningTarget(getOwningTarget());
jar.setProject(getProject());
jar.setTaskName(getTaskName());
for (FrameworkSet frameworkSet : getFrameworkSets()) {
File root = frameworkSet.getDir(getProject());
DirectoryScanner directoryScanner = frameworkSet.getDirectoryScanner(getProject());
String[] directories = directoryScanner.getIncludedDirectories();
for (String directory : directories) {
if (!directory.endsWith(".framework")) {
throw new BuildException("'name' attribute must end with '.framework'");
}
File javaFolder = new File(directory + "/Resources/Java");
if (javaFolder.exists()) {
File[] frameworkJars = javaFolder.listFiles();
if (frameworkJars != null) {
for (File frameworkJar : frameworkJars) {
ZipFileSet jarFileSet = new ZipFileSet();
FilenameSelector jarFileSelector = new FilenameSelector();
jarFileSelector.setName(frameworkJar.getAbsolutePath());
jarFileSet.addFilename(jarFileSelector);
jar.addZipfileset(jarFileSet);
}
}
}
System.out.println("WOApplication.copyEmbeddedFrameworks: directory = " + directory);
}
}
}
else {
Copy cp = new Copy();
cp.setOwningTarget(getOwningTarget());
cp.setProject(getProject());
cp.setTaskName(getTaskName());
cp.setLocation(getLocation());
cp.setTodir(embeddedFrameworksDir());
// The purpose of this is to create filesets that actually
// allow the framework directory to be copied into the
// WOApplication directory. If we didn't do this, we'd
// have to append '/' or '/**' to the end of the includes
// in the <frameworks> tag.
boolean hasEmbeddedFrameworkSets = false;
for (FrameworkSet frameworkSet : getFrameworkSets()) {
if (!frameworkSet.getEmbed()) {
continue;
}
File root = frameworkSet.getDir(getProject());
DirectoryScanner directoryScanner = frameworkSet.getDirectoryScanner(getProject());
String[] directories = directoryScanner.getIncludedDirectories();
for (String directory : directories) {
if (!directory.endsWith(".framework")) {
throw new BuildException("The includeded directory '" + directory + "' must end with '.framework'");
}
FileSet newFileSet = new FileSet();
newFileSet.setDir(root);
PatternSet.NameEntry include = newFileSet.createInclude();
include.setName(directory + "/**");
cp.addFileset(newFileSet);
hasEmbeddedFrameworkSets = true;
}
}
if (hasEmbeddedFrameworkSets) {
cp.execute();
}
}
}
/**
* Method copyEmbeddedFrameworks.
*
* @throws BuildException
*/
protected void copyEmbeddedOtherClasspaths() throws BuildException {
Copy cp = new Copy();
cp.setOwningTarget(getOwningTarget());
cp.setProject(getProject());
cp.setTaskName(getTaskName());
cp.setLocation(getLocation());
cp.setTodir(contentsDir());
boolean hasSet = false;
for (OtherClasspathSet cs : getOtherClasspath()) {
if (cs.getEmbed() == false) {
continue;
}
File root = cs.getDir(getProject());
DirectoryScanner ds = cs.getDirectoryScanner(getProject());
for (String includeName : ds.getIncludedDirectories()) {
FileSet newCs = new FileSet();
PatternSet.NameEntry include;
newCs.setDir(root);
include = newCs.createInclude();
// Since we're embedding, we expect to copy the entire subtree
// for this included entry. Force it if the task user didn't.
if (includeName.endsWith("/") == false) {
includeName = includeName + "/";
}
include.setName(includeName);
cp.addFileset(newCs);
hasSet = true;
}
}
if (hasSet)
cp.execute();
}
/**
* Returns location where WOApplication is being built up. For WebObjects
* applications this is a <code>.woa</code> directory.
*/
@Override
protected File taskDir() {
return getProject().resolveFile(destDir + File.separator + name + ".woa");
}
protected File contentsDir() {
return new File(taskDir(), "Contents");
}
protected String relativeEmbeddedFrameworksDir() {
return "Frameworks";
}
protected File embeddedFrameworksDir() {
return new File(contentsDir(), relativeEmbeddedFrameworksDir());
}
@Override
protected File resourcesDir() {
return new File(contentsDir(), "Resources");
}
@Override
protected File wsresourcesDir() {
return new File(contentsDir(), "WebServerResources");
}
@Override
protected File wsresourcesDestDir() {
File woLocation = new File(webServerDir(), "WebObjects");
File appLocation = new File(woLocation, name + ".woa");
File contentLocation = new File(appLocation, "Contents");
return new File(contentLocation, "WebServerResources");
}
/**
* @return
*/
public String getWebXML_LOCALROOT() {
return webXML_LOCALROOT;
}
/**
* @return
*/
public String getWebXML_WOAINSTALLROOT() {
return webXML_WOAINSTALLROOT;
}
/**
* @return
*/
public String getWebXML_WOAppMode() {
return webXML_WOAppMode;
}
/**
* @return
*/
public String getWebXML_WOROOT() {
log(" WOApplication.getWebXML_WOROOT() webXML_WOROOT: " + webXML_WOROOT, Project.MSG_VERBOSE);
return webXML_WOROOT;
}
/**
* @return
*/
public String getWebXML_WOtaglib() {
return webXML_WOtaglib;
}
/**
* @return
*/
public boolean getWebXML() {
return webXML;
}
/**
* @param string
*/
public void setWebXML_LOCALROOT(String string) {
webXML_LOCALROOT = string;
}
/**
* @param string
*/
public void setWebXML_WOAINSTALLROOT(String string) {
webXML_WOAINSTALLROOT = string;
}
/**
* @param string
*/
public void setWebXML_WOAppMode(String string) {
webXML_WOAppMode = string;
}
/**
* @param string
*/
public void setWebXML_WOROOT(String string) {
webXML_WOROOT = string;
}
/**
* @param string
*/
public void setWebXML_WOtaglib(String string) {
webXML_WOtaglib = string;
}
/**
* @param string
*/
public void setWebXML(boolean value) {
webXML = value;
}
@Override
protected boolean hasLib() {
return lib.size() > 0;
}
protected boolean hasEmbeddedFrameworks() {
List<FrameworkSet> theFrameworkSets = getFrameworkSets();
int size = theFrameworkSets.size();
for (int i = 0; i < size; i++) {
FrameworkSet fs = theFrameworkSets.get(i);
if (fs.getEmbed()) {
return true;
}
}
return false;
}
/**
* Create a nested FrameworkSet.
*/
public FrameworkSet createFrameworks() {
FrameworkSet frameSet = new FrameworkSet();
frameworkSets.add(frameSet);
return frameSet;
}
public List<FrameworkSet> getFrameworkSets() {
return frameworkSets;
}
/**
* Return true if any of the otherclasspath elements have the 'embed'
* attribute set to true.
*
* @return true if an otherclasspath element is embedded
*/
protected boolean hasEmbeddedOtherClasspaths() {
List<OtherClasspathSet> theClasspathSets = getOtherClasspath();
int size = theClasspathSets.size();
for (int i = 0; i < size; i++) {
OtherClasspathSet cs = theClasspathSets.get(i);
if (cs.getEmbed()) {
return true;
}
}
return false;
}
/**
* Create a nested OtherClasspath.
*/
public OtherClasspathSet createOtherclasspath() {
OtherClasspathSet otherClasspathSet = new OtherClasspathSet();
otherClasspathSets.add(otherClasspathSet);
return otherClasspathSet;
}
/**
* @return List
*/
public List<OtherClasspathSet> getOtherClasspath() {
return otherClasspathSets;
}
/**
* @return WOEnvironment
*/
@SuppressWarnings("unchecked")
public WOEnvironment getWOEnvironment() {
if (woEnvironment != null)
return woEnvironment;
woEnvironment = new WOEnvironment(this.getProject().getProperties());
if (!woEnvironment.variablesConfigured())
this.getProject().fireBuildFinished(new WOBuildPropertiesNotFoundException());
return woEnvironment;
}
/**
* @return
*/
public String getChmod() {
return chmod;
}
/**
* @param string
*/
public void setChmod(String string) {
chmod = string;
}
/**
* Method setJDB. Path to JDB executable
*
* @param jdbPath
*/
public void setJDB(String jdbPath) {
if (jdbPath == null || jdbPath.equals("${jdb}") || jdbPath.trim().length() <= 0) {
jdbPath = "jdb";
}
this.jdb = jdbPath;
}
/**
* Method getJDB returns path to jdb executable
*
* @return String
*/
public String getJDB() {
return jdb;
}
/**
* Method setJVM. Path to JVM executable.
*
* @param jvmPath
*/
public void setJVM(String jvmPath) {
if (jvmPath == null || jvmPath.equals("${jvm}") || jvmPath.trim().length() <= 0) {
this.jvm = "java";
}
this.jvm = jvmPath;
}
/**
* Method getJVM return path to java executable
*
* @return String
*/
public String getJVM() {
return jvm;
}
/**
* Method setJDBOptions.
*
* @param jdbOptions
*/
public void setJDBOptions(String jdbOptions) {
if (jdbOptions == null || jdbOptions.equals("${jdbOptions}") || jdbOptions.trim().length() <= 0) {
jdbOptions = "";
}
this.jdbOptions = jdbOptions;
}
/**
* Method getJDBOptions.
*
* @return String
*/
public String getJDBOptions() {
return jdbOptions;
}
/**
* Method setJvmOptions.
*
* @param jvmOptions
*/
public void setJvmOptions(String jvmOptions) {
if (jvmOptions == null || jvmOptions.equals("${jvmOptions}") || jvmOptions.trim().length() <= 0) {
jvmOptions = "";
}
this.jvmOptions = jvmOptions;
}
/**
* Method getJvmOptions.
*
* @return String
*/
public String getJvmOptions() {
return jvmOptions;
}
/**
* Ensure we have a consistent and legal set of attributes, and set any
* internal flags necessary based on different combinations of attributes.
*
* @throws BuildException
* if task attributes are inconsistent or missing.
*/
@Override
protected void validateAttributes() throws BuildException {
log(" this.getName().validateAttributes(): " + this.getName() + " webXML: " + webXML + " webXML_WOROOT: " + webXML_WOROOT, Project.MSG_VERBOSE);
if (webXML) {
if (webXML_WOROOT == null) {
webXML_WOROOT = this.getWOEnvironment().getWOVariables().systemRoot();
if (webXML_WOROOT == null)
throw new BuildException("'webXML_WOROOT' attribute is missing.");
}
if (webXML_LOCALROOT == null) {
webXML_LOCALROOT = this.getWOEnvironment().getWOVariables().localRoot();
if (webXML_LOCALROOT == null)
throw new BuildException("'webXML_LOCALROOT' attribute is missing.");
}
if (webXML_WOAINSTALLROOT == null) {
webXML_WOAINSTALLROOT = this.getWOEnvironment().getWOVariables().appsRoot();
if (webXML_WOAINSTALLROOT == null)
throw new BuildException("'webXML_WOAINSTALLROOT' attribute is missing.");
}
if (webXML_WOAppMode == null) {
webXML_WOAppMode = "Development";
if (webXML_WOAppMode == null)
throw new BuildException("'webXML_WOAppMode' attribute is missing.");
}
if (webXML_WOtaglib == null) {
webXML_WOtaglib = "/WEB-INF/tlds/WOtaglib_1_0.tld";
if (webXML_WOtaglib == null)
throw new BuildException("'webXML_WOtaglib' attribute is missing.");
}
}
}
public String getWebXML_CustomContent() {
return webXML_CustomContent;
}
public void setWebXML_CustomContent(String webXML_CustomContent) {
this.webXML_CustomContent = webXML_CustomContent;
}
public String getStartupScriptName() {
return startupScriptName;
}
public void setStartupScriptName(String startupScriptName) {
this.startupScriptName = startupScriptName;
}
public String getFrameworksBaseURL() {
return frameworksBaseURL;
}
public void setFrameworksBaseURL(String frameworksBaseURL) {
this.frameworksBaseURL = frameworksBaseURL;
}
}