/*
 * Copyright (c) 2009-2011 by Bjoern Kolbeck,
 *               Zuse Institute Berlin
 *
 * Licensed under the BSD License, see LICENSE file for details.
 *
 */

package org.xtreemfs.dir.operations;

import java.io.IOException;

import org.xtreemfs.babudb.api.database.DatabaseRequestListener;
import org.xtreemfs.babudb.api.exception.BabuDBException;
import org.xtreemfs.dir.DIRRequest;
import org.xtreemfs.dir.DIRRequestDispatcher;
import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType;
import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno;

import com.google.protobuf.Message;

/**
 * 
 * @author bjko
 */
public abstract class DIROperation {

    protected final DIRRequestDispatcher master;

    public DIROperation(DIRRequestDispatcher master) {
        this.master = master;
    }

    public abstract int getProcedureId();

    /**
     * called after request was parsed and operation assigned.
     * 
     * @param rq
     *            the new request
     */
    public abstract void startRequest(DIRRequest rq);

    /**
     * Method to check if operation needs user authentication.
     * 
     * @return true, if the user needs to be authenticated
     */
    public abstract boolean isAuthRequired();

    protected abstract Message getRequestMessagePrototype();

    /**
     * parses the RPC request message. Can throw any exception which
     * will result in an error message telling the client that the
     * request message data is garbage.
     * @param rq
     * @throws java.lang.Exception
     */
    public void parseRPCMessage(DIRRequest rq) throws IOException {
        rq.deserializeMessage(getRequestMessagePrototype());
    }

    void requestFailed(BabuDBException error, DIRRequest rq) {
        assert(error != null);
        rq.sendError(ErrorType.ERRNO,POSIXErrno.POSIX_ERROR_EINVAL,error.toString());
    }

    /**
     * Operation to give a failure back to the client.
     * Will decide, if a {@link RedirectException} should be returned.
     * 
     * @param error - Exception thrown.
     * @param rq - original {@link DIRRequest}.
     */
    /*
    void requestFailed(Exception error, DIRRequest rq) {
        // handle connection errors caused by being not the replication master
        if (error != null && dbsReplicationManager != null
                && ((error instanceof BabuDBException
                && ((BabuDBException) error).getErrorCode().equals(NO_ACCESS)) || ( // TODO better exception handling
                error instanceof ConcurrentModificationException)) // && !dbsReplicationManager.isMaster() ... removed for testing
                ) {

            InetAddress altMaster = dbsReplicationManager.getMaster();
            if (altMaster != null) {
                // retrieve the correct port for the DIR mirror
                String host = altMaster.getHostAddress();
                Integer port = this.master.getConfig().getMirrors().get(host);
                if (port == null) {
                    Logging.logMessage(Logging.LEVEL_ERROR, this, "The port for "
                            + "the mirror DIR '%s' could not be retrieved.",
                            host);

                    rq.sendInternalServerError(error);
                } else {
                    rq.sendRedirectException(host, port);
                }
            } else {
                // if there is a handover in progress, redirect to the local
                // server to notify the client about this process
                InetAddress host = this.master.getConfig().getAddress();
                int port = this.master.getConfig().getPort();
                InetSocketAddress address =
                        (host == null)
                        ? new InetSocketAddress(port)
                        : new InetSocketAddress(host, port);

                rq.sendRedirectException(address.getAddress().getHostAddress(),
                        port);
            }
            // handle errors caused by ServerExceptions
        } else if (error != null && error instanceof ONCRPCException) {
            Logging.logError(Logging.LEVEL_ERROR, this, error);
            rq.sendException((ONCRPCException) error);> Na dann mal schöne Grüße!
> Christian

            // handle user errors
        } else if (error != null
                && error instanceof BabuDBException
                && (((BabuDBException) error).getErrorCode().equals(NO_SUCH_DB)
                || ((BabuDBException) error).getErrorCode().equals(DB_EXISTS)
                || ((BabuDBException) error).getErrorCode().equals(NO_SUCH_INDEX)
                || ((BabuDBException) error).getErrorCode().equals(NO_SUCH_SNAPSHOT)
                || ((BabuDBException) error).getErrorCode().equals(SNAP_EXISTS))) { // blame the client
            Logging.logError(Logging.LEVEL_ERROR, this, error);
            rq.sendException(new InvalidArgumentException(error.getMessage()));
            // handle unknown errors
        } else {
            if (error != null && !(error instanceof BabuDBException)) {
                Logging.logError(Logging.LEVEL_ERROR, this, error);
            }

            if (error != null) {
                Logging.logError(Logging.LEVEL_ERROR, this, error);
            }

            rq.sendInternalServerError(error);
        }
    }*/

    /**
     * Method-interface for sending a response 
     * 
     * @param result - can be null, if not necessary.
     * @param rq - original {@link DIRRequest}.
     */
    abstract void requestFinished(Object result, DIRRequest rq);

    /**
     * Listener implementation for non-blocking BabuDB requests.
     * 
     * @author flangner
     * @since 11/16/2009
     * @param <I> - input type.
     * @param <O> - output type.
     */
    abstract class DBRequestListener<I, O> implements DatabaseRequestListener<I> {

        private final boolean finishRequest;

        DBRequestListener(boolean finishRequest) {
            this.finishRequest = finishRequest;
        }

        abstract O execute(I result, DIRRequest rq) throws Exception;

        /*
         * (non-Javadoc)
         * @see org.xtreemfs.babudb.BabuDBRequestListener#failed(org.xtreemfs.babudb.BabuDBException, java.lang.Object)
         */
        @Override
        public void failed(BabuDBException error, Object request) {
            requestFailed(error, (DIRRequest) request);
        }

        /*
         * (non-Javadoc)
         * @see org.xtreemfs.babudb.BabuDBRequestListener#finished(java.lang.Object, java.lang.Object)
         */
        @Override
        public void finished(I data, Object context) {
            try {
                O result = execute(data, (DIRRequest) context);
                if (finishRequest) {
                    requestFinished(result, (DIRRequest) context);
                }
            } catch (IllegalArgumentException ex) {
                DIRRequest rq = (DIRRequest) context;
                rq.sendError(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, ex.toString());
            } catch (java.util.ConcurrentModificationException ex) {
                DIRRequest rq = (DIRRequest) context;
                rq.sendError(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EAGAIN, ex.toString());
            } catch (Exception e) {
                DIRRequest rq = (DIRRequest) context;
                rq.sendInternalServerError(e);
            }
        }
    }
}

@@ -4211,47 +4211,8 @@
 or);
-%3E Na dann mal sch%C3%B6ne Gr%C3%BC%C3%9Fe!%0A%3E Christian
 %0A%0A  

Removed unnecessary text.