All Downloads are FREE. Search and download functionalities are using the official Maven repository.

contrib.com.ibm.as400.access.ValidationList Maven / Gradle / Ivy

There is a newer version: 11.1
Show newest version
///////////////////////////////////////////////////////////////////////////////
//                                                                             
// JTOpen (IBM Toolbox for Java - OSS version)                              
//                                                                             
// Filename: ValidationList.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) 2001-2010 International Business Machines Corporation and     
// others. All rights reserved.                                                
//                                                                             
///////////////////////////////////////////////////////////////////////////////

package com.ibm.as400.access;

import java.beans.PropertyVetoException;

/**
 * Represents a system validation list object.
 * 

* Note: The ability to find and modify the list is dependent on * the access rights of the signed-on user profile to the * validation list. * * @author Thomas Johnson ([email protected]), Kingland Systems Corporation */ public class ValidationList { private static int LISTBUFFER_LENGTH_INITIAL = 32768; //32K private static int LISTBUFFER_LENGTH_NEXT = 524288; //512K private AS400 as400_ = null; private AS400Structure listInfo_ = null; private AS400Structure vlde0100_ = null; private QSYSObjectPathName path_ = null; private String description_ = null; /** * Constructs a validation list. *

* Note: The AS400 and Path properties must be set prior to taking * action against the object. */ public ValidationList() { super(); } /** * Constructs a validation list for the given system. *

* Note: The Path property must be set prior to taking action against * the object. * * @param as400 * the system * */ public ValidationList(AS400 as400) { this(); setAS400(as400); } /** * Constructs a validation list for the given system and path. * * @param as400 * com.ibm.as400.access.AS400 * @param path * com.ibm.as400.access.QSYSObjectPathName * */ public ValidationList(AS400 as400, QSYSObjectPathName path) { this(); setAS400(as400); setPath(path); } /** * Constructs a validation list for the given system * and object/library names. * * @param as400 * com.ibm.as400.access.AS400 * @param obj * java.lang.String * @param lib * java.lang.String */ public ValidationList(AS400 as400, String obj, String lib) { this(); setAS400(as400); setPath(new QSYSObjectPathName(lib, obj, "vldl")); } /** * Adds the entry to the validation list. * * @param entry * ValidationListEntry * @exception PersistenceException * If an error occurs while calling the IBM i APIs. */ public void addEntry(ValidationListEntry entry) throws PersistenceException { ProgramCall pgm = new ProgramCall(getAS400()); ProgramParameter[] parmList = new ProgramParameter[6]; try { pgm.setProgram(QSYSObjectPathName.toPath("QSYS", "QSYADVLE", "PGM"), parmList); } catch (PropertyVetoException pve) { Trace.log(Trace.ERROR, pve); } // Refer to documentation for the QSYADVLE Security API for a complete description of parameters parmList[0] = getQualifiedNameParm(); parmList[1] = new ProgramParameter(entry.getEntryID().toBytes()); parmList[2] = new ProgramParameter(entry.getDataToEncrypt().toBytes()); parmList[3] = new ProgramParameter(entry.getUnencryptedData().toBytes()); parmList[4] = new ProgramParameter(entry.getAttributeInfo().toBytes()); parmList[5] = new ProgramParameter(new AS400Bin4().toBytes(0)); runProgram(pgm); } /** * Alters the entry in the validation list. * * @param entry * ValidationListEntry * @exception PersistenceException * If an error occurs while calling the IBM i APIs. */ public void changeEntry(ValidationListEntry entry) throws PersistenceException { ProgramCall pgm = new ProgramCall(getAS400()); ProgramParameter[] parmList = new ProgramParameter[6]; try { pgm.setProgram(QSYSObjectPathName.toPath("QSYS", "QSYCHVLE", "PGM"), parmList); } catch (PropertyVetoException pve) { Trace.log(Trace.ERROR, pve); } // Refer to documentation for the QSYCHVLE Security API for a complete description of parameters parmList[0] = getQualifiedNameParm(); parmList[1] = new ProgramParameter(entry.getEntryID().toBytes()); parmList[2] = new ProgramParameter(entry.getDataToEncrypt().toBytes()); parmList[3] = new ProgramParameter(entry.getUnencryptedData().toBytes()); parmList[4] = new ProgramParameter(entry.getAttributeInfo().toBytes()); parmList[5] = new ProgramParameter(new AS400Bin4().toBytes(0)); runProgram(pgm); } /** * Close the current list of entries maintained on the system. *

* The list is opened by the initial call to the list API. In doing so, the entire * contents of the list is retrieved as a snapshot and stored in a buffer on the * IBM i system. The list contents can then be retrieved from the pre-filled * buffer, in whole or in part, at the convenience of the application by using a * system-provided handle. The handle is used to close the list when the * application has completed processing of all entries. * * @param handle byte[] * @exception PersistenceException * If an error occurs while calling the IBM i APIs. */ private void closeList(byte[] handle) throws PersistenceException { ProgramCall pgm = new ProgramCall(getAS400()); ProgramParameter[] parmList = new ProgramParameter[2]; try { pgm.setProgram(QSYSObjectPathName.toPath("QGY", "QGYCLST", "PGM"), parmList); } catch (PropertyVetoException pve) { Trace.log(Trace.ERROR, pve); } // Refer to documentation for the QGYCLST generic list API for a complete description of parameters parmList[0] = new ProgramParameter(new AS400ByteArray(handle.length).toBytes(handle)); parmList[1] = new ProgramParameter(new AS400Bin4().toBytes(0)); runProgram(pgm); } /** * Creates the validation list on the IBM i system. * * @exception PersistenceException * If an error occurs while calling the IBM i command. */ public void create() throws PersistenceException { String obj = getPath().getObjectName(); String lib = getPath().getLibraryName(); CommandCall cmd = new CommandCall(getAS400(), "CRTVLDL VLDL("+lib+"/"+obj+") TEXT('"+getDescription()+"')"); runCommand(cmd); } /** * Deletes the validation list from the IBM i system. * * @exception PersistenceException * If an error occurs while calling the IBM i command. */ public void delete() throws PersistenceException { String obj = getPath().getObjectName(); String lib = getPath().getLibraryName(); CommandCall cmd = new CommandCall(getAS400(), "DLTVLDL VLDL("+lib+"/"+obj+")"); runCommand(cmd); } /** * Sets contents of the string buffer at the given offset from the specified string. * * @param buffer * java.lang.StringBuffer * @param offset * int * @param s * java.lang.String */ private void fillStringBuffer(StringBuffer buffer, int offset, String s) { for (int i=0; i * The ccsid parameter indicates the ccsid used to store the identifier in the * entry on the IBM i system. This apparently needs to be an exact match in order to * find the entry as it was originally inserted. *

* No attribute values are retrieved for the entry. * * @param identifier * java.lang.String * @param ccsid * int * @return * ValidationListEntry * @exception PersistenceException * If an error occurs while calling the IBM i APIs. */ public ValidationListEntry findEntry(String identifier, int ccsid) throws PersistenceException { return findEntry(identifier, ccsid, new ValidationListAttribute[0]); } /** * Returns an entry from the validation list with the given identifier and attributes. *

* The ccsid parameter indicates the ccsid used to store the identifier in the * entry on the IBM i system. This apparently needs to be an exact match in order to * find the entry as it was originally inserted. *

* The attributes parameter indicates the list of attributes to retrieve for * the entry. Each attribute specified must contain a valid identifier. * * @param identifier * java.lang.String * @param ccsid * int * @param attributes * ValidationListAttribute[] * @return * ValidationListEntry * @exception PersistenceException * If an error occurs while calling the IBM i APIs. */ public ValidationListEntry findEntry(String identifier, int ccsid, ValidationListAttribute[] attributes) throws PersistenceException { ValidationListEntry entry = new ValidationListEntry(); ProgramCall pgm = new ProgramCall(getAS400()); ProgramParameter[] parmList = new ProgramParameter[6]; try { pgm.setProgram(QSYSObjectPathName.toPath("QSYS", "QSYFDVLE", "PGM"), parmList); } catch (PropertyVetoException pve) { Trace.log(Trace.ERROR, pve); } ValidationListTranslatedData entryID = new ValidationListTranslatedData(identifier, ccsid, getAS400()); ValidationListAttributeInfo attrInfo = new ValidationListAttributeInfo(attributes); // Refer to documentation for the QSYFDVLE Security API for a complete description of parameters parmList[0] = getQualifiedNameParm(); parmList[1] = new ProgramParameter(entryID.toBytes()); parmList[2] = new ProgramParameter(attrInfo.toBytes()); parmList[3] = new ProgramParameter(entry.getByteLength()); parmList[4] = new ProgramParameter(attrInfo.getByteLength()); parmList[5] = new ProgramParameter(new AS400Bin4().toBytes(0)); runProgram(pgm); entry.init(parmList[3].getOutputData(), 0); attrInfo.setAttributesData(parmList[4].getOutputData(), 0); entry.setAttributeInfo(attrInfo); return entry; } /** * Returns the IBM i system containing the validation list. * * @return com.ibm.as400.access.AS400 */ public AS400 getAS400() { return as400_; } /** * Returns the text description for the validation list object. *

* Note: Only returned if set by the setDescription() method. * * @return java.lang.String */ public String getDescription() { if (description_ != null) return description_; return ""; } /** * Returns all entries from the validation list. *

* Note: The list is opened by the initial call to the list API. In doing so, the entire * contents of the list is retrieved as a snapshot and stored in a buffer on the * IBM i system. The list contents can then be retrieved from the pre-filled * buffer, in whole or in part, at the convenience of the application by using a * system-provided handle. The handle is used to close the list when the * application has completed processing of all entries. *

* Currently the entire list is built and retrieved synchronously by this method. * This could potentially be changed to allow for additional processing options, * such as asynchronous building of the list, retrieving only a subset of * entries, etc. For now we just keep it simple. * * @exception PersistenceException * If an error occurs while calling the IBM i APIs. */ public ValidationListEntry[] getEntries() throws PersistenceException { ProgramCall pgm = new ProgramCall(getAS400()); ProgramParameter[] parmList = new ProgramParameter[7]; int bufferLength = LISTBUFFER_LENGTH_INITIAL; try { pgm.setProgram(QSYSObjectPathName.toPath("QGY", "QSYOLVLE", "PGM"), parmList); } catch (PropertyVetoException pve) { Trace.log(Trace.ERROR, pve); } // Refer to documentation for the QSYOLVLE Security API for a complete description of parameters parmList[0] = new ProgramParameter(bufferLength); parmList[1] = new ProgramParameter(new AS400Bin4().toBytes(bufferLength)); parmList[2] = new ProgramParameter(getListInfoStruct().getByteLength()); parmList[3] = new ProgramParameter(new AS400Bin4().toBytes(-1)); // List is built synchronously parmList[4] = new ProgramParameter(new AS400Text(8, getAS400()).toBytes("VLDE0100")); parmList[5] = getQualifiedNameParm(); parmList[6] = new ProgramParameter(new AS400Bin4().toBytes(0)); // Open/initialize the list runProgram(pgm); Object[] listInfo = (Object[])getListInfoStruct().toObject(parmList[2].getOutputData()); ValidationListEntry[] list = new ValidationListEntry[((Integer)listInfo[0]).intValue()]; byte[] listHandle = (byte[])listInfo[2]; int listPosition = ((Integer)listInfo[1]).intValue(); // Process the entries retrieved on the initial call parseEntries(list, 0, parmList[0].getOutputData(), listPosition); // Continue to fetch more entries until the entire list is retrieved while (listPosition < list.length) { listPosition += getNextEntries(listHandle, listPosition, list); } // Close/cleanup the list closeList(listHandle); return list; } /** * Returns the structure used to convert values for a list information parameter. *

* This structure is referenced when calling the QSYOLVLE and QGYGTLE APIs to retrieve * the initial and subsequent lists of entries from the validation list, respectively. * * @return com.ibm.as400.access.AS400Structure */ private AS400Structure getListInfoStruct() { if (listInfo_ == null) listInfo_ = new AS400Structure( new AS400DataType[] { new AS400Bin4(), // Total records new AS400Bin4(), // Records returned new AS400ByteArray(4), // Request handle new AS400Bin4(), // Record length new AS400Text(1, as400_), // Info complete indicator new AS400ByteArray(13), // Date/time created (unconverted) new AS400Text(1, as400_), // List status indicator new AS400ByteArray(1), // Reserved new AS400Bin4(), // Length of info returned new AS400Bin4() // First record in buffer }); return listInfo_; } /** * Retrieve the next group of entries from the buffered list. *

* The list is opened by the initial call to the list API. In doing so, the entire * contents of the list is retrieved as a snapshot and stored in a buffer on the * IBM i system. The list contents can then be retrieved from the pre-filled * buffer, in whole or in part, at the convenience of the application by using a * system-provided handle. The handle is used to close the list when the * application has completed processing of all entries. *

* This method accepts the handle and starting position for retrieving the next * group of entries. All entries retrieved are stored in the list, and the * number of entries retrieved is returned. *

* The current implementation calls for all remaining entries to be retrieved in one * pass. If necessary, however, this method could be called multiple times as * necessary to fill in the remaining list items. * * @param listHandle * byte[] * @param listPosition * int * @param list * ValidationListEntry[] * @return * The number of entries retrieved. * @exception PersistenceException * If an error occurs while calling the IBM i APIs. */ private int getNextEntries(byte[] listHandle, int listPosition, ValidationListEntry[] list) throws PersistenceException { int recordsToReturn = list.length - listPosition; int recordsReturned = 0; if (recordsToReturn > 0) { ProgramCall pgm = new ProgramCall(getAS400()); ProgramParameter[] parmList = new ProgramParameter[7]; // Try & retrieve all remaining entries in a single call; keeps it simple for now int bufferLength = LISTBUFFER_LENGTH_NEXT; try { pgm.setProgram(QSYSObjectPathName.toPath("QGY", "QGYGTLE", "PGM"), parmList); } catch (PropertyVetoException pve) { Trace.log(Trace.ERROR, pve); } // Refer to documentation for the QGYGTLE generic list API for a complete description of parameters parmList[0] = new ProgramParameter(bufferLength); parmList[1] = new ProgramParameter(new AS400Bin4().toBytes(bufferLength)); parmList[2] = new ProgramParameter(listHandle); parmList[3] = new ProgramParameter(getListInfoStruct().getByteLength()); parmList[4] = new ProgramParameter(new AS400Bin4().toBytes(recordsToReturn)); parmList[5] = new ProgramParameter(new AS400Bin4().toBytes(listPosition+1)); // 1-based parmList[6] = new ProgramParameter(new AS400Bin4().toBytes(0)); runProgram(pgm); Object[] listInfo = (Object[])getListInfoStruct().toObject(parmList[3].getOutputData()); recordsReturned = ((Integer)listInfo[1]).intValue(); parseEntries(list, listPosition, parmList[0].getOutputData(), recordsReturned); } return recordsReturned; } /** * Returns the number of entries in the validation list. * * @exception PersistenceException * If an error occurs while calling the IBM i APIs. */ public int getNumberOfEntries() throws PersistenceException { ProgramCall pgm = new ProgramCall(getAS400()); ProgramParameter[] parmList = new ProgramParameter[7]; int bufferLength = 512; try { pgm.setProgram(QSYSObjectPathName.toPath("QGY", "QSYOLVLE", "PGM"), parmList); } catch (PropertyVetoException pve) { Trace.log(Trace.ERROR, pve); } // Refer to documentation for the QSYOLVLE Security API for a complete description of parameters parmList[0] = new ProgramParameter(bufferLength); parmList[1] = new ProgramParameter(new AS400Bin4().toBytes(bufferLength)); parmList[2] = new ProgramParameter(getListInfoStruct().getByteLength()); parmList[3] = new ProgramParameter(new AS400Bin4().toBytes(-1)); // List is built synchronously parmList[4] = new ProgramParameter(new AS400Text(8, getAS400()).toBytes("VLDE0100")); parmList[5] = getQualifiedNameParm(); parmList[6] = new ProgramParameter(new AS400Bin4().toBytes(0)); // Open the list runProgram(pgm); // Retrieve list information Object[] listInfo = (Object[])getListInfoStruct().toObject(parmList[2].getOutputData()); // Close the list closeList((byte[])listInfo[2]); // Return the retrieved info return ((Integer)listInfo[0]).intValue(); } /** * Returns the location (library context) of the validation list. * * @return com.ibm.as400.access.QSYSObjectPathName */ public QSYSObjectPathName getPath() { return path_; } /** * Returns a program parameter to be used for IBM i Toolbox program calls that * require the qualifed name of the validation list. *

* The object name is set into the first 10 bytes of the parameter value. * The library name is set into the next 10 bytes of the parameter value. * * @return com.ibm.as400.access.ProgramParameter */ protected ProgramParameter getQualifiedNameParm() { StringBuffer buffer = new StringBuffer(" "); fillStringBuffer(buffer, 0, getPath().getObjectName()); fillStringBuffer(buffer, 10, getPath().getLibraryName()); return new ProgramParameter( ProgramParameter.PASS_BY_REFERENCE, new AS400Text(20, getAS400()).toBytes(buffer.toString())); } /** * Returns the structure used to parse entries returned by the list APIs. *

* This structure is referenced when parsing entries returned by calls to the * QSYOLVLE and QGYGTLE APIs. * * @return com.ibm.as400.access.AS400Structure */ private AS400Structure getVlde0100Struct() { if (vlde0100_ == null) vlde0100_ = new AS400Structure( new AS400DataType[] { new AS400Bin4(), // Length of entry new AS400Bin4(), // Displacement to entry ID new AS400Bin4(), // Length of entry ID new AS400Bin4(), // CCSID of entry ID new AS400Bin4(), // Displacement to encrypted data new AS400Bin4(), // Length of encrypted data new AS400Bin4(), // CCSID of encrypted data new AS400Bin4(), // Displacement to entry data new AS400Bin4(), // Length of entry data new AS400Bin4() // CCSID of entry data }); return vlde0100_; } /** * Handles an unexpected exception that was caught as the result of invoking an IBM i * API or command. The exception is wrapped and surfaced as a PersistenceException. * * @exception PersistenceException */ private void handleUnexpectedAS400Exception(Throwable e) throws PersistenceException { throw new PersistenceException(e); } /** * Handles unexpected messages that was received as the result of invoking an IBM i * API or command. The messages are wrapped and surfaced as a PersistenceException. * * @exception PersistenceException */ private void handleUnexpectedAS400Messages(AS400Message[] messages) throws PersistenceException { throw new PersistenceException(messages); } /** * Parse the validation list entries from the raw (IBM i) bytes of a specified buffer. *

* Beginning with the specified start position, the parsed bytes are inserted * as ValidationListEntry objects into the list. The list is assumed to be * large enough to contain all the parsed entries. The buffer is assumed * to contain numberInBuffer entries. * * @param list * ValidationListEntry[] * @param start * int * @param buffer * byte[] * @param numberInBuffer * int */ private void parseEntries( ValidationListEntry[] list, int start, byte[] buffer, int numberInBuffer) { int position = 0; for (int i=0; i * Beginning with the specified start position, bytes are returned * from the buffer up to the given length. * * @param buffer byte[] * @param position int * @param length int * @return byte[] */ private byte[] parseEntryData(byte[] buffer, int start, int length) { byte[] bytes = new byte[length]; System.arraycopy(buffer, start, bytes, 0, length); return bytes; } /** * Deletes the entry from the validation list. *

* Note: The AS400 and Path properties must be set prior to calling * this method. * * @param entry * ValidationListEntry * @exception PersistenceException * If an error occurs while calling the IBM i validation list APIs. */ public void removeEntry(ValidationListEntry entry) throws PersistenceException { ProgramCall pgm = new ProgramCall(getAS400()); ProgramParameter[] parmList = new ProgramParameter[3]; // Refer to documentation for the QSYRMVLE Security API for a complete description of parameters try { pgm.setProgram(QSYSObjectPathName.toPath("QSYS", "QSYRMVLE", "PGM"), parmList); } catch (PropertyVetoException pve) { Trace.log(Trace.ERROR, pve); } parmList[0] = getQualifiedNameParm(); parmList[1] = new ProgramParameter(entry.getEntryID().toBytes()); parmList[2] = new ProgramParameter(new AS400Bin4().toBytes(0)); runProgram(pgm); } /** * Run the given IBM i command. * * @param c * com.ibm.as400.access.CommandCall * @exception PersistenceException * If the command is not successful or an unexpected exception occurs. */ private void runCommand(CommandCall c) throws PersistenceException { boolean success = false; try {success = c.run();} catch (Exception e) { handleUnexpectedAS400Exception(e); } if (!success) handleUnexpectedAS400Messages(c.getMessageList()); } /** * Run the given IBM i program call. * * @param p * com.ibm.as400.access.ProgramCall * @exception PersistenceException * If the command is not successful or an unexpected exception occurs. */ private void runProgram(ProgramCall p) throws PersistenceException { // Try up to 5 times if object is locked (message CPF9803) int i = 0; boolean success = false; boolean lockedObj = false; PersistenceException err; do { try { success = false; lockedObj = false; err = null; // Pause (if not first time through the loop) try { if (i > 0) Thread.sleep(5000); } catch (InterruptedException ie) {} // Run the program try { success = p.run(); } catch (Exception e) { handleUnexpectedAS400Exception(e); } if (!success) { // Check available messages on the program call AS400Message[] msgs = p.getMessageList(); if (msgs != null) for (int j = 0; !lockedObj && j 0) Thread.sleep(5000); } catch (InterruptedException ie) {}; // Run the service program runProgram(spc); errno = (spc.getReturnValueFormat() == ServiceProgramCall.RETURN_INTEGER && spc.getIntegerReturnValue() == 0) ? 0 : spc.getErrno(); } while (++i < 5 && errno == 3406); // Check for abnormal error condition if (errno == 0) return; PersistenceException pe = new PersistenceException( new StringBuffer("Procedure named " ).append(spc.getProcedureName() ).append(" failed with errorno " ).append(errno ).toString()); throw pe; } /** * Sets the IBM i system containing the validation list. * * @param as400 com.ibm.as400.access.AS400 */ public void setAS400(AS400 as400) { as400_ = as400; } /** * Sets the text description for the validation list object. *

* Note: Only recognized if set prior to invoking the create() method. * * @param s java.lang.String */ public void setDescription(String s) { description_ = s; } /** * Sets the location (library context) of the validation list. * * @param path com.ibm.as400.access.QSYSObjectPathName */ public void setPath(QSYSObjectPathName path) { path_ = path; } /** * Verify that the encrypted information specified for the given entry is correct. *

* The EntryID and DataToEncrypt must be specified for the entry prior * to verification. Returns true if the data to encrypt matches the data already * encrypted for the entry at that ID on the IBM i; otherwise returns false. * * @param entry * ValidationListEntry * @return boolean * @exception PersistenceException * If an error occurs while calling the IBM i APIs. */ public boolean verifyEntry(ValidationListEntry entry) throws PersistenceException { // Note: length of ID & data to encrypt must be in range accepted by API int len = entry.getDataToEncrypt().getBytes().length; if (len < 1 || len > 600) return false; len = entry.getEntryID().getBytes().length; if (len < 1 || len > 100) return false; // Create & prime the program parameters ProgramParameter[] parmList = new ProgramParameter[3]; parmList[0] = getQualifiedNameParm(); parmList[1] = new ProgramParameter( ProgramParameter.PASS_BY_REFERENCE, entry.getEntryID().toBytes()); parmList[2] = new ProgramParameter( ProgramParameter.PASS_BY_REFERENCE, entry.getDataToEncrypt().toBytes()); ServiceProgramCall sPGMCall = new ServiceProgramCall(getAS400()); // Refer to documentation for the QsyVerifyValidationLstEntry Security API for a complete description of parameters try { sPGMCall.setProgram("/QSYS.LIB/QSYVLDL.SRVPGM", parmList); sPGMCall.setProcedureName("QsyVerifyValidationLstEntry"); sPGMCall.setReturnValueFormat(ServiceProgramCall.RETURN_INTEGER); } catch (PropertyVetoException pve) { Trace.log(Trace.ERROR, pve); } runServiceProgram(sPGMCall); return sPGMCall.getIntegerReturnValue() == 0; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy