Add modules for installer webapp

git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@778324 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
antelder 2009-05-25 07:31:39 +00:00
parent 8e974c823c
commit 10209d8013
10 changed files with 2404 additions and 0 deletions

View file

@ -32,6 +32,8 @@
<modules>
<module>tomcat-hook</module>
<module>tomcat-servlet</module>
<module>tomcat-war</module>
</modules>
</project>

View file

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
-->
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-modules</artifactId>
<version>2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>tuscany-tomcat-servlet</artifactId>
<name>Apache Tuscany SCA Tomcat Integration Servlet</name>
<dependencies>
<dependency>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-tomcat-hook</artifactId>
<version>2.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.codehaus.swizzle</groupId>
<artifactId>swizzle-stream</artifactId>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View file

@ -0,0 +1,298 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.tuscany.sca.war;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
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 java.io.PrintWriter;
import org.apache.tuscany.sca.tomcat.TuscanyLifecycleListener;
import org.codehaus.swizzle.stream.DelimitedTokenReplacementInputStream;
import org.codehaus.swizzle.stream.StringTokenHandler;
public class Installer {
private static boolean restartRequired;
private static boolean tuscanyHookRunning;
static {
try {
tuscanyHookRunning = TuscanyLifecycleListener.isRunning();
} catch (Throwable e) {
tuscanyHookRunning = false;
}
}
public static boolean isTuscanyHookRunning() {
return tuscanyHookRunning;
}
public static boolean isRestartRequired() {
return restartRequired;
}
private File tuscanyWAR;
private File catalinaBase;
private String status = "";
public Installer(File tuscanyWAR, File catalinaBase) {
this.tuscanyWAR = tuscanyWAR;
this.catalinaBase = catalinaBase;
}
public static boolean isInstalled() {
return false;
}
public String getStatus() {
return status;
}
public boolean install() {
try {
doInstall();
status = "Install successful, Tomcat restart required.";
restartRequired = true;
return true;
} catch (Throwable e) {
status = "Exception during install\n";
ByteArrayOutputStream os = new ByteArrayOutputStream();
PrintWriter pw = new PrintWriter(os);
e.printStackTrace(pw);
pw.close();
status += new String(os.toByteArray());
return false;
}
}
public boolean uninstall() {
try {
doUnintsall();
status = "Tuscany removed from server.xml, please restart Tomcat and manually remove Tuscany jars from Tomcat lib";
restartRequired = true;
return true;
} catch (Throwable e) {
status = "Exception during install";
ByteArrayOutputStream os = new ByteArrayOutputStream();
PrintWriter pw = new PrintWriter(os);
e.printStackTrace(pw);
status += "/n" + new String(os.toByteArray());
return false;
}
}
private void doUnintsall() {
File serverXml = new File(catalinaBase, "/conf/server.xml");
if (!(serverXml.exists())) {
throw new IllegalStateException("conf/server.xml not found: " + serverXml.getAbsolutePath());
}
removeServerXml(serverXml);
}
private boolean doInstall() {
// First verify all the file locations are as expected
if (!tuscanyWAR.exists()) {
throw new IllegalStateException("Tuscany war missing: " + tuscanyWAR.getAbsolutePath());
}
if (!catalinaBase.exists()) {
throw new IllegalStateException("Catalina base does not exist: " + catalinaBase.getAbsolutePath());
}
File serverLib = new File(catalinaBase, "/lib");
if (!(serverLib.exists())) {
throw new IllegalStateException(" Tomcat lib/ not found: " + serverLib.getAbsolutePath());
}
File serverXml = new File(catalinaBase, "/conf/server.xml");
if (!(serverXml.exists())) {
throw new IllegalStateException("conf/server.xml not found: " + serverXml.getAbsolutePath());
}
File tuscanyTomcatJar = findTuscanyTomcatJar(tuscanyWAR);
if (tuscanyTomcatJar == null || !tuscanyTomcatJar.exists()) {
throw new IllegalStateException("Can't find tuscany-tomcat-*.jar in: " + tuscanyWAR.getAbsolutePath());
}
// Copy tuscany-tomcat jar from the tuscany webapp web-inf/lib to Tomcat server/lib
copyFile(tuscanyTomcatJar, new File(serverLib, tuscanyTomcatJar.getName()));
// Add Tuscany LifecycleListener to Tomcat server.xml
updateServerXml(serverXml);
return true;
}
private File findTuscanyTomcatJar(File tuscanyWAR) {
File lib = new File(tuscanyWAR, "/tomcat-lib");
for (File f : lib.listFiles()) {
if (f.getName().startsWith("tuscany-tomcat-hook-") && f.getName().endsWith(".jar")) {
return f;
}
}
return null;
}
static final String tuscanyListener = "\r\n" + " <!-- Tuscany plugin for Tomcat -->\r\n" + "<Listener className=\"org.apache.tuscany.sca.tomcat.TuscanyLifecycleListener\" />";
private void updateServerXml(File serverXmlFile) {
String serverXML = readAll(serverXmlFile);
if (!serverXML.contains(tuscanyListener)) {
String newServerXml = replace(
serverXML,
"<Server",
"<Server",
">",
">" + tuscanyListener);
backup(serverXmlFile);
writeAll(serverXmlFile, newServerXml);
}
}
private void removeServerXml(File serverXmlFile) {
String serverXML = readAll(serverXmlFile);
if (serverXML.contains(tuscanyListener)) {
String newServerXml = replace(
serverXML,
"<Server",
"<Server",
">" + tuscanyListener,
">");
writeAll(serverXmlFile, newServerXml);
}
}
private String replace(String inputText, String begin, String newBegin, String end, String newEnd) {
BeginEndTokenHandler tokenHandler = new BeginEndTokenHandler(newBegin, newEnd);
ByteArrayInputStream in = new ByteArrayInputStream(inputText.getBytes());
InputStream replacementStream = new DelimitedTokenReplacementInputStream(in, begin, end, tokenHandler, true);
String newServerXml = readAll(replacementStream);
close(replacementStream);
return newServerXml;
}
private boolean backup(File source) {
File backupFile = new File(source.getParent(), source.getName() + ".b4Tuscany");
if (!backupFile.exists()) {
copyFile(source, backupFile);
}
return true;
}
private String readAll(File file) {
FileInputStream in = null;
try {
in = new FileInputStream(file);
String text = readAll(in);
return text;
} catch (Exception e) {
return null;
} finally {
close(in);
}
}
private String readAll(InputStream in) {
try {
// SwizzleStream block read methods are broken so read byte at a time
StringBuilder sb = new StringBuilder();
int i = in.read();
while (i != -1) {
sb.append((char) i);
i = in.read();
}
return sb.toString();
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
private void copyFile(File source, File destination) {
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(source);
out = new FileOutputStream(destination);
writeAll(in, out);
} catch (IOException e) {
throw new IllegalStateException(e);
} finally {
close(in);
close(out);
}
}
private boolean writeAll(File file, String text) {
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(file);
writeAll(new ByteArrayInputStream(text.getBytes()), fileOutputStream);
return true;
} catch (Exception e) {
return false;
} finally {
close(fileOutputStream);
}
}
private void writeAll(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[4096];
int count;
while ((count = in.read(buffer)) > 0) {
out.write(buffer, 0, count);
}
out.flush();
}
private void close(Closeable thing) {
if (thing != null) {
try {
thing.close();
} catch (Exception ignored) {
}
}
}
private class BeginEndTokenHandler extends StringTokenHandler {
private final String begin;
private final String end;
public BeginEndTokenHandler(String begin, String end) {
this.begin = begin;
this.end = end;
}
public String handleToken(String token) throws IOException {
String result = begin + token + end;
return result;
}
}
}

