You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cactus-dev@jakarta.apache.org by vm...@apache.org on 2005/02/15 11:31:44 UTC
cvs commit: jakarta-cactus/integration/ant/src/test/org/apache/cactus/integration/ant TestCactifyEarTask.java
vmassol 2005/02/15 02:31:44
Modified: integration/ant build.xml
integration/ant/src/java/org/apache/cactus/integration/ant/deployment/application
ApplicationXml.java ApplicationXmlIo.java
ApplicationXmlTag.java DefaultApplicationXml.java
Added: integration/ant/src/java/org/apache/cactus/integration/ant
CactifyEarTask.java CactusWar.java
integration/ant/src/test-input/org/apache/cactus/integration/ant
test-cactifyear.xml
integration/ant/src/test/org/apache/cactus/integration/ant
TestCactifyEarTask.java
Log:
CACTUS-190: Added new CactifyEar Ant task. Submitted by Magnus Grimsell.
Revision Changes Path
1.60 +3 -1 jakarta-cactus/integration/ant/build.xml
Index: build.xml
===================================================================
RCS file: /home/cvs/jakarta-cactus/integration/ant/build.xml,v
retrieving revision 1.59
retrieving revision 1.60
diff -u -r1.59 -r1.60
--- build.xml 30 Jan 2005 12:12:30 -0000 1.59
+++ build.xml 15 Feb 2005 10:31:44 -0000 1.60
@@ -167,6 +167,8 @@
comment="Cactus Tasks for Ant">
<entry key="cactifywar"
value="org.apache.cactus.integration.ant.CactifyWarTask"/>
+ <entry key="cactifyear"
+ value="org.apache.cactus.integration.ant.CactifyEarTask"/>
<entry key="cactus"
value="org.apache.cactus.integration.ant.CactusTask"/>
<entry key="runservertests"
1.2 +10 -2 jakarta-cactus/integration/ant/src/java/org/apache/cactus/integration/ant/deployment/application/ApplicationXml.java
Index: ApplicationXml.java
===================================================================
RCS file: /home/cvs/jakarta-cactus/integration/ant/src/java/org/apache/cactus/integration/ant/deployment/application/ApplicationXml.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ApplicationXml.java 31 May 2004 20:05:24 -0000 1.1
+++ ApplicationXml.java 15 Feb 2005 10:31:44 -0000 1.2
@@ -1,7 +1,7 @@
/*
* ========================================================================
*
- * Copyright 2003 The Apache Software Foundation.
+ * Copyright 2003-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -84,4 +84,12 @@
* they occur in the descriptor
*/
Iterator getElements(ApplicationXmlTag theTag);
+
+ /**
+ * Adds a web module to the deployment descriptor
+ *
+ * @param theUri the uri of the new module
+ * @param theContext the context of the new module
+ */
+ void addWebModule(String theUri, String theContext);
}
1.2 +100 -2 jakarta-cactus/integration/ant/src/java/org/apache/cactus/integration/ant/deployment/application/ApplicationXmlIo.java
Index: ApplicationXmlIo.java
===================================================================
RCS file: /home/cvs/jakarta-cactus/integration/ant/src/java/org/apache/cactus/integration/ant/deployment/application/ApplicationXmlIo.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ApplicationXmlIo.java 31 May 2004 20:05:24 -0000 1.1
+++ ApplicationXmlIo.java 15 Feb 2005 10:31:44 -0000 1.2
@@ -1,7 +1,7 @@
/*
* ========================================================================
*
- * Copyright 2003 The Apache Software Foundation.
+ * Copyright 2003-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,13 +21,17 @@
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
+import org.apache.xml.serialize.OutputFormat;
+import org.apache.xml.serialize.XMLSerializer;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
@@ -148,4 +152,98 @@
return new DefaultApplicationXml(builder.parse(theInput));
}
+ /**
+ * Writes the specified document to a file.
+ *
+ * @param theAppXml The descriptor to serialize
+ * @param theFile The file to write to
+ * @throws IOException If an I/O error occurs
+ */
+ public static void writeApplicationXml(ApplicationXml theAppXml,
+ File theFile)
+ throws IOException
+ {
+ writeApplicationXml(theAppXml, theFile, null, false);
+ }
+
+ /**
+ * Writes the specified document to a file.
+ *
+ * @param theAppXml The descriptor to serialize
+ * @param theFile The file to write to
+ * @param theEncoding The character encoding to use
+ * @throws IOException If an I/O error occurs
+ */
+ public static void writeApplicationXml(ApplicationXml theAppXml,
+ File theFile,
+ String theEncoding)
+ throws IOException
+ {
+ writeApplicationXml(theAppXml, theFile, theEncoding, false);
+ }
+
+ /**
+ * Writes the specified document to a file.
+ *
+ * @param theAppXml The descriptor to serialize
+ * @param theFile The file to write to
+ * @param theEncoding The character encoding to use
+ * @param isIndent Whether the written XML should be indented
+ * @throws IOException If an I/O error occurs
+ */
+ public static void writeApplicationXml(ApplicationXml theAppXml,
+ File theFile,
+ String theEncoding,
+ boolean isIndent)
+ throws IOException
+ {
+ OutputStream out = null;
+ try
+ {
+ out = new FileOutputStream(theFile);
+ writeApplicationXml(theAppXml, out, theEncoding, isIndent);
+ }
+ finally
+ {
+ if (out != null)
+ {
+ try
+ {
+ out.close();
+ }
+ catch (IOException ioe)
+ {
+ // we'll pass on the original IO error, so ignore this one
+ }
+ }
+ }
+ }
+
+ /**
+ * Writes the specified document to an output stream.
+ *
+ * @param theAppXml The descriptor to serialize
+ * @param theOutput The output stream to write to
+ * @param theEncoding The character encoding to use
+ * @param isIndent Whether the written XML should be indented
+ * @throws IOException If an I/O error occurs
+ */
+ public static void writeApplicationXml(ApplicationXml theAppXml,
+ OutputStream theOutput,
+ String theEncoding,
+ boolean isIndent)
+ throws IOException
+ {
+ OutputFormat outputFormat =
+ new OutputFormat(theAppXml.getDocument());
+ if (theEncoding != null)
+ {
+ outputFormat.setEncoding(theEncoding);
+ }
+ outputFormat.setIndenting(isIndent);
+ outputFormat.setPreserveSpace(false);
+ XMLSerializer serializer = new XMLSerializer(theOutput, outputFormat);
+ serializer.serialize(theAppXml.getDocument());
+ }
+
}
1.2 +8 -2 jakarta-cactus/integration/ant/src/java/org/apache/cactus/integration/ant/deployment/application/ApplicationXmlTag.java
Index: ApplicationXmlTag.java
===================================================================
RCS file: /home/cvs/jakarta-cactus/integration/ant/src/java/org/apache/cactus/integration/ant/deployment/application/ApplicationXmlTag.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ApplicationXmlTag.java 31 May 2004 20:05:24 -0000 1.1
+++ ApplicationXmlTag.java 15 Feb 2005 10:31:44 -0000 1.2
@@ -1,7 +1,7 @@
/*
* ========================================================================
*
- * Copyright 2003 The Apache Software Foundation.
+ * Copyright 2003-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -73,6 +73,12 @@
public static final ApplicationXmlTag CONTEXT_ROOT =
new ApplicationXmlTag("context-root");
+ /**
+ * Element name 'security-role',
+ */
+ public static final ApplicationXmlTag SECURITY_ROLE =
+ new ApplicationXmlTag("security-role");
+
// Instance Variables ------------------------------------------------------
/**
1.2 +96 -2 jakarta-cactus/integration/ant/src/java/org/apache/cactus/integration/ant/deployment/application/DefaultApplicationXml.java
Index: DefaultApplicationXml.java
===================================================================
RCS file: /home/cvs/jakarta-cactus/integration/ant/src/java/org/apache/cactus/integration/ant/deployment/application/DefaultApplicationXml.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- DefaultApplicationXml.java 31 May 2004 20:05:24 -0000 1.1
+++ DefaultApplicationXml.java 15 Feb 2005 10:31:44 -0000 1.2
@@ -1,7 +1,7 @@
/*
* ========================================================================
*
- * Copyright 2003 The Apache Software Foundation.
+ * Copyright 2003-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -51,6 +51,18 @@
*/
private final Element rootElement;
+ /**
+ * Specifies the order in which the top-level elements must appear in the
+ * descriptor, according to the DTD.
+ */
+ private static final ApplicationXmlTag[] ELEMENT_ORDER = {
+ ApplicationXmlTag.ICON,
+ ApplicationXmlTag.DISPLAY_NAME,
+ ApplicationXmlTag.DESCRIPTION,
+ ApplicationXmlTag.MODULE,
+ ApplicationXmlTag.SECURITY_ROLE
+ };
+
// Constructors ------------------------------------------------------------
/**
@@ -171,6 +183,23 @@
return elements.iterator();
}
+ /**
+ * @see ApplicationXml#addWebModule(String, String)
+ */
+ public void addWebModule(String theUri, String theContext)
+ {
+ Element moduleElement =
+ this.document.createElement(ApplicationXmlTag.MODULE.getTagName());
+ Element webElement =
+ this.document.createElement(ApplicationXmlTag.WEB.getTagName());
+ webElement.appendChild(
+ createNestedText(ApplicationXmlTag.WEB_URI, theUri));
+ webElement.appendChild(
+ createNestedText(ApplicationXmlTag.CONTEXT_ROOT, theContext));
+ moduleElement.appendChild(webElement);
+ addElement(ApplicationXmlTag.MODULE, moduleElement);
+ }
+
// Private Methods ---------------------------------------------------------
/**
@@ -220,4 +249,69 @@
return null;
}
+ /**
+ * Creates an element that contains nested text.
+ *
+ * @param theTag The tag to create an instance of
+ * @param theText The text that should be nested in the element
+ * @return The created DOM element
+ */
+ private Element createNestedText(ApplicationXmlTag theTag, String theText)
+ {
+ Element element = this.document.createElement(theTag.getTagName());
+ element.appendChild(this.document.createTextNode(theText));
+ return element;
+ }
+
+ /**
+ * Adds an element of the specified tag to the descriptor.
+ *
+ * @param theTag The descriptor tag
+ * @param theElement The element to add
+ */
+ public final void addElement(ApplicationXmlTag theTag, Element theElement)
+ {
+ Node importedNode = this.document.importNode(theElement, true);
+ Node refNode = getInsertionPointFor(theTag);
+ this.rootElement.insertBefore(importedNode, refNode);
+ }
+
+ /**
+ * Returns the node before which the specified tag should be inserted, or
+ * <code>null</code> if the node should be inserted at the end of the
+ * descriptor.
+ *
+ * @param theTag The tag that should be inserted
+ * @return The node before which the tag can be inserted
+ */
+ private Node getInsertionPointFor(ApplicationXmlTag theTag)
+ {
+ for (int i = 0; i < ELEMENT_ORDER.length; i++)
+ {
+ if (ELEMENT_ORDER[i] == theTag)
+ {
+ for (int j = i + 1; j < ELEMENT_ORDER.length; j++)
+ {
+ NodeList elements =
+ this.rootElement.getElementsByTagName(
+ ELEMENT_ORDER[j].getTagName());
+ if (elements.getLength() > 0)
+ {
+ Node result = elements.item(0);
+ Node previous = result.getPreviousSibling();
+ while ((previous != null)
+ && ((previous.getNodeType() == Node.COMMENT_NODE)
+ || (previous.getNodeType() == Node.TEXT_NODE)))
+ {
+ result = previous;
+ previous = result.getPreviousSibling();
+ }
+ return result;
+ }
+ }
+ break;
+ }
+ }
+ return null;
+ }
}
1.1 jakarta-cactus/integration/ant/src/java/org/apache/cactus/integration/ant/CactifyEarTask.java
Index: CactifyEarTask.java
===================================================================
/*
* ========================================================================
*
* Copyright 2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ========================================================================
*/
package org.apache.cactus.integration.ant;
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.cactus.integration.ant.deployment.application.ApplicationXml;
import org.apache.cactus.integration.ant.deployment.application.ApplicationXmlIo;
import org.apache.cactus.integration.ant.deployment.application.DefaultEarArchive;
import org.apache.cactus.integration.ant.deployment.application.EarArchive;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.taskdefs.Ear;
import org.apache.tools.ant.types.ZipFileSet;
import org.apache.tools.ant.util.FileUtils;
import org.xml.sax.SAXException;
/**
* An Ant task that injects elements necessary to run Cactus tests into an
* existing EAR file.
*
* @version $Id: CactifyEarTask.java,v 1.1 2005/02/15 10:31:44 vmassol Exp $
*/
public class CactifyEarTask extends Ear
{
/**
* Cactus war configuration holder
*/
private CactusWar cactusWar;
/**
* The archive that contains the web-app that should be cactified.
*/
private File srcFile;
/**
*
* @param theCactusWar CactusWar to set
*/
public void addConfiguredCactuswar(CactusWar theCactusWar)
{
cactusWar = theCactusWar;
}
/**
* @param theSrcFile The srcFile to set.
*/
public void setSrcFile(File theSrcFile)
{
srcFile = theSrcFile;
}
/**
* @see org.apache.tools.ant.Task#execute()
*/
public void execute() throws BuildException
{
if (cactusWar == null)
{
cactusWar = createCactusWarConfig();
}
//Add everything that's in the source EAR to the destination EAR
ZipFileSet currentFiles = new ZipFileSet();
currentFiles.setSrc(this.srcFile);
currentFiles.createExclude().setName("META-INF/application.xml");
addZipfileset(currentFiles);
// cactify the application.xml
ApplicationXml appXml = getOriginalApplicationXml();
File tmpAppXml = cactifyApplicationXml(appXml);
setAppxml(tmpAppXml);
// create the cactus war
File cactusWarFile = createCactusWar();
addFileToEar(cactusWarFile, cactusWar.getFileName());
super.execute();
}
/**
*
* @return the application.xml from the source ear
*/
private ApplicationXml getOriginalApplicationXml()
{
ApplicationXml appXml = null;
try
{
EarArchive ear = new DefaultEarArchive(this.srcFile);
appXml = ear.getApplicationXml();
if (appXml == null)
{
throw new BuildException("The EAR source file does not "
+ "contain a META-INF/application.xml "
+ "deployment descriptor");
}
}
catch (SAXException e)
{
throw new BuildException(
"Parsing of application.xml deployment descriptor failed", e);
}
catch (IOException e)
{
throw new BuildException("Failed to open EAR", e);
}
catch (ParserConfigurationException e)
{
throw new BuildException("XML parser configuration error", e);
}
return appXml;
}
/**
*
* @param theAppXml the application.xml to cactify
* @return the cactified application.xml
*/
private File cactifyApplicationXml(ApplicationXml theAppXml)
{
theAppXml.addWebModule(cactusWar.getFileName(), cactusWar.getContext());
// serialize the cactified app xml
FileUtils fileUtils = FileUtils.newFileUtils();
File tmpAppXml = fileUtils.createTempFile("cactus", "application.xml",
getProject().getBaseDir());
tmpAppXml.deleteOnExit();
try
{
ApplicationXmlIo.writeApplicationXml(theAppXml,
tmpAppXml,
null, true);
}
catch (IOException ioe)
{
throw new BuildException(
"Could not write temporary deployment descriptor", ioe);
}
return tmpAppXml;
}
/**
*
* @return the cactus.war
*/
private File createCactusWar()
{
FileUtils fileUtils = FileUtils.newFileUtils();
File tmpCactusWar = fileUtils.createTempFile("cactus", "cactus.war",
getProject().getBaseDir());
tmpCactusWar.deleteOnExit();
cactusWar.setDestFile(tmpCactusWar);
cactusWar.execute();
return tmpCactusWar;
}
/**
*
* @param theFile the file to add
* @param theFullPath the path within the ear
*/
private void addFileToEar(File theFile, String theFullPath)
{
ZipFileSet fs = new ZipFileSet();
fs.setFile(theFile);
fs.setFullpath(theFullPath);
addZipfileset(fs);
}
/**
* Initialize cactusWar with some default values.
*
* @return the CactusWar configuration
*/
private CactusWar createCactusWarConfig()
{
CactusWar cactusWarConfig = new CactusWar();
CactusWar.Version version = new CactusWar.Version();
version.setValue("2.3");
cactusWarConfig.setVersion(version);
cactusWarConfig.setContext("/cactus");
cactusWarConfig.setProject(getProject());
return cactusWarConfig;
}
}
1.1 jakarta-cactus/integration/ant/src/java/org/apache/cactus/integration/ant/CactusWar.java
Index: CactusWar.java
===================================================================
/*
* ========================================================================
*
* Copyright 2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ========================================================================
*/
package org.apache.cactus.integration.ant;
/**
*
*
*
* @version $Id: CactusWar.java,v 1.1 2005/02/15 10:31:44 vmassol Exp $
*/
public class CactusWar extends CactifyWarTask
{
/**
* Name of the generated web app file
*/
private static final String FILE_NAME = "cactus.war";
/**
* Context of the cactus web application
*/
private String context;
/**
* @return Returns the context.
*/
public String getContext()
{
return context;
}
/**
* @param theContext The context to set.
*/
public void setContext(String theContext)
{
context = theContext;
}
/**
*
* @return the name of the web app file
*/
public String getFileName()
{
return FILE_NAME;
}
}
1.1 jakarta-cactus/integration/ant/src/test-input/org/apache/cactus/integration/ant/test-cactifyear.xml
Index: test-cactifyear.xml
===================================================================
<?xml version="1.0"?>
<project name="test-cactifyear" basedir="." default="help">
<property name="work.dir" location="${basedir}/work"/>
<target name="setUp">
<mkdir dir="${work.dir}"/>
</target>
<target name="testCanAddCactifiedWar">
<cactifyear srcfile="empty.ear" destfile="${work.dir}/cactified.ear"/>
</target>
<target name="testCustomCactusWarContext">
<cactifyear srcfile="empty.ear" destfile="${work.dir}/cactified.ear">
<cactuswar context="/myTestFramework" version="2.3"/>
</cactifyear>
</target>
<target name="tearDown">
<delete dir="${work.dir}"/>
</target>
</project>
1.1 jakarta-cactus/integration/ant/src/test/org/apache/cactus/integration/ant/TestCactifyEarTask.java
Index: TestCactifyEarTask.java
===================================================================
/*
* ========================================================================
*
* Copyright 2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ========================================================================
*/
package org.apache.cactus.integration.ant;
import java.io.File;
import org.apache.cactus.integration.ant.deployment.application.ApplicationXml;
import org.apache.cactus.integration.ant.deployment.application.DefaultEarArchive;
import org.apache.cactus.integration.ant.deployment.application.EarArchive;
import org.apache.cactus.integration.ant.deployment.webapp.WarArchive;
import org.apache.cactus.integration.ant.deployment.webapp.WebXml;
/**
* Test class for the CactifyEar task.
*
* @version $Id: TestCactifyEarTask.java,v 1.1 2005/02/15 10:31:44 vmassol Exp $
*/
public class TestCactifyEarTask extends AntTestCase
{
/**
* @see AntTestCase#AntTestCase
*/
public TestCactifyEarTask()
{
super("org/apache/cactus/integration/ant/test-cactifyear.xml");
}
/**
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception
{
super.setUp();
getProject().addTaskDefinition("cactifyear", CactifyEarTask.class);
}
/**
* Tests that the basic function of the task works,
* that is to add a cactified war to the ear.
*
* @throws Exception If an unexpected error occurs
*/
public void testCanAddCactifiedWar() throws Exception
{
executeTestTarget();
File destFile = getProject().resolveFile("work/cactified.ear");
EarArchive destEar = new DefaultEarArchive(destFile);
ApplicationXml appXml = destEar.getApplicationXml();
assertEquals("/cactus", appXml.getWebModuleContextRoot("cactus.war"));
WarArchive cactusWar = destEar.getWebModule("cactus.war");
WebXml webXml = cactusWar.getWebXml();
assertNotNull(webXml.getServlet("ServletRedirector"));
}
/**
* Tests that the context of the cactus.war can be specified.
*
* @throws Exception If an unexpected error occurs
*/
public void testCustomCactusWarContext() throws Exception
{
executeTestTarget();
File destFile = getProject().resolveFile("work/cactified.ear");
EarArchive destEar = new DefaultEarArchive(destFile);
ApplicationXml appXml = destEar.getApplicationXml();
assertEquals("/myTestFramework",
appXml.getWebModuleContextRoot("cactus.war"));
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: cactus-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: cactus-dev-help@jakarta.apache.org