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.resin;
021:
022: import java.io.File;
023: import java.io.IOException;
024:
025: import org.apache.cactus.integration.ant.container.AbstractJavaContainer;
026: import org.apache.cactus.integration.ant.util.ResourceUtils;
027: import org.apache.tools.ant.BuildException;
028: import org.apache.tools.ant.taskdefs.Java;
029: import org.apache.tools.ant.types.FileSet;
030: import org.apache.tools.ant.types.FilterChain;
031: import org.apache.tools.ant.types.Path;
032: import org.apache.tools.ant.util.FileUtils;
033:
034: /**
035: * Common support for all Resin container versions.
036: *
037: * @version $Id: AbstractResinContainer.java 239003 2004-05-31 20:05:27Z vmassol $
038: */
039: public abstract class AbstractResinContainer extends
040: AbstractJavaContainer {
041: // Instance Variables ------------------------------------------------------
042:
043: /**
044: * The mandatory Resin installation directory.
045: */
046: private File dir;
047:
048: /**
049: * A user-specific resin.conf configuration file. If this variable is not
050: * set, the default configuration file from the JAR resources will be used.
051: */
052: private File resinConf;
053:
054: /**
055: * The port to which the container should be bound.
056: */
057: private int port = 8080;
058:
059: /**
060: * The temporary directory from which the container will be started.
061: */
062: private File tmpDir;
063:
064: // Public Methods ----------------------------------------------------------
065:
066: /**
067: * Sets the Resin installation directory.
068: *
069: * @param theDir The directory to set
070: */
071: public final void setDir(File theDir) {
072: this .dir = theDir;
073: }
074:
075: /**
076: * Sets the temporary directory from which the container is run.
077: *
078: * @param theTmpDir The temporary directory to set
079: */
080: public final void setTmpDir(File theTmpDir) {
081: this .tmpDir = theTmpDir;
082: }
083:
084: /**
085: * Sets the configuration file to use for the test installation of Resin
086: *
087: * @param theResinConf The resin.conf file
088: */
089: public final void setResinConf(File theResinConf) {
090: this .resinConf = theResinConf;
091: }
092:
093: /**
094: * Sets the port to which the container should listen.
095: *
096: * @param thePort The port to set
097: */
098: public final void setPort(int thePort) {
099: this .port = thePort;
100: }
101:
102: /**
103: * Checks if all mandatory properties have been set and that they
104: * contain valid values.
105: */
106: public void verify() {
107: if (getDir() == null) {
108: throw new BuildException(
109: "You must specify the mandatory [dir] attribute");
110: }
111:
112: if (!getDir().isDirectory()) {
113: throw new BuildException("[" + getDir()
114: + "] is not a directory");
115: }
116: }
117:
118: // AbstractContainer Implementation ----------------------------------------
119:
120: /**
121: * Returns the port to which the container should listen.
122: *
123: * @return The port
124: */
125: public final int getPort() {
126: return this .port;
127: }
128:
129: /**
130: * @see org.apache.cactus.integration.ant.container.Container#init
131: */
132: public final void init() {
133: verify();
134: }
135:
136: /**
137: * @see org.apache.cactus.integration.ant.container.Container#startUp
138: */
139: public final void startUp() {
140: try {
141: File installDir = setupTempDirectory(getTmpDir(), "cactus/"
142: + getContainerDirName());
143: cleanTempDirectory(installDir);
144:
145: prepare(installDir);
146:
147: // Invoke the main class
148: Java java = createJavaForStartUp();
149: java.addSysproperty(createSysProperty("resin.home",
150: installDir));
151: Path classpath = java.createClasspath();
152: classpath.createPathElement().setLocation(
153: ResourceUtils.getResourceLocation("/"
154: + ResinRun.class.getName()
155: .replace('.', '/') + ".class"));
156: FileSet fileSet = new FileSet();
157: fileSet.setDir(getDir());
158: fileSet.createInclude().setName("lib/*.jar");
159: classpath.addFileset(fileSet);
160: java.setClassname(ResinRun.class.getName());
161: java.createArg().setValue("-start");
162: java.createArg().setValue("-conf");
163: java.createArg()
164: .setFile(new File(installDir, "resin.conf"));
165:
166: // Add settings specific to a given container version
167: startUpAdditions(java, classpath);
168:
169: java.execute();
170: } catch (IOException ioe) {
171: getLog().error("Failed to startup the container", ioe);
172: throw new BuildException(ioe);
173: }
174: }
175:
176: /**
177: * @see org.apache.cactus.integration.ant.container.Container#shutDown
178: */
179: public final void shutDown() {
180: File installDir = setupTempDirectory(getTmpDir(), "cactus/"
181: + getContainerDirName());
182:
183: // Invoke the main class
184: Java java = createJavaForShutDown();
185: java.setFork(true);
186: java
187: .addSysproperty(createSysProperty("resin.home",
188: installDir));
189: Path classpath = java.createClasspath();
190: classpath.createPathElement().setLocation(
191: ResourceUtils.getResourceLocation("/"
192: + ResinRun.class.getName().replace('.', '/')
193: + ".class"));
194: FileSet fileSet = new FileSet();
195: fileSet.setDir(getDir());
196: fileSet.createInclude().setName("lib/*.jar");
197: classpath.addFileset(fileSet);
198: java.setClassname(ResinRun.class.getName());
199: java.createArg().setValue("-stop");
200: java.execute();
201: }
202:
203: // Protected Methods -------------------------------------------------------
204:
205: /**
206: * Allow specific version implementations to add custom settings to the
207: * Java container that will be started.
208: *
209: * @param theJavaContainer the Ant Java object that will start the container
210: * @param theClasspath the classpath that will be used to start the
211: * container
212: */
213: protected abstract void startUpAdditions(Java theJavaContainer,
214: Path theClasspath);
215:
216: /**
217: * Allow specific version implementations to add custom preparation steps
218: * before the container is started.
219: *
220: * @param theInstallDir The directory in which to create the temporary
221: * container installation
222: * @param theFilterChain the filter chain used to replace Ant tokens in
223: * configuration
224: * @exception IOException in case of an error
225: */
226: protected abstract void prepareAdditions(File theInstallDir,
227: FilterChain theFilterChain) throws IOException;
228:
229: /**
230: * @return the name of the directory where the container will be set up
231: */
232: protected abstract String getContainerDirName();
233:
234: /**
235: * @return the directory where Resin is installed
236: */
237: protected final File getDir() {
238: return this .dir;
239: }
240:
241: /**
242: * @return The temporary directory from which the container will be
243: * started.
244: */
245: protected final File getTmpDir() {
246: return this .tmpDir;
247: }
248:
249: // Private Methods ---------------------------------------------------------
250:
251: /**
252: * Prepares a temporary installation of the container and deploys the
253: * web-application.
254: *
255: * @param theInstallDir The directory in which to create the temporary
256: * container installation
257: * @throws IOException If an I/O error occurs
258: */
259: private void prepare(File theInstallDir) throws IOException {
260: FileUtils fileUtils = FileUtils.newFileUtils();
261: FilterChain filterChain = createFilterChain();
262:
263: // Copy configuration files into the temporary container directory
264: if (this .resinConf != null) {
265: fileUtils.copyFile(this .resinConf, new File(theInstallDir,
266: "resin.conf"));
267: } else {
268: ResourceUtils.copyResource(getProject(), RESOURCE_PATH
269: + getContainerDirName() + "/resin.conf", new File(
270: theInstallDir, "resin.conf"), filterChain);
271: }
272:
273: // Deploy the web-app by copying the WAR file into the webapps
274: // directory
275: if (getDeployableFile() != null) {
276: File webappsDir = createDirectory(theInstallDir, "webapps");
277: fileUtils.copyFile(getDeployableFile().getFile(),
278: new File(webappsDir, getDeployableFile().getFile()
279: .getName()), null, true);
280: }
281:
282: // Add preparation steps specific to a given container version
283: prepareAdditions(theInstallDir, filterChain);
284: }
285: }
|