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

com.ibm.as400.data.RecordFormatDocument Maven / Gradle / Ivy

The newest version!
///////////////////////////////////////////////////////////////////////////////
//                                                                             
// JTOpen (IBM Toolbox for Java - OSS version)                                 
//                                                                             
// Filename: RecordFormatDocument.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-2003 International Business Machines Corporation and     
// others. All rights reserved.                                                
//                                                                             
///////////////////////////////////////////////////////////////////////////////

package com.ibm.as400.data;

import com.ibm.as400.access.*;
import com.ibm.as400.access.Record;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.io.StreamCorruptedException;
import java.io.UnsupportedEncodingException;

import java.lang.reflect.Method;

import java.util.Enumeration;
import java.util.Vector;
import java.util.MissingResourceException;

/**
 * Supports the use of Record Format Markup Language
 * (RFML) to specify formats and data values for file records and data buffers.
 * RFML is an XML language similar to PCML (Program Call Markup Language).
 *
 * RecordFormatDocument parses an RFML document and allows the application to
 * set and get values of specific fields within a record.
 *
 * The command line interface may be used to serialize
 * RFML document definitions.
 * 
 * java com.ibm.as400.data.RecordFormatDocument
 *     -serialize
 *     RFML document name
 * 
* Options: *
*
-serialize *
Parses the RFML document and creates a serialized version of the document. * The name of the serialized file will match the document name, and the file extension will be * .rfml.ser (lowercase). *
rfml document name *
The fully-qualified resource name of the RFML document * which defines the record format(s). *
* *

Serialized RFML files *
To increase run-time performance, you can use a serialized RFML file. * A serialized RFML file contains serialized Java objects representing the RFML. * The objects that are serialized are the same objects that are created when you * construct the RecordFormatDocument object from a RFML source file. * Using serialized RFML files gives you better performance because the IBM * XML parser is not needed at run-time to interpret and validate the RFML tags. * *

For usage examples, refer to the PCML section of the Toolbox Programmer's * Guide. The behavior of RecordFormatDocument matches that of * {@link com.ibm.as400.data.ProgramCallDocument ProgramCallDocument} * for methods that have the same name, such as setIntValue() and getIntValue(). * *

Note: This class requires Java 2 (v1.2.2) or later. * **/ public class RecordFormatDocument implements Serializable, Cloneable { static final long serialVersionUID = 5L; // @A6C static final String RFML_VERSION = "4.0"; // NOTE: This needs to match the current value for the "version" attribute for the tag. @A1a private RfmlDocument m_rfmlDoc_; /** Constructs a RecordFormatDocument.

Prior to using an object constructed with this method, either {@link #setDocument(String) setDocument} or {@link #setValues(String,com.ibm.as400.access.Record) setValues} must be called. */ public RecordFormatDocument() {} /** Constructs a RecordFormatDocument. The RFML document resource will be loaded from the classpath. The classpath will first be searched for a serialized resource. If a serialized resource is not found, the classpath will be searched for an RFML source file. @param documentName The document resource name of the RFML document for the record formats to be referenced. All RFML-related file extensions are assumed to be lowercase (for example, .rfml or .rfml.ser). The resource name can be a package qualified name. For example, "com.myCompany.myPackage.myRfml" @exception XmlException when the specified RFML document cannot be found. */ public RecordFormatDocument(String documentName) throws XmlException { if (documentName == null) throw new NullPointerException("documentName"); m_rfmlDoc_ = loadRfmlDocument(documentName, null); } /** Constructs a RecordFormatDocument. The RFML document resource will be loaded from the classpath of the specified ClassLoader. The classpath will first be searched for a serialized resource. If a serialized resource is not found, the classpath will be searched for an RFML source file. @param documentName The document resource name of the RFML document for the record formats to be referenced. All RFML-related file extensions are assumed to be lowercase (for example, .rfml or .rfml.ser). The resource name can be a package qualified name. For example, "com.myCompany.myPackage.myRfml" @param loader The ClassLoader that will be used when loading the specified document resource. @exception XmlException when the specified RFML document cannot be found. */ public RecordFormatDocument(String documentName, ClassLoader loader) throws XmlException { if (documentName == null) throw new NullPointerException("documentName"); if (loader == null) throw new NullPointerException("loader"); m_rfmlDoc_ = loadRfmlDocument(documentName, loader); } /** Constructs a RecordFormatDocument from a Record object.
Note: The following Record datatypes are not supported by this method:

  • {@link com.ibm.as400.access.AS400Structure AS400Structure}
  • {@link com.ibm.as400.access.AS400Array AS400Array} with elements of type AS400Array (multidimensional array)
@param record The Record object. * @throws XmlException */ public RecordFormatDocument(Record record) throws XmlException { if (record == null) throw new NullPointerException("record"); RecordFormat recordFormat = record.getRecordFormat(); if (recordFormat == null) { throw new XmlException(DAMRI.RECORD_NOT_INITIALIZED); } setRecordFormat(recordFormat); setValues(recordFormat.getName(), record); } /** Constructs a RecordFormatDocument from a RecordFormat object.
Note: The following Record datatypes are not supported by this method:
  • {@link com.ibm.as400.access.AS400Structure AS400Structure}
  • {@link com.ibm.as400.access.AS400Array AS400Array} with elements of type AS400Array (multidimensional array)
@param recordFormat The RecordFormat object. * @throws XmlException */ public RecordFormatDocument(RecordFormat recordFormat) throws XmlException { if (recordFormat == null) throw new NullPointerException("recordFormat"); setRecordFormat(recordFormat); } /** Adds the specified attribute to the attribute list. **/ private static void addAttribute(PcmlAttributeList attrList, String attrName, String attrValue) { PcmlAttribute attr = new PcmlAttribute(attrName, attrValue, true); attrList.addAttribute(attr); } /** Creates and returns a copy of this object. @return A copy of this object. **/ public Object clone() { RecordFormatDocument newRfml = null; try { newRfml = (RecordFormatDocument) super.clone(); if (m_rfmlDoc_ != null) newRfml.m_rfmlDoc_ = (RfmlDocument) m_rfmlDoc_.clone(); } catch (CloneNotSupportedException e) { Trace.log(Trace.DIAGNOSTIC, e); } return newRfml; } /** Returns an attribute list containing values derived from the FieldDescription. If the DataType of the FieldDescription is AS400Structure or a multidimensional AS400Array, throws an XmlException. **/ private static PcmlAttributeList generateAttributeList(FieldDescription fieldDesc, boolean isKeyField, Vector priorFieldNames, String recordFormatName) throws XmlException { // Determine what kind of field description it is, and map it to the appropriate RFML element. AS400DataType dataType = fieldDesc.getDataType(); PcmlAttributeList attrList = new PcmlAttributeList(1); int count = 1; // Note: Classes that implement interface AS400DataType: // AS400Array, AS400Bin2, AS400Bin4, AS400Bin8, AS400ByteArray, AS400Date, AS400Time, AS400Timestamp, AS400Float4, AS400Float8, AS400PackedDecimal, AS400Structure, AS400Text, AS400UnsignedBin2, AS400UnsignedBin4, AS400UnsignedBin8, AS400ZonedDecimal. int dtType = dataType.getInstanceType(); if (dtType == AS400DataType.TYPE_ARRAY) { // Set the 'count' attribute. count = ((AS400Array)dataType).getNumberOfElements(); if (count < 0) { Trace.log(Trace.DIAGNOSTIC, "AS400Array count is not set ("+count+")"); count = 1; } addAttribute(attrList, "count", Integer.toString(count)); // Set the data type to the contained type, so we can then set the attributes appropriately. dataType = ((AS400Array)dataType).getType(); dtType = dataType.getInstanceType(); if (dataType.getInstanceType() == AS400DataType.TYPE_ARRAY) { // We don't yet support AS400Array-within-AS400Array. throw new XmlException(DAMRI.MULTI_ARRAY_NOT_SUPPORTED); } } // if (dataType instanceof AS400Structure) { if (dtType == AS400DataType.TYPE_STRUCTURE) { // Note: This type is left for a future enhancement. throw new XmlException(DAMRI.DATATYPE_NOT_SUPPORTED, new String[] {"AS400Structure"} ); } // Set the 'name' attribute. String fieldName = fieldDesc.getFieldName(); if (priorFieldNames.contains(fieldName)) { // @A1a throw new XmlException(DAMRI.DUPLICATE_FIELD_NAME, new String[] {recordFormatName, fieldName} ); } if (fieldName != null && fieldName.length() != 0) { addAttribute(attrList, "name", fieldName); priorFieldNames.add(fieldName); // Remember that this name is already used. } // Set the 'length' attribute. // Note: At this point we know we don't have an AS400Structure. All RFML datatypes except "struct" require the 'length' attribute. if (dtType == AS400DataType.TYPE_BIN2 || dtType == AS400DataType.TYPE_UBIN2 || dtType == AS400DataType.TYPE_BIN4 || dtType == AS400DataType.TYPE_UBIN4 || dtType == AS400DataType.TYPE_BIN8 || dtType == AS400DataType.TYPE_UBIN8 || dtType == AS400DataType.TYPE_FLOAT4 || dtType == AS400DataType.TYPE_FLOAT8 || dtType == AS400DataType.TYPE_PACKED) { // The numeric field types have architected lengths. We will set the length in the switch() statement below. } else { int fieldLength; if (count == 0) fieldLength = fieldDesc.getLength(); else fieldLength = fieldDesc.getLength() / count; addAttribute(attrList, "length", Integer.toString(fieldLength)); } // If the field description has a default value, set the 'init' attribute. Object defaultValue = fieldDesc.getDFT(); if (defaultValue == null) defaultValue = fieldDesc.getDFTCurrentValue(); if (defaultValue != null) { if (defaultValue instanceof byte[] && ((byte[])defaultValue).length != 0) { // Note: In PCML (and RFML), if the 'init' attribute specifies a single-byte numeric value, that value is replicated into each byte in the byte-array. byte[] dftBytes = (byte[])defaultValue; if (isSameByteRepeated(dftBytes)) { String byte0 = Byte.toString(dftBytes[0]); addAttribute(attrList, "init", byte0); } else { // Construct a String that lists out each separate byte value, e.g. "7 8 9 10". StringBuffer valList = new StringBuffer(); for (int i=0; i 0) { addAttribute(attrList, "ccsid", Integer.toString(ccsid)); } } else { Method method = fieldDesc.getClass().getMethod("getCCSID", (java.lang.Class[]) null); //@pdc cast for jdk1.5 String ccsids = (String)method.invoke(fieldDesc, (java.lang.Object[]) null); //@pdc cast for jdk1.5 if (ccsids != null && ccsids.length() != 0) { addAttribute(attrList, "ccsid", ccsids); } } } catch (Exception e) { // This is OK, since not all FieldDescriptions that have type==AS400Text have ccsid's. Trace.log(Trace.DIAGNOSTIC, e); } break; case AS400DataType.TYPE_ZONED: addAttribute(attrList, "type", "zoned"); // $A2 int precision = ((ZonedDecimalFieldDescription)fieldDesc).getDecimalPositions(); int precisionZ = ((AS400ZonedDecimal) dataType).getNumberOfDecimalPositions(); // $A2 addAttribute(attrList, "precision", Integer.toString(precisionZ)); break; case AS400DataType.TYPE_DATE: addAttribute(attrList, "type", "date"); addAttribute(attrList, "length",Integer.toString(fieldDesc.getLength())); String dateFormat = ((DateFieldDescription)dataType).getDATFMT(); addAttribute(attrList, "dateformat", dateFormat); String dateSeparator = ((DateFieldDescription)dataType).getDATSEP(); addAttribute(attrList, "dateseparator", dateSeparator); break; case AS400DataType.TYPE_TIME: addAttribute(attrList, "type", "time"); addAttribute(attrList, "length",Integer.toString(fieldDesc.getLength())); String timeFormat = ((TimeFieldDescription)dataType).getTIMFMT(); addAttribute(attrList, "timeformat", timeFormat); String timeSeparator = ((TimeFieldDescription)dataType).getTIMSEP(); addAttribute(attrList, "timeseparator", timeSeparator); break; case AS400DataType.TYPE_TIMESTAMP: addAttribute(attrList, "type", "timestamp"); addAttribute(attrList, "length",Integer.toString(fieldDesc.getLength())); break; default: // None of the above. Trace.log(Trace.ERROR, "Unrecognized data type: dtType=="+dtType); throw new InternalErrorException(InternalErrorException.UNKNOWN); } // If the field is a "key field", set the keyfield attribute. if (isKeyField) { addAttribute(attrList, "keyfield", "true"); } return attrList; } /** Returns a Descriptor for the specified RFML document. The RFML document resource will be loaded from the classpath. The classpath will first be searched for a serialized resource. If a serialized resource is not found, the classpath will be searched for an RFML source file. @param documentName The document resource name of the RFML document for which the Descriptor is returned. The resource name can be a package qualified name. For example, "com.myCompany.myPackage.myRfml" @return A descriptor for the <rfml> element of the named RFML file. @exception XmlException when the specified RFML document cannot be found. **/ public static Descriptor getDescriptor(String documentName) // @A7c throws XmlException { if (documentName == null) throw new NullPointerException("documentName"); RfmlDocument pd = null; pd = loadRfmlDocument(documentName, null); return new RfmlDescriptor(pd); } /** Returns a Descriptor representing the specified RFML document. The RFML document resource will be loaded from the classpath. The classpath will first be searched for a serialized resource. If a serialized resource is not found, the classpath will be searched for an RFML source file. @param documentName The document resource name of the RFML document for which the Descriptor is returned. The resource name can be a package qualified name. For example, "com.myCompany.myPackage.myRfml" @param loader The ClassLoader that will be used when loading the specified document resource. @return A descriptor for the <rfml> element of the named RFML file. @exception XmlException when the specified RFML document cannot be found. **/ public static Descriptor getDescriptor(String documentName, ClassLoader loader) // @A7c throws XmlException { if (documentName == null) throw new NullPointerException("documentName"); if (loader == null) throw new NullPointerException("loader"); RfmlDocument pd = null; pd = loadRfmlDocument(documentName, loader); return new RfmlDescriptor(pd); } /** Returns a Descriptor representing the current RFML document. @return A descriptor for the <rfml> element of the current RFML file, or null if the RFML document has not be set. **/ public Descriptor getDescriptor() // @A7c { if (m_rfmlDoc_ != null) return new RfmlDescriptor(m_rfmlDoc_); else return null; } /** Returns a Descriptor representing the current RFML document. @return The Descriptor for the element of the current RFML file, or null if the RFML document has not be set. **/ String getDocName() { if (m_rfmlDoc_ == null) return null; else return m_rfmlDoc_.getDocName(); } /** Returns a double value for the named element. @return The integer value for the named element. @param name The name of the <data> element in the PCML document. @exception XmlException If an error occurs while processing RFML. **/ public double getDoubleValue(String name) throws XmlException { // Note: The getDoubleValue() methods require Java2 or later, since they use Double.parseDouble(). if (name == null) throw new NullPointerException("name"); if (m_rfmlDoc_ == null) { throw new XmlException(DAMRI.DOCUMENT_NOT_SET ); } return m_rfmlDoc_.getDoubleValue(name); } /** Returns a double value for the named element given indices to the data element. If the data element is an array or is an element in a structure array, an index must be specified for each dimension of the data. @return The integer value for the named element. @param name The name of the <data> element in the PCML document. @param indices An array of indices for accessing the value of an element in an array. @exception XmlException If an error occurs while processing RFML. **/ public double getDoubleValue(String name, int[] indices) throws XmlException { if (name == null) throw new NullPointerException("name"); if (indices == null) throw new NullPointerException("indices"); if (m_rfmlDoc_ == null) { throw new XmlException(DAMRI.DOCUMENT_NOT_SET ); } return m_rfmlDoc_.getDoubleValue(name, new PcmlDimensions(indices)); } /** Returns an int value for the named element. @return The integer value for the named element. @param name The name of the <data> element in the PCML document. @exception XmlException If an error occurs while processing RFML. **/ public int getIntValue(String name) throws XmlException { if (name == null) throw new NullPointerException("name"); if (m_rfmlDoc_ == null) { throw new XmlException(DAMRI.DOCUMENT_NOT_SET ); } return m_rfmlDoc_.getIntValue(name); } /** Returns an int value for the named element given indices to the data element. If the data element is an array or is an element in a structure array, an index must be specified for each dimension of the data. @return The integer value for the named element. @param name The name of the <data> element in the PCML document. @param indices An array of indices for accessing the value of an element in an array. @exception XmlException If an error occurs while processing RFML. **/ public int getIntValue(String name, int[] indices) throws XmlException { if (name == null) throw new NullPointerException("name"); if (indices == null) throw new NullPointerException("indices"); if (m_rfmlDoc_ == null) { throw new XmlException(DAMRI.DOCUMENT_NOT_SET ); } return m_rfmlDoc_.getIntValue(name, new PcmlDimensions(indices)); } /** Returns a String value for the named <data type="char"> element. The default bidi string type is assumed ({@link com.ibm.as400.access.BidiStringType#DEFAULT BidiStringType.DEFAULT}). @param name The name of the <data> element in the RFML document. * @return StringValue @exception XmlException If an error occurs while processing RFML. **/ public String getStringValue(String name) throws XmlException { return getStringValue(name, BidiStringType.DEFAULT); } /** Returns a String value for the named <data type="char"> element.

This method should be used when the string type cannot be determined until run-time. In those cases, the RFML document cannot be used to indicate the string type so this method can be used to get the value using the string type that is specified. @param name The name of the <data> element in the RFML document. @param type The bidi string type, as defined by the CDRA (Character Data Representation Architecture). * @return stringValue @exception XmlException If an error occurs while processing RFML. **/ public String getStringValue(String name, int type) throws XmlException { if (name == null) throw new NullPointerException("name"); if (m_rfmlDoc_ == null) { throw new XmlException(DAMRI.DOCUMENT_NOT_SET ); } return m_rfmlDoc_.getStringValue(name, type); } /** Returns a String value for the named <data type="char"> element, given indices to the data element. If the data element is an array or is an element in a structure array, an index must be specified for each dimension of the data.

This method should be used when the string type cannot be determined until run-time. In those cases, the RFML document cannot be used to indicate the string type so this method can be used to get the value using the string type that is specified. @param name The name of the <data> element in the RFML document. @param indices An array of indices for setting the value of an element in an array. @param type The bidi string type, as defined by the CDRA (Character Data Representation Architecture). * @return stringValue @exception XmlException If an error occurs while processing RFML. **/ public String getStringValue(String name, int[] indices, int type) throws XmlException { if (name == null) throw new NullPointerException("name"); if (indices == null) throw new NullPointerException("indices"); if (m_rfmlDoc_ == null) { throw new XmlException(DAMRI.DOCUMENT_NOT_SET ); } return m_rfmlDoc_.getStringValue(name, new PcmlDimensions(indices), type); } /** Returns the Java object value for the named element.

The type of object returned depends on the description in the RFML document.

RFML DescriptionObject Returned
type=charString
type=bytebyte[]
type=int
length=2
precision=15
Short
type=int
length=2
precision=16
Integer
type=int
length=4
precision=31
Integer
type=int
length=4
precision=32
Long
type=int
length=8
precision=63
Long
type=int
length=8
precision=64
Double
type=packedBigDecimal
type=zonedBigDecimal
type=float
length=4
Float
type=float
length=8
Double
type=structnull
@return The Java object value for the named <data> element in the RFML document. @param name The name of the <data> element in the RFML document. @exception XmlException If an error occurs while processing RFML. **/ public Object getValue(String name) throws XmlException { if (name == null) throw new NullPointerException("name"); if (m_rfmlDoc_ == null) { throw new XmlException(DAMRI.DOCUMENT_NOT_SET ); } return m_rfmlDoc_.getValue(name); } /** Returns the Java object value for the named element given indices to the data element. If the data element is an array or is an element in a structure array, an index must be specified for each dimension of the data.

The type of object returned depends on the description in the RFML document. @return The Java object value for the named <data> element in the RFML document. @param name The name of the <data> element in the RFML document. @param indices An array of indices for accessing the value of an element in an array. @exception XmlException If an error occurs while processing RFML. **/ public Object getValue(String name, int[] indices) throws XmlException { if (name == null) throw new NullPointerException("name"); if (indices == null) throw new NullPointerException("indices"); if (m_rfmlDoc_ == null) { throw new XmlException(DAMRI.DOCUMENT_NOT_SET ); } return m_rfmlDoc_.getValue(name, new PcmlDimensions(indices)); } /** Determines whether the specified byte array consists of the same byte repeated. For example, returns true for {1,1,1,1}, and returns false for {1,2,3,4}. **/ private static boolean isSameByteRepeated(byte[] bytes) { // Assume that the array is non-null and length is non-zero. for (int i=1; i The named element must be able to be set using a Integer object. @param name The name of the <data> element in the RFML document. @param value The int value for the named element. @exception XmlException If an error occurs while processing RFML. **/ public void setIntValue(String name, int value) throws XmlException { setValue(name, Integer.valueOf(value)); } /** Sets the Java object value for the named element using an int input value given indices to the data element.

The named element must be able to be set using a Integer object. @param name The name of the <data> element in the RFML document. @param indices An array of indices for setting the value of an element in an array. @param value The int value for the named element. @exception XmlException If an error occurs while processing RFML. **/ public void setIntValue(String name, int[] indices, int value) throws XmlException { setValue(name, indices, Integer.valueOf(value)); } /** Sets the document format. */ private void setRecordFormat(RecordFormat recordFormat) throws XmlException { // Assume the caller has validated the argument. String fmtName = recordFormat.getName(); if (fmtName == null || fmtName.length() == 0) { Trace.log(Trace.ERROR, "RecordFormat name is null or zero-length."); throw new XmlException(DAMRI.RECORDFORMAT_NOT_INITIALIZED); } setRecordFormat(fmtName, recordFormat); } /** Sets the document format. */ private void setRecordFormat(String formatName, RecordFormat recordFormat) throws XmlException { // Assume the caller has validated the arguments. // Set up the document node. // Get document name and attributes (version and ccsid). Note that the RecordFormat class has no CCSID attribute. PcmlAttributeList attrList = new PcmlAttributeList(1); addAttribute(attrList, "version", RFML_VERSION); // @A1c m_rfmlDoc_ = new RfmlDocument(attrList, recordFormat.getName()); // Set up a recordformat node. attrList = new PcmlAttributeList(1); addAttribute(attrList, "name", formatName); RfmlRecordFormat recFormatNode = new RfmlRecordFormat(attrList); m_rfmlDoc_.addChild(recFormatNode); // Examine the field descriptions in the RecordFormat. FieldDescription[] descriptions = recordFormat.getFieldDescriptions(); FieldDescription[] keyFieldDescriptions = recordFormat.getKeyFieldDescriptions(); Vector priorFieldNames = new Vector(); // Detect any duplicate names. // @A1a for (int i=0; i<data> element in the RFML document. @param value The string value for the named element. @exception XmlException If an error occurs while processing RFML. **/ public void setStringValue(String name, String value) throws XmlException { setStringValue(name, value, BidiStringType.DEFAULT); } /** Sets the Java object value for the named <data type="char"> element using a String input.

This method should be used when the string type cannot be determined until run-time. In those cases, the RFML document cannot be used to indicate the string type so this method can be used to set the value and the string type of the input value. @param name The name of the <data> element in the RFML document. @param value The string value for the named element. @param type The bidi string type, as defined by the CDRA (Character Data Representation Architecture). @exception XmlException If an error occurs while processing RFML. @see com.ibm.as400.access.BidiStringType **/ public void setStringValue(String name, String value, int type) throws XmlException { if (name == null) throw new NullPointerException("name"); if (value == null) throw new NullPointerException("value"); if (m_rfmlDoc_ == null) { throw new XmlException(DAMRI.DOCUMENT_NOT_SET ); } m_rfmlDoc_.setStringValue(name, value, type); } /** Sets the Java object value for the named <data type="char"> element using a String input value, given indices to the data element.

This method should be used when the string type cannot be determined until run-time. In those cases, the RFML document cannot be used to indicate the string type so this method can be used to set the value and the string type of the input value. @param name The name of the <data> element in the RFML document. @param indices An array of indices for setting the value of an element in an array. @param value The string value for the named element. @param type The bidi string type, as defined by the CDRA (Character Data Representation Architecture). @exception XmlException If an error occurs while processing RFML. **/ public void setStringValue(String name, int[] indices, String value, int type) throws XmlException { if (name == null) throw new NullPointerException("name"); if (indices == null) throw new NullPointerException("indices"); if (value == null) throw new NullPointerException("value"); if (m_rfmlDoc_ == null) { throw new XmlException(DAMRI.DOCUMENT_NOT_SET ); } m_rfmlDoc_.setStringValue(name, value, new PcmlDimensions(indices), type); } /** Sets the RFML document resource. The RFML document resource will be loaded from the classpath. The classpath will first be searched for a serialized resource. If a serialized resource is not found, the classpath will be searched for an RFML source file. @param documentName The document resource name of the RFML document for the record formats to be referenced. All RFML-related file extensions are assumed to be lowercase (for example, .rfml or .rfml.ser). The resource name can be a package qualified name. For example, "com.myCompany.myPackage.myRfml" @exception XmlException when the specified RFML document cannot be found. **/ public void setDocument(String documentName) throws XmlException { if (documentName == null) throw new NullPointerException("documentName"); if (m_rfmlDoc_ != null) throw new XmlException(DAMRI.DOCUMENT_ALREADY_SET ); m_rfmlDoc_ = loadRfmlDocument(documentName, null); } /** Sets the RFML document resource. The RFML document resource will be loaded from the classpath. The classpath will first be searched for a serialized resource. If a serialized resource is not found, the classpath will be searched for an RFML source file. @param documentName The document resource name of the RFML document for the record formats to be referenced. All RFML-related file extensions are assumed to be lowercase (for example, .rfml or .rfml.ser). The resource name can be a package qualified name. For example, "com.myCompany.myPackage.myRfml" @param loader The ClassLoader that will be used when loading the specified document resource. @exception XmlException when the specified RFML document cannot be found. **/ public void setDocument(String documentName, ClassLoader loader) throws XmlException { if (documentName == null) throw new NullPointerException("documentName"); if (loader == null) throw new NullPointerException("loader"); if (m_rfmlDoc_ != null) throw new XmlException(DAMRI.DOCUMENT_ALREADY_SET ); m_rfmlDoc_ = loadRfmlDocument(documentName, loader); } /** Sets the Java object value for the named element.

If the input value provided is not an instance of the correct Java class for the defined data type, it will be converted to the correct Java class. For example, if an element is defined as "type=int length=2 precision=15", it will automatically be converted to a Java Short object, if the value specified is an instance of Number or String. @param name The name of the <data> element in the RFML document. @param value The Java object value for the named element. The type of Object passed must be the correct type for the element definition or a String that can be converted to the correct type. Null values are not allowed. @exception XmlException If an error occurs while processing RFML. **/ public void setValue(String name, Object value) throws XmlException { if (name == null) throw new NullPointerException("name"); if (value == null) throw new NullPointerException("value"); if (m_rfmlDoc_ == null) { throw new XmlException(DAMRI.DOCUMENT_NOT_SET ); } m_rfmlDoc_.setValue(name, value); } /** Sets the Java object value for the named element given indices to the data element. If the data element is an array or is an element in a structure array, an index must be specified for each dimension of the data.

If the input value provided is not an instance of the correct Java class for the defined data type, it will be converted to the correct Java class. For example, if an element is defined as "type=int length=2 precision=15", it will automatically be converted to a Java Short object, if the value specified is an instance of Number or String. @param name The name of the <data> element in the RFML document. @param indices An array of indices for setting the value of an element in an array. @param value The Java object value for the named element. The type of Object passed must be the correct type for the element definition or a String that can be converted to the correct type. Null values are not allowed. @exception XmlException If an error occurs while processing RFML. **/ public void setValue(String name, int[] indices, Object value) throws XmlException { if (name == null) throw new NullPointerException("name"); if (indices == null) throw new NullPointerException("indices"); if (value == null) throw new NullPointerException("value"); if (m_rfmlDoc_ == null) { throw new XmlException(DAMRI.DOCUMENT_NOT_SET ); } m_rfmlDoc_.setValue(name, value, new PcmlDimensions(indices)); } /** Sets the Java object values for the specified <recordformat> element, based on the values stored in the record object passed into the method.
For any given field, if the input value provided is not an instance of the correct Java class for the defined data type, it will be converted to the correct Java class. For example, if an element is defined as "type=int length=2 precision=15", it will automatically be converted to a Java Short object, if the value specified is an instance of Number or String. If any field in the Record is null-valued, a warning is issued.
Note: The following Record datatypes are not supported by this method:

  • {@link com.ibm.as400.access.AS400Structure AS400Structure}
  • {@link com.ibm.as400.access.AS400Array AS400Array} with elements of type AS400Array (multidimensional array)
@param formatName The name of the <recordformat> element in the RFML document. @param record The record object containing the data. @exception XmlException If an error occurs while processing RFML, or if an encoding specified by the Record is unsupported. **/ public void setValues(String formatName, Record record) throws XmlException { if (formatName == null) throw new NullPointerException("formatName"); if (record == null) throw new NullPointerException("record"); if (m_rfmlDoc_ == null) { RecordFormat recFmt = record.getRecordFormat(); if (recFmt != null) setRecordFormat(formatName, recFmt); else { Trace.log(Trace.ERROR, "The Record has a null RecordFormat."); throw new XmlException(DAMRI.RECORD_NOT_INITIALIZED); } } // Get the node for the specified recordformat element. RfmlRecordFormat recFormatNode = m_rfmlDoc_.getRecordFormatNode(formatName); // Set the value of each <data> tag to the corresponding field value in the record. try { recFormatNode.setValues(record); } catch (UnsupportedEncodingException e) { throw new XmlException(e); } } /** Sets the data represented by the specified <recordformat> element. @param formatName The name of the <recordformat> element in the RFML document. @param values The byte values for all the fields in the the named element. The length of the byte array must exactly match the length of data required, otherwise an XmlException is thrown. @exception XmlException If an error occurs while processing RFML. **/ public void setValues(String formatName, byte[] values) throws XmlException { if (formatName == null) throw new NullPointerException("formatName"); if (values == null) throw new NullPointerException("values"); if (m_rfmlDoc_ == null) { throw new XmlException(DAMRI.DOCUMENT_NOT_SET ); } // Get the node for the specified recordformat element. RfmlRecordFormat recFormatNode = m_rfmlDoc_.getRecordFormatNode(formatName); // Feed the bytes to the node. int bytesConsumed = recFormatNode.parseBytes(values); if (bytesConsumed < values.length) { throw new XmlException(DAMRI.EXCESS_INPUT_DATA, new Object[] {Integer.toString(bytesConsumed), Integer.toString(values.length), "", m_rfmlDoc_.getNameForException()} ); } } /** Returns the data contained by the specified <recordformat> element, as a byte array. @return The data contained by the record. @param formatName The name of the <recordformat> element in the RFML document. * @throws XmlException **/ public byte[] toByteArray(String formatName) throws XmlException { if (formatName == null) throw new NullPointerException("formatName"); if (m_rfmlDoc_ == null) { throw new XmlException(DAMRI.DOCUMENT_NOT_SET ); } // Get the node for the specified recordformat element. RfmlRecordFormat recFormatNode = m_rfmlDoc_.getRecordFormatNode(formatName); // Generate bytes. return recFormatNode.toBytes(); } /** Returns a Record object with the same structure and data as the specified <recordformat> element. Before this method is called, all <data> elements must either have their values set, or have 'init' values.
Note: When the Record is created, the 'count' attribute of <data> elements is disregarded. @return A Record object containing the same information as the specified <recordformat> element. @param formatName The name of the <recordformat> element in the RFML document. @exception XmlException If an error occurs while processing RFML. **/ public Record toRecord(String formatName) throws XmlException { try { return new Record(toRecordFormat(formatName), toByteArray(formatName)); } catch (UnsupportedEncodingException e) { throw new XmlException(e); // This should never happen, but if it does... } } /** Returns a RecordFormat object with the same structure as the specified <recordformat> element. Note: For <data> elements, the 'count' attribute is disregarded. @return A RecordFormat object with the same structure as the specified <recordformat> element. @param formatName The name of the <recordformat> element in the RFML document. * @throws XmlException **/ public RecordFormat toRecordFormat(String formatName) throws XmlException { if (formatName == null) throw new NullPointerException("formatName"); if (m_rfmlDoc_ == null) { throw new XmlException(DAMRI.DOCUMENT_NOT_SET ); } // Get the node for the specified recordformat element. RfmlRecordFormat recFormatNode = m_rfmlDoc_.getRecordFormatNode(formatName); // Generate a RecordFormat. return recFormatNode.toRecordFormat(); } /** Generates XML (RFML) representing the data contained in this object. Throws an XmlException if this object contains no data. @param outputStream The output stream to which to write the text. @exception IOException If an error occurs while writing the data. @exception XmlException If an error occurs while processing RFML. **/ public void toXml(OutputStream outputStream) throws IOException, XmlException { if (outputStream == null) { throw new NullPointerException("outputStream"); } if (m_rfmlDoc_ == null) { throw new XmlException(DAMRI.DOCUMENT_NOT_SET ); } m_rfmlDoc_.toXml(outputStream); } /** Generates XML (RFML) representing the data contained in this object. Throws an XmlException if this object contains no data. @param file The file to which to write the text. @exception IOException If an error occurs while writing the data. @exception XmlException If an error occurs while processing RFML. **/ public void toXml(File file) throws IOException, XmlException { FileOutputStream fos = null; try { fos = new FileOutputStream(file); toXml(fos); } finally { if (fos != null) fos.close(); } } /** Generates XML (RFML) representing the data contained in this object. Throws an XmlException if this object contains no data. @param fileName The pathname of the file to which to write the text. @exception IOException If an error occurs while writing the data. @exception XmlException If an error occurs while processing RFML. **/ public void toXml(String fileName) throws IOException, XmlException { FileOutputStream fos = null; try { fos = new FileOutputStream(fileName); toXml(fos); } finally { if (fos != null) fos.close(); } } /** Custom serialization. **/ private void writeObject(ObjectOutputStream out) throws IOException { synchronized (this) { if (m_rfmlDoc_ != null) { m_rfmlDoc_.setSerializingWithData(true); } // Perform default serialization out.defaultWriteObject(); } // end of synchronized code } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy