001: /*
002: * ========================================================================
003: *
004: * Copyright 2003-2004 The Apache Software Foundation.
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: *
018: * ========================================================================
019: */
020: package org.apache.cactus.integration.ant.container;
021:
022: import java.io.File;
023: import java.io.FileNotFoundException;
024:
025: import org.apache.tools.ant.taskdefs.Java;
026: import org.apache.tools.ant.types.Path;
027: import org.apache.tools.ant.types.Environment.Variable;
028:
029: /**
030: * Abstract base class for containers that perform the starting and stopping
031: * of the server by executing Java classes in a forked JVM.
032: *
033: * @version $Id: AbstractJavaContainer.java 239096 2004-12-10 13:50:22Z felipeal $
034: */
035: public abstract class AbstractJavaContainer extends AbstractContainer {
036: // Instance Variables ------------------------------------------------------
037:
038: /**
039: * The file to which output of the container should be written.
040: */
041: private File output;
042:
043: /**
044: * Whether output of the container should be appended to an existing file,
045: * or the existing file should be truncated.
046: */
047: private boolean append;
048:
049: /**
050: * The arguments for JVM.
051: */
052: private String jvmArgs;
053:
054: // Public Methods ----------------------------------------------------------
055:
056: /**
057: * Sets the file to which output of the container should be written.
058: *
059: * @param theOutput The output file to set
060: */
061: public final void setOutput(File theOutput) {
062: this .output = theOutput;
063: }
064:
065: /**
066: * Sets whether output of the container should be appended to an existing
067: * file, or the existing file should be truncated.
068: *
069: * @param isAppend Whether output should be appended
070: */
071: public final void setAppend(boolean isAppend) {
072: this .append = isAppend;
073: }
074:
075: /**
076: * Sets the arguments for JVM.
077: *
078: * @param theJVMArgs The arguments
079: */
080: public final void setJVMArgs(String theJVMArgs) {
081: this .jvmArgs = theJVMArgs;
082: }
083:
084: // Protected Methods -------------------------------------------------------
085:
086: /**
087: * Creates a preinitialized instance of the Ant Java task to be used for
088: * shutting down the container.
089: *
090: * @return The created task instance
091: */
092: protected final Java createJavaForShutDown() {
093: Java java = (Java) createAntTask("java");
094: java.setFork(true);
095:
096: // Add extra container classpath entries specified by the user.
097: addExtraClasspath(java);
098:
099: return java;
100: }
101:
102: /**
103: * Creates a preinitialized instance of the Ant Java task to be used for
104: * starting down the container.
105: *
106: * @return The created task instance
107: */
108: protected final Java createJavaForStartUp() {
109: Java java = (Java) createAntTask("java");
110: java.setFork(true);
111: java.setOutput(this .output);
112: java.setAppend(this .append);
113:
114: // pass arguments to the JVM
115: if (this .jvmArgs != null) {
116: getLog().trace(
117: "Passing arguments to the container JVM: "
118: + this .jvmArgs);
119: java.createJvmarg().setLine(this .jvmArgs);
120: }
121:
122: // Add extra container classpath entries specified by the user.
123: addExtraClasspath(java);
124:
125: // Add Cactus properties for the server side
126: if (getSystemProperties() != null) {
127: for (int i = 0; i < getSystemProperties().length; i++) {
128: java.addSysproperty(createSysProperty(
129: getSystemProperties()[i].getKey(),
130: getSystemProperties()[i].getValue()));
131: }
132: }
133:
134: return java;
135: }
136:
137: /**
138: * Add extra container classpath entries specified by the user.
139: *
140: * @param theJavaCommand the java command used to start/stop the container
141: */
142: private void addExtraClasspath(Java theJavaCommand) {
143: Path classpath = theJavaCommand.createClasspath();
144: if (getContainerClasspath() != null) {
145: classpath.addExisting(getContainerClasspath());
146: }
147: }
148:
149: /**
150: * Convenience method to create an Ant environment variable that points to
151: * a file.
152: *
153: * @param theKey The key or name of the variable
154: * @param theFile The file the variable should point to
155: * @return The created environment variable
156: */
157: protected final Variable createSysProperty(String theKey,
158: File theFile) {
159: Variable var = new Variable();
160: var.setKey(theKey);
161: var.setFile(theFile);
162: return var;
163: }
164:
165: /**
166: * Convenience method to create an Ant environment variable that contains
167: * a path.
168: *
169: * @param theKey The key or name of the variable
170: * @param thePath The path
171: * @return The created environment variable
172: */
173: protected final Variable createSysProperty(String theKey,
174: Path thePath) {
175: Variable var = new Variable();
176: var.setKey(theKey);
177: var.setPath(thePath);
178: return var;
179: }
180:
181: /**
182: * Convenience method to create an Ant environment variable that contains a
183: * string.
184: *
185: * @param theKey The key or name of the variable
186: * @param theValue The value
187: * @return The created environment variable
188: */
189: protected final Variable createSysProperty(String theKey,
190: String theValue) {
191: Variable var = new Variable();
192: var.setKey(theKey);
193: var.setValue(theValue);
194: return var;
195: }
196:
197: /**
198: * Returns the file containing the JDK tools (such as the compiler). This
199: * method must not be called on Mac OSX as there is no tools.jar file on
200: * that platform (everything is included in classes.jar).
201: *
202: * @return The tools.jar file
203: * @throws FileNotFoundException If the tools.jar file could not be found
204: */
205: protected final File getToolsJar() throws FileNotFoundException {
206: String javaHome = System.getProperty("java.home");
207: File toolsJar = new File(javaHome, "../lib/tools.jar");
208: if (!toolsJar.isFile()) {
209: throw new FileNotFoundException(toolsJar.getAbsolutePath());
210: }
211: return toolsJar;
212: }
213:
214: /**
215: * Adds the tools.jar to the classpath, except for Mac OSX as it is not
216: * needed.
217: *
218: * @param theClasspath the classpath object to which to add the tools.jar
219: */
220: protected final void addToolsJarToClasspath(Path theClasspath) {
221: // On OSX, the tools.jar classes are included in the classes.jar so
222: // there is no need to include any tools.jar file to the cp.
223: if (!isOSX()) {
224: try {
225: theClasspath.createPathElement().setLocation(
226: getToolsJar());
227: } catch (FileNotFoundException fnfe) {
228: getLog()
229: .warn(
230: "Couldn't find tools.jar (needed for JSP compilation)");
231: }
232: }
233: }
234:
235: /**
236: * @return The arguments for JVM.
237: */
238: protected final String getJVMArgs() {
239: return this .jvmArgs;
240: }
241:
242: // Private Methods -------------------------------------------------------
243:
244: /**
245: * Is the user running on a Macintosh OS X system? Heuristic derived from
246: * <a href="http://developer.apple.com/technotes/tn/tn2042.html#Section0_1">
247: * Apple Tech Note 2042</a>.
248: *
249: * @return true if the user's system is determined to be Mac OS X.
250: */
251: private boolean isOSX() {
252: return (System.getProperty("mrj.version") != null);
253: }
254:
255: }
|