src.com.ibm.as400.access.MemberDescription Maven / Gradle / Ivy
Show all versions of jt400-jdk8 Show documentation
///////////////////////////////////////////////////////////////////////////////
//
// JTOpen (IBM Toolbox for Java - OSS version)
//
// Filename: MemberDescription.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) 2009-2009 International Business Machines Corporation and
// others. All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
package com.ibm.as400.access;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* Represents a database file member and its attributes.
* MemberDescription objects can be constructed individually, or generated
* by {@link MemberList#getMemberDescriptions MemberList.getMemberDescriptions()}.
* A member's attributes can be retrieved by calling {@link #getValue getValue()}
* and passing one of the attribute identifier constants defined in this class.
*
* Note: String data is always stored and returned without trailing blanks.
*
* Performance hint:
* If you anticipate retrieving multiple attributes for a given member,
* first call {@link #refresh refresh()}, which will make a single API call
* to retrieve (and cache) all of the member's attribute values.
*
* Implementation note:
* This class internally calls the "Retrieve Member Description" (QUSRMBRD) API.
* Information from formats MBRD0100, MBRD0200, and MBRD0300 is retrieved.
*
*
* This class is mostly based on a prototype contributed by Mihael Schmidt.
*
* @see MemberList
* @see AS400File
* @see ObjectDescription
**/
public class MemberDescription
{
private static final SimpleDateFormat dateTimeFormat_ = new SimpleDateFormat("yyMMddHHmmss");
private static final SimpleDateFormat dateFormat_ = new SimpleDateFormat("yyMMdd");
private static final String QUSRMBRD_FORMAT_100 = "MBRD0100";
private static final String QUSRMBRD_FORMAT_200 = "MBRD0200";
private static final String QUSRMBRD_FORMAT_300 = "MBRD0300";
/** The name of the database file whose member names are placed in the list. Attribute type: java.lang.String.*/
public static final int FILE_NAME = 1;
/** The name of the library where the database file is located. Attribute type: java.lang.String. */
public static final int LIBRARY_NAME = 2;
/** The name of a member found in the database file. Attribute type: java.lang.String. */
public static final int MEMBER_NAME = 3;
/** The type of file found. Attribute type: java.lang.String. */
public static final int FILE_ATTRIBUTE = 4;
/** The type of source member if this is a source file. Attribute type: java.lang.String. */
public static final int SOURCE_TYPE = 5;
/** The date and time the member was created. Attribute type: java.util.Date.*/
public static final int CREATION_DATE_TIME = 6;
/**
* For source files, the date and time that this source member was last changed.
* For SQL materialized query tables, the date and time that the last SQL Refresh
* Table statement refreshed this member. Attribute type: java.util.Date (may be null).
*/
public static final int LAST_SOURCE_CHANGE_DATE = 7;
/** Description of the member found in the database file. Attribute type: java.lang.String. */
public static final int MEMBER_TEXT_DESCRIPTION = 8;
/** Whether the database file is a source file or a data file. Attribute type: java.lang.Boolean. */
public static final int SOURCE_FILE = 9;
/**
* Whether the database file is a remote file (true = remote file, false = local file).
* Attribute type: java.lang.Boolean.
*/
public static final int REMOTE_FILE = 10;
/**
* Whether the database file is a logical or physical file (true = logical file, false =
* physical file). Attribute type: java.lang.Boolean.
*/
public static final int LOGICAL_FILE = 11;
/**
* Whether the open data path (ODP) allows sharing with other programs in the same job
* (true = ODP sharing is allowed, false = ODP sharing is not allowed). Attribute type: java.lang.Boolean.
*/
public static final int ODP_SHARING = 12;
/**
* The number of records that currently exist in this member.
* A logical member returns the summarization of index entries.
* If the requested physical file member is suspended, the value 0 is returned.
* Attribute type: java.lang.Integer.
*/
public static final int CURRENT_NUMBER_OF_RECORDS = 13;
/**
* The size of the space that contains the data of the file member, in bytes.
* A logical file returns a 0. Attribute type: java.lang.Integer.
*/
public static final int DATA_SPACE_SIZE = 14;
/**
* The access path size in bytes for this file member. If the file member is not keyed,
* the value 0 is returned. DDM files, which are not from a System/38 or iSeries system,
* return value 0. Attribute type: java.lang.Integer.
*/
public static final int ACCESS_PATH_SIZE = 15;
/**
* The number of database file members for the logical file member. If the member is a physical
* file member, the value is 0. Attribute type: java.lang.Integer.
*/
public static final int NUMBER_OF_BASED_ON_PHYICAL_FILE_MEMBERS = 16;
/**
* The date and time this member was changed. The value contains null if the member was
* never changed. Attribute type: java.util.Date.
*/
public static final int CHANGE_DATE_AND_TIME = 17;
/**
* The date and time that this member was last saved. The value contains null if the member
* was never saved. Attribute type: java.util.Date.
*/
public static final int SAVE_DATE_AND_TIME = 18;
/**
* The date and time that the member was last restored. The value contains null if the member
* was never restored. Attribute type: java.util.Date.
*/
public static final int RESTORE_DATE_AND_TIME = 19;
/** The date that this member expires. Attribute type: java.util.Date. */
public static final int EXPIRATION_DATE = 20;
/**
* The number of days the member has been used. If the member does not have a last-used date,
* the value 0 is returned. Attribute type: java.lang.Integer.
*/
public static final int NUMBER_OF_DAYS_USED = 21;
/**
* The century and date this member was last used. The value contains null if the member was
* never used. Attribute type: java.util.Date.
*/
public static final int DATE_LAST_USED = 22;
/**
* The century and date when the days-used count was last set to 0. If the date is not available
* the value contains null. Attribute type: java.util.Date.
*/
public static final int USE_RESET_DATE = 23;
/**
* The value to multiply the data space size by to get its true size. Typically this is 1, but
* for large files, the value may be greater than 1. If the data space size multiplier is
* greater than 1, then the value in the data space size field is not the actual size of the file.
* Attribute type: java.lang.Integer.
*/
public static final int DATA_SPACE_SIZE_MULTIPLIER = 24;
/** The value to multiply the access path size by to get its true size. Attribute type: java.lang.Integer. */
public static final int ACCESS_PATH_SIZE_MULTIPLIER = 25;
/** The CCSID for the member text description. Attribute type: java.lang.Integer. */
public static final int MEMBER_TEXT_DESCRIPTION_CCSID = 26;
/**
* The number of deleted records returned in the file member. Keyed logical files return a 0.
* DDM files that are not from a System/38 or iSeries system return a 0. If the requested
* physical file member is suspended, the value 0 is returned. Attribute type: java.lang.Integer.
*/
public static final int NUMBER_OF_DELETED_RECORDS = 27;
/**
* Whether the member's logical file member combines (in one record format) fields from two or
* more physical file members (true = join member, false = not a join member).
* Attribute type: java.lang.Boolean.
*/
public static final int JOIN_MEMBER = 28;
/**
* Specifies, for files with key fields or join logical files, the type of access path
* maintenance used for all members of the physical or logical file. Attribute type: java.lang.String.
*/
public static final int ACCESS_PATH_MAINTENANCE = 29;
/**
* The kind of SQL file type the file is. If the file isn't an SQL file, blank is returned.
* Attribute type: java.lang.String.
*/
public static final int SQL_FILE_TYPE = 30;
/** Whether records in the physical file can be read. Values: Y/N. Attribute type: java.lang.Boolean. */
public static final int ALLOW_READ_OPERATION = 31;
/** Whether records can be written to the file. Values: Y/N. Attribute type: java.lang.Boolean. */
public static final int ALLOW_WRITE_OPERATION = 32;
/** Whether records in this file can be updated. Values: Y/N. Attribute type: java.lang.Boolean. */
public static final int ALLOW_UPDATE_OPERATION = 33;
/** Whether records in this file can be deleted. Values: Y/N. Attribute type: java.lang.Boolean. */
public static final int ALLOW_DELETE_OPERATION = 34;
/**
* The number of inserted, updated, or deleted records that are processed before the records are
* forced into auxiliary storage. A 0 indicates that records are not forced into auxiliary storage.
* Attribute type: java.lang.Integer.
*/
public static final int RECORDS_TO_FORCE_A_WRITE = 35;
/**
* The maximum allowed percentage of deleted records for each member in the physical file. The
* percentage check is made when the member is closed. If the percentage of deleted records is
* greater than the value shown, a message is sent to the history log. This field only applies
* to physical files and is 0 when either no deleted records are allowed or the file is a
* logical file. Attribute type: java.lang.Integer.
*/
public static final int MAXIMUM_PERCENT_DELETED_RECORDS_ALLOWED = 36;
/**
* The number of records that can be written to each member of the file before the member size is
* automatically extended. This field applies only to physical files and is 0 for logical files.
* Attribute type: java.lang.Integer.
*/
public static final int INITIAL_NUMBER_OF_RECORDS = 37;
/**
* The maximum number of records that are automatically added to the member when the number of
* records in the member is greater than the initial member size. This field applies only to
* physical files and is 0 for logical files. Attribute type: java.lang.Integer.
*/
public static final int INCREMENT_NUMBER_OF_RECORDS = 38;
/**
* The maximum number of increments automatically added to the member size. This field only
* applies to physical files and is 0 for a logical file. Attribute type: java.lang.Integer.
*/
public static final int MAXIMUM_NUMBER_OF_INCREMENTS = 39;
/**
* The number of increments that have been added to the member size (data space size). This
* field is 0 for logical files because the number of increments only applies to physical files.
* Attribute type: java.lang.Integer.
*/
public static final int CURRENT_NUMBER_OF_INCREMENTS = 40;
/**
* The actual number of records this member can contain. The value is calculated by multiplying
* the increment number of records by the maximum number of increments, and adding the initial
* number of records. This field only applies to a physical file and is 0 for a logical file.
* Attribute type: java.lang.Integer.
*/
public static final int RECORD_CAPACITY = 41;
/**
* The name of a record format selector program that is called when the logical file member
* contains more than one logical record format. Attribute type: java.lang.String.
*/
public static final int RECORD_FORMAT_SELECTOR_PROGRAM_NAME = 42;
/**
* The library in which the record format selector program resides. This field is blank for
* physical files. Attribute type: java.lang.String.
*/
public static final int RECORD_FORMAT_SELECTOR_LIBRARY_NAME = 43;
private AS400 system_;
private QSYSObjectPathName pathName_;
private HashMap attributes_ = new HashMap();
private final AS400Bin4 intConverter_ = new AS400Bin4();
/**
* Constructs an MemberDescription.
* @param system The system.
* @param path The fully-qualified integrated file system path to the database file member.
* Consider using {@link QSYSObjectPathName QSYSObjectPathName} to compose
* the fully-qualified path string,
* or using {@link #MemberDescription(AS400,QSYSObjectPathName) MemberDescription(AS400,QSYSObjectPathName)} instead.
**/
public MemberDescription(AS400 system, String path)
{
this(system, new QSYSObjectPathName(path));
}
/**
* Constructs a MemberDescription object.
* @param system The system.
* @param path The fully-qualified integrated file system path to the database file member.
* Consider using {@link QSYSObjectPathName QSYSObjectPathName} to compose the fully-qualified path string.
*/
public MemberDescription(AS400 system, QSYSObjectPathName path)
{
if (system == null) throw new NullPointerException("system");
if (path == null) throw new NullPointerException("path");
system_ = system;
pathName_ = path;
}
/**
* Constructs a MemberDescription object.
*
* @param system AS400 system object
* @param libraryName Library where the database file is located.
* @param objectName The name of the database file.
* @param memberName The name of the member within the database file.
*/
public MemberDescription(AS400 system, String libraryName, String objectName, String memberName)
{
this(system, new QSYSObjectPathName(libraryName, objectName, memberName, "MBR"));
}
/**
* Constructs a MemberDescription given the specified path to the member with some preloaded
* attributes.
*
* @param system The system.
* @param path The fully-qualified integrated file system path to the member.
* Consider using {@link QSYSObjectPathName QSYSObjectPathName} to compose the fully-qualified path string.
* @param attributes Map with preloaded attributes
*
* @see MemberList
*/
MemberDescription(AS400 system, QSYSObjectPathName path, Map attributes)
{
this(system, path);
attributes_.putAll(attributes);
}
/**
* Determine the format to use on the API call depending on the attribute.
*
* @param attribute Attribute key
* @return Format name to be used for the API call.
*/
private String lookupFormat(int attribute)
{
String format;
switch (attribute)
{
case FILE_NAME:
case LIBRARY_NAME:
case MEMBER_NAME:
case FILE_ATTRIBUTE:
case SOURCE_TYPE:
case CREATION_DATE_TIME:
case LAST_SOURCE_CHANGE_DATE:
case MEMBER_TEXT_DESCRIPTION:
case SOURCE_FILE:
format = QUSRMBRD_FORMAT_100;
break;
case REMOTE_FILE:
case LOGICAL_FILE:
case ODP_SHARING:
case CURRENT_NUMBER_OF_RECORDS:
case DATA_SPACE_SIZE:
case ACCESS_PATH_SIZE:
case NUMBER_OF_BASED_ON_PHYICAL_FILE_MEMBERS:
case CHANGE_DATE_AND_TIME:
case SAVE_DATE_AND_TIME:
case RESTORE_DATE_AND_TIME:
case EXPIRATION_DATE:
case NUMBER_OF_DAYS_USED:
case DATE_LAST_USED:
case USE_RESET_DATE:
case DATA_SPACE_SIZE_MULTIPLIER:
case ACCESS_PATH_SIZE_MULTIPLIER:
case MEMBER_TEXT_DESCRIPTION_CCSID:
case NUMBER_OF_DELETED_RECORDS:
format = QUSRMBRD_FORMAT_200;
break;
case JOIN_MEMBER:
case ACCESS_PATH_MAINTENANCE:
case SQL_FILE_TYPE:
case ALLOW_READ_OPERATION:
case ALLOW_WRITE_OPERATION:
case ALLOW_UPDATE_OPERATION:
case ALLOW_DELETE_OPERATION:
case RECORDS_TO_FORCE_A_WRITE:
case MAXIMUM_PERCENT_DELETED_RECORDS_ALLOWED:
case INITIAL_NUMBER_OF_RECORDS:
case INCREMENT_NUMBER_OF_RECORDS:
case MAXIMUM_NUMBER_OF_INCREMENTS:
case CURRENT_NUMBER_OF_INCREMENTS:
case RECORD_CAPACITY:
case RECORD_FORMAT_SELECTOR_PROGRAM_NAME:
case RECORD_FORMAT_SELECTOR_LIBRARY_NAME:
format = QUSRMBRD_FORMAT_300;
break;
default:
if (Trace.traceOn_) Trace.log(Trace.WARNING, "Unrecognized attribute key:", attribute);
format = QUSRMBRD_FORMAT_100;
}
return format;
}
/**
* Returns the requested member attribute information object. If the value is not in the cache
* it will be retrieved from the system.
*
* @param attribute Attribute to be retrieved (either from cache or from system)
*
* @return Requested member attribute
*
* @throws ObjectDoesNotExistException If a system object necessary for the call does not exist on the system.
* @throws InterruptedException If this thread is interrupted.
* @throws IOException If an error occurs while communicating with the system.
* @throws ErrorCompletingRequestException If an error occurs before the request is completed.
* @throws AS400SecurityException If a security or authority error occurs.
* @throws AS400Exception If the program on the server sends an escape message.
*/
public Object getValue(int attribute)
throws AS400Exception, AS400SecurityException, ErrorCompletingRequestException,
IOException, InterruptedException, ObjectDoesNotExistException
{
final Integer key = new Integer(attribute);
Object value = null;
value = attributes_.get(key);
// If the value has not yet been retrieved from the server, the value object is still null.
// Retrieve it from the server and set the value object at last.
if (value == null)
{
value = retrieve(attribute);
// add value to the cache
attributes_.put(key, value);
}
return value;
}
/**
* Retrieves (and caches) all attributes of this member from the system.
*
* @throws ObjectDoesNotExistException If a system object necessary for the call does not exist on the system.
* @throws InterruptedException If this thread is interrupted.
* @throws IOException If an error occurs while communicating with the system.
* @throws ErrorCompletingRequestException If an error occurs before the request is completed.
* @throws AS400SecurityException If a security or authority error occurs.
* @throws AS400Exception If the program on the server sends an escape message.
**/
public void refresh() throws AS400Exception, AS400SecurityException, ErrorCompletingRequestException, InterruptedException, IOException, ObjectDoesNotExistException
{
retrieve(RECORD_FORMAT_SELECTOR_LIBRARY_NAME);
}
/**
* Sets the attribute of the member. Any previous information of the same attribute will be
* replaced.
*
* @param attribute Attribute key (Integer)
* @param value member information object to be set
*/
void setAttribute(int attribute, Object value)
{
attributes_.put(new Integer(attribute), value);
}
/**
* This method makes the actual call to the server and gets the information about the member.
* All other member information which belong to the same format are also retrieved.
*
* @param attribute Attribute to be retrieved and returned
*
* @return The value of the attribute
*
* @throws ObjectDoesNotExistException If a system object necessary for the call does not exist on the system.
* @throws InterruptedException If this thread is interrupted.
* @throws IOException If an error occurs while communicating with the system.
* @throws ErrorCompletingRequestException If an error occurs before the request is completed.
* @throws AS400SecurityException If a security or authority error occurs.
* @throws AS400Exception If the program on the server sends an escape message.
*/
private Object retrieve(int attribute)
throws AS400Exception, AS400SecurityException, ErrorCompletingRequestException,
IOException, InterruptedException, ObjectDoesNotExistException
{
final String format = lookupFormat(attribute);
ProgramParameter[] parameters = buildProgramParameters(format);
ProgramCall program = new ProgramCall(system_, "/QSYS.LIB/QUSRMBRD.PGM", parameters); // this API is not threadsafe
if (program.run())
{
readMemberInfo(parameters[0].getOutputData(), format);
return attributes_.get(new Integer(attribute));
}
else
{
throw new AS400Exception(program.getMessageList());
}
}
/**
* Builds the program parameter list for a program call to QUSRMBRD (Retrieve Member Description).
*
* @return Program parameter list for QUSRMBRD
*/
private ProgramParameter[] buildProgramParameters(String format)
throws UnsupportedEncodingException
{
Converter charConverter = new Converter(system_.getCcsid(), system_);
ProgramParameter[] parameterList = new ProgramParameter[7];
// Receiver variable:
parameterList[0] = new ProgramParameter(332);
// Length of receiver variable:
parameterList[1] = new ProgramParameter(intConverter_.toBytes(332));
// Format name:
parameterList[2] = new ProgramParameter(charConverter.stringToByteArray(format));
// Qualified database file name:
parameterList[3] = new ProgramParameter(charConverter.stringToByteArray(pathName_.toQualifiedObjectName()));
// Database member name:
String memberName = pathName_.getMemberName();
if (memberName.length() == 0)
{
memberName = "*FIRST";
if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Defaulting to member *FIRST", pathName_.getPath());
}
parameterList[4] = new ProgramParameter(new AS400Text(10,system_.getCcsid()).toBytes(memberName)); //@AF9C
// Override processing: (1 == "overrides are processed")
parameterList[5] = new ProgramParameter(charConverter.stringToByteArray("1"));
// Error code:
parameterList[6] = new ErrorCodeParameter();
return parameterList;
}
// Returns the offset of the specified field, in the MBRD* structures.
private static final int offsetOf(int attribute)
{
switch (attribute)
{
// Fields in format MBRD0100:
case FILE_NAME: return 8;
case LIBRARY_NAME: return 18;
case MEMBER_NAME: return 28;
case FILE_ATTRIBUTE: return 38;
case SOURCE_TYPE: return 48;
case CREATION_DATE_TIME: return 58;
case LAST_SOURCE_CHANGE_DATE: return 71;
case MEMBER_TEXT_DESCRIPTION: return 84;
case SOURCE_FILE: return 134;
// Additional fields in format MBRD0200:
case REMOTE_FILE: return 135;
case LOGICAL_FILE: return 136;
case ODP_SHARING: return 137;
case CURRENT_NUMBER_OF_RECORDS: return 140;
// offset 144: number of deleted records
case DATA_SPACE_SIZE: return 148;
case ACCESS_PATH_SIZE: return 152;
case NUMBER_OF_BASED_ON_PHYICAL_FILE_MEMBERS: return 156;
case CHANGE_DATE_AND_TIME: return 160;
case SAVE_DATE_AND_TIME: return 173;
case RESTORE_DATE_AND_TIME: return 186;
case EXPIRATION_DATE: return 199;
// offset 206: reserved
case NUMBER_OF_DAYS_USED: return 212;
case DATE_LAST_USED: return 216;
case USE_RESET_DATE : return 223;
// offset 230: reserved
case DATA_SPACE_SIZE_MULTIPLIER: return 232;
case ACCESS_PATH_SIZE_MULTIPLIER: return 236;
case MEMBER_TEXT_DESCRIPTION_CCSID: return 240;
case NUMBER_OF_DELETED_RECORDS: return 256;
// Additional fields in format MBRD0300:
case JOIN_MEMBER: return 266;
case ACCESS_PATH_MAINTENANCE: return 267;
case SQL_FILE_TYPE: return 268;
// offset 278: reserved
case ALLOW_READ_OPERATION: return 279;
case ALLOW_WRITE_OPERATION: return 280;
case ALLOW_UPDATE_OPERATION: return 281;
case ALLOW_DELETE_OPERATION: return 282;
// offset 283: reserved
case RECORDS_TO_FORCE_A_WRITE: return 284;
case MAXIMUM_PERCENT_DELETED_RECORDS_ALLOWED: return 288;
case INITIAL_NUMBER_OF_RECORDS: return 292;
case INCREMENT_NUMBER_OF_RECORDS: return 296;
case MAXIMUM_NUMBER_OF_INCREMENTS: return 300;
case CURRENT_NUMBER_OF_INCREMENTS: return 304;
case RECORD_CAPACITY: return 308;
case RECORD_FORMAT_SELECTOR_PROGRAM_NAME: return 312;
case RECORD_FORMAT_SELECTOR_LIBRARY_NAME: return 322;
default:
Trace.log(Trace.ERROR, "Unrecognized attribute key:", attribute);
throw new InternalErrorException(InternalErrorException.UNKNOWN, attribute);
}
}
/**
* Reads all available information from the output (receiver) bytes regardless of the attribute to
* be retrieved. The attribute to be retrieved determines in which content and format the data is sent.
*
* @param entryBytes Raw bytes of the entry
* @param format Content and format name
*
* @throws UnsupportedEncodingException If the ccsid is not supported.
*/
private void readMemberInfo(byte[] entryBytes, String format)
throws UnsupportedEncodingException
{
final CharConverter charConverter = new CharConverter(system_.getCcsid(), system_);
// Fields returned in all formats:
setAttribute(FILE_NAME,
charConverter.byteArrayToString(entryBytes, offsetOf(FILE_NAME), 10).trim());
setAttribute(LIBRARY_NAME,
charConverter.byteArrayToString(entryBytes, offsetOf(LIBRARY_NAME), 10).trim());
setAttribute(FILE_ATTRIBUTE,
charConverter.byteArrayToString(entryBytes, offsetOf(FILE_ATTRIBUTE), 10).trim());
setAttribute(MEMBER_NAME,
charConverter.byteArrayToString(entryBytes, offsetOf(MEMBER_NAME), 10).trim());
setAttribute(SOURCE_TYPE,
charConverter.byteArrayToString(entryBytes, offsetOf(SOURCE_TYPE), 10).trim());
setAttribute(MEMBER_TEXT_DESCRIPTION,
charConverter.byteArrayToString(entryBytes, offsetOf(MEMBER_TEXT_DESCRIPTION), 50).trim());
setAttribute(LAST_SOURCE_CHANGE_DATE, // Note: This field can contain hex zeros.
transformDate(charConverter.byteArrayToString(entryBytes, offsetOf(LAST_SOURCE_CHANGE_DATE), 13)));
setAttribute(CREATION_DATE_TIME,
transformDate(charConverter.byteArrayToString(entryBytes, offsetOf(CREATION_DATE_TIME), 13)));
setAttribute(SOURCE_FILE,
transformBoolean(charConverter.byteArrayToString(entryBytes, offsetOf(SOURCE_FILE), 1)));
// Fields returned in both formats 200 and 300:
if (format != QUSRMBRD_FORMAT_100)
{
setAttribute(REMOTE_FILE,
transformBoolean(charConverter.byteArrayToString(entryBytes, offsetOf(REMOTE_FILE), 1)));
setAttribute(LOGICAL_FILE,
transformBoolean(charConverter.byteArrayToString(entryBytes, offsetOf(LOGICAL_FILE), 1)));
setAttribute(CURRENT_NUMBER_OF_RECORDS,
new Integer(intConverter_.toInt(entryBytes, offsetOf(CURRENT_NUMBER_OF_RECORDS))));
setAttribute(ODP_SHARING,
transformBoolean(charConverter.byteArrayToString(entryBytes, offsetOf(ODP_SHARING), 1)));
setAttribute(DATA_SPACE_SIZE,
new Integer(intConverter_.toInt(entryBytes, offsetOf(DATA_SPACE_SIZE))));
setAttribute(ACCESS_PATH_SIZE,
new Integer(intConverter_.toInt(entryBytes, offsetOf(ACCESS_PATH_SIZE))));
setAttribute(NUMBER_OF_BASED_ON_PHYICAL_FILE_MEMBERS,
new Integer(intConverter_.toInt(entryBytes, offsetOf(NUMBER_OF_BASED_ON_PHYICAL_FILE_MEMBERS))));
setAttribute(CHANGE_DATE_AND_TIME,
transformDate(charConverter.byteArrayToString(entryBytes, offsetOf(CHANGE_DATE_AND_TIME), 13)));
setAttribute(RESTORE_DATE_AND_TIME,
transformDate(charConverter.byteArrayToString(entryBytes, offsetOf(RESTORE_DATE_AND_TIME), 13)));
setAttribute(SAVE_DATE_AND_TIME,
transformDate(charConverter.byteArrayToString(entryBytes, offsetOf(SAVE_DATE_AND_TIME), 13)));
setAttribute(EXPIRATION_DATE,
transformDate(charConverter.byteArrayToString(entryBytes, offsetOf(EXPIRATION_DATE), 13)));
setAttribute(NUMBER_OF_DAYS_USED,
new Integer(intConverter_.toInt(entryBytes, offsetOf(NUMBER_OF_DAYS_USED))));
setAttribute(DATE_LAST_USED,
transformDate(charConverter.byteArrayToString(entryBytes, offsetOf(DATE_LAST_USED), 13)));
setAttribute(USE_RESET_DATE,
transformDate(charConverter.byteArrayToString(entryBytes, offsetOf(USE_RESET_DATE), 13)));
setAttribute(DATA_SPACE_SIZE_MULTIPLIER,
new Integer(intConverter_.toInt(entryBytes, offsetOf(DATA_SPACE_SIZE_MULTIPLIER))));
setAttribute(ACCESS_PATH_SIZE_MULTIPLIER,
new Integer(intConverter_.toInt(entryBytes, offsetOf(ACCESS_PATH_SIZE_MULTIPLIER))));
setAttribute(MEMBER_TEXT_DESCRIPTION_CCSID,
new Integer(intConverter_.toInt(entryBytes, offsetOf(MEMBER_TEXT_DESCRIPTION_CCSID))));
setAttribute(NUMBER_OF_DELETED_RECORDS,
new Integer(intConverter_.toInt(entryBytes, offsetOf(NUMBER_OF_DELETED_RECORDS))));
}
// Fields returned only in format 300:
if (QUSRMBRD_FORMAT_300.equals(format))
{
setAttribute(JOIN_MEMBER,
transformBoolean(charConverter.byteArrayToString(entryBytes, offsetOf(JOIN_MEMBER), 1)));
setAttribute(ACCESS_PATH_MAINTENANCE,
charConverter.byteArrayToString(entryBytes, offsetOf(ACCESS_PATH_MAINTENANCE), 1));
setAttribute(SQL_FILE_TYPE,
charConverter.byteArrayToString(entryBytes, offsetOf(SQL_FILE_TYPE), 10).trim());
setAttribute(ALLOW_READ_OPERATION,
transformBoolean(charConverter.byteArrayToString(entryBytes, offsetOf(ALLOW_READ_OPERATION), 1)));
setAttribute(ALLOW_WRITE_OPERATION,
transformBoolean(charConverter.byteArrayToString(entryBytes, offsetOf(ALLOW_WRITE_OPERATION), 1)));
setAttribute(ALLOW_UPDATE_OPERATION,
transformBoolean(charConverter.byteArrayToString(entryBytes, offsetOf(ALLOW_UPDATE_OPERATION), 1)));
setAttribute(ALLOW_DELETE_OPERATION,
transformBoolean(charConverter.byteArrayToString(entryBytes, offsetOf(ALLOW_DELETE_OPERATION), 1)));
setAttribute(RECORDS_TO_FORCE_A_WRITE,
new Integer(intConverter_.toInt(entryBytes, offsetOf(RECORDS_TO_FORCE_A_WRITE))));
setAttribute(MAXIMUM_PERCENT_DELETED_RECORDS_ALLOWED,
new Integer(intConverter_.toInt(entryBytes, offsetOf(MAXIMUM_PERCENT_DELETED_RECORDS_ALLOWED))));
setAttribute(INITIAL_NUMBER_OF_RECORDS,
new Integer(intConverter_.toInt(entryBytes, offsetOf(INITIAL_NUMBER_OF_RECORDS))));
setAttribute(INCREMENT_NUMBER_OF_RECORDS,
new Integer(intConverter_.toInt(entryBytes, offsetOf(INCREMENT_NUMBER_OF_RECORDS))));
setAttribute(MAXIMUM_NUMBER_OF_INCREMENTS,
new Integer(intConverter_.toInt(entryBytes, offsetOf(MAXIMUM_NUMBER_OF_INCREMENTS))));
setAttribute(CURRENT_NUMBER_OF_INCREMENTS,
new Integer(intConverter_.toInt(entryBytes, offsetOf(CURRENT_NUMBER_OF_INCREMENTS))));
setAttribute(RECORD_CAPACITY,
new Integer(intConverter_.toInt(entryBytes, offsetOf(RECORD_CAPACITY))));
setAttribute(RECORD_FORMAT_SELECTOR_PROGRAM_NAME,
charConverter.byteArrayToString(entryBytes, offsetOf(RECORD_FORMAT_SELECTOR_PROGRAM_NAME), 10).trim());
setAttribute(RECORD_FORMAT_SELECTOR_LIBRARY_NAME,
charConverter.byteArrayToString(entryBytes, offsetOf(RECORD_FORMAT_SELECTOR_LIBRARY_NAME), 10).trim());
}
}
/**
* Parses the date string which should be in the format CYYMMDDHHMMSS or CYYMMDD;
*
* @param dateString Date string
*
* @return Date object representing the passed date string or null if the
* date string is null, empty or not parseable.
*/
private Date transformDate(String dateString)
{
Date retVal = null;
if (dateString == null)
{
// nothing => returns null
}
else
{
dateString = dateString.trim();
if (dateString.length() == 0)
{
// nothing => returns null
}
else
{
try
{
if (dateString.length() == 13)
{
synchronized(dateTimeFormat_)
{
retVal = dateTimeFormat_.parse(dateString.substring(1)); // skip the century digit
}
}
else if (dateString.length() == 7)
{
synchronized(dateFormat_)
{
retVal = dateFormat_.parse(dateString.substring(1)); // skip the century digit
}
}
else
{
if (Trace.traceOn_) Trace.log(Trace.WARNING, "Date string has unrecognized format:", dateString);
}
}
catch(ParseException pe) { // return null
if (Trace.traceOn_) Trace.log(Trace.ERROR, "Ignored error while parsing date string: " + dateString, pe);
}
}
}
return retVal;
}
/**
* Transforms the value of 1 to true and everything else to false.
*
* @param value
* @return Boolean object representing 1 as true and everything else as false
*/
private Boolean transformBoolean(String value)
{
// Assume that the caller has verified that the argument is non-null.
if (value.equals("1")) {
return Boolean.TRUE;
}
else {
return Boolean.FALSE;
}
}
/**
* Returns the IFS path of this member.
*
* @return IFS path to this member.
*/
public String getPath()
{
return pathName_.getPath();
}
}