diff options
Diffstat (limited to 'sca-java-2.x/branches/sca-java-2.0-M4/distribution/tomcat/tomcat-servlet/src/main/java')
3 files changed, 462 insertions, 0 deletions
diff --git a/sca-java-2.x/branches/sca-java-2.0-M4/distribution/tomcat/tomcat-servlet/src/main/java/org/apache/tuscany/sca/tomcat/foo/TuscanyTomcatNode.java b/sca-java-2.x/branches/sca-java-2.0-M4/distribution/tomcat/tomcat-servlet/src/main/java/org/apache/tuscany/sca/tomcat/foo/TuscanyTomcatNode.java new file mode 100644 index 0000000000..972aafd8b6 --- /dev/null +++ b/sca-java-2.x/branches/sca-java-2.0-M4/distribution/tomcat/tomcat-servlet/src/main/java/org/apache/tuscany/sca/tomcat/foo/TuscanyTomcatNode.java @@ -0,0 +1,74 @@ +/* + * 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.tomcat.foo; + +import java.io.File; +import java.net.MalformedURLException; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +import org.apache.tuscany.sca.node.Contribution; +import org.apache.tuscany.sca.node.Node; +import org.apache.tuscany.sca.node.NodeFactory; +import org.apache.tuscany.sca.war.Installer; + +public class TuscanyTomcatNode implements ServletContextListener { + + protected Node tomcatNode; + + public void contextInitialized(ServletContextEvent arg0) { + if (!Installer.isTuscanyHookRunning()) { + return; + } + + // TODO: this relys on the location of webapp folder, find way to get actual catalina base + File tomcatBase = new File(arg0.getServletContext().getRealPath("/")).getParentFile().getParentFile(); + + File contributionDir = new File(tomcatBase, "sca-contributions"); + if (!contributionDir.exists()) { + return; + } + File[] contributionFiles = contributionDir.listFiles(); + if (contributionFiles.length < 1) { + return; + } + + Contribution[] nodeContributions = new Contribution[contributionFiles.length]; + for (int i = 0; i<contributionFiles.length; i++) { + try { + nodeContributions[i] = + new Contribution(contributionFiles[i].getName(), contributionFiles[i].toURI().toURL().toString()); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + } + + tomcatNode = NodeFactory.newInstance().createNode(nodeContributions); + tomcatNode.start(); + } + + public void contextDestroyed(ServletContextEvent arg0) { + if (tomcatNode != null) { + tomcatNode.stop(); + } + } + +} diff --git a/sca-java-2.x/branches/sca-java-2.0-M4/distribution/tomcat/tomcat-servlet/src/main/java/org/apache/tuscany/sca/war/Installer.java b/sca-java-2.x/branches/sca-java-2.0-M4/distribution/tomcat/tomcat-servlet/src/main/java/org/apache/tuscany/sca/war/Installer.java new file mode 100644 index 0000000000..2251a2e833 --- /dev/null +++ b/sca-java-2.x/branches/sca-java-2.0-M4/distribution/tomcat/tomcat-servlet/src/main/java/org/apache/tuscany/sca/war/Installer.java @@ -0,0 +1,318 @@ +/* + * 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 java.util.Properties; + +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(boolean singleton) { + try { + + doInstall(singleton); + 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); + File propFile = new File(tuscanyWAR, "tuscany.properties"); + if (propFile.isFile()) { + propFile.delete(); + } + + } + + private boolean doInstall(boolean singleton) { + // 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())); + + if (singleton) { + try { + // Write out a property file + File propFile = new File(tuscanyWAR, "tuscany.properties"); + FileOutputStream os = new FileOutputStream(propFile); + Properties props = new Properties(); + props.put("singleton", "true"); + props.store(os, "Apache Tuscany properties for Tomcat"); + os.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + // 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; + } + } + +} diff --git a/sca-java-2.x/branches/sca-java-2.0-M4/distribution/tomcat/tomcat-servlet/src/main/java/org/apache/tuscany/sca/war/InstallerServlet.java b/sca-java-2.x/branches/sca-java-2.0-M4/distribution/tomcat/tomcat-servlet/src/main/java/org/apache/tuscany/sca/war/InstallerServlet.java new file mode 100644 index 0000000000..a7e5c7e3d7 --- /dev/null +++ b/sca-java-2.x/branches/sca-java-2.0-M4/distribution/tomcat/tomcat-servlet/src/main/java/org/apache/tuscany/sca/war/InstallerServlet.java @@ -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"))) { + String singleton = req.getParameter("singleton"); + installer.install(singleton!=null && singleton.equalsIgnoreCase("true")); + } else if ("Uninstall".equalsIgnoreCase(req.getParameter("action"))) { + installer.uninstall(); + } + + req.setAttribute("installer", installer); + RequestDispatcher rd = servletConfig.getServletContext().getRequestDispatcher("/installer.jsp"); + rd.forward(req,res); + } + +} |