midrange.com code scratchpad
Name:
MessageFile enhancement
Scriptlanguage:
Java
Tabwidth:
4
Date:
09/14/2008 04:55:47 pm
IP:
Logged
Description:
I've modified the MessageFile object to allow the first & next messages to be retrieved from a message file.

To retrieve the first message, invoke the getMessage with a message id of MessageFile.FIRST. To retrieve the next message, invoke the getMessage method with a message id of MessageFile.NEXT.

If NEXT is specified, and there are no more messages to retrieve, a null message object is returned.
Code:
  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // JTOpen (IBM Toolbox for Java - OSS version)
  4. //
  5. // Filename:  MessageFile.java
  6. //
  7. // The source code contained herein is licensed under the IBM Public License
  8. // Version 1.0, which has been approved by the Open Source Initiative.
  9. // Copyright (C) 1997-2005 International Business Machines Corporation and
  10. // others.  All rights reserved.
  11. //
  12. ///////////////////////////////////////////////////////////////////////////////
  13. package com.ibm.as400.access;
  14.  
  15. import java.beans.PropertyChangeListener;
  16. import java.beans.PropertyChangeSupport;
  17. import java.beans.PropertyVetoException;
  18. import java.beans.VetoableChangeListener;
  19. import java.beans.VetoableChangeSupport;
  20. import java.io.IOException;
  21. import java.io.Serializable;
  22.  
  23. /**
  24.  Represents a message file object on the system.  This class allows a user to get a message from a message file, returning an AS400Message object which contains the message.  The calling program can optionally supply substitution text for the message.
  25.  <p>MessageFile will optionally format the message's associated help text.  Three options are available for help text formatting:
  26.  <ol>
  27.  <li>No formatting - the help text is returned as a string of characters.  This is the default.
  28.  <li>Include formatting characters - the help text contains formatting characters.  The formatting characters are:
  29.  <ul>
  30.  <br>&N -- Force a new line.
  31.  <br>&P -- Force a new line and indent the new line six characters.
  32.  <br>&B -- Force a new line and indent the new line four characters.
  33.  </ul>
  34.  <li>Substitute formatting characters - the MessageFile class replaces system formatting characters with newline and space characters.
  35.  </ol>
  36.  The difference between options 2 and 3 are with line wrapping.  If the formatting characters remain the application can handle line wrapping and indentation.  If the MessageFile class inserts newline and space characters, Java components will handle line wrapping.
  37.  <p>For example, to retrieve and print a message:
  38.  <pre>
  39.  AS400 system = new AS400("mysystem.mycompany.com");
  40.  MessageFile messageFile = new MessageFile(system);
  41.  messageFile.setPath("/QSYS.LIB/QCPFMSG.MSGF");
  42.  AS400Message message = messageFile.getMessage("CPD0170");
  43.  System.out.println(message.getText());
  44.  </pre>
  45.  <p>You can also sequentially retrieve messages from a message file by using the FIRST & NEXT message id values.
  46.  <pre>
  47.  AS400Message msg = messageFile.getMessage(MessageFile.FIRST);
  48.  
  49.  while (msg != null) {
  50.     System.out.println(msg.getID() + " = " + msg.getText());
  51.     msg = messageFile.getMessage(MessageFile.NEXT);
  52.  }
  53. </pre>
  54.  @see  AS400Message
  55.  @see  CommandCall
  56.  @see  ProgramCall
  57.  @see  QSYSObjectPathName
  58.  **/
  59. public class MessageFile implements Serializable
  60. {
  61.     static final long serialVersionUID = 4L;
  62.  
  63.     /**
  64.      Constant indicating help text should not be formatted.
  65.      **/
  66.     public static final int NO_FORMATTING = 0;
  67.  
  68.     /**
  69.      Constant indicating formatting characters are left in the help text.
  70.      **/
  71.     public static final int RETURN_FORMATTING_CHARACTERS = 1;
  72.  
  73.     /**
  74.      Constant indicating MessageFile should replace formatting characters with newline and space characters.
  75.      **/
  76.     public static final int SUBSTITUTE_FORMATTING_CHARACTERS = 2;
  77.  
  78.     /**
  79.      Constant indicating "the CCSID of the job".
  80.      **/
  81.     public static final int CCSID_OF_JOB = 0;
  82.  
  83.     // The type of help text formatting.
  84.     private int helpTextFormatting_ = NO_FORMATTING;
  85.  
  86.     // The system where the message file is located.
  87.     private AS400 system_ = null;
  88.     // The full IFS path name of the message file.
  89.     private String path_ = "";
  90.     // The library that contains the message file.
  91.     private String library_ = null;
  92.     // The name of the message file.
  93.     private String name_ = null;
  94.  
  95.     // Track if a connection to the system has been made.
  96.     private transient boolean connected_ = false;
  97.  
  98.     // List of property change event bean listeners.
  99.     private transient PropertyChangeSupport propertyChangeListeners_ = null;  // Set on first add.
  100.     // List of vetoable change event bean listeners.
  101.     private transient VetoableChangeSupport vetoableChangeListeners_ = null;  // Set on first add.
  102.     private String lastMessageId = null;
  103.  
  104.     /**
  105.      * Constant indicating we are going to retrieve the next message
  106.      * (using the previous message as a starting point).
  107.      */
  108.     public static final String NEXT = "*NEXT";
  109.     
  110.     /**
  111.      * Constant indicating we are going to retrieve the first message
  112.      * in the message file.
  113.      */
  114.     public static final String FIRST = "*FIRST";
  115.     
  116.     private static final byte[] OPTION_MSGID = 
  117.         new byte[] { 0x5C, (byte)0xD4, (byte)0xE2, (byte)0xC7, (byte)0xC9, (byte)0xC4, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40 };
  118.     private static final byte[] OPTION_NEXT = 
  119.         new byte[] { 0x5C, (byte)0xD5, (byte)0xC5, (byte)0xE7, (byte)0xE3, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40 };
  120.     private static final byte[] OPTION_FIRST = 
  121.         new byte[] { 0x5C, (byte)0xC6, (byte)0xC9, (byte)0xD9, (byte)0xE2, (byte)0xE3, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40 };
  122.     
  123.     /**
  124.      Constructs a MessageFile object.  The system and message file name must be provided later.
  125.      **/
  126.     public MessageFile()
  127.     {
  128.         super();
  129.         if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Constructing MessageFile object.");
  130.     }
  131.  
  132.     /**
  133.      Constructs a MessageFile object.  It uses the specified system.  The message file name must be provided later.
  134.      @param  system  The system object representing the system on which the message file exists.
  135.      **/
  136.     public MessageFile(AS400 system)
  137.     {
  138.         super();
  139.         if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Constructing MessageFile object, system: " + system);
  140.         if (system == null)
  141.         {
  142.             Trace.log(Trace.ERROR, "Parameter 'system' is null.");
  143.             throw new NullPointerException("system");
  144.         }
  145.         system_ = system;
  146.     }
  147.  
  148.     /**
  149.      Constructs a MessageFile object.  It uses the specified system and message file name.
  150.      @param  system  The system object representing the system on which the message file exists.
  151.      @param  path  The integrated file system path name for the message file.  That is, the message file name as a fully qualified path name in the library file system.  The library and message file name must each be 10 characters or less.  The extension for message files is .msgf.  For example, /QSYS.LIB/MYLIB.LIB/MYFILE.MSGF.
  152.      **/
  153.     public MessageFile(AS400 system, String path)
  154.     {
  155.         super();
  156.         if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Constructing MessageFile object, system: " + system + " path: " + path);
  157.  
  158.         // Check parameters.
  159.         if (system == null)
  160.         {
  161.             Trace.log(Trace.ERROR, "Parameter 'system' is null.");
  162.             throw new NullPointerException("system");
  163.         }
  164.         if (path == null)
  165.         {
  166.             Trace.log(Trace.ERROR, "Parameter 'path' is null.");
  167.             throw new NullPointerException("path");
  168.         }
  169.         QSYSObjectPathName ifs = new QSYSObjectPathName(path, "MSGF");
  170.  
  171.         // Set instance variables.
  172.         library_ = ifs.getLibraryName();
  173.         name_ = ifs.getObjectName();
  174.         path_ = path;
  175.         system_ = system;
  176.     }
  177.  
  178.     /**
  179.      Adds a PropertyChangeListener.  The specified PropertyChangeListener's <b>propertyChange()</b> method will be called each time the value of any bound property is changed.
  180.      @param  listener  The listener.
  181.      @see  #removePropertyChangeListener
  182.      **/
  183.     public void addPropertyChangeListener(PropertyChangeListener listener)
  184.     {
  185.         if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Adding property change listener.");
  186.         if (listener == null)
  187.         {
  188.             Trace.log(Trace.ERROR, "Parameter 'listener' is null.");
  189.             throw new NullPointerException("listener");
  190.         }
  191.         synchronized (this)
  192.         {
  193.             // If first add.
  194.             if (propertyChangeListeners_ == null)
  195.             {
  196.                 propertyChangeListeners_ = new PropertyChangeSupport(this);
  197.             }
  198.             propertyChangeListeners_.addPropertyChangeListener(listener);
  199.         }
  200.     }
  201.  
  202.     /**
  203.      Adds a VetoableChangeListener.  The specified VetoableChangeListener's <b>vetoableChange()</b> method will be called each time the value of any constrained property is changed.
  204.      @param  listener  The listener.
  205.      @see  #removeVetoableChangeListener
  206.      **/
  207.     public void addVetoableChangeListener(VetoableChangeListener listener)
  208.     {
  209.         if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Adding vetoable change listener.");
  210.         if (listener == null)
  211.         {
  212.             Trace.log(Trace.ERROR, "Parameter 'listener' is null.");
  213.             throw new NullPointerException("listener");
  214.         }
  215.         synchronized (this)
  216.         {
  217.             // If first add.
  218.             if (vetoableChangeListeners_ == null)
  219.             {
  220.                 vetoableChangeListeners_ = new VetoableChangeSupport(this);
  221.             }
  222.             vetoableChangeListeners_.addVetoableChangeListener(listener);
  223.         }
  224.     }
  225.  
  226.     /**
  227.      Substitutes formatting characters with appropriate new line and indent characters.  The formatting characters are:
  228.      <ul>
  229.      <br>&N -- Force a new line.
  230.      <br>&P -- Force a new line and indent the new line six characters.
  231.      <br>&B -- Force a new line and indent the new line four characters.
  232.      </ul>
  233.      @param  sourceText  The source text.
  234.      @return  The formatted text.
  235.      **/
  236.     public static String substituteFormattingCharacters(String sourceText)
  237.     {
  238.         // To preserve behavior, assume not BiDi.
  239.         return substituteFormattingCharacters(sourceText, false);
  240.     }
  241.  
  242.     private static String substituteFormattingCharacters(String sourceText, boolean bidi)
  243.     {
  244.         String targetText = sourceText;
  245.         targetText = replaceText(targetText, "&N", "\n");
  246.         targetText = replaceText(targetText, "&P", "\n      ");
  247.         targetText = replaceText(targetText, "&B", "\n    ");
  248.  
  249.         if (bidi)
  250.         {
  251.             targetText = replaceText(targetText, "N&", "\n");
  252.             targetText = replaceText(targetText, "P&", "\n      ");
  253.             targetText = replaceText(targetText, "B&", "\n    ");
  254.         }
  255.         return targetText;
  256.     }
  257.  
  258.     /**
  259.      Returns the status of help text formatting.  Possible values are:
  260.      <ul>
  261.      <li>NO_FORMATTING - The help text is returned as a string of characters.  This is the default.
  262.      <li>RETURN_FORMATTING_CHARACTERS - The help text contains formatting characters.  The formatting characters are:
  263.      <ul>
  264.      <br>&N -- Force a new line.
  265.      <br>&P -- Force a new line and indent the new line six characters.
  266.      <br>&B -- Force a new line and indent the new line four characters.
  267.      </ul>
  268.      <li>SUBSTITUTE_FORMATTING_CHARACTERS - The MessageFile class replaces formatting characters with newline and space characters.
  269.      </ul>
  270.      @return  The status of help text formatting.
  271.      **/
  272.     public int getHelpTextFormatting()
  273.     {
  274.         if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Getting help text formatting:", helpTextFormatting_);
  275.         return helpTextFormatting_;
  276.     }
  277.  
  278.     /**
  279.      Returns the integrated file system path name of the message file.
  280.      @return  The fully-qualified message file name, or an empty string ("") if not set.
  281.      **/
  282.     public String getPath()
  283.     {
  284.         if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Getting path: " + path_);
  285.         return path_;
  286.     }
  287.  
  288.     /**
  289.      Returns an AS400Message object containing the object.  The system and message file name must be set before calling this method.
  290.      @param  ID  The message identifier, FIRST, or NEXT.
  291.      @return  An AS400Message object containing the message.
  292.      @exception  AS400SecurityException  If a security or authority error occurs.
  293.      @exception  ErrorCompletingRequestException  If an error occurs before the request is completed.
  294.      @exception  InterruptedException  If this thread is interrupted.
  295.      @exception  IOException  If an error occurs while communicating with the system.
  296.      @exception  ObjectDoesNotExistException  If the object does not exist on the system.
  297.      @exception  PropertyVetoException  If any of the registered listeners vetos the property change.
  298.      **/
  299.     public AS400Message getMessage(String ID) throws AS400SecurityException, ErrorCompletingRequestException, InterruptedException, IOException, ObjectDoesNotExistException, PropertyVetoException
  300.     {
  301.         if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Retrieving message from message file, ID: " + ID);
  302.         return getMessage(ID, (byte[])null);
  303.     }
  304.  
  305.     /**
  306.      Returns an AS400Message object containing the object.  The system and message file name must be set before calling this method.
  307.      @param  ID  The message identifier, FIRST, or NEXT.
  308.      @param  type  The bidi message string type, as defined by the CDRA (Character Data Representataion Architecture).  See <a href="BidiStringType.html"> BidiStringType</a> for more information and valid values.
  309.      @return  An AS400Message object containing the message.
  310.      @exception  AS400SecurityException  If a security or authority error occurs.
  311.      @exception  ErrorCompletingRequestException  If an error occurs before the request is completed.
  312.      @exception  InterruptedException  If this thread is interrupted.
  313.      @exception  IOException  If an error occurs while communicating with the system.
  314.      @exception  ObjectDoesNotExistException  If the object does not exist on the system.
  315.      @exception  PropertyVetoException  If any of the registered listeners vetos the property change.
  316.      **/
  317.     public AS400Message getMessage(String ID, int type) throws AS400SecurityException, ErrorCompletingRequestException, InterruptedException, IOException, ObjectDoesNotExistException, PropertyVetoException
  318.     {
  319.         if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Retrieving message from message file, ID: " + ID + ", type:", type);
  320.         return getMessage(ID, (byte[])null, type);
  321.     }
  322.  
  323.     /**
  324.      Returns an AS400Message object containing the message.  The system and message file name must be set before calling this method.  Up to 1024 bytes of substitution text can be supplied to this method.  The calling program is responsible for correctly formatting the string containing the substitution text for the specified message.
  325.      <p>For example, using CL command DSPMSGD, we see the format of the substitution text for message CPD0170 is char 4, char 10, char 10.  Passing string <pre>"12  abcd      xyz"</pre> as the substitution text on this call means "12" will be substituted for &1, "abcd" will be substituted for &2, and "xyz" will be substituted for &3.
  326.      @param  ID  The message identifier, FIRST, or NEXT.
  327.      @param  substitutionText  The substitution text.
  328.      @return  An AS400Message object containing the message.
  329.      @exception  AS400SecurityException  If a security or authority error occurs.
  330.      @exception  ErrorCompletingRequestException  If an error occurs before the request is completed.
  331.      @exception  InterruptedException  If this thread is interrupted.
  332.      @exception  IOException  If an error occurs while communicating with the system.
  333.      @exception  ObjectDoesNotExistException  If the object does not exist on the system.
  334.      @exception  PropertyVetoException  If any of the registered listeners vetos the property change.
  335.      **/
  336.     public AS400Message getMessage(String ID, String substitutionText) throws AS400SecurityException, ErrorCompletingRequestException, InterruptedException, IOException, ObjectDoesNotExistException, PropertyVetoException
  337.     {
  338.         if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Retrieving message from message file, ID: " + ID + ", substitutionText: " + substitutionText);
  339.         if (system_ == null)
  340.         {
  341.             Trace.log(Trace.ERROR, "Cannot connect to server before setting system.");
  342.             throw new ExtendedIllegalStateException("system", ExtendedIllegalStateException.PROPERTY_NOT_SET);
  343.         }
  344.  
  345.         if (AS400BidiTransform.isBidiCcsid(system_.getCcsid()))
  346.         {
  347.             return getMessage(ID, substitutionText, AS400BidiTransform.getStringType(system_.getCcsid()));
  348.         }
  349.         return getMessage(ID, substitutionText, BidiStringType.DEFAULT);
  350.     }
  351.  
  352.     /**
  353.      Returns an AS400Message object containing the message.  The system and message file name must be set before calling this method.  Up to 1024 bytes of substitution text can be supplied to this method.  The calling program is responsible for correctly formatting the string containing the substitution text for the specified message.
  354.      <p>For example, using CL command DSPMSGD, we see the format of the substitution text for message CPD0170 is char 4, char 10, char 10.  Passing string <pre>"12  abcd      xyz"</pre> as the substitution text on this call means "12" will be substituted for &1, "abcd" will be substituted for &2, and "xyz" will be substituted for &3.
  355.      @param  ID  The message identifier, FIRST, or NEXT.
  356.      @param  substitutionText  The substitution text.
  357.      @param  type  The bidi message string type, as defined by the CDRA (Character Data Representataion Architecture).  See <a href="BidiStringType.html"> BidiStringType</a> for more information and valid values.
  358.      @return  An AS400Message object containing the message.
  359.      @exception  AS400SecurityException  If a security or authority error occurs.
  360.      @exception  ErrorCompletingRequestException  If an error occurs before the request is completed.
  361.      @exception  InterruptedException  If this thread is interrupted.
  362.      @exception  IOException  If an error occurs while communicating with the system.
  363.      @exception  ObjectDoesNotExistException  If the object does not exist on the system.
  364.      @exception  PropertyVetoException  If any of the registered listeners vetos the property change.
  365.      **/
  366.     public AS400Message getMessage(String ID, String substitutionText, int type) throws AS400SecurityException, ErrorCompletingRequestException, InterruptedException, IOException, ObjectDoesNotExistException, PropertyVetoException
  367.     {
  368.         if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Retrieving message from message file, ID: " + ID + ", substitutionText: " + substitutionText + ", type:", type);
  369.         if (system_ == null)
  370.         {
  371.             Trace.log(Trace.ERROR, "Cannot connect to server before setting system.");
  372.             throw new ExtendedIllegalStateException("system", ExtendedIllegalStateException.PROPERTY_NOT_SET);
  373.         }
  374.  
  375.         return getMessage(ID, substitutionText != null ? new Converter(system_.getCcsid(), system_).stringToByteArray(substitutionText, type) : null, type);
  376.     }
  377.  
  378.     /**
  379.      Returns an AS400Message object containing the message.  The system and message file name must be set before calling this method.  Up to 1024 bytes of substitution text can be supplied to this method.  <b>The byte array is not changed or converted before being sent to the system</b>.
  380.      @param  ID  The message identifier, FIRST, or NEXT.
  381.      @param  substitutionText  The substitution text.  The bytes are assumed to be in the CCSID of the job.
  382.      @return  An AS400Message object containing the message.
  383.      @exception  AS400SecurityException  If a security or authority error occurs.
  384.      @exception  ErrorCompletingRequestException  If an error occurs before the request is completed.
  385.      @exception  InterruptedException  If this thread is interrupted.
  386.      @exception  IOException  If an error occurs while communicating with the system.
  387.      @exception  ObjectDoesNotExistException  If the object does not exist on the system.
  388.      @exception  PropertyVetoException  If any of the registered listeners vetos the property change.
  389.      **/
  390.     public AS400Message getMessage(String ID, byte[] substitutionText) throws AS400SecurityException, ErrorCompletingRequestException, InterruptedException, IOException, ObjectDoesNotExistException, PropertyVetoException
  391.     {
  392.         if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Retrieving message from message file, ID: " + ID + ", substitutionText:", substitutionText);
  393.         if (system_ == null)
  394.         {
  395.             Trace.log(Trace.ERROR, "Cannot connect to server before setting system.");
  396.             throw new ExtendedIllegalStateException("system", ExtendedIllegalStateException.PROPERTY_NOT_SET);
  397.         }
  398.  
  399.         if (AS400BidiTransform.isBidiCcsid(system_.getCcsid()))
  400.         {
  401.             return getMessage(ID, substitutionText, AS400BidiTransform.getStringType(system_.getCcsid()));
  402.         }
  403.         return getMessage(ID, substitutionText, BidiStringType.DEFAULT);
  404.     }
  405.  
  406.     /**
  407.      Returns an AS400Message object containing the message.  The system and message file name must be set before calling this method.  Up to 1024 bytes of substitution text can be supplied to this method.  <b>The byte array is not changed or converted before being sent to the system</b>.
  408.      @param  ID  The message identifier, FIRST, or NEXT.
  409.      @param  substitutionText  The substitution text.  The bytes are assumed to be in the CCSID of the job.
  410.      @param  type  The bidi message string type, as defined by the CDRA (Character Data Representataion Architecture).  See <a href="BidiStringType.html"> BidiStringType</a> for more information and valid values.
  411.      @return  An AS400Message object containing the message.
  412.      @exception  AS400SecurityException  If a security or authority error occurs.
  413.      @exception  ErrorCompletingRequestException  If an error occurs before the request is completed.
  414.      @exception  InterruptedException  If this thread is interrupted.
  415.      @exception  IOException  If an error occurs while communicating with the system.
  416.      @exception  ObjectDoesNotExistException  If the object does not exist on the system.
  417.      @exception  PropertyVetoException  If any of the registered listeners vetos the property change.
  418.      **/
  419.     public AS400Message getMessage(String ID, byte[] substitutionText, int type) throws AS400SecurityException, ErrorCompletingRequestException, InterruptedException, IOException, ObjectDoesNotExistException, PropertyVetoException
  420.     {
  421.         if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Retrieving message from message file, ID: " + ID + ", type:" + type + ", substitutionText:", substitutionText);
  422.         return getMessage(ID, substitutionText, type, CCSID_OF_JOB, CCSID_OF_JOB);
  423.     }
  424.  
  425.  
  426.     /**
  427.      Returns an AS400Message object containing the message.  The system and message file name must be set before calling this method.  Up to 1024 bytes of substitution text can be supplied to this method.  <b>The byte array is not changed or converted before being sent to the system</b>.
  428.      @param  ID  The message identifier, FIRST, or NEXT.
  429.      @param  substitutionText  The substitution text.
  430.      @param  type  The bidi message string type, as defined by the CDRA (Character Data Representataion Architecture).  The default value is {@link BidiStringType#DEFAULT BidiStringType.DEFAULT}. See <a href="BidiStringType.html"> BidiStringType</a> for more information and valid values.
  431.      @param  ccsidOfSubstitutionText  The CCSID of the substitution text.  The default value is {@link #CCSID_OF_JOB CCSID_OF_JOB}.
  432.      @param  ccsidToConvertTo  The CCSID in which the system should return the message text. The Toolbox then converts from that CCSID to Unicode when constructing the AS400Message.  The default value is {@link #CCSID_OF_JOB CCSID_OF_JOB}.
  433.      @return  An AS400Message object containing the message.
  434.      @exception  AS400SecurityException  If a security or authority error occurs.
  435.      @exception  ErrorCompletingRequestException  If an error occurs before the request is completed.
  436.      @exception  InterruptedException  If this thread is interrupted.
  437.      @exception  IOException  If an error occurs while communicating with the system.
  438.      @exception  ObjectDoesNotExistException  If the object does not exist on the system.
  439.      @exception  PropertyVetoException  If any of the registered listeners vetos the property change.
  440.      **/
  441.     public AS400Message getMessage(String ID, byte[] substitutionText, int type, int ccsidOfSubstitutionText, int ccsidToConvertTo) throws AS400SecurityException, ErrorCompletingRequestException, InterruptedException, IOException, ObjectDoesNotExistException, PropertyVetoException
  442.     {
  443.         if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Retrieving message from message file, ID: " + ID + ", type:" + type+ ", ccsidOfSubstitutionText:" + ccsidOfSubstitutionText + ", substitutionText:", substitutionText);
  444.         if (ID == null)
  445.         {
  446.             Trace.log(Trace.ERROR, "Parameter 'ID' is null.");
  447.             throw new NullPointerException("ID");
  448.         }
  449.         if (ID.length() > 7)
  450.         {
  451.             Trace.log(Trace.ERROR, "Length of parameter 'ID' is not valid: '" + ID + "'");
  452.             throw new ExtendedIllegalArgumentException("ID (" + ID + ")", ExtendedIllegalArgumentException.LENGTH_NOT_VALID);
  453.         }
  454.  
  455.         if (system_ == null)
  456.         {
  457.             Trace.log(Trace.ERROR, "Cannot connect to server before setting system.");
  458.             throw new ExtendedIllegalStateException("system", ExtendedIllegalStateException.PROPERTY_NOT_SET);
  459.         }
  460.         if (path_.length() == 0)
  461.         {
  462.             Trace.log(Trace.ERROR, "Cannot connect to server before setting path.");
  463.             throw new ExtendedIllegalStateException("path", ExtendedIllegalStateException.PROPERTY_NOT_SET);
  464.         }
  465.  
  466.         // Prevent changing the system or path after retrieving a message.
  467.         connected_ = true;
  468.  
  469.         Converter conv = new Converter(system_.getCcsid(), system_);
  470.  
  471.         byte[] nameBytes = new byte[] { 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 };  // 20 EBCDIC blanks
  472.         conv.stringToByteArray(name_, nameBytes, 0, 10, type);
  473.         conv.stringToByteArray(library_, nameBytes, 10, 10, type);
  474.  
  475.         byte[] optionBytes = OPTION_MSGID;
  476.         if (ID.equals(FIRST)) {
  477.             optionBytes = OPTION_FIRST;
  478.             ID = "";
  479.         } else if (ID.equals(NEXT)) {
  480.             optionBytes = OPTION_NEXT;
  481.             ID = lastMessageId;
  482.         }
  483.         
  484.         byte[] idBytes = new byte[] { 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 };  // 7 EBCDIC blanks
  485.         conv.stringToByteArray(ID, idBytes, 0, 7);
  486.  
  487.         if (substitutionText == null) substitutionText = new byte[0];
  488.  
  489.         byte[] starNoBytes = new byte[] { 0x5C, (byte)0xD5, (byte)0xD6, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 };  // "*NO       ", in EBCDIC
  490.         byte[] starYesBytes = new byte[] { 0x5C, (byte)0xE8, (byte)0xC5, (byte)0xE2, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 };  // "*YES      ", in EBCDIC
  491.         byte[] replace = (substitutionText.length == 0) ? starNoBytes : starYesBytes;
  492.         byte[] format = (helpTextFormatting_ == 0) ? starNoBytes : starYesBytes;
  493.  
  494.         // Setup program parameters.
  495.         ProgramParameter[] parameters = new ProgramParameter[]
  496.         {
  497.             // Message information, output, char(*).
  498.             new ProgramParameter(5120),
  499.             // Length of message information, input, binary(4). (0x1400 == 5120)
  500.             new ProgramParameter(new byte[] { 0x00, 0x00, 0x14, 0x00 } ),
  501.             // Format name, input, char(8), "RTVM0300" (EBCDIC).
  502.             new ProgramParameter(new byte[] { (byte)0xD9, (byte)0xE3, (byte)0xE5, (byte)0xD4, (byte)0xF0, (byte)0xF3, (byte)0xF0, (byte)0xF0 } ),
  503.             // Message identifier, input, char(7).
  504.             new ProgramParameter(idBytes),
  505.             // Qualified message file name, input, char(20).
  506.             new ProgramParameter(nameBytes),
  507.             // Replacement data, input, char(*).
  508.             new ProgramParameter(substitutionText),
  509.             // Length of replacement data, input, binary(4).
  510.             new ProgramParameter(BinaryConverter.intToByteArray(substitutionText.length)),
  511.             // Replace substitution values, input, char(10).
  512.             new ProgramParameter(replace),
  513.             // Return format control characters, input, char(10).
  514.             new ProgramParameter(format),
  515.             // Error code, I/0, char(*).
  516.             new ProgramParameter(new byte[8]),
  517.             // Retrieve option, input, char(10)
  518.             new ProgramParameter(optionBytes),
  519.            // CCSID to convert to, input, binary(4).  0 == "ccsid of job".
  520.             new ProgramParameter(BinaryConverter.intToByteArray(ccsidToConvertTo)),
  521.             // CCSID of replacement data, input, binary(4).  0 == "ccsid of job".
  522.             new ProgramParameter(BinaryConverter.intToByteArray(ccsidOfSubstitutionText))
  523.         };
  524.  
  525.         // Design note: The 3 "optional parameters" existed in V5R1, and probably even earlier.  But to be safe, we'll only send them if we need to.
  526.         // In order to implement the *FIRST & *NEXT options, the three optional
  527.         // parameters are now always included.
  528.         
  529.         // Call the program.
  530.         ProgramCall pc = new ProgramCall(system_, "/QSYS.LIB/QMHRTVM.PGM", parameters);
  531.         pc.setThreadSafe(true);
  532.         if (!pc.run())
  533.         {
  534.             throw new AS400Exception(pc.getMessageList()[0]);
  535.         }
  536.  
  537.         // Prepare to convert returned character bytes to Unicode.
  538.         int ccsidOfTextBytes;  // CCSID of returned character fields
  539.         if (ccsidToConvertTo == CCSID_OF_JOB) {
  540.           ccsidOfTextBytes = system_.getCcsid();
  541.         }
  542.         else {
  543.           ccsidOfTextBytes = ccsidToConvertTo;
  544.           conv = new Converter(ccsidOfTextBytes, system_);
  545.         }
  546.  
  547.         byte[] messageInformation = parameters[0].getOutputData();
  548.         ID = conv.byteArrayToString(messageInformation, 26, 7, type).trim();
  549.         
  550.         AS400Message msg = null;
  551.         
  552.         // if we got a message (assuming ID isn't blank), create & populate the
  553.         // message object.  If we didn't get a message, leave the message null.
  554.         if (ID.length() > 0) {
  555.             msg = new AS400Message();
  556.             msg.setID(ID);
  557.             msg.setSeverity(BinaryConverter.byteArrayToInt(messageInformation, 8));
  558.             int defaultReplyOffset = BinaryConverter.byteArrayToInt(messageInformation, 52);
  559.             int defaultReplyLength = BinaryConverter.byteArrayToInt(messageInformation, 56);
  560.             int messageOffset = BinaryConverter.byteArrayToInt(messageInformation, 64);
  561.             int messageLength = BinaryConverter.byteArrayToInt(messageInformation, 68);
  562.             int helpOffset = BinaryConverter.byteArrayToInt(messageInformation, 76);
  563.             int helpLength = BinaryConverter.byteArrayToInt(messageInformation, 80);
  564.  
  565.             msg.setDefaultReply(conv.byteArrayToString(messageInformation, defaultReplyOffset, defaultReplyLength, type));
  566.             msg.setText(conv.byteArrayToString(messageInformation, messageOffset, messageLength, type));
  567.             String helpText = conv.byteArrayToString(messageInformation, helpOffset, helpLength, type);
  568.             if (helpTextFormatting_ == SUBSTITUTE_FORMATTING_CHARACTERS)
  569.             {
  570.                 helpText = substituteFormattingCharacters(helpText, AS400BidiTransform.isBidiCcsid(ccsidOfTextBytes));
  571.             }
  572.             msg.setHelp(helpText);
  573.             lastMessageId = ID;
  574.  
  575.         } 
  576.  
  577.         return msg;
  578.     }
  579.  
  580.     /**
  581.      Returns the system object representing the system on which the message file exists.
  582.      @return  The system object representing the system on which the message file exists.  If the system has not been set, null is returned.
  583.      **/
  584.     public AS400 getSystem()
  585.     {
  586.         if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Getting system: " + system_);
  587.         return system_;
  588.     }
  589.  
  590.     /**
  591.      Removes the PropertyChangeListener.  If the PropertyChangeListener is not on the list, nothing is done.
  592.      @param  listener  The listener object.
  593.      **/
  594.     public void removePropertyChangeListener(PropertyChangeListener listener)
  595.     {
  596.         if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Removing property change listener.");
  597.         if (listener == null)
  598.         {
  599.             Trace.log(Trace.ERROR, "Parameter 'listener' is null.");
  600.             throw new NullPointerException("listener");
  601.         }
  602.         // If we have listeners.
  603.         if (propertyChangeListeners_ != null)
  604.         {
  605.             propertyChangeListeners_.removePropertyChangeListener(listener);
  606.         }
  607.     }
  608.  
  609.     /**
  610.      Removes the VetoableChangeListener.  If the VetoableChangeListener is not on the list, nothing is done.
  611.      @param  listener  The listener object.
  612.      **/
  613.     public void removeVetoableChangeListener(VetoableChangeListener listener)
  614.     {
  615.         if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Removing vetoable change listener.");
  616.         if (listener == null)
  617.         {
  618.             Trace.log(Trace.ERROR, "Parameter 'listener' is null.");
  619.             throw new NullPointerException("listener");
  620.         }
  621.         // If we have listeners.
  622.         if (vetoableChangeListeners_ != null)
  623.         {
  624.             vetoableChangeListeners_.removeVetoableChangeListener(listener);
  625.         }
  626.     }
  627.  
  628.     // Replace one phrase for another inside a string.
  629.     private static String replaceText(String s, String oldPhrase, String newPhrase)
  630.     {
  631.         int index = s.indexOf(oldPhrase);
  632.  
  633.         while (index >= 0)
  634.         {
  635.             if (index == 0)
  636.             {
  637.                 s = newPhrase + s.substring(3);
  638.             }
  639.             else
  640.             {
  641.                 // Copy from beginning of String to location of oldPhrase.
  642.                 StringBuffer b = new StringBuffer(s.substring(0, index));
  643.                 b.append(newPhrase);
  644.                 // Start at the 2nd position after where oldPhrase occurred.
  645.                 b.append(s.substring(index + 2));
  646.                 s = b.toString();
  647.             }
  648.  
  649.             index = s.indexOf(oldPhrase);
  650.         }
  651.  
  652.         return s;
  653.     }
  654.  
  655.     /**
  656.      Sets the help text formatting value.  Possible values are:
  657.      <ul>
  658.      <li>NO_FORMATTING - the help text is returned as a string of characters.  This is the default.
  659.      <li>RETURN_FORMATTING_CHARACTERS - the help text contains formatting characters.  The formatting characters are:
  660.      <ul>
  661.      <br>&N -- Force a new line.
  662.      <br>&P -- Force a new line and indent the new line six characters.
  663.      <br>&B -- Force a new line and indent the new line four characters.
  664.      </ul>
  665.      <li>SUBSTITUTE_FORMATTING_CHARACTERS - the MessageFile class replaces formatting characters with new line and space characters.
  666.      </ul>
  667.      @param  helpTextFormatting  The help text formatting value.
  668.      @exception  PropertyVetoException  If any of the registered listeners vetos the property change.
  669.      **/
  670.     public void setHelpTextFormatting(int helpTextFormatting) throws PropertyVetoException
  671.     {
  672.         if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Setting help text formatting:", helpTextFormatting);
  673.         if (helpTextFormatting < NO_FORMATTING || helpTextFormatting > SUBSTITUTE_FORMATTING_CHARACTERS)
  674.         {
  675.             Trace.log(Trace.ERROR, "Value of parameter 'helpTextFormatting' is not valid: " + helpTextFormatting);
  676.             throw new ExtendedIllegalArgumentException("helpTextFormatting (" + helpTextFormatting + ")", ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID);
  677.         }
  678.  
  679.         if (propertyChangeListeners_ == null && vetoableChangeListeners_ == null)
  680.         {
  681.             helpTextFormatting_ = helpTextFormatting;
  682.         }
  683.         else
  684.         {
  685.             Integer oldValue = new Integer(helpTextFormatting_);
  686.             Integer newValue = new Integer(helpTextFormatting);
  687.  
  688.             if (vetoableChangeListeners_ != null)
  689.             {
  690.                 vetoableChangeListeners_.fireVetoableChange("helpTextFormatting", oldValue, newValue);
  691.             }
  692.             helpTextFormatting_ = helpTextFormatting;
  693.             if (propertyChangeListeners_ != null)
  694.             {
  695.                 propertyChangeListeners_.firePropertyChange("helpTextFormatting", oldValue, newValue);
  696.             }
  697.         }
  698.     }
  699.  
  700.     /**
  701.      Sets the message file name.  The name cannot be changed after retrieving a message from the system.
  702.      @param  path  The integrated file system path name for the message file.  That is, the message file name as a fully qualified path name in the library file system.  The library and message file name must each be 10 characters or less.  The extension for message files is .msgf.  For example, /QSYS.LIB/MYLIB.LIB/MYFILE.MSGF.
  703.      @exception  PropertyVetoException  If any of the registered listeners vetos the property change.
  704.      **/
  705.     public void setPath(String path) throws PropertyVetoException
  706.     {
  707.         if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Setting path: " + path);
  708.         if (path == null)
  709.         {
  710.             Trace.log(Trace.ERROR, "Parameter 'path' is null.");
  711.             throw new NullPointerException("path");
  712.         }
  713.         // Cannot change the path once we retrieve the first message.
  714.         if (connected_)
  715.         {
  716.             Trace.log(Trace.ERROR, "Cannot set property 'path' after connect.");
  717.             throw new ExtendedIllegalStateException("path", ExtendedIllegalStateException.PROPERTY_NOT_CHANGED);
  718.         }
  719.         QSYSObjectPathName ifs = new QSYSObjectPathName(path, "MSGF");
  720.  
  721.         if (propertyChangeListeners_ == null && vetoableChangeListeners_ == null)
  722.         {
  723.             library_ = ifs.getLibraryName();
  724.             name_ = ifs.getObjectName();
  725.             path_ = path;
  726.         }
  727.         else
  728.         {
  729.             String oldValue = path_;
  730.             String newValue = path;
  731.  
  732.             if (vetoableChangeListeners_ != null)
  733.             {
  734.                 vetoableChangeListeners_.fireVetoableChange("path", oldValue, newValue);
  735.             }
  736.             library_ = ifs.getLibraryName();
  737.             name_ = ifs.getObjectName();
  738.             path_ = path;
  739.             if (propertyChangeListeners_ != null)
  740.             {
  741.                 propertyChangeListeners_.firePropertyChange("path", oldValue, newValue);
  742.             }
  743.         }
  744.     }
  745.  
  746.     /**
  747.      Sets the system object representing the system on which the message file exists.  The system cannot be changed after retrieving a message from the system.
  748.      @param  system  The system object representing the system on which the message file exists.
  749.      @exception  PropertyVetoException  If any of the registered listeners vetos the property change.
  750.      **/
  751.     public void setSystem(AS400 system) throws PropertyVetoException
  752.     {
  753.         if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Setting system: " + system);
  754.         if (system == null)
  755.         {
  756.             Trace.log(Trace.ERROR, "Parameter 'system' is null.");
  757.             throw new NullPointerException("system");
  758.         }
  759.         // Cannot change the system once we retrieve the first message.
  760.         if (connected_)
  761.         {
  762.             Trace.log(Trace.ERROR, "Cannot set property 'system' after connect.");
  763.             throw new ExtendedIllegalStateException("system", ExtendedIllegalStateException.PROPERTY_NOT_CHANGED);
  764.         }
  765.  
  766.         if (propertyChangeListeners_ == null && vetoableChangeListeners_ == null)
  767.         {
  768.             system_ = system;
  769.         }
  770.         else
  771.         {
  772.             AS400 oldValue = system_;
  773.             AS400 newValue = system;
  774.  
  775.             if (vetoableChangeListeners_ != null)
  776.             {
  777.                 vetoableChangeListeners_.fireVetoableChange("system", oldValue, newValue);
  778.             }
  779.             system_ = system;
  780.             if (propertyChangeListeners_ != null)
  781.             {
  782.                 propertyChangeListeners_.firePropertyChange("system", oldValue, newValue);
  783.             }
  784.         }
  785.     }
  786. }
  787.  
© 2004-2019 by midrange.com generated in 0.755s valid xhtml & css