/*
 * Copyright 2006-2007 Queplix Corp.
 *
 * Licensed under the Queplix Public License, Version 1.1.1 (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.queplix.com/solutions/commercial-open-source/queplix-public-license/
 *
 * 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 com.queplix.core.modules.eqlext.ejb;

import com.queplix.core.error.ErrorHelper;
import com.queplix.core.integrator.security.LogonSession;
import com.queplix.core.modules.eql.CompoundKey;
import com.queplix.core.modules.eql.EQLERes;
import com.queplix.core.modules.eql.EQLRes;
import com.queplix.core.modules.eql.ejb.AbstractEQLSupportedEJB;
import com.queplix.core.modules.eql.ejb.LockManagerLocal;
import com.queplix.core.modules.eql.ejb.LockManagerLocalHome;
import com.queplix.core.modules.eql.error.EQLException;
import com.queplix.core.modules.eqlext.GetRecordsRes;
import com.queplix.core.modules.eqlext.actions.GRAction;
import com.queplix.core.utils.JNDINames;
import com.queplix.core.utils.xml.XMLHelper;

import java.io.PrintWriter;
import java.util.Properties;

/**
 * <p>Ext lock records session EJB</p>
 *
 * @author [ALB] Baranov Andrey
 * @version $Revision: 1.1.1.1 $ $Date: 2005/09/12 15:30:38 $
 */

public class LockRecordsEJB
        extends AbstractEQLSupportedEJB {

    // ----------------------------------------------------- public methods

    /**
     * Initialize bean
     */
    public void ejbCreate() {
        INFO("LockRecordsEJB create - " + hashCode());
    }

    /**
     * Execute lock records procedure
     *
     * @param entityName    entity name
     * @param compoundPkey  compound record pkey
     * @param focusId       web focus id
     * @param focusInstance web focus instance number
     * @param ls            security config
     * @throws EQLException
     */
    public void lock(String entityName,
                     CompoundKey compoundPkey,
                     String focusId,
                     Long focusInstance,
                     LogonSession ls)
            throws EQLException {
        lock(null, entityName, compoundPkey, focusId, focusInstance, ls);
    }

    /**
     * Execute lock records procedure
     *
     * @param out           PrintWriter object to write Ress response (if not NULL)
     * @param entityName    entity name
     * @param compoundPkey  compound record pkey
     * @param focusId       web focus id
     * @param focusInstance web focus instance number
     * @param ls            security config
     * @throws EQLException
     */
    public void lock(PrintWriter out,
                     String entityName,
                     CompoundKey compoundPkey,
                     String focusId,
                     Long focusInstance,
                     LogonSession ls)
            throws EQLException {

        long time = System.currentTimeMillis();
        GetRecordsRes grRes = null;

        try {
            // get current record(s)
            grRes = getCurrentRecords(entityName, compoundPkey, ls);

            // do lock
            getLockManagerLocal().lock((EQLERes) grRes.getEQLRes(), focusId,
                    focusInstance, ls);

            if(out != null) {
                // print out
                XMLHelper.writeObject(grRes.getRess(), out);
            }

        } catch (EQLException ex) {
            throw ex;

        } catch (Throwable t) {
            ErrorHelper.throwSystemException(t, this);
        }

        if(getLogger().isDebugEnabled()) {
            DEBUG("...lock records complete time(ms)=" + (
                    System.currentTimeMillis() - time));
        }
    }

    /**
     * Execute unlock records procedure
     *
     * @param entityName   entity name
     * @param compoundPkey compound record pkey
     * @param ls           security config
     * @throws EQLException
     */
    public void unlock(String entityName,
                       CompoundKey compoundPkey,
                       LogonSession ls)
            throws EQLException {

        long time = System.currentTimeMillis();

        try {
            // get current record(s)
            GetRecordsRes grRes = getCurrentRecords(entityName, compoundPkey,
                    ls);

            // do unlock
            getLockManagerLocal().unlock((EQLERes) grRes.getEQLRes(), ls);

        } catch (EQLException ex) {
            throw ex;

        } catch (Throwable t) {
            ErrorHelper.throwSystemException(t, this);
        }

        if(getLogger().isDebugEnabled()) {
            DEBUG("...unlock records complete time(ms)=" + (
                    System.currentTimeMillis() - time));
        }
    }

    /**
     * Execute ping records procedure
     *
     * @param entityName   entity name
     * @param compoundPkey compound record pkey
     * @param ls           security config
     * @throws EQLException
     */
    public void ping(String entityName,
                     CompoundKey compoundPkey,
                     LogonSession ls)
            throws EQLException {

        try {
            // get current record(s)
            GetRecordsRes grRes = getCurrentRecords(entityName, compoundPkey,
                    ls);

            // do ping
            getLockManagerLocal().ping((EQLERes) grRes.getEQLRes(), ls);

        } catch (EQLException ex) {
            throw ex;

        } catch (Throwable t) {
            ErrorHelper.throwSystemException(t, this);
        }
    }

    // ----------------------------------------------------- private methods

    // get current record(s)

    private GetRecordsRes getCurrentRecords(String entityName,
                                            CompoundKey compoundPkey,
                                            LogonSession ls)
            throws EQLException {

        Properties prop = new Properties();
        prop.setProperty(GRAction.IGNORE_SEND_ON_REQ_PARAM, "true");
        GetRecordsRes grRes = getGetRecordsLocal().process(entityName,
                compoundPkey, prop, ls);

        EQLRes eqlRes = grRes.getEQLRes();
        int countRecords = eqlRes.size();
        if(countRecords == 0) {
            // record not found - skip process
            throw new EQLException("Can't find record for locking. Entity '" +
                    entityName + "'. Keys: " + compoundPkey);
        }

        return grRes;
    }

    // get GetRecords local interface
    private GetRecordsLocal getGetRecordsLocal() {
        return (GetRecordsLocal) getLocalObject(JNDINames.GetRecords,
                GetRecordsLocalHome.class);
    }

    // get Lock Manager local interface
    private LockManagerLocal getLockManagerLocal() {
        return (LockManagerLocal) getLocalObject(JNDINames.LockManager,
                LockManagerLocalHome.class);
    }
}
