com.ibm.as400.access.NPConversation 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: NPConversation.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-2001 International Business Machines Corporation and
// others. All rights reserved
//
///////////////////////////////////////////////////////////////////////////////
package com.ibm.as400.access;
import java.io.*;
import java.util.*;
/**
* NPConversation class - this internal class is used to represent an network print
* conversation to a particular system. You can get one of these things from
* a NPServer object.
* It is a wrapper for the AS400Server object that takes care of initializing the
* conversation with the host (exchanging CCSIDs and Language IDs) and holding
* the attributes of the server job.
**/
class NPConversation extends Object
{
private static final String copyright = "Copyright (C) 1997-2001 International Business Machines Corporation and others.";
// private members
// private int hostCCSID_ = 37;
private ConverterImplRemote converter_ = null;
private AS400ImplRemote system_ = null;
private AS400Server server_;
private NPCPAttribute serverAttributes_;
/**
* constructor
**/
NPConversation(AS400ImplRemote aSystem, AS400Server aServer)
throws AS400Exception,
ErrorCompletingRequestException,
IOException, InterruptedException
{
serverAttributes_ = new NPCPAttribute();
system_ = aSystem;
server_ = aServer;
try {
retrieveServerAttributes(); //xchange our attributes
}
catch (RequestNotSupportedException e) {
throw new ErrorCompletingRequestException(ErrorCompletingRequestException.AS400_ERROR);
}
}
/**
* get reference to the AS400Server object for doing your own thing
**/
AS400Server getServer()
{
return(server_);
}
/**
* get a server attribute
*@parameter attributeID which attribute to retrieve. Maybe
* and of ATTR_NPSLEVEL,
* ATTR_JOBUSER, ATTR_JOBNUMBER or
* ATTR_JOBNAME
*@see NPObject for the attribute ID defines
**/
String getAttribute(int attributeID)
{
return(serverAttributes_.getStringValue(attributeID));
}
//int getHostCCSID()
//{
// return(hostCCSID_);
//}
ConverterImpl getConverter()
{
return(converter_);
}
/**
* make a request of this host server
* @return the NPDataStream return code
**/
int makeRequest(NPDataStream request, NPDataStream reply)
throws AS400Exception,
ErrorCompletingRequestException,
IOException,
InterruptedException,
RequestNotSupportedException
{
int rc = 0;
int correlation = server_.newCorrelationId();
//request.setHostCCSID(hostCCSID_);
//reply.setHostCCSID(hostCCSID_);
request.setConverter(converter_);
reply.setConverter(converter_);
reply.setCorrelation(correlation);
DataStream ds; //@FBA
//to fix multi-threads bug; server_ clear reply and add reply should be atomic.
//If no this, sometimes server_.receive will get other type reply stream.
synchronized (server_) { //@FBA,
server_.clearInstanceReplyStreams();
server_.addInstanceReplyStream(reply);
server_.send(request, correlation);
Trace.log(Trace.DIAGNOSTIC, "makeRequest: send request with correlation" + correlation);
ds = server_.receive(correlation); //@D5A
} //@FBA
//@D5A begin
//Unknown data stream
if (ds != null) {
if (!(ds instanceof NPDataStream)) {
Trace.log(Trace.ERROR, "Unknown reply data stream:" + ds.getClass().getName(),ds.data_);
throw new InternalErrorException(InternalErrorException.DATA_STREAM_UNKNOWN);
}
}
reply = (NPDataStream)ds;
//@D5A end
//sometimes, there is ClassCastException
// reply = (NPDataStream)server_.receive(correlation); //@D5D
if (reply == null)
{
Trace.log(Trace.ERROR, "Didn't get me datastream back!");
throw new NullPointerException();
} else {
rc = reply.getReturnCode();
if (rc != 0)
{
// Do not log an ERROR here - some RCs are not hard ERRORs
// and the RC was already logged as INFORMATION in NPDataStream.
// Trace.log(Trace.ERROR, "DataStream RC = " + rc);
switch (rc)
{
// For CPF_MESSAGEs we throw an AS400Exeption error
case NPDataStream.RET_CPF_MESSAGE:
NPCPAttribute cpCPFMessage = (NPCPAttribute)reply.getCodePoint(NPCodePoint.ATTRIBUTE_VALUE);
if (cpCPFMessage != null)
{
String msgFileName = "";
String msgLibraryName = "";
String msgDate = cpCPFMessage.getStringValue(PrintObject.ATTR_DATE);
String msgTime = cpCPFMessage.getStringValue(PrintObject.ATTR_TIME);
String strCPFMessageID = cpCPFMessage.getStringValue(PrintObject.ATTR_MSGID);
String strCPFMessageText = cpCPFMessage.getStringValue(PrintObject.ATTR_MSGTEXT);
String strCPFMessageHelp = cpCPFMessage.getStringValue(PrintObject.ATTR_MSGHELP);
String strCPFMessageDefaultReply = cpCPFMessage.getStringValue(PrintObject.ATTR_MSGREPLY);
Integer intCPFMessageSeverity = cpCPFMessage.getIntValue(PrintObject.ATTR_MSGSEV);
String strCPFMessageType = cpCPFMessage.getStringValue(PrintObject.ATTR_MSGTYPE);
byte[] substitutionData = new byte[cpCPFMessage.getLength()];
Integer intCPFMessageType = Integer.valueOf(strCPFMessageType);
Trace.log(Trace.ERROR, "CPF Message("+strCPFMessageID+") = " +
strCPFMessageText + ", HelpText= " + strCPFMessageHelp);
AS400Message msg;
if ((intCPFMessageSeverity!=null) && (intCPFMessageType!=null)) {
msg = new AS400Message(strCPFMessageID, strCPFMessageText, msgFileName , msgLibraryName, intCPFMessageSeverity.intValue(), intCPFMessageType.intValue(), substitutionData , strCPFMessageHelp, msgDate, msgTime, strCPFMessageDefaultReply);
} else {
// pre-v5r1 NPS response.
msg = new AS400Message(strCPFMessageID, strCPFMessageText);
msg.setHelp(strCPFMessageHelp);
}
// throw an exception containing our CPF message
throw new AS400Exception(msg);
}
// For READ_EOF we let the caller handle that one
// For empty list we just return the RC and that is OK.
// For return code 4 and 21 (INVALID request action combination
// and function not supported yet) we just return the RC to
// the caller and let them decide if they want to throw
// an exception or just consume it. Exchanging NLVs to older
// systems gives us RC of 21 and we just consume it.
// Opening AFP resources on pre-v3r7 systems gives us
// invalid request-action rc and we end up throwing a
// RequestNotSupportedException elsewhere. We do not throw
// RequestNotSupportedException here because we do not want
// to have it on every request
// For SPLF_NO_MESSAGE we let the caller handle that one
case NPDataStream.RET_READ_EOF:
case NPDataStream.RET_EMPTY_LIST:
case NPDataStream.RET_INV_REQ_ACT:
case NPDataStream.RET_FUNCTION_NOT_SUP:
case NPDataStream.RET_SPLF_NO_MESSAGE:
case NPDataStream.RET_READ_OUT_OF_RANGE:
case NPDataStream.RET_PAGE_OUT_OF_RANGE:
break;
// NLV_NOT_AVAILABLE means that we requested the server change
// its attributes to use our NLV and it doesn't have our NLV
// installed. We'll just consume this RC and continue with the default
// host NLV.
case NPDataStream.RET_NLV_NOT_AVAILABLE:
Trace.log(Trace.WARNING, "NetPrint DataStream host cannot change to our NLV. RC = " + rc);
break;
// fill in the rest of these RCs with appropriate
// exceptions - Can be ErrorCompletingRequestExceptions
// or internal errors/datastream errors.
case NPDataStream.RET_INV_ACT_ID:
Trace.log(Trace.ERROR, "NetPrint DataStream RC = " + rc);
throw new RequestNotSupportedException(
this.getAttribute(PrintObject.ATTR_NPSLEVEL),
RequestNotSupportedException.SYSTEM_LEVEL_NOT_CORRECT);
default:
Trace.log(Trace.ERROR, "NetPrint DataStream RC = " + rc);
throw new ErrorCompletingRequestException(ErrorCompletingRequestException.AS400_ERROR);
}
}
}
return(rc);
}
private void retrieveServerAttributes()
throws AS400Exception,
ErrorCompletingRequestException,
IOException, InterruptedException,
RequestNotSupportedException
{
// first thing to do is to get the host CCSID
int rc;
NPDataStream req = new NPDataStream(NPConstants.NP_SERVER);
NPDataStream reply = new NPDataStream(NPConstants.NP_SERVER);
NPCPAttributeIDList attrsToRetrieve = new NPCPAttributeIDList();
NPCPAttribute sendAttrs = new NPCPAttribute();
NPCPAttribute recvAttrs = new NPCPAttribute(); // catches returned attributes or CPF message
//-----------------------------------------------------------------------
// 1. Exchange CCSIDs
//-----------------------------------------------------------------------
// Our ccsid is always new unicode (0x34b0).
//sendAttrs.setAttrValue(PrintObject.ATTR_NPSCCSID, 0x34b0); // HARDCODE to client CCSID 0x34B0 - new unicode
sendAttrs.setAttrValue(PrintObject.ATTR_NPSCCSID,
ExecutionEnvironment.getCcsid()); //
attrsToRetrieve.addAttrID(PrintObject.ATTR_NPSCCSID); // this is what we want back
req.setAction(NPDataStream.RETRIEVE_ATTRIBUTES);
req.addCodePoint(sendAttrs);
req.addCodePoint(attrsToRetrieve);
reply.addCodePoint(recvAttrs);
rc = makeRequest(req, reply);
if (rc == NPDataStream.RET_OK)
{
Integer serverCCSID = recvAttrs.getIntValue(PrintObject.ATTR_NPSCCSID);
if (serverCCSID != null)
{
int hostCCSID = serverCCSID.intValue();
serverAttributes_.setAttrValue(PrintObject.ATTR_NPSCCSID, hostCCSID);
converter_ = ConverterImplRemote.getConverter(hostCCSID, system_);
}
//-----------------------------------------------------------------------
// 2. Exchange NLV ID (ie: "2924")
//-----------------------------------------------------------------------
// Call to change the server language attribute
// we send up a string (in the server's CCSID which is why we first
// had to get the server CCSID value) indicating our language (ie "2924").
// The server will attempt to use that language for CFP messages that it
// sends back (changes its library list order) but it might not be able to
// if that language isn't on the 400 for the server's product. The server
// will send back the langauge that it is using on the reply.
sendAttrs.reset();
attrsToRetrieve.reset();
//
// we send up our NLV_ID (ie: "2924") and we ask the server
// to send back its NLV_ID
//
sendAttrs.setAttrValue(PrintObject.ATTR_NLV_ID, system_.getNLV());
attrsToRetrieve.addAttrID(PrintObject.ATTR_NLV_ID);
req.setAction(NPDataStream.CHANGE_ATTRIBUTES);
req.resetCodePoints();
req.addCodePoint(sendAttrs);
req.addCodePoint(attrsToRetrieve);
recvAttrs.reset();
reply.resetCodePoints();
reply.addCodePoint(recvAttrs);
// make the change server request
// makeRequest() will throw an exception if it fails
makeRequest(req, reply);
// put the attributes that we received back (should just be the
// the server's NLV_ID) into our serverAttributes_ codepoint
serverAttributes_.addUpdateAttributes(recvAttrs);
//-----------------------------------------------------------------------
// 3. Get the other server attributes (job info and VRM)
//-----------------------------------------------------------------------
// set which attribute we are interested in now from the server
// Job name, number, user, version
attrsToRetrieve.reset();
attrsToRetrieve.addAttrID(PrintObject.ATTR_NPSLEVEL);
attrsToRetrieve.addAttrID(PrintObject.ATTR_JOBNAME);
attrsToRetrieve.addAttrID(PrintObject.ATTR_JOBUSER);
attrsToRetrieve.addAttrID(PrintObject.ATTR_JOBNUMBER);
req.setAction(NPDataStream.RETRIEVE_ATTRIBUTES);
req.resetCodePoints();
req.addCodePoint(attrsToRetrieve);
recvAttrs.reset();
reply.resetCodePoints();
reply.addCodePoint(recvAttrs);
rc = makeRequest(req, reply);
if (rc == NPDataStream.RET_OK)
{
serverAttributes_.addUpdateAttributes(recvAttrs);
// if information tracing is on,
// log the VRM of the system we are talking to
if (Trace.isTraceOn() && Trace.isTraceInformationOn())
{
Trace.log(Trace.INFORMATION,
" Network Print Server started ");
Trace.log(Trace.INFORMATION,
" NetPrint Server info (System/Job#/JobUser/JobName): " +
//server_.getSystem().getSystemName() + "/" +
serverAttributes_.getStringValue(PrintObject.ATTR_JOBNUMBER) + "/" +
serverAttributes_.getStringValue(PrintObject.ATTR_JOBUSER) + "/" +
serverAttributes_.getStringValue(PrintObject.ATTR_JOBNAME)
);
Trace.log(Trace.INFORMATION,
" NetPrint Server VRM = " +
serverAttributes_.getStringValue(PrintObject.ATTR_NPSLEVEL)
);
}
}
}
} // retrieveServerAttributes
}
// NPConversation class
© 2015 - 2025 Weber Informatics LLC | Privacy Policy