com.ibm.as400.access.PSConnection Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jt400 Show documentation
Show all versions of jt400 Show documentation
The Open Source version of the IBM Toolbox for Java
The newest version!
///////////////////////////////////////////////////////////////////////////////
//
// JTOpen (IBM Toolbox for Java - OSS version)
//
// Filename: PSConnection.java
//
// The source code contained herein is licensed under the IBM Public License
// Version 1.0, which has been approved by the Open Source Initiative.
// Copyright (C) 1997-2000 International Business Machines Corporation and
// others. All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
package com.ibm.as400.access;
import java.io.EOFException;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.SocketException;
/**
The PSConnection class represents a connection
to a client of the proxy server.
**/
class PSConnection
extends StoppableThread
{
// Private data.
private boolean closed_ = false;
private long connectionId_;
private PxDSFactory factory_;
private InputStream input_;
private PSLoad load_;
private OutputStream output_;
private Socket socket_;
private PrintWriter trace_;
private PxTable proxyTable_;
/**
Constructs a PSConnection object.
@param connectionId The connection id.
@param socket The socket.
@param input The input stream.
@param output The output stream.
@param load The load.
**/
public PSConnection (long connectionId,
Socket socket,
InputStream input,
OutputStream output,
PSLoad load)
{
super("PSConnection-" + connectionId);
connectionId_ = connectionId;
socket_ = socket;
input_ = input;
load_ = load;
output_ = output;
proxyTable_ = new PxTable ();
factory_ = new PxDSFactory ();
factory_.register (new PxByteParm ());
factory_.register (new PxShortParm ());
factory_.register (new PxIntParm ());
factory_.register (new PxLongParm ());
factory_.register (new PxFloatParm ());
factory_.register (new PxDoubleParm ());
factory_.register (new PxBooleanParm ());
factory_.register (new PxCharParm ());
factory_.register (new PxStringParm ());
factory_.register (new PxSerializedObjectParm ());
factory_.register (new PxPxObjectParm (proxyTable_));
factory_.register (new PxToolboxObjectParm ());
factory_.register (new PxNullParm ());
factory_.register (new PxClassParm ());
factory_.register (new PxConstructorReqSV (proxyTable_));
factory_.register (new PxMethodReqSV (proxyTable_)); //@B2D, this));
factory_.register (new PxFinalizeReqSV (proxyTable_));
factory_.register (new PxListenerReqSV (this, proxyTable_));
if (Trace.isTraceProxyOn ()) {
trace_ = Trace.getPrintWriter();
Trace.log (Trace.PROXY, "Px server connection " + this + " opened.");
}
}
public void close ()
{
super.stopSafely();
closed_ = true;
if (Trace.isTraceProxyOn ())
Trace.log (Trace.PROXY, "Px server connection " + this + " closed.");
// I am using separate try-catch blocks to make sure
// that everything gets closed.
// NOTE: When using SSL, trying to close the output stream, input stream, and //$B1A
// socket are more prone to throw an exception. This is most likely due
// to the SSL design, which we cannot control.
try {
if (output_ != null)
output_.close ();
}
catch (IOException e) {
if (Trace.isTraceErrorOn ())
Trace.log (Trace.ERROR, "Exception closing proxy output stream.", e); //$B1C
}
try {
if (input_ != null)
input_.close ();
}
catch (IOException e) {
if (Trace.isTraceErrorOn ())
Trace.log (Trace.ERROR, "Exception closing proxy input stream.", e); //$B1C
}
try {
if (socket_ != null)
socket_.close ();
}
catch (IOException e) {
if (Trace.isTraceErrorOn ())
Trace.log (Trace.ERROR, "Exception closing proxy socket.", e); //$B1C
}
// Clean up for the connection. Make sure and do this after closing
// the input stream. Otherwise I was seeing requests come across for
// objects no longer in the proxy table. That resulted in a NullPointerException.
if (proxyTable_ != null) {
proxyTable_.removeAll ();
proxyTable_ = null;
}
factory_ = null;
load_.connectionClosed ();
Verbose.println (ResourceBundleLoader.getText ("PROXY_CONNECTION_CLOSED", Long.toString (connectionId_)));
}
protected void finalize ()
throws Throwable
{
if (! closed_)
close ();
super.finalize ();
}
/**
Handles IOExceptions that are thrown while replying
to requests.
**/
private void handleIOException (IOException e)
{
// This exception is thrown when the client application ends
// normally. It is also thrown on certain error conditions.
// We need to trace the error conditions, but weed out the
// normal ending.
if (Trace.isTraceErrorOn ())
if (((!(e instanceof SocketException)) // Normal Windows end.
&& (!(e instanceof EOFException))) // Normal AIX end.
|| ((e.getMessage () != null)
&& (e.getMessage ().indexOf ("JVM_recv") < 0)))
Trace.log (Trace.ERROR, "IOException in PSConnection", e);
if (! closed_)
close ();
}
/**
Processes a request and sends the reply, if any.
**/
private void processReq (PxReqSV request)
{
PxRepSV reply = request.process ();
if (reply != null) {
reply.setCorrelationId(request.getCorrelationId());
send (reply);
}
}
/**
Processes requests until the connection is closed.
**/
public void run()
{
load_.connectionOpened ();
// Loop, continuously replying to requests.
try {
while (canContinue ()) {
// Get the next request.
if (Trace.isTraceProxyOn())
Trace.log(Trace.PROXY,this,"calling factory_.getNextDS");
PxReqSV request = (PxReqSV) factory_.getNextDS (input_);
if (Trace.isTraceProxyOn ()) {
trace_.print(getName() + " - ");
request.dump(trace_);
}
// If the request is asychronous, then process it in another thread.
// Otherwise, run in in this thread. Synchronous requests save the
// overhead of creating a thread, but asynchronous requests are needed
// in some cases to preserve semantics. This will be most common
// for potentially long-running method calls.
if (request.isAsynchronous ()) {
final PxReqSV request2 = request;
(new Thread () { public void run () { processReq (request2); }}).start ();
}
else {
processReq (request);
}
}
}
catch (IOException e) {
if (Trace.isTraceProxyOn()) {
Trace.log(Trace.PROXY, "Exited run loop because of exception", e);
}
handleIOException (e);
}
}
/**
Sends a reply.
* @param reply
**/
public void send (PxRepSV reply)
{
try {
if (reply != null) {
synchronized (output_) {
if (Trace.isTraceProxyOn ()) {
trace_.print(getName() + " - ");
reply.dump(trace_);
}
reply.writeTo(output_);
output_.flush();
}
}
}
catch (IOException e) {
handleIOException (e);
}
}
/**
Stops the thread safely.
**/
public void stopSafely ()
{
close ();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy