All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.firebirdsql.gds.ng.AbstractFbService Maven / Gradle / Ivy

There is a newer version: 4.0.10.java7
Show newest version
/*
 * Firebird Open Source JavaEE Connector - JDBC Driver
 *
 * Distributable under LGPL license.
 * You may obtain a copy of the License at http://www.gnu.org/copyleft/lgpl.html
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * LGPL License for more details.
 *
 * This file was created by members of the firebird development team.
 * All individual contributions remain the Copyright (C) of those
 * individuals.  Contributors to this file are either listed here or
 * can be obtained from a source control history command.
 *
 * All rights reserved.
 */
package org.firebirdsql.gds.ng;

import org.firebirdsql.gds.ServiceParameterBuffer;
import org.firebirdsql.gds.ServiceRequestBuffer;
import org.firebirdsql.gds.ng.listeners.ServiceListener;
import org.firebirdsql.gds.ng.listeners.ServiceListenerDispatcher;
import org.firebirdsql.logging.Logger;
import org.firebirdsql.logging.LoggerFactory;

import java.sql.SQLException;
import java.sql.SQLWarning;

import static org.firebirdsql.gds.ISCConstants.*;
import static org.firebirdsql.gds.VaxEncoding.iscVaxInteger2;

/**
 * Abstract service implementation.
 *
 * @author Mark Rotteveel
 * @since 3.0
 */
public abstract class AbstractFbService>
        extends AbstractFbAttachment implements FbService {

    private static final Logger log = LoggerFactory.getLogger(AbstractFbService.class);
    private final ServiceListenerDispatcher serviceListenerDispatcher = new ServiceListenerDispatcher();
    private final WarningMessageCallback serviceWarningCallback = new WarningMessageCallback() {
        @Override
        public void processWarning(SQLWarning warning) {
            serviceListenerDispatcher.warningReceived(AbstractFbService.this, warning);
        }
    };

    protected AbstractFbService(T connection, DatatypeCoder datatypeCoder) {
        super(connection, datatypeCoder);
    }

    @Override
    public final  R getServiceInfo(ServiceParameterBuffer serviceParameterBuffer,
            ServiceRequestBuffer serviceRequestBuffer, int bufferLength, InfoProcessor infoProcessor)
            throws SQLException {
        final byte[] responseBuffer = getServiceInfo(serviceParameterBuffer, serviceRequestBuffer, bufferLength);
        try {
            return infoProcessor.process(responseBuffer);
        } catch (SQLException e) {
            exceptionListenerDispatcher.errorOccurred(e);
            throw e;
        }
    }

    @Override
    public final void addServiceListener(ServiceListener listener) {
        serviceListenerDispatcher.addListener(listener);
    }

    @Override
    public final void removeServiceListener(ServiceListener listener) {
        serviceListenerDispatcher.removeListener(listener);
    }

    /**
     * Actual implementation of service detach.
     * 

* Implementations of this method should only be called from {@link #close()}, and should not * notify service listeners of the service {@link ServiceListener#detaching(FbService)} and * {@link ServiceListener#detached(FbService)} events. *

*/ protected abstract void internalDetach() throws SQLException; /** * {@inheritDoc} *

* Implementation note: Calls {@link #checkConnected()} and notifies service listeners of the detaching event, then * calls {@link #internalDetach()} and finally notifies service listeners of database detach and removes all * listeners. *

*/ @Override public final void close() throws SQLException { try { checkConnected(); synchronized (getSynchronizationObject()) { serviceListenerDispatcher.detaching(this); try { internalDetach(); } finally { serviceListenerDispatcher.detached(this); serviceListenerDispatcher.shutdown(); } } } catch (SQLException e) { exceptionListenerDispatcher.errorOccurred(e); throw e; } finally { exceptionListenerDispatcher.shutdown(); } } /** * @return The warning callback for this service. */ protected final WarningMessageCallback getServiceWarningCallback() { return serviceWarningCallback; } protected ServiceRequestBuffer getDescribeServiceRequestBuffer() { ServiceRequestBuffer srb = createServiceRequestBuffer(); srb.addArgument(isc_info_svc_server_version); return srb; } protected InfoProcessor getServiceInformationProcessor() { return new ServiceInformationProcessor(); } private class ServiceInformationProcessor implements InfoProcessor { @Override public FbService process(byte[] info) throws SQLException { boolean debug = log.isDebugEnabled(); if (info.length == 0) { throw new SQLException("Response buffer for service information request is empty"); } if (debug) log.debug(String.format("ServiceInformationProcessor.process: first 2 bytes are %04X or: %02X, %02X", iscVaxInteger2(info, 0), info[0], info[1])); int len; int i = 0; while (info[i] != isc_info_end) { switch (info[i++]) { case isc_info_svc_server_version: len = iscVaxInteger2(info, i); i += 2; String firebirdVersion = new String(info, i, len); i += len; setServerVersion(firebirdVersion); if (debug) log.debug("isc_info_firebird_version:" + firebirdVersion); break; case isc_info_truncated: log.debug("isc_info_truncated "); return AbstractFbService.this; default: throw new FbExceptionBuilder().exception(isc_infunk).toSQLException(); } } return AbstractFbService.this; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy