Author: dain
Date: Wed Sep 12 16:20:23 2007
New Revision: 575118

URL: http://svn.apache.org/viewvc?rev=575118&view=rev
Log:
Basic installer is complete

Added:
    
openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/installer/Installer.java
    
openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/installer/Paths.java
Modified:
    
openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/installer/InstallerServlet.java
    openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/resources/index.html

Added: 
openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/installer/Installer.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/installer/Installer.java?rev=575118&view=auto
==============================================================================
--- 
openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/installer/Installer.java
 (added)
+++ 
openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/installer/Installer.java
 Wed Sep 12 16:20:23 2007
@@ -0,0 +1,424 @@
+/**
+ *
+ * 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.openejb.tomcat.installer;
+
+import org.codehaus.swizzle.stream.DelimitedTokenReplacementInputStream;
+import org.codehaus.swizzle.stream.StringTokenHandler;
+
+import java.io.ByteArrayInputStream;
+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.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+public class Installer {
+    public enum Status {
+        NONE, INSTALLED, REBOOT_REQUIRED
+    }
+
+    private final Paths paths;
+    private Status status = Status.NONE;
+
+    private final boolean listenerInstalled;
+    private final boolean annotationJarRemoved;
+    private final boolean agentInstalled;
+
+    // Thi may need to be redesigned but the goal is to provide some feedback 
on what happened
+    private final List<String> errors = new ArrayList<String>();
+    private final List<String> warnings = new ArrayList<String>();
+    private final List<String> infos = new ArrayList<String>();
+
+    public Installer(Paths paths) {
+        this.paths = paths;
+
+        // is the OpenEJB listener installed
+        Boolean listenerInstalled = (Boolean) 
invokeStaticNoArgMethod("org.apache.openejb.loader.OpenEJBListener", 
"isInstalled");
+        if (listenerInstalled == null) listenerInstalled = false;
+        this.listenerInstalled = listenerInstalled;
+
+        // has the annotation jar been removed
+        boolean annotationJarRemoved = false;
+        try {
+            // Tomcat persistence context class is missing the properties 
method
+            Class<?> persistenceContextClass = 
Class.forName("javax.persistence.PersistenceContext");
+            persistenceContextClass.getMethod("properties", (Class[]) null);
+            annotationJarRemoved = true;
+        } catch (Exception e) {
+        }
+        this.annotationJarRemoved = annotationJarRemoved;
+
+        // is the OpenEJB javaagent installed
+        agentInstalled = 
invokeStaticNoArgMethod("org.apache.openejb.javaagent.Agent", 
"getInstrumentation") != null;
+
+        if (listenerInstalled && annotationJarRemoved && agentInstalled) {
+            status = Status.INSTALLED;
+        }
+    }
+
+    public Status getStatus() {
+        return status;
+    }
+
+    protected void install() {
+        removeAnnotationJar();
+
+        installListener();
+
+        installJavaagent();
+
+        if (!hasErrors()) {
+            status = Status.REBOOT_REQUIRED;
+        }
+    }
+
+    private void removeAnnotationJar() {
+        if (annotationJarRemoved) {
+            addInfo("Annotation Jar already removed");
+            return;
+        }
+
+        File destination = new File(paths.getCatalinaLibDir(), 
"annotations-api.jar");
+
+        // if the file doesn't exist, there is nothing to do
+        if (!destination.exists()) {
+            return;
+        }
+
+        // attempt to delete the file
+        if (destination.delete()) {
+            addInfo("Deleted non-compliant (invalid) Tomcat annotation jar.");
+        } else {
+            // generally delete will fail on Windows
+            addWarning("Can not delete non-compliant (invalid) Tomcat 
annotation jar.  Jar havs been marked to be deleted on a normal VM exit.");
+        }
+    }
+
+    private void installListener() {
+        if (listenerInstalled) {
+            addInfo("OpenEJB Listener already installed");
+            return;
+        }
+
+        boolean copyOpenEJBLoader = true;
+
+        // copy loader jar to lib
+        File destination = new File(paths.getCatalinaLibDir(), 
paths.getOpenEJBLoaderJar().getName());
+        if (destination.exists()) {
+            if (paths.getOpenEJBLoaderJar().length() != destination.length()) {
+                // md5 diff the files
+            } else {
+                addInfo("OpenEJB loader jar already installed in Tomcat lib 
directory.");
+                copyOpenEJBLoader = false;
+            }
+        }
+
+        if (copyOpenEJBLoader) {
+            try {
+                copyFile(paths.getOpenEJBLoaderJar(), destination);
+                addInfo("Coppied " + paths.getOpenEJBLoaderJar().getName() + " 
to the Tomcat lib directory.");
+            } catch (IOException e) {
+                addError("Unable to copy OpenEJB loader jar to Tomcat lib 
directory.  This will need to be performed manually.", e);
+            }
+        }
+
+        // read server.xml
+        String serverXmlOriginal = readAll(paths.getServerXmlFile());
+
+        // server xml will be null if we couldn't read the file
+        if (serverXmlOriginal == null) {
+            return;
+        }
+
+        // does the server.xml contain our listener name... it is possible 
that they commented out our listener, but that would be a PITA to detect
+        if 
(serverXmlOriginal.contains("org.apache.openejb.loader.OpenEJBListener")) {
+            addInfo("OpenEJB Listener already declared in Tomcat server.xml 
file.");
+            return;
+        }
+
+        // if we can't backup the file, do not modify it
+        if (!backup(paths.getServerXmlFile())) {
+            return;
+        }
+
+        // add our listener
+        String newServerXml = null;
+        try {
+            newServerXml = replace(serverXmlOriginal,
+                    "<Server",
+                    "<Server",
+                    ">",
+                    ">\r\n" +
+                            "  <!-- OpenEJB plugin for Tomcat -->\r\n" +
+                            "  <Listener 
className=\"org.apache.openejb.loader.OpenEJBListener\" />");
+        } catch (IOException e) {
+            addError("Error while adding listener to server.xml file", e);
+        }
+
+        // overwrite server.xml
+        if (writeAll(paths.getServerXmlFile(), newServerXml)) {
+            addInfo("Added OpenEJB listener to Tomcat server.xml file.");
+        }
+
+        addInfo("Added OpenEJB listener to Tomcat server.xml file.");
+    }
+
+    private void installJavaagent() {
+        if (agentInstalled) {
+            addInfo("OpenEJB Agent already installed");
+            return;
+        }
+
+
+        // read the catalina sh file
+        String catalinaShOriginal = readAll(paths.getCatalinaShFile());
+
+        // catalina sh will be null if we couldn't read the file
+        if (catalinaShOriginal == null) {
+            return;
+        }
+
+        // does the catalina sh contain our comment... it is possible that 
they commented out the magic script code, but there is no way to detect that
+        if (catalinaShOriginal.contains("Add OpenEJB javaagent")) {
+            addInfo("OpenEJB javaagent already declared in Tomcat catalina.sh 
file.");
+            return;
+        }
+
+        // if we can't backup the file, do not modify it
+        if (!backup(paths.getCatalinaShFile())) {
+            return;
+        }
+
+        // add our magic bits to the catalina sh file
+        String openejbJavaagentPath = 
paths.getCatalinaBaseDir().toURI().relativize(paths.getOpenEJBJavaagentJar().toURI()).getPath();
+        String newCatalinaSh = catalinaShOriginal.replace("# ----- Execute The 
Requested Command",
+                "# Add OpenEJB javaagent\n" +
+                "if [ -r \"$CATALINA_BASE\"/" + openejbJavaagentPath + " ]; 
then\n" +
+                "  JAVA_OPTS=\"\"-javaagent:$CATALINA_BASE/" + 
openejbJavaagentPath + "\" $JAVA_OPTS\"\n" +
+                "fi\n" +
+                "\n" +
+                "# ----- Execute The Requested Command");
+
+        // overwrite the catalina.sh file
+        if (writeAll(paths.getCatalinaShFile(), newCatalinaSh)) {
+            addInfo("Added OpenEJB javaagent to Tomcat catalina.sh file.");
+        }
+    }
+
+    private String replace(String inputText, String begin, String newBegin, 
String end, String newEnd) throws IOException {
+        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) {
+        try {
+            File backupFile = new File(source.getParent(), source.getName() + 
".original");
+            if (!backupFile.exists()) {
+                copyFile(source, backupFile);
+            }
+            return true;
+        } catch (IOException e) {
+            addError("Unable to backup " + source.getAbsolutePath() + "; No 
changes will be made to this file");
+            return false;
+        }
+    }
+
+    private void copyFile(File source, File destination) throws IOException {
+        File destinationDir = destination.getParentFile();
+        if (!destinationDir.exists() && !destinationDir.mkdirs()) {
+            throw new java.io.IOException("Cannot create directory : " + 
destinationDir);
+        }
+
+        InputStream in = null;
+        OutputStream out = null;
+        try {
+            in = new FileInputStream(source);
+            out = new FileOutputStream(destination);
+            writeAll(in, out);
+        } 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) {
+            addError("Unable to write to " + file.getAbsolutePath(), 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 String readAll(File file) {
+        FileInputStream in = null;
+        try {
+            in = new FileInputStream(file);
+            String text = readAll(in);
+            return text;
+        } catch (Exception e) {
+            addError("Unable to read " + file.getAbsolutePath());
+            return null;
+        } finally {
+            close(in);
+        }
+    }
+
+    private String readAll(InputStream in) throws IOException {
+        // 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();
+    }
+
+//    private String getTomcatVersion() {
+//        String tomcatVersion = null;
+//        try {
+//            Properties properties = new Properties();
+//            
properties.load(getClass().getClassLoader().getResourceAsStream("org/apache/catalina/util/ServerInfo.properties"));
+//            tomcatVersion = properties.getProperty("server.number");
+//        } catch (IOException e) {
+//        }
+//        return tomcatVersion;
+//    }
+
+    private Object invokeStaticNoArgMethod(String className, String 
propertyName) {
+        try {
+            Class<?> clazz = loadClass(className, getClass().getClassLoader());
+            Method method = clazz.getMethod(propertyName);
+            Object result = method.invoke(null, (Object[]) null);
+            return result;
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    private Class<?> loadClass(String className, ClassLoader classLoader) 
throws ClassNotFoundException {
+        LinkedList<ClassLoader> loaders = new LinkedList<ClassLoader>();
+        for (ClassLoader loader = classLoader; loader != null; loader = 
loader.getParent()) {
+            loaders.addFirst(loader);
+        }
+        for (ClassLoader loader : loaders) {
+            try {
+                Class<?> clazz = Class.forName(className, true, loader);
+                return clazz;
+            } catch (ClassNotFoundException e) {
+            }
+        }
+        return null;
+    }
+
+    private void close(Closeable thing) {
+        if (thing != null) {
+            try {
+                thing.close();
+            } catch (Exception ignored) {
+            }
+        }
+    }
+
+    private static 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;
+        }
+    }
+
+    public boolean hasErrors() {
+        return !errors.isEmpty();
+    }
+
+
+    public List<String> getErrors() {
+        return errors;
+    }
+
+    private void addError(String message) {
+        errors.add(message);
+    }
+
+    private void addError(String message, Exception e) {
+        // todo add exception somehow
+        System.out.println(message);
+    }
+
+    public boolean hasWarnings() {
+        return !warnings.isEmpty();
+    }
+
+
+    public List<String> getWarnings() {
+        return warnings;
+    }
+
+    private void addWarning(String message) {
+        System.out.println(message);
+    }
+
+    public boolean hasInfos() {
+        return !infos.isEmpty();
+    }
+
+
+    public List<String> getInfos() {
+        return infos;
+    }
+
+    private void addInfo(String message) {
+        System.out.println(message);
+    }
+
+}

Modified: 
openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/installer/InstallerServlet.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/installer/InstallerServlet.java?rev=575118&r1=575117&r2=575118&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/installer/InstallerServlet.java
 (original)
+++ 
openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/installer/InstallerServlet.java
 Wed Sep 12 16:20:23 2007
@@ -17,28 +17,18 @@
  */
 package org.apache.openejb.tomcat.installer;
 
