org.globus.ftp.dc.AbstractDataChannel.java Source code

Java tutorial

Introduction

Here is the source code for org.globus.ftp.dc.AbstractDataChannel.java

Source

/*
 * Copyright 1999-2006 University of Chicago
 *
 * Licensed 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.globus.ftp.dc;

import java.util.Map;
import java.util.HashMap;

import org.globus.ftp.GridFTPSession;
import org.globus.ftp.Session;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public abstract class AbstractDataChannel implements DataChannel {

    private static Log logger = LogFactory.getLog(AbstractDataChannel.class.getName());

    protected Session session;

    protected static Map dataHandlers;

    private static final int SOURCE = 1;
    private static final int SINK = 2;

    static {
        try {

            // Stream [Image/Ascii] Reader and Writer support

            registerHandler(Session.MODE_STREAM, Session.TYPE_IMAGE, SOURCE, StreamImageDCReader.class);

            registerHandler(Session.MODE_STREAM, Session.TYPE_ASCII, SOURCE, StreamAsciiDCReader.class);

            registerHandler(Session.MODE_STREAM, Session.TYPE_IMAGE, SINK, StreamImageDCWriter.class);

            registerHandler(Session.MODE_STREAM, Session.TYPE_ASCII, SINK, StreamAsciiDCWriter.class);

            // EBlock

            registerHandler(GridFTPSession.MODE_EBLOCK, Session.TYPE_IMAGE, SOURCE, EBlockImageDCReader.class);

            registerHandler(GridFTPSession.MODE_EBLOCK, Session.TYPE_IMAGE, SINK, EBlockImageDCWriter.class);

            // EBlock ASCII modes not supported

        } catch (Exception e) {
            throw new RuntimeException("Failed to install default data channel handlers: " + e.getMessage());
        }
    }

    public AbstractDataChannel(Session session) {
        this.session = session;
    }

    public static void registerHandler(int transferMode, int transferType, int type, Class clazz) throws Exception {
        switch (type) {
        case SOURCE:
            if (!DataChannelReader.class.isAssignableFrom(clazz)) {
                throw new Exception("Incorrect type");
            }
            break;
        case SINK:
            if (!DataChannelWriter.class.isAssignableFrom(clazz)) {
                throw new Exception("Incorrect type");
            }
            break;
        default:
            throw new IllegalArgumentException("Type not supported: " + type);
        }

        String id = getHandlerID(transferMode, transferType, type);

        if (dataHandlers == null) {
            dataHandlers = new HashMap();
        }

        // Allow for overwrites
        /*
        if (dataHandlers.get(id) != null) {
            throw new Exception("Handler already registered.");
        }
        */

        logger.debug("registering handler for class " + clazz.toString() + "; id = " + id);
        dataHandlers.put(id, clazz);
    }

    /**
     * Tests if the client supports specified transfer type and mode
     * (the client can read data in specific type & mode from the
     * data connection)
     */
    public boolean isDataSourceModeSupported() {
        String id = getHandlerID(session.transferMode, session.transferType, SOURCE);
        return (dataHandlers.get(id) != null);
    }

    /**
     * Tests if the client supports specified transfer type and mode
     * (the client can write data in specific type & mode to the
     * data connection)
     */
    public boolean isDataSinkModeSupported() {
        String id = getHandlerID(session.transferMode, session.transferType, SINK);
        return (dataHandlers.get(id) != null);
    }

    // currently context is only needed in case of EBlock mode

    public DataChannelReader getDataChannelSource(TransferContext context) throws Exception {
        String id = getHandlerID(session.transferMode, session.transferType, SOURCE);
        logger.debug("type/mode: " + id);
        Class clazz = (Class) dataHandlers.get(id);
        if (clazz == null) {
            throw new Exception("No data reader for type/mode" + id);
        }
        DataChannelReader reader = (DataChannelReader) clazz.newInstance();
        if (reader instanceof EBlockAware) {
            ((EBlockAware) reader).setTransferContext((EBlockParallelTransferContext) context);
        }
        return reader;
    }

    public DataChannelWriter getDataChannelSink(TransferContext context) throws Exception {
        String id = getHandlerID(session.transferMode, session.transferType, SINK);
        Class clazz = (Class) dataHandlers.get(id);
        if (clazz == null) {
            throw new Exception("No data reader for type/mode");
        }
        DataChannelWriter writer = (DataChannelWriter) clazz.newInstance();
        if (writer instanceof EBlockAware) {
            ((EBlockAware) writer).setTransferContext((EBlockParallelTransferContext) context);
        }
        return writer;
    }

    // it is important for this method to handle all possible
    // mode/transfer types
    private static String getHandlerID(int transferMode, int transferType, int type) {
        String id = "";

        switch (transferMode) {
        case Session.MODE_STREAM:
            id += "S-";
            break;
        case GridFTPSession.MODE_EBLOCK:
            id += "E-";
            break;
        default:
            throw new IllegalArgumentException("Mode not supported: " + transferMode);
        }

        switch (transferType) {
        case Session.TYPE_IMAGE:
            id += "I-";
            break;
        case Session.TYPE_ASCII:
            id += "A-";
            break;
        default:
            throw new IllegalArgumentException("Type not supported: " + transferType);
        }

        switch (type) {
        case SOURCE:
            id += "R";
            break;
        case SINK:
            id += "W";
            break;
        default:
            throw new IllegalArgumentException("Type not supported: " + type);
        }

        if (id.equals("")) {
            return null;
        }
        return id;
    }

}