Using file sources

This topic describes programming concepts and requirements needed to perform basic file operations on IBM Director systems.

Subtopics

Related sample code

Understanding FileSource

The FileSource interface class represents an abstraction of a file system. Whether local or remote, using FileSource allows you to perform basic operations on a file system without worrying about Interprocess Communication calls. Within your GUI code, instantiate a FileSource object to perform file operations on the IBM Director Console, a remote IBM Director Agent, or an IBM Director Server. The respective classes that implement FileSource are: FSConsole, FSAgent, and FSServer.

Using FileSource

To use a FileSource you must first instantiate an object that implements it. Instantiating FSConsole and FSServer are very straightforward, as their constructors take no parameters.

FSConsole source = new FSConsole();
FSServer source = new FSServer();

However, instantiating FSAgent is a bit more complicated. Because there are many agents in an IBM Director system, you must have some information about which one you would like to instantiate before doing so. Generally you will instantiate an agent with its Managed Object ID, or moid, and its IPC Path. The following block of code taken from our example, FileSourceSample, illustrates one way to instantiate FSAgent. Given only the target's IP hostname, we will determine its moid and IPC Path.


  /**
   * Initialize an agent file source.  If the file source we wish to communicate with
   * is an IBM Director agent, then we must use this method to initialize it.  This
   * method takes a hostname and uses it to look up the destination address (IPC Path)
   * of the agent we wish to communicate with.  Using this data, it instantiates the agent.
   *
   * @parm String hostname of an IBM Director agent.  NOTE:  This hostname must be spelled
   *              exactly as it appears on the inventory sheet for each agent from the
   *              IBM Director main console; capitalization matters.
   */
  public static boolean initAgent(String hostname) {
    boolean rc = false;

    System.out.println("Initializing agent...");
    LongValueSet ids = null;
    String[] attribList = {TWGManagedObjectConstants.ATTRIB_IP_HOSTS};
    String[] value = {hostname};
    TWGStringArray sArray = new TWGStringArray(value);
    DataValue[] dataValue = {sArray};
    FindObjectByAttribCmd cmd = new FindObjectByAttribCmd("com.tivoli.twg.engine.TWGNativeManagedObject", attribList, dataValue);

    try {
      // NOTE:  We use the console service node here for simplicity.  However,
      // when used within Director, this could cause deadlocks. You should
      // always create your own service node to use within Director.
      if (TWGConsoleServiceNode.getConsoleServiceNode().SendCommand(cmd)) {
        if (cmd.ReturnCode() == FTConstants.FILE_TRANSFER_BASE_SUCCESS) {
          ids = cmd.getMatchingIDs();
        } else {
          System.out.println("Send Command Failed.  RC = "+cmd.ReturnCode());
        }
      } else {
        System.out.println("Send Command Failed.");
      }
    } catch (InterruptedException ie) {
      System.out.println("InterruptedException caught in initAgent: "+ie);
      ie.printStackTrace();
    } catch (ServiceNodeException sne) {
      System.out.println("ServiceNodeException in initAgent: "+sne);
      sne.printStackTrace();
    }

    if ((ids != null) && (ids.Length() > 0)) {
      String ipcPath = getClientDestinationAddress(ids.GetValue(0));

      try {

        fs = new FSAgent(ids.GetValue(0), ipcPath);

        // now we must refresh the agent, to insure population of the root level
        refresh();

        rc = true;

      } catch (FTException fte) {
        System.out.println("FTException caught while declaring: "+fte);
        fte.printStackTrace();
      }
      System.out.println("Agent initialized.");
    } else {
      System.out.println("Hostname not found.");
    }

    return rc;
  }

  /**
   * This method will return the destination address of the remote IBM Director agent.
   * This address is used to instantiate agent file sources.
   *
   * @param mo - the client managed object
   */
  public static String getClientDestinationAddress(long mo) {

    String ipcPath = null;
    try {

      TWGRemoteManagedObject rmo = TWGRemoteTaskManager.getRemoteManagedObject(
                                                                              TWGConsoleServiceNode.getConsoleServiceNode(), mo);

      // Shadow the address blob entry.
      TWGNativeAddressEntryShadow addressBlob = new TWGNativeAddressEntryShadow();

      // Try to pull the address out of the command for this
      // particular MOID.
      try {

        byte[] ber= rmo.getAddressEntryRecord();
        int berlen = rmo.getAddressEntryRecord().length;
        addressBlob.initAddressEntry(ber, 0, berlen);


      } catch (AddressEntryFormatException aefx) {
        // Could not get address, so log it and skip.
        System.out.println("AddressEntryFormatException: "+aefx);
      }

      // destination address of our remote client.
      ipcPath = addressBlob.getIPCPath();

    } catch (ServiceNodeClosedException snce) {
      System.out.println("ServiceNodeClosed: "+snce);
    }

    return(ipcPath);

  }

  /** Refresh the file source. */
  private static void refresh() {
    try {
      fs.refresh();

    } catch (FTException e) {
      System.out.println("FTException doing refresh!!!!");
      e.printStackTrace();
    }
  }

        

