com.ibm.as400.access.ProxyClientConnection 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
///////////////////////////////////////////////////////////////////////////////
//
// JTOpen (IBM Toolbox for Java - OSS version)
//
// Filename: ProxyClientConnection.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.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Enumeration;
import java.util.EventListener;
import java.util.Locale;
import java.util.Vector;
// The ProxyClientConnection class represents the connection to a proxy server. This acts as the interface between proxy implementation classes in each Toolbox component and the proxy datastream classes.
//
// Implementation notes:
//
// 1. We used to keep a PxTable on the client side to keep track of the objects we created. The problem is that the table keeps a reference to every object, which prevents them from being garbage collected. This is certainly a memory leak on the client, but since the objects never get finalized, their
//
class ProxyClientConnection extends PxClientConnectionAdapter
{
private static final String copyright = "Copyright (C) 1997-2000 International Business Machines Corporation and others.";
// Private data.
private static final String locale_ = Locale.getDefault().toString();
private static final Class[] noArgumentClasses_ = new Class[0];
private static final Object[] noArguments_ = new Object[0];
private int connectAttempts_ = 0;
private PxEventSupport eventSupport_;
private Vector pxList_ = new Vector();
private SecondaryFinalizerThread_ secondaryFinalizerThread_;
// Constructs a ProxyClientConnection object.
// @param proxyServer The proxy server.
// @param secure Options for a SSL connection, null indicates non-SSL connection.
public ProxyClientConnection(String proxyServer, SSLOptions secure)
{
super(proxyServer, secure);
connect();
}
// Adds a listener.
// @param proxyId The proxy id.
// @param listener The listener.
// @param eventName The event name.
public void addListener(long proxyId, EventListener listener, String eventName)
{
// If this is the first listener of its kind, then add a listener down on the proxy server, so that events get reported back.
if (eventSupport_.addListener(proxyId, listener))
{
PxListenerReqCV request = new PxListenerReqCV(proxyId, ProxyConstants.LISTENER_OPERATION_ADD, eventName);
send(request);
}
}
// Calls a constructor on the proxy server. The constructor creates an object on the proxy server.
// @param className The class name.
// @return The proxy id.
// @exception InvocationTargetException If the constructor throws an exception.
public long callConstructor(String className) throws InvocationTargetException
{
return callConstructor(className, true);
}
// Calls a constructor on the proxy server. The constructor creates an object on the proxy server.
// @param className The class name.
// @param flag true to tack on ImplRemote to the class name, false to use the class name, as-is.
// @return The proxy id.
// @exception InvocationTargetException If the constructor throws an exception.
public long callConstructor(String className, boolean flag) throws InvocationTargetException
{
PxConstructorReqCV request = new PxConstructorReqCV(className, flag);
long pxId = ((ProxyReturnValue)sendAndReceive(request)).getReturnValuePxId();
pxList_.addElement(Long.valueOf(pxId));
return pxId;
}
// Calls a factory method on the proxy server.
// @param proxyId The proxy id.
// @param methodName The method name.
// @param proxyImpl The proxy object representing the created object.
// @return The proxy object representing the created object, or null if no object was returned.
// @exception InvocationTargetException If the method throws an exception.
public ProxyFactoryImpl callFactoryMethod(long proxyId, String methodName, ProxyFactoryImpl proxyImpl) throws InvocationTargetException
{
return callFactoryMethod(proxyId, methodName, noArgumentClasses_, noArguments_, proxyImpl);
}
// Calls a factory method on the proxy server.
// @param proxyId The proxy id.
// @param methodName The method name.
// @param argumentClasses The argument classes.
// @param arguments The arguments.
// @param proxyImpl The proxy object representing the created object.
// @return The proxy object representing the created object, or null if no object was returned.
// @exception InvocationTargetException If the method throws an exception.
public ProxyFactoryImpl callFactoryMethod(long proxyId, String methodName, Class[] argumentClasses, Object[] arguments, ProxyFactoryImpl proxyImpl) throws InvocationTargetException
{
PxMethodReqCV request = new PxMethodReqCV(proxyId, methodName, argumentClasses, arguments, null, false, true);
long proxyId2 = ((ProxyReturnValue)sendAndReceive(request)).getReturnValuePxId();
if (proxyId2 >= 0)
{
proxyImpl.initialize(proxyId2, this);
pxList_.addElement(Long.valueOf(proxyId2));
return proxyImpl;
}
return null;
}
// Calls a finalize method on the proxy server. The object will be garbage collected on the proxy server.
// @param proxyId The proxy id.
// @exception InvocationTargetException If the finalize method throws an exception.
public void callFinalize(long proxyId) throws InvocationTargetException
{
// This may have already been called (by this object's finalize() or the ProxyImpl's finalize). Account for that fact, so that it only runs once.
Long pxId2 = Long.valueOf(proxyId);
if (pxList_.contains(pxId2))
{
eventSupport_.removeAll(proxyId);
PxFinalizeReqCV request = new PxFinalizeReqCV(proxyId);
secondaryFinalizerThread_.addRequest(request);
pxList_.removeElement(pxId2);
}
}
// Calls a method on the proxy server.
// @param proxyId The proxy id.
// @param methodName The method name.
// @return The return value.
// @exception InvocationTargetException If the method throws an exception.
public ProxyReturnValue callMethod(long proxyId, String methodName) throws InvocationTargetException
{
return callMethod(proxyId, methodName, noArgumentClasses_, noArguments_, false);
}
// Calls a method on the proxy server.
// @param proxyId The proxy id.
// @param methodName The method name.
// @param argumentClasses The argument classes.
// @param arguments The arguments.
// @return The return value.
// @exception InvocationTargetException If the method throws an exception.
public ProxyReturnValue callMethod(long proxyId, String methodName, Class[] argumentClasses, Object[] arguments) throws InvocationTargetException
{
return callMethod(proxyId, methodName, argumentClasses, arguments, false);
}
// Calls a method on the proxy server.
// @param proxyId The proxy id.
// @param methodName The method name.
// @param argumentClasses The argument classes.
// @param arguments The arguments.
// @param asynchronous true if asynchronous, false otherwise.
// @return The return value.
// @exception InvocationTargetException If the method throws an exception.
public ProxyReturnValue callMethod(long proxyId, String methodName, Class[] argumentClasses, Object[] arguments, boolean asynchronous) throws InvocationTargetException
{
PxMethodReqCV request = new PxMethodReqCV(proxyId, methodName, argumentClasses, arguments, null, asynchronous, false);
return (ProxyReturnValue)sendAndReceive(request);
}
// Calls a method on the proxy server.
// @param proxyId The proxy id.
// @param methodName The method name.
// @param argumentClasses The argument classes.
// @param arguments The arguments.
// @param returnArguments Whether return arguments are needed, or null if none are needed.
// @param asynchronous true if asynchronous, false otherwise.
// @return The return value.
// @exception InvocationTargetException If the method throws an exception.
public ProxyReturnValue callMethod(long proxyId, String methodName, Class[] argumentClasses, Object[] arguments, boolean[] returnArguments, boolean asynchronous) throws InvocationTargetException
{
PxMethodReqCV request = new PxMethodReqCV(proxyId, methodName, argumentClasses, arguments, returnArguments, asynchronous, false);
return (ProxyReturnValue)sendAndReceive(request);
}
// Calls a method on the proxy server.
// @param proxyId The proxy id.
// @param methodName The method name.
// @return The return value as a boolean.
// @exception InvocationTargetException If the method throws an exception.
public boolean callMethodReturnsBoolean(long proxyId, String methodName) throws InvocationTargetException
{
return callMethod(proxyId, methodName, noArgumentClasses_, noArguments_, false).getReturnValueBoolean();
}
// Calls a method on the proxy server.
// @param proxyId The proxy id.
// @param methodName The method name.
// @return The return value as an int.
// @exception InvocationTargetException If the method throws an exception.
public int callMethodReturnsInt(long proxyId, String methodName) throws InvocationTargetException
{
return callMethod(proxyId, methodName, noArgumentClasses_, noArguments_, false).getReturnValueInt();
}
// Calls a method on the proxy server.
// @param proxyId The proxy id.
// @param methodName The method name.
// @return The return value as an int.
// @exception InvocationTargetException If the method throws an exception.
public long callMethodReturnsLong(long proxyId, String methodName) throws InvocationTargetException
{
return callMethod(proxyId, methodName, noArgumentClasses_, noArguments_, false).getReturnValueLong();
}
// Calls a method on the proxy server.
// @param proxyId The proxy id.
// @param methodName The method name.
// @return The return value as an Object.
// @exception InvocationTargetException If the method throws an exception.
public Object callMethodReturnsObject(long proxyId, String methodName) throws InvocationTargetException
{
return callMethod(proxyId, methodName, noArgumentClasses_, noArguments_, false).getReturnValue();
}
// Closes the connection to the proxy server.
public void close()
{
super.close();
secondaryFinalizerThread_.stopSafely();
}
// Initiates the connection to the proxy server.
public void connect()
{
PxConnectReqCV request;
if (tunnel_) // @D1a
request = new PxConnectReqCV(ProxyConstants.CURRENT_MOD, connectAttempts_++, locale_, ProxyConstants.DS_CONNECT_TUNNEL_REQ); // @D1c
else // @D1a
request = new PxConnectReqCV(ProxyConstants.CURRENT_MOD, connectAttempts_++, locale_, ProxyConstants.DS_CONNECT_REQ); // @D1c
try
{
sendAndReceive(request);
}
catch (InvocationTargetException e)
{
rethrow(e);
}
}
protected void finalize() throws Throwable
{
// We should tell all of our proxy objects to finalize themselves BEFORE the socket closes.
Long[] pxList = new Long[pxList_.size()];
pxList_.copyInto(pxList);
for (int i = 0; i < pxList.length; ++i)
{
long pxId = pxList[i].longValue();
callFinalize(pxId);
}
// Call the superclass's finalize(), which will close the socket, etc.
super.finalize();
}
public void open(String proxyServer)
{
super.open(proxyServer);
// We need to reinitialize the factory everytime the connection is opened.
PxDSFactory factory = getFactory();
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 PxPxObjectParm());
factory.register(new PxSerializedObjectParm());
factory.register(new PxToolboxObjectParm());
factory.register(new PxNullParm());
factory.register(new PxClassParm());
factory.register(new PxAcceptRepCV());
factory.register(new PxRejectRepCV(this));
factory.register(new PxReturnRepCV());
factory.register(new PxExceptionRepCV());
factory.register(new PxEventRepCV(eventSupport_ = new PxEventSupport()));
// Start the secondary finalizer thread.
secondaryFinalizerThread_ = new SecondaryFinalizerThread_();
secondaryFinalizerThread_.start();
}
// Removes a listener.
// @param proxyId The proxy id.
// @param listener The listener.
// @param eventName The event name.
public void removeListener(long proxyId, EventListener listener, String eventName)
{
// If this is the last listener of its kind, then remove the listener down on the proxy server, so that events no longer get reported back.
if (eventSupport_.removeListener(proxyId, listener))
{
PxListenerReqCV request = new PxListenerReqCV(proxyId, ProxyConstants.LISTENER_OPERATION_REMOVE, eventName);
send(request);
eventSupport_.removeAll(proxyId);
}
}
// Rethrows exceptions returned as InvocationTargetExceptions. This provides some common exception handling.
// @param e The InvocationTargetException.
// @return An InternalErrorException if the exception is not known.
// @throws The exception.
public static InternalErrorException rethrow(InvocationTargetException e)
{
Throwable e2 = e.getTargetException();
if (e2 instanceof RuntimeException)
{
throw (RuntimeException)e2;
}
if (e2 instanceof Error)
{
throw (Error)e2;
}
InternalErrorException ex = new InternalErrorException(InternalErrorException.UNEXPECTED_EXCEPTION, e2);
if (Trace.isTraceProxyOn()) {
Trace.log(Trace.PROXY, "rethrow @", ex);
}
return ex ;
}
// Rethrows exceptions returned as InvocationTargetExceptions. This provides some common exception handling.
// @param e The InvocationTargetException.
// @return An InternalErrorException if the exception is not known.
// @throws The exception.
//
// Implementation note:
//
// * Throws IOException.
//
public static InternalErrorException rethrow1(InvocationTargetException e) throws IOException
{
Throwable e2 = e.getTargetException();
if (e2 instanceof IOException)
{
throw (IOException)e2;
}
return rethrow(e);
}
// Rethrows exceptions returned as InvocationTargetExceptions. This provides some common exception handling.
// @param e The InvocationTargetException.
// @return An InternalErrorException if the exception is not known.
// @throws The exception.
//
// Implementation note:
//
// * Throws [rethrow] + AS400SecurityException.
//
public static InternalErrorException rethrow2(InvocationTargetException e) throws AS400SecurityException, IOException
{
Throwable e2 = e.getTargetException();
if (e2 instanceof AS400SecurityException)
{
throw (AS400SecurityException)e2;
}
return rethrow1(e);
}
// Rethrows exceptions returned as InvocationTargetExceptions. This provides some common exception handling.
// @param e The InvocationTargetException.
// @return An InternalErrorException if the exception is not known.
// @throws The exception.
//
// Implementation note:
//
// * Throws [rethrow2] + InterruptedException.
//
public static InternalErrorException rethrow3(InvocationTargetException e) throws AS400SecurityException, InterruptedException, IOException
{
Throwable e2 = e.getTargetException();
if (e2 instanceof InterruptedException)
{
throw (InterruptedException)e2;
}
return rethrow2(e);
}
// Rethrows exceptions returned as InvocationTargetExceptions. This provides some common exception handling.
// @param e The InvocationTargetException.
// @return An InternalErrorException if the exception is not known.
// @throws The exception.
//
// Implementation note:
//
// * Throws [rethrow3] + ErrorCompletingRequestException.
//
public static InternalErrorException rethrow4(InvocationTargetException e) throws AS400SecurityException, ErrorCompletingRequestException, InterruptedException, IOException
{
Throwable e2 = e.getTargetException();
if (e2 instanceof ErrorCompletingRequestException)
{
throw (ErrorCompletingRequestException)e2;
}
return rethrow3 (e);
}
// Rethrows exceptions returned as InvocationTargetExceptions. This provides some common exception handling.
// @param e The InvocationTargetException.
// @return An InternalErrorException if the exception is not known.
// @throws The exception.
//
// Implementation note:
//
// * Throws [rethrow3] + AS400Exception.
//
public static InternalErrorException rethrow4a(InvocationTargetException e) throws AS400Exception, AS400SecurityException, InterruptedException, IOException
{
Throwable e2 = e.getTargetException();
if (e2 instanceof AS400Exception)
{
throw (AS400Exception)e2;
}
return rethrow3(e);
}
// Rethrows exceptions returned as InvocationTargetExceptions. This provides some common exception handling.
// @param e The InvocationTargetException.
// @return An InternalErrorException if the exception is not known.
// @throws The exception.
//
// Implementation note:
//
// * Throws [rethrow4] + ObjectDoesNotExistException.
//
public static InternalErrorException rethrow5(InvocationTargetException e) throws AS400SecurityException, ErrorCompletingRequestException, InterruptedException, IOException, ObjectDoesNotExistException
{
Throwable e2 = e.getTargetException();
if (e2 instanceof ObjectDoesNotExistException)
{
throw (ObjectDoesNotExistException)e2;
}
return rethrow4(e);
}
// Rethrows exceptions returned as InvocationTargetExceptions. This provides some common exception handling.
// @param e The InvocationTargetException.
// @return An InternalErrorException if the exception is not known.
// @throws The exception.
//
// Implementation note:
//
// * Throws [rethrow5] + ObjectAlreadyExistsException.
//
public static InternalErrorException rethrow6(InvocationTargetException e) throws AS400SecurityException, ErrorCompletingRequestException, InterruptedException, IOException, ObjectDoesNotExistException, ObjectAlreadyExistsException
{
Throwable e2 = e.getTargetException();
if (e2 instanceof ObjectAlreadyExistsException)
{
throw (ObjectAlreadyExistsException)e2;
}
return rethrow5(e);
}
// Rethrows exceptions returned as InvocationTargetExceptions. This provides some common exception handling.
// @param e The InvocationTargetException.
// @return An InternalErrorException if the exception is not known.
// @throws The exception.
//
// Implementation note:
//
// * Throws [rethrow5] + RequestNotSupportedException.
//
public static InternalErrorException rethrow6a(InvocationTargetException e) throws AS400Exception, AS400SecurityException, ErrorCompletingRequestException, InterruptedException, IOException, RequestNotSupportedException
{
Throwable e2 = e.getTargetException();
if (e2 instanceof RequestNotSupportedException)
{
throw (RequestNotSupportedException)e2;
}
return rethrow4(e);
}
private class SecondaryFinalizerThread_ extends StoppableThread
{
private Vector requests_ = new Vector();
public SecondaryFinalizerThread_()
{
super("Proxy client secondary finalizer thread-" + newId());
// Mark this as a daemon thread so that its running does not prevent the JVM from going away.
setDaemon(true);
}
public void addRequest(PxReqCV request)
{
synchronized(requests_)
{
requests_.addElement(request);
requests_.notify();
}
}
public void run()
{
while (canContinue())
{
synchronized(requests_)
{
try
{
requests_.wait();
}
catch(InterruptedException ignore)
{
// Ignore.
}
Enumeration list = requests_.elements();
while(list.hasMoreElements())
{
PxReqCV request = (PxReqCV)list.nextElement();
send(request);
}
requests_.removeAllElements();
}
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy