src.com.ibm.as400.access.Product Maven / Gradle / Ivy
Show all versions of jt400-jdk8 Show documentation
///////////////////////////////////////////////////////////////////////////////
//
// JTOpen (IBM Toolbox for Java - OSS version)
//
// Filename: Product.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-2004 International Business Machines Corporation and
// others. All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
package com.ibm.as400.access;
import java.beans.PropertyVetoException;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
/**
* Represents a licensed product on the system.
* The {@link #isInstalled isInstalled()} method should be called to verify that
* the product is installed on the system. If the product is not installed, other information
* returned by getters in this class might not be valid.
**/
public class Product
{
private static final String USERSPACE_NAME = "JT4PTF QTEMP ";
private static final String USERSPACE_PATH = "/QSYS.LIB/QTEMP.LIB/JT4PTF.USRSPC";
private boolean loaded_ = false; // Have we loaded the common (PRDR0100 format) values
private boolean loadedLoadID_ = false; // Have we loaded the load ID yet
private boolean partiallyLoaded_ = false; // Were we constructed from a ProductList
private boolean loadedOptions_ = false; // Have we loaded our option information
private boolean loadedDescriptionText_ = false; // Have we loaded the description yet
private boolean loaded500_ = false; // Have we loaded the PRDR0500 format values
private boolean loaded800_ = false; // Have we loaded the PRDR0500 format values
private boolean error100_ = false; // Did we get an error retrieving the PRDR0100 format values
private boolean error500_ = false; // Did we get an error retrieving the PRDR0500 format values
private boolean error800_ = false; // Did we get an error retrieving the PRDR0800 format values
private AS400 system_; // never null
private String productID_; // never null
private String productOption_; // never null
private String releaseLevel_; // never null
private String descriptionID_;
private String descriptionText_;
private String messageFile_;
private boolean installed_ = true; // Default to true; if the API throws an exception, switch to false.
private String loadID_;
// PRDR0100 format (fields that are meaningfully returned in all formats)
// Note: The loaded_ flag indicates that the following fields have been loaded.
// The loadID_ field gets its own separate flag: loadedLoadID_
private String loadType_;
private String symbolicLoadState_;
private boolean loadErrorIndicator_;
private String loadState_;
private boolean supported_;
private String registrationType_;
private String registrationValue_;
private String primaryLanguageLoadID_;
private String minimumTargetRelease_;
private String minimumBaseVRM_;
private int requirementsMet_;
private String level_;
// PRDR0500 format
private boolean allowsMultipleReleases_;
private Date releaseDate_;
private String firstCopyright_;
private String currentCopyright_;
// messageFile_;
// product options and their properties
private boolean allowsDynamicNaming_;
private String minimumVRM_;
private boolean allowsMixedReleases_;
// PRDR0800 format
private ProductDirectoryInformation[] directories_;
private Product[] options_;
private int chunkSize_ = 8192;
/**
* Constant indicating that the product load is defined but
* the product load object for this load does not exist. When
* a product definition is created, a code load is defined for
* each product option, and language loads can be defined.
**/
public static final String LOAD_STATE_DEFINED_NO_OBJECT = "10";
/**
* Constant indicating that the product load object exists, but
* before it can be saved using the Save Licensed Program (SAVLICPGM)
* command, it must be packaged with either the Package Product
* Option (PKGPRDOPT) command or the Package Product Option
* (QSZPKGPO) API.
**/
public static final String LOAD_STATE_DEFINED_OBJECT_EXISTS = "20";
/**
* Constant indicating that a Restore Licensed Program (RSTLICPGM)
* command did not complete successfully. A preoperation exit program
* failed. The product being replaced had been packaged, but not installed.
**/
public static final String LOAD_STATE_PACKAGED_RESTORE_FAILED_EXIT_PROGRAM_FAILED = "3E";
/**
* Constant indicating that a Restore Licensed Program (RSTLICPGM)
* command failed. A preoperation exit program did not fail. The product
* being replaced had been packaged, but not installed.
**/
public static final String LOAD_STATE_PACKAGED_RESTORE_FAILED = "3F";
/**
* Constant indicating that the product load object for this load has
* been packaged with the Package Product Option (PKGPRDOPT) command
* or the Package Product Option (QSZPKGPO) API.
**/
public static final String LOAD_STATE_PACKAGED = "30";
/**
* Constant indicating that the product load object for this load has
* been packaged with the Package Product Option (PKGPRDOPT) command
* or the Package Product Option (QSZPKGPO) API, but either a
* development library or folder was renamed when the product does
* not allow dynamic naming, or the product definition or product load
* for a packaged load was renamed or moved to another library.
**/
public static final String LOAD_STATE_PACKAGED_RENAMED = "32";
/**
* Constant indicating that the product load object for this load has
* been packaged with the Package Product Option (PKGPRDOPT) command
* or the Package Product Option (QSZPKGPO) API, but an object was
* found to be damaged the last time that the Check Product Option
* (CHKPRDOPT) command or Save Licensed Program (SAVLICPGM) command
* was used for this load.
**/
public static final String LOAD_STATE_PACKAGED_DAMAGED = "33";
/**
* Constant indicating that the product load object for this load has
* been packaged with the Package Product Option (PKGPRDOPT) command
* or the Package Product Option (QSZPKGPO) API, but either an attempt
* was made to delete the product load using the Delete Licensed Program
* (DLTLICPGM) command and the attempt failed, or a
* packaged object was missing the last time the Check Product Option
* (CHKPRDOPT) command or Save Licensed Program (SAVLICPGM) command was
* used for this load.
**/
public static final String LOAD_STATE_PACKAGED_DELETED = "34";
/**
* Constant indicating that a Restore Licensed Program (RSTLICPGM) command
* is in progress. The product being replaced had been packaged, but
* not installed.
**/
public static final String LOAD_STATE_PACKAGED_RESTORE_IN_PROGRESS = "35";
/**
* Constant indicating that a Delete Licensed Program (DLTLICPGM) command
* is in progress. The product being deleted had been packaged, but
* not installed.
**/
public static final String LOAD_STATE_PACKAGED_DELETE_IN_PROGRESS = "38";
/**
* Constant indicating that a Restore Licensed Program (RSTLICPGM) command
* is in progress. The product being replaced had been installed.
**/
public static final String LOAD_STATE_INSTALLED_RESTORE_IN_PROGRESS = "50";
/**
* Constant indicating that a Delete Licensed Program (DLTLICPGM) command
* is in progress. The product being deleted had been installed.
**/
public static final String LOAD_STATE_INSTALLED_DELETE_IN_PROGRESS = "53";
/**
* Constant indicating that this product is an IBM-supplied product and
* it is not compatible with the currently installed release level of the System i operating system.
* An error occurred when the product was restored or when the operating system was installed.
* The IBM-supplied product is at a release level earlier than V2R2M0, which
* is not supported by the Save Licensed Program (SAVLICPGM) command.
**/
public static final String LOAD_STATE_IBM_SUPPLIED_NOT_COMPATIBLE = "59";
/**
* Constant indicating that a Restore Licensed Program (RSTLICPGM) command
* did not complete successfully. A preoperation exit program failed. The
* product being replaced had been installed.
**/
public static final String LOAD_STATE_INSTALLED_RESTORE_FAILED_EXIT_PROGRAM_FAILED = "6E";
/**
* Constant indicating that a Restore Licensed Program (RSTLICPGM) command
* failed. The failure was not a preoperation exit program or postoperation
* exit program. The product being replaced had been installed.
**/
public static final String LOAD_STATE_INSTALLED_RESTORE_FAILED = "6F";
/**
* Constant indicating that the product load object for this load was loaded
* on to the system by the Restore Licensed Program (RSTLICPGM) command.
**/
public static final String LOAD_STATE_RESTORED = "60";
/**
* Constant indicating that the product load object for this load was loaded
* on to the system by the Restore Licensed Program (RSTLICPGM) command but
* a postoperation exit program failed.
**/
public static final String LOAD_STATE_RESTORED_EXIT_PROGRAM_FAILED = "61";
/**
* Constant indicating that an installed library or folder was renamed, but
* the product does not allow dynamic naming.
**/
public static final String LOAD_STATE_RESTORED_RENAMED = "62";
/**
* Constant indicating that the product load object for this load was installed
* by the Restore Licensed Program (RSTLICPGM) command, but an object is
* damaged.
**/
public static final String LOAD_STATE_RESTORED_DAMAGED = "63";
/**
* Constant indicating that the product load object for this load was installed
* by the Restore Licensed Program (RSTLICPGM) command, but either an object
* was found to be missing when the Check Product Option (CHKPRDOPT) command
* or the Save Licensed Program (SAVLICPGM) command was used, or an error
* occurred while the Delete Licensed Program (DLTLICPGM) command was being
* used.
**/
public static final String LOAD_STATE_RESTORED_DELETED = "64";
/**
* Constant indicating that the Check Product Option (CHKPRDOPT) command was
* used for this product load, but the postoperation exit program failed or
* indicated that an error was found.
**/
public static final String LOAD_STATE_CHECK_ERROR = "67";
/**
* Constant indicating that the product load was installed successfully. If an
* object was missing or was damaged, but the problem was corrected, using
* the Check Product Option (CHKPRDOPT) command sets the state back to this.
**/
public static final String LOAD_STATE_INSTALLED = "90";
/**
* Constant indicating a product load type of *CODE.
**/
public static final String LOAD_TYPE_CODE = "*CODE";
/**
* Constant indicating a product load type of *LNG.
**/
public static final String LOAD_TYPE_LANGUAGE = "*LNG";
/**
* Constant indicating a product option of *BASE.
**/
public static final String PRODUCT_OPTION_BASE = "*BASE";
/**
* Constant indicating a feature ID of *CODE.
**/
public static final String PRODUCT_FEATURE_CODE = "*CODE";
/**
* Constant indicating a product ID of *OPSYS.
**/
public static final String PRODUCT_ID_OPERATING_SYSTEM = "*OPSYS";
/**
* Constant indicating a release level of *CUR.
**/
public static final String PRODUCT_RELEASE_CURRENT = "*CUR";
/**
* Constant indicating a release level of *ONLY.
**/
public static final String PRODUCT_RELEASE_ONLY = "*ONLY";
/**
* Constant indicating a release level of *PRV.
**/
public static final String PRODUCT_RELEASE_PREVIOUS = "*PRV";
/**
* Constant indicating that the release level of the product
* should be determined at runtime by the system.
**/
public static final String PRODUCT_RELEASE_ANY = "ANY";
/**
* Constant indicating that the registration type *PHONE was
* specified when the product load or product definition was
* created.
**/
public static final String REGISTRATION_TYPE_PHONE = "02";
/**
* Constant indicating that the registration type is the
* same as the registration type for the operating system.
**/
public static final String REGISTRATION_TYPE_SYSTEM = "04";
/**
* Constant indicating that the registration type *CUSTOMER was
* specified when the product load or product definition was
* created.
**/
public static final String REGISTRATION_TYPE_CUSTOMER = "08";
/**
* Constant indicating that there is not enough information
* available to determine if the release requirements have
* been met. This will be the value if the load type is
* LOAD_TYPE_LANGUAGE.
**/
public static final int REQUIREMENTS_UNKNOWN = 0;
/**
* Constant indicating that the releases of the *BASE and option
* meet all requirements.
**/
public static final int REQUIREMENTS_MET = 1;
/**
* Constant indicating that the release of the option is too
* old compared to the *BASE.
**/
public static final int REQUIREMENTS_OPTION_TOO_OLD = 2;
/**
* Constant indicating that the release of the *BASE is too
* old compared to the option.
**/
public static final int REQUIREMENTS_BASE_TOO_OLD = 3;
/**
* Constant indicating that the load is defined but the product load
* object for this load does not exist.
**/
public static final String SYMBOLIC_LOAD_STATE_DEFINED = "*DEFINED";
/**
* Constant indicating that the product load object for this load
* exists. It must be packaged with the Package Product Option (PKGPRDOPT)
* command before it can be saved using the Save Licensed Program (SAVLICPGM) command.
**/
public static final String SYMBOLIC_LOAD_STATE_CREATED = "*CREATED";
/**
* Constant indicating that the product load object for this load has
* been packaged with the Package Product Option (PKGPRDOPT) command.
**/
public static final String SYMBOLIC_LOAD_STATE_PACKAGED = "*PACKAGED";
/**
* Constant indicating that either the product load object has been damaged
* (if this option is something other than the base option or the load type
* is a language load), or the product definition for this product ID and
* release level has been damaged or the product load object has been damaged
* (if this option is for the base option and code load type).
**/
public static final String SYMBOLIC_LOAD_STATE_DAMAGED = "*DAMAGED";
/**
* Constant indicating that either a Restore Licensed Program (RSTLICPGM)
* function is in progress, a Delete Licensed Program (DLTLICPGM) function
* is in progress, or the product was created previous to V2R2M0 and there
* was an error during the process of converting product information.
**/
public static final String SYMBOLIC_LOAD_STATE_LOADED = "*LOADED";
/**
* Constant indicating that the product load object for this load was loaded
* on to the system by the Restore Licensed Program (RSTLICPGM) command.
**/
public static final String SYMBOLIC_LOAD_STATE_INSTALLED = "*INSTALLED";
/**
* Constructs a Product object. The following default values are used:
*
* - productOption - PRODUCT_OPTION_BASE
*
- releaseLevel - PRODUCT_RELEASE_ANY
*
- featureID - PRODUCT_FEATURE_CODE
*
* @param system The system.
* @param productID The product identifier.
**/
public Product(AS400 system, String productID)
{
this(system, productID, PRODUCT_OPTION_BASE, PRODUCT_RELEASE_ANY, PRODUCT_FEATURE_CODE);
}
/**
* Constructs a Product object. The following default values are used:
*
* - releaseLevel - PRODUCT_RELEASE_ANY
*
- featureID - PRODUCT_FEATURE_CODE
*
* @param system The system.
* @param productID The product identifier.
* @param productOption The product option.
**/
public Product(AS400 system, String productID, String productOption)
{
this(system, productID, productOption, PRODUCT_RELEASE_ANY, PRODUCT_FEATURE_CODE);
}
/**
* Constructs a Product object.
* @param system The system.
* @param productID The product identifier.
* @param productOption The product option.
* @param releaseLevel The release level of the product.
* @param featureID The product feature identifier.
**/
public Product(AS400 system, String productID, String productOption, String releaseLevel, String featureID)
{
if (system == null) throw new NullPointerException("system");
if (productID == null) throw new NullPointerException("productID");
if (productOption == null) throw new NullPointerException("productOption");
if (releaseLevel == null) throw new NullPointerException("releaseLevel");
if (featureID == null) throw new NullPointerException("featureID");
String id = productID.toUpperCase().trim();
if (id.length() != 7 && !id.equals(PRODUCT_ID_OPERATING_SYSTEM))
{
throw new ExtendedIllegalArgumentException("productID("+id+")", ExtendedIllegalArgumentException.LENGTH_NOT_VALID);
}
String option = productOption.toUpperCase().trim();
if (option.equals(PRODUCT_OPTION_BASE))
{
option = "0000";
}
if (option.length() > 4)
{
throw new ExtendedIllegalArgumentException(id+".productOption("+option+")", ExtendedIllegalArgumentException.LENGTH_NOT_VALID);
}
while (option.length() < 4)
{
option = "0"+option;
}
String level = releaseLevel.toUpperCase().trim();
if (level.length() != 6 && level.length() != 0 && !level.equals(PRODUCT_RELEASE_CURRENT) &&
!level.equals(PRODUCT_RELEASE_ONLY) && !level.equals(PRODUCT_RELEASE_PREVIOUS) &&
!level.equals(PRODUCT_RELEASE_ANY))
{
throw new ExtendedIllegalArgumentException("releaseLevel", ExtendedIllegalArgumentException.LENGTH_NOT_VALID);
}
String load = featureID.toUpperCase().trim();
if (load.length() != 4 && !load.equals(PRODUCT_FEATURE_CODE))
{
throw new ExtendedIllegalArgumentException("featureID", ExtendedIllegalArgumentException.LENGTH_NOT_VALID);
}
system_ = system;
productID_ = id;
productOption_ = option;
releaseLevel_ = level;
loadID_ = load;
}
/**
* Constructs a Product object. Sets featureID to PRODUCT_FEATURE_CODE.
* @param system The system.
* @param productID The product identifier.
* @param productOption The product option.
* @param releaseLevel The release level of the product.
* @param loadType The type of product load.
* @param languageID The language feature ID for the product.
**/
public Product(AS400 system, String productID, String productOption, String releaseLevel, String loadType, String languageID)
{
this(system, productID, productOption, releaseLevel, PRODUCT_FEATURE_CODE);
if (loadType == null) throw new NullPointerException("loadType");
if (languageID == null) throw new NullPointerException("languageID");
loadType_ = loadType;
primaryLanguageLoadID_ = languageID;
}
/**
* This constructor is used by the 0500 format.
**/
Product(AS400 system, String id, String option, String level, String feature, boolean allow, String msgID, String minVRM)
{
this(system, id, option, level, feature);
allowsDynamicNaming_ = allow;
descriptionID_ = msgID;
minimumVRM_ = minVRM;
loadedOptions_ = true;
}
/**
* This constructor is used by ProductList.
**/
Product(AS400 system, String id, String option, String level,
String descriptionID, String descriptionText,
String messageFile, boolean installed,
boolean supported, String regType, String regValue)
{
system_ = system;
productID_ = id;
if (option.equals(PRODUCT_OPTION_BASE))
{
option = "0000";
}
else if (option.length() > 4)
{
option = option.substring(1, 5); // Chop off the first 0.
}
productOption_ = option;
releaseLevel_ = level;
descriptionID_ = descriptionID;
descriptionText_ = descriptionText;
messageFile_ = messageFile;
installed_ = installed;
supported_ = supported;
registrationType_ = regType;
registrationValue_ = regValue;
partiallyLoaded_ = true;
}
/**
* Indicates if the names of product libraries and root folders
* for this product option can be dynamically changed without
* causing a product error.
* @return true if the product can by dynamically named, false if it cannot.
* @throws AS400Exception If an error occurs.
* @throws AS400SecurityException If a security or authority error occurs.
* @throws ErrorCompletingRequestException If an error occurs before the request is completed.
* @throws InterruptedException If this thread is interrupted.
* @throws IOException If an error occurs while communicating with the system.
* @throws ObjectDoesNotExistException If the object does not exist.
**/
public boolean allowsDynamicNaming()
throws AS400Exception,
AS400SecurityException,
ErrorCompletingRequestException,
InterruptedException,
IOException,
ObjectDoesNotExistException
{
if (!loadedOptions_) fillInOptionInformation();
return allowsDynamicNaming_;
}
/**
* Indicates if this product allows mixed releases between its *BASE
* and options.
* @return true if the *BASE option and other options of this product
* can be at different release levels, false if they must all be at
* the same release level.
* @throws AS400Exception If an error occurs.
* @throws AS400SecurityException If a security or authority error occurs.
* @throws ErrorCompletingRequestException If an error occurs before the request is completed.
* @throws InterruptedException If this thread is interrupted.
* @throws IOException If an error occurs while communicating with the system.
* @throws ObjectDoesNotExistException If the object does not exist.
**/
public boolean allowsMixedReleases()
throws AS400Exception,
AS400SecurityException,
ErrorCompletingRequestException,
InterruptedException,
IOException,
ObjectDoesNotExistException
{
if (!loaded500_) refresh(500);
return allowsMixedReleases_;
}
/**
* Indicates if this product can be installed at a release level different
* from the current release level without installing over a current release.
* @return true if the product can be installed at a different release level,
* false if it cannot be installed at a different release level without
* installing over the current release.
* @throws AS400Exception If an error occurs.
* @throws AS400SecurityException If a security or authority error occurs.
* @throws ErrorCompletingRequestException If an error occurs before the request is completed.
* @throws InterruptedException If this thread is interrupted.
* @throws IOException If an error occurs while communicating with the system.
* @throws ObjectDoesNotExistException If the object does not exist.
**/
public boolean allowsMultipleReleases()
throws AS400Exception,
AS400SecurityException,
ErrorCompletingRequestException,
InterruptedException,
IOException,
ObjectDoesNotExistException
{
if (!loaded500_) refresh(500);
return allowsMultipleReleases_;
}
/**
* Helper method.
**/
private void fillInOptionInformation()
throws AS400Exception,
AS400SecurityException,
ErrorCompletingRequestException,
InterruptedException,
IOException,
ObjectDoesNotExistException
{
Product[] products = getProductOptions();
for (int i=0; i
* {@link #LOAD_STATE_DEFINED_NO_OBJECT LOAD_STATE_DEFINED_NO_OBJECT}
* {@link #LOAD_STATE_DEFINED_OBJECT_EXISTS LOAD_STATE_DEFINED_OBJECT_EXISTS}
* {@link #LOAD_STATE_PACKAGED_RESTORE_FAILED_EXIT_PROGRAM_FAILED LOAD_STATE_PACKAGED_RESTORE_FAILED_EXIT_PROGRAM_FAILED}
* {@link #LOAD_STATE_PACKAGED_RESTORE_FAILED LOAD_STATE_PACKAGED_RESTORE_FAILED}
* {@link #LOAD_STATE_PACKAGED LOAD_STATE_PACKAGED}
* {@link #LOAD_STATE_PACKAGED_RENAMED LOAD_STATE_PACKAGED_RENAMED}
* {@link #LOAD_STATE_PACKAGED_DAMAGED LOAD_STATE_PACKAGED_DAMAGED}
* {@link #LOAD_STATE_PACKAGED_DELETED LOAD_STATE_PACKAGED_DELETED}
* {@link #LOAD_STATE_PACKAGED_RESTORE_IN_PROGRESS LOAD_STATE_PACKAGED_RESTORE_IN_PROGRESS}
* {@link #LOAD_STATE_PACKAGED_DELETE_IN_PROGRESS LOAD_STATE_PACKAGED_DELETE_IN_PROGRESS}
* {@link #LOAD_STATE_INSTALLED_RESTORE_IN_PROGRESS LOAD_STATE_INSTALLED_RESTORE_IN_PROGRESS}
* {@link #LOAD_STATE_INSTALLED_DELETE_IN_PROGRESS LOAD_STATE_INSTALLED_DELETE_IN_PROGRESS}
* {@link #LOAD_STATE_IBM_SUPPLIED_NOT_COMPATIBLE LOAD_STATE_IBM_SUPPLIED_NOT_COMPATIBLE}
* {@link #LOAD_STATE_INSTALLED_RESTORE_FAILED_EXIT_PROGRAM_FAILED LOAD_STATE_INSTALLED_RESTORE_FAILED_EXIT_PROGRAM_FAILED}
* {@link #LOAD_STATE_INSTALLED_RESTORE_FAILED LOAD_STATE_INSTALLED_RESTORE_FAILED}
* {@link #LOAD_STATE_RESTORED LOAD_STATE_RESTORED}
* {@link #LOAD_STATE_RESTORED_EXIT_PROGRAM_FAILED LOAD_STATE_RESTORED_EXIT_PROGRAM_FAILED}
* {@link #LOAD_STATE_RESTORED_RENAMED LOAD_STATE_RESTORED_RENAMED}
* {@link #LOAD_STATE_RESTORED_DAMAGED LOAD_STATE_RESTORED_DAMAGED}
* {@link #LOAD_STATE_RESTORED_DELETED LOAD_STATE_RESTORED_DELETED}
* {@link #LOAD_STATE_CHECK_ERROR LOAD_STATE_CHECK_ERROR}
* {@link #LOAD_STATE_INSTALLED LOAD_STATE_INSTALLED}
*
* @return The load state.
* @throws AS400Exception If an error occurs.
* @throws AS400SecurityException If a security or authority error occurs.
* @throws ErrorCompletingRequestException If an error occurs before the request is completed.
* @throws InterruptedException If this thread is interrupted.
* @throws IOException If an error occurs while communicating with the system.
* @throws ObjectDoesNotExistException If the object does not exist.
* @see #getSymbolicLoadState
**/
public String getLoadState()
throws AS400Exception,
AS400SecurityException,
ErrorCompletingRequestException,
InterruptedException,
IOException,
ObjectDoesNotExistException
{
if (!loaded_) refresh(100);
return loadState_;
}
/**
* Returns the type of product load for which information was retrieved.
* Possible values are:
*
* - {@link #LOAD_TYPE_CODE LOAD_TYPE_CODE}
*
- {@link #LOAD_TYPE_LANGUAGE LOAD_TYPE_LANGUAGE}
*
* @return The load type.
* @throws AS400Exception If an error occurs.
* @throws AS400SecurityException If a security or authority error occurs.
* @throws ErrorCompletingRequestException If an error occurs before the request is completed.
* @throws InterruptedException If this thread is interrupted.
* @throws IOException If an error occurs while communicating with the system.
* @throws ObjectDoesNotExistException If the object does not exist.
**/
public String getLoadType()
throws AS400Exception,
AS400SecurityException,
ErrorCompletingRequestException,
InterruptedException,
IOException,
ObjectDoesNotExistException
{
if (!loaded_) refresh(100);
return loadType_;
}
/**
* Returns the minimum release level that is allowed for the option
* that will run with the current level of the *BASE option for the product.
* This method is only applicable if mixed releases are allowed.
* Possible values are a release level (e.g. "V5R1M0") or "*MATCH"
* which indicates the release of the option matches that of *BASE.
* @return The minimum required release level of this product option.
* @throws AS400Exception If an error occurs.
* @throws AS400SecurityException If a security or authority error occurs.
* @throws ErrorCompletingRequestException If an error occurs before the request is completed.
* @throws InterruptedException If this thread is interrupted.
* @throws IOException If an error occurs while communicating with the system.
* @throws ObjectDoesNotExistException If the object does not exist.
* @see #allowsMixedReleases
* @see #getMinimumRequiredReleaseForBase
**/
public String getMinimumRequiredRelease()
throws AS400Exception,
AS400SecurityException,
ErrorCompletingRequestException,
InterruptedException,
IOException,
ObjectDoesNotExistException
{
if (!loadedOptions_) fillInOptionInformation();
return minimumVRM_;
}
/**
* Returns the minimum release level that is allowed for the *BASE option
* that will run with the current level of the option for the product. This
* method is only applicable if mixed releases are allowed and if the
* load type is *CODE. Possible values are a release level (e.g. "V5R1M0")
* or "*MATCH" which indicates the release of the option matches that
* of *BASE.
* @return The minimum required release level of the base product option.
* @throws AS400Exception If an error occurs.
* @throws AS400SecurityException If a security or authority error occurs.
* @throws ErrorCompletingRequestException If an error occurs before the request is completed.
* @throws InterruptedException If this thread is interrupted.
* @throws IOException If an error occurs while communicating with the system.
* @throws ObjectDoesNotExistException If the object does not exist.
* @see #allowsMixedReleases
* @see #getMinimumRequiredRelease
**/
public String getMinimumRequiredReleaseForBase()
throws AS400Exception,
AS400SecurityException,
ErrorCompletingRequestException,
InterruptedException,
IOException,
ObjectDoesNotExistException
{
if (!loaded_) refresh(100);
return minimumBaseVRM_;
}
/**
* Returns the minimum operating system release to which the Save Licensed Program
* (SAVLICPGM) command will allow the product to be saved.
* @return The minimum target release (e.g. "V5R1M0").
* @throws AS400Exception If an error occurs.
* @throws AS400SecurityException If a security or authority error occurs.
* @throws ErrorCompletingRequestException If an error occurs before the request is completed.
* @throws InterruptedException If this thread is interrupted.
* @throws IOException If an error occurs while communicating with the system.
* @throws ObjectDoesNotExistException If the object does not exist.
**/
public String getMinimumTargetRelease()
throws AS400Exception,
AS400SecurityException,
ErrorCompletingRequestException,
InterruptedException,
IOException,
ObjectDoesNotExistException
{
if (!loaded_) refresh(100);
return minimumTargetRelease_;
}
/**
* Returns the primary language feature ID for this product.
*
* For code loads, this is the primary language of the product option;
* that is, it is the National Language Version (NLV) of the language
* that is installed in the libraries. It is "" if no language is
* installed in the libraries for the code load.
*
* For language loads (e.g. "2938"), it is "".
* @return The primary language feature ID, or "" if no language is
* installed or this product is a language load.
* @throws AS400Exception If an error occurs.
* @throws AS400SecurityException If a security or authority error occurs.
* @throws ErrorCompletingRequestException If an error occurs before the request is completed.
* @throws InterruptedException If this thread is interrupted.
* @throws IOException If an error occurs while communicating with the system.
* @throws ObjectDoesNotExistException If the object does not exist.
* @see #getLoadType
**/
public String getPrimaryLanguageFeatureID()
throws AS400Exception,
AS400SecurityException,
ErrorCompletingRequestException,
InterruptedException,
IOException,
ObjectDoesNotExistException
{
if (!loaded_) refresh(100);
return primaryLanguageLoadID_;
}
/**
* Returns the product ID for this product.
* @return The product ID (e.g. "5722JC1").
**/
public String getProductID()
{
return productID_;
}
/**
* Returns the product option for this product.
* @return The product option (e.g. "*BASE" or "0012").
**/
public String getProductOption()
{
return productOption_;
}
/**
* Returns the list of product options for this product ID.
* @return The array of products.
* @throws AS400Exception If an error occurs.
* @throws AS400SecurityException If a security or authority error occurs.
* @throws ErrorCompletingRequestException If an error occurs before the request is completed.
* @throws InterruptedException If this thread is interrupted.
* @throws IOException If an error occurs while communicating with the system.
* @throws ObjectDoesNotExistException If the object does not exist.
**/
public Product[] getProductOptions()
throws AS400Exception,
AS400SecurityException,
ErrorCompletingRequestException,
InterruptedException,
IOException,
ObjectDoesNotExistException
{
if (!loaded500_) refresh(500);
return options_;
}
/**
* Returns the list of Program Temporary Fixes (PTFs) on
* the system for this product.
* @param includeSupersededPTFs Specify true to include any
* superseded PTFs in the list; false otherwise.
* @return The array of PTFs. If there are no PTFs for the
* product, this method returns an array of size 0.
* @throws AS400Exception If an error occurs.
* @throws AS400SecurityException If a security or authority error occurs.
* @throws ErrorCompletingRequestException If an error occurs before the request is completed.
* @throws InterruptedException If this thread is interrupted.
* @throws IOException If an error occurs while communicating with the system.
* @throws ObjectDoesNotExistException If the object does not exist.
**/
public PTF[] getPTFs(boolean includeSupersededPTFs)
throws AS400Exception,
AS400SecurityException,
ErrorCompletingRequestException,
InterruptedException,
IOException,
ObjectDoesNotExistException
{
if (!isInstalled()) return new PTF[0];
int ccsid = system_.getCcsid();
ConvTable conv = ConvTable.getTable(ccsid, null);
ProgramParameter[] parms = new ProgramParameter[4];
try
{
parms[0] = new ProgramParameter(conv.stringToByteArray(USERSPACE_NAME));
parms[0].setParameterType(ProgramParameter.PASS_BY_REFERENCE);
byte[] prodInfo = new byte[50];
AS400Text text4 = new AS400Text(4, ccsid, system_);
AS400Text text6 = new AS400Text(6, ccsid, system_);
AS400Text text7 = new AS400Text(7, ccsid, system_);
AS400Text text10 = new AS400Text(10, ccsid, system_);
text7.toBytes(productID_, prodInfo, 0);
text6.toBytes(getReleaseLevel(), prodInfo, 7);
text4.toBytes(productOption_, prodInfo, 13);
if (loadID_ == null) refresh(100);
text10.toBytes((loadID_.equals(PRODUCT_FEATURE_CODE) ? "*ALL" : loadID_), prodInfo, 17);
//text10.toBytes("*ALL", prodInfo, 17);
prodInfo[27] = includeSupersededPTFs ? (byte)0xF1 : (byte)0xF0; // '1' or '0'
parms[1] = new ProgramParameter(prodInfo);
parms[1].setParameterType(ProgramParameter.PASS_BY_REFERENCE);
parms[2] = new ProgramParameter(conv.stringToByteArray("PTFL0100"));
parms[2].setParameterType(ProgramParameter.PASS_BY_REFERENCE);
parms[3] = new ProgramParameter(new byte[4]); // error code
parms[3].setParameterType(ProgramParameter.PASS_BY_REFERENCE);
}
catch (PropertyVetoException pve) { // will never happen
if (Trace.traceOn_) Trace.log(Trace.ERROR, pve);
}
ServiceProgramCall pc = new ServiceProgramCall(system_,
"/QSYS.LIB/QPZLSTFX.SRVPGM",
"QpzListPTF",
ServiceProgramCall.NO_RETURN_VALUE,
parms);
// Note: The called API is not thread-safe.
// Determine the needed scope of synchronization.
Object lockObject;
boolean willRunProgramsOnThread = pc.isStayOnThread();
if (willRunProgramsOnThread) {
// The calls will run in the job of the JVM, so lock for entire JVM.
lockObject = USERSPACE_PATH;
}
else {
// The calls will run in the job of the Remote Command Host Server, so lock on the connection.
lockObject = system_;
}
byte[] buf = null;
synchronized(lockObject)
{
UserSpace us = new UserSpace(system_, "/QSYS.LIB/QTEMP.LIB/JT4PTF.USRSPC");
us.setMustUseProgramCall(true);
if (!willRunProgramsOnThread)
{
us.setMustUseSockets(true);
// Force the use of sockets when running natively but not on-thread.
// We have to do it this way since UserSpace will otherwise make a
// native ProgramCall, and will use a different QTEMP library than that used by the host server.
}
try
{
us.create(256*1024, true, "", (byte)0, "User space for PTF list", "*EXCLUDE");
if (!pc.run())
{
AS400Message[] messages = pc.getMessageList();
if (messages.length == 1 && (messages[0].getID().equalsIgnoreCase("CPF6601") || // No PTF activity exists
messages[0].getID().equalsIgnoreCase("CPF35BE"))) // Product not supported or installed
{
return new PTF[0];
}
throw new AS400Exception(pc.getMessageList());
}
int size = us.getLength();
buf = new byte[size];
us.read(buf, 0);
}
finally
{
// Delete the temporary user space, to allow other threads to re-create and use it.
try { us.delete(); }
catch (Exception e) {
Trace.log(Trace.ERROR, "Exception while deleting temporary user space", e);
}
}
}
int startingOffset = BinaryConverter.byteArrayToInt(buf, 124);
int numEntries = BinaryConverter.byteArrayToInt(buf, 132);
int entrySize = BinaryConverter.byteArrayToInt(buf, 136);
int entryCCSID = BinaryConverter.byteArrayToInt(buf, 140);
conv = ConvTable.getTable(entryCCSID, null);
int offset = 0;
PTF[] ptfs = new PTF[numEntries];
for (int i=0; i
* {@link #REGISTRATION_TYPE_PHONE REGISTRATION_TYPE_PHONE}
* {@link #REGISTRATION_TYPE_SYSTEM REGISTRATION_TYPE_SYSTEM}
* {@link #REGISTRATION_TYPE_CUSTOMER REGISTRATION_TYPE_CUSTOMER}
*
* @return The registration type.
* @throws AS400Exception If an error occurs.
* @throws AS400SecurityException If a security or authority error occurs.
* @throws ErrorCompletingRequestException If an error occurs before the request is completed.
* @throws InterruptedException If this thread is interrupted.
* @throws IOException If an error occurs while communicating with the system.
* @throws ObjectDoesNotExistException If the object does not exist.
* @see #getRegistrationValue
**/
public String getRegistrationType()
throws AS400Exception,
AS400SecurityException,
ErrorCompletingRequestException,
InterruptedException,
IOException,
ObjectDoesNotExistException
{
if (!loaded_ && !partiallyLoaded_) refresh(100);
return registrationType_;
}
/**
* Returns the registration value associated with this product. The
* registration type and registration value together make up the
* registration ID for the product.
* @return The registration value.
* @throws AS400Exception If an error occurs.
* @throws AS400SecurityException If a security or authority error occurs.
* @throws ErrorCompletingRequestException If an error occurs before the request is completed.
* @throws InterruptedException If this thread is interrupted.
* @throws IOException If an error occurs while communicating with the system.
* @throws ObjectDoesNotExistException If the object does not exist.
* @see #getRegistrationType
**/
public String getRegistrationValue()
throws AS400Exception,
AS400SecurityException,
ErrorCompletingRequestException,
InterruptedException,
IOException,
ObjectDoesNotExistException
{
if (!loaded_ && !partiallyLoaded_) refresh(100);
return registrationValue_;
}
/**
* Returns the value specified for the release date when the product
* definition for this product load was created. If no release date
* was specified for the product, then null is returned.
* @return The release date, or null if there is no release date.
* @throws AS400Exception If an error occurs.
* @throws AS400SecurityException If a security or authority error occurs.
* @throws ErrorCompletingRequestException If an error occurs before the request is completed.
* @throws InterruptedException If this thread is interrupted.
* @throws IOException If an error occurs while communicating with the system.
* @throws ObjectDoesNotExistException If the object does not exist.
**/
public Date getReleaseDate()
throws AS400Exception,
AS400SecurityException,
ErrorCompletingRequestException,
InterruptedException,
IOException,
ObjectDoesNotExistException
{
if (!loaded500_) refresh(500);
return releaseDate_;
}
/**
* Returns the release level for this product. For example: "V5R1M0".
* If any of the special values were specified when this object was constructed,
* the real release level will be retrieved from the system.
* @return The release level.
* @throws AS400Exception If an error occurs.
* @throws AS400SecurityException If a security or authority error occurs.
* @throws ErrorCompletingRequestException If an error occurs before the request is completed.
* @throws InterruptedException If this thread is interrupted.
* @throws IOException If an error occurs while communicating with the system.
* @throws ObjectDoesNotExistException If the object does not exist.
**/
public String getReleaseLevel()
throws AS400Exception,
AS400SecurityException,
ErrorCompletingRequestException,
InterruptedException,
IOException,
ObjectDoesNotExistException
{
if (releaseLevel_.equals(PRODUCT_RELEASE_CURRENT) || releaseLevel_.equals(PRODUCT_RELEASE_PREVIOUS) ||
releaseLevel_.equals(PRODUCT_RELEASE_ONLY) || releaseLevel_.equals(PRODUCT_RELEASE_ANY))
{
refresh(100);
}
return releaseLevel_;
}
/**
* Returns the reason why the release requirements between the base and
* option may or may not be in error. (When a product allows mixed releases
* between its base and option, certain requirements must be met). If the
* load type is LOAD_TYPE_LANGUAGE, then this method returns REQUIREMENTS_UNKNOWN.
* Possible values are:
*
* - {@link #REQUIREMENTS_UNKNOWN REQUIREMENTS_UNKNOWN}
*
- {@link #REQUIREMENTS_MET REQUIREMENTS_MET}
*
- {@link #REQUIREMENTS_OPTION_TOO_OLD REQUIREMENTS_OPTION_TOO_OLD}
*
- {@link #REQUIREMENTS_BASE_TOO_OLD REQUIREMENTS_BASE_TOO_OLD}
*
* @return The reason why requirements are met or not.
* @throws AS400Exception If an error occurs.
* @throws AS400SecurityException If a security or authority error occurs.
* @throws ErrorCompletingRequestException If an error occurs before the request is completed.
* @throws InterruptedException If this thread is interrupted.
* @throws IOException If an error occurs while communicating with the system.
* @throws ObjectDoesNotExistException If the object does not exist.
* @see #getLoadType
**/
public int getRequirementsMet()
throws AS400Exception,
AS400SecurityException,
ErrorCompletingRequestException,
InterruptedException,
IOException,
ObjectDoesNotExistException
{
if (!loaded_) refresh(100);
return requirementsMet_;
}
/**
* Returns the symbolic load state for which information was retrieved.
* This value, in conjunction with the load error, can be used to determine
* if the load is installed correctly. Possible values are:
*
* - {@link #SYMBOLIC_LOAD_STATE_DEFINED SYMBOLIC_LOAD_STATE_DEFINED}
*
- {@link #SYMBOLIC_LOAD_STATE_CREATED SYMBOLIC_LOAD_STATE_CREATED}
*
- {@link #SYMBOLIC_LOAD_STATE_PACKAGED SYMBOLIC_LOAD_STATE_PACKAGED}
*
- {@link #SYMBOLIC_LOAD_STATE_DAMAGED SYMBOLIC_LOAD_STATE_DAMAGED}
*
- {@link #SYMBOLIC_LOAD_STATE_LOADED SYMBOLIC_LOAD_STATE_LOADED}
*
- {@link #SYMBOLIC_LOAD_STATE_INSTALLED SYMBOLIC_LOAD_STATE_INSTALLED}
*
* @return The symbolic load state.
* @throws AS400Exception If an error occurs.
* @throws AS400SecurityException If a security or authority error occurs.
* @throws ErrorCompletingRequestException If an error occurs before the request is completed.
* @throws InterruptedException If this thread is interrupted.
* @throws IOException If an error occurs while communicating with the system.
* @throws ObjectDoesNotExistException If the object does not exist.
* @see #getLoadState
* @see #isLoadInError
**/
public String getSymbolicLoadState()
throws AS400Exception,
AS400SecurityException,
ErrorCompletingRequestException,
InterruptedException,
IOException,
ObjectDoesNotExistException
{
return getSymbolicLoadState(true); // normal error processing
}
/**
Utility method to enable retrieval of product load state without cluttering the job log with "Product information not found" messages.
@param logErrorsInJobLog Whether errors are to be logged and reported normally.
If false, errors are to be returned in the 'error code' parameter (and not logged in the job log).
**/
private String getSymbolicLoadState(boolean logErrorsInJobLog)
throws AS400Exception,
AS400SecurityException,
ErrorCompletingRequestException,
InterruptedException,
IOException,
ObjectDoesNotExistException
{
if (!loaded_) refresh(100, logErrorsInJobLog);
return symbolicLoadState_;
}
/**
* Returns the system.
* @return The system.
**/
public AS400 getSystem()
{
return system_;
}
/**
* Indicates whether or not this product is installed on the system.
* @return true if the product is installed, false if it is not.
* @throws AS400Exception If an error occurs.
* @throws AS400SecurityException If a security or authority error occurs.
* @throws ErrorCompletingRequestException If an error occurs before the request is completed.
* @throws InterruptedException If this thread is interrupted.
* @throws IOException If an error occurs while communicating with the system.
* @throws ObjectDoesNotExistException If the object does not exist.
**/
public boolean isInstalled()
throws AS400Exception,
AS400SecurityException,
ErrorCompletingRequestException,
InterruptedException,
IOException,
ObjectDoesNotExistException
{
if (partiallyLoaded_) return installed_;
try
{
// First arg says: Don't clutter the job log with CPF0C1F "Product information not found" message (if the product isn't installed).
return getSymbolicLoadState(false).equals(SYMBOLIC_LOAD_STATE_INSTALLED);
}
catch(AS400Exception e)
{
AS400Message[] messages = e.getAS400MessageList();
if (messages.length == 1 && messages[0].getID().equalsIgnoreCase("CPF0C1F")) // Product info not found
{
return false;
}
throw e;
}
}
/**
* Indicates if there is a known error for this product load. This does
* not mean that product is necessarily installed. Check the symbolic load
* state to determine if the product load is installed or not.
* @return true if an error was found the last time that the state of
* this load was checked or updated, false if no error was found.
* @throws AS400Exception If an error occurs.
* @throws AS400SecurityException If a security or authority error occurs.
* @throws ErrorCompletingRequestException If an error occurs before the request is completed.
* @throws InterruptedException If this thread is interrupted.
* @throws IOException If an error occurs while communicating with the system.
* @throws ObjectDoesNotExistException If the object does not exist.
* @see #getSymbolicLoadState
**/
public boolean isLoadInError()
throws AS400Exception,
AS400SecurityException,
ErrorCompletingRequestException,
InterruptedException,
IOException,
ObjectDoesNotExistException
{
if (!loaded_) refresh(100);
return loadErrorIndicator_;
}
/**
* Indicates whether this product feature is currently supported. A feature
* can be supported by using the Work with Supported Products (WRKSPTPRD)
* command in the System Manager.
* @return true if the feature is supported, false if it is not.
* @throws AS400Exception If an error occurs.
* @throws AS400SecurityException If a security or authority error occurs.
* @throws ErrorCompletingRequestException If an error occurs before the request is completed.
* @throws InterruptedException If this thread is interrupted.
* @throws IOException If an error occurs while communicating with the system.
* @throws ObjectDoesNotExistException If the object does not exist.
**/
public boolean isSupported()
throws AS400Exception,
AS400SecurityException,
ErrorCompletingRequestException,
InterruptedException,
IOException,
ObjectDoesNotExistException
{
if (!loaded_ && !partiallyLoaded_) refresh(100);
return supported_;
}
/**
* Refreshes the current values and settings for this Product by retrieving all of them from the system.
* The getter methods implicitly refresh the necessary value if the value being sought has not been retrieved yet.
* @return true if some or all of the values were successfully refreshed; false if the system found no information
* for this product.
* @throws AS400Exception If an error occurs.
* @throws AS400SecurityException If a security or authority error occurs.
* @throws ErrorCompletingRequestException If an error occurs before the request is completed.
* @throws InterruptedException If this thread is interrupted.
* @throws IOException If an error occurs while communicating with the system.
* @throws ObjectDoesNotExistException If the object does not exist.
**/
public boolean refresh()
throws AS400Exception,
AS400SecurityException,
ErrorCompletingRequestException,
InterruptedException,
IOException,
ObjectDoesNotExistException
{
loadedLoadID_ = false; // disregard any previously-loaded value
// If no previous error with formats 0500 or 0100, get the format 0500 values.
if (!error500_ && !error100_) refresh(500);
// If no previous error with formats 0800 or 0100, get the format 0800 values.
if (!error800_ && !error100_) refresh(800);
// If there were errors with formats 0500 and 0800, and no errors with format 0100, get the format 0100 values.
if (error500_ && error800_ && !error100_) refresh(100);
// If no previous error with format 0500, get description text.
if (!error500_)
{
loadedDescriptionText_ = false;
getDescriptionText();
}
fillInOptionInformation();
return !error100_;
}
/**
* Does the real work based on the format requested.
* Formats currently supported are 100, 500, and 800. Note that
* all formats are supersets of the 100 format.
**/
private void refresh(int whichFormat)
throws AS400Exception,
AS400SecurityException,
ErrorCompletingRequestException,
InterruptedException,
IOException,
ObjectDoesNotExistException
{
refresh(whichFormat, true);
}
/**
* Does the real work based on the format requested.
* Formats currently supported are 100, 500, and 800. Note that
* all formats are supersets of the 100 format.
* @param logErrorsInJobLog Whether errors are to be logged and reported normally.
* If false, errors are to be returned in the 'error code' parameter (and not logged in the job log).
**/
private void refresh(int whichFormat, boolean logErrorsInJobLog)
throws AS400Exception,
AS400SecurityException,
ErrorCompletingRequestException,
InterruptedException,
IOException,
ObjectDoesNotExistException
{
if (releaseLevel_.equals(PRODUCT_RELEASE_ANY))
{
// First try ONLY, then PREVIOUS, then CURRENT, since there will
// almost always be a product definition for CURRENT.
error100_ = false;
releaseLevel_ = PRODUCT_RELEASE_ONLY;
try
{
refresh(whichFormat);
return;
}
catch(AS400Exception x) {}
if (error100_)
{
error100_ = false;
releaseLevel_ = PRODUCT_RELEASE_PREVIOUS;
try
{
refresh(whichFormat);
return;
}
catch(AS400Exception x) {}
if (error100_)
{
error100_ = false;
releaseLevel_ = PRODUCT_RELEASE_CURRENT;
refresh(whichFormat);
return;
}
}
}
String format = null;
int len = 0;
switch(whichFormat)
{
case 100:
if (error100_) return; // No point in trying again.
format = "PRDR0100";
len = 108;
break;
case 500:
if (error500_) return; // No point in trying again.
format = "PRDR0500";
len = 108+49+chunkSize_; // Don't need all the info.
break;
case 800:
if (error800_) return; // No point in trying again.
format = "PRDR0800";
len = 108+17+chunkSize_; // In real life, len = 108+17 + (50+primaryPath+installPath+(10*numberOfObjectAuthorities)*numberOfEntries
break;
default:
format = "PRDR0100";
whichFormat = 100;
len = 108;
break;
}
int ccsid = system_.getCcsid();
ConvTable conv = ConvTable.getTable(ccsid, null);
ProgramParameter[] parms = new ProgramParameter[6];
parms[0] = new ProgramParameter(len); // receiver variable
parms[1] = new ProgramParameter(BinaryConverter.intToByteArray(len)); // length of receiver variable
parms[2] = new ProgramParameter(conv.stringToByteArray(format)); // format name
byte[] productInfo = new byte[36];
AS400Text text4 = new AS400Text(4, ccsid, system_);
AS400Text text6 = new AS400Text(6, ccsid, system_);
AS400Text text7 = new AS400Text(7, ccsid, system_);
AS400Text text10 = new AS400Text(10, ccsid, system_);
text7.toBytes(productID_, productInfo, 0);
text6.toBytes(releaseLevel_, productInfo, 7);
String option = productOption_;
if (option.equals(PRODUCT_OPTION_BASE) || whichFormat == 500) // PRDR0500 needs 0000
{
option = "0000";
}
text4.toBytes(option, productInfo, 13);
text10.toBytes((loadID_ == null || whichFormat == 500) ? PRODUCT_FEATURE_CODE : loadID_, productInfo, 17); // PRDR0500 needs *CODE
BinaryConverter.intToByteArray(36, productInfo, 28);
BinaryConverter.intToByteArray(ccsid, productInfo, 32);
parms[3] = new ProgramParameter(productInfo); // product information
// 'error code' parameter
if (logErrorsInJobLog) {
parms[4] = new ErrorCodeParameter(); // normal error processing
}
else {
parms[4] = new ErrorCodeParameter(true,false); // return any errors via the 'error code' parameter; don't clutter the job log
}
parms[5] = new ProgramParameter(conv.stringToByteArray("PRDI0200")); // product information format name
ProgramCall pc = new ProgramCall(system_, "/QSYS.LIB/QSZRTVPR.PGM", parms);
// Note: The called API is not thread-safe.
boolean pcSucceeded = pc.run();
AS400Message[] messages = null;
if (logErrorsInJobLog) // normal error processing
{
if (!pcSucceeded) {
messages = pc.getMessageList(); // get errors from message list
}
}
else
{
// If any errors occurred, they were returned in the 'error code' parm, rather than in the message list.
ErrorCodeParameter errParm = (ErrorCodeParameter)parms[4];
String msgID = errParm.getMessageID();
if (msgID != null)
{
pcSucceeded = false;
// Compose a message list, as if we had called the program with a normal 'error code' parm.
try
{
String substData = errParm.getSubstitutionData();
MessageFile mf = new MessageFile(system_, "/QSYS.LIB/QCPFMSG.MSGF");
AS400Message msg = mf.getMessage(msgID, substData);
messages = new AS400Message[1];
messages[0] = msg;
}
catch (Throwable t) {
Trace.log(Trace.ERROR, "Error when retrieving error messages.", t);
}
}
}
if (!pcSucceeded)
{
if (messages.length == 1 && messages[0].getID().equalsIgnoreCase("CPF0C1F"))
{
// It's OK, there just wasn't a product definition.
if (Trace.traceOn_)
{
Trace.log(Trace.DIAGNOSTIC, "No product definition found for "+toString()+" using format "+whichFormat+".");
}
installed_ = false;
if (whichFormat != 100)
{
refresh(100);
if (whichFormat == 500)
{
releaseDate_ = null;
firstCopyright_ = null;
currentCopyright_ = null;
options_ = new Product[0];
loaded500_ = true;
error500_ = true;
}
else if (whichFormat == 800)
{
directories_ = new ProductDirectoryInformation[0];
loaded500_ = true;
error800_ = true;
}
return;
}
else
{
// The 0500 format may work since it uses a different product option than what we are set to.
// But the 0100 or 0800 formats may still fail since we switch back to use the option we were given.
error100_ = true;
}
}
throw new AS400Exception(messages);
}
byte[] outputData = parms[0].getOutputData();
int bytesReturned = BinaryConverter.byteArrayToInt(outputData, 0);
int bytesAvailable = BinaryConverter.byteArrayToInt(outputData, 4);
if (bytesReturned < bytesAvailable)
{
chunkSize_ = bytesAvailable;
refresh(whichFormat);
return;
}
releaseLevel_ = conv.byteArrayToString(outputData, 19, 6);
if (whichFormat != 500) { // Since 0500 uses *CODE, we don't want to reset it.
loadID_ = conv.byteArrayToString(outputData, 29, 4);
loadedLoadID_ = true;
}
loadType_ = conv.byteArrayToString(outputData, 33, 10).trim();
symbolicLoadState_ = conv.byteArrayToString(outputData, 43, 10);
loadErrorIndicator_ = !conv.byteArrayToString(outputData, 53, 10).trim().equals("*NONE"); // *ERROR for error, *NONE for not.
loadState_ = conv.byteArrayToString(outputData, 63, 2);
supported_ = conv.byteArrayToString(outputData, 65, 1).equals("1");
registrationType_ = conv.byteArrayToString(outputData, 66, 2);
registrationValue_ = conv.byteArrayToString(outputData, 68, 14);
primaryLanguageLoadID_ = conv.byteArrayToString(outputData, 88, 4);
minimumTargetRelease_ = conv.byteArrayToString(outputData, 92, 6);
minimumBaseVRM_ = conv.byteArrayToString(outputData, 98, 6);
requirementsMet_ = (int)(outputData[104] & 0x000F); // 0xF0 = 0, 0xF1 = 1, etc...
level_ = conv.byteArrayToString(outputData, 105, 3);
loaded_ = true; // indicate that the above 0100 fields have been loaded
if (whichFormat == 500)
{
int offset = BinaryConverter.byteArrayToInt(outputData, 84);
allowsMultipleReleases_ = (outputData[offset++] == (byte)0xF1); // '1' is yes, '0' is no.
boolean y2k = (outputData[offset++] == (byte)0xF1); // '1' is 20xx; '0' is 19xx
String d = conv.byteArrayToString(outputData, offset, 6);
Date releaseDate = null;
if (d.trim().length() == 6)
{
Calendar cal = AS400Calendar.getGregorianInstance();
cal.clear();
cal.set(Integer.parseInt(d.substring(0,2)) + (y2k ? 2000 : 1900), // year
Integer.parseInt(d.substring(2,4))-1, // month is zero based
Integer.parseInt(d.substring(4,6))); // day
releaseDate = cal.getTime();
}
releaseDate_ = releaseDate;
offset += 6;
firstCopyright_ = conv.byteArrayToString(outputData, offset, 4);
offset += 4;
currentCopyright_ = conv.byteArrayToString(outputData, offset, 4).trim();
offset += 4;
String fileName = conv.byteArrayToString(outputData, offset, 10).trim();
offset += 10;
String fileLibrary = conv.byteArrayToString(outputData, offset, 10).trim();
offset += 10;
if (fileName.length() > 0)
{
messageFile_ = QSYSObjectPathName.toPath(fileLibrary, fileName, "MSGF");
}
else
{
messageFile_ = "";
}
int numOptions = BinaryConverter.byteArrayToInt(outputData, offset);
offset += 4;
int entryLength = BinaryConverter.byteArrayToInt(outputData, offset);
offset += 4;
int offsetToOptions = BinaryConverter.byteArrayToInt(outputData, offset);
offset += 4;
allowsMixedReleases_ = (outputData[offset] == (byte)0xF1); // '1' allows, '0' doesn't.
options_ = new Product[numOptions];
for (int i=0; i