src.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-jdk8 Show documentation
Show all versions of jt400-jdk8 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 = new Integer(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