View file

@ -0,0 +1,70 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.tuscany.sca.war;
import java.io.File;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class InstallerServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private transient ServletConfig servletConfig;
private transient Installer installer;
public void init(ServletConfig servletConfig) throws ServletException {
this.servletConfig = servletConfig;
String path = servletConfig.getServletContext().getRealPath("/");
File tuscanyWarDir = null;
if (path != null) {
tuscanyWarDir = new File(path);
}
File tomcatBase = new File(System.getProperty("catalina.base"));
installer = new Installer(tuscanyWarDir, tomcatBase);
}
protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
doIt(httpServletRequest, httpServletResponse);
}
protected void doPost(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
doIt(httpServletRequest, httpServletResponse);
}
protected void doIt(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
if ("Install".equalsIgnoreCase(req.getParameter("action"))) {
installer.install();
} else if ("Uninstall".equalsIgnoreCase(req.getParameter("action"))) {
installer.uninstall();
}
req.setAttribute("installer", installer);
RequestDispatcher rd = servletConfig.getServletContext().getRequestDispatcher("/index.jsp");
rd.forward(req,res);
}
}

View file

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
-->
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-distribution</artifactId>
<version>2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>tuscany-war</artifactId>
<name>Apache Tuscany SCA Tomcat Deep Integration WAR</name>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>org.codehaus.swizzle</groupId>
<artifactId>swizzle-stream</artifactId>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-tomcat-servlet</artifactId>
<version>2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-tomcat-hook</artifactId>
<version>2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-implementation-web-runtime</artifactId>
<version>2.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<finalName>tuscany</finalName>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>war</id>
<phase>package</phase>
<goals>
<goal>attached</goal>
</goals>
</execution>
</executions>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/main/assembly/war.xml</descriptor>
</descriptors>
</configuration>
</plugin>
</plugins>
</build>
</project>

