001: // THIS SOFTWARE IS PROVIDED BY SOFTARIS PTY.LTD. AND OTHER METABOSS
002: // CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
003: // BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
004: // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SOFTARIS PTY.LTD.
005: // OR OTHER METABOSS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
006: // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
007: // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
008: // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
009: // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
010: // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
011: // EVEN IF SOFTARIS PTY.LTD. OR OTHER METABOSS CONTRIBUTORS ARE ADVISED OF THE
012: // POSSIBILITY OF SUCH DAMAGE.
013: //
014: // Copyright 2000-2005 © Softaris Pty.Ltd. All Rights Reserved.
015: package com.metaboss.sdlctools.applications.anttasks;
016:
017: import java.io.File;
018: import java.io.IOException;
019: import java.util.Properties;
020:
021: import org.apache.log4j.PropertyConfigurator;
022: import org.apache.tools.ant.BuildException;
023: import org.apache.tools.ant.Task;
024: import org.apache.tools.ant.types.FileSet;
025: import org.apache.tools.ant.types.Path;
026: import org.apache.tools.ant.util.TaskLogger;
027:
028: import com.metaboss.enterprise.BaseException;
029: import com.metaboss.sdlctools.models.ModelValidationException;
030: import com.metaboss.util.AntUtils;
031: import com.metaboss.util.MetaBossSpecificUtils;
032:
033: /**
034: * Represents the base class for all tasks using MetaBoss.
035: * It handles static initialisation of the 'MetaBoss.Home' java system property from the environment.
036: * The 'MetaBoss.Home' java system property is used by many MetaBoss programs to find out the location of the
037: * libraries, configuration files etc. This task will attempt to ensure that the
038: * 'MetaBoss.Home' java system property is set as follows:
039: * <OL>
040: * <LI>If 'MetaBoss.Home' java system property is already set - it is left alone
041: * and no futher propcessing is done.</LI>
042: * <LI>If 'metaboss_home' ant project property is set - it is verified to contain valid and accessible directory
043: * and is set as 'MetaBoss.Home' java system property.</LI>
044: * <LI>If 'METABOSS_HOME' environment variable is set - it is verified to contain valid and accessible directory
045: * and is set as 'MetaBoss.Home' java system property.</LI>
046: * <LI>The directory is inferred from the location of the jar file containing this class.
047: * This jar is expected to be in <metaboss home>/lib/ directory therefore the path to the grandparent directory
048: * of the jar is set as 'MetaBoss.Home' java system property.</LI>
049: * </OL>
050: */
051: public abstract class MetaBossTask extends Task {
052: // Commons Logging instance - this is required by various generators
053: private static boolean sClassInitialsied = false;
054: private static File sMetaBossHomeDir = null;
055: private static Properties sPathProperties = null;
056: // Ant specific logger - created on startup
057: private TaskLogger mTaskLogger = null;
058:
059: // Static initialiser - executed once per Ant run
060: private void initialiseClassIfNecessary() {
061: // In Ant there is no real need for synchronisation
062: // because tasks are executed sequentually
063: if (!sClassInitialsied) {
064: sClassInitialsied = true;
065:
066: // Find out the metaboss home directory and set up -DMetaBoss.Home
067: if (System.getProperty("MetaBoss.Home") != null) {
068: mTaskLogger
069: .info("Setting MetaBoss Home to "
070: + System.getProperty("MetaBoss.Home")
071: + " as per 'MetaBoss.Home' java system property.");
072: } else {
073: String lMetaBossHomeDirectoryName = AntUtils
074: .getOptionalProjectProperty(getProject(),
075: "metaboss_home", null);
076: if (lMetaBossHomeDirectoryName != null) {
077: mTaskLogger
078: .info("Setting MetaBoss Home to "
079: + lMetaBossHomeDirectoryName
080: + " as per 'metaboss_home' ant project property.");
081: } else {
082: lMetaBossHomeDirectoryName = AntUtils
083: .getOptionalEnvironmentProperty(
084: "METABOSS_HOME", null);
085: if (lMetaBossHomeDirectoryName != null) {
086: mTaskLogger
087: .info("Setting MetaBoss Home to "
088: + lMetaBossHomeDirectoryName
089: + " as per 'METABOSS_HOME' environment property.");
090: } else {
091: String lURLString = MetaBossTask.class
092: .getProtectionDomain().getCodeSource()
093: .getLocation().toExternalForm();
094: if (lURLString.startsWith("file:")
095: && lURLString.endsWith(".jar")) {
096: File lSourceJar = new File(lURLString
097: .substring(5));
098: File lLibDirectory = lSourceJar
099: .getParentFile();
100: if (lLibDirectory.getName()
101: .equalsIgnoreCase("lib")) {
102: lMetaBossHomeDirectoryName = lLibDirectory
103: .getParentFile()
104: .getAbsolutePath();
105: mTaskLogger
106: .info("Setting MetaBoss Home to "
107: + lMetaBossHomeDirectoryName
108: + " as per discovered location of the MetaBoss jars.");
109: }
110: }
111: }
112: }
113: if (lMetaBossHomeDirectoryName != null) {
114: File lFile = new File(lMetaBossHomeDirectoryName);
115: if (lFile.exists() == false)
116: throw new BuildException(
117: "Directory "
118: + lMetaBossHomeDirectoryName
119: + " does not exist. Unable to access MetaBoss home directory, which is mandatory for <"
120: + getTaskName() + "> task.");
121: if (lFile.isDirectory() == false)
122: throw new BuildException(
123: lMetaBossHomeDirectoryName
124: + " is not a directory. Unable to access MetaBoss home directory, which is mandatory for <"
125: + getTaskName() + "> task.");
126: if (lFile.canRead() == false)
127: throw new BuildException(
128: lMetaBossHomeDirectoryName
129: + " directory is not accessible. Unable to access MetaBoss home directory, which is mandatory for <"
130: + getTaskName() + "> task.");
131: System.setProperty("MetaBoss.Home", lFile
132: .getAbsolutePath());
133: sMetaBossHomeDir = lFile;
134: } else {
135: mTaskLogger
136: .info("Unable to set MetaBoss Home to anything meaningful. Looked at the 'metaboss_home' project property, 'METABOSS_HOME' environment property and at the actual pysical location of the MetaBoss jars.");
137: }
138: }
139: // Read metaboss installation specific properties
140: MetaBossSpecificUtils.setupSystemProperties();
141: // Configure log4j logger as early as possible, but after we have read property files
142: PropertyConfigurator.configure(System.getProperties());
143: }
144: }
145:
146: /** The lifecycle method. Derived classes must call super */
147: public void init() {
148: // Call base class first
149: super .init();
150: // Create new task logger
151: mTaskLogger = new TaskLogger(this );
152: // Call the initialisation
153: initialiseClassIfNecessary();
154: }
155:
156: /** The getter for the logger */
157: public TaskLogger getLogger() {
158: return mTaskLogger;
159: }
160:
161: // The getter for the "metaboss_home" or METABOSS_HOME property
162: protected File getMetaBossHome() throws BuildException {
163: return sMetaBossHomeDir;
164: }
165:
166: // Returns path by it's logical name. Allows to manage path in one place
167: public Path getPath(String pPathName) throws BuildException {
168: Path lPath = new Path(getProject());
169: lPath.addFileset(getPathAsFileSet(pPathName));
170: return lPath;
171: }
172:
173: // Returns path elements organised in the fileset by it's logical name. Allows to manage path in one place
174: public FileSet getPathAsFileSet(String pPathName)
175: throws BuildException {
176: FileSet lFileSet = new FileSet();
177: lFileSet.setDir(getMetaBossHome());
178: Properties lProps = getPathProperties();
179: for (int i = 1;; i++) {
180: String lNextPathElementName = pPathName + "." + i;
181: String lNextPathElement = lProps
182: .getProperty(lNextPathElementName);
183: if (lNextPathElement == null)
184: break;
185: lFileSet.createInclude().setName(lNextPathElement);
186: }
187: return lFileSet;
188: }
189:
190: // Helper. Returns path properties
191: private static Properties getPathProperties() throws BuildException {
192: try {
193: if (sPathProperties == null) {
194: sPathProperties = new Properties();
195: sPathProperties
196: .load(org.apache.tools.ant.taskdefs.optional.metaboss.MetaBossToolTask.class
197: .getResourceAsStream("path.properties"));
198: }
199: return sPathProperties;
200: } catch (IOException e) {
201: throw new BuildException(
202: "Unable to load path properties from path.properties file.",
203: e);
204: }
205: }
206:
207: // This helper must be called from all tools when exception has been caught
208: // it will print the exception in the best possible manner
209: protected void handleException(Throwable pThrowable)
210: throws BuildException {
211: System.out.println("Caught exception "
212: + pThrowable.getClass().getName());
213: if (pThrowable instanceof BaseException) {
214: pThrowable.printStackTrace(System.out);
215: // Special case for model validation exception - it has explanation
216: if (pThrowable instanceof ModelValidationException) {
217: System.out
218: .println(((ModelValidationException) pThrowable)
219: .getFullExplanation());
220: return;
221: }
222: Throwable t = pThrowable.getCause();
223: while (t != null) {
224: System.out.println();
225: System.out.println();
226: System.out.println("Cause : " + t.getClass().getName());
227: t.printStackTrace(System.out);
228: // Special case for model validation exception - it has explanation
229: if (t instanceof ModelValidationException) {
230: System.out.println(((ModelValidationException) t)
231: .getFullExplanation());
232: break;
233: } else if (t instanceof BaseException) {
234: t = ((BaseException) t).getCause();
235: } else
236: break;
237: }
238: } else
239: // Special case for model validation exception - it has explanation
240: if (pThrowable instanceof ModelValidationException) {
241: System.out.println(((ModelValidationException) pThrowable)
242: .getFullExplanation());
243: } else {
244: System.out.println(pThrowable.getMessage());
245: pThrowable.printStackTrace(System.out);
246: }
247: throw new BuildException("Caught exception: "
248: + pThrowable.getClass().getName());
249: }
250: }
|