You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by db...@apache.org on 2007/08/03 07:22:00 UTC

svn commit: r562334 [3/8] - in /openejb/trunk/openejb3/server: ./ openejb-webadmin/ openejb-webadmin/src/ openejb-webadmin/src/main/ openejb-webadmin/src/main/etc/ openejb-webadmin/src/main/java/ openejb-webadmin/src/main/java/org/ openejb-webadmin/src...

Added: openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/httpd/HttpRequestImpl.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/httpd/HttpRequestImpl.java?view=auto&rev=562334
==============================================================================
--- openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/httpd/HttpRequestImpl.java (added)
+++ openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/httpd/HttpRequestImpl.java Thu Aug  2 22:21:56 2007
@@ -0,0 +1,680 @@
+/** 
+ * Redistribution and use of this software and associated documentation
+ * ("Software"), with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain copyright
+ *    statements and notices.  Redistributions must also contain a
+ *    copy of this document.
+ *
+ * 2. Redistributions in binary form must reproduce the
+ *    above copyright notice, this list of conditions and the
+ *    following disclaimer in the documentation and/or other
+ *    materials provided with the distribution.
+ *
+ * 3. The name "OpenEJB" must not be used to endorse or promote
+ *    products derived from this Software without prior written
+ *    permission of The OpenEJB Group.  For written permission,
+ *    please contact dev@openejb.org.
+ *
+ * 4. Products derived from this Software may not be called "OpenEJB"
+ *    nor may "OpenEJB" appear in their names without prior written
+ *    permission of The OpenEJB Group. OpenEJB is a registered
+ *    trademark of The OpenEJB Group.
+ *
+ * 5. Due credit should be given to the OpenEJB Project
+ *    (http://www.openejb.org/).
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OPENEJB GROUP AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE OPENEJB GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Copyright 2001 (C) The OpenEJB Group. All Rights Reserved.
+ *
+ * $Id: HttpRequestImpl.java 445460 2005-06-16 22:29:56Z jlaskowski $
+ */
+package org.apache.openejb.webadmin.httpd;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.rmi.RemoteException;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.apache.commons.fileupload.MultipartStream;
+import org.apache.openejb.webadmin.HttpRequest;
+import org.apache.openejb.webadmin.HttpSession;
+import org.apache.openejb.core.stateful.StatefulEjbObjectHandler;
+import org.apache.openejb.loader.FileUtils;
+
+/** A class to take care of HTTP Requests.  It parses headers, content, form and url
+ * parameters.
+ * @author <a href="mailto:david.blevins@visi.com">David Blevins</a>
+ * @author <a href="mailto:tim_urberg@yahoo.com">Tim Urberg</a>
+ */
+public class HttpRequestImpl implements HttpRequest {
+    public static final String FORM_URL_ENCODED = "application/x-www-form-urlencoded";
+    public static final String MULITPART_FORM_DATA = "multipart/form-data";
+    public static final String FILENAME = "filename";
+    public static final String NAME = "name";
+
+    /** 5.1   Request-Line */
+    private String line;
+    /** 5.1.1    Method */
+    private int method;
+    /** 5.1.2    Request-URI */
+    private URL uri;
+    /** the headers for this page */
+    private HashMap headers;
+    /** the form parameters for this page */
+    private HashMap formParams = new HashMap();
+    /** the URL (or query) parameters for this page */
+    private HashMap queryParams = new HashMap();
+    /** the content of the body of this page */
+    private byte[] body;
+    private String[][] formParamsArray;
+
+
+    private String methodString;
+    private String pathString;
+
+
+    /**
+     * @return Returns the methodString.
+     */
+    public String getMethodString() {
+        return methodString;
+    }
+
+    /**
+     * @return Returns the pathString.
+     */
+    public String getPathString() {
+        return pathString;
+    }
+
+    /** Gets a header based the header name passed in.
+     * @param name The name of the header to get
+     * @return The value of the header
+     */
+    public String getHeader(String name) {
+        return (String) headers.get(name);
+    }
+
+    /** Gets a form parameter based on the name passed in.
+     * @param name The name of the form parameter to get
+     * @return The value of the parameter
+     */
+    public String getFormParameter(String name) {
+        return (String) formParams.get(name);
+    }
+
+    /** Gets all the form parameters in the form of a two-dimentional array
+     *  The second dimention has two indexes which contain the key and value
+     *  for example:
+     *  <code>
+     *  for(int i=0; i<formParams.length; i++) {
+     *     key = formParams[i][0];
+     *     value = formParams[i][1];
+     *  }
+     *  </code>
+     *
+     *  All values are strings
+     * @return All the form parameters
+     */
+    public String[][] getFormParameters() {
+        Iterator keys = formParams.keySet().iterator();
+        String[][] returnValue = new String[formParams.size()][2];
+
+        String temp;
+        int i = 0;
+        while (keys.hasNext()) {
+            temp = (String) keys.next();
+            returnValue[i][0] = temp;
+            returnValue[i++][1] = (String) formParams.get(temp);
+        }
+
+        return returnValue;
+    }
+
+    /** Gets a URL (or query) parameter based on the name passed in.
+     * @param name The name of the URL (or query) parameter
+     * @return The value of the URL (or query) parameter
+     */
+    public String getQueryParameter(String name) {
+        return (String) queryParams.get(name);
+    }
+
+    /** Gets an integer value of the request method.  These values are:
+     *
+     * OPTIONS = 0
+     * GET     = 1
+     * HEAD    = 2
+     * POST    = 3
+     * PUT     = 4
+     * DELETE  = 5
+     * TRACE   = 6
+     * CONNECT = 7
+     * UNSUPPORTED = 8
+     * @return The integer value of the method
+     */
+    public int getMethod() {
+        return method;
+    }
+
+    /** Gets the URI for the current URL page.
+     * @return The URI
+     */
+    public URL getURI() {
+        return uri;
+    }
+
+    /*------------------------------------------------------------*/
+    /*  Methods for reading in and parsing a request              */
+    /*------------------------------------------------------------*/
+    /** parses the request into the 3 different parts, request, headers, and body
+     * @param input the data input for this page
+     * @throws IOException if an exception is thrown
+     */
+    protected void readMessage(InputStream input) throws IOException {
+        DataInput in = new DataInputStream(input);
+
+        readRequestLine(in);
+        readHeaders(in);
+        readBody(in);
+    }
+
+    private String requestLine;
+
+    protected String getRequestLine(){
+        return requestLine;
+    }
+    /** reads and parses the request line
+     * @param in the input to be read
+     * @throws IOException if an exception is thrown
+     */
+    private void readRequestLine(DataInput in) throws IOException {
+
+        try {
+            line = in.readLine();
+            requestLine = line;
+//            System.out.println(line);
+        } catch (Exception e) {
+            throw new IOException(
+                "Could not read the HTTP Request Line :"
+                    + e.getClass().getName()
+                    + " : "
+                    + e.getMessage());
+        }
+
+        StringTokenizer lineParts = new StringTokenizer(line, " ");
+        /* [1] Parse the method */
+        parseMethod(lineParts);
+        /* [2] Parse the URI */
+        parseURI(lineParts);
+    }
+
+    /** parses the method for this page
+     * @param lineParts a StringTokenizer of the request line
+     * @throws IOException if an exeption is thrown
+     */
+    private void parseMethod(StringTokenizer lineParts) throws IOException {
+        String token = null;
+        try {
+            token = lineParts.nextToken();
+        } catch (Exception e) {
+            throw new IOException(
+                "Could not parse the HTTP Request Method :"
+                    + e.getClass().getName()
+                    + " : "
+                    + e.getMessage());
+        }
+
+        if (token.equalsIgnoreCase("GET")) {
+            method = GET;
+        } else if (token.equalsIgnoreCase("POST")) {
+            method = POST;
+        } else {
+            method = UNSUPPORTED;
+            throw new IOException("Unsupported HTTP Request Method :" + token);
+        }
+    }
+
+    /** parses the URI into the different parts
+     * @param lineParts a StringTokenizer of the URI
+     * @throws IOException if an exeption is thrown
+     */
+    private void parseURI(StringTokenizer lineParts) throws IOException {
+        String token = null;
+        try {
+            token = lineParts.nextToken();
+        } catch (Exception e) {
+            throw new IOException(
+                "Could not parse the HTTP Request Method :"
+                    + e.getClass().getName()
+                    + " : "
+                    + e.getMessage());
+        }
+
+        try {
+            uri = new URL("http", "localhost", token);
+        } catch (java.net.MalformedURLException e) {
+            throw new IOException("Malformed URL :" + token + " Exception: " + e.getMessage());
+        }
+
+        parseQueryParams(uri.getQuery());
+    }
+
+    /** parses the URL (or query) parameters
+     * @param query the URL (or query) parameters to be parsed
+     * @throws IOException if an exception is thrown
+     */
+    private void parseQueryParams(String query) throws IOException {
+        if (query == null)
+            return;
+        StringTokenizer parameters = new StringTokenizer(query, "&");
+
+        while (parameters.hasMoreTokens()) {
+            StringTokenizer param = new StringTokenizer(parameters.nextToken(), "=");
+
+            /* [1] Parse the Name */
+            if (!param.hasMoreTokens())
+                continue;
+            String name = URLDecoder.decode(param.nextToken());
+            if (name == null)
+                continue;
+
+            /* [2] Parse the Value */
+            if (!param.hasMoreTokens())
+                continue;
+            String value = URLDecoder.decode(param.nextToken());
+            if (value == null)
+                continue;
+
+            //System.out.println("[] "+name+" = "+value);
+            queryParams.put(name, value);
+        }
+    }
+
+    /** reads the headers from the data input sent from the browser
+     * @param in the data input sent from the browser
+     * @throws IOException if an exeption is thrown
+     */
+    private void readHeaders(DataInput in) throws IOException {
+//        System.out.println("\nREQUEST");
+        headers = new HashMap();
+        while (true) {
+            // Header Field
+            String hf = null;
+
+            try {
+                hf = in.readLine();
+                //System.out.println(hf);
+            } catch (Exception e) {
+                throw new IOException(
+                    "Could not read the HTTP Request Header Field :"
+                        + e.getClass().getName()
+                        + " : "
+                        + e.getMessage());
+            }
+
+            if (hf == null || hf.equals("")) {
+                break;
+            }
+
+            /* [1] parse the name */
+            int colonIndex = hf.indexOf((int) ':');
+            String name = hf.substring(0, colonIndex);
+            if (name == null)
+                break;
+
+            /* [2] Parse the Value */
+            String value = hf.substring(colonIndex + 1, hf.length());
+            if (value == null)
+                break;
+            value = value.trim();
+            headers.put(name, value);
+        }
+
+        //temp-debug-------------------------------------------
+        //java.util.Iterator myKeys = headers.keySet().iterator();
+        //String temp = null;
+        //while(myKeys.hasNext()) {
+        //    temp = (String)myKeys.next();
+        //    System.out.println("Test: " + temp + "=" + headers.get(temp));
+        //}
+        //end temp-debug---------------------------------------
+    }
+
+    /** reads the body from the data input passed in
+     * @param in the data input with the body of the page
+     * @throws IOException if an exception is thrown
+     */
+    private void readBody(DataInput in) throws IOException {
+        readRequestBody(in);
+        //System.out.println("Body Length: " + body.length);
+        // Content-type: application/x-www-form-urlencoded
+        // or multipart/form-data
+        String type = getHeader(HttpRequest.HEADER_CONTENT_TYPE);
+        if (FORM_URL_ENCODED.equals(type)) {
+            parseFormParams();
+        } else if (type != null && type.startsWith(MULITPART_FORM_DATA)) {
+            parseMultiPartFormParams();
+        }
+    }
+
+    /** reads the request line of the data input
+     * @param in the data input that contains the request line
+     * @throws IOException if an exception is thrown
+     */
+    private void readRequestBody(DataInput in) throws IOException {
+        // Content-length: 384
+        String len = getHeader(HttpRequest.HEADER_CONTENT_LENGTH);
+        //System.out.println("readRequestBody Content-Length: " + len);
+
+        int length = -1;
+        if (len != null) {
+            try {
+                length = Integer.parseInt(len);
+            } catch (Exception e) {
+                //don't care
+            }
+        }
+
+        if (length < 1) {
+            this.body = new byte[0];
+        } else if (length > 0) {
+            this.body = new byte[length];
+
+            try {
+                in.readFully(body);
+            } catch (Exception e) {
+                throw new IOException(
+                    "Could not read the HTTP Request Body :"
+                        + e.getClass().getName()
+                        + " : "
+                        + e.getMessage());
+            }
+        }
+    }
+
+    /** parses form parameters into the formParams variable
+     * @throws IOException if an exeption is thrown
+     */
+    private void parseFormParams() throws IOException {
+        String rawParams = new String(body);
+        //System.out.println("rawParams: " + rawParams);
+        StringTokenizer parameters = new StringTokenizer(rawParams, "&");
+        String name = null;
+        String value = null;
+
+        while (parameters.hasMoreTokens()) {
+            StringTokenizer param = new StringTokenizer(parameters.nextToken(), "=");
+
+            /* [1] Parse the Name */
+            name = URLDecoder.decode(param.nextToken());
+            if (name == null)
+                break;
+
+            /* [2] Parse the Value */
+            if (param.hasMoreTokens()) {
+                value = URLDecoder.decode(param.nextToken());
+            } else {
+                value = ""; //if there is no token set value to blank string
+            }
+
+            if (value == null)
+                value = "";
+
+            formParams.put(name, value);
+            //System.out.println(name + ": " + value);
+        }
+    }
+
+    /**
+     * A method which parses form parameters that are multipart/form-data
+     * according to <a href="http://www.ietf.org/rfc/rfc1867.txt" target="_blank">
+     * RFC 1867</a>.  Currently multipart/mixed is not implemented.
+     */
+    private void parseMultiPartFormParams() throws IOException {
+        /* see http://www.ietf.org/rfc/rfc1867.txt */
+        ByteArrayOutputStream output;
+        StringBuffer multiPartBuffer;
+        int j;
+        Map headerMap;
+        boolean isFile;
+        String fileName = null;
+        byte[] outputArray;
+        FileOutputStream fos;
+
+        String contentType = getHeader(HttpRequest.HEADER_CONTENT_TYPE);
+        int boundaryIndex = contentType.indexOf("boundary=");
+        if (boundaryIndex < 0) {
+            throw new IOException("the request was rejected because no multipart boundary was found");
+        }
+        byte[] boundary = contentType.substring(boundaryIndex + 9).getBytes();
+
+        ByteArrayInputStream input = new ByteArrayInputStream(body);
+        MultipartStream multi = new MultipartStream(input, boundary);
+
+        boolean nextPart = multi.skipPreamble();
+        while (nextPart) {
+            try {
+                output = new ByteArrayOutputStream();
+                multi.readBodyData(output);
+                outputArray = output.toByteArray();
+                multiPartBuffer = new StringBuffer(50);
+                isFile = false;
+                File jarFileInTempDir;
+                j = 0;
+
+                for (int i = 0; i < outputArray.length; i++) {
+                    //first check for \r\n end of line
+                    if (outputArray[i] == 13 && outputArray[i + 1] == 10) {
+                        //we've come to the end of a line
+                        headerMap = parseMultiPartHeader(multiPartBuffer);
+                        if (headerMap.get(NAME) != null) {
+                            fileName = (String) headerMap.get(NAME);
+                        }
+
+                        //add the filename if there is one
+                        if (fileName != null && headerMap.get(FILENAME) != null) {
+                            this.formParams.put(fileName, headerMap.get(FILENAME));
+                            isFile = true;
+                        }
+
+                        if (outputArray[i + 2] == 13 && outputArray[i + 3] == 10) {
+                            //we've reached the blank line
+                            i+=4;
+                            j = i;
+                            break;
+                        } else {
+                            i++;
+                        }
+
+                        multiPartBuffer = new StringBuffer(50);
+                    } else {
+                        multiPartBuffer.append((char) outputArray[i]);
+                    }
+                }
+
+                //here we know that we have a file and that we need to write it
+                if (isFile) {
+                    //create file
+                    jarFileInTempDir = new File((String) this.formParams.get(fileName));
+                    if (!jarFileInTempDir.exists()) {
+                        jarFileInTempDir.createNewFile();
+                    }
+
+                    //write the byte array to the file
+                    fos = new FileOutputStream(jarFileInTempDir);
+                    fos.write(outputArray, j, outputArray.length-j);
+                    fos.close();
+                } else { //form data, not a file
+                    multiPartBuffer = new StringBuffer(outputArray.length-j);
+                    for (int i = j; i < outputArray.length; i++) {
+                        multiPartBuffer.append((char)outputArray[i]);
+                    }
+
+                    this.formParams.put(
+                        fileName,
+                        multiPartBuffer.toString());
+                }
+
+                nextPart = multi.readBoundary();
+            } catch (MultipartStream.MalformedStreamException mse) {
+                throw new IOException(mse.getMessage());
+            }
+        }
+    }
+
+    /**
+     * Parses the first one or two lines of a multipart.  The usual headers are
+     * Content-Dispostion or Content-Type.
+     *
+     * @param headerBuffer - the header string to be parsed
+     * @return a map of of header info and their values
+     */
+    private Map parseMultiPartHeader(StringBuffer headerBuffer) throws IOException {
+        Map headerMap = new HashMap();
+        int colonIndex = headerBuffer.toString().indexOf(":");
+        String headerName = headerBuffer.substring(0, colonIndex);
+        StringTokenizer headerValueToken =
+            new StringTokenizer(headerBuffer.substring(colonIndex + 1, headerBuffer.length()), ";");
+
+        String currentToken;
+        //loop through the tokens of semi-colon
+        while (headerValueToken.hasMoreTokens()) {
+            currentToken = headerValueToken.nextToken();
+            if (currentToken.indexOf("=") > -1) {
+                headerMap.put(
+                    currentToken.substring(0, currentToken.indexOf("=")).trim(),
+                    currentToken
+                        .substring(currentToken.indexOf("=") + 2, currentToken.length() - 1)
+                        .trim());
+            } else {
+                headerMap.put(headerName, currentToken.trim());
+            }
+        }
+
+        //first get rid of any path that might already be there then
+        //change the path of the file name to a temp directory
+        String fileName = (String) headerMap.get(FILENAME);
+        if (fileName != null) {
+            StringBuffer temp;
+            if (fileName.indexOf("\\") > -1) {
+                temp = new StringBuffer(fileName).reverse();
+                fileName = temp.delete(temp.toString().indexOf("\\"), temp.length()).reverse().toString();
+            }
+
+            temp = new StringBuffer();
+            temp.append(FileUtils.createTempDirectory().getAbsolutePath());
+            temp.append(System.getProperty("file.separator"));
+            temp.append(fileName);
+            headerMap.put(FILENAME, temp.toString());
+        }
+
+        return headerMap;
+    }
+
+    private HashMap cookies;
+
+    protected HashMap getCookies(){
+        if (cookies != null) return cookies;
+
+        cookies = new HashMap();
+
+        String cookieHeader = getHeader(HEADER_COOKIE);
+        if (cookieHeader == null ) return cookies;
+
+        StringTokenizer tokens = new StringTokenizer(cookieHeader, ";");
+        while (tokens.hasMoreTokens()){
+            StringTokenizer token = new StringTokenizer(tokens.nextToken(),"=");
+            String name = token.nextToken();
+            String value = token.nextToken();
+            cookies.put(name, value);
+        }
+        return cookies;
+    }
+
+    protected static final String EJBSESSIONID = "EJBSESSIONID";
+
+    protected String getCookie(String name){
+        return (String) getCookies().get(name);
+    }
+
+    public HttpSession getSession() {
+        return getSession(true);
+    }
+
+    private WebSession session;
+
+    public HttpSession getSession(boolean create) {
+        if (session != null) return session;
+
+        String id = getCookie(EJBSESSIONID);
+
+        if (id != null) {
+            session = (WebSession)sessions.get(id);
+        }
+
+        if (session == null && create){
+            session = createSession();
+            sessions.put(session.getId(), session);
+        }
+        return session;
+    }
+
+    private static final Hashtable sessions = new Hashtable();
+
+    private WebSession createSession(){
+        // Lookup/create sessions
+        WebSessionHome home = null;
+
+        try {
+            home = (WebSessionHome)new InitialContext().lookup("java:openejb/ejb/httpd/session");
+        } catch (NamingException e) {
+            // TODO Auto-generated catch block
+            throw new IllegalStateException("The WebSessionBean has not been deployed. "+
+                    " This is required for the HTTPd service to provide HttpSession support. "+
+                    e.getClass().getName()+": "+e.getMessage());
+        }
+
+
+        WebSession session = null;
+        try {
+            session = home.create();
+        } catch (RemoteException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        // mark them as nocopy
+        Object obj = org.apache.openejb.util.proxy.ProxyManager.getInvocationHandler(session);
+        StatefulEjbObjectHandler handler = (StatefulEjbObjectHandler) obj;
+        handler.setIntraVmCopyMode(false);
+        return session;
+    }
+}
\ No newline at end of file

Propchange: openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/httpd/HttpRequestImpl.java
------------------------------------------------------------------------------
    svn:executable = *

Added: openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/httpd/HttpResponseImpl.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/httpd/HttpResponseImpl.java?view=auto&rev=562334
==============================================================================
--- openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/httpd/HttpResponseImpl.java (added)
+++ openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/httpd/HttpResponseImpl.java Thu Aug  2 22:21:56 2007
@@ -0,0 +1,514 @@
+/** 
+ * Redistribution and use of this software and associated documentation
+ * ("Software"), with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain copyright
+ *    statements and notices.  Redistributions must also contain a
+ *    copy of this document.
+ *
+ * 2. Redistributions in binary form must reproduce the
+ *    above copyright notice, this list of conditions and the
+ *    following disclaimer in the documentation and/or other
+ *    materials provided with the distribution.
+ *
+ * 3. The name "OpenEJB" must not be used to endorse or promote
+ *    products derived from this Software without prior written
+ *    permission of The OpenEJB Group.  For written permission,
+ *    please contact dev@openejb.org.
+ *
+ * 4. Products derived from this Software may not be called "OpenEJB"
+ *    nor may "OpenEJB" appear in their names without prior written
+ *    permission of The OpenEJB Group. OpenEJB is a registered
+ *    trademark of The OpenEJB Group.
+ *
+ * 5. Due credit should be given to the OpenEJB Project
+ *    (http://www.openejb.org/).
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OPENEJB GROUP AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE OPENEJB GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Copyright 2001 (C) The OpenEJB Group. All Rights Reserved.
+ *
+ * $Id: HttpResponseImpl.java 445469 2005-06-19 22:40:34Z jlaskowski $
+ */
+package org.apache.openejb.webadmin.httpd;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+import org.apache.openejb.webadmin.HttpRequest;
+import org.apache.openejb.webadmin.HttpResponse;
+import org.apache.openejb.webadmin.HttpSession;
+import org.apache.openejb.util.JarUtils;
+import org.apache.openejb.util.OpenEjbVersion;
+
+/** This class takes care of HTTP Responses.  It sends data back to the browser.
+ * @author <a href="mailto:david.blevins@visi.com">David Blevins</a>
+ * @author <a href="mailto:tim_urberg@yahoo.com">Tim Urberg</a>
+ */
+public class HttpResponseImpl implements HttpResponse {
+
+    /** Response string */
+    private String responseString = "OK";
+
+    /** Code */
+    private int code = 200;
+
+    /** Response headers */
+    private HashMap headers;
+
+    /** Response body */
+    private byte[] body = new byte[0];
+
+    /** the writer for the response */
+    private transient PrintWriter writer;
+    /** the raw body */
+    private transient ByteArrayOutputStream baos;
+
+    /** the HTTP version */
+    public static final String HTTP_VERSION = "HTTP/1.1";
+    /** a line feed character */
+    public static final String CRLF = "\r\n";
+    /** a space character */
+    public static final String SP = " ";
+    /** a colon and space */
+    public static final String CSP = ": ";
+    /** the server to send data from */
+    public static String server;
+
+    private HttpRequestImpl request;
+    private URLConnection content;
+
+    protected void setRequest(HttpRequestImpl request){
+        this.request = request;
+    }
+
+    /** sets a header to be sent back to the browser
+     * @param name the name of the header
+     * @param value the value of the header
+     */
+    public void setHeader(String name, String value){
+        headers.put(name, value);
+    }
+
+    /** Gets a header based on the name passed in
+     * @param name The name of the header
+     * @return the value of the header
+     */
+    public String getHeader(String name){
+        return (String) headers.get(name);
+    }
+
+    /** Gets the PrintWriter to send data to the browser
+     * @return the PrintWriter to send data to the browser
+     */
+    public PrintWriter getPrintWriter(){
+        return writer;
+    }
+
+    /** gets the OutputStream to send data to the browser
+     * @return the OutputStream to send data to the browser
+     */
+    public OutputStream getOutputStream(){
+        return baos;
+    }
+
+    /** sets the HTTP response code to be sent to the browser.  These codes are:
+     *
+     * OPTIONS = 0
+     * GET     = 1
+     * HEAD    = 2
+     * POST    = 3
+     * PUT     = 4
+     * DELETE  = 5
+     * TRACE   = 6
+     * CONNECT = 7
+     * UNSUPPORTED = 8
+     * @param code the code to be sent to the browser
+     */
+    public void setCode(int code){
+        this.code = code;
+    }
+
+    /** gets the HTTP response code
+     * @return the HTTP response code
+     */
+    public int getCode(){
+        return code;
+    }
+
+    /** sets the content type to be sent back to the browser
+     * @param type the type to be sent to the browser (i.e. "text/html")
+     */
+    public void setContentType(String type){
+        setHeader("Content-Type", type);
+    }
+
+    /** gets the content type that will be sent to the browser
+     * @return the content type (i.e. "text/html")
+     */
+    public String getContentType(){
+        return getHeader("Content-Type");
+    }
+
+    /** Sets the response string to be sent to the browser
+     * @param responseString the response string
+     */
+    public void setResponseString(String responseString){
+       this.responseString = responseString;
+    }
+
+    /** Sets the response string to be sent to the browser
+     * @return the response string
+     */
+    public String getResponseString(){
+        return responseString;
+    }
+
+    /** resets the data to be sent to the browser */
+    public void reset(){
+        initBody();
+    }
+
+    /** resets the data to be sent to the browser with the response code and response
+     * string
+     * @param code the code to be sent to the browser
+     * @param responseString the response string to be sent to the browser
+     */
+    public void reset(int code, String responseString){
+        setCode(code);
+        setResponseString(responseString);
+        initBody();
+    }
+
+    /*------------------------------------------------------------*/
+    /*  Methods for writing out a response                        */
+    /*------------------------------------------------------------*/
+    /** creates a new instance of HttpResponseImpl with default values */
+    protected HttpResponseImpl(){
+        this(200, "OK", "text/html");
+    }
+
+    /** Creates a new HttpResponseImpl with user provided parameters
+     * @param code the HTTP Response code, see <a href="http://www.ietf.org/rfc/rfc2616.txt">http://www.ietf.org/rfc/rfc2616.txt</a>
+     * for these codes
+     * @param responseString the response string to be sent back
+     * @param contentType the content type to be sent back
+     */
+    protected HttpResponseImpl(int code, String responseString, String contentType){
+        this.responseString = responseString;
+        this.headers = new HashMap();
+        this.code = code;
+
+        // Default headers
+        setHeader("Server", getServerName());
+        setHeader("Connection","close");
+        setHeader("Content-Type",contentType);
+
+        // create the body.
+        initBody();
+    }
+
+    /** Takes care of sending the response line, headers and body
+     *
+     * HTTP/1.1 200 OK
+     * Server: Netscape-Enterprise/3.6 SP3
+     * Date: Thu, 07 Jun 2001 17:30:42 GMT
+     * Content-Type: text/html
+     * Connection: close
+     * @param output the output to send the response to
+     * @throws IOException if an exception is thrown
+     */
+    protected void writeMessage(OutputStream output) throws IOException{
+        DataOutput out = new DataOutputStream(output);
+        DataOutput log = new DataOutputStream(System.out);
+        //System.out.println("\nRESPONSE");
+        closeMessage();
+        //writeResponseLine(log);
+//        writeHeaders(log);
+//        writeBody(log);
+        writeResponseLine(out);
+        writeHeaders(out);
+        writeBody(out);
+    }
+
+     /** initalizes the body */
+    private void initBody(){
+        baos = new ByteArrayOutputStream();
+        writer = new PrintWriter( baos );
+    }
+
+    /** Creates a string version of the response similar to:
+     *
+     * HTTP/1.1 200 OK
+     * @return the string value of this HttpResponseImpl
+     */
+    public String toString(){
+        StringBuffer buf = new StringBuffer(40);
+
+        buf.append(HTTP_VERSION);
+        buf.append(SP);
+        buf.append(code+"");
+        buf.append(SP);
+        buf.append(responseString);
+
+        return buf.toString();
+    }
+
+    /** closes the message sent to the browser
+     * @throws IOException if an exception is thrown
+     */
+    private void closeMessage() throws IOException{
+        setContentLengthHeader();
+        setCookieHeader();
+    }
+
+
+    private void setContentLengthHeader() {
+        if (content == null){
+            writer.flush();
+            writer.close();
+            body = baos.toByteArray();
+            setHeader("Content-Length", body.length+"");
+        } else {
+            setHeader("Content-Length", content.getContentLength()+"");
+        }
+    }
+
+    private void setCookieHeader() {
+        if (request == null || request.getSession() == null) return;
+
+        HttpSession session = request.getSession(false);
+
+        if (session == null) return;
+
+        StringBuffer cookie = new StringBuffer();
+        cookie.append(HttpRequestImpl.EJBSESSIONID);
+        cookie.append('=');
+        cookie.append(session.getId());
+        cookie.append("; Path=/");
+
+        headers.put(HttpRequest.HEADER_SET_COOKIE, cookie.toString());
+    }
+
+    /** Writes a response line similar to this:
+     *
+     * HTTP/1.1 200 OK
+     *
+     * to the browser
+     * @param out the output stream to write the response line to
+     * @throws IOException if an exception is thrown
+     */
+    private void writeResponseLine(DataOutput out) throws IOException{
+        out.writeBytes(HTTP_VERSION);
+        out.writeBytes(SP);
+        out.writeBytes(code+"");
+        out.writeBytes(SP);
+        out.writeBytes(responseString);
+        out.writeBytes(CRLF);
+    }
+
+    /** writes the headers out to the browser
+     * @param out the output stream to be sent to the browser
+     * @throws IOException if an exception is thrown
+     */
+    private void writeHeaders(DataOutput out) throws IOException{
+        Iterator it =  headers.entrySet().iterator();
+
+        while (it.hasNext()){
+            Map.Entry entry = (Map.Entry)it.next();
+            out.writeBytes(""+entry.getKey());
+            out.writeBytes(CSP);
+            out.writeBytes(""+entry.getValue());
+            out.writeBytes(CRLF);
+        }
+    }
+
+    /** writes the body out to the browser
+     * @param out the output stream that writes to the browser
+     * @throws IOException if an exception is thrown
+     */
+    private void writeBody(DataOutput out) throws IOException{
+        out.writeBytes(CRLF);
+        if (content == null){
+            out.write(body);
+        } else {
+            InputStream in = content.getInputStream();
+            byte buf[] = new byte[1024];
+            for(int i = 0; (i = in.read(buf)) != -1; out.write(buf, 0, i));
+        }
+    }
+
+    /** gets the name of the server being used
+     * @return the name of the server
+     */
+    public String getServerName(){
+        if (server == null) {
+            String version = "???";
+            String os = "(unknown os)";
+
+            OpenEjbVersion openejbInfo = OpenEjbVersion.get();
+
+            version = openejbInfo.getVersion();
+            os = System.getProperty("os.name")+"/"+System.getProperty("os.version")+" ("+System.getProperty("os.arch")+")";
+
+            server = "OpenEJB/" +version+ " "+os;
+        }
+        return server;
+    }
+
+
+    /** This could be improved at some day in the future
+     * to also include a stack trace of the exceptions
+     * @param message the error message to be sent
+     * @return the HttpResponseImpl that this error belongs to
+     */
+    protected static HttpResponseImpl createError(String message){
+        return createError(message, null);
+    }
+
+    /** creates an error with user defined variables
+     * @param message the message of the error
+     * @param t a Throwable to print a stack trace to
+     * @return the HttpResponseImpl that this error belongs to
+     */
+    protected static HttpResponseImpl createError(String message, Throwable t){
+        HttpResponseImpl res = new HttpResponseImpl(500, "Internal Server Error", "text/html");
+        java.io.PrintWriter body = res.getPrintWriter();
+
+        body.println("<html>");
+        body.println("<body>");
+        body.println("<h3>Internal Server Error</h3>");
+        body.println("<br><br>");
+
+        if (message != null) {
+            StringTokenizer msg = new StringTokenizer(message, "\n\r");
+
+            while (msg.hasMoreTokens()) {
+                body.print( msg.nextToken() );
+                body.println("<br>");
+            }
+        }
+
+        if (t != null) {
+            try{
+                body.println("<br><br>");
+                body.println("Stack Trace:<br>");
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                PrintWriter writer = new PrintWriter( baos );
+                t.printStackTrace(writer);
+                writer.flush();
+                writer.close();
+                message = new String(baos.toByteArray());
+                StringTokenizer msg = new StringTokenizer(message, "\n\r");
+
+                while (msg.hasMoreTokens()) {
+                    body.print( msg.nextToken() );
+                    body.println("<br>");
+                }
+            } catch (Exception e){
+            }
+        }
+
+        body.println("</body>");
+        body.println("</html>");
+
+        return res;
+    }
+
+    /** Creates a forbidden response to be sent to the browser using IP authentication
+     * @param ip the ip that is forbidden
+     * @return the HttpResponseImpl that this error belongs to
+     */
+    protected static HttpResponseImpl createForbidden(String ip){
+        HttpResponseImpl res = new HttpResponseImpl(403, "Forbidden", "text/html");
+        java.io.PrintWriter body = res.getPrintWriter();
+
+        body.println("<html>");
+        body.println("<body>");
+        body.println("<h3>Forbidden</h3>");
+        body.println("<br><br>");
+        // Add more text here
+        // IP not allowed, etc.
+        body.println("IP address: " + ip + " is not registered on this server, please contact your system administrator.");
+        body.println("</body>");
+        body.println("</html>");
+
+        return res;
+    }
+
+    /** writes this object out to a file
+     * @param out the ObjectOutputStream to write to
+     * @throws IOException if an exception is thrown
+     */
+    private void writeObject(java.io.ObjectOutputStream out) throws IOException{
+        /** Response string */
+        out.writeObject( responseString );
+
+        /** Code */
+        out.writeInt( code );
+
+        /** Response headers */
+        out.writeObject( headers );
+
+        /** Response body */
+        writer.flush();
+        body = baos.toByteArray();
+        //System.out.println("[] body "+body.length );
+        out.writeObject( body );
+    }
+
+    /** Reads in a serilized HttpResponseImpl object from a file
+     * @param in the input to read the object from
+     * @throws IOException if an exception is thrown
+     * @throws ClassNotFoundException if an exception is thrown
+     */
+    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException{
+        /** Response string */
+        this.responseString = (String)in.readObject();
+
+        /** Code */
+        this.code = in.readInt();
+
+        /** Response headers */
+        this.headers = (HashMap) in.readObject();
+
+        /** Response body */
+        body = (byte[]) in.readObject();
+        //System.out.println("[] body "+body.length );
+        baos = new ByteArrayOutputStream();
+        baos.write( body );
+        writer = new PrintWriter( baos );
+
+    }
+    /**
+     * @param content The content to set.
+     */
+    public void setContent(URLConnection content) {
+        this.content = content;
+    }
+
+}
\ No newline at end of file

Propchange: openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/httpd/HttpResponseImpl.java
------------------------------------------------------------------------------
    svn:executable = *

Added: openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/httpd/HttpServer.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/httpd/HttpServer.java?view=auto&rev=562334
==============================================================================
--- openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/httpd/HttpServer.java (added)
+++ openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/httpd/HttpServer.java Thu Aug  2 22:21:56 2007
@@ -0,0 +1,327 @@
+/**
+ * Redistribution and use of this software and associated documentation
+ * ("Software"), with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain copyright
+ *    statements and notices.  Redistributions must also contain a
+ *    copy of this document.
+ *
+ * 2. Redistributions in binary form must reproduce the
+ *    above copyright notice, this list of conditions and the
+ *    following disclaimer in the documentation and/or other
+ *    materials provided with the distribution.
+ *
+ * 3. The name "OpenEJB" must not be used to endorse or promote
+ *    products derived from this Software without prior written
+ *    permission of The OpenEJB Group.  For written permission,
+ *    please contact dev@openejb.org.
+ *
+ * 4. Products derived from this Software may not be called "OpenEJB"
+ *    nor may "OpenEJB" appear in their names without prior written
+ *    permission of The OpenEJB Group. OpenEJB is a registered
+ *    trademark of The OpenEJB Group.
+ *
+ * 5. Due credit should be given to the OpenEJB Project
+ *    (http://www.openejb.org/).
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OPENEJB GROUP AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE OPENEJB GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Copyright 2001 (C) The OpenEJB Group. All Rights Reserved.
+ *
+ * $Id: HttpServer.java 446024 2006-02-21 08:45:52Z dblevins $
+ */
+package org.apache.openejb.webadmin.httpd;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.URL;
+import java.util.Properties;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+
+import org.apache.openejb.server.ServerService;
+import org.apache.openejb.server.ServiceException;
+import org.apache.openejb.util.Logger;
+import org.apache.openejb.webadmin.HttpHome;
+import org.apache.openejb.webadmin.HttpObject;
+
+/** 
+ * This is the main class for the web administration.  It takes care of the
+ * processing from the browser, sockets and threading.
+ * 
+ * @author <a href="mailto:david.blevins@visi.com">David Blevins</a>
+ * @author <a href="mailto:tim_urberg@yahoo.com">Tim Urberg</a>
+ * @since 11/25/2001
+ */
+public class HttpServer implements ServerService{
+
+    private static final Logger logger = Logger.getInstance( "OpenEJB.server", "org.apache.openejb.server.util.resources" );
+    private InitialContext jndiContext;
+
+    public void service(InputStream in, OutputStream out) throws ServiceException, IOException {
+        throw new UnsupportedOperationException("service(in,out)");
+    }
+    
+    public void service(Socket socket) throws ServiceException, IOException {
+        /**
+         * The InputStream used to receive incoming messages from the client.
+         */
+        InputStream in = socket.getInputStream();
+        /**
+         * The OutputStream used to send outgoing response messages to the client.
+         */
+        OutputStream out = socket.getOutputStream();
+
+
+        try {
+            processRequest(socket, in, out);
+        } catch ( Throwable e ) {
+            logger.error( "Unexpected error", e );
+        } finally {
+            try {
+                if ( out != null ) {
+                    out.flush();
+                    out.close();
+                }
+                if (in != null)
+                    in.close();
+                if (socket != null)
+                    socket.close();
+            } catch ( Throwable t ){
+                logger.error(
+                        "Encountered problem while closing connection with client: "
+                        + t.getMessage());
+            }
+        }
+    }
+
+    public void start() throws ServiceException {
+    }
+
+    public void stop() throws ServiceException {
+    }
+
+    public String getName() {
+        return "webadmin";
+    }
+
+    public int getPort() {
+        return 0;
+    }
+
+    public String getIP() {
+        return "";
+    }
+
+
+    /** Initalizes this instance and takes care of starting things up
+     * @param props a properties instance for system properties
+     * @throws Exception if an exeption is thrown
+     */
+    public void init(Properties props) throws Exception{
+
+        //props.putAll(System.getProperties());
+
+        Properties properties = new Properties();
+        properties.put(
+            Context.INITIAL_CONTEXT_FACTORY,
+            "org.apache.openejb.core.ivm.naming.InitContextFactory");
+        jndiContext = new InitialContext(properties);
+
+    }
+
+    /** 
+     * takes care of processing requests and creating the webadmin ejb's
+     * 
+     * @param in the input stream from the browser
+     * @param out the output stream to the browser
+     */
+    private void processRequest(Socket socket, InputStream in, OutputStream out) {
+
+        HttpRequestImpl req = new HttpRequestImpl();
+        HttpResponseImpl res = new HttpResponseImpl();
+        InetAddress client = socket.getInetAddress();
+        
+
+        try {
+            req.readMessage(in);
+            res.setRequest(req);
+//            logger.info(client.getHostName()+": "+req.getRequestLine());
+        } catch (Throwable t) {
+            //TODO: log or something
+            //t.printStackTrace();
+            res =
+                HttpResponseImpl.createError(
+                    "Could not read the request.\n" + t.getClass().getName() + ":\n" + t.getMessage(),
+                    t);
+            try {
+                logger.error(client.getHostName()+": "+res.getCode()+" "+req.getRequestLine()+ " ["+ res.getResponseString()+"]");
+                res.writeMessage(out);
+            } catch (Throwable t2) {
+                //TODO: log or something
+                //t2.printStackTrace();
+            }
+            return;
+        }
+
+        //System.out.println("[] read");
+        URL uri = null;
+        String file = null;
+
+        try {
+            uri = req.getURI();
+            file = uri.getFile();
+            int querry = file.indexOf("?");
+            if (querry != -1) {
+                file = file.substring(0, querry);
+            }
+
+            //System.out.println("[] file="+file);
+
+        } catch (Throwable t) {
+            //TODO: log or something
+            //t.printStackTrace();
+            res =
+                HttpResponseImpl.createError(
+                    "Could not determine the module "
+                        + file
+                        + "\n"
+                        + t.getClass().getName()
+                        + ":\n"
+                        + t.getMessage());
+            try {
+                logger.error(client.getHostName()+": "+res.getCode()+" "+req.getRequestLine()+ " ["+ res.getResponseString()+"]");
+                res.writeMessage(out);
+            } catch (Throwable t2) {
+                //TODO: log or something
+                //t2.printStackTrace();
+            }
+            return;
+        }
+
+        HttpObject httpObject = null;
+
+        try {
+            httpObject = getHttpObject(file);
+            //System.out.println("[] module="+httpObject);
+        } catch (Throwable t) {
+            //TODO: log or something
+            //t.printStackTrace();
+            res =
+                HttpResponseImpl.createError(
+                    "Could not load the module "
+                        + file
+                        + "\n"
+                        + t.getClass().getName()
+                        + ":\n"
+                        + t.getMessage(),
+                    t);
+            //System.out.println("[] res="+res);
+            try {
+                logger.error(client.getHostName()+": "+res.getCode()+" "+req.getRequestLine()+ " ["+ res.getResponseString()+"]");
+                res.writeMessage(out);
+            } catch (Throwable t2) {
+                //TODO: log or something
+                //t2.printStackTrace();
+            }
+            return;
+        }
+
+        try {
+            httpObject.onMessage(req, res);
+        } catch (Throwable t) {
+            //TODO: log or something
+            //t.printStackTrace();
+            res =
+                HttpResponseImpl.createError(
+                    "Error occurred while executing the module "
+                        + file
+                        + "\n"
+                        + t.getClass().getName()
+                        + ":\n"
+                        + t.getMessage(),
+                    t);
+            try {
+                logger.error(client.getHostName()+": "+res.getCode()+" "+req.getRequestLine()+ " ["+ res.getResponseString()+"]");
+                res.writeMessage(out);
+            } catch (Throwable t2) {
+                //TODO: log or something
+                //t2.printStackTrace();
+            }
+
+            return;
+        }
+
+        try {
+            logger.info(client.getHostName()+": "+res.getCode()+" "+req.getRequestLine()+ " ["+ res.getResponseString()+"]");
+            res.writeMessage(out);
+        } catch (Throwable t) {
+            //TODO: log or something
+            //t.printStackTrace();
+            return;
+        }
+    }
+
+    /** gets an ejb object reference for use in <code>processRequest</code>
+     * @param beanName the name of the ejb to look up
+     * @throws IOException if an exception is thrown
+     * @return an object reference of the ejb
+     */
+    private HttpObject getHttpObject(String beanName) throws IOException {
+        Object obj = null;
+
+        //check for no name, add something here later
+        if (beanName.equals("/")) {
+            try {
+                obj = jndiContext.lookup("Webadmin/Home");
+            } catch (javax.naming.NamingException ne) {
+                throw new IOException(ne.getMessage());
+            }
+        } else {
+            try {
+                obj = jndiContext.lookup(beanName);
+            } catch (javax.naming.NameNotFoundException e) {
+                try {
+                    obj = jndiContext.lookup("httpd/DefaultBean");
+                } catch (javax.naming.NamingException ne) {
+                    throw new IOException(ne.getMessage());
+                }
+            } catch (javax.naming.NamingException e) {
+                throw new IOException(e.getMessage());
+            }
+        }
+
+        HttpHome ejbHome = (HttpHome) obj;
+        HttpObject httpObject = null;
+
+        try {
+            httpObject = ejbHome.create();
+
+            // 
+            obj = org.apache.openejb.util.proxy.ProxyManager.getInvocationHandler(httpObject);
+            org.apache.openejb.core.ivm.BaseEjbProxyHandler handler = null;
+            handler = (org.apache.openejb.core.ivm.BaseEjbProxyHandler) obj;
+            handler.setIntraVmCopyMode(false);
+        } catch (javax.ejb.CreateException cre) {
+            throw new IOException(cre.getMessage());
+        }
+
+        return httpObject;
+    }
+}

Propchange: openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/httpd/HttpServer.java
------------------------------------------------------------------------------
    svn:executable = *

Added: openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/httpd/WebSession.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/httpd/WebSession.java?view=auto&rev=562334
==============================================================================
--- openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/httpd/WebSession.java (added)
+++ openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/httpd/WebSession.java Thu Aug  2 22:21:56 2007
@@ -0,0 +1,56 @@
+/**
+ * Redistribution and use of this software and associated documentation
+ * ("Software"), with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain copyright
+ *    statements and notices.  Redistributions must also contain a
+ *    copy of this document.
+ *
+ * 2. Redistributions in binary form must reproduce the
+ *    above copyright notice, this list of conditions and the
+ *    following disclaimer in the documentation and/or other
+ *    materials provided with the distribution.
+ *
+ * 3. The name "OpenEJB" must not be used to endorse or promote
+ *    products derived from this Software without prior written
+ *    permission of The OpenEJB Group.  For written permission,
+ *    please contact dev@openejb.org.
+ *
+ * 4. Products derived from this Software may not be called "OpenEJB"
+ *    nor may "OpenEJB" appear in their names without prior written
+ *    permission of The OpenEJB Group. OpenEJB is a registered
+ *    trademark of The OpenEJB Group.
+ *
+ * 5. Due credit should be given to the OpenEJB Project
+ *    (http://www.openejb.org/).
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OPENEJB GROUP AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE OPENEJB GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Copyright 2001 (C) The OpenEJB Group. All Rights Reserved.
+ *
+ * $Id: WebSession.java 445460 2005-06-16 22:29:56Z jlaskowski $
+ */
+package org.apache.openejb.webadmin.httpd;
+
+import javax.ejb.EJBObject;
+
+import org.apache.openejb.webadmin.HttpSession;
+
+/**
+ * @author <a href="mailto:david.blevins@visi.com">David Blevins</a>
+ */
+public interface WebSession extends EJBObject, HttpSession {
+
+}

Propchange: openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/httpd/WebSession.java
------------------------------------------------------------------------------
    svn:executable = *

Added: openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/httpd/WebSessionBean.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/httpd/WebSessionBean.java?view=auto&rev=562334
==============================================================================
--- openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/httpd/WebSessionBean.java (added)
+++ openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/httpd/WebSessionBean.java Thu Aug  2 22:21:56 2007
@@ -0,0 +1,115 @@
+/**
+ * Redistribution and use of this software and associated documentation
+ * ("Software"), with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain copyright
+ *    statements and notices.  Redistributions must also contain a
+ *    copy of this document.
+ *
+ * 2. Redistributions in binary form must reproduce the
+ *    above copyright notice, this list of conditions and the
+ *    following disclaimer in the documentation and/or other
+ *    materials provided with the distribution.
+ *
+ * 3. The name "OpenEJB" must not be used to endorse or promote
+ *    products derived from this Software without prior written
+ *    permission of The OpenEJB Group.  For written permission,
+ *    please contact dev@openejb.org.
+ *
+ * 4. Products derived from this Software may not be called "OpenEJB"
+ *    nor may "OpenEJB" appear in their names without prior written
+ *    permission of The OpenEJB Group. OpenEJB is a registered
+ *    trademark of The OpenEJB Group.
+ *
+ * 5. Due credit should be given to the OpenEJB Project
+ *    (http://www.openejb.org/).
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OPENEJB GROUP AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE OPENEJB GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Copyright 2001 (C) The OpenEJB Group. All Rights Reserved.
+ *
+ * $Id: WebSessionBean.java 445605 2005-08-04 01:20:07Z dblevins $
+ */
+package org.apache.openejb.webadmin.httpd;
+
+import java.util.HashMap;
+
+import javax.ejb.CreateException;
+import javax.ejb.SessionBean;
+import javax.ejb.SessionContext;
+import javax.ejb.Stateless;
+import javax.ejb.RemoteHome;
+
+import org.apache.openejb.core.stateful.StatefulEjbObjectHandler;
+import org.apache.openejb.util.proxy.ProxyManager;
+
+/**
+ * @author <a href="mailto:david.blevins@visi.com">David Blevins</a>
+ */
+@Stateless(name = "httpd/session")
+@RemoteHome(WebSessionHome.class)
+public class WebSessionBean implements SessionBean {
+
+    private SessionContext ctx;
+    private HashMap attributes;
+
+    public void ejbCreate() throws CreateException {
+        attributes = new HashMap();
+    }
+
+    public String getId() {
+        Object obj = ProxyManager.getInvocationHandler(ctx.getEJBObject());
+        StatefulEjbObjectHandler handler = (StatefulEjbObjectHandler) obj;
+        return handler.getRegistryId() + "";
+    }
+
+//    private void uberHack() throws Exception {
+//        org.apache.catalina.core.StandardWrapperFacade standardWrapperFacade = (org.apache.catalina.core.StandardWrapperFacade)config;
+//        org.apache.catalina.core.ContainerBase containerBase = (org.apache.catalina.core.ContainerBase)standardWrapperFacade.config;
+//        org.apache.catalina.core.ContainerBase containerBase2 = (org.apache.catalina.core.ContainerBase)containerBase.parent;
+//        java.util.HashMap children = (java.util.HashMap)containerBase2.children;
+//        org.apache.catalina.core.StandardWrapper standardWrapper = (org.apache.catalina.core.StandardWrapper) children.get("jsp");
+//        org.apache.jasper.servlet.JspServlet jspServlet = (org.apache.jasper.servlet.JspServlet)standardWrapper.instance;
+//        jspServlet.rctxt;
+//    }
+
+    public Object getAttribute(String name) {
+        return attributes.get(name);
+    }
+
+    public void setAttribute(String name, Object value) {
+        attributes.put(name, value);
+    }
+
+    public void removeAttribute(String name) {
+        attributes.remove(name);
+    }
+
+    public void ejbActivate() {
+
+    }
+
+    public void ejbPassivate() {
+
+    }
+
+    public void ejbRemove() {
+
+    }
+
+    public void setSessionContext(SessionContext ctx) {
+        this.ctx = ctx;
+    }
+}

Propchange: openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/httpd/WebSessionBean.java
------------------------------------------------------------------------------
    svn:executable = *

Added: openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/httpd/WebSessionHome.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/httpd/WebSessionHome.java?view=auto&rev=562334
==============================================================================
--- openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/httpd/WebSessionHome.java (added)
+++ openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/httpd/WebSessionHome.java Thu Aug  2 22:21:56 2007
@@ -0,0 +1,58 @@
+/**
+ * Redistribution and use of this software and associated documentation
+ * ("Software"), with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain copyright
+ *    statements and notices.  Redistributions must also contain a
+ *    copy of this document.
+ *
+ * 2. Redistributions in binary form must reproduce the
+ *    above copyright notice, this list of conditions and the
+ *    following disclaimer in the documentation and/or other
+ *    materials provided with the distribution.
+ *
+ * 3. The name "OpenEJB" must not be used to endorse or promote
+ *    products derived from this Software without prior written
+ *    permission of The OpenEJB Group.  For written permission,
+ *    please contact dev@openejb.org.
+ *
+ * 4. Products derived from this Software may not be called "OpenEJB"
+ *    nor may "OpenEJB" appear in their names without prior written
+ *    permission of The OpenEJB Group. OpenEJB is a registered
+ *    trademark of The OpenEJB Group.
+ *
+ * 5. Due credit should be given to the OpenEJB Project
+ *    (http://www.openejb.org/).
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OPENEJB GROUP AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE OPENEJB GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Copyright 2001 (C) The OpenEJB Group. All Rights Reserved.
+ *
+ * $Id: WebSessionHome.java 445460 2005-06-16 22:29:56Z jlaskowski $
+ */
+package org.apache.openejb.webadmin.httpd;
+
+import java.rmi.RemoteException;
+
+import javax.ejb.EJBHome;
+
+/**
+ * @author <a href="mailto:david.blevins@visi.com">David Blevins</a>
+ */
+public interface WebSessionHome extends EJBHome {
+
+    public WebSession create() throws RemoteException;
+    
+}

Propchange: openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/httpd/WebSessionHome.java
------------------------------------------------------------------------------
    svn:executable = *

Added: openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/main/DeploymentListBean.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/main/DeploymentListBean.java?view=auto&rev=562334
==============================================================================
--- openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/main/DeploymentListBean.java (added)
+++ openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/main/DeploymentListBean.java Thu Aug  2 22:21:56 2007
@@ -0,0 +1,332 @@
+/**
+ * Redistribution and use of this software and associated documentation
+ * ("Software"), with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain copyright
+ *    statements and notices.  Redistributions must also contain a
+ *    copy of this document.
+ *
+ * 2. Redistributions in binary form must reproduce the
+ *    above copyright notice, this list of conditions and the
+ *    following disclaimer in the documentation and/or other
+ *    materials provided with the distribution.
+ *
+ * 3. The name "OpenEJB" must not be used to endorse or promote
+ *    products derived from this Software without prior written
+ *    permission of The OpenEJB Group.  For written permission,
+ *    please contact dev@openejb.org.
+ *
+ * 4. Products derived from this Software may not be called "OpenEJB"
+ *    nor may "OpenEJB" appear in their names without prior written
+ *    permission of The OpenEJB Group. OpenEJB is a registered
+ *    trademark of The OpenEJB Group.
+ *
+ * 5. Due credit should be given to the OpenEJB Project
+ *    (http://www.openejb.org/).
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OPENEJB GROUP AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE OPENEJB GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Copyright 2001 (C) The OpenEJB Group. All Rights Reserved.
+ *
+ * $Id: DeploymentListBean.java 445460 2005-06-16 22:29:56Z jlaskowski $
+ */
+package org.apache.openejb.webadmin.main;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+
+import org.apache.openejb.DeploymentInfo;
+import org.apache.openejb.OpenEJB;
+import org.apache.openejb.core.CoreDeploymentInfo;
+import org.apache.openejb.spi.ContainerSystem;
+import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.webadmin.HttpRequest;
+import org.apache.openejb.webadmin.HttpResponse;
+import org.apache.openejb.webadmin.WebAdminBean;
+import org.apache.openejb.webadmin.HttpHome;
+import org.apache.openejb.assembler.classic.EjbReferenceInfo;
+import org.apache.openejb.assembler.classic.EnterpriseBeanInfo;
+import org.apache.openejb.assembler.classic.EnvEntryInfo;
+import org.apache.openejb.assembler.classic.JndiEncInfo;
+import org.apache.openejb.assembler.classic.ResourceReferenceInfo;
+import org.apache.openejb.assembler.classic.OpenEjbConfiguration;
+import org.apache.openejb.assembler.classic.AppInfo;
+import org.apache.openejb.assembler.classic.EjbJarInfo;
+import org.apache.openejb.assembler.classic.EjbLocalReferenceInfo;
+import org.apache.openejb.assembler.classic.ResourceEnvReferenceInfo;
+import org.apache.openejb.assembler.classic.PersistenceUnitReferenceInfo;
+import org.apache.openejb.assembler.classic.PersistenceContextReferenceInfo;
+import org.apache.openejb.assembler.classic.ServiceReferenceInfo;
+import org.apache.openejb.util.StringUtilities;
+
+import javax.ejb.Stateless;
+import javax.ejb.RemoteHome;
+
+/**
+ * A bean which lists all deployed beans.
+ * 
+ * @author <a href="mailto:david.blevins@visi.com">David Blevins</a>
+ * @author <a href="mailto:tim_urberg@yahoo.com">Tim Urberg</a>
+ */
+@Stateless(name = "Webadmin/DeploymentList")
+@RemoteHome(HttpHome.class)
+public class DeploymentListBean extends WebAdminBean {
+    private HashMap deploymentIdIndex;
+    private HashMap containerIdIndex;
+
+    /** Creates a new instance of DeploymentListBean */
+    public void ejbCreate() {
+        this.section = "DeploymentList";
+    }
+
+    /** called after all content is written to the browser
+     * @param request the http request
+     * @param response the http response
+     * @throws IOException if an exception is thrown
+     *
+     */
+    public void postProcess(HttpRequest request, HttpResponse response) throws IOException {}
+
+    /** called before any content is written to the browser
+     * @param request the http request
+     * @param response the http response
+     * @throws IOException if an exception is thrown
+     *
+     */
+    public void preProcess(HttpRequest request, HttpResponse response) throws IOException {
+        createIndexes();
+    }
+
+    /** writes the main body content to the broswer.  This content is inside a <code>&lt;p&gt;</code> block
+     *
+     *
+     * @param body the output to write to
+     * @exception IOException if an exception is thrown
+     *
+     */
+    public void writeBody(PrintWriter body) throws IOException {
+        String id = request.getQueryParameter("id");
+        if (id != null) {
+            showDeployment(body, id);
+        } else {
+            printDeployments(body);
+        }
+    }
+
+    private void createIndexes() {
+        deploymentIdIndex = new HashMap();
+        containerIdIndex = new HashMap();
+        OpenEjbConfiguration configuration = SystemInstance.get().getComponent(OpenEjbConfiguration.class);
+        for (AppInfo appInfo : configuration.containerSystem.applications) {
+            for (EjbJarInfo ejbJarInfo : appInfo.ejbJars) {
+                for (EnterpriseBeanInfo bean : ejbJarInfo.enterpriseBeans) {
+                    deploymentIdIndex.put(bean.ejbDeploymentId, bean);
+                }
+            }
+        }
+    }
+
+    private void showDeployment(PrintWriter body, String id) throws IOException {
+        EnterpriseBeanInfo bean = getBeanInfo(id);
+
+        // TODO:0: Inform the user the id is bad
+        if (bean == null)
+            return;
+
+        // Assuming things are good        
+        body = response.getPrintWriter();
+
+        body.println("<h2>General</h2><br>");
+        body.println("<table width=\"100%\" border=\"1\">");
+        body.println("<tr bgcolor=\"#5A5CB8\">");
+        body.println("<td><font face=\"arial\" color=\"white\">ID</font></td>");
+        body.println("<td><font color=\"white\">" + id + "</font></td>");
+        body.println("</tr>");
+
+        SystemInstance system = SystemInstance.get();
+        ContainerSystem containerSystem = system.getComponent(ContainerSystem.class);
+
+        CoreDeploymentInfo di = (CoreDeploymentInfo) containerSystem.getDeploymentInfo(id);
+
+        printRow("Name", bean.ejbName, body);
+        printRow(
+            "Description",
+            StringUtilities.replaceNullOrBlankStringWithNonBreakingSpace(bean.description),
+            body);
+
+        String type = null;
+
+        switch (di.getComponentType()) {
+            case CMP_ENTITY :
+                type = "EntityBean with Container-Managed Persistence";
+                break;
+            case BMP_ENTITY :
+                type = "EntityBean with Bean-Managed Persistence";
+                break;
+            case STATEFUL :
+                type = "Stateful SessionBean";
+                break;
+            case STATELESS :
+                type = "Stateless SessionBean";
+                break;
+            default :
+                type = "Unkown Bean Type";
+                break;
+        }
+
+        printRow("Bean Type", type, body);
+        printRow("Bean Class", bean.ejbClass, body);
+        printRow("Home Interface", bean.home, body);
+        printRow("Remote Interface", bean.remote, body);
+        printRow("Jar location", bean.codebase, body);
+
+        //String container = URLEncoder.encode("" + di.getContainer().getContainerID());
+        String container = (String)di.getContainer().getContainerID();
+        printRow("Deployed in", container, body);
+
+        body.println("</table>");
+
+        JndiEncInfo enc = bean.jndiEnc;
+
+        body.println("<h2>JNDI Environment Details</h2><br>");
+        body.println("<table width=\"100%\" border=\"1\">");
+        body.println("<tr bgcolor=\"#5A5CB8\">");
+        body.println("<td><font face=\"arial\" color=\"white\">JNDI Name</font></td>");
+        body.println("<td><font face=\"arial\" color=\"white\">Value</font></td>");
+        body.println("<td><font face=\"arial\" color=\"white\">Type</font></td>");
+        body.println("</tr>");
+
+        for (EnvEntryInfo info : enc.envEntries) {
+            printRow(info.name, info.value, info.type, body);
+        }
+
+        for (EjbLocalReferenceInfo info : enc.ejbLocalReferences) {
+            printRow(info.referenceName, info.ejbDeploymentId, info.homeType, body);
+        }
+
+        for (EjbReferenceInfo info : enc.ejbReferences) {
+            printRow(info.referenceName, info.ejbDeploymentId, info.homeType, body);
+        }
+
+        for (ResourceReferenceInfo info : enc.resourceRefs) {
+            printRow(info.referenceName, info.resourceID, info.referenceType, body);
+        }
+
+        for (ResourceEnvReferenceInfo info : enc.resourceEnvRefs) {
+            printRow(info.resourceEnvRefName, info.resourceID, info.resourceEnvRefType, body);
+        }
+
+        for (PersistenceUnitReferenceInfo info : enc.persistenceUnitRefs) {
+            printRow(info.referenceName, info.persistenceUnitName, "", body);
+        }
+
+        for (PersistenceContextReferenceInfo info : enc.persistenceContextRefs) {
+            printRow(info.referenceName, info.persistenceUnitName, "", body);
+        }
+
+        for (ServiceReferenceInfo info : enc.serviceRefs) {
+            printRow(info.referenceName, "<not-supported>", "", body);
+        }
+
+        body.println("</table>");
+    }
+
+    private EnterpriseBeanInfo getBeanInfo(String id) {
+        return (EnterpriseBeanInfo) deploymentIdIndex.get(id);
+    }
+
+    private void printDeployments(PrintWriter out) throws IOException {
+        SystemInstance system = SystemInstance.get();
+        ContainerSystem containerSystem = system.getComponent(ContainerSystem.class);
+
+        DeploymentInfo[] deployments = containerSystem.deployments();
+        String[] deploymentString = new String[deployments.length];
+        out.println("<table width=\"100%\" border=\"1\">");
+        out.println("<tr bgcolor=\"#5A5CB8\">");
+        out.println("<td><font color=\"white\">Deployment ID</font></td>");
+        out.println("</tr>");
+
+        if (deployments.length > 0) {
+            for (int i = 0; i < deployments.length; i++) {
+                deploymentString[i] = (String) deployments[i].getDeploymentID();
+            }
+            Arrays.sort(deploymentString);
+
+            for (int i = 0; i < deploymentString.length; i++) {
+                if (i % 2 == 1) {
+                    out.println("<tr bgcolor=\"#c9c5fe\">");
+                } else {
+                    out.println("<tr>");
+                }
+
+                out.print("<td><span class=\"bodyBlack\">");
+                out.print("<a href=\"DeploymentList?id=" + deploymentString[i] + "\">");
+                out.print(deploymentString[i]);
+                out.print("</a>");
+                out.println("</span></td></tr>");
+            }
+        }
+        out.println("</table>");
+    }
+
+    /** Write the TITLE of the HTML document.  This is the part
+     * that goes into the <code>&lt;head&gt;&lt;title&gt;
+     * &lt;/title&gt;&lt;/head&gt;</code> tags
+     *
+     * @param body the output to write to
+     * @exception IOException of an exception is thrown
+     *
+     */
+    public void writeHtmlTitle(PrintWriter body) throws IOException {
+        body.println(HTML_TITLE);
+    }
+
+    /** Write the title of the page.  This is displayed right
+     * above the main block of content.
+     *
+     * @param body the output to write to
+     * @exception IOException if an exception is thrown
+     *
+     */
+    public void writePageTitle(PrintWriter body) throws IOException {
+        body.println("EnterpriseBean Details");
+    }
+
+    /** Write the sub items for this bean in the left navigation bar of
+     * the page.  This should look somthing like the one below:
+     *
+     *      <code>
+     *      &lt;tr&gt;
+     *       &lt;td valign="top" align="left"&gt;
+     *        &lt;a href="system?show=deployments"&gt;&lt;span class="subMenuOff"&gt;
+     *        &nbsp;&nbsp;&nbsp;Deployments
+     *        &lt;/span&gt;
+     *        &lt;/a&gt;&lt;/td&gt;
+     *      &lt;/tr&gt;
+     *      </code>
+     *
+     * Alternately, the bean can use the method formatSubMenuItem(..) which
+     * will create HTML like the one above
+     *
+     * @param body the output to write to
+     * @exception IOException if an exception is thrown
+     *
+     */
+    public void writeSubMenuItems(PrintWriter body) throws IOException {}
+
+}

Propchange: openejb/trunk/openejb3/server/openejb-webadmin/src/main/java/org/apache/openejb/webadmin/main/DeploymentListBean.java
------------------------------------------------------------------------------
    svn:executable = *