View file

@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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.
-->
<assembly>
<id>war</id>
<formats>
<format>war</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${basedir}</directory>
<includes>
<include>README.txt</include>
</includes>
</fileSet>
<fileSet>
<directory>${basedir}/target/classes</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>README.txt</include>
<include>NOTICE.txt</include>
<include>LICENSE.txt</include>
</includes>
</fileSet>
<fileSet>
<directory>${basedir}/src/main/webapp</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
<fileSet>
<directory>${basedir}/target/classes</directory>
<outputDirectory>/</outputDirectory>
<excludes>
<exclude>org/**</exclude>
<exclude>META-INF/LICENSE</exclude>
<exclude>META-INF/NOTICE</exclude>
</excludes>
</fileSet>
<fileSet>
<directory>${basedir}/target/classes</directory>
<outputDirectory>WEB-INF/classes</outputDirectory>
</fileSet>
<fileSet>
<directory>${basedir}/target</directory>
<outputDirectory>lib</outputDirectory>
<includes>
<include>tuscany-host*.jar</include>
</includes>
</fileSet>
</fileSets>
<dependencySets>
<dependencySet>
<outputDirectory>tuscany-lib</outputDirectory>
<scope>runtime</scope>
<excludes>
<exclude>org.apache.tomcat:catalina</exclude>
<exclude>org.apache.tomcat:annotations-api</exclude>
<exclude>org.apache.tomcat:juli</exclude>
<exclude>org.apache.tomcat:servlet-api</exclude>
</excludes>
</dependencySet>
<dependencySet>
<outputDirectory>tomcat-lib</outputDirectory>
<scope>runtime</scope>
<includes>
<include>org.apache.tuscany.sca:tuscany-tomcat-hook</include>
</includes>
</dependencySet>
<dependencySet>
<outputDirectory>WEB-INF/lib</outputDirectory>
<scope>runtime</scope>
<includes>
<include>org.apache.tuscany.sca:tuscany-tomcat-servlet</include>
<include>org.codehaus.swizzle:swizzle-stream</include>
</includes>
</dependencySet>
</dependencySets>
</assembly>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,79 @@
Apache Tuscany
Copyright (c) 2005 - 2009 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
This product includes/uses the Axion : the Open Source Java Database (http://axion.tigris.org/)
Copyright (c) 2002-2003 Axion Development Team. All rights reserved.
This product includes/uses XmlSchema developed at
The Apache Software Foundation (http://ws.apache.org/commons/XmlSchema)
Portions Copyright 2006 International Business Machines Corp.
This product includes/uses the Jetty Servlet Engine (http://jetty.mortbay.org),
developed by Mort Bay Consulting (http://www.mortbay.com)
This product includes/uses DOM4J : the flexible XML framework for java (http://www.dom4j.org/)
Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
This product includes/uses software, AOP alliance (http://aopalliance.sourceforge.net)
License: Public Domain
This product includes/uses javacc (https://javacc.dev.java.net/)
Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
This product includes software from the GlassFish project (https://glassfish.dev.java.net/)
Copyright (c) 2006, Sun Microsystems, Inc.
This product includes/uses the Sourceforge wsdl4j project (http://sourceforge.net/projects/wsdl4j/)
This product includes/uses JDOM (http://www.jdom.org/)
Copyright (C) 2000-2004 Jason Hunter & Brett McLaughlin. All rights reserved.
This product includes/uses javacc (https://javacc.dev.java.net/)
Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
This product includes/uses ASM (http://asm.objectweb.org)
Copyright (c) 2000-2005 INRIA, France Telecom. All rights reserved.
This product includes/uses Jaxen (http://jaxen.codehaus.org/)
Copyright 2003-2006 The Werken Company. All Rights Reserved.
This product includes/uses Serp (http://serp.sourceforge.net/) under the BSD license:
Copyright (c) 2002, A. Abram White. All rights reserved.
This product also includes software under the BSD license
with the following copyright:
Copyright (c) 2006, Sun Microsystems, Inc. All rights reserved.
The Program includes all or portions of the following software: "The
Saxon XSLT and XQuery Processor from Saxonica Limited" distributed under
an MPL v1.0 license. Please refer to the homepage URL at
http://www.saxonica.com/.
This product includes/uses Serp (http://serp.sourceforge.net/) under the BSD license:
Copyright (c) 2002, A. Abram White. All rights reserved.
This product also includes "OSGi Materials."
Copyright (c) 2000, 2006
OSGi Alliance Bishop Ranch 6
2400 Camino Ramon, Suite 375
San Ramon, CA 94583 USA
All Rights Reserved.
This product includes software under the Service Component Architecture JavaDoc,
Interface Definition files and XSD files license.
(c) Copyright SCA Collaboration 2006, 2007
This product includes software under the Service Data Objects JavaDoc and
Interface Definition file license
(c) Copyright BEA Systems, Inc., International Business Machines Corporation,
Oracle Corporation, Primeton Technologies Ltd., Rogue Wave Software, SAP AG.,
Software AG., Sun Microsystems, Sybase Inc., Xcalia, Zend Technologies,
2005, 2006. All rights reserved.
This product includes software under the OASIS license
Copyright (C) OASIS(R) 2005, 2009. All Rights Reserved.

View file

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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.
-->
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>Tuscany Installer Application</display-name>
<servlet>
<servlet-name>InstallerServlet</servlet-name>
<servlet-class>org.apache.tuscany.sca.war.InstallerServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>InstallerServlet</servlet-name>
<url-pattern>/installer</url-pattern>
</servlet-mapping>
<welcome-file-list id="WelcomeFileList">
<welcome-file>installer.jsp</welcome-file>
</welcome-file-list>
</web-app>

View file

@ -0,0 +1,73 @@
<!--
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
-->
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="org.apache.tuscany.sca.war.Installer" %>
<%
Installer installer = (Installer) request.getAttribute("installer");
%>
<html>
<body >
<h2>Apache Tuscany Tomcat Integration</h2>
The Tuscany Tomcat integration turns Tomcat into an SCA enabled runtime so it can run SCA contributions and SCA-enabled Web Applications.
<p>
Status: Tuscany is <B>
<% if (Installer.isTuscanyHookRunning()) { %>
installed and active
<% } else if (Installer.isRestartRequired()) {%>
installed but Tomcat needs to be restarted
<% } else {%>
not installed
<% }%>
</B>
in Tomcat.
<p>
<% if (!Installer.isTuscanyHookRunning() && !Installer.isRestartRequired()) { %>
<B>Install Tuscany</B><BR>
To install Tuscany into Tomcat, click:
<form action='installer' method='post'>
<input type='submit' name='action' value='Install'>
</form>
<BR>
<% } else {%>
<B>Uninstall Tuscany</B><BR>
If remove Tuscany from Tomcat, click:
<form action='installer' method='post'>
<input type='submit' name='action' value='Uninstall'>
</form>
<BR>
<% }%>
<p>
<BR>
<B>
<% if (installer != null) { %>
<%= installer.getStatus() %>
<% }%>
</B>
</body>
</html>