com.ibm.as400.access.PrintObjectListImplRemote 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: PrintObjectListImplRemote.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-2002 International Business Machines Corporation and
// others. All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
package com.ibm.as400.access;
import java.util.Vector;
import java.io.IOException;
/**
* The PrintObjectList class is an abstract base class for the various types of network print object lists.
**/
abstract class PrintObjectListImplRemote implements PrintObjectListImpl, Runnable
{
private static final String copyright = "Copyright (C) 1997-2002 International Business Machines Corporation and others.";
// These instance variable are persistent.
private NPCPAttributeIDList attrsToRetrieve_;
private NPCPID idFilter_; // for certain lists an idcodepoint may be used to filter
private NPCPSelection selection_; // selection filter
private AS400ImplRemote system_; // @A4 - changed from AS400 to AS400ImplRemote
private int typeOfObject_ = 0; // indicates object type
// These instance variables are not persistent.
private transient boolean completed_ = false;
private transient boolean closed_ = false;
private final Object closeLock_ = new Object();
private transient boolean waiting_ = false;
private final Object waitLock_ = new Object();
private transient int waitingForItem_ = -1;
private transient Vector cpidList_ = null; // @A5A
private transient Vector cpattrList_ = null; // @A5A
private transient int numItems_ = 0;
private transient Exception anyException_ = null;
private transient Vector printObjectListListeners_ = null;
private boolean useCache_ = true;
/**
*Adds the specified PrintObjectList listener to receive
*PrintObjectList events from this print object list.
*
* @see #removePrintObjectListListener
* @param listener The PrintObjectList listener.
**/
public void addPrintObjectListListener(PrintObjectListListener listener)
{
if (printObjectListListeners_ == null) printObjectListListeners_ = new Vector();
synchronized(printObjectListListeners_)
{
printObjectListListeners_.addElement(listener);
}
}
/**
* This method does all of the datastream work and object creations.
**/
private void buildList()
throws AS400Exception,
AS400SecurityException,
ErrorCompletingRequestException,
InterruptedException,
IOException,
RequestNotSupportedException
{
NPSystem npSystem = NPSystem.getSystem(getSystem());
if (npSystem != null)
{
NPConversation conversation = npSystem.getConversation();
try
{
if (conversation != null)
{
boolean fTossData = false;
boolean fMoreData = true;
int count = 0;
// @B1D int ccsid = conversation.getHostCCSID();
ConverterImpl converter = conversation.getConverter(); // @B1A
AS400Server server = conversation.getServer();
int correlation = server.newCorrelationId();
NPDataStream request = new NPDataStream(typeOfObject_);
NPDataStream reply;
request.setCorrelation(correlation);
request.setAction(NPDataStream.LIST);
// @B1D request.setHostCCSID(ccsid);
request.setConverter(converter); // @B1A
if (selection_ != null)
{
request.addCodePoint(selection_);
}
if (idFilter_ != null)
{
request.addCodePoint(idFilter_);
}
if (attrsToRetrieve_ != null)
{
request.addCodePoint(attrsToRetrieve_);
}
else
{
request.addCodePoint(getDefaultAttrsToList());
}
server.send(request, correlation);
do
{
reply = (NPDataStream)server.receive(correlation);
if (reply == null)
{
// throw execption - internal error.
fMoreData = false;
Trace.log(Trace.ERROR, "buildList: Null reply from AS400Server.receive()!");
throw new InternalErrorException(InternalErrorException.PROTOCOL_ERROR);
}
else
{
count++;
fMoreData = !(reply.isLastReply());
if (!fTossData)
{
// we are going to keep this reply so set the
// ccsid so it can tranlsate its text correctly
// @B1D reply.setHostCCSID(ccsid);
reply.setConverter(converter); // @B1A
int rc = reply.getReturnCode();
if (rc == NPDataStream.RET_OK)
{
// @A5D PrintObject npObject = newNPObject(getSystem(), reply);
NPCPID cpid = newNPCPID(reply); // @A5A
NPCPAttribute cpattr = newNPCPAttribute(reply); // @A5A
if (cpid != null) // @A5C
{
synchronized(closeLock_) // In case someone tries to close us before we're finished.
{
if (closed_ || completed_) // Don't add the item if we've been closed already.
{
// the list has been closed before
// it completed, start tossing any
// incoming data...
fTossData = true;
}
else
{
if (useCache_) cpidList_.addElement(cpid);
if (useCache_) cpattrList_.addElement(cpattr);
++numItems_;
// tell any listeners an object was added to the list. // @A2A
firePrintObjectList(PrintObjectListEvent.OBJECT_ADDED, cpid, cpattr, null); // @A5A
if (waiting_ && waitingForItem_ <= numItems_ && waitingForItem_ > -1)
{
// Only notify if someone is waiting to be notified.
synchronized(waitLock_)
{
waitLock_.notifyAll();
}
}
}
}
}
}
else
{
if (rc == NPDataStream.RET_CPF_MESSAGE)
{
NPCPAttribute cpCPFMessage = (NPCPAttribute)reply.getCodePoint(NPCodePoint.ATTRIBUTE_VALUE);
if (cpCPFMessage != null)
{
String strCPFMessageID = cpCPFMessage.getStringValue(PrintObject.ATTR_MSGID);
String strCPFMessageText = cpCPFMessage.getStringValue(PrintObject.ATTR_MSGTEXT);
String strCPFMessageHelp = cpCPFMessage.getStringValue(PrintObject.ATTR_MSGHELP);
if (Trace.traceOn_) Trace.log(Trace.ERROR, "buildList: CPF Message("+strCPFMessageID+") = " + strCPFMessageText + ", HelpText= " +strCPFMessageHelp); //@CRS
// Create an AS400Message object
AS400Message msg = new AS400Message(strCPFMessageID, strCPFMessageText);
msg.setHelp(strCPFMessageHelp);
AS400Exception e = new AS400Exception(msg);
// throw an exception containing our CPF message.
// our catcher will actually fire the error event.
throw e;
}
}
else
{
if (rc == NPDataStream.RET_EMPTY_LIST)
{
// the list is empty, that isn't an error.
}
else
{
// look at RC and throw appropriate exception
Trace.log(Trace.ERROR, "buildList: Host Return Code" + rc);
// we get back a 4 (INV_REQ_ACT) if we try to list
// AFP Resources on pre V3R7 systems..
if (rc == NPDataStream.RET_INV_REQ_ACT)
{
throw new RequestNotSupportedException(conversation.getAttribute(PrintObject.ATTR_NPSLEVEL),
RequestNotSupportedException.SYSTEM_LEVEL_NOT_CORRECT);
}
else
{
throw new ErrorCompletingRequestException(ErrorCompletingRequestException.AS400_ERROR,
"QNPSERVS RC = " + rc);
}
}
}
}
}
}
// every 15 datastreams that we get we'll call to the
// garbage collector to keep the VM from running out of
// of memory
//@C0 - This is a serious performance bottleneck and should no longer be
// necessary under today's "modern" JVMs.
//@C0D if ((count % 15) == 0)
//@C0D {
//@C0D System.gc();
//@C0D }
} while (fMoreData);
}
}
finally
{
npSystem.returnConversation(conversation);
}
}
}
// The sub classes have default constructors implemented
// for JavaBean support in visual builders. We need to
// check the run time state of the object. The sub classes
// may add additional checks by having their own
// checkRunTimeState(), but will call super.checkRunTimeState()
// to get this check.
void checkRunTimeState()
{
if (getSystem() == null)
{
Trace.log(Trace.ERROR, "checkRunTimeState: Parameter 'system' has not been set.");
throw new ExtendedIllegalStateException(
"system", ExtendedIllegalStateException.PROPERTY_NOT_SET);
}
}
/**
* Closes the list so that objects in the list can be garbage collected.
**/
public void close()
{
synchronized(closeLock_)
{
closed_ = true;
cpidList_ = null; // @A5A
cpattrList_ = null; // @A5A
numItems_ = 0; //@CRS
anyException_ = null;
}
// tell any listeners the list was closed.
firePrintObjectList(PrintObjectListEvent.CLOSED, null, null, null); // @A5C
// At this point, all other threads that are using us should not be
// firing events.
}
// The JavaBeans 1.0 Specification strongly recommends to avoid
// using a synchronized method to fire an event. We use a
// synchronized block to locate the target listeners and then
// call the event listeners from unsynchronized code.
private void firePrintObjectList(int id,
NPCPID cpid, // @A5A
NPCPAttribute cpattr, // @A5A
Exception exception )
{
// Return if no listeners are registered.
if (printObjectListListeners_ == null) //@CRS
{
return;
}
PrintObjectListEvent event;
// Now that we know we have listeners, we construct
// the event object. We could have passed an event
// oject to firePrintObjectList() but that would be
// extra overhead if there were no listeners.
if (exception !=null)
{
event = new PrintObjectListEvent(this, exception);
}
else if (cpid != null) // @A5D
{
event = new PrintObjectListEvent(this, cpid, cpattr); // @A5D
}
else
{
event = new PrintObjectListEvent(this, id);
}
synchronized(printObjectListListeners_) // We don't want listeners being added/removed while we're firing an event.
{
int size = printObjectListListeners_.size();
for (int i=0; i < size; i++)
{
switch (id)
{
// OBJECT_ADDED is the most frequent case.
case PrintObjectListEvent.OBJECT_ADDED:
((PrintObjectListListener)printObjectListListeners_.elementAt(i)).listObjectAdded(event);
break;
case PrintObjectListEvent.CLOSED:
((PrintObjectListListener)printObjectListListeners_.elementAt(i)).listClosed(event);
break;
case PrintObjectListEvent.COMPLETED:
((PrintObjectListListener)printObjectListListeners_.elementAt(i)).listCompleted(event);
break;
case PrintObjectListEvent.ERROR_OCCURRED:
((PrintObjectListListener)printObjectListListeners_.elementAt(i)).listErrorOccurred(event);
break;
case PrintObjectListEvent.OPENED:
((PrintObjectListListener)printObjectListListeners_.elementAt(i)).listOpened(event);
break;
}
}
}
}
/**
* Non-externalized abstract method that the child-classes implement to
* set the default attributes to retrieve on the list
**/
abstract NPCPAttributeIDList getDefaultAttrsToList();
// @A5A
public synchronized NPCPID getNPCPID(int index)
{
return(NPCPID)cpidList_.elementAt(index);
}
// @A5A
public synchronized NPCPAttribute getNPCPAttribute(int index)
{
return(NPCPAttribute)cpattrList_.elementAt(index);
}
// This method is called by subclassed ImplRemotes
NPCPSelection getSelectionCP()
{
return selection_;
}
/**
* Returns the system name. This method is primarily provided for visual
* application builders that support JavaBeans.
*
* @return The system on which the objects in the list exist.
**/
final public AS400ImplRemote getSystem()
{
return system_;
}
/**
* Checks if a list that was opened asynchronously has completed.
* If any exception occurred while the list was being retrieved, it will
* be thrown here.
*
* @exception AS400Exception If the server returns an error message.
* @exception AS400SecurityException If a security or authority error occurs.
* @exception ConnectionDroppedException If the connection is dropped unexpectedly.
* @exception ErrorCompletingRequestException If an error occurs before the request is completed.
* @exception InterruptedException If this thread is interrupted.
* @exception IOException If an error occurs while communicating with the server.
* @exception RequestNotSupportedException If the requested function is not supported because
* the server operating system is not at the correct level.
* @return true if the list is completely built; false otherwise.
**/
public boolean isCompleted()
throws AS400Exception,
AS400SecurityException,
ConnectionDroppedException,
ErrorCompletingRequestException,
InterruptedException,
IOException,
RequestNotSupportedException
{
if (anyException_ != null)
{
rethrowException();
}
return completed_;
}
/**
* Non-externalized abstract method that child-classes implement to
* create the correct type of object from the reply datastream
**/
abstract NPCPID newNPCPID(NPDataStream reply); // @A5A
// @A5A
NPCPAttribute newNPCPAttribute(NPDataStream reply)
{
return(NPCPAttribute)reply.getCodePoint(NPCodePoint.ATTRIBUTE_VALUE); // may return null
}
/**
* Builds the list asynchronously. This method starts a thread
* to build the list and then returns. The caller may register
* listeners to obtain status about the list, or call isCompleted(),
* waitForItem(), or waitForListToComplete().
**/
public void openAsynchronously()
{
checkRunTimeState();
// Start thread to build the list. We are runnable, and
// so our run() method just calls openSynchronously().
Thread t = new Thread(this);
t.start();
}
/**
* Builds the list synchronously. This method will not
* return until the list has been built completely.
* The caller may then call the getObjects() method
* to get an enumeration of the list.
*
* @exception AS400Exception If the server returns an error message.
* @exception AS400SecurityException If a security or authority error occurs.
* @exception ConnectionDroppedException If the connection is dropped unexpectedly.
* @exception ErrorCompletingRequestException If an error occurs before the request is completed.
* @exception InterruptedException If this thread is interrupted.
* @exception IOException If an error occurs while communicating with the server.
* @exception RequestNotSupportedException If the requested function is not supported because the
* server operating system is not at the correct level.
**/
public void openSynchronously()
throws AS400Exception,
AS400SecurityException,
ConnectionDroppedException,
ErrorCompletingRequestException,
InterruptedException,
IOException,
RequestNotSupportedException
{
// check the run time state of the object. To support JavaBeans
// the sub-classes provide null constructors.
checkRunTimeState();
AS400ImplRemote theSystem = getSystem();
if (theSystem != null)
{ // @A1A
NPSystem npSystem = NPSystem.getSystem(theSystem); // @A1A
if (npSystem != null) // @A1A
{
// @A1A
NPConversation conversation = npSystem.getConversation(); // @A1A
npSystem.returnConversation(conversation); // @A1A
} // @A1A
} // @A1A
cpidList_ = new Vector(); // @A5A
cpattrList_ = new Vector(); // @A5A
numItems_ = 0;
completed_ = false; // @A2A
closed_ = false; // @A6A
anyException_ = null; // @A2A
// tell any listeners the list was opened. // @A2A
firePrintObjectList(PrintObjectListEvent.OPENED, null, null, null); // @A2A @A5C
try // @A2A
{
buildList();
} // @A2A
catch (Exception e) // @A2A
{
anyException_ = e; // @A2A
// tell any listeners an error occurred. // @A2A
firePrintObjectList(PrintObjectListEvent.ERROR_OCCURRED, null, null, e); // @A2A @A5C
} // @A2A
finally // @A2A
{
// tell any listeners the list completed. // @A2A
firePrintObjectList(PrintObjectListEvent.COMPLETED, null, null, null); // @A2A @A5C
synchronized(waitLock_) // Notify anyone who is waiting for an item or the list to complete.
{
completed_ = true;
waitLock_.notifyAll();
}
} // @A2A
// we caught the exception above so that we could notify any // @A2A
// listeners. Now, rethrow the exception for applications // @A2A
// that may not be using listeners. // @A2A
if (anyException_ != null) // @A2A
{
// @A2A
rethrowException(); // @A2A
} // @A2A
}
/**
*Removes the specified PrintObjectList listener
*so that it no longer receives PrintObjectList events
*from this print object list.
*
* @see #addPrintObjectListListener
* @param listener The PrintObjectList listener.
**/
public void removePrintObjectListListener( PrintObjectListListener listener )
{
if (printObjectListListeners_ != null)
{
synchronized(printObjectListListeners_)
{
printObjectListListeners_.removeElement(listener);
}
}
}
/**
* Resets the list of object attributes to retrieve.
**/
public void resetAttributesToRetrieve()
{
attrsToRetrieve_ = null;
}
/**
* Resets the list filter back to default values.
**/
public void resetFilter()
{
selection_.reset();
idFilter_ = null; // effectively resets the id Codepoint filter;
}
// Rethrow any exception.
private void rethrowException()
throws AS400Exception,
AS400SecurityException,
ConnectionDroppedException,
ErrorCompletingRequestException,
InterruptedException,
IOException,
RequestNotSupportedException
{
if (anyException_ instanceof AS400Exception)
throw (AS400Exception)anyException_;
if (anyException_ instanceof AS400SecurityException)
throw (AS400SecurityException)anyException_;
if (anyException_ instanceof ConnectionDroppedException)
throw (ConnectionDroppedException)anyException_;
if (anyException_ instanceof ErrorCompletingRequestException)
throw (ErrorCompletingRequestException)anyException_;
if (anyException_ instanceof InterruptedException)
throw (InterruptedException)anyException_;
if (anyException_ instanceof IOException)
throw (IOException)anyException_;
if (anyException_ instanceof RequestNotSupportedException)
throw (RequestNotSupportedException)anyException_;
// runtime exceptions
if (anyException_ instanceof ExtendedIllegalStateException)
throw (ExtendedIllegalStateException)anyException_;
if (anyException_ instanceof NullPointerException)
throw (NullPointerException)anyException_;
// If we get here we are getting an exception we overlooked,
// trace it for debugging.
Trace.log(Trace.ERROR, "rethrowException: Exception was not rethrown.");
}
/**
* This is called automatically when Thread.start() is called by openAsynchronously().
**/
public void run()
{
try
{
openSynchronously();
}
catch (Exception e)
{
anyException_ = e;
}
}
/**
* Sets the attributes of the object that should be returned in the list.
* This method can be used to speed up the listing if
* only interested in a few attributes for each item in the list.
*
* @param attributes An array of attribute IDs that define which
* object attributes will be retrieved for each item in the list
* when the list is opened.
*
* @see PrintObject
**/
public void setAttributesToRetrieve(int[] attributes)
{
// check params
if (attributes == null)
{
Trace.log(Trace.ERROR, "setAttributesToRetrieve: Parameter 'attributes' is null.");
throw new NullPointerException("attributes");
}
if (attrsToRetrieve_ != null)
{
attrsToRetrieve_.reset();
}
else
{
attrsToRetrieve_ = new NPCPAttributeIDList();
}
for (int i = 0; i
© 2015 - 2025 Weber Informatics LLC | Privacy Policy