/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 2003-2004 Bull S.A.
 * Contact: jonas-team@ow2.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */

package org.ow2.jonas.webapp.jonasadmin.catalina;

import java.io.IOException;
import java.net.InetAddress;
import java.util.Iterator;

import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.ow2.jonas.lib.management.extensions.base.JonasManagementRepr;
import org.ow2.jonas.webapp.jonasadmin.Jlists;
import org.ow2.jonas.webapp.jonasadmin.WhereAreYou;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;

/**
 * @author Michel-Ange ANTON
 * @author Adriana Danes
 * - update to Tomact 5.0
 * - update to Tomact 5.5 (04/2005)
 */
public class EditConnectorAction extends CatalinaBaseAction {

// --------------------------------------------------------- Public Methods

    public ActionForward executeAction(ActionMapping pMapping, ActionForm pForm
        , HttpServletRequest pRequest, HttpServletResponse pResponse)
        throws IOException, ServletException {

        // Current JOnAS server name
        String serverName = m_WhereAreYou.getCurrentJonasServerName();

        // Current Tomcat Connector MBean (to be used to create form)
        ObjectName oObjectName = null;

        // Selected Tomcat Connector MBean
        ObjectName selectObjectName = null;
        try {
            selectObjectName = new ObjectName(pRequest.getParameter("select"));
        } catch (Exception e) {
            m_Errors.add("select", new ActionMessage("error.catalina.connector.select.bad"
                , pRequest.getParameter("select")));
            addGlobalError(e);
            saveErrors(pRequest, m_Errors);
            return (pMapping.findForward("Global Error"));
        }
        String selectedPort = selectObjectName.getKeyProperty("port");
        String selectedAddress = selectObjectName.getKeyProperty("address");
        // Check InetAddress corectness (get round Tomcat bug)
        if (selectedAddress != null) {
            boolean fromTreeBuilder = false;
            if (selectedAddress.startsWith("/")) {
                // We come fropm the tree builder
                selectedAddress = selectedAddress.substring(1);
                fromTreeBuilder = true;
            }
            ObjectName o;
            try {
                o = ObjectName.getInstance(m_WhereAreYou.getCurrentDomainName() + ":type=Connector,port=" + selectedPort + ",*");
            } catch (MalformedObjectNameException e) {
                addGlobalError(e);
                saveErrors(pRequest, m_Errors);
                return (pMapping.findForward("Global Error"));
            }
            Iterator it = JonasManagementRepr.queryNames(o, serverName).iterator();
            while (it.hasNext()) {
                ObjectName on = (ObjectName) it.next();
                if (on.getKeyProperty("port").equals(selectedPort)) {
                    String foundAddress = on.getKeyProperty("address");
                    if (foundAddress != null) {
                        if (fromTreeBuilder) {
                            // starting / in selected address was eliminated
                            if (foundAddress.endsWith(selectedAddress)) {
                                oObjectName = on;
                                break;
                            }
                        } else {
                            // selected address starts with %2F
                            if (foundAddress.equals(selectedAddress)) {
                                // now we can eliminate the %2F
                                if (selectedAddress.startsWith("%2F")) {
                                    selectedAddress = selectedAddress.substring(3);
                                }
                                oObjectName = on;
                                break;
                            }

                        }
                    }
                }
            }
            // be sure oObjectName not null
            if (oObjectName == null) {
                oObjectName = selectObjectName;
            }
        } else {
            // use selected ObjectName directly
            oObjectName = selectObjectName;
        }

        // Fill in the form values for display and editing
        ConnectorForm oForm = new ConnectorForm();
        m_Session.setAttribute("catalinaConnectorForm", oForm);
        oForm.setAction("edit");
        oForm.setObjectName(oObjectName.toString());
        oForm.setBooleanVals(Jlists.getBooleanValues());
        // Populate
        try {
            // Determine connector type
            String sHandlerClassName = getStringAttribute(oObjectName, "protocolHandlerClassName");
            int period = sHandlerClassName.lastIndexOf('.');
            String sHandlerType = sHandlerClassName.substring(period + 1);
            if ("JkCoyoteHandler".equalsIgnoreCase(sHandlerType)) {
                oForm.setConnectorType("AJP");
            } else if ("Http11Protocol".equalsIgnoreCase(sHandlerType)) {
                if ("http".equalsIgnoreCase(oForm.getScheme())) {
                    oForm.setConnectorType("HTTP");
                } else if ("https".equalsIgnoreCase(oForm.getScheme())) {
                    oForm.setConnectorType("HTTPS");
                }
            } else {
                oForm.setConnectorType("????");
            }
            // Common properties
            oForm.setAllowTrace(getBooleanAttribute(oObjectName, "allowTrace"));
            oForm.setEmptySessionPath(getBooleanAttribute(oObjectName, "emptySessionPath"));
            oForm.setEnableLookups(getBooleanAttribute(oObjectName, "enableLookups"));
            oForm.setMaxPostSizeText(toStringIntegerAttribute(oObjectName, "maxPostSize"));
            oForm.setProtocol(getStringAttribute(oObjectName, "protocol"));
            oForm.setProxyName(getStringAttribute(oObjectName, "proxyName"));
            oForm.setProxyPortText(toStringIntegerAttribute(oObjectName, "proxyPort"));
            oForm.setRedirectPortText(toStringIntegerAttribute(oObjectName, "redirectPort"));
            oForm.setScheme(getStringAttribute(oObjectName, "scheme"));
            oForm.setSecure(getBooleanAttribute(oObjectName, "secure"));
            oForm.setURIEncoding(getStringAttribute(oObjectName, "URIEncoding"));
            oForm.setUseBodyEncodingForURI(getBooleanAttribute(oObjectName, "useBodyEncodingForURI"));
            oForm.setXpoweredBy(getBooleanAttribute(oObjectName, "xpoweredBy"));
            // Coyote Connector properties
            oForm.setAcceptCountText(toStringIntegerAttribute(oObjectName, "acceptCount"));

            InetAddress inetAddress = (InetAddress) JonasManagementRepr.getAttribute(oObjectName, "address", serverName);
            if (inetAddress != null) {
                oForm.setAddress(inetAddress.toString());
            }
            oForm.setPortText(toStringIntegerAttribute(oObjectName, "port"));
            oForm.setRedirectPortText(toStringIntegerAttribute(oObjectName, "redirectPort"));
            oForm.setTcpNoDelay(getBooleanAttribute(oObjectName, "tcpNoDelay"));
            // ------ Threads management
            oForm.setMaxThreadsText(toStringIntegerAttribute(oObjectName, "maxThreads"));
            oForm.setMinSpareThreadsText(getStringAttribute(oObjectName, "minSpareThreads"));
            oForm.setMaxSpareThreadsText(getStringAttribute(oObjectName, "maxSpareThreads"));
            // In Tomcat 5.5.17 these attributes hade integer type
            //oForm.setMinSpareThreadsText(toStringIntegerAttribute(oObjectName, "minSpareThreads"));
            //oForm.setMaxSpareThreadsText(toStringIntegerAttribute(oObjectName, "maxSpareThreads"));

            // Supported by HTTP and HTTPS only
            if (!("AJP".equalsIgnoreCase(oForm.getConnectorType()))) {
                oForm.setBufferSizeText(toStringIntegerAttribute(oObjectName, "bufferSize"));
                oForm.setCompression(getStringAttribute(oObjectName, "compression"));
                oForm.setConnectionLingerText(toStringIntegerAttribute(oObjectName, "connectionLingerText"));
                oForm.setConnTimeOutText(toStringIntegerAttribute(oObjectName, "connectionTimeout"));
                oForm.setConnectionUploadTimeoutText(toStringIntegerAttribute(oObjectName, "connectionUploadTimeout"));
                oForm.setDisableUploadTimeout(getBooleanAttribute(oObjectName, "disableUploadTimeout"));
                oForm.setMaxHttpHeaderSizeText(toStringIntegerAttribute(oObjectName, "maxHttpHeaderSize"));
                oForm.setMaxKeepAliveRequestsText(toStringIntegerAttribute(oObjectName, "maxKeppAliveRequests"));
                oForm.setStrategy(getStringAttribute(oObjectName, "strategy"));
                oForm.setThreadPriorityText(toStringIntegerAttribute(oObjectName, "threadPriority"));
            }
            // Supported by AJP only
            if (oForm.getConnectorType() == "AJP") {
                oForm.setOutputBufferSizeText(toStringIntegerAttribute(oObjectName, "bufferSize"));
                oForm.setTomcatAuthentication(getBooleanAttribute(oObjectName, "tomcatAuthentication"));
            }
            // SSL Support
            if ("HTTPS".equalsIgnoreCase(oForm.getConnectorType())) {
                // These are set only for SSL connectors.
                oForm.setAlgorithm(getStringAttribute(oObjectName, "algorithm"));
                oForm.setClientAuth(getBooleanAttribute(oObjectName, "clientAuth"));
                oForm.setKeystoreFile(getStringAttribute(oObjectName, "keystoreFile"));
                oForm.setKeystorePass(getStringAttribute(oObjectName, "keystorePass"));
                oForm.setKeystoreType(getStringAttribute(oObjectName, "keystoreType"));
                oForm.setSslProtocol(getStringAttribute(oObjectName, "sslProtocol"));
                oForm.setCiphers(getStringAttribute(oObjectName, "ciphers"));
            }

            // Force the node selected in tree
            String nodeName = getTreeBranchName(DEPTH_SERVER) + WhereAreYou.NODE_SEPARATOR
                + "protocols" + WhereAreYou.NODE_SEPARATOR
                + "connectors" + WhereAreYou.NODE_SEPARATOR
                + m_WhereAreYou.getCurrentCatalinaDomainName() + WhereAreYou.NODE_SEPARATOR
                + oForm.getPortText();
            if (selectedAddress != null) {
                nodeName = nodeName + selectedAddress;
            }
            m_WhereAreYou.selectNameNode(nodeName, true);
        } catch (Throwable t) {
            addGlobalError(t);
            saveErrors(pRequest, m_Errors);
            return (pMapping.findForward("Global Error"));
        }
        // Forward to the connector display page
        return (pMapping.findForward("Catalina Connector"));
    }
}