-import org.codehaus.swizzle.stream.DelimitedTokenReplacementInputStream;
-import org.codehaus.swizzle.stream.StringTokenHandler;
+import static org.apache.openejb.tomcat.installer.Installer.Status.INSTALLED;
+import static 
org.apache.openejb.tomcat.installer.Installer.Status.REBOOT_REQUIRED;
+import static org.apache.openejb.tomcat.installer.Installer.Status.NONE;
 
 import javax.servlet.ServletConfig;
-import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
 import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import java.io.ByteArrayInputStream;
-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.PrintStream;
-import java.lang.reflect.Method;
-import java.util.LinkedList;
-import java.util.Properties;
+import java.io.File;
 
 /**
  * Installs OpenEJB into Tomcat.
@@ -46,446 +36,126 @@
  * NOTE: This servlet can not use any classes from OpenEJB since it is 
installing OpenEJB itself.
  */
 public class InstallerServlet extends HttpServlet {
-    private ServletContext servletContext;
+    protected Paths paths;
+    protected Installer installer;
+    protected int attempts;
 
     public void init(ServletConfig servletConfig) throws ServletException {
-        servletContext = servletConfig.getServletContext();
+        paths = new Paths(servletConfig.getServletContext());
+        installer = new Installer(paths);
     }
 
-    protected void doGet(HttpServletRequest req, HttpServletResponse res) 
throws ServletException, IOException {
-        res.setContentType("text/plain");
-        ServletOutputStream out = res.getOutputStream();
-        out.println("Running Verifier...");
-
-        try {
-            boolean agentInstalled = 
invokeStaticNoArgMethod("org.apache.openejb.javaagent.Agent", 
"getInstrumentation") != null;
-
-            Boolean listenerInstalled = (Boolean) 
invokeStaticNoArgMethod("org.apache.openejb.loader.OpenEJBListener", 
"isInstalled");
-            if (listenerInstalled == null) listenerInstalled = false;
-
-            boolean annotationJarRemoved;
-            try {
-                // Tomcat persistence context class is missing the properties 
method
-                Class<?> persistenceContextClass = 
Class.forName("javax.persistence.PersistenceContext");
-                persistenceContextClass.getMethod("properties", (Class[]) 
null);
-                annotationJarRemoved = true;
-            } catch (Exception e) {
-                annotationJarRemoved = false;
-            }
-
-            out.println("Agent " + (agentInstalled ? "" : "NOT ") + 
"Installed");
-            out.println("Listener " + (listenerInstalled ? "" : "NOT ") + 
"Installed");
-            out.println("Annotation Jar " + (annotationJarRemoved ? "" : "NOT 
") + "Removed");
-
-            String tomcatVersion = getTomcatVersion();
-            out.println("TomcatVersion = " + tomcatVersion);
-
-            // find catalina home directory
-            String catalinaHome = System.getProperty("catalina.home");
-            out.println("catalina.home=" + catalinaHome);
-            File catalinaHomeDir = new File(catalinaHome);
-            if (!catalinaHomeDir.exists()) {
-                out.println("Catalina home does not exist");
-                return;
-            }
-            if (!catalinaHomeDir.isDirectory()) {
-                out.println("Catalina home does not a directory");
-                return;
-            }
-
-            // find catalina base directory
-            String catalinaBase = System.getProperty("catalina.base");
-            out.println("catalina.base=" + catalinaBase);
-            File catalinaBaseDir = new File(catalinaBase);
-            if (!catalinaBaseDir.exists()) {
-                out.println("Catalina base does not exist");
-                return;
-            }
-            if (!catalinaBaseDir.isDirectory()) {
-                out.println("Catalina base does not a directory");
-                return;
-            }
-
-            // find tomcat lib directory
-            File libDir = new File(catalinaHomeDir, "lib");
-            out.println("lib=" + libDir.getAbsolutePath());
-            if (!libDir.exists()) {
-                out.println("lib dir does not exist");
-                return;
-            }
-            if (!libDir.isDirectory()) {
-                out.println("lib dir is not a directory");
-                return;
-            }
-
-            // find tomcat conf directory
-            File confDir = new File(catalinaBaseDir, "conf");
-            out.println("conf=" + confDir.getAbsolutePath());
-            if (!confDir.exists()) {
-                out.println("conf dir does not exist");
-                return;
-            }
-            if (!confDir.isDirectory()) {
-                out.println("conf dir is not a directory");
-                return;
-            }
-
-            // find tomcat server.xml file
-            File serverXml = new File(confDir, "server.xml");
-            out.println("serverXml=" + serverXml.getAbsolutePath());
-            if (!serverXml.exists()) {
-                out.println("server.xml file does not exist");
-                return;
-            }
-            if (!serverXml.canWrite()) {
-                out.println("server.xml file is not writable");
-                return;
-            }
-            if (!serverXml.isFile()) {
-                out.println("server.xml file is not a file");
-                return;
-            }
-
-            // find the tomcat bin directory
-            File binDir = new File(catalinaHomeDir, "bin");
-            out.println("bin=" + binDir.getAbsolutePath());
-            if (!binDir.exists()) {
-                out.println("bin dir does not exist");
-                return;
-            }
-            if (!binDir.isDirectory()) {
-                out.println("bin dir is not a directory");
-                return;
-            }
+    protected void doGet(HttpServletRequest httpServletRequest, 
HttpServletResponse httpServletResponse) throws ServletException, IOException {
+        doIt(httpServletRequest, httpServletResponse);
+    }
 
-            // find tomcat catalina.sh file
-            File catalinaSh = new File(binDir, "catalina.sh");
-            out.println("catalinaSh=" + catalinaSh.getAbsolutePath());
-            if (!catalinaSh.exists()) {
-                out.println("catalina.sh file does not exist");
-                return;
-            }
-            if (!catalinaSh.canWrite()) {
-                out.println("catalina.sh file is not writable");
-                return;
-            }
-            if (!catalinaSh.isFile()) {
-                out.println("catalina.sh file is not a file");
-                return;
-            }
+    protected void doPost(HttpServletRequest httpServletRequest, 
HttpServletResponse httpServletResponse) throws ServletException, IOException {
+        doIt(httpServletRequest, httpServletResponse);
+    }
 
-            // find openejb lib dir
-            String openejbLib = servletContext.getRealPath("lib");
-            if (openejbLib == null) {
-                out.println("Can not find OpenEJB lib directory");
-                return;
-            }
-            File openejbLibDir = new File(openejbLib);
-            out.println("OpenEJB lib=" + openejbLibDir.getAbsolutePath());
-            if (!openejbLibDir.exists()) {
-                out.println("OpenEJB lib dir does not exist");
-                return;
-            }
-            if (!openejbLibDir.isDirectory()) {
-                out.println("OpenEJB lib dir is not a directory");
-                return;
-            }
+    protected void doIt(HttpServletRequest req, HttpServletResponse res) 
throws ServletException, IOException {
+        // if they clicked the install button...
+        if ("install".equals(req.getParameter("action"))) {
+            // If not already installed, try to install
+            if (installer.getStatus() == NONE) {
+                attempts++;
+                paths.setCatalinaHomeDir(req.getParameter("catalinaHome"));
+                paths.setCatalinaBaseDir(req.getParameter("catalinaBase"));
+                paths.setServerXmlFile(req.getParameter("serverXml"));
 
-            // find openejb-loader jar
-            File openejbLoaderJar = null;
-            for (File file : openejbLibDir.listFiles()) {
-                if (file.getName().startsWith("openejb-loader-") && 
file.getName().endsWith(".jar")) {
-                    openejbLoaderJar = file;
+                if (paths.verify()) {
+                    installer.install();
                 }
             }
-            if (openejbLoaderJar == null) {
-                out.println("Can not find OpenEJB loader jar");
-                return;
-            }
-            out.println("openejbLoaderJar=" + 
openejbLoaderJar.getAbsolutePath());
 
+            // send redirect to avoid double post lameness
+            res.sendRedirect(req.getRequestURI());
+        }
 
-            // find openejb-javaagent jar
-            File openejbJavaagentJar = null;
-            for (File file : openejbLibDir.listFiles()) {
-                if (file.getName().startsWith("openejb-javaagent-") && 
file.getName().endsWith(".jar")) {
-                    openejbJavaagentJar = file;
-                }
-            }
-            if (openejbJavaagentJar == null) {
-                out.println("Can not find OpenEJB javaagent jar");
-                return;
-            }
-            out.println("openejbJavaagentJar=" + 
openejbJavaagentJar.getAbsolutePath());
+        res.setHeader("Pragma", "No-cache");
+        res.setHeader("Cache-Control", "no-cache");
+        res.setDateHeader("Expires", 1);
+        res.setContentType("text/html");
 
-            String openejbJavaagentPath = 
catalinaBaseDir.toURI().relativize(openejbJavaagentJar.toURI()).getPath();
-            out.println("openejbJavaagentPath=" + openejbJavaagentPath);
+        ServletOutputStream out = res.getOutputStream();
+        out.println("<html>");
+        out.println("<head>");
+        out.println("<meta HTTP-EQUIV='Pragma' content='no-cache'>");
+        out.println("<meta HTTP-EQUIV='Expires' content='-1'>");
+        out.println("<title>OpenEJB Installer for Tomcat</title>");
+        out.println("</head>");
+        out.println("<body>");
 
+        // Is OpenEJB already installed?
+        if (installer.getStatus() == INSTALLED) {
+            out.println("<h1>INSTALLATION SUCCESSFUL!</h1>");
+        } else if (installer.getStatus() == REBOOT_REQUIRED) {
+            out.println("<h1>Installation Complete.  REBOOT REQUIRED</h1>");
 
-            out.println();
-            if (annotationJarRemoved) {
-                out.println("Annotation Jar already removed");
-            } else {
-                // copy loader jar to lib
-                File destination = new File(libDir, "annotations-api.jar");
-                if (destination.exists()) {
-                    out.flush();
-
-                    if (destination.delete()) {
-                        out.println("Deleted non-compliant (invalid) Tomcat 
annotation jar.");
-                    } else {
-                        out.println("Can not delete non-compliant (invalid) 
Tomcat annotation jar.  Jar havs been marked to be deleted on a normal VM 
exit.");
-                    }
+            if (installer.hasWarnings()) {
+                out.println("<h3>Warnings:</h3>");
+                for (String warning : installer.getWarnings()) {
+                    out.println(warning + "<br>");
                 }
             }
-
-//            out.println();
-            if (listenerInstalled) {
-                out.println("OpenEJB Listener already installed");
-            } else {
-
-                boolean copyOpenEJBLoader = true;
-
-                // copy loader jar to lib
-                File destination = new File(libDir, 
openejbLoaderJar.getName());
-                if (destination.exists()) {
-                    out.flush();
-
-                    if (openejbLoaderJar.length() != destination.length()) {
-                        // md5 diff the files
-                    } else {
-                        out.println("OpenEJB loader jar already installed in 
Tomcat lib directory.");
-                        copyOpenEJBLoader = false;
-                    }
-                }
-
-                if (copyOpenEJBLoader) {
-                    copyFile(openejbLoaderJar, destination);
-                    out.println("Coppied " + openejbLoaderJar.getName() + " to 
the Tomcat lib directory.");
-                }
-
-                // add listener to server.xml
-                String serverXmlOriginal = readAll(serverXml);
-
-                // write backup
-                {
-                    File backupFile = new File(confDir, "server.xml.original");
-                    if (!backupFile.exists()) {
-                        FileOutputStream fileOutputStream = new 
FileOutputStream(backupFile);
-                        try {
-                            writeAll(new 
ByteArrayInputStream(serverXmlOriginal.getBytes()), fileOutputStream);
-                        } finally {
-                            close(fileOutputStream);
-                        }
-                    }
-                }
-
-//                out.println();
-//                out.println("====== ORIGINAL SERVER XML =====");
-//                out.println(serverXmlOriginal);
-
-                if 
(serverXmlOriginal.contains("org.apache.openejb.loader.OpenEJBListener")) {
-                    out.println("OpenEJB Listener already declared in Tomcat 
server.xml file.");
-                } else {
-                    String newServerXml = replace(serverXmlOriginal,
-                            "<Server",
-                            "<Server",
-                            ">",
-                            ">\r\n" +
-                                    "  <!-- OpenEJB plugin for Tomcat -->\r\n" 
+
-                                    "  <Listener 
className=\"org.apache.openejb.loader.OpenEJBListener\" />");
-
-//                out.println();
-//                out.println("====== NEW SERVER XML =====");
-//                out.println(newServerXml);
-
-                    // overwrite server.xml
-                    FileOutputStream fileOutputStream = new 
FileOutputStream(serverXml);
-                    try {
-                        writeAll(new 
ByteArrayInputStream(newServerXml.getBytes()), fileOutputStream);
-                    } finally {
-                        close(fileOutputStream);
-                    }
-
-                    out.println("Added OpenEJB listener to Tomcat server.xml 
file.");
+            if (installer.hasInfos()) {
+                out.println("<h3>Info:</h3>");
+                for (String info : installer.getInfos()) {
+                    out.println(info + "<br>");
                 }
             }
+        } else {
+            // Not installed
 
-//            out.println();
-            if (agentInstalled) {
-                out.println("OpenEJB Agent already installed");
-            } else {
-
-                // add agent to catalina.sh
-                String catalinaShOriginal = readAll(catalinaSh);
-
-                // write backup
-                {
-                    File backupFile = new File(binDir, "catalina.sh.original");
-                    if (!backupFile.exists()) {
-                        FileOutputStream fileOutputStream = new 
FileOutputStream(backupFile);
-                        try {
-                            writeAll(new 
ByteArrayInputStream(catalinaShOriginal.getBytes()), fileOutputStream);
-                        } finally {
-                            close(fileOutputStream);
-                        }
-                    }
+            // Did an installation fail?
+            if (paths.hasErrors()) {
+                out.println("<h1>Installation Failed</h1>");
+                for (String error : paths.getErrors()) {
+                    out.println(error + "<br>");
                 }
-
-//                out.println();
-//                out.println("====== ORIGINAL CATALINA SH =====");
-//                out.println(catalinaShOriginal);
-
-                if (catalinaShOriginal.contains("Add OpenEJB javaagent")) {
-                    out.println("OpenEJB javaagent already declared in Tomcat 
catalina.sh file.");
-                } else {
-                    String newCatalinaSh = catalinaShOriginal.replace("# ----- 
Execute The Requested Command",
-                            "# Add OpenEJB javaagent\n" +
-                            "if [ -r \"$CATALINA_BASE\"/" + 
openejbJavaagentPath + " ]; then\n" +
-                            "  JAVA_OPTS=\"\"-javaagent:$CATALINA_BASE/" + 
openejbJavaagentPath + "\" $JAVA_OPTS\"\n" +
-                            "fi\n" +
-                            "\n" +
-                            "# ----- Execute The Requested Command");
-//                    out.println();
-//                    out.println("====== NEW CATALINA SH =====");
-//                    out.println(newServerXml);
-
-                    // overwrite server.xml
-                    FileOutputStream fileOutputStream = new 
FileOutputStream(catalinaSh);
-                    try {
-                        writeAll(new 
ByteArrayInputStream(newCatalinaSh.getBytes()), fileOutputStream);
-                    } finally {
-                        close(fileOutputStream);
-                    }
-
-                    out.println("Added OpenEJB javaagent to Tomcat catalina.sh 
file.");
+            } else if (installer.hasErrors()) {
+                out.println("<h1>Installation Failed</h1>");
+                for (String error : installer.getErrors()) {
+                    out.println(error + "<br>");
                 }
             }
 
-        } catch (Throwable e) {
-            PrintStream printStream = new PrintStream(out, true);
-            e.printStackTrace(printStream);
-            printStream.flush();
-        }
-    }
-
-    private String replace(String inputText, String begin, String newBegin, 
String end, String newEnd) throws IOException {
-        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 void copyFile(File source, File destination) throws IOException {
-        File destinationDir = destination.getParentFile();
-        if (!destinationDir.exists() && !destinationDir.mkdirs()) {
-            throw new java.io.IOException("Cannot create directory : " + 
destinationDir);
+            // write the for either way
+            writeInstallerForm(req, out);
         }
 
-        InputStream in = null;
-        OutputStream out = null;
-        try {
-            in = new FileInputStream(source);
-            out = new FileOutputStream(destination);
-            writeAll(in, out);
-        } finally {
-            close(in);
-            close(out);
-        }
+        out.println("</body>");
+        out.println("</html>");
     }
 
-    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);
+    private void writeInstallerForm(HttpServletRequest req, 
ServletOutputStream out) throws IOException {
+        // if we have tried once (and failed) add more text
+        if (attempts > 0) {
+            out.println("<h1>Try Again?</h1>");
         }
-        out.flush();
-    }
 
-    private String readAll(File file) throws IOException {
-        FileInputStream in = new FileInputStream(file);
-        try {
-            String text = readAll(in);
-            return text;
-        } finally {
-            close(in);
-        }
-    }
+        out.println("<form action='" + req.getRequestURI() + "' 
method='post'>");
 
-    private String readAll(InputStream in) throws IOException {
-        // 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();
-    }
+        out.println("Catalina Home:");
+        out.println("<input type='text' size='100' name='catalinaHome' 
value='" + safeGetAbsolutePath(paths.getCatalinaHomeDir()) + "'>");
+        out.println("<br>");
 
-    private String getTomcatVersion() {
-        String tomcatVersion = null;
-        try {
-            Properties properties = new Properties();
-            
properties.load(getClass().getClassLoader().getResourceAsStream("org/apache/catalina/util/ServerInfo.properties"));
-            tomcatVersion = properties.getProperty("server.number");
-        } catch (IOException e) {
-        }
-        return tomcatVersion;
-    }
+        out.println("Catalina Base:");
+        out.println("<input type='text' size='100' name='catalinaBase' 
value='" + safeGetAbsolutePath(paths.getCatalinaBaseDir()) + "'>");
+        out.println("<br>");
 
-    private Object invokeStaticNoArgMethod(String className, String 
propertyName) {
-        try {
-            Class<?> clazz = loadClass(className, getClass().getClassLoader());
-            Method method = clazz.getMethod(propertyName);
-            Object result = method.invoke(null, (Object[]) null);
-            return result;
-        } catch (Exception e) {
-            return null;
-        }
-    }
+        out.println("Catalina server.xml:");
+        out.println("<input type='text' size='100' name='serverXml' value='" + 
safeGetAbsolutePath(paths.getServerXmlFile()) + "'>");
+        out.println("<br>");
 
-    private Class<?> loadClass(String className, ClassLoader classLoader) 
throws ClassNotFoundException {
-        LinkedList<ClassLoader> loaders = new LinkedList<ClassLoader>();
-        for (ClassLoader loader = classLoader; loader != null; loader = 
loader.getParent()) {
-            loaders.addFirst(loader);
-        }
-        for (ClassLoader loader : loaders) {
-            try {
-                Class<?> clazz = Class.forName(className, true, loader);
-                return clazz;
-            } catch (ClassNotFoundException e) {
-            }
-        }
-        return null;
-    }
+        out.println("<input type='submit' name='action' value='install'>");
+        
+        out.println("</form>");
 
-    private void close(Closeable thing) {
-        if (thing != null) {
-            try {
-                thing.close();
-            } catch (Exception ignored) {
-            }
-        }
     }
 
-    private static 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;
-        }
+    private String safeGetAbsolutePath(File file) {
+        if (file == null) return "";
+        return file.getAbsolutePath();
     }
 }

Added: 
openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/installer/Paths.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/installer/Paths.java?rev=575118&view=auto
==============================================================================
--- 
openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/installer/Paths.java
 (added)
+++ 
openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/installer/Paths.java
 Wed Sep 12 16:20:23 2007
@@ -0,0 +1,278 @@
+/**
+ *
+ * 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.openejb.tomcat.installer;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class Paths {
+    private final ServletContext servletContext;
+    private final List<String> errors = new ArrayList<String>();
+    private File catalinaHomeDir;
+    private File catalinaBaseDir;
+    private File serverXmlFile;
+
+    public Paths(ServletContext servletContext) {
+        this.servletContext = servletContext;
+    }
+
+    public File getCatalinaHomeDir() {
+        if (catalinaHomeDir == null) {
+            String catalinaHome = System.getProperty("catalina.home");
+            if (catalinaHome != null) {
+                catalinaHomeDir = new File(catalinaHome);
+            }
+        }
+        return catalinaHomeDir;
+    }
+
+    public void setCatalinaHomeDir(String catalinaHomeDir) {
+        this.catalinaHomeDir = createFile(catalinaHomeDir);
+    }
+
+    public void setCatalinaHomeDir(File catalinaHomeDir) {
+        this.catalinaHomeDir = catalinaHomeDir;
+    }
+
+    public File getCatalinaBaseDir() {
+        if (catalinaBaseDir == null) {
+            String catalinaBase = System.getProperty("catalina.base");
+            if (catalinaBase != null) {
+                catalinaBaseDir = new File(catalinaBase);
+            }
+        }
+        return catalinaBaseDir;
+    }
+
+    public void setCatalinaBaseDir(String catalinaBaseDir) {
+        this.catalinaBaseDir = createFile(catalinaBaseDir);
+    }
+
+    public void setCatalinaBaseDir(File catalinaBaseDir) {
+        this.catalinaBaseDir = catalinaBaseDir;
+    }
+
+    public File getServerXmlFile() {
+        if (serverXmlFile == null) {
+            File catalinaBaseDir = getCatalinaBaseDir();
+            if (catalinaBaseDir == null) return null;
+
+            File catalinaConfDir = new File(catalinaBaseDir, "conf");
+            serverXmlFile = new File(catalinaConfDir, "server.xml");
+        }
+        return serverXmlFile;
+    }
+
+    public void setServerXmlFile(String serverXmlFile) {
+        this.serverXmlFile = createFile(serverXmlFile);
+    }
+
+    public void setServerXmlFile(File serverXmlFile) {
+        this.serverXmlFile = serverXmlFile;
+    }
+
+    public File getCatalinaLibDir() {
+        File catalinaHomeDir = getCatalinaHomeDir();
+
+        if (catalinaHomeDir == null) return null;
+
+        return new File(catalinaHomeDir, "lib");
+    }
+
+    public File getCatalinaBinDir() {
+        File catalinaHomeDir = getCatalinaHomeDir();
+
+        if (catalinaHomeDir == null) return null;
+
+        return new File(catalinaHomeDir, "bin");
+    }
+
+    public File getCatalinaShFile() {
+        File binDir = getCatalinaBinDir();
+
+        if (binDir == null) return null;
+
+        return new File(binDir, "catalina.sh");
+    }
+
+    public File getOpenEJBLibDir() {
+        if (servletContext == null) return null;
+
+        return new File(servletContext.getRealPath("lib"));
+    }
+
+    public File getOpenEJBLoaderJar() {
+        return findOpenEJBJar("openejb-loader");
+    }
+
+    public File getOpenEJBJavaagentJar() {
+        return findOpenEJBJar("openejb-javaagent");
+    }
+
+    private File findOpenEJBJar(String namePrefix) {
+        File openEJBLibDir = getOpenEJBLibDir();
+        if (openEJBLibDir == null) return null;
+
+        File openejbLoaderJar = null;
+        for (File file : openEJBLibDir.listFiles()) {
+            if (file.getName().startsWith(namePrefix + "-") && 
file.getName().endsWith(".jar")) {
+                return file;
+            }
+        }
+
+        return openejbLoaderJar;
+    }
+
+    public boolean verify() {
+        if (getCatalinaHomeDir() == null) {
+            addError("Catalina home directory is not defined");
+        }
+        if (getCatalinaBaseDir() == null) {
+            addError("Catalina base directory is not defined");
+        }
+
+        verifyDirectory("Catalina home", getCatalinaHomeDir());
+        verifyDirectory("Catalina base", getCatalinaBaseDir());
+
+        // if catalina home or base has errors, just give up
+        if (hasErrors()) {
+            return false;
+        }
+
+        verifyWritableDirectory("Catalina lib", getCatalinaLibDir());
+        verifyDirectory("Catalina bin", getCatalinaBinDir());
+        verifyWritableFile("Catalina server.xml", getServerXmlFile());
+        verifyWritableFile("Catalina catalina.sh", getCatalinaShFile());
+
+        verifyDirectory("OpenEJB lib", getOpenEJBLibDir());
+
+        File openejbLoaderJar = getOpenEJBLoaderJar();
+        if (openejbLoaderJar == null) {
+            addError("OpenEJB loader jar was not found in the OpenEJB lib 
dir");
+        }
+        verifyFile("OpenEJB loader jar", openejbLoaderJar);
+
+        File openejbJavaagentJar = getOpenEJBJavaagentJar();
+        if (openejbJavaagentJar == null) {
+            addError("OpenEJB javaagent jar was not found in the OpenEJB lib 
dir");
+        }
+        verifyFile("OpenEJB javaagent jar", openejbJavaagentJar);
+
+        return !hasErrors();
+    }
+
+    public boolean hasErrors() {
+        return !errors.isEmpty();
+    }
+
+
+    public List<String> getErrors() {
+        return errors;
+    }
+
+    private void addError(String message) {
+        System.out.println(message);
+    }
+
+    private void verifyDirectory(String description, File file) {
+        if (file == null) {
+            // ignore... files are built up based on other files, and probles
+            // with the root files will have been logged else where
+            return;
+        }
+        if (!file.exists()) {
+            addError(description + " directory does not exist");
+            return;
+        }
+        if (!file.isDirectory()) {
+            addError(description + " directory is not a directory");
+            return;
+        }
+        if (!file.canRead()) {
+            addError(description + " directory is not readable");
+        }
+    }
+
+    private void verifyWritableDirectory(String description, File file) {
+        verifyDirectory(description, file);
+        verifyWritable(description, file);
+    }
+
+    private void verifyFile(String description, File file) {
+        if (file == null) {
+            // ignore... files are built up based on other files, and probles
+            // with the root files will have been logged else where
+            return;
+        }
+        if (!file.exists()) {
+            addError(description + " file does not exist");
+            return;
+        }
+        if (!file.isFile()) {
+            addError(description + " file is not a file");
+            return;
+        }
+        if (!file.canRead()) {
+            addError(description + " file is not readable");
+        }
+    }
+
+    private void verifyWritableFile(String description, File file) {
+        verifyFile(description, file);
+        verifyWritable(description, file);
+    }
+
+    private void verifyWritable(String description, File file) {
+        if (file == null) {
+            // ignore... files are built up based on other files, and probles
+            // with the root files will have been logged else where
+            return;
+        }
+        if (!file.canWrite()) {
+            addError(description + " file is not writable");
+        }
+    }
+
+    private File createFile(String catalinaHomeDir) {
+        if (catalinaHomeDir != null && catalinaHomeDir.trim().length() > 0) {
+            return new File(catalinaHomeDir.trim());
+        }
+        return null;
+    }
+
+    public void dump(ServletOutputStream out) throws IOException {
+        printFile(out, "Catalina home: ", getCatalinaHomeDir());
+        printFile(out, "Catalina base: ", getCatalinaBaseDir());
+        printFile(out, "Catalina server.xml: ", getServerXmlFile());
+        printFile(out, "Catalina lib: ", getCatalinaLibDir());
+        printFile(out, "Catalina bin: ", getCatalinaBinDir());
+        printFile(out, "Catalina catalina.sh: ", getCatalinaShFile());
+        printFile(out, "OpenEJB lib: ", getOpenEJBLibDir());
+        printFile(out, "OpenEJB loader jar: ", getOpenEJBLoaderJar());
+        printFile(out, "OpenEJB javaagent jar: ", getOpenEJBJavaagentJar());
+    }
+
+    private void printFile(ServletOutputStream out, String description, File 
file) throws IOException {
+        out.println(description + ":");
+        out.println("    " + file);
+    }
+}

Modified: 
openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/resources/index.html
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/resources/index.html?rev=575118&r1=575117&r2=575118&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/resources/index.html 
(original)
+++ 
openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/resources/index.html 
Wed Sep 12 16:20:23 2007
@@ -1,5 +1,6 @@
 <html>
 <body>
 <h1>Welcome to OpenEJB</h1>
+Click <a href="installer">HERE</a> to install OpenEJB into Tomcat.
 </body>
 </html>


Reply via email to