/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.cocoon.acting;

import org.apache.avalon.excalibur.datasource.DataSourceComponent;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.thread.ThreadSafe;
import org.apache.cocoon.Constants;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Redirector;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.SourceResolver;
import org.apache.commons.lang.StringUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

/**
 * Select a record from a database. If request parameters are present,
 * their values are used to populate request attributes. Otherwise,
 * values from database are used.
 *
 * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
 * @author <a href="mailto:vgritsenko@apache.org">Vadim Gritsenko</a>
 * @version CVS $Id$
 */
public class DatabaseSelectAction extends AbstractDatabaseAction implements ThreadSafe {

    private static final Map selectStatements = new HashMap();

    /**
     * Select a record from the database.  This action assumes that
     * the file referenced by the "descriptor" parameter conforms
     * to the AbstractDatabaseAction specifications.
     */
    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters param) throws Exception {
        DataSourceComponent datasource = null;
        Connection conn = null;
        int currentIndex = 0;

        // read global parameter settings
        boolean reloadable = Constants.DESCRIPTOR_RELOADABLE_DEFAULT;
        if (this.settings.containsKey("reloadable"))
            reloadable = Boolean.valueOf((String) this.settings.get("reloadable")).booleanValue();
        // read local parameter settings
        try {
            Configuration conf =
                this.getConfiguration(param.getParameter("descriptor", (String) this.settings.get("descriptor")),
                                      resolver,
                                      param.getParameterAsBoolean("reloadable",reloadable));

            Request request = ObjectModelHelper.getRequest(objectModel);

            Configuration[] keys = conf.getChild("table").getChild("keys").getChildren("key");
            Configuration[] values = conf.getChild("table").getChild("values").getChildren("value");

            PreparedStatement statement = null;
            ResultSet rset = null;
            boolean result = false;

            for (int i = 0; i < keys.length; i++) {
                final String parameter = keys[i].getAttribute("param");
                Object value = request.getParameter(parameter);
                if (StringUtils.isEmpty((String)value)) {
                    if (statement == null) {
                        final String query = this.getSelectQuery(conf);
                        datasource = this.getDataSource(conf);
                        conn = datasource.getConnection();
                        statement = conn.prepareStatement(query);
                        currentIndex = 1;
                        for (int j = 0; j < keys.length; j++, currentIndex++) {
                            this.setColumn(statement, currentIndex, request, keys[j]);
                        }
                        rset = statement.executeQuery();
                        result = rset.next();
                    }
                    if (result) {
                        value = this.getColumn(rset, request, keys[i]);
                    }
                }
                if (value != null) {
                    request.setAttribute(parameter, value.toString());
                }
            }

            for (int i = 0; i < values.length; i++) {
                final String parameter = values[i].getAttribute("param");
                Object value = request.getParameter(parameter);
                if (StringUtils.isEmpty((String)value)) {
                    if (statement == null) {
                        final String query = this.getSelectQuery(conf);
                        datasource = this.getDataSource(conf);
                        conn = datasource.getConnection();
                        statement = conn.prepareStatement(query);
                        currentIndex = 1;
                        for (int j = 0; j < keys.length; j++, currentIndex++) {
                            this.setColumn(statement, currentIndex, request, keys[j]);
                        }
                        rset = statement.executeQuery();
                        result = rset.next();
                    }
                    if (result) {
                        value = this.getColumn(rset, request, values[i]);
                    }
                }
                if (value != null) {
                    request.setAttribute(parameter, value.toString());
                }
            }
            if(statement != null) {
                statement.close();
            }
            return EMPTY_MAP;
        } catch (Exception e) {
            throw new ProcessingException("Could not prepare statement :position = " + currentIndex, e);
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException sqe) {
                    getLogger().warn("There was an error closing the datasource", sqe);
                }
            }
            if (datasource != null) {
                this.dbselector.release(datasource);
            }
        }

        // Result is empty map or exception. No null.
    }

    /**
     * Get the String representation of the PreparedStatement.  This is
     * mapped to the Configuration object itself, so if it doesn't exist,
     * it will be created.
     */
    protected String getSelectQuery(Configuration conf) throws ConfigurationException {
        String query = null;

        synchronized (DatabaseSelectAction.selectStatements) {
            query = (String)DatabaseSelectAction.selectStatements.get(conf);

            if (query == null) {
                Configuration table = conf.getChild("table");
                Configuration[] keys = table.getChild("keys").getChildren("key");
                Configuration[] values = table.getChild("values").getChildren("value");

                StringBuffer queryBuffer = new StringBuffer("SELECT ");
                queryBuffer.append(buildList(keys, 0));
                queryBuffer.append(buildList(values, keys.length));
                queryBuffer.append(" FROM ");
                queryBuffer.append(table.getAttribute("name"));

                queryBuffer.append(" WHERE ");
                queryBuffer.append(buildList(keys, " AND "));
                query = queryBuffer.toString();

                DatabaseSelectAction.selectStatements.put(conf, query);
            }
        }
        return query;
    }
}