Once you have created a FileSource object you will have a basic representation of a file system, and can perform an array of tasks using it. You will be able to create directories, rename files, delete files, read in files, write out files, retrieve file lists, retrieve registry values, and much more. Below are a few examples of the actions you might perform.

While browsing the following examples, you will notice references to FSTObjects. An FSTObject is a subclass of the IBM Director class com.tivoli.twg.guilibs.UFTreeListViewObject, which is in turn a subclass of the Swing class DefaultMutableTreeNode, and is the basis for the FileSource framework. Each file and directory discovered by the FileSource is saved internally as an FSTObject, and therefore many of the main FileSource methods return them, or require them as parameters. Since FSTObjects are subclassed TreeNodes, they might be used for display purposes, and it is recommended that you use them as such.

Note: In each example the FileSource object is called source.

Delete a file.


        try {
           if (source.deleteFile("c:\myFile.txt")) {
              System.out.println("File deleted successfully");
           }
        } catch (FTException ftx) {
           System.out.println("FTException caught: "+ftx);
        }
        

Print out the file size.


        try {
           long size = getFileSize("c:\myFile.txt");
           System.out.println("Size of myFile: "+size);
        } catch (FTException ftx) {
           System.out.println("FTException caught: "+ftx);
        }
        

Create a directory.


        try {
           if (mkdir("c:\newDirectory")) {
              System.out.println("Directory created successfully");
           }
        } catch (FTException ftx) {
           System.out.println("FTException caught: "+ftx);
        }
        

Retrieve the list of drives and print out their root directories.


        try {

           // get the list of drives
           FSTObject[] rootLevel = source.getRootLevel();

           for (int i = 0; i < rootLevel.length; i++) {

              try {

                 // populate the drive FSTObject with children
                 if (getDirectoryTree(rootlets[i])) {

                    // now print out all the first level children
                    for (int j = 0; j < rootLevel[i].getChildCount(); j++) {

                       // print out the fully-qualified path of each child
                       System.out.println(rootLevel[i].getChildAt(i).toString());

                    }

                 } else {
                    System.out.println(rootLevel[i].toString() + " Unavailable.");
                 }

              } catch (FTException x) {
                 System.out.println("Access denied to: "+rootLevel[i].toString());
              }

           }

        } catch (FTException ftx) {
           System.out.println("FTException caught: "+ftx);
        }
        

Read in a file from one source and write it out to another.

Source FileSource is srcFS.
Target FileSource is tgtFS.


        InputStream is = null;
        OutputStream os = null;

        try {
           is = srcFS.getInputStream("C:\inFile.txt");
        } catch (FTException isx) {
           System.out.println("Unable to open input.");
        }

        try {
           os = tgtFS.getOutputStream("C:\outFile.txt");
        }  catch (FTException osx) {
           System.out.println("Unable to open output.");
        }

        if ((is != null) && (os != null)) {

           // the streams are open, now we can read in and write out the files.

           char [] cb = new char [1024];
           int read = 0;

           /*Transfer the bytes*/
           try {

              // Initial read
              read = is.read(cb);

           } catch (IOException e) {
              System.out.println("IOException occurred during read: "+e);
              return;
           }

           while (read != -1) {

              try {

                 os.write(cb, 0, read);

              } catch (IOException e) {
                 System.out.println("IOException caught during write: "+e);
                 break;
              }

              try {

                 read = is.read(cb);

              } catch (IOException e) {
                 System.out.println("IOException occurred during read: "+e);
                 break;
              }

           } // end while



           // flush the OutputStream to ensure all was written out
           try {
              os.flush();
           } catch (IOException e) {
              System.out.println("Flush failed.");
           }

           // close the streams
           try {
              is.close();
              os.close();
           } catch (IOException e) {
              // NOOP
           }

        } else {
           System.out.println("An error occurred initializing the streams");
        }

        

