summaryrefslogtreecommitdiffstats
path: root/sca-java-2.x/tags/2.0.1-RC1/distribution/tomcat/tomcat-servlet/src/main/java/org/apache/tuscany/sca/war/Installer.java
diff options
context:
space:
mode:
Diffstat (limited to 'sca-java-2.x/tags/2.0.1-RC1/distribution/tomcat/tomcat-servlet/src/main/java/org/apache/tuscany/sca/war/Installer.java')
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/distribution/tomcat/tomcat-servlet/src/main/java/org/apache/tuscany/sca/war/Installer.java374
1 files changed, 374 insertions, 0 deletions
diff --git a/sca-java-2.x/tags/2.0.1-RC1/distribution/tomcat/tomcat-servlet/src/main/java/org/apache/tuscany/sca/war/Installer.java b/sca-java-2.x/tags/2.0.1-RC1/distribution/tomcat/tomcat-servlet/src/main/java/org/apache/tuscany/sca/war/Installer.java
new file mode 100644
index 0000000000..59fecbf8f7
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/distribution/tomcat/tomcat-servlet/src/main/java/org/apache/tuscany/sca/war/Installer.java
@@ -0,0 +1,374 @@
+/*
+ * 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);
+ removeHostConfigXml(serverXml);
+ removeContextXml();
+ }
+
+ 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())) {
+ // try Tomcat 5 server/lib
+ if (new File(catalinaBase, "/server").exists()) {
+ serverLib = new File(new File(catalinaBase, "/server"), "/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);
+
+ // Add Tuscany HostConfig to Hosts definitions in server.xml
+ updateHostConfigXml(serverXml);
+
+ // Add Tuscany specific default web.xml and context.xml definitions
+ addTuscanyWebXml();
+ addTuscanyContextXml();
+
+ return true;
+ }
+
+ private static final String tuscanyWebXML =
+ "\r\n\r\n" + " <!-- Tuscany Listener and Filter definitions -->\r\n" +
+ " <listener>\r\n" +
+ " <listener-class>org.apache.tuscany.sca.host.webapp.TuscanyContextListener</listener-class>\r\n" +
+ " </listener>\r\n" +
+ "\r\n" +
+ " <filter>\r\n" +
+ " <filter-name>tuscany</filter-name>\r\n" +
+ " <filter-class>org.apache.tuscany.sca.host.webapp.TuscanyServletFilter</filter-class>\r\n" +
+ " </filter>\r\n" +
+ "\r\n" +
+ " <filter-mapping>\r\n" +
+ " <filter-name>tuscany</filter-name>\r\n" +
+ " <url-pattern>/*</url-pattern>\r\n" +
+ " </filter-mapping>";
+
+ private void addTuscanyWebXml() {
+ File tuscanyWebXmlFile = new File(catalinaBase, "/conf/tuscany-web.xml");
+ if (!(tuscanyWebXmlFile.exists())) {
+ File webXmlFile = new File(catalinaBase, "/conf/web.xml");
+ if (!(webXmlFile.exists())) {
+ throw new IllegalStateException("conf/web.xml not found: " + webXmlFile.getAbsolutePath());
+ }
+ String webXML = readAll(webXmlFile);
+ String newWebXml = replace(webXML, "<web-app", "<web-app", ">", ">" + tuscanyWebXML);
+ writeAll(tuscanyWebXmlFile, newWebXml);
+ }
+ }
+
+ private static final String tuscanyContextXML =
+ "\r\n\r\n <!-- The Tuscany SCA default domain URI.\r\n" +
+ " Individual contributions may used different domains by having their \r\n" +
+ " context.xml files overriding this parameter. -->\r\n" +
+ " <Parameter name=\"org.apache.tuscany.sca.defaultDomainURI\" value=\"default\"/>";
+
+ private void addTuscanyContextXml() {
+ File contextXmlFile = new File(catalinaBase, "/conf/context.xml");
+ if ((contextXmlFile.exists())) {
+ String contextXML = readAll(contextXmlFile);
+ String newcontextXml = replace(contextXML, "<Context>", "<Context>" + tuscanyContextXML, "<", "<");
+ backup(contextXmlFile);
+ writeAll(contextXmlFile, newcontextXml);
+ }
+ }
+ private void removeContextXml() {
+ File contextXmlFile = new File(catalinaBase, "/conf/context.xml");
+ if ((contextXmlFile.exists())) {
+ String contextXML = readAll(contextXmlFile);
+ String oldContextXml = replace(contextXML, "<Context>" + tuscanyContextXML, "<Context>", "<", "<");
+ writeAll(contextXmlFile, oldContextXml);
+ }
+ }
+
+ 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;
+ }
+
+ private 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);
+ }
+ }
+
+ static final String tuscanyHostConfig = " hostConfigClass=\"org.apache.tuscany.sca.tomcat.TuscanyHostConfig\" >";
+
+ private void updateHostConfigXml(File serverXmlFile) {
+ String serverXML = readAll(serverXmlFile);
+ String newServerXml = replace(serverXML, "<Host", "<Host", ">", tuscanyHostConfig);
+ backup(serverXmlFile);
+ writeAll(serverXmlFile, newServerXml);
+ }
+
+ private void removeHostConfigXml(File serverXmlFile) {
+ String serverXML = readAll(serverXmlFile);
+ if (serverXML.contains(tuscanyHostConfig)) {
+ String newServerXml = replace(serverXML, "<Host", "<Host", tuscanyHostConfig, ">");
+ 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;
+ }
+ }
+
+}