<%
/**
 * $RCSfile: setup3.jsp,v $
 * $Revision: 1.1.1.1 $
 * $Date: 2002/09/09 13:50:32 $
 *
 * Copyright (C) 1999-2001 CoolServlets, Inc. All rights reserved.
 *
 * This software is the proprietary information of CoolServlets, Inc.
 * Use is subject to license terms.
 */
%>

<%@ page import="java.io.*,
                 java.lang.reflect.*,
                 java.util.*,
                 java.sql.*,
                 java.beans.*,
                 com.jivesoftware.forum.*,
                 com.jivesoftware.forum.util.*,
                 com.jivesoftware.forum.database.*"%>

<%! // global methods/classes/variables

    /**
     * A helper class for comparing PropertyDescriptor objects.
     */
    class PropertyDescriptorComparator implements Comparator {
        public static final int NAME = 1;
        public static final int DISPLAY_NAME = 2;
        public static final int CLASS_NAME = 3;
        public static final int SORT_ORDER = 4;
        private int field = NAME;

        public PropertyDescriptorComparator(int field) {
            this.field = field;
        }
        public int compare(Object obj1, Object obj2) {
            PropertyDescriptor pd1 = (PropertyDescriptor)obj1;
            PropertyDescriptor pd2 = (PropertyDescriptor)obj2;
            if (field == NAME) {
                return (pd1.getName().compareTo(pd2.getName()));
            }
            else if (field == DISPLAY_NAME) {
                return (pd1.getDisplayName().compareTo(pd2.getDisplayName()));
            }
            else if (field == CLASS_NAME) {
                String pd1Classname = pd1.getClass().getName();
                String pd2Classname = pd2.getClass().getName();
                return (pd1Classname.compareTo(pd2Classname));
            }
            else {
                return 0;
            }
        }
        public boolean equals(Object obj) {
            return true;
        }
    }

    /**
     *
     */
    private static final String getHTML(HttpServletRequest request,
            ConnectionProvider conProvider, PropertyDescriptor descriptor)
    {
        // HTML of the customizer for this property
        String HTML = null;
        // Get the name of the property (this becomes the name of the form element)
        String propName = descriptor.getName();
        // Get the parameter value
        String paramValue = request.getParameter(propName);
        // Reader method
        Method readMethod = descriptor.getReadMethod();
        // Get the current value of the property
        Object value = null;
        try {
            value = readMethod.invoke(conProvider, null);
        }
        catch (Exception e) {}
        // Get the class of this property
        Class propClass = descriptor.getPropertyType();
        String className = propClass.getName();
        if ("int".equals(className) ||
            "double".equals(className) ||
            "long".equals(className))
        {
            HTML = "<input type=\"text\" name=\"" + propName + "\" size=\"6\" maxlength=\"10\"";
            if (paramValue != null) {
                HTML += " value=\"" + paramValue + "\"";
            }
            else if (value != null) {
                HTML += " value=\"" + value.toString() + "\"";
            }
            HTML += ">";
        }
        else if ("java.lang.String".equals(className)) {
            if (propName.toLowerCase().equals("password")) {
                HTML = "<input type=\"password\"";
            }
            else {
                HTML = "<input type=\"text\"";
            }
            HTML += " name=\"" + propName + "\" size=\"30\" maxlength=\"150\"";
            if (paramValue != null) {
                HTML += " value=\"" + paramValue + "\"";
            }
            else if (value != null) {
                HTML += " value=\"" + value.toString() + "\"";
            }
            HTML += ">";
        }
        else {
            return null;
        }
        return HTML;
    }

    /**
     *
     */
    private static final boolean isParameterValid(HttpServletRequest request,
            ConnectionProvider conProvider, PropertyDescriptor descriptor)
    {
        boolean isValid = true;
        // Name of this parameters
        String name = descriptor.getName();
        // Get the parameter value
        String value = request.getParameter(name);
        // Get the class of this property
        String className = descriptor.getPropertyType().getName();
        try {
            if ("int".equals(className)) {
                if (value != null && !value.equals("")) {
                    if (Integer.parseInt(value) < 0) {
                        isValid = false;
                    }
                }
            }
            else if ("double".equals(className)) {
                if (value != null && !value.equals("")) {
                    if (Double.parseDouble(value) < 0.0) {
                        isValid = false;
                    }
                }
            }
            else if ("java.lang.String".equals(className)) {
                if (value == null || value.equals("")) {
                    isValid = false;
                }
            }
        }
        catch (Exception e) {
            isValid = false;
        }
        return isValid;
    }

    private static final PropertyDescriptor getPropertyDescriptor(PropertyDescriptor[] pd,
            String name)
    {
        for (int i=0; i<pd.length; i++) {
            if (name.equals(pd[i].getName())) {
                return pd[i];
            }
        }
        return null;
    }
%>

<%  // Figure out if we need to stay on this page or go to setup4.jsp
    if ("true".equals((String)session.getAttribute("setup3.done"))) {
        response.sendRedirect("setup4.jsp");
        return;
    }


    // Get the global Jive locale
	Locale locale = JiveGlobals.getLocale();
	// Set the JSP page to use the Jive locale
	response.setLocale(locale);
	// Load the appropriate resource bundle to display the page.
	ResourceBundle bundle = SkinUtils.getResourceBundle("skin_admin_setup", locale);

    // Load error messages from the bundle
    HashMap dbFieldErrorMessages = new HashMap();
    dbFieldErrorMessages.put("driver",bundle.getString("setup3.driver_errorMessage"));
    dbFieldErrorMessages.put("serverURL",bundle.getString("setup3.serverURL_errorMessage"));
    dbFieldErrorMessages.put("username",bundle.getString("setup3.username_errorMessage"));
    dbFieldErrorMessages.put("password",bundle.getString("setup3.password_errorMessage"));
    dbFieldErrorMessages.put("minConnections",bundle.getString("setup3.minConnections_errorMessage"));
    dbFieldErrorMessages.put("maxConnections",bundle.getString("setup3.maxConnections_errorMessage"));
    dbFieldErrorMessages.put("connectionTimeout",bundle.getString("setup3.connectionTimeout_errorMessage"));

    // Collect info about the database connection manager. The Jive connection
    // manager is really a bean, so we're going to use the BeanInfo introspection
    // classes to get and set its properties.

    // Get the Jive database connection provider.
    ConnectionProvider conProvider = new DefaultConnectionProvider();
    // Get the BeanInfo object associated with it (will load
    // com.jivesoftware.forum.database.DefaultConnectionProviderBeanInfo)
	BeanInfo beanInfo = Introspector.getBeanInfo(conProvider.getClass());
	// Get the connection provider's properties:
    PropertyDescriptor[] propDescriptors = beanInfo.getPropertyDescriptors();
    // Hard code the order of property descriptors
    String[] propertyNames = DefaultConnectionProviderBeanInfo.PROPERTY_NAMES;

    // Get parameters
    boolean validate = ParamUtils.getBooleanParameter(request,"validate");

    // Collect the database field prop values from the parameters, if requested
    // and validate the fields if necessary
    boolean errors = false;
    boolean[] validFields = new boolean[propDescriptors.length];
    if (validate) {
        for (int i=0; i<propertyNames.length; i++) {
            PropertyDescriptor descriptor = getPropertyDescriptor(propDescriptors, propertyNames[i]);
            String propName = descriptor.getName();
            validFields[i] = isParameterValid(request, conProvider, descriptor);
            if (!validFields[i]) {
                errors = true;
            }
            else {
                // field specific validation
                if (propName.equals("driver")) {
                    // try to load the driver
                    String driver = ParamUtils.getParameter(request,"driver");
                    try {
                        Class.forName(driver);
                    }
                    catch (Exception e) {
                        validFields[i] = false;
                        errors = true;
                    }
                }
            }
        }
    }

    // Get all of the parameters
    String driver = ParamUtils.getParameter(request,"driver");
    String serverURL = ParamUtils.getParameter(request,"serverURL");
    String username = ParamUtils.getParameter(request,"username");
    String password = ParamUtils.getParameter(request,"password");
    double connectionTimeout = ParamUtils.getDoubleParameter(request,"connectionTimeout",0.0);
    int maxConnections = ParamUtils.getIntParameter(request,"maxConnections",-1);
    int minConnections = ParamUtils.getIntParameter(request,"minConnections",-1);

    // Test the connection to the database if there are no errors and all fields
    // have been validated
    boolean conErrors = false;
    String conErrorMessage = null;
    if (!errors && validate) {
        // set all values passed in
        PropertyDescriptor descriptor = null;
        Method writeMethod = null;
        Object[] args = null;

        // ints: maxConnections, minConnections
        descriptor = getPropertyDescriptor(propDescriptors,"minConnections");
        writeMethod = descriptor.getWriteMethod();
        args = new Integer[1];
        args[0] = new Integer(minConnections);
        writeMethod.invoke(conProvider, args);

        descriptor = getPropertyDescriptor(propDescriptors,"maxConnections");
        writeMethod = descriptor.getWriteMethod();
        args = new Integer[1];
        args[0] = new Integer(maxConnections);
        writeMethod.invoke(conProvider, args);

        // double: connectionTimeout
        descriptor = getPropertyDescriptor(propDescriptors,"connectionTimeout");
        writeMethod = descriptor.getWriteMethod();
        args = new Double[1];
        args[0] = new Double(connectionTimeout);
        writeMethod.invoke(conProvider, args);

        // Strings: driver, serverURL, username and password
        descriptor = getPropertyDescriptor(propDescriptors,"driver");
        writeMethod = descriptor.getWriteMethod();
        args = new String[1];
        args[0] = driver;
        writeMethod.invoke(conProvider, args);

        descriptor = getPropertyDescriptor(propDescriptors,"serverURL");
        writeMethod = descriptor.getWriteMethod();
        args = new String[1];
        args[0] = serverURL;
        writeMethod.invoke(conProvider, args);

        descriptor = getPropertyDescriptor(propDescriptors,"username");
        writeMethod = descriptor.getWriteMethod();
        args = new String[1];
        args[0] = username;
        writeMethod.invoke(conProvider, args);

        descriptor = getPropertyDescriptor(propDescriptors,"password");
        writeMethod = descriptor.getWriteMethod();
        args = new String[1];
        args[0] = password;
        writeMethod.invoke(conProvider, args);

        ConnectionManager.setConnectionProvider(conProvider);
        Connection con = null;
        try {
            con = ConnectionManager.getConnection();
            if (con == null) {
                conErrors = true;
                conErrorMessage = "A connection to the database could not be "
                    + "made. View the error message by opening the "
                    + "\"jiveHome\\logs\\DefaultConnectionProvider.log\" log "
                    + "file, then go back to fix the problem.";
            }
            else {
            	// See if the Jive db schema is installed.
            	try {
            		java.sql.Statement stmt = con.createStatement();
            		// Pick an arbitrary table to see if it's there.
            		stmt.executeQuery("SELECT * FROM jiveID");
            		stmt.close();
            	}
            	catch (SQLException sqle) {
            		sqle.printStackTrace();
            		conErrors = true;
            		conErrorMessage = "The Jive Forums database schema does not "
                        + "appear to be installed. Follow the installation guide to "
                        + "fix this error.";
            	}
            }
        }
        finally {
            try {
        	    con.close();
            } catch (Exception ignored) {}
        }
    }

    if (!errors && !conErrors && validate) {
        // set all the values
        response.sendRedirect("setup4.jsp");
        return;
    }
%>

<%@ include file="include/global.jsp" %>

<%@ include file="include/header.jsp" %>

<table cellpadding="6" cellspacing="0" border="0" width="100%">
<tr>
<td width="1%" valign="top">
<%  // set sidebar properties
    session.setAttribute("sidebar.2.active", new Boolean(true));
    if (!GREEN.equals(getSessionString(session,"sidebar.2.light"))) {
        session.setAttribute("sidebar.2.light", YELLOW);
    }
%>
<%@ include file="include/sidebar.jsp" %>
</td>
<td width="99%" valign="top">

    <b><%= bundle.getString("setup3.header") %></b>
    <hr size="0">

    <font size="-1">
    <%= bundle.getString("setup3.top_msg") %>
    </font>
    <p>

    <%  if (conErrors) { %>
        <font size="-1" color="#ff0000">
        <%= conErrorMessage %>
        <p>
        </font>
    <%  } %>

<form action="setup3.jsp" method="post">
<input type="hidden" name="validate" value="true">

<table cellpadding="4" cellspacing="0" border="0">
<%  int row = 0;
    for (int i=0; i<propertyNames.length; i++) {
        PropertyDescriptor descriptor = getPropertyDescriptor(propDescriptors, propertyNames[i]);
        String propName = descriptor.getName();
        String errorMessage = (String)dbFieldErrorMessages.get(propName);
        String bgcolor = (row++%2==0)?"#f2f8ff":"#ffffff";
%>
<tr bgcolor="<%= bgcolor %>">
    <td width="1%" nowrap>
        <font size="-1">
        <%= descriptor.getDisplayName() %>
        </font>
    </td>
    <td width="1%"><%= getHTML(request, conProvider,descriptor) %></td>
    <td width="98%">&nbsp;</td>
</tr>
<tr bgcolor="<%= bgcolor %>">
    <td colspan="3">
        <table cellpadding="0" cellspacing="0" width="100%" border="0">
        <td width="1%"><img src="images/blank.gif" width="25" height="1" border="0"></td>
        <td width="99%">
        <font size="-2">
<%      if (validate && !validFields[i]) { %>
        <font color="#cc3300"><%= errorMessage %></font>
        <br>
<%      } %>
        <%= descriptor.getShortDescription() %>
        </font>
        </td>
        </table>
    </td>
</tr>
<%  } %>
</table>

<p>

<hr size="0">
<div align="center">
<input type="submit" value="Test Connection...">
<br>
<font size="-2">(This may take up to a minute)</font>
</form>
</div>

</form>

<%@ include file="include/footer.jsp" %>

</td>
</tr>
</table>