For other examples using FileSources, see the sample code:

samples\javasrc\com\BobCo\FileSource\FileSourceSample.java

FileSource methods

canRead(FSTObject)
Determines whether the specified FSTObject can be read.

The syntax of this method is:

  public abstract boolean canRead (FSTObject file) throws FTException;

canRead(String)
Determines whether the specified filename can be read.

The syntax of this method is:

  public abstract boolean canRead (String filename) throws FTException;

canWrite(FSTObject)
Determines whether the specified FSTObject can be written to.

The syntax of this method is:

   public abstract boolean canWrite (FSTObject file) throws FTException; 

canWrite(String)
Determines whether the specified filename can be written to.

The syntax of this method is:

   public abstract boolean canWrite (String filename) throws FTException; 

cleanup()
Do all necessary cleanup here. This method should be called only by the derived classes.

The syntax of this method is:

   public abstract void cleanup () throws FTException; 

deleteFile(FSTObject)
Deletes the specified file.

The syntax of this method is:

   public abstract boolean deleteFile (FSTObject file) throws FTException; 

deleteFile(String)
Deletes the specified file.

The syntax of this method is:

   public abstract boolean deleteFile (String filename) throws FTException; 

exists(String)
Determines if the specified filename exists on the FileSource.

The syntax of this method is:

   public abstract boolean exists (String filename) throws FTException; 

getDefaultEncoding()
Returns the default codepage to use for file streams. This property is generally determined at instantiation by the derived classes. It returns a string representing a valid Java codepage.

The syntax of this method is:

   public abstract String getDefaultEncoding(); 

getDirectoryTree(FSTObject)
Use this method to retrieve the files underneath a directory on the file system represented by this FileSource. Returns an updated FSTObject for a directory.

The syntax of this method is:

   public abstract boolean getDirectoryTree(FSTObject parent) throws FTException; 

getDriveDelimiter()
Get the default drive delimiter of this file source. This method returns a string representing the default drive delimiter. For example, on DOS based systems, the string returned would be ":"

The syntax of this method is:

   public abstract String getDriveDelimiter(); 

getEnvironmentVariable(String)
Get an environment variable from the file source. Note: This method is only valid for FileSources representing Windows based systems.

The syntax of this method is:

   public abstract String getEnvironmentVariable(String varName) throws FTException;  

getFileAttributes(FSTObject)
This method returns the file attributes of a file in the form of a FileAttrs object.

The syntax of this method is:

   public abstract FileAttrs getFileAttributes(FSTObject file) throws FTException;  

getFileAttributes(String)
This method returns the file attributes of a file in the form of a FileAttrs object.

The syntax of this method is:

   public abstract FileAttrs getFileAttributes(String filename) throws FTException; 

getFileSize(FSTObject)
Retrieves the file size of the specified FSTObject.

The syntax of this method is:

   public abstract long getFileSize (FSTObject file) throws FTException; 

getFileSize(String)
Retrieves the file size of the specified file.

The syntax of this method is:

   public abstract long getFileSize (String filename) throws FTException;  

getFileSourceState()
This method returns the state of the FileSource initialization and is useful to query whether the source is ready for use. It returns an int, one of:

The syntax of this method is:

   public abstract int getFileSourceState(); 

getFiletransferVersion(Locale, MultiLocaleBundle)
This method is only used internally by FileSource implementations to ensure backwards compatibility. It returns the version of File Transfer utilized by the IBM Director Server.

The syntax of this method is:

   public static float getFiletransferVersion (Locale loc, MultiLocaleBundle ourBundle) 

getHostname()
Returns the name of this FileSource, which is commonly used for GUI display.

The syntax of this method is:

   public abstract String getHostname(); 

getInputStream(FSTObject)
Returns an InputStream for the specified FSTObject. Use the InputStream returned by this method to read the contents of a file.

The syntax of this method is:

   public abstract InputStream getInputStream (FSTObject file) throws FTException; 

getInputStream(String)
Returns an InputStream for the specified file. Use the InputStream returned by this method to read the contents of a file.

The syntax of this method is:

   public abstract InputStream getInputStream (String filename) throws FTException; 

getNameDelimiter()
Get the default name delimiter of this file source. This method returns a string representing the default name delimiter.

The syntax of this method is:

   public abstract String getNameDelimiter(); 

getOutputStream(FSTObject)
Returns an OutputStream for the specified FSTObject. Use the OutputStream returned by this method to write out to a file.

