org.firebirdsql.gds.ng.wire.AbstractFbWireService Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jaybird Show documentation
Show all versions of jaybird Show documentation
JDBC Driver for the Firebird RDBMS
/*
* Firebird Open Source 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.wire;
import org.firebirdsql.gds.ISCConstants;
import org.firebirdsql.gds.JaybirdErrorCodes;
import org.firebirdsql.gds.ServiceParameterBuffer;
import org.firebirdsql.gds.ServiceRequestBuffer;
import org.firebirdsql.gds.impl.wire.XdrInputStream;
import org.firebirdsql.gds.impl.wire.XdrOutputStream;
import org.firebirdsql.gds.ng.AbstractFbService;
import org.firebirdsql.gds.ng.DefaultDatatypeCoder;
import org.firebirdsql.gds.ng.FbExceptionBuilder;
import org.firebirdsql.gds.ng.LockCloseable;
import org.firebirdsql.gds.ng.WarningMessageCallback;
import java.io.IOException;
import java.sql.SQLException;
import static java.util.Objects.requireNonNull;
/**
* Abstract service implementation for the wire protocol.
*
* @author Mark Rotteveel
* @since 3.0
*/
public abstract class AbstractFbWireService extends AbstractFbService
implements FbWireService {
protected final ProtocolDescriptor protocolDescriptor;
protected final FbWireOperations wireOperations;
/**
* Creates an AbstractFbWireDatabase instance.
*
* @param connection
* A WireConnection with an established connection to the server.
* @param descriptor
* The ProtocolDescriptor that created this connection (this is
* used for creating further dependent objects).
*/
protected AbstractFbWireService(WireServiceConnection connection, ProtocolDescriptor descriptor) {
super(connection, DefaultDatatypeCoder.forEncodingFactory(connection.getEncodingFactory()));
protocolDescriptor = requireNonNull(descriptor, "parameter descriptor should be non-null");
wireOperations = descriptor.createWireOperations(connection, getServiceWarningCallback());
}
@Override
public final int getHandle() {
// The handle is always 0 for a TCP/IP service
return 0;
}
@Override
public void forceClose() throws SQLException {
try {
if (connection.isConnected()) {
connection.close();
}
} catch (IOException e) {
throw new FbExceptionBuilder().exception(ISCConstants.isc_net_write_err).cause(e).toSQLException();
} finally {
serviceListenerDispatcher.detached(this);
serviceListenerDispatcher.shutdown();
exceptionListenerDispatcher.shutdown();
}
}
@Override
public final ServiceParameterBuffer createServiceParameterBuffer() {
return protocolDescriptor.createServiceParameterBuffer(connection);
}
@Override
public final ServiceRequestBuffer createServiceRequestBuffer() {
return protocolDescriptor.createServiceRequestBuffer(connection);
}
@Override
public final boolean isAttached() {
return super.isAttached() && connection.isConnected();
}
/**
* Checks if a physical connection to the server is established.
*
* @throws SQLException
* If not connected.
*/
protected final void checkConnected() throws SQLException {
if (!connection.isConnected()) {
throw FbExceptionBuilder.forException(JaybirdErrorCodes.jb_notConnectedToServer).toSQLException();
}
}
/**
* Checks if a physical connection to the server is established and if the
* connection is attached to a database.
*
* This method calls {@link #checkConnected()}, so it is not necessary to
* call both.
*
*
* @throws SQLException
* If the database not connected or attached.
*/
protected final void checkAttached() throws SQLException {
checkConnected();
if (!isAttached()) {
throw FbExceptionBuilder.forException(JaybirdErrorCodes.jb_notAttachedToDatabase).toSQLException();
}
}
@Override
public void setNetworkTimeout(int milliseconds) throws SQLException {
try (LockCloseable ignored = withLock()) {
checkConnected();
wireOperations.setNetworkTimeout(milliseconds);
}
}
/**
* Gets the XdrInputStream.
*
* @return Instance of XdrInputStream
* @throws SQLException
* If no connection is opened or when exceptions occur
* retrieving the InputStream
*/
protected final XdrInputStream getXdrIn() throws SQLException {
return getXdrStreamAccess().getXdrIn();
}
/**
* Gets the XdrOutputStream.
*
* @return Instance of XdrOutputStream
* @throws SQLException
* If no connection is opened or when exceptions occur
* retrieving the OutputStream
*/
protected final XdrOutputStream getXdrOut() throws SQLException {
return getXdrStreamAccess().getXdrOut();
}
@Override
public final GenericResponse readGenericResponse(WarningMessageCallback warningCallback)
throws SQLException, IOException {
return wireOperations.readGenericResponse(warningCallback);
}
@Override
public final XdrStreamAccess getXdrStreamAccess() {
return connection.getXdrStreamAccess();
}
/**
* Closes the WireConnection associated with this connection.
*
* @throws IOException
* For errors closing the connection.
*/
protected final void closeConnection() throws IOException {
if (!connection.isConnected()) return;
try (LockCloseable ignored = withLock()) {
try {
connection.close();
} finally {
setDetached();
}
}
}
@Override
protected void finalize() throws Throwable {
try {
if (!connection.isConnected()) return;
if (isAttached()) {
safelyDetach();
} else {
closeConnection();
}
} finally {
super.finalize();
}
}
}