The syntax of this method is:

   public abstract OutputStream getOutputStream (FSTObject file)throws FTException; 

getOutputStream(String)
Returns an OutputStream for the specified file. Use the OutputStream returned by this method to write out to a file.

The syntax of this method is:

   public abstract OutputStream getOutputStream (String filename)throws FTException; 

getPathDelimiter()
Get the default path delimiter of this file source. This method returns a string representing the default path delimiter. For example, on DOS based systems, the string returned would be "\\".

The syntax of this method is:

   public abstract String getPathDelimiter(); 

getRegBytesValue(String, String)
Get a registry value of type byte[] from the file source.

The syntax of this method is:

   public abstract byte [] getRegBytesValue(String keyName, String valueName) throws FTException; 

getRegIntValue(String, String)
Get a registry value of type int from the file source.

The syntax of this method is:

   public abstract int getRegIntValue(String keyName, String valueName) throws FTException; 

getRegStringValue(String, String)
Get a registry value of type String from the file source.

The syntax of this method is:

   public abstract String getRegStringValue(String keyName, String valueName) throws FTException; 

getRootDelimiter()
Get the default root delimiter of this file source. This method returns a string representing the default root delimiter.

The syntax of this method is:

   public abstract String getRootDelimiter(); 

getRootLevel()
Get the root level of the FileSource on drive type systems. This will be a list of all available drives. On non-drive systems this will be the root directory. This method returns an array of FSTObjects representing the root level of the file system.

The syntax of this method is:

   public abstract FSTObject [] getRootLevel () throws FTException; 

getSearchString()
Get the default search string of this file source. This method returns a string representing the default path delimiter (e.g. "*.*" or "*").

The syntax of this method is:

   public abstract String getSearchString(); 

hasServerFSAccess()
Call this method to query whether the current user has access to the server file system.

The syntax of this method is:

   public static boolean hasServerFSAccess()  

isAbsolute(String)
Determines whether the specified filename is an absolute path.

The syntax of this method is:

   public abstract boolean isAbsolute (String filename); 

isDirectory(String)
Determines if the specified filename exists, and is a DIRECTORY, rather than a FILE.

The syntax of this method is:

   public abstract boolean isDirectory (String filename)throws FTException;
 

isFile(String)
Determines if the specified filename exists, and is a FILE, rather than a DIRECTORY.

The syntax of this method is:

   public abstract boolean isFile (String filename) throws FTException; 

mkdir(FSTObject)
Creates the specified directory on the file system.

The syntax of this method is:

   public abstract boolean mkdir (FSTObject directory) throws FTException; 

mkdir(String)
Creates the specified directory on the file system.

The syntax of this method is:

   public abstract boolean mkdir (String directoryName) throws FTException; 

refresh()
Reinitializes the FileSource and refreshes its drive list.

The syntax of this method is:

   public abstract void refresh() throws FTException; 

renameFile(FSTObject, String)
Renames the specified FSTObject to the new name passed in.

The syntax of this method is:

   public abstract boolean renameFile (FSTObject file, String newFilename) throws FTException; 

renameFile(String, String)
Renames the specified file to the new name passed in.

The syntax of this method is:

   public abstract boolean renameFile (String originalFilename, String newFilename) throws FTException; 

setHostname(String)
Set the name of this FileSource used for GUI display.

The syntax of this method is:

   public abstract void setHostname(String host);  

Running the example

To run the sample code, you must first compile it. The sample code consists of one Java file:

\Program Files\IBM\IBM Director SDK\samples\javasrc\com\BobCo\FileSource\FileSourceSample.java

To compile it, change directory to:

[drive]:\Program Files\IBM\IBM Director SDK\samples\javasrc\com\BobCo\FileSource

In this directory you will find both the Java source file and a makefile. Run the makefile to compile the source. The class file created by the makefile will now be found in:

[drive]:\Program Files\IBM\IBM Director SDK\samples\classes\com\BobCo\FileSource

After compiling the code, copy the class files to:

[drive]:\Program Files\IBM\Director\classes\com\BobCo\FileSource

Change directory to:

[drive]:\Program Files\IBM\Director\classes

To run the sample, enter:

twgjava com.BobCo.FileSource.FileSourceSample [parameter]

where [parameter] is one of the following:

Example:

twgjava com.BobCo.FileSource.FileSourceSample agent director.mywork.com

After launching this application, you will be prompted for input. Enter help to see a list of commands.