diff --git a/src/main/java/com/ibm/as400/access/IFSCachedAttributes.java b/src/main/java/com/ibm/as400/access/IFSCachedAttributes.java index a42a4934..3b37a1f5 100644 --- a/src/main/java/com/ibm/as400/access/IFSCachedAttributes.java +++ b/src/main/java/com/ibm/as400/access/IFSCachedAttributes.java @@ -16,193 +16,179 @@ /** -Store cached attributes. -**/ -class IFSCachedAttributes implements Serializable + * Store cached attributes. + **/ +class IFSCachedAttributes implements Serializable { - static final long serialVersionUID = 4L; - - static final int FA_READONLY = 0x01; - static final int FA_HIDDEN = 0x02; - - long accessDate_; - long creationDate_; - int fixedAttributes_; - boolean isDirectory_; - boolean isFile_; - boolean isSymbolicLink_; - long modificationDate_; - String name_; - int objectType_; - String parent_; // path of directory - long size_; // @A1c - byte[] restartID_; // @C3a - - //@AC7 Start - int fileDataCCSID_; - String ownerName_; - int fileAsp_; - int fileSystemType_; - static final int UNINITIALIZED = -1; - //@AC7 End - -/** -Construct listCachedAttributes object from a list of attributes. -**/ - IFSCachedAttributes(long accessDate, long creationDate, int fixedAttributes, - long modificationDate, int objectType, long size, - String name, String parent, boolean isDirectory, boolean isFile, - byte[] restartID, boolean isSymbolicLink, int fileSystemType) // @A1c @C3c - { - accessDate_ = accessDate; - creationDate_ = creationDate; - fixedAttributes_ = fixedAttributes; - isDirectory_ = isDirectory; - isFile_ = isFile; - modificationDate_ = modificationDate; - name_ = name; - objectType_ = objectType; - parent_ = parent; - size_ = size; - restartID_ = restartID; // @C3a - isSymbolicLink_ = isSymbolicLink; + static final long serialVersionUID = 4L; + + static final int FA_READONLY = 0x01; + static final int FA_HIDDEN = 0x02; + + long accessDate_; + long creationDate_; + int fixedAttributes_; + boolean isDirectory_; + boolean isFile_; + boolean isSymbolicLink_; + long modificationDate_; + String name_; + int objectType_; + String parent_; // path of directory + long size_; + byte[] restartID_; + + int fileDataCCSID_; + String ownerName_; + String description_; + int fileAsp_; + int fileSystemType_; - //@AC7 Start - fileSystemType_ = fileSystemType; - ownerName_ = null; - fileAsp_ = UNINITIALIZED; - fileDataCCSID_ = UNINITIALIZED; - //@AC7 End - } - -/** -Return access date. -**/ - long getAccessDate() - { - return accessDate_; - } - -/** -Return creation date. -**/ - long getCreationDate() - { - return creationDate_; - } - -/** -Return fixed attributes. -**/ - int getFixedAttributes() - { - return fixedAttributes_; - } - -/** -Return isDir_ -**/ - boolean getIsDirectory() - { - return isDirectory_; - } - -/** -Return isFile_ -**/ - boolean getIsFile() - { - return isFile_; - } - -/** -Return modification date. -**/ - long getModificationDate() - { - return modificationDate_; - } - -/** -Return name. -**/ - String getName() - { - return name_; - } - -/** -Return object type. -**/ - int getObjectType() - { - return objectType_; - } - -/** -Return path of parent directory. -**/ - String getParent() - { - return parent_; - } - -// @C3a -/** -Return restart ID. -**/ - byte[] getRestartID() - { - return restartID_; - } - -/** -Return size. -**/ - long getSize() // @A1c - { - return size_; - } - -/** -Return isSymbolicLink_ -**/ - boolean isSymbolicLink() - { - return isSymbolicLink_; - } - - //@AC7 Start - /** - * Return File system type - */ - int getFileSystemType() { - return fileSystemType_; - } - - /** - * - * @return Owner name - */ - String getOwnerName() { - return ownerName_; - } - - /** - * - * @return File ASP - */ - int getFileAsp() { - return fileAsp_; - } - - /** - * - * @return File data CCSID - */ - int getFileDataCcsid() { - return fileDataCCSID_; - } -//@AC7 End - + static final int UNINITIALIZED = -1; + + /** + * Construct listCachedAttributes object from a list of attributes. + **/ + IFSCachedAttributes(long accessDate, long creationDate, int fixedAttributes, long modificationDate, int objectType, + long size, String name, String parent, boolean isDirectory, boolean isFile, byte[] restartID, + boolean isSymbolicLink, int fileSystemType) + { + accessDate_ = accessDate; + creationDate_ = creationDate; + fixedAttributes_ = fixedAttributes; + isDirectory_ = isDirectory; + isFile_ = isFile; + modificationDate_ = modificationDate; + name_ = name; + objectType_ = objectType; + parent_ = parent; + size_ = size; + restartID_ = restartID; + isSymbolicLink_ = isSymbolicLink; + + fileSystemType_ = fileSystemType; + + // These fields are special and we do not get from cache + description_ = null; + ownerName_ = null; + fileAsp_ = UNINITIALIZED; + fileDataCCSID_ = UNINITIALIZED; + } + + /** + * Return access date. + **/ + long getAccessDate() { + return accessDate_; + } + + /** + * Return creation date. + **/ + long getCreationDate() { + return creationDate_; + } + + /** + * Return fixed attributes. + **/ + int getFixedAttributes() { + return fixedAttributes_; + } + + /** + * Return isDir_ + **/ + boolean getIsDirectory() { + return isDirectory_; + } + + /** + * Return isFile_ + **/ + boolean getIsFile() { + return isFile_; + } + + /** + * Return modification date. + **/ + long getModificationDate() { + return modificationDate_; + } + + /** + * Return name. + **/ + String getName() { + return name_; + } + + /** + * Return object type. + **/ + int getObjectType() { + return objectType_; + } + + /** + * Return path of parent directory. + **/ + String getParent() { + return parent_; + } + + /** + * Return restart ID. + **/ + byte[] getRestartID() { + return restartID_; + } + + /** + * Return size. + **/ + long getSize() + { + return size_; + } + + /** + * Return isSymbolicLink_ + **/ + boolean isSymbolicLink() { + return isSymbolicLink_; + } + + /** + * Return File system type + */ + int getFileSystemType() { + return fileSystemType_; + } + + /** + * @return Owner name + */ + String getOwnerName() { + return ownerName_; + } + + /** + * @return File ASP + */ + int getFileAsp() { + return fileAsp_; + } + + /** + * @return File data CCSID + */ + int getFileDataCcsid() { + return fileDataCCSID_; + } + + public String getDescription() { + return description_; + } } diff --git a/src/main/java/com/ibm/as400/access/IFSFile.java b/src/main/java/com/ibm/as400/access/IFSFile.java index 1b4124ee..135571f4 100644 --- a/src/main/java/com/ibm/as400/access/IFSFile.java +++ b/src/main/java/com/ibm/as400/access/IFSFile.java @@ -125,8 +125,7 @@ * @see IFSFileWriter **/ -public class IFSFile - implements Serializable, Comparable // @B9c +public class IFSFile implements Serializable, Comparable { static final long serialVersionUID = 4L; @@ -183,542 +182,408 @@
Using POSIX semantics, all files are listed that match the pattern and do no transient private VetoableChangeSupport vetos_; transient private Vector fileListeners_; transient private IFSFileImpl impl_; - transient private ServiceProgramCall servicePgm_; private AS400 system_; private String path_ = ""; // Note: This is never allowed to be null. - private Permission permission_; //@A6A + + private Permission permission_; private String subType_; - //@D2C Changed IFSListAttrsRep to IFSCachedAttributes - transient private IFSCachedAttributes cachedAttributes_;//@A7A - private boolean isDirectory_; //@A7A - private boolean isFile_; //@A7A + transient private IFSCachedAttributes cachedAttributes_; + private boolean isDirectory_; + private boolean isFile_; private boolean isSymbolicLink_; private int patternMatching_; // type of pattern matching to use when listing files private boolean sortLists_; // whether file-lists are returned from the File Server in sorted order - // Several pieces of member data set by listFiles0() for IFSFileEnumeration @D5A - // to indicate the number of objects returned from the IFS File Server and @D5A - // also the restartName and restartID info of the last object returned. @D5A - private int listFiles0LastNumObjsReturned_; //@D5A - private String listFiles0LastRestartName_=null; //@D5A - private byte[] listFiles0LastRestartID_; //@D5A + // Several pieces of member data set by listFiles0() for IFSFileEnumeration + // to indicate the number of objects returned from the IFS File Server and + // also the restartName and restartID info of the last object returned. + private int listFiles0LastNumObjsReturned_; + private String listFiles0LastRestartName_=null; + private byte[] listFiles0LastRestartID_; /** - Constructs an IFSFile object. - It creates a default IFSFile instance. + * Constructs an IFSFile object. It creates a default IFSFile instance. **/ - public IFSFile() - { - initializeTransient(); + public IFSFile() { + initializeTransient(); } - /** - Constructs an IFSFile object. - It creates an IFSFile instance that represents the integrated file system - object on system that has a path name of directory, that is - followed by the separator character and name. - @param system The system that contains the file. - @param directory The directory. - @param name The file name. + * Constructs an IFSFile object. It creates an IFSFile instance that represents the integrated file system object on + * system that has a path name of directory, that is followed by the separator character and + * name. + * + * @param system The system that contains the file. + * @param directory The directory. + * @param name The file name. **/ - public IFSFile(AS400 system, - IFSFile directory, - String name) + public IFSFile(AS400 system, IFSFile directory, String name) { - // Validate arguments. - if (system == null) - throw new NullPointerException("system"); - if (directory == null) - throw new NullPointerException("directory"); - else if (name == null) - throw new NullPointerException("name"); + if (system == null) + throw new NullPointerException("system"); + if (directory == null) + throw new NullPointerException("directory"); + else if (name == null) + throw new NullPointerException("name"); - initializeTransient(); - - // Build the file's full path name. - path_ = directory.getAbsolutePath(); - if (path_.charAt(path_.length() - 1) != separatorChar) - { - // Append a separator character. - path_ += separator; - } - path_ += name; - - system_ = system; - - // @A6A Add permission property. - permission_ = null; + initialize(system, directory.getAbsolutePath(), name); } - /** - Constructs an IFSFile object. - It creates an IFSFile instance that represents the integrated file system - object on system that has a path name of path. - @param system The system that contains the file. - @param path The absolute path name of the file. + * Constructs an IFSFile object. It creates an IFSFile instance that represents the integrated file system object on + * system that has a path name of path. + * + * @param system The system that contains the file. + * @param path The absolute path name of the file. **/ - public IFSFile(AS400 system, - String path) + public IFSFile(AS400 system, String path) { - // Validate arguments. - if (system == null) - throw new NullPointerException("system"); - else if (path == null) - throw new NullPointerException("path"); - - initializeTransient(); + if (system == null) + throw new NullPointerException("system"); + else if (path == null) + throw new NullPointerException("path"); - // If the specified path doesn't start with the separator character, - // add one. All paths are absolute for IFS. - if (path.length() == 0 || path.charAt(0) != separatorChar) - { - path_ = separator + path; - } - else - { - path_ = path; - } - - system_ = system; + initialize(system, null, path); } - /** - Constructs an IFSFile object. - It creates an IFSFile instance that represents the integrated file system - object on system that has a - path name is of directory, followed by the separator character - and name. - @param system The system that contains the file. - @param directory The directory path name. - @param name The file name. + * Constructs an IFSFile object. It creates an IFSFile instance that represents the integrated file system object on + * system that has a path name is of directory, followed by the separator character and name. + * + * @param system The system that contains the file. + * @param directory The directory path name. + * @param name The file name. + **/ + public IFSFile(AS400 system, String directory, String name) + { + if (system == null) + throw new NullPointerException("system"); + else if (directory == null) + throw new NullPointerException("directory"); + else if (name == null) + throw new NullPointerException("name"); + + initialize(system, directory, name); + } + + /** + * Creates a new IFSFile instance from a parent abstract pathname and a child pathname string. + *

+ * The directory argument cannot be null. The constructed IFSFile instance uses the following settings taken + * from directory: + *

+ * The resulting file name is taken from the path name of directory, followed by the separator character, + * followed by name. + * + * @param directory The directory where the IFSFile is or will be stored. + * @param name The name of the IFSFile object. **/ - public IFSFile(AS400 system, - String directory, - String name) + public IFSFile(IFSFile directory, String name) { - // Validate arguments. - if (system == null) - throw new NullPointerException("system"); - else if (directory == null) - throw new NullPointerException("directory"); - else if (name == null) - throw new NullPointerException("name"); - initialize(system,directory,name); - + if (directory == null) + throw new NullPointerException("directory"); + + initialize(directory.getSystem(), directory.getPath(), name); } - private void initialize(AS400 system, String directory, String name) { - initializeTransient(); - - // Build the file's full path name. Prepend a separator character - // to the directory name if there isn't one already. All paths - // are absolute in IFS. - if (directory.length() == 0 || directory.charAt(0) != separatorChar) - { - path_ = separator + directory; - } - else - { - path_ = directory; - } - if (path_.charAt(path_.length() - 1) != separatorChar) - { - // Append a separator character. - path_ += separator; - } - path_ += name; - - system_ = system; + /** + * Constructs an IFSFile object. It creates an IFSFile instance that represents the integrated file system object on + * system that has a path name of directory, that is followed by the separator character and + * name. + * + * @param system The system that contains the file. + * @param directory The directory. + * @param name The file name. + **/ + public IFSFile(AS400 system, IFSJavaFile directory, String name) + { + if (system == null) + throw new NullPointerException("system"); + else if (directory == null) + throw new NullPointerException("directory"); + else if (name == null) + throw new NullPointerException("name"); + + initialize(system, directory.getAbsolutePath().replace(File.separatorChar, separatorChar), name); } + private void initialize(AS400 system, String directory, String name) + { + initializeTransient(); + + path_ = normalizePath(directory, name); + system_ = system; + } /** - Constructs an IFSFile object. - It creates an IFSFile instance that represents the integrated file system - object on system that has a path name of directory, that is - followed by the separator character and name. - @param system The system that contains the file. - @param directory The directory. - @param name The file name. + * INTERNAL USE ONLY - SUBJECT TO CHANGE + * + * Constructs an IFSFile object. It creates an IFSFile instance that represents the integrated file system object on + * system that has a path name of directory, that is followed by the separator character and + * name. {@link #isDirectory() isDirectory} and {@link #isFile() isFile} will both return false for invalid + * symbolic links. + * + * @param system The system that contains the file. + * @param attributes The attributes of the file. **/ - // @A4A - public IFSFile(AS400 system, - IFSJavaFile directory, - String name) + IFSFile(AS400 system, IFSCachedAttributes attributes) { - - // Validate arguments. - if (system == null) - throw new NullPointerException("system"); - else if (directory == null) - throw new NullPointerException("directory"); - else if (name == null) - throw new NullPointerException("name"); - initialize(system, directory, name); - } - - private void initialize(AS400 system, IFSJavaFile directory, String name) { - initializeTransient(); - - // Build the file's full path name. - path_ = directory.getAbsolutePath().replace (File.separatorChar, separatorChar); - if (path_.charAt(path_.length() - 1) != separatorChar) - { - // Append a separator character. - path_ += separator; - } - path_ += name; - - system_ = system; - } - - - //@A7A Added new IFSFile method to support caching file attributes. - /** - Constructs an IFSFile object. - It creates an IFSFile instance that represents the integrated file system object - on system that has a path name of directory, that is followed by the - separator character and name. - {@link #isDirectory() isDirectory} and {@link #isFile() isFile} will both return false - for invalid symbolic links. - @param system The system that contains the file. - @param attributes The attributes of the file. - **/ - IFSFile(AS400 system, IFSCachedAttributes attributes) //@D2C - Use IFSCachedAttributes - { - // Validate arguments. - if (attributes == null) - throw new NullPointerException("attributes"); - - initializeTransient(); - - String directory = attributes.getParent(); //@D2C - Use IFSCachedAttributes - String name = attributes.getName(); //@D2C - Use IFSCachedAttributes - - // Build the file's full path name. Prepend a separator character - // to the directory name if there isn't one already. All paths - // are absolute in IFS. - StringBuffer buff = new StringBuffer(); - if (directory.length() == 0 || directory.charAt(0) != separatorChar) - { - buff.append(separator).append(directory); - } - else - { - buff.append(directory); - } - if (buff.toString().charAt(buff.toString().length() - 1) != separatorChar) - { - // Append a separator character. - buff.append(separator); - } - - path_ = buff.append(name).toString(); - - system_ = system; - - // Cache file attributes. - cachedAttributes_ = attributes; - //isDirectory and isFile can both be false if the object is an invalid - //symbolic link. - isDirectory_ = attributes.getIsDirectory(); - isFile_ = attributes.getIsFile(); - isSymbolicLink_ = attributes.isSymbolicLink(); - } + // Validate arguments. + if (attributes == null) + throw new NullPointerException("attributes"); -/** - * Creates a new IFSFile instance from a parent abstract pathname and a child pathname string. - *

- * The directory argument cannot be null. The constructed - * IFSFile instance uses the following settings taken from - * directory: - *

- * The resulting file name is taken from the path name of directory, - * followed by the separator character, followed by name. - * - * @param directory The directory where the IFSFile is or will be stored. - * @param name The name of the IFSFile object. -**/ - public IFSFile(IFSFile directory, String name) - { - if (directory == null) - throw new NullPointerException("directory"); - - initialize(directory.getSystem(), directory.getPath(),name); - } + initialize(system, attributes.getParent(), attributes.getName()); + // Cache file attributes. + cachedAttributes_ = attributes; + + //isDirectory and isFile can both be false if the object is an invalid symbolic link. + isDirectory_ = attributes.getIsDirectory(); + isFile_ = attributes.getIsFile(); + isSymbolicLink_ = attributes.isSymbolicLink(); + } /** - Adds a file listener to receive file events from this IFSFile. - @param listener The file listener. + * Adds a file listener to receive file events from this IFSFile. + * + * @param listener The file listener. **/ public void addFileListener(FileListener listener) { - if (listener == null) - throw new NullPointerException("listener"); + if (listener == null) + throw new NullPointerException("listener"); fileListeners_.addElement(listener); } /** - Adds a property change listener. - @param listener The property change listener to add. + * Adds a property change listener. + * + * @param listener The property change listener to add. **/ public void addPropertyChangeListener(PropertyChangeListener listener) { - if (listener == null) - throw new NullPointerException("listener"); + if (listener == null) + throw new NullPointerException("listener"); - changes_.addPropertyChangeListener(listener); + changes_.addPropertyChangeListener(listener); } /** - Adds a vetoable change listener. - @param listener The vetoable change listener to add. + * Adds a vetoable change listener. + * + * @param listener The vetoable change listener to add. **/ public void addVetoableChangeListener(VetoableChangeListener listener) { - if (listener == null) - throw new NullPointerException("listener"); + if (listener == null) + throw new NullPointerException("listener"); - vetos_.addVetoableChangeListener(listener); + vetos_.addVetoableChangeListener(listener); } - /** - Determines if the application is allowed to execute the integrated file system - object represented by this object. - This method is supported for IBM i V5R1 and higher. For older releases, it simply returns false. - If the user profile has *ALLOBJ special authority (and system is V5R1 or higher), this method always returns true. - @return true if the object exists and is executable by the application; false otherwise. - * @throws IOException If an error occurs while communicating with the system. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. + * Determines if the application is allowed to execute the integrated file system object represented by this object. + * This method is supported for IBM i V5R1 and higher. For older releases, it simply returns false. If the user + * profile has *ALLOBJ special authority (and system is V5R1 or higher), this method always returns true. + * + * @return true if the object exists and is executable by the application; false otherwise. + * @throws IOException If an error occurs while communicating with the system. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. **/ - public boolean canExecute() - throws IOException + public boolean canExecute() throws IOException { - try - { - // Note: The called API (QlgAccess) is supported for V5R1 and higher. - if (impl_ == null) - chooseImpl(); - - return impl_.canExecute(); - } - catch (AS400SecurityException e) - { - // If we got the exception simply because we don't have "execute" access, ignore it. - if (e.getReturnCode() == AS400SecurityException.DIRECTORY_ENTRY_ACCESS_DENIED) + try { - // Assume it's already been traced. - return false; + // Note: The called API (QlgAccess) is supported for V5R1 and higher. + if (impl_ == null) + chooseImpl(); + + return impl_.canExecute(); } - else // some other return code + catch (AS400SecurityException e) { - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); + // If we got the exception simply because we don't have "execute" access, ignore it. + if (e.getReturnCode() == AS400SecurityException.DIRECTORY_ENTRY_ACCESS_DENIED) + return false; + + // some other return code + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); } - } } - /** - Determines if the application can read from the integrated file system - object represented by this object. - Note that IBM i directories are never readable; only files can be readable. - @return true if the object exists and is readable by the application; false otherwise. - * @throws IOException If an error occurs while communicating with the system. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. + * Determines if the application can read from the integrated file system object represented by this object. Note that + * IBM i directories are never readable; only files can be readable. + * + * @return true if the object exists and is readable by the application; false otherwise. + * @throws IOException If an error occurs while communicating with the system. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. **/ - public boolean canRead() - throws IOException + public boolean canRead() throws IOException { - try - { - if (impl_ == null) - chooseImpl(); - - return impl_.canRead(); - } - catch (AS400SecurityException e) - { - // If we got the exception simply because we don't have "read" access, ignore it. - if (e.getReturnCode() == AS400SecurityException.DIRECTORY_ENTRY_ACCESS_DENIED) + try { - // Assume it's already been traced. - return false; + if (impl_ == null) + chooseImpl(); + + return impl_.canRead(); } - else // some other return code + catch (AS400SecurityException e) { - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); + // If we got the exception simply because we don't have "read" access, ignore it. + if (e.getReturnCode() == AS400SecurityException.DIRECTORY_ENTRY_ACCESS_DENIED) + return false; + + // some other return code + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); } - } } - /** - Determines if the application can write to the integrated file system - object represented by this object. - Note that IBM i directories are never writable; only files can be writable. - @return true if the object exists and is writeable by the application; false otherwise. - * @throws IOException If an error occurs while communicating with the system. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - + * Determines if the application can write to the integrated file system object represented by this object. Note that + * IBM i directories are never writable; only files can be writable. + * + * @return true if the object exists and is writeable by the application; false otherwise. + * @throws IOException If an error occurs while communicating with the system. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + * **/ - public boolean canWrite() - throws IOException + public boolean canWrite() throws IOException { - try - { - if (impl_ == null) - chooseImpl(); - - return impl_.canWrite(); - } - catch (AS400SecurityException e) - { - // If we got the exception simply because we don't have "write" access, ignore it. - if (e.getReturnCode() == AS400SecurityException.DIRECTORY_ENTRY_ACCESS_DENIED) + try { - // Assume it's already been traced. - return false; + if (impl_ == null) + chooseImpl(); + + return impl_.canWrite(); } - else // some other return code + catch (AS400SecurityException e) { - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); + // If we got the exception simply because we don't have "write" access, ignore it. + if (e.getReturnCode() == AS400SecurityException.DIRECTORY_ENTRY_ACCESS_DENIED) + return false; + + // some other return code + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); } - } } - /** - Chooses the appropriate implementation. - **/ - void chooseImpl() - throws IOException, AS400SecurityException + /* + * INTERNAL USE ONLY - SUBJECT TO CHANGE + * + * Chooses the appropriate implementation. + */ + void chooseImpl() throws IOException, AS400SecurityException { - if (impl_ == null) - { - // Ensure that the system has been set. - if (system_ == null) - { - throw new ExtendedIllegalStateException("system", - ExtendedIllegalStateException.PROPERTY_NOT_SET); - } + if (impl_ != null) + return; + + // Ensure that the system has been set. + if (system_ == null) + throw new ExtendedIllegalStateException("system", ExtendedIllegalStateException.PROPERTY_NOT_SET); - // Ensure that the path name is set. - if (path_.length() == 0) - { - throw new ExtendedIllegalStateException("path", - ExtendedIllegalStateException.PROPERTY_NOT_SET); - } + // Ensure that the path name is set. + if (path_.length() == 0) + throw new ExtendedIllegalStateException("path", ExtendedIllegalStateException.PROPERTY_NOT_SET); - impl_ = (IFSFileImpl) system_.loadImpl2 - ("com.ibm.as400.access.IFSFileImplRemote", - "com.ibm.as400.access.IFSFileImplProxy"); - system_.connectService(AS400.FILE); - impl_.setSystem(system_.getImpl()); - impl_.setPath(path_); - } + impl_ = (IFSFileImpl) system_.loadImpl2("com.ibm.as400.access.IFSFileImplRemote", + "com.ibm.as400.access.IFSFileImplProxy"); + + system_.connectService(AS400.FILE); + impl_.setSystem(system_.getImpl()); + impl_.setPath(path_); } - - -// @D6A /** - Clear the cached attributes. This is needed when cached attributes - need to be refreshed. - - @see #listFiles - **/ + * Clear the cached attributes. This is needed when cached attributes need to be refreshed. + * + * @see #listFiles + **/ public void clearCachedAttributes() { cachedAttributes_ = null; - if (impl_ != null) //@D8A - { - impl_.clearCachedAttributes(); //@D8A - } + if (impl_ != null) + impl_.clearCachedAttributes(); } - - -// @B9a -/** - * Compares the path of this IFSFile with an Object's path. - * If the other object is not an IFSFile or java.io.File, - * this method throws a ClassCastException, since - * IFSFile is comparable only to IFSFile and java.io.File. - * - *

Note:
The comparison is case sensitive. - * - * @param obj The Object to be compared. - * - * @return 0 if this IFSFile path equals the argument's path; - * a value less than 0 if this IFSFile path is less than the argument's - * path; and a value greater than 0 if this IFSFile path is greater - * than the argument's path. - * -**/ + /** + * Compares the path of this IFSFile with an Object's path. If the other object is not an IFSFile or + * java.io.File, this method throws a ClassCastException, since IFSFile is comparable only to IFSFile and + * java.io.File. + * + *

+ * Note:
+ * The comparison is case sensitive. + * + * @param obj The Object to be compared. + * + * @return 0 if this IFSFile path equals the argument's path; a value less than 0 if this + * IFSFile path is less than the argument's path; and a value greater than 0 if this IFSFile path + * is greater than the argument's path. + * + **/ + @Override public int compareTo(Object obj) { - if (obj instanceof IFSFile) - return getPath().compareTo(((IFSFile)obj).getPath()); - else + if (obj instanceof IFSFile) + return getPath().compareTo(((IFSFile)obj).getPath()); + return getPath().compareTo(((java.io.File)obj).getPath()); } - /** - * Copies this file or directory to the specified file or directory - * on the system. - * If the destination file already exists, it is overwritten. - * If this IFSFile represents a directory: + * Copies this file or directory to the specified file or directory on the system. If the destination file already + * exists, it is overwritten. If this IFSFile represents a directory: *

- * @param path The destination path to copy this IFSFile to. - *
If the system is V5R2 or earlier: If the current object is a file (rather than a directory), the destination path must also specify a file (rather than a directory), otherwise the copy may fail. - * @return true if the copy succeeded (or at least one file of a source - * directory's contents was copied); false otherwise. - * @throws IOException If an error occurs while communicating with the system. - * @throws AS400SecurityException If a security or authority error occurs. - * @throws ObjectAlreadyExistsException If the object already exists. - **/ + * + * @param path The destination path to copy this IFSFile to.
+ * If the system is V5R2 or earlier: If the current object is a file (rather than a directory), the + * destination path must also specify a file (rather than a directory), otherwise the copy may fail. + * @return true if the copy succeeded (or at least one file of a source directory's contents was copied); false + * otherwise. + * @throws IOException If an error occurs while communicating with the system. + * @throws AS400SecurityException If a security or authority error occurs. + * @throws ObjectAlreadyExistsException If the object already exists. + **/ public boolean copyTo(String path) throws IOException, AS400SecurityException, ObjectAlreadyExistsException { - return copyTo(path, true); + return copyTo(path, true); } /** + * INTERNAL USE ONLY - SUBJECT TO CHANGE + * * Copies this file or directory to the specified file or directory * on the system. * If the destination file already exists: @@ -743,72 +608,67 @@ public boolean copyTo(String path) throws IOException, AS400SecurityException, O // Wait until we have better support from the File Server. boolean copyTo(String path, boolean replace) throws IOException, AS400SecurityException, ObjectAlreadyExistsException { - if (path == null) throw new NullPointerException("path"); - if (impl_ == null) chooseImpl(); - return impl_.copyTo(path, replace); - } - - - /** - Determines the time that the integrated file system object represented by this - object was created. - @return The time (measured in milliseconds since 01/01/1970 00:00:00 GMT) - that the integrated file system object was created, or 0L if - the object does not exist or is not accessible. - * @throws IOException If an error occurs while communicating with the system. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - - **/ - public long created() //D3a - throws IOException //D3a - { //D3a - try //D3a - { //D3a - //@A7A Added check for cached attributes. //@D3a - if (cachedAttributes_ != null) //@D3a - { //@D3a - return cachedAttributes_.getCreationDate(); //@D3a - } //@D3a - else //@D3a - { //@D3a - if (impl_ == null) //@D3a - chooseImpl(); //@D3a - //@D3a - return impl_.created(); //@D3a - } //@D3a - } //D3a - catch (AS400SecurityException e) //D3a - { //D3a - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); //D3a - //return 0L; //D3a @B6d - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); // @B6a - } //D3a - } //D3a - - - /** - Atomically creates a new, empty file named by this abstract pathname if and only if a file with this name does not yet exist. - The check for the existence of the file and the creation of the file if it does not exist are a single operation that is atomic with respect to all other filesystem activities that might affect the file. - If the file already exists, its data are left intact. - @return true if the named file does not exist and was successfully created; false if the named file already exists. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - @exception IOException If the user is not authorized to create the file. - **/ - // @D1 - new method because of changes to java.io.File in Java 2. - public boolean createNewFile() - throws IOException + if (path == null) + throw new NullPointerException("path"); + if (impl_ == null) + chooseImpl(); + + return impl_.copyTo(path, replace); + } + + /** + * Determines the time that the integrated file system object represented by this object was created. + * + * @return The time (measured in milliseconds since 01/01/1970 00:00:00 GMT) that the integrated file system object + * was created, or 0L if the object does not exist or is not accessible. + * @throws IOException If an error occurs while communicating with the system. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + * + **/ + public long created() throws IOException + { + try + { + if (cachedAttributes_ != null) + return cachedAttributes_.getCreationDate(); + + if (impl_ == null) + chooseImpl(); + + return impl_.created(); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); + } + } + + + /** + * Atomically creates a new, empty file named by this abstract pathname if and only if a file with this name does not + * yet exist. The check for the existence of the file and the creation of the file if it does not exist are a single + * operation that is atomic with respect to all other filesystem activities that might affect the file. If the file + * already exists, its data are left intact. + * + * @return true if the named file does not exist and was successfully created; false if the named + * file already exists. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + * @exception IOException If the user is not authorized to create the file. + **/ + public boolean createNewFile() throws IOException { int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; + try { if (impl_ == null) @@ -834,438 +694,413 @@ public boolean createNewFile() catch (AS400SecurityException e) { Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); // @B6a + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); } + return (returnCode == IFSReturnCodeRep.SUCCESS); } - - -//internal delete that returns a return code status indicator - int delete0() - throws IOException, AS400SecurityException + /* + * INTERNAL USE ONLY - SUBJECT TO CHANGE + * + * internal delete that returns a return code status indicator + */ + int delete0() throws IOException, AS400SecurityException { - if (impl_ == null) - chooseImpl(); + if (impl_ == null) + chooseImpl(); - int rc = impl_.delete(); + int rc = impl_.delete(); - // Verify that the request was successful. - if (rc == IFSReturnCodeRep.SUCCESS) - { - // Fire the file deleted event. - if (fileListeners_.size() != 0) + // Verify that the request was successful. + if (rc == IFSReturnCodeRep.SUCCESS) { - FileEvent event = new FileEvent(this, FileEvent.FILE_DELETED); - synchronized(fileListeners_) - { - Enumeration e = fileListeners_.elements(); - while (e.hasMoreElements()) + // Fire the file deleted event. + if (fileListeners_.size() != 0) { - FileListener listener = (FileListener)e.nextElement(); - listener.fileDeleted(event); + FileEvent event = new FileEvent(this, FileEvent.FILE_DELETED); + synchronized (fileListeners_) + { + Enumeration e = fileListeners_.elements(); + while (e.hasMoreElements()) + { + FileListener listener = (FileListener) e.nextElement(); + listener.fileDeleted(event); + } + } } - } - } - // Clear any cached attributes. - cachedAttributes_ = null; //@A7a - } + // Clear any cached attributes. + cachedAttributes_ = null; + } - return rc; + return rc; } /** - Deletes the integrated file system object represented by this object. - - @return true if the file system object is successfully deleted; false otherwise. - Returns false if the file system object did not exist prior to the delete() or is not accessible. - * @throws IOException If an error occurs while communicating with the system. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - + * Deletes the integrated file system object represented by this object. + * + * @return true if the file system object is successfully deleted; false otherwise. Returns false if the file system + * object did not exist prior to the delete() or is not accessible. + * @throws IOException If an error occurs while communicating with the system. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + * **/ - public boolean delete() - throws IOException + public boolean delete() throws IOException { - // If it looks like it's in QSYS, then the stream file operation to the host server will likely not work. For - // files and members, though, we can handle specially here. - if(isInQsys()) { - AS400File tmpPF = null; - ObjectDescription objectDescription = new ObjectDescription(system_, path_.replaceAll("//+", "/")); - try { - String type = objectDescription.getType(); - switch (type) { - case "FILE": //note: includes *SAVF objects - tmpPF = new SequentialFile(system_, objectDescription.getPath()); - tmpPF.delete(); - return true; - case "MBR": - tmpPF = new SequentialFile(system_, objectDescription.getPath()); - tmpPF.deleteMember(); - return true; - } - } catch (AS400SecurityException | InterruptedException | IOException | ErrorCompletingRequestException e) { - Trace.log( - Trace.WARNING, "Unable to delete QSYS file using classic techniques. Will try host server stream file operations."+path_, e); - } finally { - if(null != tmpPF) { - try { - tmpPF.close(); - } catch (AS400Exception | AS400SecurityException | InterruptedException | IOException e) { - Trace.log(Trace.ERROR, "Unexpected error closing file "+path_, e); + // If it looks like it's in QSYS, then the stream file operation to the host server will likely not work. For + // files and members, though, we can handle specially here. + if(isInQsys()) + { + AS400File tmpPF = null; + ObjectDescription objectDescription = new ObjectDescription(system_, path_.replaceAll("//+", "/")); + try + { + String type = objectDescription.getType(); + switch (type) + { + case "FILE": //note: includes *SAVF objects + tmpPF = new SequentialFile(system_, objectDescription.getPath()); + tmpPF.delete(); + return true; + case "MBR": + tmpPF = new SequentialFile(system_, objectDescription.getPath()); + tmpPF.deleteMember(); + return true; + } } - } + catch (AS400SecurityException | InterruptedException | IOException | ErrorCompletingRequestException e) { + Trace.log(Trace.WARNING, "Unable to delete QSYS file using classic techniques. Will try host server stream file operations."+path_, e); + } + finally + { + if(null != tmpPF) + { + try { + tmpPF.close(); + } + catch (AS400Exception | AS400SecurityException | InterruptedException | IOException e) { + Trace.log(Trace.ERROR, "Unexpected error closing file "+path_, e); + } + } + } + } + + int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; + try { + returnCode = delete0(); + } + catch (AS400SecurityException e) + { + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); } - } - int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; - try - { - returnCode = delete0(); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - // returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; //@A7D Unnecessary assignment. - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); // @B6a - } - return (returnCode == IFSReturnCodeRep.SUCCESS); + + return (returnCode == IFSReturnCodeRep.SUCCESS); } - - // @D4A - /** - Lists the integrated file system objects in the directory represented by this - object that satisfy filter. The returned Enumeration contains an IFSFile - object for each file or directory in the list. The list is loaded incrementally, - which will improve initial response time for large lists. - - @param filter A file object filter. - @param pattern The pattern that all filenames must match. Acceptable - characters are wildcards (*) and question marks (?). - - @return An Enumeration of IFSFile objects which represent the contents of the directory that satisfy the filter - and pattern. This Enumeration does not include the current directory or the parent - directory. If this object does not represent a directory, - this object represents an empty directory, or the filter or pattern does - not match any files, then an empty Enumeration is returned. The IFSFile object - passed to the filter object has cached file attribute information. - * @throws IOException If an error occurs while communicating with the system. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system, or the directory is not accessible. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. + /** + * Lists the integrated file system objects in the directory represented by this object that satisfy filter. + * The returned Enumeration contains an IFSFile object for each file or directory in the list. The list is loaded + * incrementally, which will improve initial response time for large lists. + * + * @param filter A file object filter. + * @param pattern The pattern that all filenames must match. Acceptable characters are wildcards (*) and question + * marks (?). + * + * @return An Enumeration of IFSFile objects which represent the contents of the directory that satisfy the filter and + * pattern. This Enumeration does not include the current directory or the parent directory. If this object + * does not represent a directory, this object represents an empty directory, or the filter or pattern does + * not match any files, then an empty Enumeration is returned. The IFSFile object passed to the filter object + * has cached file attribute information. + * @throws IOException If an error occurs while communicating with the system. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system, or the directory is + * not accessible. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. **/ - public Enumeration enumerateFiles(IFSFileFilter filter, String pattern) - throws IOException + public Enumeration enumerateFiles(IFSFileFilter filter, String pattern) throws IOException { // Validate arguments. Note that we tolerate a null-valued 'filter'. if (pattern == null) - throw new NullPointerException("pattern"); + throw new NullPointerException("pattern"); try { return new IFSFileEnumeration(this, filter, pattern); } - catch (AS400SecurityException e) { - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - //return null; // @B6d - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); // @B6a + catch (AS400SecurityException e) + { + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); } } - -// @D4A - /** - Lists the integrated file system objects in the directory represented by this - object. The returned Enumeration contains an IFSFile - object for each file or directory in the list. The list is loaded incrementally, - which will improve initial response time for large lists. - - @param pattern The pattern that all filenames must match. Acceptable - characters are wildcards (*) and question marks (?). - - @return An Enumeration of IFSFile objects which represent the contents of the directory. - This Enumeration does not include the current directory or the parent - directory. If this object does not represent a directory, - this object represents an empty directory, or the pattern does - not match any files, then an empty Enumeration is returned. - * @throws IOException If an error occurs while communicating with the system. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system, or the directory is not accessible. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - **/ - public Enumeration enumerateFiles(String pattern) - throws IOException + /** + * Lists the integrated file system objects in the directory represented by this object. The returned Enumeration + * contains an IFSFile object for each file or directory in the list. The list is loaded incrementally, which will + * improve initial response time for large lists. + * + * @param pattern The pattern that all filenames must match. Acceptable characters are wildcards (*) and question + * marks (?). + * + * @return An Enumeration of IFSFile objects which represent the contents of the directory. This Enumeration does not + * include the current directory or the parent directory. If this object does not represent a directory, this + * object represents an empty directory, or the pattern does not match any files, then an empty Enumeration is + * returned. + * @throws IOException If an error occurs while communicating with the system. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system, or the directory is + * not accessible. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + **/ + public Enumeration enumerateFiles(String pattern) throws IOException { // Validate arguments. Note that we tolerate a null-valued 'filter'. if (pattern == null) - throw new NullPointerException("pattern"); + throw new NullPointerException("pattern"); try { - return new IFSFileEnumeration(this, null, pattern); + return new IFSFileEnumeration(this, null, pattern); } - catch (AS400SecurityException e) { - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - //return null; // @B6d - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); // @B6a + catch (AS400SecurityException e) + { + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); } } -// @D4A - /** - Lists the integrated file system objects in the directory represented by this - object that satisfy filter. The returned Enumeration contains an IFSFile - object for each file or directory in the list. The list is loaded incrementally, - which will improve initial response time for large lists. - - @param filter A file object filter. - - @return An Enumeration of IFSFile objects which represent the contents of the directory. - This Enumeration does not include the current directory or the parent - directory. If this object does not represent a directory, - this object represents an empty directory, or the filter does - not match any files, then an empty Enumeration is returned. The IFSFile object - passed to the filter object has cached file attribute information. - * @throws IOException If an error occurs while communicating with the system. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system, or the directory is not accessible. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - **/ - public Enumeration enumerateFiles(IFSFileFilter filter) - throws IOException + /** + * Lists the integrated file system objects in the directory represented by this object that satisfy filter. + * The returned Enumeration contains an IFSFile object for each file or directory in the list. The list is loaded + * incrementally, which will improve initial response time for large lists. + * + * @param filter A file object filter. + * + * @return An Enumeration of IFSFile objects which represent the contents of the directory. This Enumeration does not + * include the current directory or the parent directory. If this object does not represent a directory, this + * object represents an empty directory, or the filter does not match any files, then an empty Enumeration is + * returned. The IFSFile object passed to the filter object has cached file attribute information. + * @throws IOException If an error occurs while communicating with the system. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system, or the directory is + * not accessible. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + **/ + public Enumeration enumerateFiles(IFSFileFilter filter) throws IOException { try { - return new IFSFileEnumeration(this, filter, "*"); + return new IFSFileEnumeration(this, filter, "*"); } - catch (AS400SecurityException e) { - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - // return null; // @B6d - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); // @B6a + catch (AS400SecurityException e) + { + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); } } - -// @D4A - /** - Lists the integrated file system objects in the directory represented by this - object. The returned Enumeration contains an IFSFile - object for each file or directory in the list. The list is loaded incrementally, - which will improve initial response time for large lists. - - @return An Enumeration of IFSFile objects which represent the contents of the directory. - This Enumeration does not include the current directory or the parent - directory. If this object does not represent a directory, - this object represents an empty directory, or the filter or pattern does - not match any files, then an empty Enumeration is returned. - * @throws IOException If an error occurs while communicating with the system. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system, or the directory is not accessible. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - **/ - public Enumeration enumerateFiles() - throws IOException - { - try { - return new IFSFileEnumeration(this, null, "*"); - } - catch (AS400SecurityException e) { - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - // return null; // @B6d - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); // @B6a + /** + * Lists the integrated file system objects in the directory represented by this object. The returned Enumeration + * contains an IFSFile object for each file or directory in the list. The list is loaded incrementally, which will + * improve initial response time for large lists. + * + * @return An Enumeration of IFSFile objects which represent the contents of the directory. This Enumeration does not + * include the current directory or the parent directory. If this object does not represent a directory, this + * object represents an empty directory, or the filter or pattern does not match any files, then an empty + * Enumeration is returned. + * @throws IOException If an error occurs while communicating with the system. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system, or the directory is + * not accessible. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + **/ + public Enumeration enumerateFiles() throws IOException + { + try { + return new IFSFileEnumeration(this, null, "*"); + } + catch (AS400SecurityException e) + { + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); } } - - /** - Determines if two IFSFile objects are equal. - @param obj The object with which to compare. - @return true if the path name and system names of the objects are equal; - false otherwise. + * Determines if two IFSFile objects are equal. + * + * @param obj The object with which to compare. + * @return true if the path name and system names of the objects are equal; false otherwise. **/ + @Override public boolean equals(Object obj) { - if (obj == null || !(obj instanceof IFSFile)) // @A8C - return false; - - // Determine the system name and path name. - IFSFile target = (IFSFile) obj; - String targetPathName = target.getPath(); - AS400 targetSystem = target.getSystem(); - String targetSystemName = null; - if (targetSystem != null) - { - targetSystemName = targetSystem.getSystemName(); - } - - // @A8D - //return (system_ != null && targetSystemName != null && - // path_.equals(targetPathName) && - // system_.getSystemName().equals(targetSystemName)); - - // @A8A: - boolean result = true; - // It's OK for *neither* or *both* objects have system==null. - if (system_ == null) - result = (targetSystemName == null); - else - result = system_.getSystemName().equals(targetSystemName); - result = result && (path_.equals(targetPathName)); - return result; + if (obj == null || !(obj instanceof IFSFile)) + return false; + + // Determine the system name and path name. + IFSFile target = (IFSFile) obj; + String targetPathName = target.getPath(); + AS400 targetSystem = target.getSystem(); + String targetSystemName = null; + if (targetSystem != null) + targetSystemName = targetSystem.getSystemName(); + + boolean result = true; + // It's OK for *neither* or *both* objects have system==null. + if (system_ == null) + result = (targetSystemName == null); + else + result = system_.getSystemName().equals(targetSystemName); + + result = result && (path_.equals(targetPathName)); + + return result; } -//internal exists that returns a return code status indicator - int exists0() - throws IOException, AS400SecurityException + /* + * INTERNAL USE ONLY - SUBJECT TO CHANGE + * + * internal exists that returns a return code status indicator + */ + int exists0() throws IOException, AS400SecurityException { - // Assume the argument has been validated as non-null. + // Assume the argument has been validated as non-null. - if (impl_ == null) - chooseImpl(); + if (impl_ == null) + chooseImpl(); - return impl_.exists(); + return impl_.exists(); } /** - Determines if the integrated file system object represented by this object exists. - @return true if the object exists; false if the object does not exist or is not accessible. - * @throws IOException If an error occurs while communicating with the system. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - + * Determines if the integrated file system object represented by this object exists. + * + * @return true if the object exists; false if the object does not exist or is not accessible. + * @throws IOException If an error occurs while communicating with the system. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + * **/ - public boolean exists() - throws IOException + public boolean exists() throws IOException { - int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; - try - { - returnCode = exists0(); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); // @B6a - } - return (returnCode == IFSReturnCodeRep.SUCCESS); + int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; + try { + returnCode = exists0(); + } + catch (AS400SecurityException e) + { + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); + } + + return (returnCode == IFSReturnCodeRep.SUCCESS); } - - /** - Returns the path name of the integrated file system object represented by - this object. This is the full path starting at the root directory. - @return The absolute path name of this integrated file system object. + * Returns the path name of the integrated file system object represented by this object. This is the full path + * starting at the root directory. + * + * @return The absolute path name of this integrated file system object. **/ - public String getAbsolutePath() - { - return path_; + public String getAbsolutePath() { + return path_; } - /** - Returns the canonical pathname string of the integrated file system - object represented by this object. This is the full path starting - at the root directory. This typically involves removing redundant - names such as "." and ".." from the pathname. - Symbolic links are not resolved. - @return The canonical path name of this integrated file system object. + * Returns the canonical pathname string of the integrated file system object represented by this object. This is the + * full path starting at the root directory. This typically involves removing redundant names such as "." and ".." + * from the pathname. Symbolic links are not resolved. + * + * @return The canonical path name of this integrated file system object. **/ public String getCanonicalPath() { - // Numerous changes added to remove DOT, DOTDOT, and multiple @D4A - // separator characters. Previously, this method simply @D4A - // returned path_ @D4A - StringBuffer pathBuffer = new StringBuffer(""); - String pathElem; + // Numerous changes added to remove DOT, DOTDOT, and multiple + // separator characters. Previously, this method simply returned path_ + + StringBuilder pathBuffer = new StringBuilder(""); + String pathElem; - if (Trace.isTraceOn()) Trace.log(Trace.DIAGNOSTIC, " path_='"+path_+"'"); + if (Trace.isTraceOn()) Trace.log(Trace.DIAGNOSTIC, " path_='"+path_+"'"); - StringTokenizer st = new StringTokenizer(path_, separator); + StringTokenizer st = new StringTokenizer(path_, separator); - // Process each path element. - while (st.hasMoreTokens()) - { - pathElem = st.nextToken(); + // Process each path element. + while (st.hasMoreTokens()) + { + pathElem = st.nextToken(); - if (Trace.isTraceOn()) Trace.log(Trace.DIAGNOSTIC, " pathElem='"+pathElem+"'"); + if (Trace.isTraceOn()) Trace.log(Trace.DIAGNOSTIC, " pathElem='"+pathElem+"'"); - if (pathElem.length() == 0) - { - // pathElem is empty... or is only the separator - // Nothing to add to pathBuffer... - } - else if (pathElem.equals(DOT)) - { - // Remove the "." from the path... copy nothing to pathBuffer. - } - else if (pathElem.equals(DOTDOT)) - { - // Remove last element of current canPath - int lastSepIndex = pathBuffer.lastIndexOf(separator); - if (lastSepIndex == -1) - { - // Can get here if too many DOT-DOTs which would result - // in trying to preceed the root directory.... - // Ignore this path element - } - else - { - // This will remove the last element of canPath - //(e.g. "/abc/xyz" will become "/abc") - pathBuffer.delete(lastSepIndex, pathBuffer.length()); - } - } - else - { - // Normal path element... so append it - pathBuffer.append(separator); - pathBuffer.append(pathElem); + if (pathElem.length() == 0) + { + // pathElem is empty... or is only the separator + // Nothing to add to pathBuffer... + } + else if (pathElem.equals(DOT)) + { + // Remove the "." from the path... copy nothing to pathBuffer. + } + else if (pathElem.equals(DOTDOT)) + { + // Remove last element of current canPath + int lastSepIndex = pathBuffer.lastIndexOf(separator); + if (lastSepIndex == -1) + { + // Can get here if too many DOT-DOTs which would result + // in trying to preceed the root directory.... + // Ignore this path element + } + else + { + // This will remove the last element of canPath + //(e.g. "/abc/xyz" will become "/abc") + pathBuffer.delete(lastSepIndex, pathBuffer.length()); + } + } + else + { + // Normal path element... so append it + pathBuffer.append(separator); + pathBuffer.append(pathElem); + } } - } - if (Trace.isTraceOn()) Trace.log(Trace.DIAGNOSTIC, " pathBuffer.toString()='"+pathBuffer.toString()+"'"); + if (Trace.isTraceOn()) Trace.log(Trace.DIAGNOSTIC, " pathBuffer.toString()='"+pathBuffer.toString()+"'"); - if (pathBuffer.length() == 0) - { - // This is possible if original path_ contains nothing but DOTs and DOTDOTs - return(separator); - } - else - { - return(pathBuffer.toString()); - } + // Return path. Note that 0-length path is possible if path_ contains nothing but DOTs and DOTDOTs + return (pathBuffer.length() == 0) ? separator : pathBuffer.toString(); } - - //@A9a /** - Returns the file's data CCSID. All files in the system's integrated file system - are tagged with a CCSID. This method returns the value of that tag. - If the file is non-existent, returns -1. - If the file is a directory and the authentication scheme is not password, returns -1. - @return The file's CCSID. - @exception IOException If an error occurs while communicating with the system. + * Returns the file's data CCSID. All files in the system's integrated file system are tagged with a CCSID. This + * method returns the value of that tag. If the file is non-existent, returns -1. If the file is a directory and the + * authentication scheme is not password, returns -1. + * + * @return The file's CCSID. + * @exception IOException If an error occurs while communicating with the system. **/ public int getCCSID() throws IOException { @@ -1274,12 +1109,8 @@ public int getCCSID() throws IOException if (impl_ == null) chooseImpl(); - // In 7.5 and prior releases, need to create user handle for IFS tables to be initialized. - // Not sure why only for directories. - if (this.isDirectory() - && (getSystem().getAuthenticationScheme()== AS400.AUTHENTICATION_SCHEME_PASSWORD - || getSystem().getAuthenticationScheme()== AS400.AUTHENTICATION_SCHEME_GSS_TOKEN)) - return impl_.getCCSIDByUserHandle(); + if (!isFile()) + return impl_.getCCSID(); return impl_.getCCSID(true); } @@ -1289,223 +1120,243 @@ public int getCCSID() throws IOException throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); } } - + + /** + * Returns the description of the object. Not all objects have descriptions, in which + * case a zero-length string is returned. + * + * @return description of the object. + * @throws IOException IOException If an error occurs while communicating with the system. + */ + public String getDescription() throws IOException + { + try + { + if (impl_ == null) + chooseImpl(); - //@A6A - /** + return impl_.getDescription(); + } + catch (AS400SecurityException e) + { + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); + } + } + + /** * Returns the full path of the object. + * * @return The full path of the object. * - **/ - public String getFileSystem() - { + **/ + public String getFileSystem() { return getPath(); } - - /** - Returns the amount of unused storage space that is available to the user. - @return The number of bytes of storage available to the user, or special value {@link Long#MAX_VALUE Long.MAX_VALUE} if the system reports "no maximum". - * @throws IOException If an error occurs while communicating with the system. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - + * Returns the amount of unused storage space that is available to the user. + * + * @return The number of bytes of storage available to the user, or special value {@link Long#MAX_VALUE + * Long.MAX_VALUE} if the system reports "no maximum". + * @throws IOException If an error occurs while communicating with the system. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + * **/ - public long getFreeSpace() - throws IOException + public long getFreeSpace() throws IOException { - try - { - if (impl_ == null) - chooseImpl(); + try + { + if (impl_ == null) + chooseImpl(); - return impl_.getAvailableSpace(true); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); - } + return impl_.getAvailableSpace(true); + } + catch (AS400SecurityException e) + { + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); + } } /** - Returns the amount of unused storage space that is available to the user. - @param system The system of interest. - @return The number of bytes of storage available to the user, or special value {@link Long#MAX_VALUE Long.MAX_VALUE} if the system reports "no maximum". - * @throws IOException If an error occurs while communicating with the system. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - + * Returns the amount of unused storage space that is available to the user. + * + * @param system The system of interest. + * @return The number of bytes of storage available to the user, or special value {@link Long#MAX_VALUE + * Long.MAX_VALUE} if the system reports "no maximum". + * @throws IOException If an error occurs while communicating with the system. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + * **/ - public static long getFreeSpace(AS400 system) - throws IOException + public static long getFreeSpace(AS400 system) throws IOException { - if (system == null) { - throw new NullPointerException("system"); - } + if (system == null) + throw new NullPointerException("system"); - try - { - IFSFileImpl impl = (IFSFileImpl) system.loadImpl2 - ("com.ibm.as400.access.IFSFileImplRemote", - "com.ibm.as400.access.IFSFileImplProxy"); - system.connectService(AS400.FILE); - impl.setSystem(system.getImpl()); - impl.setPath("/"); - return impl.getAvailableSpace(true); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - throw new ExtendedIOException(ExtendedIOException.ACCESS_DENIED); - } + try + { + IFSFileImpl impl = (IFSFileImpl) system.loadImpl2("com.ibm.as400.access.IFSFileImplRemote", + "com.ibm.as400.access.IFSFileImplProxy"); + system.connectService(AS400.FILE); + impl.setSystem(system.getImpl()); + impl.setPath("/"); + return impl.getAvailableSpace(true); + } + catch (AS400SecurityException e) + { + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(ExtendedIOException.ACCESS_DENIED); + } } - - - /** - Returns the amount of unused storage space that is available to the user. - Note: If the user profile has a "maximum storage allowed" setting of *NOMAX, then getAvailableSpace(true) returns the same value as getAvailableSpace(false). - @param forUserOnly Whether to report only the space for the user. If false, report space available in the entire file system. - @return The number of bytes of storage available. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - - **/ - long getAvailableSpace(boolean forUserOnly) - throws IOException, AS400SecurityException + /* + * INTERNAL USE ONLY - SUBJECT TO CHANGE + * + * Returns the amount of unused storage space that is available to the user. Note: If the user profile has a "maximum + * storage allowed" setting of *NOMAX, then getAvailableSpace(true) returns the same value as + * getAvailableSpace(false). + * + * @param forUserOnly Whether to report only the space for the user. If false, report space available in the entire + * file system. + * @return The number of bytes of storage available. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + * + */ + long getAvailableSpace(boolean forUserOnly) throws IOException, AS400SecurityException { - if (impl_ == null) - chooseImpl(); + if (impl_ == null) + chooseImpl(); - return impl_.getAvailableSpace(forUserOnly); + return impl_.getAvailableSpace(forUserOnly); } - /** - Returns the total amount of storage space on the file system. - @param forUserOnly Whether to report only the space for the user. If false, report total space in the entire file system. - @return The total number of bytes on the file system. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - + * Returns the total amount of storage space on the file system. + * + * @param forUserOnly Whether to report only the space for the user. If false, report total space in the entire file + * system. + * @return The total number of bytes on the file system. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + * **/ - long getTotalSpace(boolean forUserOnly) - throws IOException, AS400SecurityException + long getTotalSpace(boolean forUserOnly) throws IOException, AS400SecurityException { - if (impl_ == null) - chooseImpl(); + if (impl_ == null) + chooseImpl(); - return impl_.getTotalSpace(forUserOnly); + return impl_.getTotalSpace(forUserOnly); } - IFSFileImpl getImpl() - throws IOException, AS400SecurityException + /* + * INTERNAL USE ONLY - SUBJECT TO CHANGE + */ + IFSFileImpl getImpl() throws IOException, AS400SecurityException { - if (impl_ == null) - chooseImpl(); - return impl_; + if (impl_ == null) + chooseImpl(); + + return impl_; } - // Package scope getter methods to return data set by listFiles0() @D5A - // Number of objects returned by the File Server to listFiles0() and @D5A - // also the restartName and restartID info of the last object returned. @D5A - int getListFiles0LastNumObjsReturned() //@D5A - { //@D5A - return listFiles0LastNumObjsReturned_; //@D5A - } //@D5A - String getListFiles0LastRestartName() //@D5A - { //@D5A - if (listFiles0LastRestartName_ == null) //@D5A - return ""; //@D5A - else //@D5A - return listFiles0LastRestartName_; //@D5A - } //@D5A - byte[] getListFiles0LastRestartID() //@D5A - { //@D5A - return listFiles0LastRestartID_; //@D5A - } //@D5A - + /* + * INTERNAL USE ONLY - SUBJECT TO CHANGE + * + * Package scope getter methods to return data set by listFiles0() + * + * Number of objects returned by the File Server to listFiles0() and + * also the restartName and restartID info of the last object returned. + */ + int getListFiles0LastNumObjsReturned() { + return listFiles0LastNumObjsReturned_; + } + + String getListFiles0LastRestartName() { + return (listFiles0LastRestartName_ == null) ? "" : listFiles0LastRestartName_; + } + + /* + * INTERNAL USE ONLY - SUBJECT TO CHANGE + */ + byte[] getListFiles0LastRestartID() { + return listFiles0LastRestartID_; + } /** - Determines the name of the integrated file system object represented by this object. - @return The name (without directory components). + * Determines the name of the integrated file system object represented by this object. + * + * @return The name (without directory components). **/ public String getName() { - String name = null; + String name = null; - // The name is everything after the last occurrence of the - // file separator character. - // (Unless quoted, e.g. /parent/"/filename", in which case the name is "/filename", quotes included.) - int index = path_.lastIndexOf(separatorChar); - if (index >= 0) - { - if (index < path_.length() - 1) + // The name is everything after the last occurrence of the + // file separator character. + // (Unless quoted, e.g. /parent/"/filename", in which case the name is "/filename", quotes included.) + int index = path_.lastIndexOf(separatorChar); + if (index >= 0) { - name = path_.substring(index + 1); + if (index < path_.length() - 1) + name = path_.substring(index + 1); + else + name = ""; } else + name = path_; + + // If name contains exactly 1 quote, and there's another quote earlier in the path, back up to the separator + // character before the prior quote. + int quoteIndex = name.indexOf('"'); + if (quoteIndex >= 0) // name includes at least 1 quote { - name = ""; - } - } - else - { - name = path_; - } - - // If name contains exactly 1 quote, and there's another quote earlier in the path, back up to the separator character before the prior quote. - int quoteIndex = name.indexOf('"'); - if (quoteIndex >= 0) // name includes at least 1 quote - { - if (quoteIndex == name.lastIndexOf('"')) // we only captured 1 quote - { - int priorQuoteIndex = path_.lastIndexOf('"', index); - if (priorQuoteIndex >= 0) // there's an earlier quote in path - { - int priorSeparatorIndex = path_.lastIndexOf(separatorChar, priorQuoteIndex); - if (priorSeparatorIndex >= 0) // there's a separator prior to 1st quote - { - name = path_.substring(priorSeparatorIndex+1); - } - else // no separator, so back up to beginning of path + if (quoteIndex == name.lastIndexOf('"')) // we only captured 1 quote { - name = path_; + int priorQuoteIndex = path_.lastIndexOf('"', index); + if (priorQuoteIndex >= 0) // there's an earlier quote in path + { + int priorSeparatorIndex = path_.lastIndexOf(separatorChar, priorQuoteIndex); + if (priorSeparatorIndex >= 0) // there's a separator prior to 1st quote + name = path_.substring(priorSeparatorIndex+1); + else // no separator, so back up to beginning of path + name = path_; + } } - } } - } - return name; + return name; } - /** - Returns the name of the user profile that is the owner of the file. - @return The name of the user profile that owns the file, or "" if owner cannot be determined. If the file is a directory, only password authentication scheme is supported. - - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. - @exception ExtendedIOException If the file does not exist. + * Returns the name of the user profile that is the owner of the file. + * + * @return The name of the user profile that owns the file, or "" if owner cannot be determined. If the file is a + * directory, only password authentication scheme is supported. + * + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. + * @exception ExtendedIOException If the file does not exist. **/ public String getOwnerName() throws IOException, AS400SecurityException { @@ -1516,224 +1367,199 @@ public String getOwnerName() throws IOException, AS400SecurityException chooseImpl(); // In 7.5 and prior releases, need to create user handle for IFS tables to be initialized. - // Not sure why only for directories. - if (this.isDirectory() - && (getSystem().getAuthenticationScheme()== AS400.AUTHENTICATION_SCHEME_PASSWORD - || getSystem().getAuthenticationScheme()== AS400.AUTHENTICATION_SCHEME_GSS_TOKEN)) - return impl_.getOwnerNameByUserHandle(false); - - String pathUpperCase = path_.toUpperCase(system_.getLocale()); - if (pathUpperCase.startsWith("/QSYS.LIB") && !pathUpperCase.endsWith(".FILE")) - return impl_.getOwnerNameByUserHandle(); + if (!isFile()) + return (isDirectory()) ? impl_.getOwnerNameByUserHandle(false) : impl_.getOwnerNameByUserHandle(true); return impl_.getOwnerName(true); } - - // @C0a /** - Returns the "user ID number" of the owner of the integrated file system file. - If the file is non-existent or is a directory, returns -1. - @return The file owner's ID number. - @exception IOException If an error occurs while communicating with the system. + * Returns the "user ID number" of the owner of the integrated file system file. + * + * @return The file owner's ID number, or -1 if the file is non-existent or is a directory. + * @exception IOException If an error occurs while communicating with the system. **/ - public long getOwnerUID() - throws IOException + public long getOwnerUID() throws IOException { - // Design note: It would be preferable if we could report the user profile name instead of UID number. However, the File Server doesn't report the user name. FYI: There is a service program (QSYPAPI/getpwuid()) that reports the user profile name associated with a given uid number, but getpwuid returns its results as a pointer to a struct, which our ServiceProgramCall class can't handle at the moment. - long result = -1L; - try - { - if (impl_ == null) - chooseImpl(); - - result = impl_.getOwnerUID(); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); - } - return result; - } - - - // @B7a - /** - Returns the "user ID number" of the owner of the integrated file system file. - If the file is non-existent or is a directory, returns -1. - @return The file owner's ID number. - @exception IOException If an error occurs while communicating with the system. - @deprecated Use getOwnerUID() instead. - **/ // @C0c - public int getOwnerId() - throws IOException - { - // Design note: It would be preferable if we could report the user profile name instead of UID number. However, the File Server doesn't report the user name. FYI: There is a service program (QSYPAPI/getpwuid()) that reports the user profile name associated with a given uid number, but getpwuid returns its results as a pointer to a struct, which our ServiceProgramCall class can't handle at the moment. - 1 Feb 2001 - int result = -1; - try - { - if (impl_ == null) - chooseImpl(); + // Design note: It would be preferable if we could report the user profile name instead of UID number. + // However, the File Server doesn't report the user name. FYI: There is a service program (QSYPAPI/getpwuid()) + // that reports the user profile name associated with a given uid number, but getpwuid returns its results + // as a pointer to a struct, which our ServiceProgramCall class can't handle at the moment. + long result = -1L; + try + { + if (impl_ == null) + chooseImpl(); - result = (int)impl_.getOwnerUID(); // @C0c - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); - } - return result; + result = impl_.getOwnerUID(); + } + catch (AS400SecurityException e) + { + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); + } + + return result; } /** - Returns the path of the parent directory of the integrated file system object - represented by this object. The parent directory is everything in - the path name before the last occurrence of the separator character, - or null if the separator character does not appear in the path name. - @return The parent directory. - @see #getParentFile() + * Returns the "user ID number" of the owner of the integrated file system file. + * + * @return The file owner's ID number, or -1 if the file is non-existent or is a directory. + * @exception IOException If an error occurs while communicating with the system. + * @deprecated Use getOwnerUID() instead. **/ - public String getParent() - { - return getParent(path_); // Note: path_ is never allowed to be null. + @Deprecated + public int getOwnerId() throws IOException { + return (int)getOwnerUID(); } + /** + * Returns the path of the parent directory of the integrated file system object represented by this object. The + * parent directory is everything in the path name before the last occurrence of the separator character, or null if + * the separator character does not appear in the path name. + * + * @return The parent directory. + * @see #getParentFile() + **/ + public String getParent() { + return getParent(path_); // Note: path_ is never allowed to be null. + } - // Returns the parent directory of the file represented by this object. + /* + * INTERNAL USE ONLY - SUBJECT TO CHANGE + * + * Returns the parent directory of the file represented by this object. + */ static String getParent(String directory) { - String parent = null; + String parent = null; - // The parent directory is everything in the pathname before - // the last occurrence of the file separator character. - if (!directory.equals(separator)) - { - if (directory.length() == 0) return null; - int index = directory.lastIndexOf(separatorChar); - if (index <= 0) - { - // This object is in the root. - parent = separator; - } - else if (index == directory.length() - 1) - { - // The path has a trailing separator, ignore it. - return getParent(directory.substring(0, directory.length() - 1)); - } - else + // The parent directory is everything in the pathname before + // the last occurrence of the file separator character. + if (!directory.equals(separator)) { - parent = directory.substring(0, index); + if (directory.length() == 0) + return null; + + int index = directory.lastIndexOf(separatorChar); + if (index <= 0) // root? + parent = separator; + else if (index == directory.length() - 1) + { + // The path has a trailing separator, ignore it. + return getParent(directory.substring(0, directory.length() - 1)); + } + else + parent = directory.substring(0, index); } - } - return parent; + return parent; } /** - Returns the parent directory of the current object. - The parent is the path name before the - last occurrence of the separator character. - Null is returned if the separator character does not appear in the path, - or if the current object is the file system root. - If the system property is not yet set in the current object, - then the system property will not be set in the returned object. - - @return an IFSJavaFile object representing the - parent directory if one exists; null otherwise. - - @see #getParent() + * Returns the parent directory of the current object. The parent is the path name before the last occurrence of the + * separator character. Null is returned if the separator character does not appear in the path, or if the current + * object is the file system root. If the system property is not yet set in the current object, then the + * system property will not be set in the returned object. + * + * @return an IFSJavaFile object representing the parent directory if one exists; null otherwise. + * + * @see #getParent() **/ public IFSFile getParentFile() { - String parentPath = getParent(); + String parentPath = getParent(); - if (parentPath == null) - return null; + if (parentPath == null) + return null; - if (system_ == null) - { - IFSFile parent = new IFSFile(); - try { parent.setPath(parentPath); } - catch (PropertyVetoException e) { // will never happen - throw new InternalErrorException(InternalErrorException.UNEXPECTED_EXCEPTION, e); + if (system_ == null) + { + IFSFile parent = new IFSFile(); + try { + parent.setPath(parentPath); + } + catch (PropertyVetoException e) { // will never happen + throw new InternalErrorException(InternalErrorException.UNEXPECTED_EXCEPTION, e); + } + + return parent; } - return parent; - } return new IFSFile(system_, parentPath); } - /** - Returns the path of the integrated file system object represented by this object. - @return The integrated file system path name. + * Returns the path of the integrated file system object represented by this object. + * + * @return The integrated file system path name. **/ - public String getPath() - { + public String getPath() { return path_; } - /** - Returns the path of the integrated file system object that is directly pointed to by the symbolic link represented by this object; or null if the file is not a symbolic link or does not exist. -

- This method is not supported for files in the following file systems: -

    -
  • QSYS.LIB -
  • Independent ASP QSYS.LIB -
  • QDLS -
  • QOPT -
  • QNTC -
- - @return The path directly pointed to by the symbolic link, or null if the IFS object is not a symbolic link or does not exist. Depending on how the symbolic link was defined, the path may be either relative or absolute. - - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. + * Returns the path of the integrated file system object that is directly pointed to by the symbolic link represented + * by this object; or null if the file is not a symbolic link or does not exist. + *

+ * This method is not supported for files in the following file systems: + *

    + *
  • QSYS.LIB + *
  • Independent ASP QSYS.LIB + *
  • QDLS + *
  • QOPT + *
  • QNTC + *
+ * + * @return The path directly pointed to by the symbolic link, or null if the IFS object is not a symbolic + * link or does not exist. Depending on how the symbolic link was defined, the path may be either relative or + * absolute. + * + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. **/ - public String getPathPointedTo() - throws IOException, AS400SecurityException + public String getPathPointedTo() throws IOException, AS400SecurityException { - // See if we've already determined that the file isn't a symbolic link. - if (cachedAttributes_ != null && !isSymbolicLink_) return null; + // See if we've already determined that the file isn't a symbolic link. + if (cachedAttributes_ != null && !isSymbolicLink_) + return null; - if (impl_ == null) - chooseImpl(); + if (impl_ == null) + chooseImpl(); - return impl_.getPathPointedTo(); + return impl_.getPathPointedTo(); } - /** - Returns the pattern-matching behavior used when files are listed by any of the list() or listFiles() methods. The default is PATTERN_POSIX. - @return Either {@link #PATTERN_POSIX PATTERN_POSIX}, {@link #PATTERN_POSIX_ALL PATTERN_POSIX_ALL}, or {@link #PATTERN_OS2 PATTERN_OS2} - * @throws IOException If an error occurs while communicating with the system. - @see #setPatternMatching(int) + * Returns the pattern-matching behavior used when files are listed by any of the list() or + * listFiles() methods. The default is PATTERN_POSIX. + * + * @return Either {@link #PATTERN_POSIX PATTERN_POSIX}, {@link #PATTERN_POSIX_ALL PATTERN_POSIX_ALL}, or + * {@link #PATTERN_OS2 PATTERN_OS2} + * @throws IOException If an error occurs while communicating with the system. + * @see #setPatternMatching(int) **/ - public int getPatternMatching() - throws IOException - { - return patternMatching_; + public int getPatternMatching() throws IOException { + return patternMatching_; } - - // @A6A - /** + /** * Returns the permission of the object. + * * @return The permission of the object. * @see #setPermission - * @exception AS400Exception If the system returns an error message. - * @exception AS400SecurityException If a security or authority error occurs. - * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception AS400Exception If the system returns an error message. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. * @exception ErrorCompletingRequestException If an error occurs before the request is completed. - * @exception InterruptedException If this thread is interrupted. - * @exception IOException If an error occurs while communicating with the system. - * @exception ObjectDoesNotExistException If the object does not exist on the system. - * @throws UnsupportedEncodingException If the Character Encoding is not supported. + * @exception InterruptedException If this thread is interrupted. + * @exception IOException If an error occurs while communicating with the system. + * @exception ObjectDoesNotExistException If the object does not exist on the system. + * @throws UnsupportedEncodingException If the Character Encoding is not supported. * @exception UnknownHostException If the system cannot be located. * - **/ + **/ public Permission getPermission() throws AS400Exception, AS400SecurityException, @@ -1745,169 +1571,162 @@ public Permission getPermission() UnsupportedEncodingException { - if (permission_ == null) - { - permission_ = new Permission(this); - } - return permission_; + if (permission_ == null) + permission_ = new Permission(this); + + return permission_; } -// @C3a - // Returns the Restart ID associated with the file, or null if no attributes have been cached. + /* + * INTERNAL USE ONLY - SUBJECT TO CHANGE + * + * Returns the Restart ID associated with the file, or null if no attributes have been cached. + */ byte[] getRestartID() { - if (cachedAttributes_ != null) - { - return cachedAttributes_.getRestartID(); - } - else - { - if (Trace.traceOn_) Trace.log(Trace.ERROR, - "IFSFile.getRestartID() was called when cachedAttributes_==null."); + if (cachedAttributes_ != null) + return cachedAttributes_.getRestartID(); + + if (Trace.traceOn_) Trace.log(Trace.ERROR, "IFSFile.getRestartID() was called when cachedAttributes_==null."); return null; - } } - -// @B5a /** - Returns the subtype of the integrated file system object represented by this object. Some possible values that might be returned include:
- CMNF, DKTF, DSPF, ICFF, LF, PF, PRTF, SAVF, TAPF.
- Note that many file system objects do not have a subtype: for example, - .MBR objects, and any Root, QOpenSys or UDFS object. -
Returns a zero-length string if the object has no subtype. - @return The subtype of the object. - * @throws IOException If an error occurs while communicating with the system. - - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception AS400SecurityException If a security or authority error occurs. + * Returns the subtype of the integrated file system object represented by this object. Some possible values that + * might be returned include:
+ * CMNF, DKTF, DSPF, ICFF, LF, PF, PRTF, SAVF, TAPF.
+ * Note that many file system objects do not have a subtype: for example, .MBR objects, and any Root, + * QOpenSys or UDFS object. + * + * @return The subtype of the object, or a zero-length string if the object has no subtype. + * @throws IOException If an error occurs while communicating with the system. + * + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception AS400SecurityException If a security or authority error occurs. **/ - public String getSubtype() - throws IOException, AS400SecurityException + public String getSubtype() throws IOException, AS400SecurityException { - if (subType_ == null) - { - if (impl_ == null) + if (subType_ == null) { - chooseImpl(); - } - subType_ = impl_.getSubtype(); - } - return subType_; - } - private boolean isInFileSystem(String _fs) { - String lowercasePath = path_.toLowerCase().replaceAll("//+","/"); - return lowercasePath.equals("/"+_fs.toLowerCase()) || lowercasePath.startsWith("/"+_fs.toLowerCase()+"/"); + if (impl_ == null) + chooseImpl(); + subType_ = impl_.getSubtype(); + } + + return subType_; + } + + private boolean isInFileSystem(String fs) + { + String lowercasePath = path_.toLowerCase().replaceAll("//+","/"); + return lowercasePath.equals("/"+fs.toLowerCase()) || lowercasePath.startsWith("/"+fs.toLowerCase()+"/"); } public boolean isInQOpenSys() { - return isInFileSystem("QOpenSys"); + return isInFileSystem("QOpenSys"); } public boolean isInQsys() { - return isInFileSystem("qsys.lib"); + return isInFileSystem("qsys.lib"); } public boolean isInQDLS() { - return isInFileSystem("qdls"); + return isInFileSystem("qdls"); } /** - Determines if the file is an IBM i "source physical file". - Physical files reside under QSYS, and can be either source files (type *SRC) or data files (type *DATA). - For further information, refer to the specification of the QDBRTVFD (Retrieve Database File Description) API. - @return Whether the file is a source file. - - @exception AS400Exception If the system returns an error message. - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the system. - @see AS400File#TYPE_SOURCE - @see AS400File#TYPE_DATA + * Determines if the file is an IBM i "source physical file". Physical files reside under QSYS, and can be either + * source files (type *SRC) or data files (type *DATA). For further information, refer to the specification of the + * QDBRTVFD (Retrieve Database File Description) API. + * + * @return Whether the file is a source file. + * + * @exception AS400Exception If the system returns an error message. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception IOException If an error occurs while communicating with the system. + * @see AS400File#TYPE_SOURCE + * @see AS400File#TYPE_DATA **/ - public boolean isSourcePhysicalFile() - throws AS400Exception, AS400SecurityException, IOException + public boolean isSourcePhysicalFile() throws AS400Exception, AS400SecurityException, IOException { - String pathUpperCase = path_.toUpperCase(system_.getLocale()); //@AE8A - if (!pathUpperCase.endsWith(".FILE") || - pathUpperCase.indexOf("/QSYS.LIB") == -1 || - !getSubtype().equals("PF")) - { - if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Not a physical file."); - return false; - } + String pathUpperCase = path_.toUpperCase(system_.getLocale()); + if (!pathUpperCase.endsWith(".FILE") || pathUpperCase.indexOf("/QSYS.LIB") == -1 || !getSubtype().equals("PF")) + { + if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Not a physical file."); + return false; + } - return impl_.isSourcePhysicalFile(); + return impl_.isSourcePhysicalFile(); } - /** - Returns the system that this object references. - @return The system object. + * Returns the system that this object references. + * + * @return The system object. **/ - public AS400 getSystem() - { - return system_; + public AS400 getSystem() { + return system_; } - /**Return the auxiliary storage pool (ASP) that holds the object. Note only password authentication scheme is supported, otherwise returns -1. - @param retrieveAll more attributes at same time when set true. - @return Return the auxiliary storage pool (ASP) that holds the object. - Possible values are: -
    -
  • 1: the system ASP (QASP01, also known as the system disk pool) -
  • 2 to 32: user ASPs (QASP02 to QASP32) -
  • 33 to 255: independent ASPs -
  • -1: authentication scheme is not supported -
- @throws IOException If an error occurs while communicating with the system. - @throws AS400SecurityException If a security or authority error occurs. - **/ - -public int getASP(boolean retrieveAll) throws IOException, AS400SecurityException -{ - if (impl_ == null) - chooseImpl(); - - if (getSystem().getAuthenticationScheme() == AS400.AUTHENTICATION_SCHEME_PASSWORD - || getSystem().getAuthenticationScheme()== AS400.AUTHENTICATION_SCHEME_GSS_TOKEN) - return (retrieveAll) ? impl_.getASP(this.isDirectory()) : impl_.getASP(); + /** + * Return the auxiliary storage pool (ASP) that holds the object. + * + * @param retrieveAll more attributes at same time when set true. + * @return Return the auxiliary storage pool (ASP) that holds the object. Possible values are: + *
    + *
  • 1: the system ASP (QASP01, also known as the system disk pool) + *
  • 2 to 32: user ASPs (QASP02 to QASP32) + *
  • 33 to 255: independent ASPs + *
  • -1: unable to retrieve ASP. + *
+ * @throws IOException If an error occurs while communicating with the system. + * @throws AS400SecurityException If a security or authority error occurs. + * @deprecated Use {@link #getASP()} + **/ + + @Deprecated + public int getASP(boolean retrieveAll) throws IOException, AS400SecurityException + { + if (impl_ == null) + chooseImpl(); - return -1; -} + return impl_.getASP(); + } - /**Return the auxiliary storage pool (ASP) that holds the object. Note only password authentication scheme is supported, otherwise returns -1. - @return Return the auxiliary storage pool (ASP) that holds the object. - Possible values are: -
    -
  • 1: the system ASP (QASP01, also known as the system disk pool) -
  • 2 to 32: user ASPs (QASP02 to QASP32) -
  • 33 to 255: independent ASPs -
  • -1: authentication scheme is not supported -
- @throws IOException If an error occurs while communicating with the system. - @throws AS400SecurityException If a security or authority error occurs. + /** + * Return the auxiliary storage pool (ASP) that holds the object. + * + * @return Return the auxiliary storage pool (ASP) that holds the object. Possible values are: + *
    + *
  • 1: the system ASP (QASP01, also known as the system disk pool) + *
  • 2 to 32: user ASPs (QASP02 to QASP32) + *
  • 33 to 255: independent ASPs + *
  • -1: unable to retrieve ASP + *
+ * @throws IOException If an error occurs while communicating with the system. + * @throws AS400SecurityException If a security or authority error occurs. **/ public int getASP() throws IOException, AS400SecurityException { if (impl_ == null) chooseImpl(); - if (getSystem().getAuthenticationScheme() == AS400.AUTHENTICATION_SCHEME_PASSWORD - || getSystem().getAuthenticationScheme()== AS400.AUTHENTICATION_SCHEME_GSS_TOKEN) - return impl_.getASP(); - - return -1; + return impl_.getASP(); } -//@AC7 Start - /**Return the type of file system. Note only password authentication scheme is supported, otherwise returns "". + /** + * Return the type of file system. + * * @param retrieveAll true or false, retrieve all attributes at same time. - @return Return the type of file system. - Possible values are:EPFS,QDLS,QSYS,NFS,LRFS,QOPT,QRFS,EPFSP,QNETC,QDTL,IEPFS,ASPQSYS - @throws IOException If an error occurs while communicating with the system. - @throws AS400SecurityException If a security or authority error occurs. - **/ + * @return Return the type of file system. Possible values + * are: EPFS,QDLS,QSYS,NFS,LRFS,QOPT,QRFS,EPFSP,QNETC,QDTL,IEPFS, and ASPQSYS. + * If unable to retrieve file system type, a zero-length string is returned. + * @throws IOException If an error occurs while communicating with the system. + * @throws AS400SecurityException If a security or authority error occurs. + * @deprecated Use {@link #getFileSystemType()} + **/ + @Deprecated public String getFileSystemType(boolean retrieveAll) throws IOException, AS400SecurityException { if (cachedAttributes_ != null) @@ -1922,62 +1741,30 @@ else if (fileSystemType == 3) if (impl_ == null) chooseImpl(); - if (getSystem().getAuthenticationScheme() == AS400.AUTHENTICATION_SCHEME_PASSWORD - || getSystem().getAuthenticationScheme()== AS400.AUTHENTICATION_SCHEME_GSS_TOKEN) - return (retrieveAll) ? impl_.getFileSystemType(this.isDirectory()) : impl_.getFileSystemType(); - - return ""; + return impl_.getFileSystemType(); } - /**Return the type of file system. Note only password authentication scheme is supported, otherwise returns "". - @return Return the type of file system. - Possible values are:EPFS,QDLS,QSYS,NFS,LRFS,QOPT,QRFS,EPFSP,QNETC,QDTL,IEPFS,ASPQSYS - @throws IOException If an error occurs while communicating with the system. - @throws AS400SecurityException If a security or authority error occurs. + /** + * Return the type of file system. + * + * @return Return the type of file system. Possible values + * are: EPFS,QDLS,QSYS,NFS,LRFS,QOPT,QRFS,EPFSP,QNETC,QDTL,IEPFS, and ASPQSYS. + * If unable to retrieve file system type, a zero-length string is returned. + * @throws IOException If an error occurs while communicating with the system. + * @throws AS400SecurityException If a security or authority error occurs. **/ - public String getFileSystemType() throws IOException, AS400SecurityException - { - if (cachedAttributes_ != null) - { - int fileSystemType = cachedAttributes_.getFileSystemType(); - if (fileSystemType == 2) - return "QDLS"; - else if (fileSystemType == 3) - return "QSYS"; - } - - if (impl_ == null) - chooseImpl(); - - if (getSystem().getAuthenticationScheme() == AS400.AUTHENTICATION_SCHEME_PASSWORD - || getSystem().getAuthenticationScheme()== AS400.AUTHENTICATION_SCHEME_GSS_TOKEN) - return impl_.getFileSystemType(); - - return ""; + public String getFileSystemType() throws IOException, AS400SecurityException { + return getFileSystemType(false); } /** - Computes a hash code for this object. - @return A hash code value for this object. + * Computes a hash code for this object. + * + * @return A hash code value for this object. **/ - public int hashCode() - { - // @A3 - We need to be about to compute a hash code even when - // the path is not set. This ends up getting called - // when serializing the object via MS Internet Explorer. - // As a result, we were not able to serialize an object - // unless its path was set. - // - // I commented out this chunk of code: - // - // // Ensure that the path name is set. - // if (path_.length() == 0) - // { - // throw new ExtendedIllegalStateException("path", - // ExtendedIllegalStateException.PROPERTY_NOT_SET); - // } - - return path_.hashCode(); + @Override + public int hashCode() { + return path_.hashCode(); } /** @@ -1985,790 +1772,715 @@ public int hashCode() **/ private void initializeTransient() { - changes_ = new PropertyChangeSupport(this); - vetos_ = new VetoableChangeSupport(this); - fileListeners_ = new Vector(); + changes_ = new PropertyChangeSupport(this); + vetos_ = new VetoableChangeSupport(this); + fileListeners_ = new Vector(); - cachedAttributes_ = null; - impl_ = null; + cachedAttributes_ = null; + impl_ = null; } - /** - Determines if the path name of this integrated file system object is an - absolute path name. - @return true if the path name specification is absolute; false otherwise. - **/ + /** + * Determines if the path name of this integrated file system object is an absolute path name. + * + * @return true if the path name specification is absolute; false otherwise. + **/ public boolean isAbsolute() { - // Ensure that the path name is set. - if (path_.length() == 0) - { - throw new ExtendedIllegalStateException("path", - ExtendedIllegalStateException.PROPERTY_NOT_SET); - } + // Ensure that the path name is set. + if (path_.length() == 0) + throw new ExtendedIllegalStateException("path", ExtendedIllegalStateException.PROPERTY_NOT_SET); - return (path_.length() > 0 && path_.charAt(0) == '/'); + return (path_.length() > 0 && path_.charAt(0) == '/'); } - private boolean isDirectoryInited_ = false; //@AC7 + private boolean isDirectoryInited_ = false; - //internal isDirectory that returns a return code status indicator - int isDirectory0() throws IOException, AS400SecurityException { - //@A7A Added check for cached attributes. - if (cachedAttributes_ != null) { - if (isDirectory_) { + /* + * INTERNAL USE ONLY - SUBJECT TO CHANGE + * + * internal isDirectory that returns a return code status indicator + */ + int isDirectory0() throws IOException, AS400SecurityException + { + if (cachedAttributes_ != null) + { + if (isDirectory_) return IFSReturnCodeRep.SUCCESS; - } else + else return IFSReturnCodeRep.FILE_NOT_FOUND; - } else { - //@AC7 Start - if (isDirectoryInited_) { - if (isDirectory_) { - return IFSReturnCodeRep.SUCCESS; - } else - return IFSReturnCodeRep.FILE_NOT_FOUND; - } else { - if (impl_ == null) - chooseImpl(); - int rc = impl_.isDirectory(); - isDirectory_ = rc == 0? true : false; - isDirectoryInited_ = true; - return rc; - } - } - } - //@AC7 End + } + + if (isDirectoryInited_) + { + if (isDirectory_) + return IFSReturnCodeRep.SUCCESS; + else + return IFSReturnCodeRep.FILE_NOT_FOUND; + } + + if (impl_ == null) + chooseImpl(); + + int rc = impl_.isDirectory(); + isDirectory_ = (rc == 0) ? true : false; + isDirectoryInited_ = true; + return rc; + } /** - Determines if the integrated file system object represented by this object is a - directory. -
Both isDirectory() and {@link #isFile() isFile} will return false - for invalid symbolic links. + * Determines if the integrated file system object represented by this object is a directory.
+ * Both isDirectory() and {@link #isFile() isFile} will return false for invalid symbolic links. + * + * @return true if the integrated file system object exists and is a directory; false otherwise. + * @throws IOException If an error occurs while communicating with the system. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + * + **/ + public boolean isDirectory() throws IOException + { + int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; + try { + returnCode = isDirectory0(); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); + } - @return true if the integrated file system object exists and is a directory; false otherwise. - * @throws IOException If an error occurs while communicating with the system. + return (returnCode == IFSReturnCodeRep.SUCCESS); + } - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. + /* + * INTERNAL USE ONLY - SUBJECT TO CHANGE + * + * internal isFile that returns a return code status indicator + */ + int isFile0() throws IOException, AS400SecurityException + { + if (cachedAttributes_ != null) + { + if (isFile_) + return IFSReturnCodeRep.SUCCESS; + else + return IFSReturnCodeRep.FILE_NOT_FOUND; + } - **/ - public boolean isDirectory() - throws IOException - { - int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; - try - { - returnCode = isDirectory0(); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - // returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; //@A7D Unnecessary assignment. - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); // @B6a - } - return (returnCode == IFSReturnCodeRep.SUCCESS); - } - -//internal isFile that returns a return code status indicator - int isFile0() - throws IOException, AS400SecurityException - { - //@A7A Added check for cached attributes. - if (cachedAttributes_ != null) - { - if (isFile_) - return IFSReturnCodeRep.SUCCESS; - else - return IFSReturnCodeRep.FILE_NOT_FOUND; - } - else - { - if (impl_ == null) - chooseImpl(); + if (impl_ == null) + chooseImpl(); - return impl_.isFile(); - } + return impl_.isFile(); } /** - Determines if the integrated file system object represented by this object is a - "normal" file. -
A file is "normal" if it is not a directory or a container of other objects.
- Both {@link #isDirectory() isDirectory} and isFile() will return false - for invalid symbolic links. - - @return true if the specified file exists and is a "normal" file; false otherwise. - * @throws IOException If an error occurs while communicating with the system. - - @see #isSymbolicLink() - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. + * Determines if the integrated file system object represented by this object is a "normal" file.
+ * A file is "normal" if it is not a directory or a container of other objects.
+ * Both {@link #isDirectory() isDirectory} and isFile() will return false for invalid symbolic links. + * + * @return true if the specified file exists and is a "normal" file; false otherwise. + * @throws IOException If an error occurs while communicating with the system. + * + * @see #isSymbolicLink() + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. **/ - public boolean isFile() - throws IOException + public boolean isFile() throws IOException { - int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; - try - { - returnCode = isFile0(); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - // returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; //@A7D Unnecessary assignment. - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); // @B6a - } - return (returnCode == IFSReturnCodeRep.SUCCESS); + int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; + try { + returnCode = isFile0(); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); + } + + return (returnCode == IFSReturnCodeRep.SUCCESS); } /** - Determines if the integrated file system object represented by this object is hidden. - - @return true if the hidden attribute of this integrated file system object - is set; false otherwise. - * @throws IOException If an error occurs while communicating with the system. + * Determines if the integrated file system object represented by this object is hidden. + * + * @return true if the hidden attribute of this integrated file system object is set; false otherwise. + * @throws IOException If an error occurs while communicating with the system. + * + * @exception AS400SecurityException If a security or authority error occurs. + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + **/ + public boolean isHidden() throws IOException, AS400SecurityException + { + // If the attributes are cached from an earlier listFiles() operation + // use the cached attributes instead of getting a new set from the system. + if (cachedAttributes_ != null) + return (cachedAttributes_.getFixedAttributes() & IFSCachedAttributes.FA_HIDDEN) != 0; - @exception AS400SecurityException If a security or authority error occurs. - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - **/ - // @D1 - new method because of changes to java.io.File in Java 2. - public boolean isHidden() - throws IOException, AS400SecurityException - { - // If the attributes are cached from an earlier listFiles() operation - // use the cached attributes instead of getting a new set from the system. - if (cachedAttributes_ != null) - return (cachedAttributes_.getFixedAttributes() & - IFSCachedAttributes.FA_HIDDEN) != 0; - //@D2C - Changed IFSListAttrsRep to IFSCached Attributes - else - { - if (impl_ == null) + if (impl_ == null) chooseImpl(); - return impl_.isHidden(); - } + return impl_.isHidden(); } /** - Determines if the integrated file system object represented by this object is a - symbolic link. -
Note: Both {@link #isDirectory() isDirectory} and {@link #isFile() isFile} resolve symbolic links to their ultimate destination. For example, if this object represents a symbolic link on the system, that resolves to a file object, then isSymbolicLink() will return true, isFile() will return true, and isDirectory() will return false. -
Note: If the system is V5R2 or earlier, this method always returns false, regardless of whether the system object is a link or not. - - @return true if the specified file exists and is a symbolic link; false otherwise. -
If the system is V5R2 or earlier, this method always returns false. - * @throws IOException If an error occurs while communicating with the system. - * @throws AS400SecurityException If a security or authority error occurs. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - + * Determines if the integrated file system object represented by this object is a symbolic link.
+ * Note: Both {@link #isDirectory() isDirectory} and {@link #isFile() isFile} resolve symbolic links to their ultimate + * destination. For example, if this object represents a symbolic link on the system, that resolves to a file object, + * then isSymbolicLink() will return true, isFile() will return true, and isDirectory() will return false.
+ * Note: If the system is V5R2 or earlier, this method always returns false, regardless of whether the system object + * is a link or not. + * + * @return true if the specified file exists and is a symbolic link; false otherwise.
+ * If the system is V5R2 or earlier, this method always returns false. + * @throws IOException If an error occurs while communicating with the system. + * @throws AS400SecurityException If a security or authority error occurs. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + * **/ - public boolean isSymbolicLink() - throws IOException, AS400SecurityException + public boolean isSymbolicLink() throws IOException, AS400SecurityException { - if (cachedAttributes_ != null) { - return isSymbolicLink_; - } - else - { - if (impl_ == null) - chooseImpl(); + if (cachedAttributes_ != null) + return isSymbolicLink_; - return impl_.isSymbolicLink(); - } - } + if (impl_ == null) + chooseImpl(); + return impl_.isSymbolicLink(); + } /** - Determines if the integrated file system object represented by this object is read only. - - @return true if the read only attribute of this integrated file system object - is set; false otherwise. - * @throws IOException If an error occurs while communicating with the system. + * Determines if the integrated file system object represented by this object is read only. + * + * @return true if the read only attribute of this integrated file system object is set; false otherwise. + * @throws IOException If an error occurs while communicating with the system. + * + * @exception AS400SecurityException If a security or authority error occurs. + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + **/ + public boolean isReadOnly() throws IOException, AS400SecurityException + { + // If the attributes are cached from an earlier listFiles() operation + // use the cached attributes instead of getting a new set from the system. + if (cachedAttributes_ != null) + return (cachedAttributes_.getFixedAttributes() & IFSCachedAttributes.FA_READONLY) != 0; - @exception AS400SecurityException If a security or authority error occurs. - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - **/ - // @D1 - new method because of changes to java.io.File in Java 2. - public boolean isReadOnly() - throws IOException, AS400SecurityException - { - // If the attributes are cached from an earlier listFiles() operation - // use the cached attributes instead of getting a new set from the system. - if (cachedAttributes_ != null) - return (cachedAttributes_.getFixedAttributes() & - IFSCachedAttributes.FA_READONLY) != 0; - //@D2C - Changed IFSListAttrsRep to IFSCached Attributes - else - { - if (impl_ == null) - chooseImpl(); + if (impl_ == null) + chooseImpl(); - return impl_.isReadOnly(); - } + return impl_.isReadOnly(); } /** - Returns the sorting behavior used when files are listed by any of the list() or listFiles() methods. - @return true if lists of files are returned in sorted order; false otherwise. - * @throws IOException If an error occurs while communicating with the system. + * Returns the sorting behavior used when files are listed by any of the list() or listFiles() + * methods. + * + * @return true if lists of files are returned in sorted order; false otherwise. + * @throws IOException If an error occurs while communicating with the system. **/ - public boolean isSorted() - throws IOException - { + public boolean isSorted() throws IOException { return sortLists_; } /** - Determines the time that the integrated file system object represented by this - object was last accessed. With the use of the {@link #listFiles() listFiles} methods, attribute - information is cached and will not be automatically refreshed from the system. - This means the reported last accessed time may become inconsistent with the system. - @return The time (measured in milliseconds since 01/01/1970 00:00:00 GMT) - that the integrated file system object was last accessed, or 0L if - the object does not exist or is not accessible. - * @throws IOException If an error occurs while communicating with the system. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - - **/ - public long lastAccessed() //D3a - throws IOException //D3a - { //D3a - try //D3a - { //D3a - //@A7A Added check for cached attributes. //@D3a - if (cachedAttributes_ != null) //@D3a - { //@D3a - return cachedAttributes_.getAccessDate(); //@D3a - } //@D3a - else //@D3a - { //@D3a - if (impl_ == null) //@D3a - chooseImpl(); //@D3a - //@D3a - return impl_.lastAccessed(); //@D3a - } //@D3a - } //D3a - catch (AS400SecurityException e) //D3a - { //D3a - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); //D3a - //return 0L; //D3a @B6d - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); // @B6a - } //D3a - } //D3a - - - - - -//internal lastModified that throws a security exception - long lastModified0() - throws IOException, AS400SecurityException - { - //@A7A Added check for cached attributes. - if (cachedAttributes_ != null) - { - return cachedAttributes_.getModificationDate(); - } - else - { - if (impl_ == null) - chooseImpl(); + * Determines the time that the integrated file system object represented by this object was last accessed. With the + * use of the {@link #listFiles() listFiles} methods, attribute information is cached and will not be automatically + * refreshed from the system. This means the reported last accessed time may become inconsistent with the system. + * + * @return The time (measured in milliseconds since 01/01/1970 00:00:00 GMT) that the integrated file system object + * was last accessed, or 0L if the object does not exist or is not accessible. + * @throws IOException If an error occurs while communicating with the system. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + * + **/ + public long lastAccessed() throws IOException + { + try + { + if (cachedAttributes_ != null) + return cachedAttributes_.getAccessDate(); - return impl_.lastModified(); - } - } + if (impl_ == null) + chooseImpl(); + + return impl_.lastAccessed(); + } + catch (AS400SecurityException e) + { + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); + } + } - /** - Determines the time that the integrated file system object represented by this - object was last modified. With the use of the {@link #listFiles() listFiles} methods, attribute - information is cached and will not be automatically refreshed from the system. - This means the reported last modified time may become inconsistent with the system. - @return The time (measured in milliseconds since 01/01/1970 00:00:00 GMT) - that the integrated file system object was last modified, or 0L if it does not exist - or is not accessible. - * @throws IOException If an error occurs while communicating with the system. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - - **/ - public long lastModified() - throws IOException - { - try - { - return lastModified0(); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - //return 0L; // @B6d - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); // @B6a - } - } - -//internal length that throws a security exception - long length0() - throws IOException, AS400SecurityException - { - //@A7A Added check for cached attributes. - if (cachedAttributes_ != null) - { - return cachedAttributes_.getSize(); - } - else - { - if (impl_ == null) - chooseImpl(); + /* + * INTERNAL USE ONLY - SUBJECT TO CHANGE + * + * internal length that throws a security exception + */ + long lastModified0() throws IOException, AS400SecurityException + { + if (cachedAttributes_ != null) + return cachedAttributes_.getModificationDate(); - return impl_.length(); - } + if (impl_ == null) + chooseImpl(); + + return impl_.lastModified(); } /** - Determines the length of the integrated file system object represented by this - object. With the use of the {@link #listFiles() listFiles} methods, attribute - information is cached and will not be automatically refreshed from the system. - This means the reported length may become inconsistent with the system. - @return The length, in bytes, of the integrated file system object, or - 0L if it does not exist or is not accessible. -
Note: When used following {@link #listFiles() listFiles} or - {@link #enumerateFiles() enumerateFiles} methods (for symbolic link objects) - this method will return the length of the symbolic link object as returned by the File Server. - In order to retrieve the length of the target object, you must use - {@link #clearCachedAttributes() clearCachedAttributes()} followed by {@link #length() length()}. - * @throws IOException If an error occurs while communicating with the system. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - + * Determines the time that the integrated file system object represented by this object was last modified. With the + * use of the {@link #listFiles() listFiles} methods, attribute information is cached and will not be automatically + * refreshed from the system. This means the reported last modified time may become inconsistent with the system. + * + * @return The time (measured in milliseconds since 01/01/1970 00:00:00 GMT) that the integrated file system object + * was last modified, or 0L if it does not exist or is not accessible. + * @throws IOException If an error occurs while communicating with the system. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + * **/ - public long length() - throws IOException + public long lastModified() throws IOException { - try - { - return length0(); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - // return 0L; // @B6d - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); // @B6a - } + try { + return lastModified0(); + } + catch (AS400SecurityException e) + { + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); + } } - /** - Lists the integrated file system objects in the directory represented by this object. + /* + * INTERNAL USE ONLY - SUBJECT TO CHANGE + * + * internal length that throws a security exception + */ + long length0() throws IOException, AS400SecurityException + { + if (cachedAttributes_ != null) + return cachedAttributes_.getSize(); - @return An array of object names in the directory. This list does not - include the current directory or the parent directory. If this object - does not represent a directory, null is returned. If this object represents - an empty directory, an empty string array is returned. -
Note: Due to a limitation in the File Server, at most 65,535 files will be listed. - * @throws IOException If an error occurs while communicating with the system. + if (impl_ == null) + chooseImpl(); - @see #listFiles() - @see #setPatternMatching(int) - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system, or the directory is not accessible. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. + return impl_.length(); + } + /** + * Determines the length of the integrated file system object represented by this object. With the use of the + * {@link #listFiles() listFiles} methods, attribute information is cached and will not be automatically refreshed + * from the system. This means the reported length may become inconsistent with the system. + * + * @return The length, in bytes, of the integrated file system object, or 0L if it does not exist or is not + * accessible.
+ * Note: When used following {@link #listFiles() listFiles} or {@link #enumerateFiles() enumerateFiles} + * methods (for symbolic link objects) this method will return the length of the symbolic link object as + * returned by the File Server. In order to retrieve the length of the target object, you must use + * {@link #clearCachedAttributes() clearCachedAttributes()} followed by {@link #length() length()}. + * @throws IOException If an error occurs while communicating with the system. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + * **/ - public String[] list() - throws IOException + public long length() throws IOException { - return list("*"); + try { + return length0(); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); + } } /** - Lists the integrated file system objects in the directory represented by this - object that satisfy filter. - @param filter A file object filter. If null, then no filtering is done. - @return An array of object names in the directory that satisfy the filter. This - list does not include the current directory or the parent directory. If this - object does not represent a directory, null is returned. If this object - represents an empty directory, or the filter does not match any files, - an empty string array is returned. The IFSFile object passed to the filter - object have cached file attribute information. Maintaining references to - these IFSFile objects after the list operation increases the chances that - their file attribute information will not be valid. -
Note: Due to a limitation in the File Server, at most 65,535 files will be listed. - * @throws IOException If an error occurs while communicating with the system. - - @see #listFiles(IFSFileFilter) - @see #setPatternMatching(int) - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system or the directory is not accessible. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - - **/ - public String[] list(IFSFileFilter filter) - throws IOException - { // @A5D Removed null filter check (null means no filtering) - return list(filter, "*"); + * Lists the integrated file system objects in the directory represented by this object. + * + * @return An array of object names in the directory. This list does not include the current directory or the parent + * directory. If this object does not represent a directory, null is returned. If this object represents an + * empty directory, an empty string array is returned.
+ * Note: Due to a limitation in the File Server, at most 65,535 files will be listed. + * @throws IOException If an error occurs while communicating with the system. + * + * @see #listFiles() + * @see #setPatternMatching(int) + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system, or the directory is + * not accessible. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + * + **/ + public String[] list() throws IOException + { + return list("*"); } - /** - Lists the integrated file system objects in the directory represented by this object - that satisfy filter. - @param filter A file object filter. - @param pattern The pattern that all filenames must match. - Acceptable characters are wildcards (*) and question marks (?). + * Lists the integrated file system objects in the directory represented by this object that satisfy filter. + * + * @param filter A file object filter. If null, then no filtering is done. + * @return An array of object names in the directory that satisfy the filter. This list does not include the current + * directory or the parent directory. If this object does not represent a directory, null is returned. If this + * object represents an empty directory, or the filter does not match any files, an empty string array is + * returned. The IFSFile object passed to the filter object have cached file attribute information. + * Maintaining references to these IFSFile objects after the list operation increases the chances that their + * file attribute information will not be valid.
+ * Note: Due to a limitation in the File Server, at most 65,535 files will be listed. + * @throws IOException If an error occurs while communicating with the system. + * + * @see #listFiles(IFSFileFilter) + * @see #setPatternMatching(int) + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system or the directory is + * not accessible. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + * **/ - String[] list0(IFSFileFilter filter, String pattern) - throws IOException, AS400SecurityException - { // @A5D removed check for null filter (null means no filtering). - // Ensure that we are connected to the system. - if (impl_ == null) - chooseImpl(); - - // Assume that the 'pattern' argument has been validated as non-null. - // Note that we tolerate a null-valued 'filter' argument. - - // List the attributes of all files in this directory. Have to append - // a file separator and * to the path so that all files in the - // directory are returned. - String directory = path_; - if (directory.lastIndexOf(separatorChar) != directory.length() - 1) - { - // Add a separator character. - directory = directory + separatorChar; - } - String[] allNames = impl_.listDirectoryContents(directory + pattern); - - // Add the name for each reply that matches the filter to the array - // of names. - - // @A1C - // Changed the behavior of the list() to conform to that of the JDK1.1.x - // so that a NULL is returned if and only if the directory or file represented - // by this IFSFile object doesn't exist. - // - // Original code: - // if (replys != null && replys.size() != 0) - String[] names = null; - if (allNames != null) - { - names = new String[allNames.length]; - int j = 0; - for (int i = 0; i < allNames.length; i++) - { - String name = allNames[i]; - boolean addThisOne = false; - if (!(name.equals(".") || name.equals(".."))) - { - addThisOne = false; // Broke up this "double if" check to avoid constructing - if (filter == null) // the IFSFile object when there is no filter specified. - { - addThisOne = true; - } else - { - IFSFile file = new IFSFile(system_, directory, name); - if (filter.accept(file)) - { - addThisOne = true; - } - } - if (addThisOne == true) // Specified the add in only one place to avoid confusion - { // over how many add sequences actually take place. - names[j++] = name; - } - } - } + public String[] list(IFSFileFilter filter) throws IOException + { + return list(filter, "*"); + } - if (j == 0) + /* + * INTERNAL USE ONLY - SUBJECT TO CHANGE + * + * Lists the integrated file system objects in the directory represented by this object that satisfy filter. + * + * @param filter A file object filter. + * + * @param pattern The pattern that all filenames must match. Acceptable characters are wildcards (*) and question + * marks (?). + */ + String[] list0(IFSFileFilter filter, String pattern) throws IOException, AS400SecurityException + { + // Ensure that we are connected to the system. + if (impl_ == null) + chooseImpl(); + + // Assume that the 'pattern' argument has been validated as non-null. + // Note that we tolerate a null-valued 'filter' argument. + + // List the attributes of all files in this directory. Have to append + // a file separator and * to the path so that all files in the + // directory are returned. + String directory = path_; + if (directory.lastIndexOf(separatorChar) != directory.length() - 1) { - // @A1C - // - // Original code: - // names = null; - names = new String[0]; // @A1C + // Add a separator character. + directory = directory + separatorChar; } - else if (names.length != j) + String[] allNames = impl_.listDirectoryContents(directory + pattern); + + // Add the name for each reply that matches the filter to the array + // of names. + + // Changed the behavior of the list() to conform to that of the JDK1.1.x + // so that a NULL is returned if and only if the directory or file represented + // by this IFSFile object doesn't exist. + + String[] names = null; + if (allNames != null) { - // Copy the names to an array of the exact size. - String[] newNames = new String[j]; - System.arraycopy(names, 0, newNames, 0, j); - names = newNames; + names = new String[allNames.length]; + int j = 0; + for (int i = 0; i < allNames.length; i++) + { + String name = allNames[i]; + boolean addThisOne = false; + if (!(name.equals(".") || name.equals(".."))) + { + addThisOne = false; // Broke up this "double if" check to avoid constructing + if (filter == null) // the IFSFile object when there is no filter specified. + addThisOne = true; + else + { + IFSFile file = new IFSFile(system_, directory, name); + if (filter.accept(file)) + addThisOne = true; + } + + // Specified the add in only one place to avoid confusion + // over how many add sequences actually take place. + if (addThisOne == true) + names[j++] = name; + } + } + + if (j == 0) + names = new String[0]; + else if (names.length != j) + { + // Copy the names to an array of the exact size. + String[] newNames = new String[j]; + System.arraycopy(names, 0, newNames, 0, j); + names = newNames; + } } - } - return names; + return names; } /** - Lists the integrated file system objects in the directory represented by this - object that satisfy filter. - @param filter A file object filter. - @param pattern The pattern that all filenames must match. Acceptable characters - are wildcards (*) and - question marks (?). - @return An array of object names in the directory that satisfy the filter - and pattern. This list does not include the current directory or the parent - directory. If this object does not represent a directory, null is returned. - If this object represents an empty directory, or the filter or pattern does - not match any files, an empty string array is returned. The IFSFile object - passed to the filter object have cached file attribute information. - Maintaining references to these IFSFile objects after the list operation - increases the chances that their file attribute information will not be valid. -
Note: Due to a limitation in the File Server, at most 65,535 files will be listed. - * @throws IOException If an error occurs while communicating with the system. - - @see #listFiles(IFSFileFilter,String) - @see #setPatternMatching(int) - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system or the directory is not accessible. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - - **/ - public String[] list(IFSFileFilter filter, - String pattern) - throws IOException - { - // Validate arguments. Note that we tolerate a null-valued 'filter'. - if (pattern == null) - throw new NullPointerException("pattern"); - - try - { - return list0(filter, pattern); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - // return null; // @B6d - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); // @B6a - } - } - - /** - Lists the integrated file system objects in the directory represented - by this object that match pattern. - @param pattern The pattern that all filenames must match. Acceptable - characters are wildcards (*) and - question marks (?). - @return An array of object names in the directory that match the pattern. - This list does not include the current directory or the parent directory. - If this object does not represent a directory, null is returned. If - this object represents an empty directory, or the pattern does not - match any files, an empty string array is returned. -
Note: Due to a limitation in the File Server, at most 65,535 files will be listed. - * @throws IOException If an error occurs while communicating with the system. - - @see #listFiles(String) - @see #setPatternMatching(int) - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system, or the directory is not accessible. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - - **/ - public String[] list(String pattern) - throws IOException - { - return list(null, pattern); - } - - //@A7A Added function to return an array of files in a directory. - /** - Lists the integrated file system objects in the directory represented by this object. With the use of this method, attribute information is cached and will not be automatically refreshed from the system. This means that retrieving attribute information for files returned in the list is much faster than using the {@link #list() list} method, but attribute information may become inconsistent with the system. -

- When the IFSFile object represents the root of the QSYS file system, this method may return a partial list of the contents of the directory. - - @return An array of objects in the directory. This list does not - include the current directory or the parent directory. If this - object does not represent a directory, or this object represents - an empty directory, an empty object array is returned. -
Note: Due to a limitation in the File Server, at most 65,535 files will be listed. - * @throws IOException If an error occurs while communicating with the system. - - @see #setPatternMatching(int) - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system, or the directory is not accessible. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - - **/ - public IFSFile[] listFiles() - throws IOException - { - return listFiles((IFSFileFilter)null, "*"); - } - - - //@A7A Added function to return an array of files in a directory. - /** - Lists the integrated file system objects in the directory represented by this object that satisfy filter. With the use of this method, attribute information is cached and will not be automatically refreshed from the system. This means that retrieving attribute information for files returned in the list is much faster than using the {@link #list(IFSFileFilter) list} method, but attribute information may become inconsistent with the system. -

- When the IFSFile object represents the root of the QSYS file system, this method may return a partial list of the contents of the directory. + * Lists the integrated file system objects in the directory represented by this object that satisfy filter. + * + * @param filter A file object filter. + * @param pattern The pattern that all filenames must match. Acceptable characters are wildcards (*) and question + * marks (?). + * @return An array of object names in the directory that satisfy the filter and pattern. This list does not include + * the current directory or the parent directory. If this object does not represent a directory, null is + * returned. If this object represents an empty directory, or the filter or pattern does not match any files, + * an empty string array is returned. The IFSFile object passed to the filter object have cached file + * attribute information. Maintaining references to these IFSFile objects after the list operation increases + * the chances that their file attribute information will not be valid.
+ * Note: Due to a limitation in the File Server, at most 65,535 files will be listed. + * @throws IOException If an error occurs while communicating with the system. + * + * @see #listFiles(IFSFileFilter,String) + * @see #setPatternMatching(int) + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system or the directory is + * not accessible. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + * + **/ + public String[] list(IFSFileFilter filter, String pattern) throws IOException + { + // Validate arguments. Note that we tolerate a null-valued 'filter'. + if (pattern == null) + throw new NullPointerException("pattern"); - @param filter A file object filter. - @return An array of objects in the directory. This list does not - include the current directory or the parent directory. If this - object does not represent a directory, or this - object represents an empty directory, an empty object array is returned. -
Note: Due to a limitation in the File Server, at most 65,535 files will be listed. - * @throws IOException If an error occurs while communicating with the system. + try { + return list0(filter, pattern); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); + } + } - @see #setPatternMatching(int) - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system, or the directory is not accessible. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. + /** + * Lists the integrated file system objects in the directory represented by this object that match pattern. + * + * @param pattern The pattern that all filenames must match. Acceptable characters are wildcards (*) and question + * marks (?). + * @return An array of object names in the directory that match the pattern. This list does not include the current + * directory or the parent directory. If this object does not represent a directory, null is returned. If this + * object represents an empty directory, or the pattern does not match any files, an empty string array is + * returned.
+ * Note: Due to a limitation in the File Server, at most 65,535 files will be listed. + * @throws IOException If an error occurs while communicating with the system. + * + * @see #listFiles(String) + * @see #setPatternMatching(int) + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system, or the directory is + * not accessible. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + * + **/ + public String[] list(String pattern) throws IOException + { + return list(null, pattern); + } + /** + * Lists the integrated file system objects in the directory represented by this object. With the use of this method, + * attribute information is cached and will not be automatically refreshed from the system. This means that retrieving + * attribute information for files returned in the list is much faster than using the {@link #list() list} method, but + * attribute information may become inconsistent with the system. + *

+ * When the IFSFile object represents the root of the QSYS file system, this method may return a partial list of the + * contents of the directory. + * + * @return An array of objects in the directory. This list does not include the current directory or the parent + * directory. If this object does not represent a directory, or this object represents an empty directory, an + * empty object array is returned.
+ * Note: Due to a limitation in the File Server, at most 65,535 files will be listed. + * @throws IOException If an error occurs while communicating with the system. + * + * @see #setPatternMatching(int) + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system, or the directory is + * not accessible. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + * **/ - public IFSFile[] listFiles(IFSFileFilter filter) - throws IOException + public IFSFile[] listFiles() throws IOException { - return listFiles(filter, "*"); + return listFiles((IFSFileFilter)null, "*"); } + /** + * Lists the integrated file system objects in the directory represented by this object that satisfy filter. + * With the use of this method, attribute information is cached and will not be automatically refreshed from the + * system. This means that retrieving attribute information for files returned in the list is much faster than using + * the {@link #list(IFSFileFilter) list} method, but attribute information may become inconsistent with the system. + *

+ * When the IFSFile object represents the root of the QSYS file system, this method may return a partial list of the + * contents of the directory. + * + * @param filter A file object filter. + * @return An array of objects in the directory. This list does not include the current directory or the parent + * directory. If this object does not represent a directory, or this object represents an empty directory, an + * empty object array is returned.
+ * Note: Due to a limitation in the File Server, at most 65,535 files will be listed. + * @throws IOException If an error occurs while communicating with the system. + * + * @see #setPatternMatching(int) + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system, or the directory is + * not accessible. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + * + **/ + public IFSFile[] listFiles(IFSFileFilter filter) throws IOException + { + return listFiles(filter, "*"); + } - //@A7A Added function to return an array of files in a directory. /** - Lists the integrated file system objects in the directory represented by this object that satisfy filter. With the use of this method, attribute information is cached and will not be automatically refreshed from the system. This means that retrieving attribute information for files returned in the list is much faster than using the {@link #list(IFSFileFilter,String) list} method, but attribute information may become inconsistent with the system. -

- When pattern is "*" and the IFSFile object represents the root of the QSYS file system, this method may return a partial list of the contents of the directory. + * Lists the integrated file system objects in the directory represented by this object that satisfy filter. + * With the use of this method, attribute information is cached and will not be automatically refreshed from the + * system. This means that retrieving attribute information for files returned in the list is much faster than using + * the {@link #list(IFSFileFilter,String) list} method, but attribute information may become inconsistent with the + * system. + *

+ * When pattern is "*" and the IFSFile object represents the root of the QSYS file system, this method + * may return a partial list of the contents of the directory. + * + * @param filter A file object filter. + * @param pattern The pattern that all filenames must match. Acceptable characters are wildcards (*) and question + * marks (?). + * @return An array of object names in the directory that satisfy the filter and pattern. This list does not include + * the current directory or the parent directory. If this object does not represent a directory, this object + * represents an empty directory, or the filter or pattern does not match any files, an empty object array is + * returned. The IFSFile object passed to the filter object has cached file attribute information. Maintaining + * references to these IFSFile objects after the list operation increases the chances that their file + * attribute information will not be valid.
+ * Note: Due to a limitation in the File Server, at most 65,535 files will be listed. + * @throws IOException If an error occurs while communicating with the system. + * + * @see #setPatternMatching(int) + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system, or the directory is + * not accessible. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + * + **/ + public IFSFile[] listFiles(IFSFileFilter filter, String pattern) throws IOException + { + // Validate arguments. Note that we tolerate a null-valued 'filter'. + if (pattern == null) + throw new NullPointerException("pattern"); + + try { + return listFiles0(filter, pattern, -1, (String) null, (byte[]) null, true); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); + } + } - @param filter A file object filter. - @param pattern The pattern that all filenames must match. Acceptable - characters are wildcards (*) and - question marks (?). - @return An array of object names in the directory that satisfy the filter - and pattern. This list does not include the current directory or the parent - directory. If this object does not represent a directory, this object represents an empty directory, or the filter or pattern does - not match any files, an empty object array is returned. The IFSFile object - passed to the filter object has cached file attribute information. Maintaining - references to these IFSFile objects after the list operation increases the - chances that their file attribute information will not be valid. -
Note: Due to a limitation in the File Server, at most 65,535 files will be listed. - * @throws IOException If an error occurs while communicating with the system. - - @see #setPatternMatching(int) - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system, or the directory is not accessible. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - - **/ - public IFSFile[] listFiles(IFSFileFilter filter, String pattern) - throws IOException - { - // Validate arguments. Note that we tolerate a null-valued 'filter'. - if (pattern == null) - throw new NullPointerException("pattern"); - - try - { - return listFiles0(filter, pattern, -1, (String)null, (byte[])null, true); // @D4C @C3C @D7C - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - // return null; // @B6d - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); // @B6a - } - } - - - //@A7A Added function to return an array of files in a directory. - /** - Lists the integrated file system objects in the directory represented by this object that match pattern. With the use of this method, attribute information is cached and will not be automatically refreshed from the system. This means that retrieving attribute information for files returned in the list is much faster than using the {@link #list(String) list} method, but attribute information may become inconsistent with the system. -

- When pattern is "*" and the IFSFile object represents the root of the QSYS file system, this method may return a partial list of the contents of the directory. - - @param pattern The pattern that all filenames must match. Acceptable characters - are wildcards (*) and - question marks (?). - @return An array of object names in the directory that match the pattern. This - list does not include the current directory or the parent directory. If this - object does not represent a directory, this object - represents an empty directory, or the pattern does not match any files, - an empty object array is returned. -
Note: Due to a limitation in the File Server, at most 65,535 files will be listed. - * @throws IOException If an error occurs while communicating with the system. - - @see #setPatternMatching(int) - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system, or the directory is not accessible. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - - **/ - public IFSFile[] listFiles(String pattern) - throws IOException - { - return listFiles((IFSFileFilter)null, pattern); - } - - //@A7A Added function to return an array of files in a directory. - //@C3c Moved logic to new private method. /** - Lists the integrated file system objects in the directory represented by this - object that satisfy filter. With the use of this method, attribute - information is cached and will not be automatically refreshed from the system. - This means attribute information may become inconsistent with the system. - @param filter A file object filter. - @param pattern The pattern that all filenames must match. - @param maxGetCount The maximum number of directory entries to retrieve. - -1 indicates that all entries that match the search criteria should be retrieved. - @param restartName The file name from which to start the search. - If null, the search is started at the beginning of the list. - Acceptable characters are wildcards (*) and question marks (?). + * Lists the integrated file system objects in the directory represented by this object that match pattern. + * With the use of this method, attribute information is cached and will not be automatically refreshed from the + * system. This means that retrieving attribute information for files returned in the list is much faster than using + * the {@link #list(String) list} method, but attribute information may become inconsistent with the system. + *

+ * When pattern is "*" and the IFSFile object represents the root of the QSYS file system, this method + * may return a partial list of the contents of the directory. + * + * @param pattern The pattern that all filenames must match. Acceptable characters are wildcards (*) and question + * marks (?). + * @return An array of object names in the directory that match the pattern. This list does not include the current + * directory or the parent directory. If this object does not represent a directory, this object represents an + * empty directory, or the pattern does not match any files, an empty object array is returned.
+ * Note: Due to a limitation in the File Server, at most 65,535 files will be listed. + * @throws IOException If an error occurs while communicating with the system. + * + * @see #setPatternMatching(int) + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system, or the directory is + * not accessible. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + * **/ - IFSFile[] listFiles0(IFSFileFilter filter, String pattern, int maxGetCount, String restartName) // @D4C - throws IOException, AS400SecurityException + public IFSFile[] listFiles(String pattern) throws IOException { - return listFiles0(filter, pattern, maxGetCount, restartName, null, true); //@D7C + return listFiles((IFSFileFilter)null, pattern); + } + + /* + * INTERNAL USE ONLY - SUBJECT TO CHANGE + * + * Lists the integrated file system objects in the directory represented by this object that satisfy filter. + * With the use of this method, attribute information is cached and will not be automatically refreshed from the + * system. This means attribute information may become inconsistent with the system. + * + * @param filter A file object filter. + * @param pattern The pattern that all filenames must match. + * @param maxGetCount The maximum number of directory entries to retrieve. -1 indicates that all entries that match + * the search criteria should be retrieved. + * @param restartName The file name from which to start the search. If null, the search is started at the beginning of + * the list. Acceptable characters are wildcards (*) and question marks (?). + */ + IFSFile[] listFiles0(IFSFileFilter filter, String pattern, int maxGetCount, String restartName) throws IOException, AS400SecurityException + { + return listFiles0(filter, pattern, maxGetCount, restartName, null, true); //@D7C } - //@C3a Relocated logic from original listFiles0 method. /** Lists the integrated file system objects in the directory represented by this object that satisfy filter. With the use of this method, attribute @@ -2779,73 +2491,62 @@ IFSFile[] listFiles0(IFSFileFilter filter, String pattern, int maxGetCount, Stri Acceptable characters are wildcards (*) and question marks (?). **/ private IFSFile[] listFiles0(IFSFileFilter filter, String pattern, int maxGetCount, String restartName, - byte[] restartID, boolean allowSortedRequests) // @D4C @D7C - throws IOException, AS400SecurityException - { - // Do not specify both restartName and restartID. Specify one or the other. - - // Ensure that we are connected to the system. - if (impl_ == null) - chooseImpl(); - - // Assume that the 'pattern' argument has been validated as non-null. - // Note that we tolerate a null-valued 'filter' argument. - - // List the attributes of all files in this directory. Have to append - // a file separator and * to the path so that all files in the - // directory are returned. - String directory = path_; - if (directory.lastIndexOf(separatorChar) != directory.length() - 1) - { - // Add a separator character. - directory = directory + separatorChar; - } - IFSCachedAttributes[] fileAttributeList; //@C3C - if (restartName != null) { - fileAttributeList = impl_.listDirectoryDetails(directory + pattern, directory, maxGetCount, restartName); //@D2C @D4C - } - else { - fileAttributeList = impl_.listDirectoryDetails(directory + pattern, directory, maxGetCount, restartID,allowSortedRequests); //@C3a @D7C - } - - // Add the name for each reply that matches the filter to the array - // of files. - - if (Trace.isTraceOn()) Trace.log(Trace.DIAGNOSTIC, "IFSFile::listFile0(): returned ("+listFiles0LastNumObjsReturned_+") pre objects"); - if (fileAttributeList == null) - { - return new IFSFile[0]; - } - else - { - // Save number of objects read, restartname, and restartID @D5A - listFiles0LastNumObjsReturned_ = fileAttributeList.length; // @D5A + byte[] restartID, boolean allowSortedRequests) throws IOException, AS400SecurityException + { + // Do not specify both restartName and restartID. Specify one or the other. + + // Ensure that we are connected to the system. + if (impl_ == null) + chooseImpl(); + + // Assume that the 'pattern' argument has been validated as non-null. + // Note that we tolerate a null-valued 'filter' argument. + + // List the attributes of all files in this directory. Have to append + // a file separator and * to the path so that all files in the + // directory are returned. + String directory = path_; + if (directory.lastIndexOf(separatorChar) != directory.length() - 1) + directory = directory + separatorChar; + + IFSCachedAttributes[] fileAttributeList; + if (restartName != null) + fileAttributeList = impl_.listDirectoryDetails(directory + pattern, directory, maxGetCount, restartName); + else + fileAttributeList = impl_.listDirectoryDetails(directory + pattern, directory, maxGetCount, restartID,allowSortedRequests); + + // Add the name for each reply that matches the filter to the array of files. + + if (Trace.isTraceOn()) Trace.log(Trace.DIAGNOSTIC, "IFSFile::listFile0(): returned ("+listFiles0LastNumObjsReturned_+") pre objects"); + + if (fileAttributeList == null) + return new IFSFile[0]; + + // Save number of objects read, restartname, and restartID + listFiles0LastNumObjsReturned_ = fileAttributeList.length; IFSFile[] files = new IFSFile[fileAttributeList.length]; if (fileAttributeList.length > 0) { - IFSFile lastFile = new IFSFile(system_, fileAttributeList[fileAttributeList.length - 1]); + IFSFile lastFile = new IFSFile(system_, fileAttributeList[fileAttributeList.length - 1]); - // Save the last restartName and restartID from the files @D5A - // returned from the server (to be used for subsequent reads) @D5A - listFiles0LastRestartName_ = lastFile.getName(); // @D5A - listFiles0LastRestartID_ = lastFile.getRestartID(); // @D5A + // Save the last restartName and restartID from the files + // returned from the server (to be used for subsequent reads) + listFiles0LastRestartName_ = lastFile.getName(); + listFiles0LastRestartID_ = lastFile.getRestartID(); } int j = 0; - for (int i = 0; i < fileAttributeList.length; i++) { - IFSFile file = new IFSFile(system_, fileAttributeList[i]); //@D2C - if (filter == null || filter.accept(file)) //@D2C - { - files[j++] = file; //@D2C - } + for (int i = 0; i < fileAttributeList.length; i++) + { + IFSFile file = new IFSFile(system_, fileAttributeList[i]); + if (filter == null || filter.accept(file)) + files[j++] = file; } if (j == 0) - { files = new IFSFile[0]; - } else if (files.length != j) { // Copy the objects to an array of the exact size. @@ -2855,707 +2556,674 @@ else if (files.length != j) } if (Trace.isTraceOn()) Trace.log(Trace.DIAGNOSTIC, "IFSFile::listFile0(): returned ("+files.length+") post objects"); + return files; - } } - //@C3a - IFSFile[] listFiles0(IFSFileFilter filter, String pattern, int maxGetCount, byte[] restartID) - throws IOException, AS400SecurityException + /* + * INTERNAL USE ONLY - SUBJECT TO CHANGE + */ + IFSFile[] listFiles0(IFSFileFilter filter, String pattern, int maxGetCount, byte[] restartID) throws IOException, AS400SecurityException { // This method is only called by IFSEnumeration() which reads 128 objects at a time. @D7A // The IFS file server does not allow "sort" and "restart ID" to be set in the same server request. // Therefore, since the user may have previously called setSorted(), we need to inform // IFSFileImplRemote to not allow sorting on this server request. The last parameter // indicates "allowSortedRequests" and is set to "false" - return listFiles0(filter, pattern, maxGetCount, null, restartID, false); //@D7C + return listFiles0(filter, pattern, maxGetCount, null, restartID, false); } - //@C3a - IFSFile[] listFiles0(IFSFileFilter filter, String pattern) - throws IOException, AS400SecurityException + /* + * INTERNAL USE ONLY - SUBJECT TO CHANGE + */ + IFSFile[] listFiles0(IFSFileFilter filter, String pattern) throws IOException, AS400SecurityException { - return listFiles0(filter, pattern, -1, null, null, true); //@D7C + return listFiles0(filter, pattern, -1, null, null, true); } - -//internal mkdir that returns return codes and throws exceptions. - int mkdir0(String directory) - throws IOException, AS400SecurityException + /* + * INTERNAL USE ONLY - SUBJECT TO CHANGE + * + * internal mkdirs that returns return codes and throws exceptions + */ + int mkdir0(String directory) throws IOException, AS400SecurityException { - // Assume the argument has been validated as non-null. + // Assume the argument has been validated as non-null. - if (impl_ == null) - chooseImpl(); + if (impl_ == null) + chooseImpl(); - return impl_.mkdir(directory); + return impl_.mkdir(directory); } - /** Creates an integrated file system directory whose path name is - specified by this object. - - @return true if the directory was created; false otherwise. - * @throws IOException If an error occurs while communicating with the system. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - + /** + * Creates an integrated file system directory whose path name is specified by this object. + * + * @return true if the directory was created; false otherwise. + * @throws IOException If an error occurs while communicating with the system. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + * **/ - public boolean mkdir() - throws IOException + public boolean mkdir() throws IOException { - int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; - try - { - returnCode = mkdir0(path_); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); - } + int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; + try { + returnCode = mkdir0(path_); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); + } - return (returnCode == IFSReturnCodeRep.SUCCESS); + return (returnCode == IFSReturnCodeRep.SUCCESS); } -//internal mkdirs that returns return codes and throws exceptions - int mkdirs0() - throws IOException, AS400SecurityException + /* + * INTERNAL USE ONLY - SUBJECT TO CHANGE + * + * internal mkdirs that returns return codes and throws exceptions + */ + int mkdirs0() throws IOException, AS400SecurityException { - if (impl_ == null) - chooseImpl(); + if (impl_ == null) + chooseImpl(); - return impl_.mkdirs(); + return impl_.mkdirs(); } /** - Creates an integrated file system directory whose path name is - specified by this object. In addition, create all parent directories as necessary. - - @return true if the directory (or directories) were created; false otherwise. - * @throws IOException If an error occurs while communicating with the system. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - - **/ - public boolean mkdirs() - throws IOException + * Creates an integrated file system directory whose path name is specified by this object. In addition, create all + * parent directories as necessary. + * + * @return true if the directory (or directories) were created; false otherwise. + * @throws IOException If an error occurs while communicating with the system. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + * + **/ + public boolean mkdirs() throws IOException { - int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; - try - { - returnCode = mkdirs0(); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - // returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; //@A7D Unnecessary assignment. - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); // @B6a - } - return (returnCode == IFSReturnCodeRep.SUCCESS); + int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; + try { + returnCode = mkdirs0(); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); + } + + return (returnCode == IFSReturnCodeRep.SUCCESS); } - /** - Restores the state of this object from an object input stream. - @param ois The stream of state information. - @exception IOException - @exception ClassNotFoundException - **/ - private void readObject(java.io.ObjectInputStream ois) - throws IOException, ClassNotFoundException + /* + * Restores the state of this object from an object input stream. + * + * @param ois The stream of state information. + * @exception IOException + * @exception ClassNotFoundException + */ + private void readObject(java.io.ObjectInputStream ois) throws IOException, ClassNotFoundException { - // Restore the non-static and non-transient fields. - ois.defaultReadObject(); + // Restore the non-static and non-transient fields. + ois.defaultReadObject(); - // Initialize the transient fields. - initializeTransient(); + // Initialize the transient fields. + initializeTransient(); } /** - Removes a file listener so that it no longer receives file events from - this IFSFile. - @param listener The file listener. + * Removes a file listener so that it no longer receives file events from this IFSFile. + * + * @param listener The file listener. **/ public void removeFileListener(FileListener listener) { - if (listener == null) - throw new NullPointerException("listener"); + if (listener == null) + throw new NullPointerException("listener"); fileListeners_.removeElement(listener); } /** - Removes a property change listener. - @param listener The property change listener to remove. + * Removes a property change listener. + * + * @param listener The property change listener to remove. **/ public void removePropertyChangeListener(PropertyChangeListener listener) { - if (listener == null) - throw new NullPointerException("listener"); + if (listener == null) + throw new NullPointerException("listener"); - changes_.removePropertyChangeListener(listener); + changes_.removePropertyChangeListener(listener); } /** - Removes a vetoable change listener. - @param listener The vetoable change listener to remove. + * Removes a vetoable change listener. + * + * @param listener The vetoable change listener to remove. **/ public void removeVetoableChangeListener(VetoableChangeListener listener) { - if (listener == null) - throw new NullPointerException("listener"); + if (listener == null) + throw new NullPointerException("listener"); + + vetos_.removeVetoableChangeListener(listener); + } + + /* + * INTERNAL USE ONLY - SUBJECT TO CHANGE + * + * internal renameTo that returns an error code + */ + int renameTo0(IFSFile file) throws IOException, PropertyVetoException, AS400SecurityException + { + // Assume the argument has been validated as non-null. + + if (impl_ == null) + chooseImpl(); + + String targetPath = file.getAbsolutePath(); + if (targetPath.length() == 0) + throw new ExtendedIllegalStateException("path", ExtendedIllegalStateException.PROPERTY_NOT_SET); + + // Fire a vetoable change event. + vetos_.fireVetoableChange("path", path_, file.getAbsolutePath()); + + // Rename the file. + int rc = impl_.renameTo(file.getImpl()); + + if (rc == IFSReturnCodeRep.SUCCESS) + { + String oldPath = path_; + path_ = file.getAbsolutePath(); + + // Fire the property change event having null as the name to + // indicate that the path, parent, etc. have changed. + changes_.firePropertyChange("path", oldPath, path_); + + // Clear any cached attributes. + cachedAttributes_ = null; + } + + return rc; + } + + /** + * Renames the integrated file system object specified by this object to have the path name of file. Wildcards + * are not permitted in this file name. + * + * @param file The new file name. + * + * @return true if successful; false otherwise. + * @throws IOException If an error occurs while communicating with the system. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception PropertyVetoException If the change is vetoed. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + * + **/ + public boolean renameTo(IFSFile file) throws IOException, PropertyVetoException + { + // Validate the argument. + if (file == null) + throw new NullPointerException("file"); + + int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; + try { + returnCode = renameTo0(file); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); + } + + return (returnCode == IFSReturnCodeRep.SUCCESS); + } + + /* + * INTERNAL USE ONLY - SUBJECT TO CHANGE + * + * Sets the access mode of the integrated file system object. This method is supported for IBM i V5R1 and higher. For + * older releases, it does nothing and returns false. + * + * @param accessType The type of access to set on the file. Valid values are:

  • {@link #ACCESS_READ + * ACCESS_READ}
  • {@link #ACCESS_WRITE ACCESS_WRITE}
  • {@link #ACCESS_EXECUTE ACCESS_EXECUTE}
+ * + * @param accessMode If true, sets the access permission to allow the specified type of operation; if false, to + * disallow the operation. + * + * @param ownerOnly If true, the specified permission applies only to the owner's permission; otherwise, it applies to + * everybody. + * + * @return true if successful; false otherwise. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + */ + boolean setAccess(int accessType, boolean enableAccess, boolean ownerOnly) throws IOException, AS400SecurityException + { + // Note: The called API (QlgChmod) is supported for V5R1 and higher. + // The impl object will check the VRM. + + if (accessType != ACCESS_READ && accessType != ACCESS_WRITE && accessType != ACCESS_EXECUTE) + throw new ExtendedIllegalArgumentException("accessType ("+accessType+")", ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID); - vetos_.removeVetoableChangeListener(listener); + if (impl_ == null) + chooseImpl(); + + return impl_.setAccess(accessType, enableAccess, ownerOnly); } -//internal renameTo that returns an error code - int renameTo0(IFSFile file) - throws IOException, PropertyVetoException, AS400SecurityException + /** + * Sets the file's data CCSID. + * + * @param ccsid The file data CCSID. Note that the data in the file is not changed; only the CCSID "tag" on the file + * is changed. + * @return true if successful; false otherwise. + * @throws IOException If an error occurs while communicating with the system. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system, or if the file + * doesn't exist or is a directory. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + **/ + public boolean setCCSID(int ccsid) throws IOException { - // Assume the argument has been validated as non-null. + boolean success = false; + try + { + if (impl_ == null) + chooseImpl(); - if (impl_ == null) - chooseImpl(); + success = impl_.setCCSID(ccsid); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); + } - String targetPath = file.getAbsolutePath(); - if (targetPath.length() == 0) - { - throw new ExtendedIllegalStateException("path", - ExtendedIllegalStateException.PROPERTY_NOT_SET); - } + if (success) + { + // Fire the file modified event. + if (fileListeners_.size() != 0) + IFSFileDescriptor.fireModifiedEvents(this, fileListeners_); + } - // Fire a vetoable change event. - vetos_.fireVetoableChange("path", path_, file.getAbsolutePath()); + return success; + } - // Rename the file. - int rc = impl_.renameTo(file.getImpl()); + /* + * INTERNAL USE ONLY - SUBJECT TO CHANGE + * + * Changes the fixed attributes (read only, hidden, etc.) of the integrated file system object represented by this + * object to attributes. + * + * @param attributes The attributes to set on the file. These attributes are not ORed with existing attributes. + * They replace the existing fixed attributes of the file. The attributes are a bit map as follows
  • 0x0001: on + * = file is a readonly file
  • 0x0002: on = file is a hidden file
  • 0x0004: on = file is a system file
  • 0x0010: + * on = file is a directory
  • 0x0020: on = file has been changed (archive bit)
For example, 0x0023 is a + * readonly, hidden file with the archive bit on. + * + * @return true if successful; false otherwise. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + */ + boolean setFixedAttributes(int attributes) throws IOException + { + // Validate arguments. + if ((attributes & 0xFFFFFF00) != 0) + throw new ExtendedIllegalArgumentException("attributes ("+attributes+")", ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID); - if (rc == IFSReturnCodeRep.SUCCESS) - { - String oldPath = path_; - path_ = file.getAbsolutePath(); + try + { + if (impl_ == null) + chooseImpl(); - // Fire the property change event having null as the name to - // indicate that the path, parent, etc. have changed. - changes_.firePropertyChange("path", oldPath, path_); + boolean success = impl_.setFixedAttributes(attributes); - // Clear any cached attributes. - cachedAttributes_ = null; //@A7a - } + if (success) + cachedAttributes_ = null; - return rc; + return success; + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); + } } /** - Renames the integrated file system object specified by this object to - have the path name of file. Wildcards are not permitted in this file name. - @param file The new file name. - - @return true if successful; false otherwise. - * @throws IOException If an error occurs while communicating with the system. + * Marks the integrated file system object represented by this object as hidden. + * + * @return true if successful; false otherwise. + * @throws IOException If an error occurs while communicating with the system. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + **/ + public boolean setHidden() throws IOException { + return setHidden(true); + } - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception PropertyVetoException If the change is vetoed. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. + /** + * Changes the hidden attribute of the integrated file system object represented by this object. + * + * @param attribute True to set the hidden attribute of the file. False to turn off the hidden attribute. + * + * @return true if successful; false otherwise. + * @throws IOException If an error occurs while communicating with the system. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. **/ - public boolean renameTo(IFSFile file) - throws IOException, PropertyVetoException + public boolean setHidden(boolean attribute) throws IOException { - // Validate the argument. - if (file == null) - throw new NullPointerException("file"); - - int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; - try - { - returnCode = renameTo0(file); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - // returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; //@A7D Unnecessary assignment. - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); // @B6a - } - return (returnCode == IFSReturnCodeRep.SUCCESS); - } + try + { + if (impl_ == null) + chooseImpl(); + boolean success = impl_.setHidden(attribute); - /** - Sets the access mode of the integrated file system object. - This method is supported for IBM i V5R1 and higher. For older releases, it does nothing and returns false. - @param accessType The type of access to set on the file. Valid values are: -
    -
  • {@link #ACCESS_READ ACCESS_READ} -
  • {@link #ACCESS_WRITE ACCESS_WRITE} -
  • {@link #ACCESS_EXECUTE ACCESS_EXECUTE} -
- @param accessMode If true, sets the access permission to allow the specified type of operation; if false, to disallow the operation. - @param ownerOnly If true, the specified permission applies only to the owner's permission; otherwise, it applies to everybody. - @return true if successful; false otherwise. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - **/ - boolean setAccess(int accessType, boolean enableAccess, boolean ownerOnly) - throws IOException, AS400SecurityException - { - // Note: The called API (QlgChmod) is supported for V5R1 and higher. - // The impl object will check the VRM. - - if (accessType != ACCESS_READ && accessType != ACCESS_WRITE && accessType != ACCESS_EXECUTE) - { - throw new ExtendedIllegalArgumentException("accessType ("+accessType+")", - ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID); - } - - if (impl_ == null) - chooseImpl(); - - return impl_.setAccess(accessType, enableAccess, ownerOnly); - } - - - /** - Sets the file's data CCSID. - @param ccsid The file data CCSID. Note that the data in the file is not changed; only the CCSID "tag" on the file is changed. - @return true if successful; false otherwise. - * @throws IOException If an error occurs while communicating with the system. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system, or if the file doesn't exist or is a directory. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - **/ - public boolean setCCSID(int ccsid) - throws IOException - { - boolean success = false; - try - { - if (impl_ == null) chooseImpl(); - success = impl_.setCCSID(ccsid); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); - } - - if (success) - { - // Fire the file modified event. - if (fileListeners_.size() != 0) { - IFSFileDescriptor.fireModifiedEvents(this, fileListeners_); - } - } - return success; - } - - - - /** - Changes the fixed attributes (read only, hidden, etc.) of the integrated - file system object - represented by this object to attributes. - @param attributes The attributes to set on the file. These attributes are not - ORed with existing attributes. They replace the existing - fixed attributes of the file. The attributes are a bit map as - follows -
    -
  • 0x0001: on = file is a readonly file -
  • 0x0002: on = file is a hidden file -
  • 0x0004: on = file is a system file -
  • 0x0010: on = file is a directory -
  • 0x0020: on = file has been changed (archive bit) -
- For example, 0x0023 is a readonly, hidden file with the - archive bit on. - @return true if successful; false otherwise. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - **/ - // @D1 - new method because of changes to java.io.File in Java 2. - boolean setFixedAttributes(int attributes) - throws IOException - { - // Validate arguments. - if ((attributes & 0xFFFFFF00) != 0) - { - throw new ExtendedIllegalArgumentException("attributes ("+attributes+")", - ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID); - } - - try - { - if (impl_ == null) - chooseImpl(); + if (success) + { + cachedAttributes_ = null; - boolean success = impl_.setFixedAttributes(attributes); + // Fire the file modified event. + if (fileListeners_.size() != 0) + IFSFileDescriptor.fireModifiedEvents(this, fileListeners_); + } - if (success) + return success; + } + catch (AS400SecurityException e) { - cachedAttributes_ = null; + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); } - - return success; - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); - } } - /** - Marks the integrated file system object represented by this object as hidden. - @return true if successful; false otherwise. - * @throws IOException If an error occurs while communicating with the system. - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. + /** + * Changes the last modified time of the integrated file system object represented by this object to time. + * + * @param time The desired last modification time (measured in milliseconds since January 1, 1970 00:00:00 GMT), or 0 + * to leave the last modification time unchanged, or -1 to set the last modification time to the current + * system time. + * + * @return true if successful; false otherwise. + * @throws IOException If an error occurs while communicating with the system. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + * @exception PropertyVetoException If the change is vetoed. **/ - // @D1 - new method because of changes to java.io.File in Java 2. - public boolean setHidden() - throws IOException + public boolean setLastModified(long time) throws IOException, PropertyVetoException { - return setHidden(true); - } + // Fire a vetoable change event for lastModified. + vetos_.fireVetoableChange("lastModified", null, Long.valueOf(time)); + try { + return setLastModified0(time); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); + } + } /** - Changes the hidden attribute of the integrated file system object - represented by this object. - @param attribute True to set the hidden attribute of the file. - False to turn off the hidden attribute. - - @return true if successful; false otherwise. - * @throws IOException If an error occurs while communicating with the system. + * Beans friendly version of setLastModified. + * + * @param time + * @throws IOException If an error occurs while communicating with the system. + * @throws PropertyVetoException If the recipient wishes the property change to be rolled back. + */ + public void setLastModifiedV(long time) throws IOException, PropertyVetoException { + setLastModified(time); + } - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - **/ - // @D1 - new method because of changes to java.io.File in Java 2. - public boolean setHidden(boolean attribute) - throws IOException + /* + * INTERNAL USE ONLY - SUBJECT TO CHANGE + * + * Changes the last modified time of the integrated file system object represented by this object to time. + * + * @param time The desired last modification time (measured in milliseconds since January 1, 1970 00:00:00 GMT), or 0 + * to leave the last modification time unchanged, or -1 to set the last modification time to the current system time. + * + * @return true if successful; false otherwise. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. + * @exception PropertyVetoException If the change is vetoed. + */ + boolean setLastModified0(long time) throws IOException, AS400SecurityException { - try - { + // Validate arguments. + if (time < -1) + { + throw new ExtendedIllegalArgumentException("time (" + Long.toString(time) + ")", + ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID); + } + if (impl_ == null) - chooseImpl(); + chooseImpl(); - boolean success = impl_.setHidden(attribute); + boolean success = impl_.setLastModified(time); if (success) { - cachedAttributes_ = null; + // Fire the property change event. + changes_.firePropertyChange("lastModified", null, Long.valueOf(time)); - // Fire the file modified event. - if (fileListeners_.size() != 0) { - IFSFileDescriptor.fireModifiedEvents(this, fileListeners_); - } + // Fire the file modified event. + if (fileListeners_.size() != 0) + IFSFileDescriptor.fireModifiedEvents(this, fileListeners_); + + // Clear any cached attributes. + cachedAttributes_ = null; } + return success; - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); - } } - /** - Changes the last modified time of the integrated file system object - represented by this object to time. - @param time The desired last modification time (measured in milliseconds - since January 1, 1970 00:00:00 GMT), or 0 to leave the last modification - time unchanged, or -1 to set the last modification time to the current system time. - - @return true if successful; false otherwise. - * @throws IOException If an error occurs while communicating with the system. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - @exception PropertyVetoException If the change is vetoed. + * Sets the length of the integrated file system object represented by this object. The file can be made larger or + * smaller. If the file is made larger, the contents of the new bytes of the file are undetermined. + * + * @param length The new length, in bytes. + * @return true if successful; false otherwise. + * @throws IOException If an error occurs while communicating with the system. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. **/ - public boolean setLastModified(long time) - throws IOException, PropertyVetoException + public boolean setLength(int length) throws IOException { - // Fire a vetoable change event for lastModified. - vetos_.fireVetoableChange("lastModified", null, Long.valueOf(time)); - - try - { - return setLastModified0(time); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); - } + try { + return setLength0(length); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); + } } - /** - * Beans friendly version of setLastModified. + /* + * INTERNAL USE ONLY - SUBJECT TO CHANGE * - * @param time - * @throws IOException If an error occurs while communicating with the system. - * @throws PropertyVetoException If the recipient wishes the property change to be rolled back. + * Sets the length of the integrated file system object represented by this object. The file can be made larger or + * smaller. If the file is made larger, the contents of the new bytes of the file are undetermined. + * + * @param length The new length, in bytes. + * + * @return true if successful; false otherwise. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. */ - /*@R2A*/ - public void setLastModifiedV(long time) throws IOException, PropertyVetoException { - setLastModified(time); - } - - /** - Changes the last modified time of the integrated file system object - represented by this object to time. - @param time The desired last modification time (measured in milliseconds - since January 1, 1970 00:00:00 GMT), or 0 to leave the last modification - time unchanged, or -1 to set the last modification time to the current system time. - - @return true if successful; false otherwise. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - @exception PropertyVetoException If the change is vetoed. - **/ - boolean setLastModified0(long time) - throws IOException, AS400SecurityException + boolean setLength0(int length) throws IOException, AS400SecurityException { - // Validate arguments. - if (time < -1) // @B8c - { - throw new ExtendedIllegalArgumentException("time (" + - Long.toString(time) + ")", - ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID); - } + // Validate arguments. + if (length < 0) + { + throw new ExtendedIllegalArgumentException("length (" + Integer.toString(length) + ")", + ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID); + } + + // Note: The file system will not allow us to set the length of a file to a value larger than (2Gig minus 1), + // or 2147483647 (0x7FFFFFFF) bytes, which happens to be the maximum positive value which an 'int' will hold. + // Therefore we do not provide a setLength(long) method. - if (impl_ == null) - chooseImpl(); + if (impl_ == null) + chooseImpl(); - boolean success = impl_.setLastModified(time); + boolean success = impl_.setLength(length); - if (success) - { - // Fire the property change event. - changes_.firePropertyChange("lastModified", null, Long.valueOf(time)); + if (success) + { + // Fire the file modified event. + if (fileListeners_.size() != 0) + IFSFileDescriptor.fireModifiedEvents(this, fileListeners_); - // Fire the file modified event. - if (fileListeners_.size() != 0) { - IFSFileDescriptor.fireModifiedEvents(this, fileListeners_); + // Clear any cached attributes. + cachedAttributes_ = null; } - // Clear any cached attributes. - cachedAttributes_ = null; //@A7a - } - - return success; + return success; } - // @B8a /** - Sets the length of the integrated file system object represented by this object. The file can be made larger or smaller. If the file is made larger, the contents of the new bytes of the file are undetermined. - @param length The new length, in bytes. - @return true if successful; false otherwise. - * @throws IOException If an error occurs while communicating with the system. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. + * Sets the file path. An exception will be returned if the IFSFile object + * has been operated on that results in a server connection being established. + * + * @param path The absolute file path. + * @exception PropertyVetoException If the change is vetoed. **/ - public boolean setLength(int length) - throws IOException + public void setPath(String path) throws PropertyVetoException { - try - { - return setLength0(length); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); - } - } - - // @B8a - /** - Sets the length of the integrated file system object represented by this object. The file can be made larger or smaller. If the file is made larger, the contents of the new bytes of the file are undetermined. - @param length The new length, in bytes. - @return true if successful; false otherwise. + if (path == null) + throw new NullPointerException("path"); - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - **/ - boolean setLength0(int length) - throws IOException, AS400SecurityException - { - // Validate arguments. - if (length < 0) - { - throw new ExtendedIllegalArgumentException("length (" + - Integer.toString(length) + ")", - ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID); - } - // Note: The file system will not allow us to set the length of a file to a value larger than (2Gig minus 1), or 2147483647 (0x7FFFFFFF) bytes, which happens to be the maximum positive value which an 'int' will hold. Therefore we do not provide a setLength(long) method. + // Ensure that the path is not altered after the connection is established. + if (impl_ != null) + throw new ExtendedIllegalStateException("path", ExtendedIllegalStateException.PROPERTY_NOT_CHANGED); - if (impl_ == null) - chooseImpl(); + // Remember the current path value. + String oldPath = path_; - boolean success = impl_.setLength(length); + // If the specified path doesn't start with the separator character, + // add one. All paths are absolute for IFS. + String newPath = normalizePath(null, path); - if (success) - { - // Fire the file modified event. - if (fileListeners_.size() != 0) { - IFSFileDescriptor.fireModifiedEvents(this, fileListeners_); - } + // Fire a vetoable change event for the path. + vetos_.fireVetoableChange("path", oldPath, newPath); - // Clear any cached attributes. - cachedAttributes_ = null; - } + // Update the path value. + path_ = newPath; - return success; + // Fire the property change event having null as the name to + // indicate that the path, parent, etc. have changed. + changes_.firePropertyChange("path", oldPath, newPath); } + /** - Sets the file path. - @param path The absolute file path. - @exception PropertyVetoException If the change is vetoed. + * Sets the pattern-matching behavior used when files are listed by any of the list() or listFiles() + * methods. The default is PATTERN_POSIX. + * + * @param patternMatching Either {@link #PATTERN_POSIX PATTERN_POSIX}, {@link #PATTERN_POSIX_ALL PATTERN_POSIX_ALL}, + * or {@link #PATTERN_OS2 PATTERN_OS2} + * @throws IOException If an error occurs while communicating with the system. + * + * @see #getPatternMatching() + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. **/ - public void setPath(String path) - throws PropertyVetoException + public void setPatternMatching(int patternMatching) throws IOException { - if (path == null) - { - throw new NullPointerException("path"); - } + if (patternMatching < PATTERN_POSIX || patternMatching > PATTERN_OS2) { + throw new ExtendedIllegalArgumentException("patternMatching ("+patternMatching+")", + ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID); + } + + if (impl_ == null) + { + try { + chooseImpl(); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); + } + } - // Ensure that the path is not altered after the connection is - // established. - if (impl_ != null) - { - throw new ExtendedIllegalStateException("path", - ExtendedIllegalStateException.PROPERTY_NOT_CHANGED); - } - - // Remember the current path value. - String oldPath = path_; - - // If the specified path doesn't start with the separator character, - // add one. All paths are absolute for IFS. - String newPath; - if (path.length() == 0 || path.charAt(0) != separatorChar) - { - newPath = separator + path; - } - else - { - newPath = path; - } - - // Fire a vetoable change event for the path. - vetos_.fireVetoableChange("path", oldPath, newPath); - - // Update the path value. - path_ = newPath; - - // Fire the property change event having null as the name to - // indicate that the path, parent, etc. have changed. - changes_.firePropertyChange("path", oldPath, newPath); - } - - - /** - Sets the pattern-matching behavior used when files are listed by any of the list() or listFiles() methods. The default is PATTERN_POSIX. - @param patternMatching Either {@link #PATTERN_POSIX PATTERN_POSIX}, {@link #PATTERN_POSIX_ALL PATTERN_POSIX_ALL}, or {@link #PATTERN_OS2 PATTERN_OS2} - * @throws IOException If an error occurs while communicating with the system. - - @see #getPatternMatching() - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. - **/ - public void setPatternMatching(int patternMatching) - throws IOException - { - if (patternMatching < PATTERN_POSIX || patternMatching > PATTERN_OS2) { - throw new ExtendedIllegalArgumentException("patternMatching ("+patternMatching+")", - ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID); - } - if (impl_ == null) - try - { - chooseImpl(); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); - } - - impl_.setPatternMatching(patternMatching); - patternMatching_ = patternMatching; - } - - -// @A6A - /** + impl_.setPatternMatching(patternMatching); + patternMatching_ = patternMatching; + } + + + /** * Sets the permission of the object. + * * @param permission The permission that will be set to the object. * @see #getPermission - * @exception AS400Exception If the system returns an error message. - * @exception AS400SecurityException If a security or authority error occurs. - * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception AS400Exception If the system returns an error message. + * @exception AS400SecurityException If a security or authority error occurs. + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. * @exception ErrorCompletingRequestException If an error occurs before the request is completed. - * @exception InterruptedException If this thread is interrupted. - * @exception IOException If an error occurs while communicating with the system. - * @exception ObjectDoesNotExistException If the object does not exist on the system. - * @throws ServerStartupException If the server cannot be started. + * @exception InterruptedException If this thread is interrupted. + * @exception IOException If an error occurs while communicating with the system. + * @exception ObjectDoesNotExistException If the object does not exist on the system. + * @throws ServerStartupException If the server cannot be started. * @exception PropertyVetoException If the change is vetoed. - * @exception UnknownHostException If the system cannot be located. - + * @exception UnknownHostException If the system cannot be located. * - **/ + **/ public void setPermission(Permission permission) throws AS400Exception, AS400SecurityException, @@ -3568,210 +3236,216 @@ public void setPermission(Permission permission) PropertyVetoException, UnknownHostException { - if (permission == null) - { - throw new NullPointerException("permission"); - } - - AS400 system=permission.getSystem(); - if (system == null) - { - throw new ExtendedIllegalArgumentException("permission.system (null)", - ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID); - } - - if (system.equals(system_)) - { - if ((this.getFileSystem()).equals(permission.getObjectPath())) - { - vetos_.fireVetoableChange("permission", null, permission_); + if (permission == null) + throw new NullPointerException("permission"); - this.permission_=permission; - permission.commit(); + AS400 system=permission.getSystem(); + if (system == null) + throw new ExtendedIllegalArgumentException("permission.system (null)", ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID); + + if (system.equals(system_)) + { + if ((this.getFileSystem()).equals(permission.getObjectPath())) + { + vetos_.fireVetoableChange("permission", null, permission_); - changes_.firePropertyChange("permission", null, permission_); + this.permission_=permission; + permission.commit(); + changes_.firePropertyChange("permission", null, permission_); + } + else + { + throw new ExtendedIllegalArgumentException("permission.objectPath (" + permission.getObjectPath() + ")", + ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID); + } } else { - throw new ExtendedIllegalArgumentException("permission.objectPath (" + - permission.getObjectPath() + ")", - ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID); + String systemName = system.getSystemName(); + throw new ExtendedIllegalArgumentException("permission.system (" + systemName + ")", + ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID); } - } - else - { - String systemName = system.getSystemName(); - throw new ExtendedIllegalArgumentException("permission.system (" + - systemName + ")", - ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID); - } } - /** - Marks the integrated file system object represented by this object so - that only read operations are allowed. - @return true if successful; false otherwise. - * @throws IOException If an error occurs while communicating with the system. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. + * Marks the integrated file system object represented by this object so that only read operations are allowed. + * + * @return true if successful; false otherwise. + * @throws IOException If an error occurs while communicating with the system. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. **/ - // @D1 - new method because of changes to java.io.File in Java 2. - public boolean setReadOnly() - throws IOException - { + public boolean setReadOnly() throws IOException { return setReadOnly(true); } /** - Changes the read only attribute of the integrated file system object - represented by this object. - @param attribute True to set the read only attribute of the file such that - the file cannot be changed. False to set the read only - attributes such that the file can be changed. - - @return true if successful; false otherwise. - * @throws IOException If an error occurs while communicating with the system. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. + * Changes the read only attribute of the integrated file system object represented by this object. + * + * @param attribute True to set the read only attribute of the file such that the file cannot be changed. False to set + * the read only attributes such that the file can be changed. + * + * @return true if successful; false otherwise. + * @throws IOException If an error occurs while communicating with the system. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. **/ - - // @D1a new method because of changes to java.io.File in Java 2. - public boolean setReadOnly(boolean attribute) - throws IOException + public boolean setReadOnly(boolean attribute) throws IOException { - try - { - return setReadOnly0(attribute); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); - } + try { + return setReadOnly0(attribute); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); + } } - /** - Changes the read only attribute of the integrated file system object - represented by this object. - @param attribute True to set the read only attribute of the file such that - the file cannot be changed. False to set the read only - attributes such that the file can be changed. - - @return true if successful; false otherwise. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the host server cannot be started. - @exception UnknownHostException If the system cannot be located. + * INTERNAL USE ONLY - SUBJECT TO CHANGE + * + * Changes the read only attribute of the integrated file system object represented by this object. + * + * @param attribute True to set the read only attribute of the file such that the file cannot be changed. False to set + * the read only attributes such that the file can be changed. + * + * @return true if successful; false otherwise. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception InterruptedIOException If this thread is interrupted. + * @exception ServerStartupException If the host server cannot be started. + * @exception UnknownHostException If the system cannot be located. **/ - // @D1a new method because of changes to java.io.File in Java 2. - boolean setReadOnly0(boolean attribute) - throws IOException, AS400SecurityException + boolean setReadOnly0(boolean attribute) throws IOException, AS400SecurityException { - if (impl_ == null) - chooseImpl(); + if (impl_ == null) + chooseImpl(); - boolean success = impl_.setReadOnly(attribute); + boolean success = impl_.setReadOnly(attribute); - if (success) - { - cachedAttributes_ = null; + if (success) + { + cachedAttributes_ = null; - // Fire the file modified event. - if (fileListeners_.size() != 0) { - IFSFileDescriptor.fireModifiedEvents(this, fileListeners_); + // Fire the file modified event. + if (fileListeners_.size() != 0) + IFSFileDescriptor.fireModifiedEvents(this, fileListeners_); } - - } - return success; + + return success; } - /** - Sets the sorting behavior used when files are listed by any of the list() or listFiles() methods. The default is false (unsorted). - @param sort If true: Lists of files are returned in sorted order. - If false: Lists of files are returned in whatever order the file system provides. - - @exception IOException If an error occurs while communicating with the system. - @exception AS400SecurityException If a security or authority error occurs. + * Sets the sorting behavior used when files are listed by any of the list() or listFiles() methods. + * The default is false (unsorted). + * + * @param sort If true: Lists of files are returned in sorted order. If false: Lists of files are + * returned in whatever order the file system provides. + * + * @exception IOException If an error occurs while communicating with the system. + * @exception AS400SecurityException If a security or authority error occurs. **/ - public void setSorted(boolean sort) - throws IOException, AS400SecurityException + public void setSorted(boolean sort) throws IOException, AS400SecurityException { - if (impl_ == null) - try - { - chooseImpl(); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); - throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); - } + if (impl_ == null) + { + try { + chooseImpl(); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, SECURITY_EXCEPTION, e); + throw new ExtendedIOException(path_, ExtendedIOException.ACCESS_DENIED); + } + } - impl_.setSorted(sort); - sortLists_ = sort; + impl_.setSorted(sort); + sortLists_ = sort; } - - /** - Sets the system. - The system cannot be changed once a connection is made to the system. - @param system The system object. - @exception PropertyVetoException If the change is vetoed. + * Sets the system. The system cannot be changed once a connection is made to the system. + * + * @param system The system object. + * @exception PropertyVetoException If the change is vetoed. **/ - public void setSystem(AS400 system) - throws PropertyVetoException + public void setSystem(AS400 system) throws PropertyVetoException { - if (system == null) - { - throw new NullPointerException("system"); - } + if (system == null) + throw new NullPointerException("system"); - // Ensure that system is not altered after the connection is - // established. - if (impl_ != null) - { - Trace.log(Trace.ERROR, "Cannot set property 'system' after connect."); - throw new ExtendedIllegalStateException("system", - ExtendedIllegalStateException.PROPERTY_NOT_CHANGED); - } + // Ensure that system is not altered after the connection is + // established. + if (impl_ != null) + { + Trace.log(Trace.ERROR, "Cannot set property 'system' after connect."); + throw new ExtendedIllegalStateException("system", ExtendedIllegalStateException.PROPERTY_NOT_CHANGED); + } - // Fire a vetoable change event for system. - vetos_.fireVetoableChange("system", system_, system); + // Fire a vetoable change event for system. + vetos_.fireVetoableChange("system", system_, system); - // Remember the old system value. - AS400 oldSystem = system_; + // Remember the old system value. + AS400 oldSystem = system_; - system_ = system; + system_ = system; - // Fire the property change event. - changes_.firePropertyChange("system", oldSystem, system_); + // Fire the property change event. + changes_.firePropertyChange("system", oldSystem, system_); } /** - Generates a String representation of this object. - @return The path name of the integrated file system object represented by this object. + * Generates a String representation of this object. + * + * @return The path name of the integrated file system object represented by this object. **/ - public String toString() - { - return path_; + @Override + public String toString() { + return path_; } + /* + * INTERNAL USE ONLY - SUBJECT TO CHANGE + * + * This function normalizes the path of the object in IFSFile. If a directory path + * is passed, it will be prepended to the path (or name). It will also ensure + * that the resultant path is absolute (i.e. starts from the root ('/')). + * + * Note: The path parameter can be a simple name or path. + */ + static String normalizePath(String dir, String path) + { + StringBuilder sb = new StringBuilder(); + + // Include directory in path if there is one. + if (dir != null) + { + sb.append(dir); + if (path != null && sb.length() != 0 && sb.charAt(sb.length() - 1) != separatorChar) + sb.append(separatorChar); + } + + // If path/name specified, append it. + if (path != null) + sb.append(path); + + // If the specified path doesn't start with the separator character, + // add one. All paths are absolute for IFS. + if (sb.length() == 0 || sb.charAt(0) != separatorChar) + sb.insert(0, separatorChar); + + return sb.toString(); + } } diff --git a/src/main/java/com/ibm/as400/access/IFSFileDescriptor.java b/src/main/java/com/ibm/as400/access/IFSFileDescriptor.java index 0932feb9..2aadc91e 100644 --- a/src/main/java/com/ibm/as400/access/IFSFileDescriptor.java +++ b/src/main/java/com/ibm/as400/access/IFSFileDescriptor.java @@ -24,171 +24,158 @@ /** -Represents an integrated file system file descriptor. -Instances of the file descriptor class serve as an opaque handle to the underlying structure representing an open file or an open socket. Applications should not create their own file descriptors.
-Here is an example of two input streams sharing a file descriptor: -
-    AS400 as400 = new AS400("mySystem");
-    IFSFileInputStream is1 = new IFSFileInputStream(as400, "/Dir/File");
-    IFSFileInputStream is2 = new IFSFileInputStream(is1.getFD());
-
-Reading in one object advances the current file position of all objects that share the same descriptor. -@see IFSFileInputStream#getFD -@see IFSFileOutputStream#getFD -@see IFSRandomAccessFile#getFD -**/ -public final class IFSFileDescriptor - implements java.io.Serializable + * Represents an integrated file system file descriptor. Instances of the file descriptor class serve as an opaque + * handle to the underlying structure representing an open file or an open socket. Applications should not create their + * own file descriptors.
+ * Here is an example of two input streams sharing a file descriptor: + * + *
+ * AS400 as400 = new AS400("mySystem");
+ * IFSFileInputStream is1 = new IFSFileInputStream(as400, "/Dir/File");
+ * IFSFileInputStream is2 = new IFSFileInputStream(is1.getFD());
+ * 
+ * + * Reading in one object advances the current file position of all objects that share the same descriptor. + * + * @see IFSFileInputStream#getFD + * @see IFSFileOutputStream#getFD + * @see IFSRandomAccessFile#getFD + **/ +public final class IFSFileDescriptor implements java.io.Serializable { static final long serialVersionUID = 4L; - private transient long fileOffset_; - private transient Object parent_; // The object that instantiated - // this IFSDescriptor. - private String path_ = ""; - private int shareOption_; - private AS400 system_; - private boolean closed_ = false; + private transient long fileOffset_; + private transient Object parent_; // The object that instantiated + // this IFSDescriptor. + private String path_ = ""; + private int shareOption_; + private AS400 system_; + private boolean closed_ = false; - private transient Object fileOffsetLock_ = new Object(); - // Semaphore for synchronizing access to fileOffset_. + // Semaphore for synchronizing access to fileOffset_. + private transient Object fileOffsetLock_ = new Object(); - private transient IFSFileDescriptorImpl impl_; + private transient IFSFileDescriptorImpl impl_; + /** + * Constructs an IFSFileDescriptor object. + **/ + public IFSFileDescriptor() + { + } -/** -Constructs an IFSFileDescriptor object. -**/ - public IFSFileDescriptor() - { - } - - IFSFileDescriptor(AS400 system, - String path, - int shareOption, - Object parent) - { - system_ = system; - path_ = path; - shareOption_ = shareOption; - parent_ = parent; - } + IFSFileDescriptor(AS400 system, String path, int shareOption, Object parent) + { + system_ = system; + path_ = path; + shareOption_ = shareOption; + parent_ = parent; + } - IFSFileDescriptor(int shareOption, - Object parent) - { - shareOption_ = shareOption; - parent_ = parent; - } + IFSFileDescriptor(int shareOption, Object parent) + { + shareOption_ = shareOption; + parent_ = parent; + } /** Chooses the appropriate implementation. **/ void chooseImpl () { - if (impl_ == null) - { - impl_ = (IFSFileDescriptorImpl) system_.loadImpl2 - ("com.ibm.as400.access.IFSFileDescriptorImplRemote", - "com.ibm.as400.access.IFSFileDescriptorImplProxy"); + if (impl_ != null) + return; + + impl_ = (IFSFileDescriptorImpl) system_.loadImpl2("com.ibm.as400.access.IFSFileDescriptorImplRemote", + "com.ibm.as400.access.IFSFileDescriptorImplProxy"); // Get the "impl" object for the parent, so we can pass it to the impl_. Object parentImpl = null; if (parent_ != null) { - // Get the impl object for the parent. - //@A3D Class clazz = parent_.getClass (); - //@A3D Method method = clazz.getDeclaredMethod ("getImpl", new Class[] {}); - //@A3D parentImpl = method.invoke (parent_, new Object[] {}); - //@A3A - String className = parent_.getClass().getName(); - if (parent_ instanceof IFSFileInputStream) { - parentImpl = ((IFSFileInputStream)parent_).getImpl(); - } - else if (parent_ instanceof IFSFileOutputStream) { - parentImpl = ((IFSFileOutputStream)parent_).getImpl(); - } - else if (parent_ instanceof IFSTextFileInputStream) { - parentImpl = ((IFSTextFileInputStream)parent_).getImpl(); - } - else if (parent_ instanceof IFSTextFileOutputStream) { - parentImpl = ((IFSTextFileOutputStream)parent_).getImpl(); - } - else if (parent_ instanceof IFSRandomAccessFile) { - parentImpl = ((IFSRandomAccessFile)parent_).getImpl(); - } - else { - Trace.log(Trace.ERROR, "IFSFileDescriptor has invalid parent: " + className); - throw new InternalErrorException (InternalErrorException.UNEXPECTED_EXCEPTION); - } + // Get the impl object for the parent. + String className = parent_.getClass().getName(); + if (parent_ instanceof IFSFileInputStream) + parentImpl = ((IFSFileInputStream) parent_).getImpl(); + else if (parent_ instanceof IFSFileOutputStream) + parentImpl = ((IFSFileOutputStream) parent_).getImpl(); + else if (parent_ instanceof IFSTextFileInputStream) + parentImpl = ((IFSTextFileInputStream) parent_).getImpl(); + else if (parent_ instanceof IFSTextFileOutputStream) + parentImpl = ((IFSTextFileOutputStream) parent_).getImpl(); + else if (parent_ instanceof IFSRandomAccessFile) + parentImpl = ((IFSRandomAccessFile) parent_).getImpl(); + else + { + Trace.log(Trace.ERROR, "IFSFileDescriptor has invalid parent: " + className); + throw new InternalErrorException(InternalErrorException.UNEXPECTED_EXCEPTION); + } } - impl_.initialize(fileOffset_, parentImpl, - path_, shareOption_, system_.getImpl()); - } + impl_.initialize(fileOffset_, parentImpl, path_, shareOption_, system_.getImpl()); } void close() { - if (impl_ != null) impl_.close(); - closed_ = true; + if (impl_ != null) + impl_.close(); + closed_ = true; } - /** - Fires events to indicate file has been closed. - This static method is provided as a utility for use by other classes. + * Fires events to indicate file has been closed. This static method is provided as a utility for use by other + * classes. **/ static void fireClosedEvents(Object source, Vector fileListeners) { - FileEvent event = new FileEvent(source, FileEvent.FILE_CLOSED); - synchronized(fileListeners) - { - Enumeration e = fileListeners.elements(); - while (e.hasMoreElements()) + FileEvent event = new FileEvent(source, FileEvent.FILE_CLOSED); + synchronized (fileListeners) { - FileListener listener = (FileListener)e.nextElement(); - listener.fileClosed(event); + Enumeration e = fileListeners.elements(); + while (e.hasMoreElements()) + { + FileListener listener = (FileListener) e.nextElement(); + listener.fileClosed(event); + } } - } } - /** - Fires events to indicate file has been modified. - This static method is provided as a utility for use by other classes. + * Fires events to indicate file has been modified. This static method is provided as a utility for use by other + * classes. **/ static void fireModifiedEvents(Object source, Vector fileListeners) { - FileEvent event = new FileEvent(source, FileEvent.FILE_MODIFIED); - synchronized(fileListeners) - { - Enumeration e = fileListeners.elements(); - while (e.hasMoreElements()) + FileEvent event = new FileEvent(source, FileEvent.FILE_MODIFIED); + synchronized (fileListeners) { - FileListener listener = (FileListener)e.nextElement(); - listener.fileModified(event); + Enumeration e = fileListeners.elements(); + while (e.hasMoreElements()) + { + FileListener listener = (FileListener) e.nextElement(); + listener.fileModified(event); + } } - } } /** - Fires events to indicate file has been opened. - This static method is provided as a utility for use by other classes. + * Fires events to indicate file has been opened. This static method is provided as a utility for use by other + * classes. **/ static void fireOpenedEvents(Object source, Vector fileListeners) { - FileEvent event = new FileEvent(source, FileEvent.FILE_OPENED); - synchronized(fileListeners) - { - Enumeration e = fileListeners.elements(); - while (e.hasMoreElements()) + FileEvent event = new FileEvent(source, FileEvent.FILE_OPENED); + synchronized (fileListeners) { - FileListener listener = (FileListener)e.nextElement(); - listener.fileOpened(event); + Enumeration e = fileListeners.elements(); + while (e.hasMoreElements()) + { + FileListener listener = (FileListener) e.nextElement(); + listener.fileOpened(event); + } } - } } @@ -201,171 +188,149 @@ static void fireOpenedEvents(Object source, Vector fileListeners) IFSFileDescriptorImpl getImpl() { - if (impl_ == null) chooseImpl(); - return impl_; + if (impl_ == null) + chooseImpl(); + return impl_; } /** - Returns the file's "data CCSID" setting. + * Returns the file's "data CCSID" setting. **/ - int getCCSID() - throws IOException + int getCCSID() throws IOException { - if (impl_ == null) chooseImpl(); - return impl_.getCCSID(); + if (impl_ == null) + chooseImpl(); + return impl_.getCCSID(); } long getFileOffset() { - if (impl_ == null) - { - return fileOffset_; - } - else + if (impl_ == null) + return fileOffset_; + return impl_.getFileOffset(); } - String getPath() - { - return path_; // this field is never reset by the ImplRemote + String getPath() { + return path_; // this field is never reset by the ImplRemote } - int getShareOption() - { - return shareOption_; // this field is never reset by the ImplRemote + int getShareOption() { + return shareOption_; // this field is never reset by the ImplRemote } - AS400 getSystem() - { - return system_; // this field is never reset by the ImplRemote + AS400 getSystem() { + return system_; // this field is never reset by the ImplRemote } void incrementFileOffset(long fileOffsetIncrement) { - if (impl_ == null) - { - synchronized(fileOffsetLock_) + if (impl_ == null) { - fileOffset_ += fileOffsetIncrement; - } - } - else - impl_.incrementFileOffset(fileOffsetIncrement); + synchronized (fileOffsetLock_) { + fileOffset_ += fileOffsetIncrement; + } + } + else + impl_.incrementFileOffset(fileOffsetIncrement); } - boolean isClosed() - { - return closed_; + boolean isClosed() { + return closed_; } boolean isOpen() { - if (impl_ == null) - return false; - else + if (impl_ == null) + return false; + return impl_.isOpen(); } /** - Restores the state of this object from an object input stream. - @param ois The stream of state information. - @exception IOException If an error occurs while communicating with the server. - @exception ClassNotFoundException + * Restores the state of this object from an object input stream. + * + * @param ois The stream of state information. + * @exception IOException If an error occurs while communicating with the server. + * @exception ClassNotFoundException **/ - private void readObject(java.io.ObjectInputStream ois) - throws IOException, ClassNotFoundException + private void readObject(java.io.ObjectInputStream ois) throws IOException, ClassNotFoundException { - // Restore the non-static and non-transient fields. - ois.defaultReadObject(); - - // Initialize the transient fields. - fileOffset_ = 0; - parent_ = null; - fileOffsetLock_ = new Object(); - impl_ = null; + // Restore the non-static and non-transient fields. + ois.defaultReadObject(); + + // Initialize the transient fields. + fileOffset_ = 0; + parent_ = null; + fileOffsetLock_ = new Object(); + impl_ = null; } - void setFileOffset(long fileOffset) //@A1C - Change parameter from int to long + void setFileOffset(long fileOffset) // @A1C - Change parameter from int to long { - if (impl_ == null) - { - synchronized(fileOffsetLock_) + if (impl_ == null) { - fileOffset_ = fileOffset; - } - } - else - impl_.setFileOffset(fileOffset); + synchronized (fileOffsetLock_) { + fileOffset_ = fileOffset; + } + } + else + impl_.setFileOffset(fileOffset); } void setPath(String path) { - if (impl_ == null) - path_ = path; - else - throw new ExtendedIllegalStateException("path", - ExtendedIllegalStateException.PROPERTY_NOT_CHANGED); + if (impl_ == null) + path_ = path; + else + throw new ExtendedIllegalStateException("path", ExtendedIllegalStateException.PROPERTY_NOT_CHANGED); } void setShareOption(int shareOption) { - if (impl_ == null) - shareOption_ = shareOption; - else - throw new ExtendedIllegalStateException("shareOption", - ExtendedIllegalStateException.PROPERTY_NOT_CHANGED); + if (impl_ == null) + shareOption_ = shareOption; + else + throw new ExtendedIllegalStateException("shareOption", ExtendedIllegalStateException.PROPERTY_NOT_CHANGED); } void setSystem(AS400 system) { - if (impl_ == null) - system_ = system; - else - throw new ExtendedIllegalStateException("system", - ExtendedIllegalStateException.PROPERTY_NOT_CHANGED); + if (impl_ == null) + system_ = system; + else + throw new ExtendedIllegalStateException("system", ExtendedIllegalStateException.PROPERTY_NOT_CHANGED); } /** - Force the system buffers to synchronize with the underlying device. - * @throws IOException If an error occurs while communicating with the system. - **/ // $A1 + * Force the system buffers to synchronize with the underlying device. + * + * @throws IOException If an error occurs while communicating with the system. + **/ public void sync() throws IOException { - if (impl_ == null) - { - if (parent_ == null) + if (impl_ == null) { - Trace.log(Trace.ERROR, "Parent is null, nothing to synchronize."); - // Tolerate the error. - } - else if (parent_ instanceof IFSRandomAccessFile) - { - ((IFSRandomAccessFile)parent_).flush(); - } - else if (parent_ instanceof IFSFileOutputStream) - { - ((IFSFileOutputStream)parent_).flush(); - } + if (parent_ == null) + Trace.log(Trace.ERROR, "Parent is null, nothing to synchronize."); + else if (parent_ instanceof IFSRandomAccessFile) + ((IFSRandomAccessFile) parent_).flush(); + else if (parent_ instanceof IFSFileOutputStream) + ((IFSFileOutputStream) parent_).flush(); + else + Trace.log(Trace.ERROR, "Parent does not have a flush() method: " + parent_.getClass().getName()); + } else - { - Trace.log(Trace.ERROR, "Parent does not have a flush() method: " + - parent_.getClass().getName()); - // Tolerate the error. - } - } - else - { - impl_.sync(); - } + impl_.sync(); } -/** -Determines if this file descriptor represents an open file. -@return true if this file descriptor represents a valid, open file; false otherwise. -**/ - public boolean valid() - { - return isOpen(); + /** + * Determines if this file descriptor represents an open file. + * + * @return true if this file descriptor represents a valid, open file; false otherwise. + **/ + public boolean valid() { + return isOpen(); } } diff --git a/src/main/java/com/ibm/as400/access/IFSFileDescriptorImplProxy.java b/src/main/java/com/ibm/as400/access/IFSFileDescriptorImplProxy.java index 88e9a15f..44b118e0 100644 --- a/src/main/java/com/ibm/as400/access/IFSFileDescriptorImplProxy.java +++ b/src/main/java/com/ibm/as400/access/IFSFileDescriptorImplProxy.java @@ -16,125 +16,107 @@ import java.io.IOException; import java.lang.reflect.InvocationTargetException; - /** - Provides a local proxy implementation for the IFSFileDescriptor class. + * Provides a local proxy implementation for the IFSFileDescriptor class. **/ -class IFSFileDescriptorImplProxy -extends AbstractProxyImpl -implements IFSFileDescriptorImpl +class IFSFileDescriptorImplProxy extends AbstractProxyImpl implements IFSFileDescriptorImpl { - private static final String copyright = "Copyright (C) 1997-2000 International Business Machines Corporation and others."; - - - - IFSFileDescriptorImplProxy () - { - super ("IFSFileDescriptor"); - } - - public void close() - { - try { - connection_.callMethod (pxId_, "close"); - } - catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow (e); - } - } - - public int getCCSID() throws IOException - { - try { - return connection_.callMethod (pxId_, "getCCSID") - .getReturnValueInt(); - } - catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow (e); - } - } - - public long getFileOffset() - { - try { - return connection_.callMethod (pxId_, "getFileOffset") - .getReturnValueLong(); - } - catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow (e); - } - } - - public void incrementFileOffset(long fileOffsetIncrement) - { - try { - connection_.callMethod (pxId_, "incrementFileOffset", - new Class[] { Long.TYPE }, - new Object[] { Long.valueOf(fileOffsetIncrement)}); - } - catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow (e); + private static final String copyright = "Copyright (C) 1997-2000 International Business Machines Corporation and others."; + + IFSFileDescriptorImplProxy() { + super("IFSFileDescriptor"); + } + + @Override + public void close() + { + try { + connection_.callMethod(pxId_, "close"); + } + catch (InvocationTargetException e) { + throw ProxyClientConnection.rethrow(e); + } + } + + @Override + public int getCCSID() throws IOException + { + try { + return connection_.callMethod(pxId_, "getCCSID").getReturnValueInt(); + } + catch (InvocationTargetException e) { + throw ProxyClientConnection.rethrow(e); + } + } + + @Override + public long getFileOffset() + { + try { + return connection_.callMethod(pxId_, "getFileOffset").getReturnValueLong(); + } + catch (InvocationTargetException e) { + throw ProxyClientConnection.rethrow(e); + } + } + + @Override + public void incrementFileOffset(long fileOffsetIncrement) + { + try { + connection_.callMethod(pxId_, "incrementFileOffset", new Class[] { Long.TYPE }, new Object[] { Long.valueOf(fileOffsetIncrement) }); + } + catch (InvocationTargetException e) { + throw ProxyClientConnection.rethrow(e); + } + } + + @Override + public void initialize(long fileOffset, Object parentImpl, String path, int shareOption, AS400Impl system) + { + try { + connection_.callMethod(pxId_, "initialize", + new Class[] { Long.TYPE, Object.class, String.class, Integer.TYPE, AS400Impl.class }, + new Object[] { Long.valueOf(fileOffset), parentImpl, path, Integer.valueOf(shareOption), system }); + } + catch (InvocationTargetException e) { + throw ProxyClientConnection.rethrow(e); + } + } + + @Override + public boolean isOpen() + { + try { + return connection_.callMethod(pxId_, "isOpen").getReturnValueBoolean(); + } + catch (InvocationTargetException e) { + throw ProxyClientConnection.rethrow(e); + } + } + + @Override + public void setFileOffset(long fileOffset) + { + try { + connection_.callMethod(pxId_, "setFileOffset", new Class[] { Long.TYPE }, new Object[] { Long.valueOf(fileOffset) }); + } + catch (InvocationTargetException e) { + throw ProxyClientConnection.rethrow(e); + } + } + + @Override + public void sync() throws IOException + { + try { + connection_.callMethod(pxId_, "sync"); + } + catch (InvocationTargetException e) { + throw ProxyClientConnection.rethrow1(e); + } } - } - - public void initialize(long fileOffset, Object parentImpl, String path, int shareOption, - AS400Impl system) - { - try { - connection_.callMethod (pxId_, "initialize", - new Class[] { Long.TYPE, - Object.class, - String.class, - Integer.TYPE, - AS400Impl.class - }, - new Object[] { Long.valueOf(fileOffset), - parentImpl, - path, - Integer.valueOf(shareOption), - system - }); - } - catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow (e); - } - } - - public boolean isOpen() - { - try { - return connection_.callMethod (pxId_, "isOpen") - .getReturnValueBoolean(); - } - catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow (e); - } - } - - public void setFileOffset(long fileOffset) - { - try { - connection_.callMethod (pxId_, "setFileOffset", - new Class[] { Long.TYPE }, - new Object[] { Long.valueOf(fileOffset)}); - } - catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow (e); - } - } - - public void sync() throws IOException - { - try { - connection_.callMethod (pxId_, "sync"); - } - catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow1 (e); - } - } - } - diff --git a/src/main/java/com/ibm/as400/access/IFSFileDescriptorImplRemote.java b/src/main/java/com/ibm/as400/access/IFSFileDescriptorImplRemote.java index e56797de..3528e732 100644 --- a/src/main/java/com/ibm/as400/access/IFSFileDescriptorImplRemote.java +++ b/src/main/java/com/ibm/as400/access/IFSFileDescriptorImplRemote.java @@ -35,414 +35,366 @@ /** Provides a full remote implementation for the IFSFileDescriptor class. **/ -class IFSFileDescriptorImplRemote -implements IFSFileDescriptorImpl +class IFSFileDescriptorImplRemote implements IFSFileDescriptorImpl { - private static final int UNINITIALIZED = -1; // @B8a - private static final int MAX_BYTES_PER_READ = 16000000; // limit of file server - - // Note: We allow direct access to some of these fields, for performance. @B2C - ConverterImplRemote converter_; - private int fileHandle_ = UNINITIALIZED; // @B8c - int preferredServerCCSID_; - private int fileDataCCSID_ = UNINITIALIZED; - private int fileAsp_ = UNINITIALIZED;//@V4A - private int fileSystemType_ = UNINITIALIZED;//@V4A - int serverDatastreamLevel_; // @B3A - int requestedDatastreamLevel_; // @B6a - private long fileOffset_; - boolean isOpen_; - boolean isOpenAllowed_ = true; - private Object parent_; // The object that instantiated this IFSDescriptor. - String path_ = ""; - byte[] pathnameBytes_; - transient Object serverLock_ = new Object(); - AS400Server server_; // Note: AS400Server is not serializable. - private int shareOption_; - AS400ImplRemote system_; - - private Object fileOffsetLock_ = new Object(); - // Semaphore for synchronizing access to fileOffset_. - - private int maxDataBlockSize_ = 1024; // @B2A - // Used by IFSFileOutputStreamImplRemote, IFSRandomAccessFileImplRemote. - - private boolean determinedSystemVRM_ = false; // @B3A @B4C - private int systemVRM_; // @B3A @B4C - transient int errorRC_; // error return code from most recent request - int patternMatching_ = IFSFile.PATTERN_DEFAULT; // pattern-matching semantics + private static final int UNINITIALIZED = -1; + private static final int MAX_BYTES_PER_READ = 16000000; // limit of file server + + // Note: We allow direct access to some of these fields, for performance. + ConverterImplRemote converter_; + private int fileHandle_ = UNINITIALIZED; + int preferredServerCCSID_; + private int fileDataCCSID_ = UNINITIALIZED; + private int fileAsp_ = UNINITIALIZED; + private int fileSystemType_ = UNINITIALIZED; + int serverDatastreamLevel_; + int requestedDatastreamLevel_; + private long fileOffset_; + boolean isOpen_; + boolean isOpenAllowed_ = true; + private Object parent_; // The object that instantiated this IFSDescriptor. + String path_ = ""; + byte[] pathnameBytes_; + transient Object serverLock_ = new Object(); + AS400Server server_; // Note: AS400Server is not serializable. + private int shareOption_; + AS400ImplRemote system_; + private Object fileOffsetLock_ = new Object(); // Semaphore for synchronizing access to fileOffset_. + private int maxDataBlockSize_ = 1024; + private Integer systemVRM_; + transient int errorRC_; // error return code from most recent request + int patternMatching_ = IFSFile.PATTERN_DEFAULT; // pattern-matching semantics - // Used for debugging only. This should always be false for production. - // When this is false, all debug code will theoretically compile out. - private static final boolean DEBUG = false; // @B3A + // Used for debugging only. This should always be false for production. + private static final boolean DEBUG = false; - //@AC7 Start - String fileOwnerName_ = null; - boolean isDirectory_ = false; - //@AC7 End + String fileOwnerName_ = null; - // Static initialization code. - static - { - // Add all byte stream reply data streams of interest to the - // AS400 server's reply data stream hash table. - AS400Server.addReplyStream(new IFSCloseRep(), AS400.FILE); - AS400Server.addReplyStream(new IFSExchangeAttrRep(), AS400.FILE); - AS400Server.addReplyStream(new IFSLockBytesRep(), AS400.FILE); - AS400Server.addReplyStream(new IFSReturnCodeRep(), AS400.FILE); - AS400Server.addReplyStream(new IFSWriteRep(), AS400.FILE); - AS400Server.addReplyStream(new IFSReadRep(), AS400.FILE); - } + static + { + // Add all byte stream reply data streams of interest to the + // AS400 server's reply data stream hash table. + AS400Server.addReplyStream(new IFSCloseRep(), AS400.FILE); + AS400Server.addReplyStream(new IFSExchangeAttrRep(), AS400.FILE); + AS400Server.addReplyStream(new IFSLockBytesRep(), AS400.FILE); + AS400Server.addReplyStream(new IFSReturnCodeRep(), AS400.FILE); + AS400Server.addReplyStream(new IFSWriteRep(), AS400.FILE); + AS400Server.addReplyStream(new IFSReadRep(), AS400.FILE); + } // Cast an IFSFileDescriptorImpl object into an IFSFileDescriptorImplRemote. // Used by various IFS*ImplRemote classes. static IFSFileDescriptorImplRemote castImplToImplRemote(IFSFileDescriptorImpl fd) { - try - { - return (IFSFileDescriptorImplRemote)fd; - } - catch (ClassCastException e) - { - Trace.log(Trace.ERROR, "Argument is not an instance of IFSFileDescriptorImplRemote", e); - throw new - InternalErrorException(InternalErrorException.UNEXPECTED_EXCEPTION); - } + try { + return (IFSFileDescriptorImplRemote)fd; + } + catch (ClassCastException e) + { + Trace.log(Trace.ERROR, "Argument is not an instance of IFSFileDescriptorImplRemote", e); + throw new InternalErrorException(InternalErrorException.UNEXPECTED_EXCEPTION); + } } - // @B8m - Moved this method here from IFSFileImplRemote. - // Determine if the directory entry can be accessed in the specified - // manner. + // Determine if the directory entry can be accessed in the specified manner. // Returns the returnCode that was set (as a side effect) by createFileHandle(). - int checkAccess(int access, int openOption) // @D1C @B8c - throws IOException, AS400SecurityException + int checkAccess(int access, int openOption) throws IOException, AS400SecurityException { - int fileHandle = UNINITIALIZED; - try { - fileHandle = createFileHandle(access, openOption); - } - finally { - if (fileHandle != UNINITIALIZED) close(fileHandle); // we don't need this handle anymore - } - return errorRC_; + int fileHandle = UNINITIALIZED; + try { + fileHandle = createFileHandle(access, openOption); + } finally { + if (fileHandle != UNINITIALIZED) + close(fileHandle); // we don't need this handle anymore + } + + return errorRC_; } - + @Override public void close() { - try { - close0(); - } - catch (IOException e) { - Trace.log(Trace.ERROR, "Error while closing file " + path_, e); - } + try { + close0(); + } + catch (IOException e) { + Trace.log(Trace.ERROR, "Error while closing file " + path_, e); + } } - - public void close0() throws IOException + public void close0() throws IOException { - isOpen_ = false; - close(fileHandle_); - fileHandle_ = UNINITIALIZED; + isOpen_ = false; + close(fileHandle_); + fileHandle_ = UNINITIALIZED; } void close(int fileHandle) throws IOException { - if (fileHandle == UNINITIALIZED) return; // @B8c + if (fileHandle == UNINITIALIZED) + return; - // Close the file. Send a close request to the server. - ClientAccessDataStream ds = null; - IFSCloseReq req = new IFSCloseReq(fileHandle); - try - { - ds = (ClientAccessDataStream) server_.sendAndReceive(req); - } - catch(ConnectionDroppedException e) - { - Trace.log(Trace.ERROR, "Byte stream connection lost during close", e); - connectionDropped(e); - } - catch(InterruptedException e) - { - Trace.log(Trace.ERROR, "Interrupted", e); - InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); - throwException.initCause(e); - throw throwException; - } + // Close the file. Send a close request to the server. + ClientAccessDataStream ds = null; + IFSCloseReq req = new IFSCloseReq(fileHandle); + try { + ds = (ClientAccessDataStream) server_.sendAndReceive(req); + } + catch (ConnectionDroppedException e) { + Trace.log(Trace.ERROR, "Byte stream connection lost during close", e); + connectionDropped(e); + } + catch (InterruptedException e) { + Trace.log(Trace.ERROR, "Interrupted", e); + InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); + throwException.initCause(e); + throw throwException; + } - // Validate the reply. - if (ds instanceof IFSCloseRep) - { - int rc = ((IFSCloseRep) ds).getReturnCode(); - if (rc != 0) + // Validate the reply. + if (ds instanceof IFSCloseRep) { - Trace.log(Trace.ERROR, "IFSCloseRep return code", rc); - throw new ExtendedIOException(path_, rc); + int rc = ((IFSCloseRep) ds).getReturnCode(); + if (rc != 0) { + Trace.log(Trace.ERROR, "IFSCloseRep return code", rc); + throw new ExtendedIOException(path_, rc); + } } - } - else if (ds instanceof IFSReturnCodeRep) - { - int rc = ((IFSReturnCodeRep) ds).getReturnCode(); - if (rc != IFSReturnCodeRep.SUCCESS) + else if (ds instanceof IFSReturnCodeRep) + { + int rc = ((IFSReturnCodeRep) ds).getReturnCode(); + if (rc != IFSReturnCodeRep.SUCCESS) { + Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", descriptionForReturnCode(rc)); + throw new ExtendedIOException(path_, rc); + } + } + else { - Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", descriptionForReturnCode(rc)); - throw new ExtendedIOException(path_, rc); + Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); + throw new InternalErrorException(Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); } - } - else - { - Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); - throw new - InternalErrorException(Integer.toHexString(ds.getReqRepID()), - InternalErrorException.DATA_STREAM_UNKNOWN); - } } - /** Establishes communications with the server. - - @exception AS400SecurityException If a security or authority error occurs. - @exception IOException If an error occurs while communicating with the server. **/ - void connect() // @B2A - code relocated from IFSFileOutputStreamImplRemote,etc. - throws IOException, AS400SecurityException + void connect() throws IOException, AS400SecurityException { - // Connect to the byte stream server if not already connected. - if (server_ == null) - { - // Ensure that the system has been set. + if (server_ != null) + return; + if (system_ == null) - { - throw new ExtendedIllegalStateException("system", - ExtendedIllegalStateException.PROPERTY_NOT_SET); - } + throw new ExtendedIllegalStateException("system", ExtendedIllegalStateException.PROPERTY_NOT_SET); try { - server_ = system_.getConnection(AS400.FILE, false /*forceNewConnection*/, false /*skip signon server */ ); + server_ = system_.getConnection(AS400.FILE, false /* forceNewConnection */, false /* skip signon server */ ); } - catch(AS400SecurityException e) - { - Trace.log(Trace.ERROR, "Access to byte stream server on '" + - system_.getSystemName() + "' denied.", e); - throw e; + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, "Access to byte stream server on '" + system_.getSystemName() + "' denied.", e); + throw e; } - // Exchange attributes with the server. exchangeServerAttributes(); - } } /** Disconnects from the byte stream server. - @exception ConnectionDroppedException If the connection is dropped unexpectedly. **/ - void connectionDropped(ConnectionDroppedException e) // @B2A - code relocated from IFSFileOutputStreamImplRemote,etc. - throws ConnectionDroppedException + void connectionDropped(ConnectionDroppedException e) throws ConnectionDroppedException { - if (server_ != null) - { - system_.disconnectServer(server_); - server_ = null; - try { close(); } catch (Exception exc) {} // Note: Not relevant for IFSFileImplRemote. - } - Trace.log(Trace.ERROR, "Byte stream connection lost."); - throw e; + if (server_ != null) + { + system_.disconnectServer(server_); + server_ = null; + try { + close(); + } + catch (Exception exc) { } // Note: Not relevant for IFSFileImplRemote. + } + + Trace.log(Trace.ERROR, "Byte stream connection lost."); + throw e; } /** * Copies a file or directory to another file or directory. **/ - boolean copyTo(String destinationPath, boolean replace) - throws AS400SecurityException, IOException + boolean copyTo(String destinationPath, boolean replace) throws AS400SecurityException, IOException { - ClientAccessDataStream ds = null; - IFSCopyReq req = new IFSCopyReq(path_, destinationPath, replace); - try - { - ds = (ClientAccessDataStream) server_.sendAndReceive(req); - } - catch(ConnectionDroppedException e) - { - Trace.log(Trace.ERROR, "Byte stream connection lost during copy", e); - connectionDropped(e); - } - catch(InterruptedException e) - { - Trace.log(Trace.ERROR, "Interrupted", e); - InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); - throwException.initCause(e); - throw throwException; - } - if (ds instanceof IFSReturnCodeRep) - { - int rc = ((IFSReturnCodeRep) ds).getReturnCode(); - if (rc != IFSReturnCodeRep.SUCCESS) + ClientAccessDataStream ds = null; + IFSCopyReq req = new IFSCopyReq(path_, destinationPath, replace); + + try { + ds = (ClientAccessDataStream) server_.sendAndReceive(req); + } + catch(ConnectionDroppedException e) { - String path = (rc == IFSReturnCodeRep.DUPLICATE_DIR_ENTRY_NAME ? destinationPath : path_); - throwSecurityExceptionIfAccessDenied(path,rc); // check for "access denied" - Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", descriptionForReturnCode(rc)); - throw new ExtendedIOException(path, rc); + Trace.log(Trace.ERROR, "Byte stream connection lost during copy", e); + connectionDropped(e); } - return true; - } - else - { + catch(InterruptedException e) + { + Trace.log(Trace.ERROR, "Interrupted", e); + InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); + throwException.initCause(e); + throw throwException; + } + + if (ds instanceof IFSReturnCodeRep) + { + int rc = ((IFSReturnCodeRep) ds).getReturnCode(); + if (rc != IFSReturnCodeRep.SUCCESS) + { + String path = (rc == IFSReturnCodeRep.DUPLICATE_DIR_ENTRY_NAME ? destinationPath : path_); + throwSecurityExceptionIfAccessDenied(path,rc); // check for "access denied" + Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", descriptionForReturnCode(rc)); + throw new ExtendedIOException(path, rc); + } + + return true; + } + Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); - throw new - InternalErrorException(Integer.toHexString(ds.getReqRepID()), - InternalErrorException.DATA_STREAM_UNKNOWN); - } + throw new InternalErrorException(Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); } - // Opens the file for 'read' access, and returns a file handle. - // If failure, sets errorRC_ and returns UNINITIALIZED. - private final int createFileHandle() - throws IOException, AS400SecurityException - { - return createFileHandle(IFSOpenReq.READ_ACCESS, IFSOpenReq.OPEN_OPTION_FAIL_OPEN); + private final int createFileHandle() throws IOException, AS400SecurityException { + return createFileHandle(IFSOpenReq.READ_ACCESS, IFSOpenReq.OPEN_OPTION_FAIL_OPEN); } // Opens the file with specified access and option, and returns a file handle. // If failure, sets errorRC_ and returns UNINITIALIZED. - int createFileHandle(int access, int openOption) // @D1C @B8c - throws IOException, AS400SecurityException + int createFileHandle(int access, int openOption) throws IOException, AS400SecurityException { - int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; - int fileHandle = UNINITIALIZED; - errorRC_ = 0; + int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; + int fileHandle = UNINITIALIZED; + errorRC_ = 0; - // Try to open the file for the specified type of access. - try - { - // Process an open file request. - // For 3rd parm (file data CCSID), specify 0 since we don't care about CCSID. - IFSOpenReq req = new IFSOpenReq(getPathnameAsBytes(), preferredServerCCSID_, - 0, access, IFSOpenReq.DENY_NONE, - IFSOpenReq.NO_CONVERSION, - openOption, serverDatastreamLevel_); // @D1C - ClientAccessDataStream ds = (ClientAccessDataStream) server_.sendAndReceive(req); - if (ds instanceof IFSOpenRep) + // Try to open the file for the specified type of access. + try { - // The open was successful. Close the file if appropriate. - returnCode = IFSReturnCodeRep.SUCCESS; - fileHandle = ((IFSOpenRep) ds).getFileHandle(); // @B8a + // Process an open file request. + // For 3rd parm (file data CCSID), specify 0 since we don't care about CCSID. + IFSOpenReq req = new IFSOpenReq(getPathnameAsBytes(), preferredServerCCSID_, 0, access, + IFSOpenReq.DENY_NONE, IFSOpenReq.NO_CONVERSION, openOption, serverDatastreamLevel_); + ClientAccessDataStream ds = (ClientAccessDataStream) server_.sendAndReceive(req); + if (ds instanceof IFSOpenRep) + { + // The open was successful. Close the file if appropriate. + returnCode = IFSReturnCodeRep.SUCCESS; + fileHandle = ((IFSOpenRep) ds).getFileHandle(); // @B8a + } + else if (ds instanceof IFSReturnCodeRep) + { + returnCode = ((IFSReturnCodeRep) ds).getReturnCode(); + throwSecurityExceptionIfAccessDenied(path_,returnCode); // check for "access denied" + } + else + { + Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); + throw new InternalErrorException(Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); + } } - else if (ds instanceof IFSReturnCodeRep) + catch(ConnectionDroppedException e) { - returnCode = ((IFSReturnCodeRep) ds).getReturnCode(); - throwSecurityExceptionIfAccessDenied(path_,returnCode); // check for "access denied" + Trace.log(Trace.ERROR, "Byte stream server connection lost", e); + connectionDropped(e); } - else + catch(InterruptedException e) { - // Unknown data stream. - Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); - throw new - InternalErrorException(Integer.toHexString(ds.getReqRepID()), - InternalErrorException.DATA_STREAM_UNKNOWN); + Trace.log(Trace.ERROR, "Interrupted", e); + InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); + throwException.initCause(e); + throw throwException; } - } - catch(ConnectionDroppedException e) - { - Trace.log(Trace.ERROR, "Byte stream server connection lost", e); - connectionDropped(e); - } - catch(InterruptedException e) - { - Trace.log(Trace.ERROR, "Interrupted", e); - InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); - throwException.initCause(e); - throw throwException; - } - if (returnCode != IFSReturnCodeRep.SUCCESS) - { - if (Trace.isTraceOn() && Trace.isTraceDiagnosticOn()) + if (returnCode != IFSReturnCodeRep.SUCCESS) { - Trace.log(Trace.DIAGNOSTIC, "Unable to open file " + path_ + ": " + - "IFSReturnCodeRep return code", descriptionForReturnCode(returnCode)); + if (Trace.isTraceOn() && Trace.isTraceDiagnosticOn()) + { + Trace.log(Trace.DIAGNOSTIC, "Unable to open file " + path_ + ": " + + "IFSReturnCodeRep return code", descriptionForReturnCode(returnCode)); + } + + errorRC_ = returnCode; + return UNINITIALIZED; } - errorRC_ = returnCode; - return UNINITIALIZED; - } - return fileHandle; + return fileHandle; } - /** - Exchanges server attributes. - @exception IOException If an error occurs while communicating with the server. - **/ - void exchangeServerAttributes() // @B2A - code relocated from IFSFileOutputStreamImplRemote,etc. - throws IOException, AS400SecurityException + void exchangeServerAttributes() throws IOException, AS400SecurityException { synchronized (serverLock_) { DataStream ds = server_.getExchangeAttrReply(); IFSExchangeAttrRep rep = null; - try { rep = (IFSExchangeAttrRep)ds; } + try { + rep = (IFSExchangeAttrRep)ds; + } catch (ClassCastException e) { - if (ds instanceof IFSReturnCodeRep) - { - int rc = ((IFSReturnCodeRep) ds).getReturnCode(); - throwSecurityExceptionIfAccessDenied(path_,rc); // check for "access denied" - Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", descriptionForReturnCode(rc)); - throw new ExtendedIOException(path_, rc); - } - else { - String className = ( ds == null ? "null" : ds.getClass().getName()); - Trace.log(Trace.ERROR, "Unexpected reply from Exchange Server Attributes: " + className); - throw new InternalErrorException(InternalErrorException.DATA_STREAM_UNKNOWN); - } + if (ds instanceof IFSReturnCodeRep) + { + int rc = ((IFSReturnCodeRep) ds).getReturnCode(); + throwSecurityExceptionIfAccessDenied(path_,rc); // check for "access denied" + Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", descriptionForReturnCode(rc)); + throw new ExtendedIOException(path_, rc); + } + else + { + String className = ( ds == null ? "null" : ds.getClass().getName()); + Trace.log(Trace.ERROR, "Unexpected reply from Exchange Server Attributes: " + className); + throw new InternalErrorException(InternalErrorException.DATA_STREAM_UNKNOWN); + } } // Note: For releases after V5R4, we ask for Datastream Level 16; // for V5R3 thru V5R4, we ask for Datastream Level 8; // for V4R5 thru V5R2, we ask for Datastream Level 2; - // for earlier systems, we ask for Datastream Level 0. // @B6c + // for earlier systems, we ask for Datastream Level 0. if (getSystemVRM() >= 0x00060100) requestedDatastreamLevel_ = 16; else if (getSystemVRM() >= 0x00050300) requestedDatastreamLevel_ = 8; - else if (getSystemVRM() >= 0x00040500) // @B3A @B4C + else if (getSystemVRM() >= 0x00040500) requestedDatastreamLevel_ = 2; else requestedDatastreamLevel_ = 0; + if (rep == null) { ds = null; + try { - int[] preferredCcsids; // @A2A - // Datastream level 8 was introduced in release V5R3. - if (getSystemVRM() >= 0x00050300) - { // System is post-V5R2. - preferredCcsids = new int[] {0x04b0,0x34b0,0xf200}; // UTF-16, new or old Unicode. - } - // Note: Pre-V4R5 systems hang when presented with multiple - // preferred CCSIDs in the exchange of attributes. @B3A @B4C - else if (getSystemVRM() >= 0x00040500) // @B3A @B4C - { // System is V4R5 or later. We can present a list of preferred CCSIDs. - preferredCcsids = new int[] {0x34b0,0xf200}; // New or old Unicode. - } - else - { // System is pre-V4R5. Exchange attr's the old way. - preferredCcsids = new int[] {0xf200}; // Old Unicode only. - } - - // Use GMT date/time, don't use posix style return codes, - // use PC pattern matching semantics, - // maximum data transfer size of 0xffffffff. - ds = server_.sendExchangeAttrRequest( //@B3A + int[] preferredCcsids; + + // Datastream level 8 was introduced in release V5R3. Present a list of preferred CCSIDs, if possible. + if (getSystemVRM() >= 0x00050300) + preferredCcsids = new int[] {0x04b0,0x34b0,0xf200}; // UTF-16, new or old Unicode. + else if (getSystemVRM() >= 0x00040500) + preferredCcsids = new int[] {0x34b0,0xf200}; // New or old Unicode. + else + { + // System is pre-V4R5. Exchange attr's the old way. + // Note: Pre-V4R5 systems hang when presented with multiple + // preferred CCSIDs in the exchange of attributes. + preferredCcsids = new int[] {0xf200}; // Old Unicode only. + } + + // Use GMT date/time, don't use posix style return codes, + // use PC pattern matching semantics, + // maximum data transfer size of 0xffffffff. + ds = server_.sendExchangeAttrRequest( new IFSExchangeAttrReq(true, false, IFSExchangeAttrReq.PC_PATTERN_MATCH, 0xffffffff, requestedDatastreamLevel_, - preferredCcsids)); // @A2C - rep = (IFSExchangeAttrRep)ds; + preferredCcsids)); + rep = (IFSExchangeAttrRep)ds; } catch(ConnectionDroppedException e) { @@ -467,18 +419,19 @@ else if (getSystemVRM() >= 0x00040500) // @B3A @B4C } catch(ClassCastException e) { - if (ds instanceof IFSReturnCodeRep) - { - int rc = ((IFSReturnCodeRep) ds).getReturnCode(); - throwSecurityExceptionIfAccessDenied(path_,rc); // check for "access denied" - Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", descriptionForReturnCode(rc)); - throw new ExtendedIOException(path_, rc); - } - else { - String className = ( ds == null ? "null" : ds.getClass().getName()); - Trace.log(Trace.ERROR, "Unexpected reply from Exchange Server Attributes: " + className); - throw new InternalErrorException(InternalErrorException.DATA_STREAM_UNKNOWN); - } + if (ds instanceof IFSReturnCodeRep) + { + int rc = ((IFSReturnCodeRep) ds).getReturnCode(); + throwSecurityExceptionIfAccessDenied(path_,rc); // check for "access denied" + Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", descriptionForReturnCode(rc)); + throw new ExtendedIOException(path_, rc); + } + else + { + String className = ( ds == null ? "null" : ds.getClass().getName()); + Trace.log(Trace.ERROR, "Unexpected reply from Exchange Server Attributes: " + className); + throw new InternalErrorException(InternalErrorException.DATA_STREAM_UNKNOWN); + } } } @@ -488,26 +441,24 @@ else if (getSystemVRM() >= 0x00040500) // @B3A @B4C maxDataBlockSize_ = ((IFSExchangeAttrRep) rep).getMaxDataBlockSize(); preferredServerCCSID_ = rep.getPreferredCCSID(); serverDatastreamLevel_ = rep.getDataStreamLevel(); - setConverter(ConverterImplRemote.getConverter(preferredServerCCSID_, - system_)); - if (DEBUG) { - System.out.println("DEBUG: IFSFileDescriptorImplRemote.exchangeServerAttributes(): " + - "preferredServerCCSID_ == " + preferredServerCCSID_); - int[] list = rep.getPreferredCCSIDs(); - for (int i=0; i 1) { - if (Trace.traceOn_) Trace.log(Trace.WARNING, "Received multiple replies from listAttributes(fileHandle) (" + - replys.size() + ")"); + // Verify that we got exactly one reply. + if (replys == null) { + if (Trace.traceOn_) Trace.log(Trace.WARNING, "Received null from listAttributes(fileHandle)."); + } + else if (replys.size() == 0) { + if (Trace.traceOn_) Trace.log(Trace.WARNING, "Received no replies from listAttributes(fileHandle)."); + } + else if (replys.size() > 1) { + if (Trace.traceOn_) Trace.log(Trace.WARNING, "Received multiple replies from listAttributes(fileHandle) (" + replys.size() + ")"); + } + else { + reply = (IFSListAttrsRep) replys.elementAt(0); + } } - else { - reply = (IFSListAttrsRep) replys.elementAt(0); + finally + { + if(!usedGlobalHandle && fileHandle != UNINITIALIZED) + close(fileHandle); } - } - finally { - if(!usedGlobalHandle && fileHandle != UNINITIALIZED) //@KKBA - close(fileHandle); - } - return reply; + return reply; } @@ -1083,91 +979,73 @@ else if (replys.size() > 1) { @param offset The first byte of the file to lock (zero is the first byte). @param length The number of bytes to lock. @return A key for undoing this lock. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the server. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the server cannot be started. - @exception UnknownHostException If the system cannot be located. - - @see IFSKey - @see #unlock **/ - IFSKey lock(long length) // @B2A - throws IOException, AS400SecurityException - { - return lock(fileOffset_, length); + IFSKey lock(long length) throws IOException, AS400SecurityException { + return lock(fileOffset_, length); } - IFSKey lock(long offset, // @B2A - code relocated from IFSFileOutputStreamImplRemote,etc. - long length) - throws IOException, AS400SecurityException + IFSKey lock(long offset, long length) throws IOException, AS400SecurityException { - // Assume the arguments have been validated by the caller. + // Assume the arguments have been validated by the caller. - // Attempt to lock the file. - ClientAccessDataStream ds = null; - try - { - // Issue a mandatory, exclusive lock bytes request. Mandatory - // means that the file system enforces the lock by causing any - // operation which conflicts with the lock to fail. Exclusive - // means that only the owner of the lock can read or write the - // locked area. - IFSLockBytesReq req = - new IFSLockBytesReq(fileHandle_, true, false, offset, - length, serverDatastreamLevel_); - ds = (ClientAccessDataStream) server_.sendAndReceive(req); - } - catch(ConnectionDroppedException e) - { - Trace.log(Trace.ERROR, "Byte stream server connection lost"); - connectionDropped(e); - } - catch(InterruptedException e) - { - Trace.log(Trace.ERROR, "Interrupted", e); - InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); - throwException.initCause(e); - throw throwException; - } + // Attempt to lock the file. + ClientAccessDataStream ds = null; + + try + { + // Issue a mandatory, exclusive lock bytes request. Mandatory + // means that the file system enforces the lock by causing any + // operation which conflicts with the lock to fail. Exclusive + // means that only the owner of the lock can read or write the + // locked area. + IFSLockBytesReq req = new IFSLockBytesReq(fileHandle_, true, false, offset, length, serverDatastreamLevel_); + ds = (ClientAccessDataStream) server_.sendAndReceive(req); + } + catch(ConnectionDroppedException e) + { + Trace.log(Trace.ERROR, "Byte stream server connection lost"); + connectionDropped(e); + } + catch(InterruptedException e) + { + Trace.log(Trace.ERROR, "Interrupted", e); + InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); + throwException.initCause(e); + throw throwException; + } - // Verify the reply. - if (ds instanceof IFSLockBytesRep) - { - int rc = ((IFSLockBytesRep) ds).getReturnCode(); - if (rc != 0) + // Verify the reply. + if (ds instanceof IFSLockBytesRep) { - Trace.log(Trace.ERROR, "IFSLockBytesRep return code", rc); - throw new ExtendedIOException(path_, rc); + int rc = ((IFSLockBytesRep) ds).getReturnCode(); + if (rc != 0) + { + Trace.log(Trace.ERROR, "IFSLockBytesRep return code", rc); + throw new ExtendedIOException(path_, rc); + } } - } - else if (ds instanceof IFSReturnCodeRep) - { - int rc = ((IFSReturnCodeRep) ds).getReturnCode(); - if (rc != IFSReturnCodeRep.SUCCESS) + else if (ds instanceof IFSReturnCodeRep) { - throwSecurityExceptionIfAccessDenied(path_,rc); // check for "access denied" - Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", descriptionForReturnCode(rc)); - throw new ExtendedIOException(path_, rc); + int rc = ((IFSReturnCodeRep) ds).getReturnCode(); + if (rc != IFSReturnCodeRep.SUCCESS) + { + throwSecurityExceptionIfAccessDenied(path_,rc); // check for "access denied" + Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", descriptionForReturnCode(rc)); + throw new ExtendedIOException(path_, rc); + } + } + else + { + Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); + throw new InternalErrorException(Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); } - } - else - { - // Unknown data stream. - Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); - throw new - InternalErrorException(Integer.toHexString(ds.getReqRepID()), - InternalErrorException.DATA_STREAM_UNKNOWN); - } - // Generate the key for this lock. - IFSKey key = new IFSKey(fileHandle_, offset, length, true); + // Generate the key for this lock. + IFSKey key = new IFSKey(fileHandle_, offset, length, true); - return key; + return key; } - // Common code used by IFSFileInputStreamImplRemote and IFSRandomAccessFileImplRemote. /** Reads up to length bytes of data from this input stream into data, starting at the array offset dataOffset. @@ -1175,377 +1053,323 @@ else if (ds instanceof IFSReturnCodeRep) @param offset The start offset of the data in the buffer. @param length The maximum number of bytes to read @return The total number of bytes read into the buffer, or -1 if there is no more data because the end of file has been reached. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the server. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the server cannot be started. - @exception UnknownHostException If the system cannot be located. - **/ - int read(byte[] data, // @B2A - code relocated from IFSFileInputStreamImplRemote,etc. - int dataOffset, - int length) - throws IOException, AS400SecurityException + int read(byte[] data, int dataOffset, int length) throws IOException, AS400SecurityException { - // Assume the arguments have been validated by the public class. + // Assume the arguments have been validated by the public class. - // If length is zero then return zero. - if (length == 0) - { - return 0; - } - - int totalBytesRead = 0; - int bytesRemainingToRead = length; - boolean endOfFile = false; - while (totalBytesRead < length && !endOfFile) - { - // If the number of bytes being requested is greater than 16 million, then submit multiple requests for smaller chunks. The File Server has a limit that is somewhat below 16 megabytes (allowing for headers, etc), so 16 _million_ bytes is a safe limit. - - // Issue the read data request. - int bytesToReadThisTime = Math.min(bytesRemainingToRead, MAX_BYTES_PER_READ); - IFSReadReq req = new IFSReadReq(fileHandle_, fileOffset_, - bytesToReadThisTime, serverDatastreamLevel_); - ClientAccessDataStream ds = null; - try - { - ds = (ClientAccessDataStream) server_.sendAndReceive(req); - } - catch(ConnectionDroppedException e) - { - Trace.log(Trace.ERROR, "Byte stream server connection lost"); - connectionDropped(e); - } - catch(InterruptedException e) - { - Trace.log(Trace.ERROR, "Interrupted", e); - InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); - throwException.initCause(e); - throw throwException; - } + // If length is zero then return zero. + if (length == 0) + return 0; - // Receive replies until the end of chain. - boolean endOfChain = false; - int bytesReadByThisRequest = 0; - do + int totalBytesRead = 0; + int bytesRemainingToRead = length; + boolean endOfFile = false; + + while (totalBytesRead < length && !endOfFile) { - if (ds instanceof IFSReadRep) - { - // Copy the data from the reply to the data parameter. - byte[] buffer = ((IFSReadRep) ds).getData(); - if (buffer.length > 0) - { - System.arraycopy(buffer, 0, data, dataOffset, buffer.length); - bytesReadByThisRequest += buffer.length; - dataOffset += buffer.length; - } - else // no data returned. This implies end-of-file (e.g. if file is empty). - { - bytesReadByThisRequest = -1; - endOfFile = true; - } - } - else if (ds instanceof IFSReturnCodeRep) - { - // Check for failure. - int rc = ((IFSReturnCodeRep) ds).getReturnCode(); + // If the number of bytes being requested is greater than 16 million, then submit multiple requests for smaller chunks. + // The File Server has a limit that is somewhat below 16 megabytes (allowing for headers, etc), so 16 _million_ bytes is a safe limit. - if (rc == IFSReturnCodeRep.SUCCESS) - { // It worked, so nothing special to do here. - } - else if (rc == IFSReturnCodeRep.NO_MORE_DATA) - { - // End of file. - bytesReadByThisRequest = -1; - endOfFile = true; - } - else // none of the above - { - throwSecurityExceptionIfAccessDenied(path_,rc); // check for "access denied" - Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", descriptionForReturnCode(rc)); - throw new ExtendedIOException(path_, rc); - } - } - else // neither IFSReadRep nor IFSReturnCodeRep - { - // Unknown data stream. - Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); - throw new - InternalErrorException(Integer.toHexString(ds.getReqRepID()), - InternalErrorException.DATA_STREAM_UNKNOWN); - } - - // Get the next reply if not end of chain. - endOfChain = ((IFSDataStream) ds).isEndOfChain(); - if (!endOfChain) - { - try - { - ds = (ClientAccessDataStream) - server_.receive(req.getCorrelation()); + // Issue the read data request. + int bytesToReadThisTime = Math.min(bytesRemainingToRead, MAX_BYTES_PER_READ); + IFSReadReq req = new IFSReadReq(fileHandle_, fileOffset_, bytesToReadThisTime, serverDatastreamLevel_); + ClientAccessDataStream ds = null; + + try{ + ds = (ClientAccessDataStream) server_.sendAndReceive(req); } catch(ConnectionDroppedException e) { - Trace.log(Trace.ERROR, "Byte stream server connection lost"); - connectionDropped(e); + Trace.log(Trace.ERROR, "Byte stream server connection lost"); + connectionDropped(e); } catch(InterruptedException e) { - Trace.log(Trace.ERROR, "Interrupted", e); - InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); - throwException.initCause(e); - throw throwException; + Trace.log(Trace.ERROR, "Interrupted", e); + InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); + throwException.initCause(e); + throw throwException; + } + + // Receive replies until the end of chain. + boolean endOfChain = false; + int bytesReadByThisRequest = 0; + + do + { + if (ds instanceof IFSReadRep) + { + // Copy the data from the reply to the data parameter. + byte[] buffer = ((IFSReadRep) ds).getData(); + if (buffer.length > 0) + { + System.arraycopy(buffer, 0, data, dataOffset, buffer.length); + bytesReadByThisRequest += buffer.length; + dataOffset += buffer.length; + } + else // no data returned. This implies end-of-file (e.g. if file is empty). + { + bytesReadByThisRequest = -1; + endOfFile = true; + } + } + else if (ds instanceof IFSReturnCodeRep) + { + // Check for failure. + int rc = ((IFSReturnCodeRep) ds).getReturnCode(); + + if (rc == IFSReturnCodeRep.SUCCESS) + { // It worked, so nothing special to do here. + } + else if (rc == IFSReturnCodeRep.NO_MORE_DATA) + { + // End of file. + bytesReadByThisRequest = -1; + endOfFile = true; + } + else // none of the above + { + throwSecurityExceptionIfAccessDenied(path_,rc); // check for "access denied" + Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", descriptionForReturnCode(rc)); + throw new ExtendedIOException(path_, rc); + } + } + else + { + Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); + throw new InternalErrorException(Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); + } + + // Get the next reply if not end of chain. + endOfChain = ((IFSDataStream) ds).isEndOfChain(); + if (!endOfChain) + { + try { + ds = (ClientAccessDataStream) server_.receive(req.getCorrelation()); + } + catch(ConnectionDroppedException e) + { + Trace.log(Trace.ERROR, "Byte stream server connection lost"); + connectionDropped(e); + } + catch(InterruptedException e) + { + Trace.log(Trace.ERROR, "Interrupted", e); + InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); + throwException.initCause(e); + throw throwException; + } + } } - } - } - while (!endOfChain); + while (!endOfChain); - // Advance the file pointer. - if (bytesReadByThisRequest > 0) { - incrementFileOffset(bytesReadByThisRequest); - totalBytesRead += bytesReadByThisRequest; - bytesRemainingToRead -= bytesReadByThisRequest; + // Advance the file pointer. + if (bytesReadByThisRequest > 0) + { + incrementFileOffset(bytesReadByThisRequest); + totalBytesRead += bytesReadByThisRequest; + bytesRemainingToRead -= bytesReadByThisRequest; + } } - } - - // If we have read zero bytes and hit end-of-file, indicate that by returning -1. - // Otherwise return total number of bytes read. - return (endOfFile && totalBytesRead == 0 ? -1 : totalBytesRead); + // If we have read zero bytes and hit end-of-file, indicate that by returning -1. + // Otherwise return total number of bytes read. + return (endOfFile && totalBytesRead == 0 ? -1 : totalBytesRead); } - void setConverter(ConverterImplRemote converter) - { + void setConverter(ConverterImplRemote converter) { converter_ = converter; } - - /** - Sets the cached "file data CCSID" value. - **/ - void setCCSID(int ccsid) - throws IOException - { - fileDataCCSID_ = ccsid; + void setCCSID(int ccsid) throws IOException { + fileDataCCSID_ = ccsid; } public void setFileOffset(long fileOffset) { - synchronized(fileOffsetLock_) - { - fileOffset_ = fileOffset; - } + synchronized (fileOffsetLock_) { + fileOffset_ = fileOffset; + } } - - // @B8a - boolean setLength(long length) - throws IOException, AS400SecurityException + boolean setLength(long length) throws IOException, AS400SecurityException { - // Assume that we are connected to the server. + // Assume that we are connected to the server. - // Prepare to issue a 'change attributes' request. - ClientAccessDataStream ds = null; - - int fileHandle = UNINITIALIZED; + // Prepare to issue a 'change attributes' request. + ClientAccessDataStream ds = null; + int fileHandle = UNINITIALIZED; - try - { - // Open the file for read/write, get a file handle, and call 'change attributes'. - fileHandle = createFileHandle(IFSOpenReq.WRITE_ACCESS, IFSOpenReq.OPEN_OPTION_FAIL_OPEN); - if (fileHandle == UNINITIALIZED) + try { - if (Trace.traceOn_) Trace.log(Trace.ERROR, "Unable to create handle to file " + path_ + ". IFSReturnCodeRep return code", errorRC_); - return false; + // Open the file for read/write, get a file handle, and call 'change attributes'. + fileHandle = createFileHandle(IFSOpenReq.WRITE_ACCESS, IFSOpenReq.OPEN_OPTION_FAIL_OPEN); + if (fileHandle == UNINITIALIZED) + { + if (Trace.traceOn_) Trace.log(Trace.ERROR, "Unable to create handle to file " + path_ + ". IFSReturnCodeRep return code", errorRC_); + return false; + } + + IFSChangeAttrsReq req = new IFSChangeAttrsReq(fileHandle, length, serverDatastreamLevel_); + ds = (ClientAccessDataStream) server_.sendAndReceive(req); + } + catch(ConnectionDroppedException e) + { + Trace.log(Trace.ERROR, "Byte stream server connection lost."); + connectionDropped(e); + } + catch(InterruptedException e) + { + Trace.log(Trace.ERROR, "Interrupted"); + InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); + throwException.initCause(e); + throw throwException; + } + finally { + close(fileHandle); // we don't need this handle anymore } - IFSChangeAttrsReq req = new IFSChangeAttrsReq(fileHandle, length, serverDatastreamLevel_); - ds = (ClientAccessDataStream) server_.sendAndReceive(req); - } - catch(ConnectionDroppedException e) - { - Trace.log(Trace.ERROR, "Byte stream server connection lost."); - connectionDropped(e); - } - catch(InterruptedException e) - { - Trace.log(Trace.ERROR, "Interrupted"); - InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); - throwException.initCause(e); - throw throwException; - } - finally { - close(fileHandle); // we don't need this handle anymore - } - // Verify the reply. - boolean success = false; - if (ds instanceof IFSReturnCodeRep) - { - int rc = ((IFSReturnCodeRep) ds).getReturnCode(); - if (rc == IFSReturnCodeRep.SUCCESS) - success = true; + // Verify the reply. + boolean success = false; + if (ds instanceof IFSReturnCodeRep) + { + int rc = ((IFSReturnCodeRep) ds).getReturnCode(); + if (rc == IFSReturnCodeRep.SUCCESS) + success = true; + else + { + Trace.log(Trace.ERROR, path_ + ": IFSReturnCodeRep return code", descriptionForReturnCode(rc)); + + throwSecurityExceptionIfAccessDenied(path_,rc); // check for "access denied" + } + } else { - throwSecurityExceptionIfAccessDenied(path_,rc); // check for "access denied" - Trace.log(Trace.ERROR, path_ + ": IFSReturnCodeRep return code", descriptionForReturnCode(rc)); + Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); + throw new InternalErrorException(Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); } - } - else - { - // Unknown data stream. - Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); - throw new - InternalErrorException(Integer.toHexString(ds.getReqRepID()), - InternalErrorException.DATA_STREAM_UNKNOWN); - } - // Back off the file pointer if needed. - if (fileOffset_ > length) { - fileOffset_ = length; - } + // Back off the file pointer if needed. + if (fileOffset_ > length) + fileOffset_ = length; - return success; + return success; } - // Ignores fileHandle if state==false. void setOpen(boolean state, int fileHandle) { - if (state == true) - { - if (fileHandle == UNINITIALIZED) - { - Trace.log(Trace.ERROR, "Called setOpen with invalid file handle: " + fileHandle); - throw new - InternalErrorException(InternalErrorException.UNEXPECTED_EXCEPTION); - } - else + if (state == true) { - if (fileHandle != fileHandle_) close(); // close currently-open handle if different - fileHandle_ = fileHandle; + if (fileHandle == UNINITIALIZED) + { + Trace.log(Trace.ERROR, "Called setOpen with invalid file handle: " + fileHandle); + throw new InternalErrorException(InternalErrorException.UNEXPECTED_EXCEPTION); + } + else + { + if (fileHandle != fileHandle_) close(); // close currently-open handle if different + fileHandle_ = fileHandle; + } } - } - isOpen_ = state; + + isOpen_ = state; } - void setOpenAllowed(boolean state) - { - isOpenAllowed_ = state; + void setOpenAllowed(boolean state) { + isOpenAllowed_ = state; } - void setPreferredCCSID(int ccsid) - { - preferredServerCCSID_ = ccsid; + void setPreferredCCSID(int ccsid) { + preferredServerCCSID_ = ccsid; } - void setServer(AS400Server server) - { - server_ = server; + void setServer(AS400Server server) { + server_ = server; } - - /** - Force the system buffers to synchronize with the underlying device. - **/ // $A1 + + @Override public void sync() throws IOException { - if (parent_ == null) - { - Trace.log(Trace.ERROR, "IFSFileDescriptor.sync() was called when parent is null."); - } - // Note: UserSpaceImplRemote creates an IFSFileDescriptorImplRemote directly. - else if (parent_ instanceof IFSRandomAccessFileImplRemote) - { - ((IFSRandomAccessFileImplRemote)parent_).flush(); - } - else if (parent_ instanceof IFSFileOutputStreamImplRemote) - { - ((IFSFileOutputStreamImplRemote)parent_).flush(); - } - else - { - Trace.log(Trace.WARNING, "IFSFileDescriptor.sync() was called " + - "when parent is neither an IFSRandomAccessFile nor an IFSFileOutputStream."); - } + // Note: UserSpaceImplRemote creates an IFSFileDescriptorImplRemote directly. + + if (parent_ == null) + Trace.log(Trace.ERROR, "IFSFileDescriptor.sync() was called when parent is null."); + else if (parent_ instanceof IFSRandomAccessFileImplRemote) + ((IFSRandomAccessFileImplRemote)parent_).flush(); + else if (parent_ instanceof IFSFileOutputStreamImplRemote) + ((IFSFileOutputStreamImplRemote)parent_).flush(); + else + { + Trace.log(Trace.WARNING, "IFSFileDescriptor.sync() was called " + + "when parent is neither an IFSRandomAccessFile nor an IFSFileOutputStream."); + } } - private static final void throwSecurityExceptionIfAccessDenied(String path, int returnCode) - throws AS400SecurityException + private static final void throwSecurityExceptionIfAccessDenied(String path, int returnCode) throws AS400SecurityException { - if (returnCode == IFSReturnCodeRep.ACCESS_DENIED_TO_DIR_ENTRY || - returnCode == IFSReturnCodeRep.ACCESS_DENIED_TO_REQUEST) - { - if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Access denied to file " + path + ". " + - "IFSReturnCodeRep return code", returnCode); - throw new AS400SecurityException(path, AS400SecurityException.DIRECTORY_ENTRY_ACCESS_DENIED); - } + if (returnCode == IFSReturnCodeRep.ACCESS_DENIED_TO_DIR_ENTRY || + returnCode == IFSReturnCodeRep.ACCESS_DENIED_TO_REQUEST) + { + if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Access denied to file " + path + ". " + + "IFSReturnCodeRep return code", returnCode); + throw new AS400SecurityException(path, AS400SecurityException.DIRECTORY_ENTRY_ACCESS_DENIED); + } } /** Undoes a lock on this file. @param key The key for the lock. - - @exception IOException If an error occurs while communicating with the server. - - @see IFSKey - @see #lock **/ - void unlock(IFSKey key) // @B2A - code relocated from IFSFileOutputStreamImplRemote,etc. - throws IOException, AS400SecurityException + void unlock(IFSKey key) throws IOException, AS400SecurityException { - // Assume the argument has been validated by the caller. - - // Verify that this key is compatible with this file. - if (key.fileHandle_ != fileHandle_) - { - Trace.log(Trace.ERROR, "Attempt to use IFSKey on different file stream."); - throw new ExtendedIllegalArgumentException("key", - ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID); - } - - // Attempt to unlock the file. - ClientAccessDataStream ds = null; - // Issue an unlock bytes request. - IFSUnlockBytesReq req = - new IFSUnlockBytesReq(key.fileHandle_, key.offset_, - key.length_, key.isMandatory_, serverDatastreamLevel_); - try - { - ds = (ClientAccessDataStream) server_.sendAndReceive(req); - } - catch(ConnectionDroppedException e) - { - Trace.log(Trace.ERROR, "Byte stream server connection lost"); - connectionDropped(e); - } - catch(InterruptedException e) - { - Trace.log(Trace.ERROR, "Interrupted", e); - InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); - throwException.initCause(e); - throw throwException; - } + // Assume the argument has been validated by the caller. - // Verify the reply. - if (ds instanceof IFSReturnCodeRep) - { - int rc = ((IFSReturnCodeRep) ds).getReturnCode(); - if (rc != IFSReturnCodeRep.SUCCESS) + // Verify that this key is compatible with this file. + if (key.fileHandle_ != fileHandle_) { - throwSecurityExceptionIfAccessDenied(path_,rc); // check for "access denied" - Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", descriptionForReturnCode(rc)); - throw new ExtendedIOException(path_, rc); + Trace.log(Trace.ERROR, "Attempt to use IFSKey on different file stream."); + throw new ExtendedIllegalArgumentException("key", ExtendedIllegalArgumentException.PARAMETER_VALUE_NOT_VALID); } - } - else - { - // Unknown data stream. - Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); - throw new - InternalErrorException(Integer.toHexString(ds.getReqRepID()), - InternalErrorException.DATA_STREAM_UNKNOWN); - } + + // Attempt to unlock the file. + ClientAccessDataStream ds = null; + IFSUnlockBytesReq req = new IFSUnlockBytesReq(key.fileHandle_, key.offset_, + key.length_, key.isMandatory_, serverDatastreamLevel_); + try { + ds = (ClientAccessDataStream) server_.sendAndReceive(req); + } + catch(ConnectionDroppedException e) + { + Trace.log(Trace.ERROR, "Byte stream server connection lost"); + connectionDropped(e); + } + catch(InterruptedException e) + { + Trace.log(Trace.ERROR, "Interrupted", e); + InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); + throwException.initCause(e); + throw throwException; + } + + // Verify the reply. + if (ds instanceof IFSReturnCodeRep) + { + int rc = ((IFSReturnCodeRep) ds).getReturnCode(); + if (rc != IFSReturnCodeRep.SUCCESS) + { + throwSecurityExceptionIfAccessDenied(path_,rc); // check for "access denied" + Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", descriptionForReturnCode(rc)); + throw new ExtendedIOException(path_, rc); + } + } + else + { + Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); + throw new InternalErrorException(Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); + } } @@ -1556,126 +1380,101 @@ void unlock(IFSKey key) // @B2A - code relocated from IFSFileOutputStreamImplRe @param dataOffset The start offset in the data. @param length The number of bytes to write. @parm forceToStorage Whether data must be written before the server replies. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the server. - @exception InterruptedIOException If this thread is interrupted. - @exception ServerStartupException If the server cannot be started. - @exception UnknownHostException If the system cannot be located. - **/ - void writeBytes(byte[] data, // @B2A - int dataOffset, - int length) - throws IOException, AS400SecurityException - { - writeBytes(data, dataOffset, length, false); + void writeBytes(byte[] data, int dataOffset, int length) throws IOException, AS400SecurityException { + writeBytes(data, dataOffset, length, false); } - void writeBytes(byte[] data, // @B2A - code relocated from IFSFileOutputStreamImplRemote,etc. - int dataOffset, - int length, - boolean forceToStorage) - throws IOException, AS400SecurityException + + void writeBytes(byte[] data, int dataOffset, int length, boolean forceToStorage) throws IOException, AS400SecurityException { - // Assume the arguments have been validated by the caller. + // Assume the arguments have been validated by the caller. - // Send write requests until all data has been written. - while(length > 0) - { - // Determine how much data can be written on this request. - int writeLength = (length > maxDataBlockSize_ ? - maxDataBlockSize_ : length); - - // Build the write request. Set the chain bit if there is - // more data to write. - IFSWriteReq req = new IFSWriteReq(fileHandle_, fileOffset_, - data, dataOffset, writeLength, - 0xffff, forceToStorage, serverDatastreamLevel_); - if (length - writeLength > 0) + // Send write requests until all data has been written. + while(length > 0) { - // Indicate that there is more to write. - req.setChainIndicator(1); - } + // Determine how much data can be written on this request. + int writeLength = (length > maxDataBlockSize_ ? maxDataBlockSize_ : length); + + // Build the write request. Set the chain bit if there is + // more data to write. + IFSWriteReq req = new IFSWriteReq(fileHandle_, fileOffset_, + data, dataOffset, writeLength, + 0xffff, forceToStorage, serverDatastreamLevel_); + if (length - writeLength > 0) + { + // Indicate that there is more to write. + req.setChainIndicator(1); + } - // Send the request. - ClientAccessDataStream ds = null; - try - { - // Send the request and receive the response. - ds = (ClientAccessDataStream) server_.sendAndReceive(req); - } - catch(ConnectionDroppedException e) - { - Trace.log(Trace.ERROR, "Byte stream server connection lost"); - connectionDropped(e); - } - catch(InterruptedException e) - { - Trace.log(Trace.ERROR, "Interrupted", e); - InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); - throwException.initCause(e); - throw throwException; - } + // Send the request. + ClientAccessDataStream ds = null; + try { + ds = (ClientAccessDataStream) server_.sendAndReceive(req); + } + catch(ConnectionDroppedException e) + { + Trace.log(Trace.ERROR, "Byte stream server connection lost"); + connectionDropped(e); + } + catch(InterruptedException e) + { + Trace.log(Trace.ERROR, "Interrupted", e); + InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); + throwException.initCause(e); + throw throwException; + } - // Check the reply. - if (ds instanceof IFSWriteRep) - { - IFSWriteRep rep = (IFSWriteRep) ds; - int rc = rep.getReturnCode(); - if (rc != 0) - { - Trace.log(Trace.ERROR, "IFSWriteRep return code", rc); - throw new ExtendedIOException(path_, rc); - } - - // Advance the file pointer the length of the data - // written. - int lengthWritten = writeLength - rep.getLengthNotWritten(); - incrementFileOffset(lengthWritten); - dataOffset += lengthWritten; - length -= lengthWritten; - - // Ensure that all data requested was written. - if (lengthWritten != writeLength) - { - Trace.log(Trace.ERROR, "Incomplete write. Only " + - Integer.toString(lengthWritten) + " bytes of a requested " + - Integer.toString(writeLength) + " were written."); - throw new ExtendedIOException(path_, ExtendedIOException.UNKNOWN_ERROR); - } - } - else if (ds instanceof IFSReturnCodeRep) - { - int rc = ((IFSReturnCodeRep) ds).getReturnCode(); - if (rc != IFSReturnCodeRep.SUCCESS) - { - throwSecurityExceptionIfAccessDenied(path_,rc); // check for "access denied" - Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", descriptionForReturnCode(rc)); - throw new ExtendedIOException(path_, rc); - } - } - else - { - // Unknown data stream. - Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); - throw new - InternalErrorException(Integer.toHexString(ds.getReqRepID()), - InternalErrorException.DATA_STREAM_UNKNOWN); + // Check the reply. + if (ds instanceof IFSWriteRep) + { + IFSWriteRep rep = (IFSWriteRep) ds; + int rc = rep.getReturnCode(); + if (rc != 0) + { + Trace.log(Trace.ERROR, "IFSWriteRep return code", rc); + throw new ExtendedIOException(path_, rc); + } + + // Advance the file pointer the length of the data written. + int lengthWritten = writeLength - rep.getLengthNotWritten(); + incrementFileOffset(lengthWritten); + dataOffset += lengthWritten; + length -= lengthWritten; + + // Ensure that all data requested was written. + if (lengthWritten != writeLength) + { + Trace.log(Trace.ERROR, "Incomplete write. Only " + + Integer.toString(lengthWritten) + " bytes of a requested " + + Integer.toString(writeLength) + " were written."); + throw new ExtendedIOException(path_, ExtendedIOException.UNKNOWN_ERROR); + } + } + else if (ds instanceof IFSReturnCodeRep) + { + int rc = ((IFSReturnCodeRep) ds).getReturnCode(); + if (rc != IFSReturnCodeRep.SUCCESS) + { + throwSecurityExceptionIfAccessDenied(path_,rc); // check for "access denied" + Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", descriptionForReturnCode(rc)); + throw new ExtendedIOException(path_, rc); + } + } + else + { + Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); + throw new InternalErrorException(Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); + } } - } } + public int getServerDatastreamLevel() { - return serverDatastreamLevel_; + return serverDatastreamLevel_; } public void freeHandle(int objectHandle) throws IOException, AS400SecurityException{ - IFSFreeHandleReq req = new IFSFreeHandleReq(objectHandle); - server_.send(req); - } - - public int getASP(boolean isDirectory) throws IOException, AS400SecurityException { - isDirectory_ = isDirectory; - return getASP(); + IFSFreeHandleReq req = new IFSFreeHandleReq(objectHandle); + server_.send(req); } public int getASP() throws IOException, AS400SecurityException @@ -1700,7 +1499,7 @@ public int getASP() throws IOException, AS400SecurityException try { // Issue a Look up request to create an object handle. - IFSLookupReq req = new IFSLookupReq(pathname, preferredServerCCSID_, userHandle, IFSLookupReq.OA12, IFSObjAttrs1.OWNERANAME_ASP_FLAS, 0); //@AC7A + IFSLookupReq req = new IFSLookupReq(pathname, preferredServerCCSID_, userHandle, IFSLookupReq.OA12, IFSObjAttrs1.OWNERANAME_ASP_FLAS, 0); ds = (ClientAccessDataStream) server_.sendAndReceive(req); } catch(ConnectionDroppedException e) @@ -1732,7 +1531,6 @@ else if (ds instanceof IFSReturnCodeRep) } else { - // Unknown data stream. Trace.log(Trace.ERROR, "Unknown reply data stream", ds.getReqRepID()); throw new InternalErrorException(Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); } @@ -1750,85 +1548,70 @@ else if (ds instanceof IFSReturnCodeRep) public String getOwnerNameByUserHandle(boolean forceRetrieve) throws IOException, AS400SecurityException { Trace.log(Trace.INFORMATION, "Owner Name " + (fileOwnerName_ == null? "is null" : fileOwnerName_)); - isDirectory_ = true; + if (forceRetrieve || fileOwnerName_ == null) { Trace.log(Trace.INFORMATION, "force retrieve for Owner Name."); - fileOwnerName_ = getOwnerNameByUserHandle(); - } - - return fileOwnerName_; - } - - public String getOwnerNameByUserHandle() throws IOException, AS400SecurityException - { - ClientAccessDataStream ds = null; - int rc = 0; + ClientAccessDataStream ds = null; + int rc = 0; - // Ensure that we are connected to the server. - connect(); - byte[] pathname = getConverter().stringToByteArray(path_); - - //create user handle - int userHandle = UNINITIALIZED, objectHandle = UNINITIALIZED; - try - { - // In 7.5 and prior releases, need to create user handle for IFS tables to be initialized. - userHandle = (getSystem().getVRM() <= 0x00070500) ? system_.createUserHandle() : 0; - + // Ensure that we are connected to the server. + connect(); + byte[] pathname = getConverter().stringToByteArray(path_); + + //create user handle + int userHandle = UNINITIALIZED, objectHandle = UNINITIALIZED; try { - // Issue a Look up request to create an object handle. - IFSLookupReq req = new IFSLookupReq(pathname, preferredServerCCSID_, userHandle, IFSLookupReq.OA12, IFSObjAttrs1.OWNERANAME_ASP_FLAS, 0); //@AC7A - ds = (ClientAccessDataStream) server_.sendAndReceive(req); - } - catch(ConnectionDroppedException e) - { - Trace.log(Trace.ERROR, "Byte stream server connection lost."); - connectionDropped(e); - } - catch(InterruptedException e) - { - Trace.log(Trace.ERROR, "Interrupted"); - InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); - throwException.initCause(e); - throw throwException; - } + // In 7.5 and prior releases, need to create user handle for IFS tables to be initialized. + userHandle = (getSystem().getVRM() <= 0x00070500) ? system_.createUserHandle() : 0; + + try + { + // Issue a Look up request to create an object handle. + IFSLookupReq req = new IFSLookupReq(pathname, preferredServerCCSID_, userHandle, IFSLookupReq.OA12, IFSObjAttrs1.OWNERANAME_ASP_FLAS, 0); + ds = (ClientAccessDataStream) server_.sendAndReceive(req); + } + catch(ConnectionDroppedException e) + { + Trace.log(Trace.ERROR, "Byte stream server connection lost."); + connectionDropped(e); + } + catch(InterruptedException e) + { + Trace.log(Trace.ERROR, "Interrupted"); + InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); + throwException.initCause(e); + throw throwException; + } - // Verify that we got a handle back. - rc = 0; - if (ds instanceof IFSLookupRep) - { - //ownerName = ((IFSLookupRep) ds).getOwnerName(system_.getCcsid()); //@AC7A End - objectHandle = ((IFSLookupRep) ds).getHandle(); - retrieveAttributes(ds, objectHandle); //@AC7A + // Verify that we got a handle back. + rc = 0; + if (ds instanceof IFSLookupRep) + { + objectHandle = ((IFSLookupRep) ds).getHandle(); + retrieveAttributes(ds, objectHandle); //@AC7A + } + else if (ds instanceof IFSReturnCodeRep) + { + rc = ((IFSReturnCodeRep) ds).getReturnCode(); + if (rc != IFSReturnCodeRep.SUCCESS) Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", rc); + throw new ExtendedIOException(path_, rc); + } + else + { + Trace.log(Trace.ERROR, "Unknown reply data stream", ds.getReqRepID()); + throw new InternalErrorException(Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); + } } - else if (ds instanceof IFSReturnCodeRep) - { - rc = ((IFSReturnCodeRep) ds).getReturnCode(); - if (rc != IFSReturnCodeRep.SUCCESS) Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", rc); - throw new ExtendedIOException(path_, rc); - } - else + finally { - // Unknown data stream. - Trace.log(Trace.ERROR, "Unknown reply data stream", ds.getReqRepID()); - throw new InternalErrorException(Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); + if(objectHandle != UNINITIALIZED) + freeHandle(objectHandle); } } - finally - { - if(objectHandle != UNINITIALIZED) - freeHandle(objectHandle); - } - - return (fileOwnerName_ == null ? "" : fileOwnerName_); //@AC7A - } - - public String getFileSystemType(boolean isDirectory) throws IOException, AS400SecurityException - { - isDirectory_ = isDirectory; - return getFileSystemType(); + + return (fileOwnerName_ == null ? "" : fileOwnerName_); } public String getFileSystemType() throws IOException, AS400SecurityException @@ -1885,7 +1668,6 @@ else if (ds instanceof IFSReturnCodeRep) } else { - // Unknown data stream. Trace.log(Trace.ERROR, "Unknown reply data stream", ds.getReqRepID()); throw new InternalErrorException(Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); } @@ -1919,8 +1701,12 @@ else if (ds instanceof IFSReturnCodeRep) private void retrieveAttributes(ClientAccessDataStream ds, int objectHandle) throws IOException, AS400SecurityException { fileAsp_ = ((IFSLookupRep) ds).getASP(); + if (fileAsp_ < 1) fileAsp_ = UNINITIALIZED; + fileOwnerName_ = ((IFSLookupRep) ds).getOwnerName(system_.getCcsid()); + fileDataCCSID_ = ((IFSLookupRep) ds).getCCSID(serverDatastreamLevel_); + if (fileDataCCSID_ < 1) fileDataCCSID_ = UNINITIALIZED; int userHandle = (getSystem().getVRM() <= 0x00070500) ? system_.getUserHandle() : 0; @@ -1956,7 +1742,6 @@ else if (ds instanceof IFSReturnCodeRep) } else { - // Unknown data stream. Trace.log(Trace.ERROR, "Unknown reply data stream", ds.getReqRepID()); throw new InternalErrorException(InternalErrorException.DATA_STREAM_UNKNOWN, Integer.toHexString(ds.getReqRepID()),null); } diff --git a/src/main/java/com/ibm/as400/access/IFSFileEnumeration.java b/src/main/java/com/ibm/as400/access/IFSFileEnumeration.java index 5f9c6c13..e4eb73f3 100644 --- a/src/main/java/com/ibm/as400/access/IFSFileEnumeration.java +++ b/src/main/java/com/ibm/as400/access/IFSFileEnumeration.java @@ -22,34 +22,26 @@ import java.util.Enumeration; import java.util.NoSuchElementException; - -class IFSFileEnumeration -implements Enumeration +class IFSFileEnumeration implements Enumeration { // The block size is hardcoded based on the value chosen by OpNav. // For now, it is not configurable. private static final int MAXIMUM_GET_COUNT_ = 128; private IFSFile[] contents_; - private IFSFile[] contentsPending_; // Staging area for contents_ @A1a + private IFSFile[] contentsPending_; // Staging area for contents_ private IFSFile file_; private IFSFileFilter filter_; private int index_; private String pattern_; - //private String restartName_; - //private byte[] restartID_; // @C3a - private boolean isRestartByNameSupported_; // @A1a - + private boolean isRestartByNameSupported_; - - IFSFileEnumeration(IFSFile file, IFSFileFilter filter, String pattern) - throws AS400SecurityException, IOException + IFSFileEnumeration(IFSFile file, IFSFileFilter filter, String pattern) throws AS400SecurityException, IOException { file_ = file; filter_ = filter; pattern_ = pattern; - // @A1a: // Note from the File Server team on 02/05/01: // "The vnode architecture allows a file system to use the cookie // (Restart Number) or a Restart Name to find the entry @@ -58,23 +50,19 @@ class IFSFileEnumeration // "Restart by name" only works for QSYS.LIB and QDLS. @A1a String path = file_.getPath().toUpperCase(); - int indexOfQSYS = path.indexOf("/QSYS.LIB"); // @D1A - added support to look for /IASPNAME../QSYS.LIB + // TODO AMRA iASP verification is flawed @D1A - added support to look for /IASPNAME../QSYS.LIB + int indexOfQSYS = path.indexOf("/QSYS.LIB"); if (path.startsWith("/QSYS.LIB") || path.startsWith("/QDLS.LIB") || - path.startsWith("/QDLS") || ((indexOfQSYS != -1) && (indexOfQSYS <= 11))) { // @C3a //@D1C - added support to look for /IASPNAME../QSYS.LIB - isRestartByNameSupported_ = true; - contentsPending_ = loadPendingBlock((String)null);// "Prime the pump" with the first block. @A1a @C3c - /*if (contentsPending_ != null) { // @C3a - restartName_ = contentsPending_[contentsPending_.length - 1].getName(); - } */ + path.startsWith("/QDLS") || ((indexOfQSYS != -1) && (indexOfQSYS <= 11))) + { + isRestartByNameSupported_ = true; + contentsPending_ = loadPendingBlock((String)null);// "Prime the pump" with the first block. } - else { // Use "restart by ID". - isRestartByNameSupported_ = false; -//@C3d if (Trace.traceOn_) Trace.log(Trace.WARNING, -//@C3d "Restart-by-name is not supported for directory " + path); - contentsPending_ = loadPendingBlock((byte[])null);// "Prime the pump" with the first block. @C3a - /*if (contentsPending_ != null) { // @C3a - restartID_ = contentsPending_[contentsPending_.length - 1].getRestartID(); - } */ + else + { + // Use "restart by ID". + isRestartByNameSupported_ = false; + contentsPending_ = loadPendingBlock((byte[])null);// "Prime the pump" with the first block. } getNextBlock(); @@ -87,122 +75,139 @@ public boolean hasMoreElements() (contentsPending_ != null)); // @A1c } - - // @A1a @C3c - private IFSFile[] loadPendingBlock(String restartName) - throws AS400SecurityException, IOException + private IFSFile[] loadPendingBlock(String restartName) throws AS400SecurityException, IOException { - IFSFile[] block = null; - // Design note: Using contents_ and contentsPending_ allows us to "look ahead" and detect end-of-list in all situations, including when the number of matching files in the directory is an exact multiple of MAXIMUM_GET_COUNT. - // Continue reading/loading until we have something to return (that @D5A - // didn't all get filtered out) @D5A - do //@D5A - { //@D5A - block = file_.listFiles0(filter_, pattern_, MAXIMUM_GET_COUNT_, restartName); - restartName = file_.getListFiles0LastRestartName(); //@D5A - } //@D5A - while ((block.length == 0) && (file_.getListFiles0LastNumObjsReturned() > 0)); //@D5A - - if (block.length == 0) block = null; // Never return an empty list. - return block; - } + IFSFile[] block = null; + // Design note: Using contents_ and contentsPending_ allows us to "look ahead" and detect end-of-list in all + // situations, including when the number of matching files in the directory is an exact multiple of + // MAXIMUM_GET_COUNT. + // Continue reading/loading until we have something to return (that + // didn't all get filtered out) + do + { + block = file_.listFiles0(filter_, pattern_, MAXIMUM_GET_COUNT_, restartName); + restartName = file_.getListFiles0LastRestartName(); + } + while ((block.length == 0) && (file_.getListFiles0LastNumObjsReturned() > 0)); + if (block.length == 0) + block = null; // Never return an empty list. + + return block; + } - // @C3a - private IFSFile[] loadPendingBlock(byte[] restartID) - throws AS400SecurityException, IOException + private IFSFile[] loadPendingBlock(byte[] restartID) throws AS400SecurityException, IOException { - IFSFile[] block = null; - // Design note: Using contents_ and contentsPending_ allows us to "look ahead" and detect end-of-list in all situations, including when the number of matching files in the directory is an exact multiple of MAXIMUM_GET_COUNT. - // Continue reading/loading until we have something to return (that @D5A - // didn't all get filtered out) @D5A - do //@D5A - { //@D5A - block = file_.listFiles0(filter_, pattern_, MAXIMUM_GET_COUNT_, restartID); - restartID = file_.getListFiles0LastRestartID(); //@D5A - } //@D5A - while ((block.length == 0) && (file_.getListFiles0LastNumObjsReturned() > 0)); //@D5A - - if (block.length == 0) block = null; // Never return an empty list. - return block; - } + IFSFile[] block = null; + + // Design note: Using contents_ and contentsPending_ allows us to "look ahead" and detect end-of-list in all + // situations, including when the number of matching files in the directory is an exact multiple of + // MAXIMUM_GET_COUNT. + // Continue reading/loading until we have something to return (that + // didn't all get filtered out) + do + { + block = file_.listFiles0(filter_, pattern_, MAXIMUM_GET_COUNT_, restartID); + restartID = file_.getListFiles0LastRestartID(); + } + while ((block.length == 0) && (file_.getListFiles0LastNumObjsReturned() > 0)); + if (block.length == 0) + block = null; // Never return an empty list. + + return block; + } // Transfers the "pending block" into the "current block". // Assumes loadPendingBlock() has been called at least once, to initialize contentsPending_. - private void getNextBlock() - throws AS400SecurityException, IOException + private void getNextBlock() throws AS400SecurityException, IOException { - // @A1a - if (contentsPending_ == null) { - if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, - "getNextBlock() was called when contentsPending_==null."); - return; - } - - // Transfer the "pending contents" into "current contents". - contents_ = contentsPending_; - contentsPending_ = null; // @C3M - index_ = 0; - - // If contentsPending held fewer than max_get_count entries, we know that there are no more entries remaining to be read from the server. - // @R5A Above comments are not true, as if there is IFSFileFilter specified, the content_ length will be handled and the length may not get the Max value even if there is still block not read. - - // Note: Prior to V5R2, the file list returned by the "List Contents of Directory" request included "." and "..", which get weeded out by IFSFileImplRemote, so we need to check for (max_get_count - 2). @C3A - if (file_.getListFiles0LastNumObjsReturned() == 0 || !isContainWildcard(pattern_)) { // No objects last time. @D5C If no wildcard in pattern, we only need one time reading as no more will return, otherwise it loops for using restartname //@R5C - // We're done. // @C3C - } - else // previous listFiles0 returned 1 to max_get_count number of objects - { - if (isRestartByNameSupported_) + if (contentsPending_ == null) { - // Load the next block from the system. - contentsPending_ = loadPendingBlock(file_.getListFiles0LastRestartName());// @C3c @D5C + if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "getNextBlock() was called when contentsPending_==null."); + return; } - else + + // Transfer the "pending contents" into "current contents". + contents_ = contentsPending_; + contentsPending_ = null; + index_ = 0; + + // If contentsPending held fewer than max_get_count entries, we know that there are no more entries remaining to + // be read from the server. + // Above comments are not true, as if there is IFSFileFilter specified, the content_ length will be handled + // and the length may not get the Max value even if there is still block not read. + + // Note: Prior to V5R2, the file list returned by the "List Contents of Directory" request included "." and + // "..", which get weeded out by IFSFileImplRemote, so we need to check for (max_get_count - 2). + if (file_.getListFiles0LastNumObjsReturned() == 0 || !isContainWildcard(pattern_)) + { + // No objects last time. If no wildcard in pattern, we only need one time reading as no more will return, + // otherwise it loops for using restartname We're done. + } + else // previous listFiles0 returned 1 to max_get_count number of objects { - // Load the next block from the system. - byte[] restartID = file_.getListFiles0LastRestartID(); - - // See if a zero-valued restartID was returned. - if (isAllZeros(restartID)) - { - if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, - "IFSFileEnumeration::getNextBlock(): A zero-valued restartID was returned."); - - // Try setting the last filename returned, as the "restart name" for the next request. - // Note that this is the only circumstance where the File Server supports "restart by name" for file systems other than QSYS and QDLS. - if (contents_ != null && contents_.length != 0) { - String restartName = contents_[contents_.length-1].getName(); - if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, - "IFSFileEnumeration::getNextBlock(): Specifying restartName '"+restartName+"' for next request."); - contentsPending_ = loadPendingBlock(restartName); - return; + if (isRestartByNameSupported_) + { + // Load the next block from the system. + contentsPending_ = loadPendingBlock(file_.getListFiles0LastRestartName());// @C3c @D5C } - else { - if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, - "IFSFileEnumeration::getNextBlock(): No restartName available from prior reply."); + else + { + // Load the next block from the system. + byte[] restartID = file_.getListFiles0LastRestartID(); + + // See if a zero-valued restartID was returned. + if (isAllZeros(restartID)) + { + if (Trace.traceOn_) + Trace.log(Trace.DIAGNOSTIC, "IFSFileEnumeration::getNextBlock(): A zero-valued restartID was returned."); + + // Try setting the last filename returned, as the "restart name" for the next request. + // Note that this is the only circumstance where the File Server supports "restart by name" for file + // systems other than QSYS and QDLS. + if (contents_ != null && contents_.length != 0) + { + String restartName = contents_[contents_.length - 1].getName(); + if (Trace.traceOn_) + Trace.log(Trace.DIAGNOSTIC, "IFSFileEnumeration::getNextBlock(): Specifying restartName '" + + restartName + "' for next request."); + contentsPending_ = loadPendingBlock(restartName); + return; + } + else + { + if (Trace.traceOn_) + Trace.log(Trace.DIAGNOSTIC, "IFSFileEnumeration::getNextBlock(): No restartName available from prior reply."); + } + } + + contentsPending_ = loadPendingBlock(restartID); } - } - contentsPending_ = loadPendingBlock(restartID);// @C3c @D5C } - } } private static final boolean isAllZeros(byte[] arry) { - if (arry == null || arry.length == 0) return false; - for (int i=0; i0) - return pattern.indexOf("*")!=-1|| pattern.indexOf("?")!=-1; - return false; + // whether a pattern contains wildcard or not + private static boolean isContainWildcard(String pattern) + { + if (pattern != null && pattern.length() > 0) + return pattern.indexOf("*") != -1 || pattern.indexOf("?") != -1; + + return false; } @Override @@ -212,16 +217,14 @@ public IFSFile nextElement() return contents_[index_++]; else if (contentsPending_ == null) throw new NoSuchElementException(); - else { - try { - getNextBlock(); - } - catch(Exception e) { - throw new NoSuchElementException(); - } - return contents_[index_++]; + + try { + getNextBlock(); } + catch (Exception e) { + throw new NoSuchElementException(); + } + + return contents_[index_++]; } - - } diff --git a/src/main/java/com/ibm/as400/access/IFSFileImpl.java b/src/main/java/com/ibm/as400/access/IFSFileImpl.java index bcbc7816..37fdb66e 100644 --- a/src/main/java/com/ibm/as400/access/IFSFileImpl.java +++ b/src/main/java/com/ibm/as400/access/IFSFileImpl.java @@ -22,81 +22,358 @@ import java.io.IOException; /** - Specifies the methods which the implementation objects for the IFSFile class - need to support. + * Specifies the methods which the implementation objects for the IFSFile class need to support. **/ interface IFSFileImpl { - boolean canExecute() throws IOException, AS400SecurityException; - boolean canRead() throws IOException, AS400SecurityException; - boolean canWrite() throws IOException, AS400SecurityException; - void clearCachedAttributes(); //@D8A - boolean copyTo(String path, boolean replace) throws IOException, AS400SecurityException, ObjectAlreadyExistsException; - long created() throws IOException, AS400SecurityException; //@D3a - int createNewFile() throws IOException, AS400SecurityException; - int delete() throws IOException, AS400SecurityException; - int exists() throws IOException, AS400SecurityException; - - long getAvailableSpace(boolean forUserOnly) throws IOException, AS400SecurityException; - long getTotalSpace(boolean forUserOnly) throws IOException, AS400SecurityException; - int getCCSID() throws IOException, AS400SecurityException; - int getCCSIDByUserHandle() throws IOException, AS400SecurityException; //@A2a //@SCc //@V4A - String getOwnerName() throws IOException, AS400SecurityException; - String getOwnerNameByUserHandle() throws IOException, AS400SecurityException; //@SCc //@V4A - String getOwnerNameByUserHandle(boolean forceRetrieve) throws IOException, AS400SecurityException; //@AC7 - int getASP() throws IOException, AS400SecurityException;//@RDA @SAD - String getFileSystemType()throws IOException, AS400SecurityException;//@SAA //@V4A - long getOwnerUID() throws IOException, AS400SecurityException; //@B7a @C0c - String getPathPointedTo() throws IOException, AS400SecurityException; - String getSubtype() throws IOException, AS400SecurityException; //@B5a - int isDirectory() throws IOException, AS400SecurityException; - int isFile() throws IOException, AS400SecurityException; - boolean isHidden() throws IOException, AS400SecurityException; //@D1a - boolean isReadOnly() throws IOException, AS400SecurityException; //@D1a - boolean isSourcePhysicalFile() throws IOException, AS400SecurityException, AS400Exception; - boolean isSymbolicLink() throws IOException, AS400SecurityException; - - long lastAccessed() throws IOException, AS400SecurityException; //@D3a - long lastModified() throws IOException, AS400SecurityException; - long length() throws IOException, AS400SecurityException; - String[] listDirectoryContents(String directoryPath) - throws IOException, AS400SecurityException; - //@A1A Added this method which is similar to listDirectoryContents(), but returns - //an IFSFile array. - IFSCachedAttributes[] listDirectoryDetails(String directoryPattern, - String directoryPath, - int maximumGetCount, // @D4A - String restartName) // @D4A - throws IOException, AS400SecurityException; - //@C3a - IFSCachedAttributes[] listDirectoryDetails(String directoryPattern, - String directoryPath, - int maximumGetCount, - byte[] restartID, //@D7C - boolean allowSortedRequests) //@D7A - throws IOException, AS400SecurityException; - int mkdir(String directory) throws IOException, AS400SecurityException; - int mkdirs() throws IOException, AS400SecurityException; - int renameTo(IFSFileImpl file) - throws IOException, AS400SecurityException; - - boolean setCCSID(int ccsid) throws IOException, AS400SecurityException; - boolean setAccess(int accessType, boolean enableAccess, boolean ownerOnly) throws IOException, AS400SecurityException; - boolean setFixedAttributes(int attributes) throws IOException, AS400SecurityException; //@D1a - boolean setHidden(boolean attribute) throws IOException, AS400SecurityException; //@D1a - boolean setLastModified(long time) throws IOException, AS400SecurityException; - boolean setLength(int length) throws IOException, AS400SecurityException; //@B8a - void setPatternMatching(int patternMatching); - boolean setReadOnly(boolean attribute) throws IOException, AS400SecurityException; //@D1a - void setPath(String path); - void setSorted(boolean sort); - void setSystem(AS400Impl system); - //@AC7 Start - String getFileSystemType(boolean retrieveAll)throws IOException, AS400SecurityException; - int getASP(boolean retrieveAll) throws IOException, AS400SecurityException; - int getCCSID(boolean retrieveAll) throws IOException, AS400SecurityException; - String getOwnerName(boolean retrieveAll) throws IOException, AS400SecurityException; - //@AC7 End + /** + * Determines if the application can execute the integrated file system object represented by this object. If the + * file does not exist, returns false. + * + * @return true if the object exists and is executable by the application; false otherwise. + **/ + boolean canExecute() throws IOException, AS400SecurityException; + /** + * Determines if the application can read from the integrated file system object represented by this object. Note + * that IBM i directories are never readable; only files can be readable. + * + * @return true if the object exists and is readable by the application; false otherwise. + **/ + boolean canRead() throws IOException, AS400SecurityException; + + /** + * Determines if the application can write to the integrated file system object represented by this object. Note + * that IBM i directories are never writable; only files can be writable. + * + * @return true if the object exists and is writeable by the application; false otherwise. + **/ + boolean canWrite() throws IOException, AS400SecurityException; + + /** + * Clear the cached attributes. This is needed when cached attributes need to be refreshed. + **/ + void clearCachedAttributes(); + + /** + * Copies the current file to the specified path. + * + * @return true if successful copy; false otherwise. + **/ + boolean copyTo(String path, boolean replace) throws IOException, AS400SecurityException, ObjectAlreadyExistsException; + + /** + * Determines the time that the integrated file system object represented by this object was created. + * + * @return time object was created. + **/ + long created() throws IOException, AS400SecurityException; + + /** + * If file does not exist, create it. If the file does exist, return an error. The goal is to atomically create a + * new file if and only if the file does not yet exist. + * + * @return 0 on success; an error code is returned on failure. + **/ + int createNewFile() throws IOException, AS400SecurityException; + + /** + * Deletes the integrated file system object represented by this object. + * + * @return 0 on success; an error code is returned on failure. + **/ + int delete() throws IOException, AS400SecurityException; + + /** + * Determines if the integrated file system object represented by this object exists. + * + * @return 0 if object exists; otherwise, an error code is returned. + **/ + int exists() throws IOException, AS400SecurityException; + + /** + * Determines the amount of unused storage space in the file system. + * + * @param forUserOnly Whether to report only the space for the user. If false, report space in entire file system. + * @return The number of bytes of storage available. Returns special value Long.MAX_VALUE if the system reports "no + * maximum". + **/ + long getAvailableSpace(boolean forUserOnly) throws IOException, AS400SecurityException; + + /** + * Determines the total amount of storage space in the file system. + * + * @param forUserOnly Whether to report only the space for the user. If false, report space in entire file system. + * @return The number of bytes of storage. Returns special value Long.MAX_VALUE if the system reports "no maximum". + **/ + long getTotalSpace(boolean forUserOnly) throws IOException, AS400SecurityException; + + /** + * Returns the file's data CCSID. All files in the system's integrated file system are tagged with a CCSID. This + * method returns the value of that tag. If the file is non-existent, returns -1. If the file is a directory and the + * authentication scheme is not password, returns -1. Returns the file's data CCSID. Returns -1 if failure or if + * directory. + **/ + int getCCSID() throws IOException, AS400SecurityException; + int getCCSID(boolean retrieveAll) throws IOException, AS400SecurityException; + + + /** + * Returns the name of the user profile that is the owner of the file. + * + * @return object owner name, or zero-length string if unable to retrieve value. + **/ + String getOwnerName() throws IOException, AS400SecurityException; + String getOwnerName(boolean retrieveAll) throws IOException, AS400SecurityException; + String getOwnerNameByUserHandle(boolean forceRetrieve) throws IOException, AS400SecurityException; + + int getASP() throws IOException, AS400SecurityException;// @RDA @SAD + + String getFileSystemType() throws IOException, AS400SecurityException; + + /** + * Returns the file's owner's "user ID" number. + * + * @return file UID, or -1 if an error occurred. + **/ + long getOwnerUID() throws IOException, AS400SecurityException; + + /** + * Returns the path of the integrated file system object that is directly pointed to by the symbolic link represented + * by this object. Returns null if the file is not a symbolic link, does not exist, or is in an unsupported + * file system. + *

+ * This method is not supported for files in the following file systems: + *

    + *
  • QSYS.LIB + *
  • Independent ASP QSYS.LIB + *
  • QDLS + *
  • QOPT + *
  • QNTC + *
+ * + * @return The path directly pointed to by the symbolic link, or null if the IFS object is not a symbolic + * link or does not exist. Depending on how the symbolic link was defined, the path may be either relative or + * absolute. + **/ + String getPathPointedTo() throws IOException, AS400SecurityException; + + /** + * Retrieve object subtype. + * + * @return Return object subtype. If object does not have a subtype, a zero length strength is returned. + **/ + String getSubtype() throws IOException, AS400SecurityException; + + /** + * Determines if the integrated file system object represented by this object is a directory. + * + * @return 0 if object is a directory; otherwise, error code. + **/ + int isDirectory() throws IOException, AS400SecurityException; + + /** + * Determines if the integrated file system object represented by this object is a "normal" file.
+ * A file is "normal" if it is not a directory or a container of other objects. + * + * @return 0 if object is a file; otherwise, error code. + **/ + int isFile() throws IOException, AS400SecurityException; + + /** + * Determines if the integrated file system object represented by this object has its hidden attribute set. + * + * @return true if object is hidden; otherwise, false. + **/ + boolean isHidden() throws IOException, AS400SecurityException; + + /** + * Determines if the integrated file system object represented by this object has its hidden attribute set. + * + * @return true if object is read-only; otherwise, false. + **/ + boolean isReadOnly() throws IOException, AS400SecurityException; + + /** + * Determines if the file is a "source physical file". + * + * @return true if object is source physical file; otherwise, false. + **/ + boolean isSourcePhysicalFile() throws IOException, AS400SecurityException, AS400Exception; + + /** + * Determines if the integrated file system object represented by this object is a symbolic link. + * + * @return true if symbolic link; otherwise, false. + **/ + boolean isSymbolicLink() throws IOException, AS400SecurityException; + + /** + * Determines the time that the integrated file system object represented by this object was last accessed. + * + * @return time object was last accessed + **/ + long lastAccessed() throws IOException, AS400SecurityException; + + /** + * Determines the time that the integrated file system object represented by this object was last modified. + * + * @return time object was last modified + **/ + long lastModified() throws IOException, AS400SecurityException; + + /** + * Determines the length of the integrated file system object represented by this object. + * + * @return length of object. + */ + long length() throws IOException, AS400SecurityException; + + /** + * List the files/directories in the specified directory. + * + * @param directoryPath + * @return List of object names in specified directory, or null if specified file or directory does not exist. + */ + String[] listDirectoryContents(String directoryPath) throws IOException, AS400SecurityException; + + + /** + * List the files/directories details in the specified directory. + * + * @return List of object attributes, or null if specified file or directory does not exist. + */ + IFSCachedAttributes[] listDirectoryDetails(String directoryPattern, String directoryPath, int maximumGetCount, + String restartName) throws IOException, AS400SecurityException; + + /** + * List the files/directories details in the specified directory. + * + * @return List of object attributes, or null if specified file or directory does not exist. + */ + IFSCachedAttributes[] listDirectoryDetails(String directoryPattern, String directoryPath, int maximumGetCount, + byte[] restartID, boolean allowSortedRequests) throws IOException, AS400SecurityException; + + /** + * Creates an integrated file system directory whose path name is specified by this object. + * + * @param directory Path of directory to create. + * @return 0 for success; otherwise, error return code. + */ + int mkdir(String directory) throws IOException, AS400SecurityException; + + /** + * Creates an integrated file system directory whose path name is specified by this object. In addition, create all + * parent directories as necessary. + * + * @return 0 for success; otherwise, error return code. + **/ + int mkdirs() throws IOException, AS400SecurityException; + + /** + * Renames the integrated file system object specified by this object to have the path name of file. Wildcards + * are not permitted in this file name. + * + * @param file The new file name. + **/ + int renameTo(IFSFileImpl file) throws IOException, AS400SecurityException; + + /** + * Sets the file's "data CCSID" tag. + * + * @param ccsid the CCSID for the file. + * @return true if successful; false otherwise. + */ + boolean setCCSID(int ccsid) throws IOException, AS400SecurityException; + + boolean setAccess(int accessType, boolean enableAccess, boolean ownerOnly) throws IOException, AS400SecurityException; + + /** + * Changes the fixed attributes (read only, hidden, etc.) of the integrated file system object represented by this + * object to attributes. + * + * @param attributes The set of attributes to apply to the object. Note these attributes are not ORed with the + * existing attributes. They replace the existing fixed attributes of the file. + * @return true if successful; false otherwise. + **/ + boolean setFixedAttributes(int attributes) throws IOException, AS400SecurityException; + + /** + * Alters the hidden attribute of the object. If attribute is true, the bit is turned on. If attribute + * is turned off, the bit is turned off. + * + * @param attribute The new state of the hidden attribute. The hidden attribute is the second bit from the right. + * + * @return true if successful; false otherwise. + **/ + boolean setHidden(boolean attribute) throws IOException, AS400SecurityException; + + /** + * Changes the last modified time of the integrated file system object represented by this object to time. + * + * @param time The desired last modification time (measured in milliseconds since January 1, 1970 00:00:00 GMT), or -1 + * to set the last modification time to the current system time. + * + * @return true if successful; false otherwise. + **/ + boolean setLastModified(long time) throws IOException, AS400SecurityException; + + /** + * Sets the length of the integrated file system object represented by this object. The file can be made larger or + * smaller. If the file is made larger, the contents of the new bytes of the file are undetermined. + * + * @param length The new length, in bytes. + * @return true if successful; false otherwise. + **/ + boolean setLength(int length) throws IOException, AS400SecurityException; + + /** + * Sets the pattern-matching behavior used when files are listed by any of the list() or listFiles() + * methods. The default is PATTERN_POSIX. + * + * @param patternMatching Either {@link IFSFile#PATTERN_POSIX PATTERN_POSIX}, {@link IFSFile#PATTERN_POSIX_ALL + * PATTERN_POSIX_ALL}, or {@link IFSFile#PATTERN_OS2 PATTERN_OS2} + **/ + void setPatternMatching(int patternMatching); + + /** + * Alters the read only attribute of the object. If attribute is true, the bit is turned on. If + * attribute is turned off, the bit is turned off. + * + * @param attribute The new state of the read only attribute + * + * @return true if successful; false otherwise. + **/ + boolean setReadOnly(boolean attribute) throws IOException, AS400SecurityException; + + /** + * Sets the file path. + * + * @param path The absolute file path. + **/ + void setPath(String path); + + /** + * Sets the sorting behavior used when files are listed by any of the list() or listFiles() + * methods. The default is false (unsorted). + * + * @param sort If true: Return lists of files in sorted order. If false: Return lists of files in + * whatever order the file system provides. + **/ + void setSorted(boolean sort); + + /** + * Sets the system. + * + * @param system The server object. + **/ + void setSystem(AS400Impl system); + + /** + * Return object description. + * + * @return The object description. + */ + String getDescription() throws IOException, AS400SecurityException; } diff --git a/src/main/java/com/ibm/as400/access/IFSFileImplProxy.java b/src/main/java/com/ibm/as400/access/IFSFileImplProxy.java index 36b17121..eb45e801 100644 --- a/src/main/java/com/ibm/as400/access/IFSFileImplProxy.java +++ b/src/main/java/com/ibm/as400/access/IFSFileImplProxy.java @@ -23,696 +23,605 @@ /** - Provides a local proxy implementation for the IFSFile class. + * Provides a local proxy implementation for the IFSFile class. **/ -class IFSFileImplProxy -extends AbstractProxyImpl -implements IFSFileImpl +class IFSFileImplProxy extends AbstractProxyImpl implements IFSFileImpl { - - IFSFileImplProxy () - { - super ("IFSFile"); - } - - public boolean canExecute() - throws IOException, AS400SecurityException - { - try { - return connection_.callMethodReturnsBoolean (pxId_, "canExecute"); + IFSFileImplProxy() { + super("IFSFile"); } - catch (InvocationTargetException e) { - throw rethrow2 (e); - } - } - public boolean canRead() - throws IOException, AS400SecurityException - { - try { - return connection_.callMethodReturnsBoolean (pxId_, "canRead"); - } - catch (InvocationTargetException e) { - throw rethrow2 (e); + @Override + public boolean canExecute() throws IOException, AS400SecurityException + { + try { + return connection_.callMethodReturnsBoolean(pxId_, "canExecute"); + } + catch (InvocationTargetException e) { + throw rethrow2(e); + } } - } - public boolean canWrite() - throws IOException, AS400SecurityException - { - try { - return connection_.callMethodReturnsBoolean (pxId_, "canWrite"); - } - catch (InvocationTargetException e) { - throw rethrow2 (e); + @Override + public boolean canRead() throws IOException, AS400SecurityException + { + try { + return connection_.callMethodReturnsBoolean(pxId_, "canRead"); + } + catch (InvocationTargetException e) { + throw rethrow2(e); + } } - } - public void clearCachedAttributes() //@D8A - { - try { - connection_.callMethod(pxId_, "clearCachedAttributes"); - } - catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow (e); + @Override + public boolean canWrite() throws IOException, AS400SecurityException + { + try { + return connection_.callMethodReturnsBoolean(pxId_, "canWrite"); + } + catch (InvocationTargetException e) { + throw rethrow2(e); + } } - } - - public boolean copyTo(String path, boolean replace) - throws IOException, AS400SecurityException, ObjectAlreadyExistsException - { - try + @Override + public void clearCachedAttributes() { - return ((Boolean)connection_.callMethod(pxId_, "copyTo", - new Class[] { String.class, Boolean.TYPE }, - new Object[] { path, Boolean.valueOf(replace) }).getReturnValue()).booleanValue(); + try { + connection_.callMethod(pxId_, "clearCachedAttributes"); + } + catch (InvocationTargetException e) { + throw ProxyClientConnection.rethrow(e); + } } - catch (InvocationTargetException e) + + @Override + public boolean copyTo(String path, boolean replace) + throws IOException, AS400SecurityException, ObjectAlreadyExistsException { - throw rethrow3a(e); + try { + return ((Boolean) connection_.callMethod(pxId_, "copyTo", + new Class[] { String.class, Boolean.TYPE }, + new Object[] { path, Boolean.valueOf(replace) }).getReturnValue()).booleanValue(); + } + catch (InvocationTargetException e) { + throw rethrow3a(e); + } } - } - // @D3 created0 is a new method - public long created() - throws IOException, AS400SecurityException - { - try { - return connection_.callMethod (pxId_, "created").getReturnValueLong(); - } - catch (InvocationTargetException e) { - throw rethrow2 (e); + @Override + public long created() throws IOException, AS400SecurityException + { + try { + return connection_.callMethod(pxId_, "created").getReturnValueLong(); + } + catch (InvocationTargetException e) { + throw rethrow2(e); + } } - } - public int createNewFile() - throws IOException, AS400SecurityException - { - try { - return connection_.callMethodReturnsInt (pxId_, "createNewFile"); + @Override + public int createNewFile() throws IOException, AS400SecurityException + { + try { + return connection_.callMethodReturnsInt(pxId_, "createNewFile"); + } + catch (InvocationTargetException e) { + throw rethrow2(e); + } } - catch (InvocationTargetException e) { - throw rethrow2 (e); + + @Override + public int delete() throws IOException, AS400SecurityException + { + try { + return connection_.callMethodReturnsInt(pxId_, "delete"); + } + catch (InvocationTargetException e) { + throw rethrow2(e); + } } - } + @Override + public int exists() throws IOException, AS400SecurityException + { + try { + return connection_.callMethodReturnsInt(pxId_, "exists"); + } + catch (InvocationTargetException e) { + throw rethrow2(e); + } + } + @Override + public int getCCSID(boolean retrieveAll) throws IOException, AS400SecurityException { + return getCCSID(); + } - public int delete() - throws IOException, AS400SecurityException - { - try { - return connection_.callMethodReturnsInt (pxId_, "delete"); + @Override + public int getCCSID() throws IOException, AS400SecurityException + { + try { + return connection_.callMethodReturnsInt(pxId_, "getCCSID"); + } + catch (InvocationTargetException e) { + throw ProxyClientConnection.rethrow2(e); + } } - catch (InvocationTargetException e) { - throw rethrow2 (e); + + @Override + public long getAvailableSpace(boolean forUserOnly) throws IOException, AS400SecurityException + { + try { + return connection_.callMethod(pxId_, "getAvailableSpace", + new Class[] { Boolean.TYPE }, + new Object[] { Boolean.valueOf(forUserOnly) }).getReturnValueLong(); + } + catch (InvocationTargetException e) { + throw ProxyClientConnection.rethrow2(e); + } + } + + @Override + public long getTotalSpace(boolean forUserOnly) throws IOException, AS400SecurityException + { + try { + return connection_.callMethod(pxId_, "getTotalSpace", + new Class[] { Boolean.TYPE }, + new Object[] { Boolean.valueOf(forUserOnly) }).getReturnValueLong(); + } + catch (InvocationTargetException e) { + throw ProxyClientConnection.rethrow2(e); + } } - } - public int exists() - throws IOException, AS400SecurityException - { - try { - return connection_.callMethodReturnsInt (pxId_, "exists"); + @Override + public String getOwnerName(boolean retrieveAll) throws IOException, AS400SecurityException { + return getOwnerName(); } - catch (InvocationTargetException e) { - throw rethrow2 (e); + + @Override + public String getOwnerName() throws IOException, AS400SecurityException + { + try { + return (String) connection_.callMethod(pxId_, "getOwnerName").getReturnValue(); + } + catch (InvocationTargetException e) { + throw ProxyClientConnection.rethrow2(e); + } + } + + @Override + public String getOwnerNameByUserHandle(boolean forceRetrieve) throws IOException, AS400SecurityException { + try { + return (String) connection_.callMethod(pxId_, "getOwnerNameByUserHandle").getReturnValue(); + } + catch (InvocationTargetException e) { + throw ProxyClientConnection.rethrow2(e); + } + } + + @Override + public int getASP() throws IOException, AS400SecurityException + { + try { + return connection_.callMethod(pxId_, "getASP").getReturnValueInt(); + } + catch (InvocationTargetException e) { + throw ProxyClientConnection.rethrow2(e); + } } - } - - //@AC7A Start - public int getCCSID(boolean retrieveAll) throws IOException, AS400SecurityException { - return getCCSID(); - } - //@AC7A End - // @A3a - //@SCd //@T2C - public int getCCSID() - throws IOException, AS400SecurityException + @Override + public String getFileSystemType() throws IOException, AS400SecurityException { - try { - return connection_.callMethodReturnsInt (pxId_, "getCCSID"); - } - catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow2 (e); - } - } - //@SCa //@V4C - public int getCCSIDByUserHandle() - throws IOException, AS400SecurityException - { try { - return connection_.callMethod (pxId_, "getCCSIDByUserHandle").getReturnValueInt(); - } + return (String) connection_.callMethod(pxId_, "getFileSystemType").getReturnValue(); + } catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow2 (e); + throw ProxyClientConnection.rethrow2(e); } - } - - public long getAvailableSpace(boolean forUserOnly) - throws IOException, AS400SecurityException - { - try { - return connection_.callMethod (pxId_, "getAvailableSpace", - new Class[] { Boolean.TYPE }, - new Object[] { Boolean.valueOf(forUserOnly) }) - .getReturnValueLong(); - } - catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow2 (e); - } } - public long getTotalSpace(boolean forUserOnly) - throws IOException, AS400SecurityException + @Override + public long getOwnerUID() throws IOException, AS400SecurityException { - try { - return connection_.callMethod (pxId_, "getTotalSpace", - new Class[] { Boolean.TYPE }, - new Object[] { Boolean.valueOf(forUserOnly) }) - .getReturnValueLong(); - } - catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow2 (e); - } - } - - //@AC7A Start - public String getOwnerName(boolean retrieveAll) throws IOException, AS400SecurityException { - return getOwnerName(); + try { + return connection_.callMethod(pxId_, "getOwnerUID").getReturnValueLong(); + } + catch (InvocationTargetException e) { + throw ProxyClientConnection.rethrow2(e); + } } - //@AC7A End - //@SCd @T2C - public String getOwnerName() - throws IOException, AS400SecurityException + @Override + public String getPathPointedTo() throws IOException, AS400SecurityException { - try { - return (String)connection_.callMethod (pxId_, "getOwnerName").getReturnValue(); - } - catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow2 (e); - } - } - - //@AC7A Start - public String getOwnerNameByUserHandle(boolean forceRetrieve) throws IOException, AS400SecurityException { - return getOwnerNameByUserHandle(); - } - //@AC7A End - - //@SCa - public String getOwnerNameByUserHandle() - throws IOException, AS400SecurityException - { try { - return (String)connection_.callMethod (pxId_, "getOwnerNameByUserHandle").getReturnValue(); + return (String) connection_.callMethod(pxId_, "getPathPointedTo").getReturnValue(); } catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow2 (e); + throw ProxyClientConnection.rethrow2(e); } - } + } - //@RDA @SAD - /*public int getASP() - throws IOException, AS400SecurityException - { + @Override + public String getSubtype() throws IOException, AS400SecurityException + { try { - return connection_.callMethod (pxId_, "getASP").getReturnValueInt(); + return (String) connection_.callMethod(pxId_, "getSubtype").getReturnValue(); } catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow2 (e); + throw ProxyClientConnection.rethrow2(e); } - }*/ - - //@SAA - -//@AC7A Start - public int getASP(boolean isDirectory) throws IOException, AS400SecurityException{ - return getASP(); - } -//@AC7A End - - public int getASP() - throws IOException, AS400SecurityException - { + } + + @Override + public int isDirectory() throws IOException, AS400SecurityException + { try { - return connection_.callMethod(pxId_, "getASP").getReturnValueInt(); + return connection_.callMethodReturnsInt(pxId_, "isDirectory"); } catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow2 (e); + throw rethrow2(e); } - } - -//@AC7A Start - public String getFileSystemType(boolean isDirectory) throws IOException, AS400SecurityException { - return getFileSystemType(); } -//@AC7A End - - //@SAA - public String getFileSystemType() - throws IOException, AS400SecurityException - { + + @Override + public int isFile() throws IOException, AS400SecurityException + { try { - return (String) connection_.callMethod (pxId_, "getUserHandleSeed").getReturnValue(); + return connection_.callMethodReturnsInt(pxId_, "isFile"); } catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow2 (e); + throw rethrow2(e); } - } - // @B7a - public long getOwnerUID() - throws IOException, AS400SecurityException // @C0c - { - try { - return connection_.callMethod (pxId_, "getOwnerUID").getReturnValueLong(); // @C0c - } - catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow2 (e); - } } - public String getPathPointedTo() - throws IOException, AS400SecurityException + @Override + public boolean isHidden() throws IOException, AS400SecurityException { - try { - return (String)connection_.callMethod (pxId_, "getPathPointedTo") - .getReturnValue(); - } - catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow2 (e); - } + try { + return connection_.callMethodReturnsBoolean(pxId_, "isHidden"); + } + catch (InvocationTargetException e) { + throw rethrow2(e); + } } - // @B5a - public String getSubtype() - throws IOException, AS400SecurityException + @Override + public boolean isReadOnly() throws IOException, AS400SecurityException { - try { - return (String)connection_.callMethod (pxId_, "getSubtype") - .getReturnValue(); - } - catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow2 (e); - } + try { + return connection_.callMethodReturnsBoolean(pxId_, "isReadOnly"); + } + catch (InvocationTargetException e) { + throw rethrow2(e); + } } - public int isDirectory() - throws IOException, AS400SecurityException + @Override + public boolean isSourcePhysicalFile() throws IOException, AS400SecurityException, AS400Exception { - try { - return connection_.callMethodReturnsInt (pxId_, "isDirectory"); - } - catch (InvocationTargetException e) { - throw rethrow2 (e); - } + try { + return connection_.callMethodReturnsBoolean(pxId_, "isSymbolicLink"); + } + catch (InvocationTargetException e) { + throw rethrow3(e); + } } - public int isFile() - throws IOException, AS400SecurityException + @Override + public boolean isSymbolicLink() throws IOException, AS400SecurityException { - try { - return connection_.callMethodReturnsInt (pxId_, "isFile"); - } - catch (InvocationTargetException e) { - throw rethrow2 (e); - } + try { + return connection_.callMethodReturnsBoolean(pxId_, "isSymbolicLink"); + } + catch (InvocationTargetException e) { + throw rethrow2(e); + } } - // @D1 - new method because of changes to java.io.file in Java 2. - public boolean isHidden() - throws IOException, AS400SecurityException + @Override + public long lastAccessed() throws IOException, AS400SecurityException { - try { - return connection_.callMethodReturnsBoolean (pxId_, "isHidden"); - } - catch (InvocationTargetException e) { - throw rethrow2 (e); - } + try { + return connection_.callMethod(pxId_, "lastAccessed").getReturnValueLong(); + } + catch (InvocationTargetException e) { + throw rethrow2(e); + } } - // @D1 - new method because of changes to java.io.file in Java 2. - public boolean isReadOnly() - throws IOException, AS400SecurityException + @Override + public long lastModified() throws IOException, AS400SecurityException { - try { - return connection_.callMethodReturnsBoolean (pxId_, "isReadOnly"); - } - catch (InvocationTargetException e) { - throw rethrow2 (e); - } + try { + return connection_.callMethod(pxId_, "lastModified").getReturnValueLong(); + } + catch (InvocationTargetException e) { + throw rethrow2(e); + } } - public boolean isSourcePhysicalFile() - throws IOException, AS400SecurityException, AS400Exception + @Override + public long length() throws IOException, AS400SecurityException { - try { - return connection_.callMethodReturnsBoolean (pxId_, "isSymbolicLink"); - } - catch (InvocationTargetException e) { - throw rethrow3 (e); - } + try { + return connection_.callMethod(pxId_, "length").getReturnValueLong(); + } + catch (InvocationTargetException e) { + throw rethrow2(e); + } } - public boolean isSymbolicLink() - throws IOException, AS400SecurityException + @Override + public String[] listDirectoryContents(String directoryPath) throws IOException, AS400SecurityException { - try { - return connection_.callMethodReturnsBoolean (pxId_, "isSymbolicLink"); - } - catch (InvocationTargetException e) { - throw rethrow2 (e); - } + try { + return (String[]) connection_.callMethod(pxId_, "listDirectoryContents", + new Class[] { String.class }, + new Object[] { directoryPath }).getReturnValue(); + } + catch (InvocationTargetException e) { + throw rethrow2(e); + } } - // @D3 lastAccessed0 is a new method - public long lastAccessed() - throws IOException, AS400SecurityException + @Override + public IFSCachedAttributes[] listDirectoryDetails(String directoryPattern, String directoryPath, int maxGetCount, String restartName) + throws IOException, AS400SecurityException { - try { - return connection_.callMethod (pxId_, "lastAccessed").getReturnValueLong(); - } - catch (InvocationTargetException e) { - throw rethrow2 (e); - } + try { + return (IFSCachedAttributes[]) connection_ + .callMethod(pxId_, "listDirectoryDetails", + new Class[] { String.class, String.class, Integer.TYPE, String.class }, + new Object[] { directoryPattern, directoryPath, Integer.valueOf(maxGetCount), restartName }) + .getReturnValue(); + } + catch (InvocationTargetException e) { + throw rethrow2(e); + } } - public long lastModified() - throws IOException, AS400SecurityException + @Override + public IFSCachedAttributes[] listDirectoryDetails(String directoryPattern, String directoryPath, int maxGetCount, byte[] restartID, boolean allowSortedRequests) + throws IOException, AS400SecurityException { - try { - return connection_.callMethod (pxId_, "lastModified").getReturnValueLong(); - } - catch (InvocationTargetException e) { - throw rethrow2 (e); - } + try { + return (IFSCachedAttributes[]) connection_.callMethod (pxId_, "listDirectoryDetails", + new Class[] { String.class, String.class, Integer.TYPE, byte[].class, Boolean.TYPE }, + new Object[] { directoryPattern, directoryPath, Integer.valueOf(maxGetCount), restartID, Boolean.valueOf(allowSortedRequests) }) + .getReturnValue(); + } + catch (InvocationTargetException e) { + throw rethrow2 (e); + } } - public long length() - throws IOException, AS400SecurityException + @Override + public int mkdir(String directory) throws IOException, AS400SecurityException { - try { - return connection_.callMethod (pxId_, "length").getReturnValueLong(); - } - catch (InvocationTargetException e) { - throw rethrow2 (e); - } + try { + return connection_.callMethod(pxId_, "mkdir", new Class[] { String.class }, new Object[] { directory }).getReturnValueInt(); + } + catch (InvocationTargetException e) { + throw rethrow2(e); + } } - - // @A1A - // List the files/directories in the specified directory. - public String[] listDirectoryContents(String directoryPath) - throws IOException, AS400SecurityException + @Override + public int mkdirs() throws IOException, AS400SecurityException { - try { - return (String[]) connection_.callMethod (pxId_, "listDirectoryContents", - new Class[] { String.class }, - new Object[] { directoryPath }) - .getReturnValue(); - } - catch (InvocationTargetException e) { - throw rethrow2 (e); - } + try { + return connection_.callMethodReturnsInt(pxId_, "mkdirs"); + } + catch (InvocationTargetException e) { + throw rethrow2(e); + } } - // @A2A - // List the file/directory details in the specified directory. - public IFSCachedAttributes[] listDirectoryDetails(String directoryPattern, - String directoryPath, - int maxGetCount, // @D4A - String restartName) // @D4A - throws IOException, AS400SecurityException + @Override + public int renameTo(IFSFileImpl file) throws IOException, AS400SecurityException { - try { - return (IFSCachedAttributes[]) connection_.callMethod (pxId_, "listDirectoryDetails", - new Class[] { String.class, String.class, Integer.TYPE, String.class }, // @D4C - new Object[] { directoryPattern, directoryPath, Integer.valueOf(maxGetCount), restartName }) // @D4C - .getReturnValue(); - } - catch (InvocationTargetException e) { - throw rethrow2 (e); - } + try { + return connection_.callMethod(pxId_, "renameTo", new Class[] { IFSFileImpl.class }, new Object[] { file }).getReturnValueInt(); + } + catch (InvocationTargetException e) { + throw rethrow2(e); + } } - // @C3A - // List the file/directory details in the specified directory. - public IFSCachedAttributes[] listDirectoryDetails(String directoryPattern, - String directoryPath, - int maxGetCount, - byte[] restartID, - boolean allowSortedRequests) //@D7C - throws IOException, AS400SecurityException - { - try { - return (IFSCachedAttributes[]) connection_.callMethod (pxId_, "listDirectoryDetails", - new Class[] { String.class, String.class, Integer.TYPE, byte[].class, Boolean.TYPE }, - new Object[] { directoryPattern, directoryPath, Integer.valueOf(maxGetCount), restartID, Boolean.valueOf(allowSortedRequests) })//@D7C - .getReturnValue(); - } - catch (InvocationTargetException e) { - throw rethrow2 (e); - } - } - public int mkdir(String directory) - throws IOException, AS400SecurityException + private static InternalErrorException rethrow2(InvocationTargetException e) throws IOException, AS400SecurityException { - try { - return connection_.callMethod (pxId_, "mkdir", - new Class[] { String.class }, - new Object[] { directory }) - .getReturnValueInt(); - } - catch (InvocationTargetException e) { - throw rethrow2 (e); - } - } + Throwable e2 = e.getTargetException(); + if (e2 instanceof IOException) + throw (IOException) e2; + else if (e2 instanceof AS400SecurityException) + throw (AS400SecurityException) e2; - public int mkdirs() - throws IOException, AS400SecurityException - { - try { - return connection_.callMethodReturnsInt (pxId_, "mkdirs"); - } - catch (InvocationTargetException e) { - throw rethrow2 (e); - } + return ProxyClientConnection.rethrow(e); } - public int renameTo(IFSFileImpl file) - throws IOException, AS400SecurityException + private static InternalErrorException rethrow3 (InvocationTargetException e) throws IOException, AS400SecurityException, AS400Exception { - try { - return connection_.callMethod (pxId_, "renameTo", - new Class[] { IFSFileImpl.class }, - new Object[] { file }) - .getReturnValueInt(); - } - catch (InvocationTargetException e) { - throw rethrow2 (e); - } - } + Throwable e2 = e.getTargetException(); + if (e2 instanceof IOException) + throw (IOException) e2; + else if (e2 instanceof AS400SecurityException) + throw (AS400SecurityException) e2; + else if (e2 instanceof AS400Exception) + throw (AS400Exception) e2; - - private static InternalErrorException rethrow2 (InvocationTargetException e) - throws IOException, AS400SecurityException - { - Throwable e2 = e.getTargetException (); - if (e2 instanceof IOException) - throw (IOException) e2; - else if (e2 instanceof AS400SecurityException) - throw (AS400SecurityException) e2; - else - return ProxyClientConnection.rethrow (e); + return ProxyClientConnection.rethrow(e); } - private static InternalErrorException rethrow3 (InvocationTargetException e) - throws IOException, AS400SecurityException, AS400Exception + private static InternalErrorException rethrow3a (InvocationTargetException e) throws IOException, AS400SecurityException, ObjectAlreadyExistsException { - Throwable e2 = e.getTargetException (); - if (e2 instanceof IOException) - throw (IOException) e2; - else if (e2 instanceof AS400SecurityException) - throw (AS400SecurityException) e2; - else if (e2 instanceof AS400Exception) - throw (AS400Exception) e2; - else - return ProxyClientConnection.rethrow (e); - } + Throwable e2 = e.getTargetException(); + if (e2 instanceof IOException) + throw (IOException) e2; + else if (e2 instanceof AS400SecurityException) + throw (AS400SecurityException) e2; + else if (e2 instanceof ObjectAlreadyExistsException) + throw (ObjectAlreadyExistsException) e2; - private static InternalErrorException rethrow3a (InvocationTargetException e) - throws IOException, AS400SecurityException, ObjectAlreadyExistsException - { - Throwable e2 = e.getTargetException (); - if (e2 instanceof IOException) - throw (IOException) e2; - else if (e2 instanceof AS400SecurityException) - throw (AS400SecurityException) e2; - else if (e2 instanceof ObjectAlreadyExistsException) - throw (ObjectAlreadyExistsException) e2; - else - return ProxyClientConnection.rethrow (e); + return ProxyClientConnection.rethrow(e); } - public boolean setAccess(int accessType, boolean enableAccess, boolean ownerOnly) - throws IOException, AS400SecurityException + @Override + public boolean setAccess(int accessType, boolean enableAccess, boolean ownerOnly) throws IOException, AS400SecurityException { - try { - return connection_.callMethod (pxId_, "setAccess", - new Class[] { Integer.TYPE, Boolean.TYPE, Boolean.TYPE }, - new Object[] { Integer.valueOf(accessType), Boolean.valueOf(enableAccess), Boolean.valueOf(ownerOnly) }) - .getReturnValueBoolean(); - } - catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow2 (e); - } + try { + return connection_.callMethod(pxId_, "setAccess", + new Class[] { Integer.TYPE, Boolean.TYPE, Boolean.TYPE }, + new Object[] { Integer.valueOf(accessType), Boolean.valueOf(enableAccess), Boolean.valueOf(ownerOnly) }) + .getReturnValueBoolean(); + } + catch (InvocationTargetException e) { + throw ProxyClientConnection.rethrow2(e); + } } - public boolean setCCSID(int ccsid) - throws IOException, AS400SecurityException + @Override + public boolean setCCSID(int ccsid) throws IOException, AS400SecurityException { - try { - return connection_.callMethod (pxId_, "setCCSID", - new Class[] { Integer.TYPE }, - new Object[] { Integer.valueOf(ccsid) }) - .getReturnValueBoolean(); - } - catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow2 (e); - } + try { + return connection_ + .callMethod(pxId_, "setCCSID", + new Class[] { Integer.TYPE }, new Object[] { Integer.valueOf(ccsid) }) + .getReturnValueBoolean(); + } + catch (InvocationTargetException e) { + throw ProxyClientConnection.rethrow2(e); + } } - - // @D1 - new method because of changes to java.io.file in Java 2. - public boolean setFixedAttributes(int attributes) - throws IOException, AS400SecurityException + @Override + public boolean setFixedAttributes(int attributes) throws IOException, AS400SecurityException { - try { - return connection_.callMethod (pxId_, "setFixedAttributes", - new Class[] { Integer.TYPE }, - new Object[] { Integer.valueOf(attributes) }) - .getReturnValueBoolean(); - } - catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow2 (e); - } + try { + return connection_.callMethod(pxId_, "setFixedAttributes", + new Class[] { Integer.TYPE }, + new Object[] { Integer.valueOf(attributes) }).getReturnValueBoolean(); + } + catch (InvocationTargetException e) { + throw ProxyClientConnection.rethrow2(e); + } } - // @D1 - new method because of changes to java.io.file in Java 2. - public boolean setHidden(boolean attribute) - throws IOException, AS400SecurityException + @Override + public boolean setHidden(boolean attribute) throws IOException, AS400SecurityException { - try { - return connection_.callMethod (pxId_, "setHidden", - new Class[] { Boolean.TYPE }, - new Object[] { Boolean.valueOf(attribute) }) - .getReturnValueBoolean(); - } - catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow2 (e); - } + try { + return connection_.callMethod(pxId_, "setHidden", + new Class[] { Boolean.TYPE }, + new Object[] { Boolean.valueOf(attribute) }).getReturnValueBoolean(); + } + catch (InvocationTargetException e) { + throw ProxyClientConnection.rethrow2(e); + } } - public boolean setLastModified(long time) - throws IOException, AS400SecurityException + @Override + public boolean setLastModified(long time) throws IOException, AS400SecurityException { - try { - return connection_.callMethod (pxId_, "setLastModified", - new Class[] { Long.TYPE }, - new Object[] { Long.valueOf(time)}) - .getReturnValueBoolean(); - } - catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow2 (e); - } + try { + return connection_.callMethod (pxId_, "setLastModified", + new Class[] { Long.TYPE }, + new Object[] { Long.valueOf(time)}).getReturnValueBoolean(); + } + catch (InvocationTargetException e) { + throw ProxyClientConnection.rethrow2 (e); + } } - // @B8a - public boolean setLength(int length) - throws IOException, AS400SecurityException + @Override + public boolean setLength(int length) throws IOException, AS400SecurityException { - try { - return connection_.callMethod (pxId_, "setLength", + try { + return connection_.callMethod (pxId_, "setLength", new Class[] { Integer.TYPE }, - new Object[] { Integer.valueOf(length) }) - .getReturnValueBoolean(); - } - catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow2 (e); - } + new Object[] { Integer.valueOf(length) }).getReturnValueBoolean(); + } + catch (InvocationTargetException e) { + throw ProxyClientConnection.rethrow2 (e); + } } + @Override public void setPatternMatching(int patternMatching) { - try { - connection_.callMethod (pxId_, "setPatternMatching", - new Class[] { Integer.TYPE }, - new Object[] { Integer.valueOf(patternMatching) }); - } - catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow (e); - } + try { + connection_.callMethod (pxId_, "setPatternMatching", + new Class[] { Integer.TYPE }, + new Object[] { Integer.valueOf(patternMatching) }); + } + catch (InvocationTargetException e) { + throw ProxyClientConnection.rethrow (e); + } } - // @D1 - new method because of changes to java.io.file in Java 2. - public boolean setReadOnly(boolean attribute) - throws IOException, AS400SecurityException + @Override + public boolean setReadOnly(boolean attribute) throws IOException, AS400SecurityException { - try { - return connection_.callMethod (pxId_, "setReadOnly", - new Class[] { Boolean.TYPE }, - new Object[] { Boolean.valueOf(attribute) }) - .getReturnValueBoolean(); - } - catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow2 (e); - } + try { + return connection_.callMethod(pxId_, "setReadOnly", + new Class[] { Boolean.TYPE }, + new Object[] { Boolean.valueOf(attribute) }).getReturnValueBoolean(); + } + catch (InvocationTargetException e) { + throw ProxyClientConnection.rethrow2 (e); + } } + @Override public void setPath(String path) { - try { - connection_.callMethod (pxId_, "setPath", - new Class[] { String.class }, - new Object[] { path }); - } - catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow (e); - } + try { + connection_.callMethod(pxId_, "setPath", + new Class[] { String.class }, new Object[] { path }); + } + catch (InvocationTargetException e) { + throw ProxyClientConnection.rethrow(e); + } } - /** - Sets the sorting behavior used when files are listed by any of the list() or listFiles() methods. The default is false (unsorted). - @param sort If true: Return lists of files in sorted order. - If false: Return lists of files in whatever order the file system provides. - - **/ + @Override public void setSorted(boolean sort) { - try { - connection_.callMethod (pxId_, "setSorted", - new Class[] { Boolean.TYPE }, - new Object[] { Boolean.valueOf(sort) }); - } - catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow (e); - } + try { + connection_.callMethod (pxId_, "setSorted", + new Class[] { Boolean.TYPE }, + new Object[] { Boolean.valueOf(sort) }); + } + catch (InvocationTargetException e) { + throw ProxyClientConnection.rethrow (e); + } } + @Override public void setSystem(AS400Impl system) { - try { - connection_.callMethod (pxId_, "setSystem", - new Class[] { AS400Impl.class }, - new Object[] { system }); - } - catch (InvocationTargetException e) { - throw ProxyClientConnection.rethrow (e); - } + try { + connection_.callMethod (pxId_, "setSystem", + new Class[] { AS400Impl.class }, + new Object[] { system }); + } + catch (InvocationTargetException e) { + throw ProxyClientConnection.rethrow (e); + } } + @Override + public String getDescription() throws AS400SecurityException, IOException + { + try { + return (String) connection_.callMethod(pxId_, "getDescription").getReturnValue(); + } + catch (InvocationTargetException e) { + throw ProxyClientConnection.rethrow2(e); + } + } } diff --git a/src/main/java/com/ibm/as400/access/IFSFileImplRemote.java b/src/main/java/com/ibm/as400/access/IFSFileImplRemote.java index 380f91a6..83bc775e 100644 --- a/src/main/java/com/ibm/as400/access/IFSFileImplRemote.java +++ b/src/main/java/com/ibm/as400/access/IFSFileImplRemote.java @@ -28,205 +28,184 @@ package com.ibm.as400.access; import java.io.InterruptedIOException; -import java.text.SimpleDateFormat; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Arrays; -import java.util.Date; import java.util.Hashtable; import java.util.Vector; -import java.beans.PropertyVetoException; /** - Provides a full remote implementation for the IFSFile class. + * Provides a full remote implementation for the IFSFile class. **/ -class IFSFileImplRemote -implements IFSFileImpl +class IFSFileImplRemote implements IFSFileImpl { - // Used for debugging only. This should always be false for production. - // When this is false, all debug code will theoretically compile out. - private static final boolean DEBUG = false; // @B2A - - private static final boolean IS_RESTART_NAME = true; // mnemonic for use in argument lists - private static final boolean NO_RESTART_NAME = IS_RESTART_NAME; // mnemonic - private static final boolean SORT_LIST = true; // mnemonic - private static final int NO_MAX_GET_COUNT = -1; // mnemonic - private static final int UNINITIALIZED = -1; - - // Constants for QlgAccess(), from system definitions file "unistd.h" - //private static final int ACCESS_MODE_READ = 0x04; // R_OK: test for read permission - //private static final int ACCESS_MODE_WRITE = 0x02; // W_OK: test for write permission - private static final int ACCESS_MODE_EXECUTE = 0x01; // X_OK: test for execute permission - //private static final int ACCESS_MODE_EXISTS = 0x00; // F_OK: test for existence of file - -//TODO @ZZA - private String ownerName_ = null; - private int fileCcsid_ = -1; + // Used for debugging only. This should always be false for production. + private static final boolean DEBUG = false; - // Static initialization code. - static - { - // Add all byte stream reply data streams of interest to the - // server's reply data stream hash table. - AS400Server.addReplyStream(new IFSListAttrsRep(), AS400.FILE); - AS400Server.addReplyStream(new IFSOpenRep(), AS400.FILE); - AS400Server.addReplyStream(new IFSCreateDirHandleRep(), AS400.FILE); - AS400Server.addReplyStream(new IFSQuerySpaceRep(), AS400.FILE); - AS400Server.addReplyStream(new IFSReturnCodeRep(), AS400.FILE); - AS400Server.addReplyStream(new IFSLookupRep(), AS400.FILE); - AS400Server.addReplyStream(new IFSGetFileSystemRep(), AS400.FILE); - } + private static final boolean IS_RESTART_NAME = true; + private static final boolean NO_RESTART_NAME = IS_RESTART_NAME; + private static final boolean SORT_LIST = true; + private static final int NO_MAX_GET_COUNT = -1; + private static final int UNINITIALIZED = -1; - transient private IFSListAttrsRep attributesReply_; // "list attributes" reply + // Constants for QlgAccess(), from system definitions file "unistd.h" + //private static final int ACCESS_MODE_READ = 0x04; // R_OK: test for read permission + //private static final int ACCESS_MODE_WRITE = 0x02; // W_OK: test for write permission + private static final int ACCESS_MODE_EXECUTE = 0x01; // X_OK: test for execute permission + //private static final int ACCESS_MODE_EXISTS = 0x00; // F_OK: test for existence of file - private IFSFileDescriptorImplRemote fd_ = new IFSFileDescriptorImplRemote(); // @B2A + static + { + // Add all byte stream reply data streams of interest to the + // server's reply data stream hash table. + AS400Server.addReplyStream(new IFSListAttrsRep(), AS400.FILE); + AS400Server.addReplyStream(new IFSOpenRep(), AS400.FILE); + AS400Server.addReplyStream(new IFSCreateDirHandleRep(), AS400.FILE); + AS400Server.addReplyStream(new IFSQuerySpaceRep(), AS400.FILE); + AS400Server.addReplyStream(new IFSReturnCodeRep(), AS400.FILE); + AS400Server.addReplyStream(new IFSLookupRep(), AS400.FILE); + AS400Server.addReplyStream(new IFSGetFileSystemRep(), AS400.FILE); + } - private boolean isSymbolicLink_; - private boolean determinedIsSymbolicLink_; - private boolean sortLists_; // whether file-lists are returned from the File Server in sorted order - private RemoteCommandImpl rmtCmd_; // Impl object for remote command host server. + transient private IFSListAttrsRep attributesReply_; // "list attributes" reply - private byte[] qualifiedFileName_; - private Integer databaseFileAttributes_; + private IFSFileDescriptorImplRemote fd_ = new IFSFileDescriptorImplRemote(); - /** - Determines if the application can execute the integrated file system object represented by this object. If the file does not exist, returns false. - **/ - public boolean canExecute() - throws IOException, AS400SecurityException - { - // Ensure that we are connected to the server. - fd_.connect(); + private Boolean isSymbolicLink_; + private boolean sortLists_; // whether file-lists are returned from the File Server in sorted order + private RemoteCommandImpl rmtCmd_; // Impl object for remote command host server. - return canAccess(ACCESS_MODE_EXECUTE); - } + private byte[] qualifiedFileName_; + private Integer databaseFileAttributes_; - /** - Determines if the applet or application can read from the integrated file system object represented by this object. - **/ - public boolean canRead() - throws IOException, AS400SecurityException - { - // Ensure that we are connected to the server. - fd_.connect(); + @Override + public boolean canExecute() throws IOException, AS400SecurityException + { + // Ensure that we are connected to the server. + fd_.connect(); - int rc = fd_.checkAccess(IFSOpenReq.READ_ACCESS, IFSOpenReq.OPEN_OPTION_FAIL_OPEN); - return (rc == IFSReturnCodeRep.SUCCESS); - // Design note: The QlgAccess() API gives somewhat different results in certain scenarios. - // Using IFSOpenReq appears to be a bit more "thorough". - } + return canAccess(ACCESS_MODE_EXECUTE); + } + @Override + public boolean canRead() throws IOException, AS400SecurityException + { + // Ensure that we are connected to the server. + fd_.connect(); - /** - Determines if the applet or application can write to the integrated file system object represented by this object. - **/ - public boolean canWrite() - throws IOException, AS400SecurityException - { - // Ensure that we are connected to the server. - fd_.connect(); + int rc = fd_.checkAccess(IFSOpenReq.READ_ACCESS, IFSOpenReq.OPEN_OPTION_FAIL_OPEN); + return (rc == IFSReturnCodeRep.SUCCESS); + // Design note: The QlgAccess() API gives somewhat different results in certain scenarios. + // Using IFSOpenReq appears to be a bit more "thorough". + } - int rc = fd_.checkAccess(IFSOpenReq.WRITE_ACCESS, IFSOpenReq.OPEN_OPTION_FAIL_OPEN); - return (rc == IFSReturnCodeRep.SUCCESS); - // Design note: The QlgAccess() API gives somewhat different results in certain scenarios. - // Using IFSOpenReq appears to be a bit more "thorough". - } + @Override + public boolean canWrite() throws IOException, AS400SecurityException + { + // Ensure that we are connected to the server. + fd_.connect(); + int rc = fd_.checkAccess(IFSOpenReq.WRITE_ACCESS, IFSOpenReq.OPEN_OPTION_FAIL_OPEN); + return (rc == IFSReturnCodeRep.SUCCESS); + // Design note: The QlgAccess() API gives somewhat different results in certain scenarios. + // Using IFSOpenReq appears to be a bit more "thorough". + } /** Calls QlgAccess() to determine whether the current user can access the file in the specified mode. If the file does not exist, returns false. Note: The QlgAccess API was introduced in V5R1. **/ - private boolean canAccess(int accessMode) - throws IOException, AS400SecurityException + private boolean canAccess(int accessMode) throws IOException, AS400SecurityException { - // Assume that the caller has already connected to the server. - - if (fd_.getSystemVRM() < 0x00050100) - { - if (Trace.traceOn_) Trace.log(Trace.WARNING, "Server is pre-V5R1, so canAccess() is returning false."); - return false; - } - - // We will call the QlgAccess API, to determine whether the current user can access the file in the specified mode. - // Note: According to the spec for QlgAccess: "If the [user profile] has *ALLOBJ special authority, access() will indicate success for R_OK, W_OK, or X_OK even if none of the permission bits are set." - // Note: QlgAccess() is only _conditionally_ threadsafe. - - boolean result; - try - { - // Create the pgm call object - if (rmtCmd_ == null) { - setupRemoteCommand(); - } - - ProgramParameter[] parameters = new ProgramParameter[] - { - // Parameter 1: Qlg_Path_Name_T *Path_Name (input) : - new ProgramParameter(ProgramParameter.PASS_BY_REFERENCE, createPathName()), - // Parameter 2: int amode (input) : - new ProgramParameter(ProgramParameter.PASS_BY_VALUE, BinaryConverter.intToByteArray(accessMode)) - }; + // Assume that the caller has already connected to the server. - // Call the service program. - byte[] returnedBytes = rmtCmd_.runServiceProgram("QSYS", "QP0LLIB1", "QlgAccess", parameters); - if (returnedBytes == null) + if (fd_.getSystemVRM() < 0x00050100) { - Trace.log(Trace.ERROR, "Call to QlgAccess() returned null."); - throw new AS400Exception(rmtCmd_.getMessageList()); + if (Trace.traceOn_) Trace.log(Trace.WARNING, "Server is pre-V5R1, so canAccess() is returning false."); + return false; } - int returnValue = BinaryConverter.byteArrayToInt(returnedBytes, 0); + // We will call the QlgAccess API, to determine whether the current user can access the file in the specified + // mode. + // Note: According to the spec for QlgAccess: "If the [user profile] has *ALLOBJ special authority, access() will + // indicate success for R_OK, W_OK, or X_OK even if none of the permission bits are set." + // Note: QlgAccess() is only _conditionally_ threadsafe. - switch (returnValue) + boolean result; + try { - case -1: // this indicates that we got an "errno" back + // Create the pgm call object + if (rmtCmd_ == null) + setupRemoteCommand(); + + ProgramParameter[] parameters = new ProgramParameter[] { + // Parameter 1: Qlg_Path_Name_T *Path_Name (input) : + new ProgramParameter(ProgramParameter.PASS_BY_REFERENCE, createPathName()), + // Parameter 2: int amode (input) : + new ProgramParameter(ProgramParameter.PASS_BY_VALUE, BinaryConverter.intToByteArray(accessMode)) + }; + + // Call the service program. + byte[] returnedBytes = rmtCmd_.runServiceProgram("QSYS", "QP0LLIB1", "QlgAccess", parameters); + if (returnedBytes == null) { - result = false; - int errno = BinaryConverter.byteArrayToInt(returnedBytes, 4); - switch (errno) - { - case 3025: // ENOENT: "No such path or directory." - // Assume that we got this error because the file isn't a symlink. - if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Received errno "+errno+" from QlgAccess() for file " + fd_.path_ + ". Assuming that the file does not exist."); - break; - case 3401: // EACCES: "Permission denied." - // Assume that we got this error because we don't have the specified access. - if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Received errno "+errno+" from QlgAccess() for file " + fd_.path_ + ". Assuming that the user does not have the specified access."); - break; - default: // some other errno - Trace.log(Trace.ERROR, "Received errno "+errno+" from QlgAccess() for file " + fd_.path_); - throw new ExtendedIOException(fd_.path_, ExtendedIOException.UNKNOWN_ERROR, errno); - // Note: An ErrnoException might be more appropriate, but the ErrnoException constructor requires an AS400 object, and we don't have one to give it. - } - break; + Trace.log(Trace.ERROR, "Call to QlgAccess() returned null."); + throw new AS400Exception(rmtCmd_.getMessageList()); } - case 0: // the call to QlgAccess() was successful. - { - result = true; - break; - } - default: // This should never happen. The API spec says it only returns 0 or -1. + int returnValue = BinaryConverter.byteArrayToInt(returnedBytes, 0); + + switch (returnValue) { - Trace.log(Trace.ERROR, "Received unexpected return value " + returnValue + " from QlgAccess() for file " + fd_.path_); - throw new InternalErrorException(InternalErrorException.UNEXPECTED_RETURN_CODE, "QlgAccess()", returnValue); + case -1: // this indicates that we got an "errno" back + { + result = false; + int errno = BinaryConverter.byteArrayToInt(returnedBytes, 4); + switch (errno) + { + case 3025: // ENOENT: "No such path or directory." + // Assume that we got this error because the file isn't a symlink. + if (Trace.traceOn_) + Trace.log(Trace.DIAGNOSTIC, "Received errno "+errno+" from QlgAccess() for file " + + fd_.path_ + ". Assuming that the file does not exist."); + break; + case 3401: // EACCES: "Permission denied." + // Assume that we got this error because we don't have the specified access. + if (Trace.traceOn_) + Trace.log(Trace.DIAGNOSTIC, "Received errno "+errno+" from QlgAccess() for file " + + fd_.path_ + ". Assuming that the user does not have the specified access."); + break; + default: // some other errno + Trace.log(Trace.ERROR, "Received errno "+errno+" from QlgAccess() for file " + fd_.path_); + + // Note: An ErrnoException might be more appropriate, but the ErrnoException constructor + // requires an AS400 object, and we don't have one to give it. + throw new ExtendedIOException(fd_.path_, ExtendedIOException.UNKNOWN_ERROR, errno); + } + break; + } + case 0: // the call to QlgAccess() was successful. + { + result = true; + break; + } + default: // This should never happen. The API spec says it only returns 0 or -1. + { + Trace.log(Trace.ERROR, "Received unexpected return value " + returnValue + " from QlgAccess() for file " + fd_.path_); + throw new InternalErrorException(InternalErrorException.UNEXPECTED_RETURN_CODE, "QlgAccess()", returnValue); + } } } - } - catch (AS400SecurityException e) { - throw e; - } - catch (IOException e) { - throw e; - } - catch (Exception e) { - Trace.log(Trace.ERROR, "Error while determining accessibility of file.", e); - throw new ExtendedIOException(fd_.path_, ExtendedIOException.UNKNOWN_ERROR); - } + catch (AS400SecurityException|IOException e) { + throw e; + } catch (Exception e) { + Trace.log(Trace.ERROR, "Error while determining accessibility of file.", e); + throw new ExtendedIOException(fd_.path_, ExtendedIOException.UNKNOWN_ERROR); + } - return result; + return result; } @@ -235,95 +214,89 @@ Calls QlgChmod() to reset the access mode for the file. // If the file does not exist, returns false. Note: The QlgChmod API was introduced in V5R1. **/ - public boolean setAccess(int accessType, boolean enableAccess, boolean ownerOnly) - throws IOException, AS400SecurityException + @Override + public boolean setAccess(int accessType, boolean enableAccess, boolean ownerOnly) throws IOException, AS400SecurityException { - // Assume that the caller has already connected to the server. - - // We will call the QlgChmod API, to determine whether the current user can access the file in the specified mode. - // Note: QlgChmod() is only _conditionally_ threadsafe. - - if (fd_.getSystemVRM() < 0x00050100) - { - if (Trace.traceOn_) Trace.log(Trace.WARNING, "Server is pre-V5R1, so setAccess() is not supported."); - return false; - } - - try - { - // Create the pgm call object - if (rmtCmd_ == null) { - setupRemoteCommand(); - } + // Assume that the caller has already connected to the server. - // Get the current access modes, so that we can selectively turn on/off the desired bit(s). - int oldAccessMode = getAccess(); - - int bitMask = accessType << 6; // for example: 0000400 == [ 'read' for owner ] - if (!ownerOnly) { - bitMask = bitMask | (accessType << 3) | accessType; - // for example: 0000444 == [ 'read' for owner, group, and other ] - } - - int newAccessMode; - if (enableAccess) { - newAccessMode = oldAccessMode | bitMask; // selectively turn bits _on_ - } - else { // disable access - newAccessMode = oldAccessMode & ~bitMask; // selectively turn bits _off_ - } - newAccessMode = newAccessMode & 0007777; // QlgChmod can only set the low 12 bits + // We will call the QlgChmod API, to determine whether the current user can access the file in the specified mode. + // Note: QlgChmod() is only _conditionally_ threadsafe. - ProgramParameter[] parameters = new ProgramParameter[] + if (fd_.getSystemVRM() < 0x00050100) { - // Parameter 1: Qlg_Path_Name_T *Path_Name (input) : - new ProgramParameter(ProgramParameter.PASS_BY_REFERENCE, createPathName()), - // Parameter 2: int amode (input) : - new ProgramParameter(ProgramParameter.PASS_BY_VALUE, BinaryConverter.intToByteArray(newAccessMode)) - }; + if (Trace.traceOn_) Trace.log(Trace.WARNING, "Server is pre-V5R1, so setAccess() is not supported."); + return false; + } - // Call the service program. - byte[] returnedBytes = rmtCmd_.runServiceProgram("QSYS", "QP0LLIB1", "QlgChmod", parameters); - if (returnedBytes == null) + try { - Trace.log(Trace.ERROR, "Call to QlgChmod() returned null."); - throw new AS400Exception(rmtCmd_.getMessageList()); - } + // Create the pgm call object + if (rmtCmd_ == null) + setupRemoteCommand(); - int returnValue = BinaryConverter.byteArrayToInt(returnedBytes, 0); + // Get the current access modes, so that we can selectively turn on/off the desired bit(s). + int oldAccessMode = getAccess(); - switch (returnValue) - { - case -1: // this indicates that we got an "errno" back + int bitMask = accessType << 6; // for example: 0000400 == [ 'read' for owner ] + if (!ownerOnly) { - int errno = BinaryConverter.byteArrayToInt(returnedBytes, 4); - Trace.log(Trace.ERROR, "Received errno " + errno + " from QlgChmod() for file " + fd_.path_); - throw new ExtendedIOException(fd_.path_, ExtendedIOException.UNKNOWN_ERROR, errno); + bitMask = bitMask | (accessType << 3) | accessType; + // for example: 0000444 == [ 'read' for owner, group, and other ] } - case 0: // the call to QlgChmod() was successful. + int newAccessMode; + if (enableAccess) + newAccessMode = oldAccessMode | bitMask; // selectively turn bits _on_ + else { + // disable access + newAccessMode = oldAccessMode & ~bitMask; // selectively turn bits _off_ + } + newAccessMode = newAccessMode & 0007777; // QlgChmod can only set the low 12 bits + + ProgramParameter[] parameters = new ProgramParameter[] { + // Parameter 1: Qlg_Path_Name_T *Path_Name (input) : + new ProgramParameter(ProgramParameter.PASS_BY_REFERENCE, createPathName()), + // Parameter 2: int amode (input) : + new ProgramParameter(ProgramParameter.PASS_BY_VALUE, BinaryConverter.intToByteArray(newAccessMode)) + }; + + // Call the service program. + byte[] returnedBytes = rmtCmd_.runServiceProgram("QSYS", "QP0LLIB1", "QlgChmod", parameters); + if (returnedBytes == null) { - break; + Trace.log(Trace.ERROR, "Call to QlgChmod() returned null."); + throw new AS400Exception(rmtCmd_.getMessageList()); } - default: // This should never happen. The API spec says it only returns 0 or -1. + + int returnValue = BinaryConverter.byteArrayToInt(returnedBytes, 0); + + switch (returnValue) { - Trace.log(Trace.ERROR, "Received unexpected return value " + returnValue + " from QlgChmod() for file " + fd_.path_); - throw new InternalErrorException(InternalErrorException.UNEXPECTED_RETURN_CODE, "QlgChmod()", returnValue); + case -1: // this indicates that we got an "errno" back + { + int errno = BinaryConverter.byteArrayToInt(returnedBytes, 4); + Trace.log(Trace.ERROR, "Received errno " + errno + " from QlgChmod() for file " + fd_.path_); + throw new ExtendedIOException(fd_.path_, ExtendedIOException.UNKNOWN_ERROR, errno); + } + case 0: // the call to QlgChmod() was successful. + { + break; + } + default: // This should never happen. The API spec says it only returns 0 or -1. + { + Trace.log(Trace.ERROR, "Received unexpected return value " + returnValue + " from QlgChmod() for file " + fd_.path_); + throw new InternalErrorException(InternalErrorException.UNEXPECTED_RETURN_CODE, "QlgChmod()", returnValue); + } } + } + catch (AS400SecurityException | IOException e) { + throw e; + } catch (Exception e) { + Trace.log(Trace.ERROR, "Error while determining accessibility of file.", e); + throw new ExtendedIOException(fd_.path_, ExtendedIOException.UNKNOWN_ERROR); } - } - catch (AS400SecurityException e) { - throw e; - } - catch (IOException e) { - throw e; - } - catch (Exception e) { - Trace.log(Trace.ERROR, "Error while determining accessibility of file.", e); - throw new ExtendedIOException(fd_.path_, ExtendedIOException.UNKNOWN_ERROR); - } - return true; + return true; } @@ -332,274 +305,218 @@ Calls QlgStat() to get status information about the file. If the file does not exist, throws an ObjectDoesNotExistException. Note: The QlgStat API was introduced in V5R1. Do not call this method without checking VRM. **/ - private int getAccess() - throws IOException, AS400SecurityException, ObjectDoesNotExistException + private int getAccess() throws IOException, AS400SecurityException, ObjectDoesNotExistException { - // Assume that the caller has already connected to the server. - // Assume that the caller has already verified that the server is V5R1 or higher. - - // We will call the QlgStat API, to get status information about the file. - // Note: QlgStat() is only _conditionally_ threadsafe. - - int statInfo = 0; - try - { - // Create the pgm call object - if (rmtCmd_ == null) { - setupRemoteCommand(); - } - - int bufferSizeProvided = 128; // large enough to accommodate a 'stat' structure - - ProgramParameter[] parameters = new ProgramParameter[] - { - // Parameter 1: Qlg_Path_Name_T *Path_Name (input) : - new ProgramParameter(ProgramParameter.PASS_BY_REFERENCE, createPathName()), - // Parameter 2: struct stat *buf (output) : - new ProgramParameter(ProgramParameter.PASS_BY_REFERENCE, bufferSizeProvided), - }; - - // Call the service program. - byte[] returnedBytes = rmtCmd_.runServiceProgram("QSYS", "QP0LLIB1", "QlgStat", parameters); - if (returnedBytes == null) - { - Trace.log(Trace.ERROR, "Call to QlgStat() returned null."); - throw new AS400Exception(rmtCmd_.getMessageList()); - } + // Assume that the caller has already connected to the server. + // Assume that the caller has already verified that the server is V5R1 or higher. - int returnValue = BinaryConverter.byteArrayToInt(returnedBytes, 0); + // We will call the QlgStat API, to get status information about the file. + // Note: QlgStat() is only _conditionally_ threadsafe. - switch (returnValue) + int statInfo = 0; + try { - case -1: // this indicates that we got an "errno" back + // Create the pgm call object + if (rmtCmd_ == null) + setupRemoteCommand(); + + int bufferSizeProvided = 128; // large enough to accommodate a 'stat' structure + + ProgramParameter[] parameters = new ProgramParameter[] { + // Parameter 1: Qlg_Path_Name_T *Path_Name (input) : + new ProgramParameter(ProgramParameter.PASS_BY_REFERENCE, createPathName()), + // Parameter 2: struct stat *buf (output) : + new ProgramParameter(ProgramParameter.PASS_BY_REFERENCE, bufferSizeProvided) + }; + + // Call the service program. + byte[] returnedBytes = rmtCmd_.runServiceProgram("QSYS", "QP0LLIB1", "QlgStat", parameters); + if (returnedBytes == null) { - int errno = BinaryConverter.byteArrayToInt(returnedBytes, 4); - switch (errno) - { - case 3025: // ENOENT: "No such path or directory." - // Assume that we got this error because the file isn't a symlink. - Trace.log(Trace.ERROR, "Received errno "+errno+" from QlgStat() for file " + fd_.path_ + ". Assuming that the file does not exist."); - throw new ObjectDoesNotExistException(fd_.path_, ObjectDoesNotExistException.OBJECT_DOES_NOT_EXIST); - case 3401: // EACCES: "Permission denied." - // Assume that we got this error because we don't have the specified access. - Trace.log(Trace.ERROR, "Received errno "+errno+" from QlgStat() for file " + fd_.path_ + ". Assuming that the user does not have permission to access the file."); - throw new AS400SecurityException(fd_.path_, AS400SecurityException.DIRECTORY_ENTRY_ACCESS_DENIED); - default: // some other errno - Trace.log(Trace.ERROR, "Received errno " + errno + " from QlgStat() for file " + fd_.path_); - throw new ExtendedIOException(fd_.path_, ExtendedIOException.UNKNOWN_ERROR, errno); - } + Trace.log(Trace.ERROR, "Call to QlgStat() returned null."); + throw new AS400Exception(rmtCmd_.getMessageList()); } - case 0: // the call to QglStat() was successful. - { - // Parse the "file modes" from the returned stat structure (second parameter). - statInfo = parseStatInfo(parameters[1].getOutputData()); - break; - } - default: // This should never happen. The API spec says it only returns 0 or -1. + int returnValue = BinaryConverter.byteArrayToInt(returnedBytes, 0); + + switch (returnValue) { - Trace.log(Trace.ERROR, "Received unexpected return value " + returnValue + " from QlgStat() for file " + fd_.path_); - throw new InternalErrorException(InternalErrorException.UNEXPECTED_RETURN_CODE, "QlgStat()", returnValue); + case -1: // this indicates that we got an "errno" back + { + int errno = BinaryConverter.byteArrayToInt(returnedBytes, 4); + switch (errno) + { + case 3025: // ENOENT: "No such path or directory." + // Assume that we got this error because the file isn't a symlink. + Trace.log(Trace.ERROR, "Received errno "+errno+" from QlgStat() for file " + fd_.path_ + ". Assuming that the file does not exist."); + throw new ObjectDoesNotExistException(fd_.path_, ObjectDoesNotExistException.OBJECT_DOES_NOT_EXIST); + case 3401: // EACCES: "Permission denied." + // Assume that we got this error because we don't have the specified access. + Trace.log(Trace.ERROR, "Received errno "+errno+" from QlgStat() for file " + fd_.path_ + ". Assuming that the user does not have permission to access the file."); + throw new AS400SecurityException(fd_.path_, AS400SecurityException.DIRECTORY_ENTRY_ACCESS_DENIED); + default: // some other errno + Trace.log(Trace.ERROR, "Received errno " + errno + " from QlgStat() for file " + fd_.path_); + throw new ExtendedIOException(fd_.path_, ExtendedIOException.UNKNOWN_ERROR, errno); + } + } + case 0: // the call to QglStat() was successful. + { + // Parse the "file modes" from the returned stat structure (second parameter). + statInfo = parseStatInfo(parameters[1].getOutputData()); + break; + } + default: // This should never happen. The API spec says it only returns 0 or -1. + { + Trace.log(Trace.ERROR, "Received unexpected return value " + returnValue + " from QlgStat() for file " + fd_.path_); + throw new InternalErrorException(InternalErrorException.UNEXPECTED_RETURN_CODE, "QlgStat()", returnValue); + } } } - } - catch (AS400SecurityException e) { - throw e; - } - catch (IOException e) { - throw e; - } - catch (Exception e) { - Trace.log(Trace.ERROR, "Error while determining accessibility of file.", e); - throw new ExtendedIOException(fd_.path_, ExtendedIOException.UNKNOWN_ERROR); - } + catch (AS400SecurityException|IOException e) { + throw e; + } + catch (Exception e) { + Trace.log(Trace.ERROR, "Error while determining accessibility of file.", e); + throw new ExtendedIOException(fd_.path_, ExtendedIOException.UNKNOWN_ERROR); + } - return statInfo; + return statInfo; } - /** - Clear the cached attributes. This is needed when cached attributes - need to be refreshed. - **/ - public void clearCachedAttributes() //@D9A + @Override + public void clearCachedAttributes() { - attributesReply_ = null; - databaseFileAttributes_ = null; + attributesReply_ = null; + databaseFileAttributes_ = null; } - /** - Copies the current file to the specified path. - **/ - public boolean copyTo(String destinationPath, boolean replace) - throws IOException, AS400SecurityException, ObjectAlreadyExistsException + @Override + public boolean copyTo(String destinationPath, boolean replace) throws IOException, AS400SecurityException, ObjectAlreadyExistsException { - fd_.connect(); - if (Trace.traceOn_ && replace==false && fd_.getSystemVRM() < 0x00050300) { - Trace.log(Trace.WARNING, "Server is V5R2 or lower, so the 'Do not replace' argument will be ignored."); - } + fd_.connect(); + if (Trace.traceOn_ && replace==false && fd_.getSystemVRM() < 0x00050300) + Trace.log(Trace.WARNING, "Server is V5R2 or lower, so the 'Do not replace' argument will be ignored."); - // If the source is a directory, verify that the destination doesn't already exist. - if (isDirectory() == IFSReturnCodeRep.SUCCESS && - exists(destinationPath) == IFSReturnCodeRep.SUCCESS) { - throw new ObjectAlreadyExistsException(destinationPath, ObjectAlreadyExistsException.OBJECT_ALREADY_EXISTS); - } + // If the source is a directory, verify that the destination doesn't already exist. + if (isDirectory() == IFSReturnCodeRep.SUCCESS && exists(destinationPath) == IFSReturnCodeRep.SUCCESS) + throw new ObjectAlreadyExistsException(destinationPath, ObjectAlreadyExistsException.OBJECT_ALREADY_EXISTS); - return fd_.copyTo(destinationPath, replace); + return fd_.copyTo(destinationPath, replace); } - /** - @D3a created0 is a new method - Determines the time that the integrated file system object represented by this object was created. - **/ - public long created() - throws IOException, AS400SecurityException - { - // Ensure that we are connected to the server. - fd_.connect(); - long creationDate = 0L; + @Override + public long created() throws IOException, AS400SecurityException + { + // Ensure that we are connected to the server. + fd_.connect(); + long creationDate = 0L; - // Attempt to list the attributes of the specified file. - // Note: Do not use cached attributes, since they may be out of date. - IFSListAttrsRep attrs = getAttributeSetFromServer(fd_.path_); - if (attrs != null) - { - attributesReply_ = attrs; - creationDate = attrs.getCreationDate(); - } + // Attempt to list the attributes of the specified file. + // Note: Do not use cached attributes, since they may be out of date. + IFSListAttrsRep attrs = getAttributeSetFromServer(fd_.path_); + if (attrs != null) { + attributesReply_ = attrs; + creationDate = attrs.getCreationDate(); + } - return creationDate; + return creationDate; } - - - - /** - If file does not exist, create it. If the file - does exist, return an error. The goal is to atomically - create a new file if and only if the file does not - yet exist. - **/ - // @D1 - new method because of changes to java.io.file in Java 2. - - public int createNewFile() - throws IOException, AS400SecurityException + @Override + public int createNewFile() throws IOException, AS400SecurityException { - // Ensure that we are connected to the server. - fd_.connect(); + // Ensure that we are connected to the server. + fd_.connect(); - return (fd_.checkAccess(IFSOpenReq.WRITE_ACCESS, IFSOpenReq.OPEN_OPTION_CREATE_FAIL)); + return (fd_.checkAccess(IFSOpenReq.WRITE_ACCESS, IFSOpenReq.OPEN_OPTION_CREATE_FAIL)); } - - - - /** - Deletes the integrated file system object represented by this object. - **/ - public int delete() - throws IOException, AS400SecurityException + @Override + public int delete() throws IOException, AS400SecurityException { - // Ensure that we are connected to the server. - fd_.connect(); + // Ensure that we are connected to the server. + fd_.connect(); - // Convert the path name to the server CCSID. - byte[] pathname = fd_.converter_.stringToByteArray(fd_.path_); + // Convert the path name to the server CCSID. + byte[] pathname = fd_.converter_.stringToByteArray(fd_.path_); - // Determine if this is a file or directory and instantiate the - // appropriate type of delete request. - IFSDataStreamReq req = - new IFSDeleteFileReq(pathname, fd_.preferredServerCCSID_); - try - { - if (!isSymbolicLink() && isDirectory() == IFSReturnCodeRep.SUCCESS ) + // Determine if this is a file or directory and instantiate the + // appropriate type of delete request. + IFSDataStreamReq req = new IFSDeleteFileReq(pathname, fd_.preferredServerCCSID_); + try { - req = new IFSDeleteDirReq(pathname, fd_.preferredServerCCSID_); + if (!isSymbolicLink() && isDirectory() == IFSReturnCodeRep.SUCCESS ) + req = new IFSDeleteDirReq(pathname, fd_.preferredServerCCSID_); } - } - catch (Exception e) - { - - if (Trace.traceOn_) Trace.log(Trace.WARNING, - "Unable to determine if file or directory.\n" + e.toString()); + catch (Exception e) + { + if (Trace.traceOn_) Trace.log(Trace.WARNING, "Unable to determine if file or directory.\n" + e.toString()); - // If the server has been disconnected, go ahead and throw an exception - // to avoid the null pointer exception from fs_.server_ - if (fd_.server_ == null) { - if (e instanceof IOException) { - throw (IOException) e; - } else { - throw new IOException(e); - } + // If the server has been disconnected, go ahead and throw an exception + // to avoid the null pointer exception from fs_.server_ + if (fd_.server_ == null) + { + if (e instanceof IOException) + throw (IOException) e; + else + throw new IOException(e); + } } - } - // Delete this entry. - ClientAccessDataStream ds = null; - try - { - // Send a delete request. - ds = (ClientAccessDataStream) fd_.server_.sendAndReceive(req); - } - catch(ConnectionDroppedException e) - { - Trace.log(Trace.ERROR, "Byte stream server connection lost."); - fd_.connectionDropped(e); - } - catch(InterruptedException e) - { - Trace.log(Trace.ERROR, "Interrupted"); - InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); - throwException.initCause(e); - throw throwException; - } + // Delete this entry. + ClientAccessDataStream ds = null; + try { + ds = (ClientAccessDataStream) fd_.server_.sendAndReceive(req); + } + catch(ConnectionDroppedException e) + { + Trace.log(Trace.ERROR, "Byte stream server connection lost."); + fd_.connectionDropped(e); + } + catch(InterruptedException e) + { + Trace.log(Trace.ERROR, "Interrupted"); + InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); + throwException.initCause(e); + throw throwException; + } - // Verify that the request was successful. - int rc = 0; - if (ds instanceof IFSReturnCodeRep) - { - rc = ((IFSReturnCodeRep) ds).getReturnCode(); - if (rc != IFSReturnCodeRep.SUCCESS) + // Verify that the request was successful. + int rc = 0; + if (ds instanceof IFSReturnCodeRep) + { + rc = ((IFSReturnCodeRep) ds).getReturnCode(); + if (rc != IFSReturnCodeRep.SUCCESS) { + if (Trace.traceOn_) Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", rc); + } + } + else { - if (Trace.traceOn_) Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", rc); + Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); + throw new InternalErrorException(InternalErrorException.DATA_STREAM_UNKNOWN, Integer.toHexString(ds.getReqRepID()), null); } - } - else - { - // Unknown data stream. - Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); - throw new - InternalErrorException(InternalErrorException.DATA_STREAM_UNKNOWN, - Integer.toHexString(ds.getReqRepID()),null); - } - // Clear any cached file attributes. - attributesReply_ = null; + // Clear any cached file attributes. + attributesReply_ = null; - return (rc); + return (rc); } - //@B1A Moved code from isDirectory() to support determining if a file is a directory - //without a call to the server. /** Determines if a file is a directory without a call to the server. **/ private boolean determineIsDirectory(IFSListAttrsRep attributeList) { - boolean answer = false; - // Determine if the file attributes indicate a directory. - // Don't need to check if attributeList == null because it has already been - // checked by the two methods that call it. Also don't check converter - // because it is set by a connect() method before calling this. - -// String name = fd_.converter_.byteArrayToString(attributeList.getName(/*fd_.serverDatastreamLevel_*/)); - switch (attributeList.getObjectType()) - { + boolean answer = false; + // Determine if the file attributes indicate a directory. + switch (attributeList.getObjectType()) + { case IFSListAttrsRep.DIRECTORY: case IFSListAttrsRep.FILE: - answer = ((attributeList.getFixedAttributes() & IFSListAttrsRep.FA_DIRECTORY) != 0); - break; + answer = ((attributeList.getFixedAttributes() & IFSListAttrsRep.FA_DIRECTORY) != 0); + break; // * Deleted the following case... treat as default (false) @D8A // * For example, OUTQ, DSPF, PRTF, and TAPF objects are NOT directories @D8A // * LIB, PF, LF, SRCPF are returned as IFSListAttrsRep.DIRECTORY @D8A @@ -615,31 +532,25 @@ private boolean determineIsDirectory(IFSListAttrsRep attributeList) // //path_.endsWith(".FILE" + IFSFile.separator)); // break; @D8D*/ default: - answer = false; - } - return answer; + answer = false; + } + + return answer; } - //@B1A Moved code from isFile() to support determining if a file is a file - //without a call to the server. /** Determines if a file is a file without a call to the server. **/ private boolean determineIsFile(IFSListAttrsRep attributeList) { - boolean answer = false; - // Determine if the file attributes indicate a file. - // Don't need to check if attributeList == null because it has already been - // checked by the two methods that call it. Also don't check converter - // because it is set by a connect() method before calling this. - -// String name = fd_.converter_.byteArrayToString(attributeList.getName(/*fd_.serverDatastreamLevel_*/)); - switch(attributeList.getObjectType()) - { + boolean answer = false; + // Determine if the file attributes indicate a file. + switch (attributeList.getObjectType()) + { case IFSListAttrsRep.DIRECTORY: case IFSListAttrsRep.FILE: - answer = ((attributeList.getFixedAttributes() & IFSListAttrsRep.FA_DIRECTORY) == 0); - break; + answer = ((attributeList.getFixedAttributes() & IFSListAttrsRep.FA_DIRECTORY) == 0); + break; // * Deleted the following case... treat as default (false) @D8A // * For example, OUTQ, DSPF, PRTF, and TAPF objects are NOT files @D8A // * LIB, PF, LF, SRCPF are returned as IFSListAttrsRep.DIRECTORY @D8A @@ -655,56 +566,49 @@ private boolean determineIsFile(IFSListAttrsRep attributeList) // //path_.endsWith(".FILE" + IFSFile.separator)); // break; @D8D*/ default: - answer = false; - } - return answer; + answer = false; + } + + return answer; } - /** - Determines if the integrated file system object represented by this object exists. - **/ - public int exists() - throws IOException, AS400SecurityException - { - return exists(fd_.path_); + @Override + public int exists() throws IOException, AS400SecurityException { + return exists(fd_.path_); } - - //@B4a /** Determines if the integrated file system object represented by this object exists. **/ - private int exists(String name) - throws IOException, AS400SecurityException + private int exists(String name) throws IOException, AS400SecurityException { - int returnCode = IFSReturnCodeRep.SUCCESS; + int returnCode = IFSReturnCodeRep.SUCCESS; - // Ensure that we are connected to the server. - fd_.connect(); + // Ensure that we are connected to the server. + fd_.connect(); - returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; - // Attempt to list the attributes of the specified file. - try - { - IFSListAttrsRep attrs = getAttributeSetFromServer(name); - if (attrs != null) + returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; + // Attempt to list the attributes of the specified file. + try { - returnCode = IFSReturnCodeRep.SUCCESS; - attributesReply_ = attrs; + IFSListAttrsRep attrs = getAttributeSetFromServer(name); + if (attrs != null) + { + returnCode = IFSReturnCodeRep.SUCCESS; + attributesReply_ = attrs; + } + } + catch (AS400SecurityException e) { + returnCode = IFSReturnCodeRep.ACCESS_DENIED_TO_DIR_ENTRY; + // Note: This is consistent with the behavior of java.io.File on IBM JVMs. + // On IBM i, java.io.File.exists() returns false if the profile is denied access to the file being queried. } - } - catch (AS400SecurityException e) - { - returnCode = IFSReturnCodeRep.ACCESS_DENIED_TO_DIR_ENTRY; - // Note: This is consistent with the behavior of java.io.File on IBM JVMs. - // On IBM i, java.io.File.exists() returns false if the profile is denied access to the file being queried. - } - return (returnCode); - // Design note: - // The QlgAccess() API gives somewhat different results in certain scenarios. - // For example, in one test it returned 'true' when the directory didn't exist. - // Using IFSListAttrsReq appears to be more reliable. + return (returnCode); + // Design note: + // The QlgAccess() API gives somewhat different results in certain scenarios. + // For example, in one test it returned 'true' when the directory didn't exist. + // Using IFSListAttrsReq appears to be more reliable. } @@ -712,102 +616,66 @@ private int exists(String name) Returns the path name of the integrated file system object represented by this object. This is the full path starting at the root directory. @return The absolute path name of this integrated file system object. **/ - String getAbsolutePath() - { - return fd_.path_; + String getAbsolutePath() { + return fd_.path_; } - /** Get a list attribute reply from the server for a single entity (get the attributes of a specific object, not the attributes of every file in a directory). **/ - // @D1 - new method because of changes to java.io.file in Java 2. - - private IFSListAttrsRep getAttributeSetFromServer(String filePath) - throws IOException, AS400SecurityException + private IFSListAttrsRep getAttributeSetFromServer(String filePath) throws IOException, AS400SecurityException { - IFSListAttrsRep reply = null; + IFSListAttrsRep reply = null; - // Attempt to list the attributes of the specified file. - Vector replys = listAttributes(filePath, NO_MAX_GET_COUNT, null, NO_RESTART_NAME, !SORT_LIST); - // Note: This does setFD() on each returned IFSListAttrsRep. + // Attempt to list the attributes of the specified file. + Vector replys = listAttributes(filePath, NO_MAX_GET_COUNT, null, NO_RESTART_NAME, !SORT_LIST); + // Note: This does setFD() on each returned IFSListAttrsRep. - // If this is a directory then there must be exactly one reply. - if (replys != null && replys.size() == 1) - { - reply = (IFSListAttrsRep) replys.elementAt(0); - } + // If this is a directory then there must be exactly one reply. + if (replys != null && replys.size() == 1) + reply = (IFSListAttrsRep) replys.elementAt(0); - return reply; + return reply; } -//@AC7A Start - public int getCCSID(boolean retrieveAll) throws IOException, AS400SecurityException - { - return fd_.getCCSID(retrieveAll); - } -//@AC7A End - - // @B4a - /** - Returns the file's data CCSID. Returns -1 if failure or if directory. - **/ - //@SCd @T2C - public int getCCSID() - throws IOException, AS400SecurityException - { - //fd_.connect(); //@V4D. connect is called in following fd_getCCSID() - return fd_.getCCSID(); - } - - //@SCa @V4C - public int getCCSIDByUserHandle() throws IOException, AS400SecurityException { - return fd_.getCCSIDByUserHandle(); + @Override + public int getCCSID(boolean retrieveAll) throws IOException, AS400SecurityException { + return fd_.getCCSID(retrieveAll); } + @Override + public int getCCSID() throws IOException, AS400SecurityException { + return fd_.getCCSID(); + } private static final boolean SPACE_AVAILABLE = true; private static final boolean SPACE_TOTAL = false; - /** - Determines the amount of unused storage space in the file system. - @param forUserOnly Whether to report only the space for the user. If false, report space in entire file system. - @return The number of bytes of storage available. - Returns special value Long.MAX_VALUE if the system reports "no maximum". - **/ - public long getAvailableSpace(boolean forUserOnly) - throws IOException, AS400SecurityException + + @Override + public long getAvailableSpace(boolean forUserOnly) throws IOException, AS400SecurityException { - long spaceAvailable = getAmountOfSpace(forUserOnly, SPACE_AVAILABLE); - - // Design note: When querying the space available for a specific user, - // the File Server team advises us to make two queries: - // First query the space available to the user (within the user profile's "Maximum Storage Allowed" limit). - // Then query the total space available in the file system. - // The smaller of the two values is what we should then report to the application. - if (forUserOnly) - { - long spaceAvailableInFileSystem = getAmountOfSpace(false, SPACE_AVAILABLE); - spaceAvailable = Math.min(spaceAvailable, spaceAvailableInFileSystem); - } + long spaceAvailable = getAmountOfSpace(forUserOnly, SPACE_AVAILABLE); + + // Design note: When querying the space available for a specific user, + // the File Server team advises us to make two queries: + // First query the space available to the user (within the user profile's "Maximum Storage Allowed" limit). + // Then query the total space available in the file system. + // The smaller of the two values is what we should then report to the application. + if (forUserOnly) + { + long spaceAvailableInFileSystem = getAmountOfSpace(false, SPACE_AVAILABLE); + spaceAvailable = Math.min(spaceAvailable, spaceAvailableInFileSystem); + } - return spaceAvailable; + return spaceAvailable; } - - /** - Determines the total amount of storage space in the file system. - @param forUserOnly Whether to report only the space for the user. If false, report space in entire file system. - @return The number of bytes of storage. - Returns special value Long.MAX_VALUE if the system reports "no maximum". - **/ - public long getTotalSpace(boolean forUserOnly) - throws IOException, AS400SecurityException - { - return getAmountOfSpace(forUserOnly, SPACE_TOTAL); + @Override + public long getTotalSpace(boolean forUserOnly) throws IOException, AS400SecurityException { + return getAmountOfSpace(forUserOnly, SPACE_TOTAL); } - /** Returns the amount of storage space. @param forUserOnly Whether to report only the space for the user. If false, report space in entire file system. @@ -815,239 +683,195 @@ public long getTotalSpace(boolean forUserOnly) @return The number of bytes of storage. Returns special value Long.MAX_VALUE if the system reports "no maximum". **/ - private long getAmountOfSpace(boolean forUserOnly, boolean availableSpaceOnly) - throws IOException, AS400SecurityException + private long getAmountOfSpace(boolean forUserOnly, boolean availableSpaceOnly) throws IOException, AS400SecurityException { - // Ensure that we are connected to the server. - fd_.connect(); + // Ensure that we are connected to the server. + fd_.connect(); - long amountOfSpace = 0L; - int directoryHandle; - ClientAccessDataStream ds = null; - int rc = 0; + long amountOfSpace = 0L; + int directoryHandle; + ClientAccessDataStream ds = null; + int rc = 0; - if (forUserOnly) // prepare to get space info for specific user - { - // Special value for file handle, indicating that space attributes for the user should be retrieved, rather than space attributes of the file system. - // According to the PWSI Datastream Spec: - // "When the client sends 0 as the working directory handle ... the space characteristics of the user are returned instead of the characteristics of the system." - directoryHandle = 0; - } - else // prepare to get space info for the entire file system - { - // To query the file system, we need to specify a "working directory handle" to the directory. So first, get a handle. - String path = fd_.path_; - if (isDirectory() != IFSReturnCodeRep.SUCCESS) { - path = IFSFile.getParent(fd_.path_); - } - byte[] pathname = fd_.getConverter().stringToByteArray(path); - try + if (forUserOnly) // prepare to get space info for specific user { - // Issue a Create Working Directory Handle request. - IFSCreateDirHandleReq req = new IFSCreateDirHandleReq(pathname, fd_.preferredServerCCSID_); - ds = (ClientAccessDataStream) fd_.server_.sendAndReceive(req); + // Special value for file handle, indicating that space attributes for the user should be retrieved, rather + // than space attributes of the file system. + // According to the PWSI Datastream Spec: + // "When the client sends 0 as the working directory handle ... the space characteristics of the user are + // returned instead of the characteristics of the system." + directoryHandle = 0; } - catch(ConnectionDroppedException e) + else // prepare to get space info for the entire file system { - Trace.log(Trace.ERROR, "Byte stream server connection lost."); - fd_.connectionDropped(e); - } - catch(InterruptedException e) - { - Trace.log(Trace.ERROR, "Interrupted"); - InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); - throwException.initCause(e); - throw throwException; + // To query the file system, we need to specify a "working directory handle" to the directory. So first, get a + // handle. + String path = fd_.path_; + if (isDirectory() != IFSReturnCodeRep.SUCCESS) + path = IFSFile.getParent(fd_.path_); + + byte[] pathname = fd_.getConverter().stringToByteArray(path); + try + { + // Issue a Create Working Directory Handle request. + IFSCreateDirHandleReq req = new IFSCreateDirHandleReq(pathname, fd_.preferredServerCCSID_); + ds = (ClientAccessDataStream) fd_.server_.sendAndReceive(req); + } + catch(ConnectionDroppedException e) + { + Trace.log(Trace.ERROR, "Byte stream server connection lost."); + fd_.connectionDropped(e); + } + catch(InterruptedException e) + { + Trace.log(Trace.ERROR, "Interrupted"); + InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); + throwException.initCause(e); + throw throwException; + } + + // Verify that we got a handle back. + rc = 0; + if (ds instanceof IFSCreateDirHandleRep) + directoryHandle = ((IFSCreateDirHandleRep) ds).getHandle(); + else if (ds instanceof IFSReturnCodeRep) + { + rc = ((IFSReturnCodeRep) ds).getReturnCode(); + if (rc != IFSReturnCodeRep.SUCCESS) Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", rc); + throw new ExtendedIOException(fd_.path_, rc); + } + else + { + Trace.log(Trace.ERROR, "Unknown reply data stream", ds.getReqRepID()); + throw new InternalErrorException(Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); + } } - // Verify that we got a handle back. - rc = 0; - if (ds instanceof IFSCreateDirHandleRep) + // Query the amount of space. + ds = null; + try { - directoryHandle = ((IFSCreateDirHandleRep) ds).getHandle(); + IFSQuerySpaceReq req = new IFSQuerySpaceReq(directoryHandle); + ds = (ClientAccessDataStream) fd_.server_.sendAndReceive(req); } - else if (ds instanceof IFSReturnCodeRep) + catch(ConnectionDroppedException e) { - rc = ((IFSReturnCodeRep) ds).getReturnCode(); - if (rc != IFSReturnCodeRep.SUCCESS) - { - Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", rc); - } - throw new ExtendedIOException(fd_.path_, rc); + Trace.log(Trace.ERROR, "Byte stream server connection lost."); + fd_.connectionDropped(e); } - else + catch(InterruptedException e) { - // Unknown data stream. - Trace.log(Trace.ERROR, "Unknown reply data stream", - ds.getReqRepID()); - throw new - InternalErrorException(Integer.toHexString(ds.getReqRepID()), - InternalErrorException.DATA_STREAM_UNKNOWN); + Trace.log(Trace.ERROR, "Interrupted"); + InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); + throwException.initCause(e); + throw throwException; } - } - - // Query the amount of space. - ds = null; - try - { - // Issue a query space request. - IFSQuerySpaceReq req = new IFSQuerySpaceReq(directoryHandle); - ds = (ClientAccessDataStream) fd_.server_.sendAndReceive(req); - } - catch(ConnectionDroppedException e) - { - Trace.log(Trace.ERROR, "Byte stream server connection lost."); - fd_.connectionDropped(e); - } - catch(InterruptedException e) - { - Trace.log(Trace.ERROR, "Interrupted"); - InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); - throwException.initCause(e); - throw throwException; - } - // Verify the reply. - rc = 0; - if (ds instanceof IFSQuerySpaceRep) - { - if (availableSpaceOnly) { - amountOfSpace = ((IFSQuerySpaceRep) ds).getSpaceAvailable(); - } - else { - amountOfSpace = ((IFSQuerySpaceRep) ds).getTotalSpace(); + // Verify the reply. + rc = 0; + if (ds instanceof IFSQuerySpaceRep) + amountOfSpace = (availableSpaceOnly) ? ((IFSQuerySpaceRep) ds).getSpaceAvailable() : ((IFSQuerySpaceRep) ds).getTotalSpace(); + else if (ds instanceof IFSReturnCodeRep) + { + rc = ((IFSReturnCodeRep) ds).getReturnCode(); + if (rc != IFSReturnCodeRep.SUCCESS) Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", rc); + throw new ExtendedIOException(fd_.path_, rc); } - } - else if (ds instanceof IFSReturnCodeRep) - { - rc = ((IFSReturnCodeRep) ds).getReturnCode(); - if (rc != IFSReturnCodeRep.SUCCESS) + else { - Trace.log(Trace.ERROR, "IFSReturnCodeRep return code", rc); + Trace.log(Trace.ERROR, "Unknown reply data stream", ds.getReqRepID()); + throw new InternalErrorException(InternalErrorException.DATA_STREAM_UNKNOWN, Integer.toHexString(ds.getReqRepID()), null); } - throw new ExtendedIOException(fd_.path_, rc); - } - else - { - // Unknown data stream. - Trace.log(Trace.ERROR, "Unknown reply data stream", - ds.getReqRepID()); - throw new - InternalErrorException(InternalErrorException.DATA_STREAM_UNKNOWN, - Integer.toHexString(ds.getReqRepID()),null); - } - return amountOfSpace; + return amountOfSpace; } -//@AC7A Start - public String getFileSystemType(boolean isDirectory) throws IOException, AS400SecurityException { - return fd_.getFileSystemType(isDirectory); - } -//@AC7A End - - //@SAA @V4C + @Override public String getFileSystemType() throws IOException, AS400SecurityException { - return fd_.getFileSystemType(); + return fd_.getFileSystemType(); } - -//@AC7A Start - public String getOwnerName(boolean retrieveAll) - throws IOException, AS400SecurityException - { - // Design note: This method demonstrates how to get attributes that are returned in the OA1* structure (as opposed to the OA2). - String ownerName = null; - - fd_.connect(); - // The 'owner name' field is in the OA1 structure; the flag is in the first Flags() field. - try - { - IFSListAttrsRep reply = null; - if (retrieveAll) - return fd_.getOwnerName(); - else - reply = fd_.listObjAttrs1(IFSObjAttrs1.OWNER_NAME_FLAG, 0); - - if (reply != null) { - ownerName = reply.getOwnerName(fd_.system_.getCcsid()); - } - else { - if (Trace.traceOn_) Trace.log(Trace.WARNING, "getOwnerName: " + - "IFSReturnCodeRep return code", fd_.errorRC_); - if (fd_.errorRC_ == IFSReturnCodeRep.FILE_NOT_FOUND || - fd_.errorRC_ == IFSReturnCodeRep.PATH_NOT_FOUND) - { - throw new ExtendedIOException(fd_.path_, ExtendedIOException.PATH_NOT_FOUND); - } - } - } - catch (ExtendedIOException e) { - if (e.getReturnCode() == ExtendedIOException.DIR_ENTRY_EXISTS) { - if (Trace.traceOn_) Trace.log(Trace.WARNING, "Unable to determine owner of directory.", e); - } - else throw e; - } - - return (ownerName == null ? "" : ownerName); - } - //@AC7A End - - /** - Returns the name of the user profile that is the owner of the file. - Returns "" if called against a directory. - **/ - //@SCd @T2C - public String getOwnerName() - throws IOException, AS400SecurityException + + @Override + public String getOwnerName(boolean retrieveAll) throws IOException, AS400SecurityException { + // Design note: This method demonstrates how to get attributes that are returned in the OA1* structure (as opposed to the OA2). + String ownerName = null; + + fd_.connect(); + + // The 'owner name' field is in the OA1 structure; the flag is in the first Flags() field. + try + { + IFSListAttrsRep reply = null; + if (retrieveAll) + return fd_.getOwnerName(); + else + reply = fd_.listObjAttrs1(IFSObjAttrs1.OWNER_NAME_FLAG, 0); + + if (reply != null) + ownerName = reply.getOwnerName(fd_.system_.getCcsid()); + else + { + if (Trace.traceOn_) Trace.log(Trace.WARNING, "getOwnerName: " + "IFSReturnCodeRep return code", fd_.errorRC_); + + if (fd_.errorRC_ == IFSReturnCodeRep.FILE_NOT_FOUND || fd_.errorRC_ == IFSReturnCodeRep.PATH_NOT_FOUND) + throw new ExtendedIOException(fd_.path_, ExtendedIOException.PATH_NOT_FOUND); + } + } + catch (ExtendedIOException e) + { + if (e.getReturnCode() == ExtendedIOException.DIR_ENTRY_EXISTS) { + if (Trace.traceOn_) Trace.log(Trace.WARNING, "Unable to determine owner of directory.", e); + } + else + throw e; + } + + return (ownerName == null ? "" : ownerName); + } + +@Override +public String getOwnerName() throws IOException, AS400SecurityException +{ // Design note: This method demonstrates how to get attributes that are returned in the OA1* structure (as opposed to the OA2). String ownerName = null; fd_.connect(); + // The 'owner name' field is in the OA1 structure; the flag is in the first Flags() field. try { - IFSListAttrsRep reply = fd_.listObjAttrs1(IFSObjAttrs1.OWNER_NAME_FLAG, 0); - if (reply != null) { - ownerName = reply.getOwnerName(fd_.system_.getCcsid()); - } - else { - if (Trace.traceOn_) Trace.log(Trace.WARNING, "getOwnerName: " + - "IFSReturnCodeRep return code", fd_.errorRC_); - if (fd_.errorRC_ == IFSReturnCodeRep.FILE_NOT_FOUND || - fd_.errorRC_ == IFSReturnCodeRep.PATH_NOT_FOUND) + IFSListAttrsRep reply = fd_.listObjAttrs1(IFSObjAttrs1.OWNER_NAME_FLAG, 0); + if (reply != null) + ownerName = reply.getOwnerName(fd_.system_.getCcsid()); + else { - throw new ExtendedIOException(fd_.path_, ExtendedIOException.PATH_NOT_FOUND); + if (Trace.traceOn_) Trace.log(Trace.WARNING, "getOwnerName: IFSReturnCodeRep return code", fd_.errorRC_); + + if (fd_.errorRC_ == IFSReturnCodeRep.FILE_NOT_FOUND || fd_.errorRC_ == IFSReturnCodeRep.PATH_NOT_FOUND) + throw new ExtendedIOException(fd_.path_, ExtendedIOException.PATH_NOT_FOUND); } - } } - catch (ExtendedIOException e) { - if (e.getReturnCode() == ExtendedIOException.DIR_ENTRY_EXISTS) { - if (Trace.traceOn_) Trace.log(Trace.WARNING, "Unable to determine owner of directory.", e); - } - else throw e; + catch (ExtendedIOException e) + { + if (e.getReturnCode() == ExtendedIOException.DIR_ENTRY_EXISTS) { + if (Trace.traceOn_) Trace.log(Trace.WARNING, "Unable to determine owner of directory.", e); + } + else + throw e; } return (ownerName == null ? "" : ownerName); - } - //@SCa - public String getOwnerNameByUserHandle() throws IOException, AS400SecurityException { - return fd_.getOwnerNameByUserHandle(); - } - - public String getOwnerNameByUserHandle(boolean forceRetrieve) throws IOException, AS400SecurityException { - return fd_.getOwnerNameByUserHandle(forceRetrieve); - } - - //@AC7A Start - public int getASP(boolean isDirectory) throws IOException, AS400SecurityException { - return fd_.getASP(isDirectory); - } -//@AC7A End +} - //@SAA + @Override + public String getOwnerNameByUserHandle(boolean forceRetrieve) throws IOException, AS400SecurityException { + return fd_.getOwnerNameByUserHandle(forceRetrieve); + } + + @Override public int getASP() throws IOException, AS400SecurityException { - return fd_.getASP(); + return fd_.getASP(); } // Design note: The following is an alternative implementation of getOwnerName(), using the Qp0lGetAttr API. @@ -1150,150 +974,125 @@ public int getASP() throws IOException, AS400SecurityException { // } - // @B7a - /** - Returns the file's owner's "user ID" number. - Returns -1 if error. - **/ - public long getOwnerUID() - throws IOException, AS400SecurityException // @C0c + + @Override + public long getOwnerUID() throws IOException, AS400SecurityException { - fd_.connect(); - IFSListAttrsRep reply = fd_.listObjAttrs2(); // the "owner UID" field is in the OA2 structure - if (reply != null) - { - return reply.getOwnerUID(); - } - else return -1L; // @C0c + fd_.connect(); + IFSListAttrsRep reply = fd_.listObjAttrs2(); + + return (reply != null) ? reply.getOwnerUID() : -1; } - - /** - Returns the path of the integrated file system object that is directly pointed to by the symbolic link represented by this object. Returns null if the file is not a symbolic link, does not exist, or is in an unsupported file system. -

- This method is not supported for files in the following file systems: -

    -
  • QSYS.LIB -
  • Independent ASP QSYS.LIB -
  • QDLS -
  • QOPT -
  • QNTC -
- - @return The path directly pointed to by the symbolic link, or null if the IFS object is not a symbolic link or does not exist. Depending on how the symbolic link was defined, the path may be either relative or absolute. - - @exception IOException If an error occurs while communicating with the system. - @exception AS400SecurityException If a security or authority error occurs. - **/ - public String getPathPointedTo() - throws IOException, AS400SecurityException + @Override + public String getPathPointedTo() throws IOException, AS400SecurityException { - // Ensure that we are connected to the server. - fd_.connect(); - - // We will call the QlgReadlink API, to determine the path of the immediately pointed-to file. Note that QlgReadlink is only _conditionally_ threadsafe. - - String resolvedPathname = null; - try - { - // Create the pgm call object - if (rmtCmd_ == null) { - setupRemoteCommand(); - } - - int bufferSizeProvided = 1024; // large enough for most anticipated paths - - ProgramParameter[] parameters = new ProgramParameter[] - { - // Parameter 1: Qlg_Path_Name_T *path (input) : - new ProgramParameter(ProgramParameter.PASS_BY_REFERENCE, createPathName()), - // Parameter 2: Qlg_Path_Name_T *buf (output) : - new ProgramParameter(ProgramParameter.PASS_BY_REFERENCE, bufferSizeProvided), - // Parameter 3: size_t bufsiz (input) : - new ProgramParameter(ProgramParameter.PASS_BY_VALUE, BinaryConverter.intToByteArray(bufferSizeProvided)) - }; + // Ensure that we are connected to the server. + fd_.connect(); - final int HEADER_LENGTH = 32; // fixed header of returned Qlg_Path_Name_T structure + // We will call the QlgReadlink API, to determine the path of the immediately pointed-to file. Note that + // QlgReadlink is only _conditionally_ threadsafe. - boolean repeatRun; - do + String resolvedPathname = null; + try { - repeatRun = false; - // Call the service program. - byte[] returnedBytes = rmtCmd_.runServiceProgram("QSYS", "QP0LLIB1", "QlgReadlink", parameters); - if (returnedBytes == null) - { - Trace.log(Trace.ERROR, "Call to QlgReadlink() returned null."); - throw new AS400Exception(rmtCmd_.getMessageList()); - } - - int returnValue = BinaryConverter.byteArrayToInt(returnedBytes, 0); - - if (returnValue == -1) // this indicates that we got an "errno" back - { - int errno = BinaryConverter.byteArrayToInt(returnedBytes, 4); - switch (errno) + // Create the pgm call object + if (rmtCmd_ == null) + setupRemoteCommand(); + + int bufferSizeProvided = 1024; // large enough for most anticipated paths + + ProgramParameter[] parameters = new ProgramParameter[] { + // Parameter 1: Qlg_Path_Name_T *path (input) : + new ProgramParameter(ProgramParameter.PASS_BY_REFERENCE, createPathName()), + // Parameter 2: Qlg_Path_Name_T *buf (output) : + new ProgramParameter(ProgramParameter.PASS_BY_REFERENCE, bufferSizeProvided), + // Parameter 3: size_t bufsiz (input) : + new ProgramParameter(ProgramParameter.PASS_BY_VALUE, BinaryConverter.intToByteArray(bufferSizeProvided)) + }; + + final int HEADER_LENGTH = 32; // fixed header of returned Qlg_Path_Name_T structure + + boolean repeatRun; + do { - case 3021: // EINVAL: "The value specified for the argument is not correct." - // Assume that we got this error because the file isn't a symlink. - if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Received errno "+errno+" from QlgReadlink() for file " + fd_.path_ + ". Assuming that the file is not a symbolic link."); - break; - case 3025: // ENOENT: "No such path or directory." - // Assume that we got this error because the file isn't a symlink. - if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Received errno "+errno+" from QlgReadlink() for file " + fd_.path_ + ". Assuming that the file does not exist."); - break; - default: // some other errno - Trace.log(Trace.ERROR, "Received errno " + errno + " from QlgReadlink() for file " + fd_.path_); - throw new ExtendedIOException(fd_.path_, ExtendedIOException.UNKNOWN_ERROR, errno); + repeatRun = false; + + // Call the service program. + byte[] returnedBytes = rmtCmd_.runServiceProgram("QSYS", "QP0LLIB1", "QlgReadlink", parameters); + if (returnedBytes == null) + { + Trace.log(Trace.ERROR, "Call to QlgReadlink() returned null."); + throw new AS400Exception(rmtCmd_.getMessageList()); + } + + int returnValue = BinaryConverter.byteArrayToInt(returnedBytes, 0); + + if (returnValue == -1) // this indicates that we got an "errno" back + { + int errno = BinaryConverter.byteArrayToInt(returnedBytes, 4); + switch (errno) + { + case 3021: // EINVAL: "The value specified for the argument is not correct." + // Assume that we got this error because the file isn't a symlink. + if (Trace.traceOn_) + Trace.log(Trace.DIAGNOSTIC, "Received errno "+errno+" from QlgReadlink() for file " + fd_.path_ + ". Assuming that the file is not a symbolic link."); + break; + case 3025: // ENOENT: "No such path or directory." + // Assume that we got this error because the file isn't a symlink. + if (Trace.traceOn_) + Trace.log(Trace.DIAGNOSTIC, "Received errno "+errno+" from QlgReadlink() for file " + fd_.path_ + ". Assuming that the file does not exist."); + break; + default: // some other errno + Trace.log(Trace.ERROR, "Received errno " + errno + " from QlgReadlink() for file " + fd_.path_); + throw new ExtendedIOException(fd_.path_, ExtendedIOException.UNKNOWN_ERROR, errno); + } + } + else if ((returnValue + HEADER_LENGTH) > bufferSizeProvided) + { + repeatRun = true; + // Note: returnValue is number of bytes required to hold complete path. + int bufferSizeNeeded = returnValue + HEADER_LENGTH; + if (Trace.traceOn_) + Trace.log(Trace.DIAGNOSTIC, "QlgReadlink() buffer too small. Buffer size provided: " + bufferSizeProvided + ". Buffer size needed: " + bufferSizeNeeded+". Calling QlgReadLink() with larger buffer."); + + bufferSizeProvided = bufferSizeNeeded; + parameters[1].setOutputDataLength(bufferSizeProvided); + parameters[2].setInputData(BinaryConverter.intToByteArray(bufferSizeProvided)); + } + else // We allocated a sufficiently large buffer for the returned data. + { + // Parse the pathname from the returned pathname structure (second parameter). + resolvedPathname = parsePathName(parameters[1].getOutputData()); + } } - } - - else if ((returnValue + HEADER_LENGTH) > bufferSizeProvided) - { - repeatRun = true; - // Note: returnValue is number of bytes required to hold complete path. - int bufferSizeNeeded = returnValue + HEADER_LENGTH; - if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "QlgReadlink() buffer too small. Buffer size provided: " + bufferSizeProvided + ". Buffer size needed: " + bufferSizeNeeded+". Calling QlgReadLink() with larger buffer."); - bufferSizeProvided = bufferSizeNeeded; - parameters[1].setOutputDataLength(bufferSizeProvided); - parameters[2].setInputData(BinaryConverter.intToByteArray(bufferSizeProvided)); - } - - else // We allocated a sufficiently large buffer for the returned data. - { - // Parse the pathname from the returned pathname structure (second parameter). - resolvedPathname = parsePathName(parameters[1].getOutputData()); - } + while (repeatRun); + } + catch (AS400SecurityException|IOException e) { + throw e; + } + catch (Exception e) + { + Trace.log(Trace.ERROR, "Error while resolving symbolic link.", e); + throw new ExtendedIOException(fd_.path_, ExtendedIOException.UNKNOWN_ERROR); } - while (repeatRun); - } // try - catch (AS400SecurityException e) { - throw e; - } - catch (IOException e) { - throw e; - } - catch (Exception e) { - Trace.log(Trace.ERROR, "Error while resolving symbolic link.", e); - throw new ExtendedIOException(fd_.path_, ExtendedIOException.UNKNOWN_ERROR); - } - return resolvedPathname; + return resolvedPathname; } // // Path name structure for QlgAccess(): // -// 0 INPUT BINARY(4) CCSID -// 4 INPUT CHAR(2) Country or region ID -// 6 INPUT CHAR(3) Language ID -// 9 INPUT CHAR(3) Reserved -// 12 INPUT BINARY(4) Path type indicator -// 16 INPUT BINARY(4) Length of path name -// 20 INPUT CHAR(2) Path name delimiter character -// 22 INPUT CHAR(10) Reserved -// 32 INPUT CHAR(*) Path name +// 0 INPUT BINARY(4) CCSID +// 4 INPUT CHAR(2) Country or region ID +// 6 INPUT CHAR(3) Language ID +// 9 INPUT CHAR(3) Reserved +// 12 INPUT BINARY(4) Path type indicator +// 16 INPUT BINARY(4) Length of path name +// 20 INPUT CHAR(2) Path name delimiter character +// 22 INPUT CHAR(10) Reserved +// 32 INPUT CHAR(*) Path name // // // Value of "path type indicator" field: @@ -1304,66 +1103,68 @@ else if ((returnValue + HEADER_LENGTH) > bufferSizeProvided) // Utility method to convert String path into path name parameter used by the QlgAccess() API. private byte[] createPathName() throws IOException { - ConverterImplRemote conv = new ConverterImplRemote(); - conv.setCcsid(1200, fd_.system_); - int pathLength = fd_.path_.length(); // number of Unicode chars - - byte[] buf = new byte[32 + pathLength * 2]; // 2 bytes per Unicode char - BinaryConverter.intToByteArray(1200, buf, 0); // CCSID - BinaryConverter.intToByteArray(2, buf, 12); // path type indicator - BinaryConverter.intToByteArray(pathLength * 2, buf, 16); // length of path name (#bytes) - conv.stringToByteArray("/", buf, 20, 2); // path name delimiter - conv.stringToByteArray(fd_.path_, buf, 32); // path name - return buf; + ConverterImplRemote conv = new ConverterImplRemote(); + conv.setCcsid(1200, fd_.system_); + int pathLength = fd_.path_.length(); // number of Unicode chars + + byte[] buf = new byte[32 + pathLength * 2]; // 2 bytes per Unicode char + BinaryConverter.intToByteArray(1200, buf, 0); // CCSID + BinaryConverter.intToByteArray(2, buf, 12); // path type indicator + BinaryConverter.intToByteArray(pathLength * 2, buf, 16); // length of path name (#bytes) + conv.stringToByteArray("/", buf, 20, 2); // path name delimiter + conv.stringToByteArray(fd_.path_, buf, 32); // path name + + return buf; } // Utility method to parse the path name parameter returned by the QlgAccess() API. private String parsePathName(byte[] buf) throws IOException { - ConverterImplRemote conv = new ConverterImplRemote(); - conv.setCcsid(1200, fd_.system_); - int offset = 0; - int nameLength; - if (DEBUG) - { - System.out.println("Buffer length: " + buf.length); - System.out.println("CCSID: " + BinaryConverter.byteArrayToInt(buf, offset)); - offset += 4; - //System.out.println("Country: " + conv.byteArrayToString(buf, offset, 2)); - offset += 2; - //System.out.println("LangID: " + conv.byteArrayToString(buf, offset, 3)); - offset += 3; - offset += 3; // reserved field - System.out.println("Path type: " + BinaryConverter.byteArrayToInt(buf, offset)); - offset += 4; - nameLength = BinaryConverter.byteArrayToInt(buf, offset); - System.out.println("Path name length: " + nameLength); - offset += 4; - System.out.println("Delimiter: " + conv.byteArrayToString(buf, offset, 2)); - offset += 2; - offset += 10; // reserved field - } - else { - offset += 16; - nameLength = BinaryConverter.byteArrayToInt(buf, offset); - offset += 16; - } + ConverterImplRemote conv = new ConverterImplRemote(); + conv.setCcsid(1200, fd_.system_); + int offset = 0; + int nameLength; + if (DEBUG) + { + System.out.println("Buffer length: " + buf.length); + System.out.println("CCSID: " + BinaryConverter.byteArrayToInt(buf, offset)); + offset += 4; + // System.out.println("Country: " + conv.byteArrayToString(buf, offset, 2)); + offset += 2; + // System.out.println("LangID: " + conv.byteArrayToString(buf, offset, 3)); + offset += 3; + offset += 3; // reserved field + System.out.println("Path type: " + BinaryConverter.byteArrayToInt(buf, offset)); + offset += 4; + nameLength = BinaryConverter.byteArrayToInt(buf, offset); + System.out.println("Path name length: " + nameLength); + offset += 4; + System.out.println("Delimiter: " + conv.byteArrayToString(buf, offset, 2)); + offset += 2; + offset += 10; // reserved field + } + else + { + offset += 16; + nameLength = BinaryConverter.byteArrayToInt(buf, offset); + offset += 16; + } - // We will assume that the caller has verified that the buffer was big enough to accommodate the returned data. - String pathname = conv.byteArrayToString(buf, offset, nameLength); - return pathname; + // We will assume that the caller has verified that the buffer was big enough to accommodate the returned data. + String pathname = conv.byteArrayToString(buf, offset, nameLength); + + return pathname; } - // Utility method to parse the structure returned by the QlgStat() API. private int parseStatInfo(byte[] buf) throws IOException { - ConverterImplRemote conv = new ConverterImplRemote(); - conv.setCcsid(37, fd_.system_); // always EBCDIC + ConverterImplRemote conv = new ConverterImplRemote(); + conv.setCcsid(37, fd_.system_); // always EBCDIC - int fileMode = BinaryConverter.byteArrayToInt(buf, 0); - return fileMode; + int fileMode = BinaryConverter.byteArrayToInt(buf, 0); + return fileMode; // This is for future reference, in case we ever want to exploit other returned fields. @@ -1417,135 +1218,129 @@ private int parseStatInfo(byte[] buf) throws IOException } - // @B5a - // Returns zero-length string if the file has no subtype. - public String getSubtype() - throws IOException, AS400SecurityException + @Override + public String getSubtype() throws IOException, AS400SecurityException { - String subtype = ""; + String subtype = ""; - // Ensure that we are connected to the server. - fd_.connect(); + // Ensure that we are connected to the server. + fd_.connect(); + + // Convert the path name to the server CCSID. + byte[] pathname = fd_.converter_.stringToByteArray(fd_.path_); - // Convert the path name to the server CCSID. - byte[] pathname = fd_.converter_.stringToByteArray(fd_.path_); + boolean needCodePage = (fd_.getSystemVRM() >= 0x00060100 && fd_.path_.indexOf("/QSYS.LIB") != -1); - boolean needCodePage; - if (fd_.getSystemVRM() >= 0x00060100 && - fd_.path_.indexOf("/QSYS.LIB") != -1) { - needCodePage = true; - } - else needCodePage = false; - - // Prepare the List Attributes request. - - // Set up the list of Extended Attributes Names. - byte[] eaName_TYPE = fd_.converter_.stringToByteArray(".TYPE"); - int eaNameBytesLength; - byte[][] eaNamesList; - // Special handling for QSYS files, starting in V6R1. - // Starting in V6R1, for QSYS files, the ".TYPE" EA value field is returned in the CCSID of the object. - // Prior to V6R1, the field is always returned in EBCDIC. - if (needCodePage) - { - byte[] eaName_CODEPAGE = fd_.converter_.stringToByteArray(".CODEPAGE"); - eaNameBytesLength = eaName_TYPE.length + eaName_CODEPAGE.length; - eaNamesList = new byte[][] { eaName_TYPE, eaName_CODEPAGE }; - } - else // not in QSYS, or pre-V6R1 - { - eaNameBytesLength = eaName_TYPE.length; - eaNamesList = new byte[][] { eaName_TYPE }; - } + // Prepare the List Attributes request. + + // Set up the list of Extended Attributes Names. + byte[] eaName_TYPE = fd_.converter_.stringToByteArray(".TYPE"); + int eaNameBytesLength; + byte[][] eaNamesList; + + // Special handling for QSYS files, starting in V6R1. + // Starting in V6R1, for QSYS files, the ".TYPE" EA value field is returned in the CCSID of the object. + // Prior to V6R1, the field is always returned in EBCDIC. + if (needCodePage) + { + byte[] eaName_CODEPAGE = fd_.converter_.stringToByteArray(".CODEPAGE"); + eaNameBytesLength = eaName_TYPE.length + eaName_CODEPAGE.length; + eaNamesList = new byte[][] { eaName_TYPE, eaName_CODEPAGE }; + } + else // not in QSYS, or pre-V6R1 + { + eaNameBytesLength = eaName_TYPE.length; + eaNamesList = new byte[][] { eaName_TYPE }; + } - IFSListAttrsReq req = new IFSListAttrsReq(pathname, fd_.preferredServerCCSID_, - IFSListAttrsReq.NO_AUTHORITY_REQUIRED, NO_MAX_GET_COUNT, - null, false, eaNamesList, eaNameBytesLength, false, fd_.patternMatching_); // @C3c + IFSListAttrsReq req = new IFSListAttrsReq(pathname, fd_.preferredServerCCSID_, + IFSListAttrsReq.NO_AUTHORITY_REQUIRED, NO_MAX_GET_COUNT, + null, false, eaNamesList, eaNameBytesLength, false, fd_.patternMatching_); - Vector replys = fd_.listAttributes(req); + Vector replys = fd_.listAttributes(req); - // Verify that we got at least one reply. - if (replys == null) { - if (Trace.traceOn_) Trace.log(Trace.WARNING, "Received null from listAttributes(req)."); - } - else if (replys.size() == 0) { - if (Trace.traceOn_) Trace.log(Trace.WARNING, "Received no replies from listAttributes(req)."); - } - else - { - if (replys.size() > 1) { - if (Trace.traceOn_) Trace.log(Trace.WARNING, "Received multiple replies from listAttributes(req) (" + - replys.size() + ")"); - } - IFSListAttrsRep reply = (IFSListAttrsRep)replys.elementAt(0); - Hashtable extendedAttributes = reply.getExtendedAttributeValues(); - byte[] subtypeAsBytes = (byte[])extendedAttributes.get(".TYPE"); - if (subtypeAsBytes != null) - { - int ccsid; - if (!needCodePage) { - ccsid = 37; // the returned bytes are in EBCDIC - } - else { - // Get the ".CODEPAGE" extended attribute value from the reply. - byte[] codepageAsBytes = (byte[])extendedAttributes.get(".CODEPAGE"); - // The .CODEPAGE attribute is returned as 2 bytes in little-endian format. - // Therefore we need to swap the bytes. - byte[] swappedBytes = new byte[2]; // the codepage is returned in 2 bytes - swappedBytes[0] = codepageAsBytes[1]; - swappedBytes[1] = codepageAsBytes[0]; - ccsid = BinaryConverter.byteArrayToUnsignedShort(swappedBytes,0); - if (ccsid == 1400) ccsid = 1200; // codepage 1400 corresponds to CCSID 1200 - } - try { - subtype = (new CharConverter(ccsid)).byteArrayToString(subtypeAsBytes, 0).trim(); - } - catch (java.io.UnsupportedEncodingException e) { - Trace.log(Trace.ERROR, "Unrecognized codepage returned: " + ccsid, e); - subtype = "??"; - } + // Verify that we got at least one reply. + if (replys == null) { + if (Trace.traceOn_) Trace.log(Trace.WARNING, "Received null from listAttributes(req)."); } - } - return subtype; + else if (replys.size() == 0) { + if (Trace.traceOn_) Trace.log(Trace.WARNING, "Received no replies from listAttributes(req)."); + } + else + { + if (replys.size() > 1) { + if (Trace.traceOn_) Trace.log(Trace.WARNING, "Received multiple replies from listAttributes(req) (" + replys.size() + ")"); + } + + IFSListAttrsRep reply = (IFSListAttrsRep)replys.elementAt(0); + Hashtable extendedAttributes = reply.getExtendedAttributeValues(); + byte[] subtypeAsBytes = (byte[])extendedAttributes.get(".TYPE"); + + if (subtypeAsBytes != null) + { + int ccsid; + if (!needCodePage) + ccsid = 37; // the returned bytes are in EBCDIC + else + { + // Get the ".CODEPAGE" extended attribute value from the reply. + byte[] codepageAsBytes = (byte[])extendedAttributes.get(".CODEPAGE"); + // The .CODEPAGE attribute is returned as 2 bytes in little-endian format. + // Therefore we need to swap the bytes. + byte[] swappedBytes = new byte[2]; // the codepage is returned in 2 bytes + swappedBytes[0] = codepageAsBytes[1]; + swappedBytes[1] = codepageAsBytes[0]; + ccsid = BinaryConverter.byteArrayToUnsignedShort(swappedBytes,0); + if (ccsid == 1400) + ccsid = 1200; // codepage 1400 corresponds to CCSID 1200 + } + + try { + subtype = (new CharConverter(ccsid)).byteArrayToString(subtypeAsBytes, 0).trim(); + } + catch (java.io.UnsupportedEncodingException e) { + Trace.log(Trace.ERROR, "Unrecognized codepage returned: " + ccsid, e); + subtype = "??"; + } + } + } + + return subtype; } - - /** - Determines if the file is a "source physical file". - **/ - public boolean isSourcePhysicalFile() - throws IOException, AS400SecurityException, AS400Exception + @Override + public boolean isSourcePhysicalFile() throws IOException, AS400SecurityException, AS400Exception { - // Assume that the caller has verified that the file is a Physical File in QSYS. - - // Layout of first 2 attribute bytes returned in FILD0100 format: - // - // BIT(2): Reserved. - // BIT(1): Type of file. If on, the file is a logical database file. - // If off, a physical database file. - // BIT(1): Reserved. - // BIT(1): File type (FILETYPE). If on, the file is a source file (*SRC). - // If off, a data file (*DATA). - // BIT(1): Reserved. - // BIT(1): Access path. If on, the file has a keyed sequence access path. - // If off, an arrival sequence access path. - // BIT(1): Reserved. - // BIT(1): Record format level check (LVLCHK). - // If on, the record format level identifiers are checked when the file is opened (*YES). - // If off, they are not checked when the file is opened (*NO). - // BIT(1): Select/omit. If on, the file is a select/omit logical file. - // BIT(4): Reserved. - // BIT(1): Double-byte character set (DBCS) or Graphic data. - // If on, the file's record format(s) contains DBCS or Graphic data fields. - // BIT(1): Double-byte character set (DBCS) or Graphic literals. - // If on, the file's record format(s) contains DBCS or Graphic literals. - // - - // Examine the FILETYPE bit (the 12th bit from the right). - // If the bit is on, that indicates the file is a source file (*SRC). - // If the bit is off, that indicates the file is a data file (*DATA). - int attributeFlags = retrieveDatabaseFileAttributes(); - return ((attributeFlags & 0x00000800) != 0); // 12th bit from the right + // Assume that the caller has verified that the file is a Physical File in QSYS. + + // Layout of first 2 attribute bytes returned in FILD0100 format: + // + // BIT(2): Reserved. + // BIT(1): Type of file. If on, the file is a logical database file. + // If off, a physical database file. + // BIT(1): Reserved. + // BIT(1): File type (FILETYPE). If on, the file is a source file (*SRC). + // If off, a data file (*DATA). + // BIT(1): Reserved. + // BIT(1): Access path. If on, the file has a keyed sequence access path. + // If off, an arrival sequence access path. + // BIT(1): Reserved. + // BIT(1): Record format level check (LVLCHK). + // If on, the record format level identifiers are checked when the file is opened (*YES). + // If off, they are not checked when the file is opened (*NO). + // BIT(1): Select/omit. If on, the file is a select/omit logical file. + // BIT(4): Reserved. + // BIT(1): Double-byte character set (DBCS) or Graphic data. + // If on, the file's record format(s) contains DBCS or Graphic data fields. + // BIT(1): Double-byte character set (DBCS) or Graphic literals. + // If on, the file's record format(s) contains DBCS or Graphic literals. + // + + // Examine the FILETYPE bit (the 12th bit from the right). + // If the bit is on, that indicates the file is a source file (*SRC). + // If the bit is off, that indicates the file is a data file (*DATA). + int attributeFlags = retrieveDatabaseFileAttributes(); + return ((attributeFlags & 0x00000800) != 0); // 12th bit from the right } /** @@ -1554,1354 +1349,1088 @@ Call QDBRTVFD (if necessary) to get additional status information about the file **/ private int retrieveDatabaseFileAttributes() throws IOException, AS400SecurityException, AS400Exception { - if (databaseFileAttributes_ == null) - { - try + if (databaseFileAttributes_ == null) { - int bufferSizeProvided = 400; // the FILD0100-format structure occupies 400 bytes - ProgramParameter[] parameters = new ProgramParameter[] - { - // Receiver variable, Output, Char(*) - new ProgramParameter(bufferSizeProvided), - // Length of receiver variable, Input, Binary(4) - new ProgramParameter(BinaryConverter.intToByteArray(bufferSizeProvided)), - // Qualified returned file name, Output, Char(20) - new ProgramParameter(20), - // Format name, Input, Char(8) : EBCDIC 'FILD0100' - new ProgramParameter(new byte[] { (byte)0xC6, (byte)0xC9, (byte)0xD3, (byte)0xC4, (byte)0xF0, (byte)0xF1, (byte)0xF0, (byte)0xF0 } ), - // Qualified file name, Input, Char(20) : fileName + libraryName - new ProgramParameter(composeQualifiedNameBytes()), - // Record format name, Input, Char(10) : 10 EBCDIC blanks - new ProgramParameter(new byte[] { (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40 } ), - // Override processing, Input, Char(1) : EBCDIC '0' (no override processing) - new ProgramParameter(new byte[] { (byte)0xF0 } ), - // System, Input, Char(10) : EBCDIC '*LCL' (local files only) - new ProgramParameter(new byte[] { (byte)0x5C, (byte)0xD3, (byte)0xC3, (byte)0xD3, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40 } ), - // Format type, Input, Char(10) : EBCDIC '*INT' - new ProgramParameter(new byte[] { (byte)0x5C, (byte)0xC9, (byte)0xD5, (byte)0xE3, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40 } ), - // Error Code, I/O, Char(*) - new ErrorCodeParameter() - }; - - // Create the pgm call object - if (rmtCmd_ == null) { - setupRemoteCommand(); - } - - if (!rmtCmd_.runProgram("QSYS", "QDBRTVFD", parameters)) // conditionally threadsafe - { - throw new AS400Exception(rmtCmd_.getMessageList()); - } - - byte[] outputData = parameters[0].getOutputData(); - int bytesReturned = BinaryConverter.byteArrayToInt(outputData, 0); - if (bytesReturned < 10) - { - Trace.log(Trace.ERROR, "Insufficient output bytes returned from QDBRTVFD: " + bytesReturned); - throw new InternalErrorException(fd_.path_, InternalErrorException.UNKNOWN); - } - - // Grab the "attribute bytes". These are the 2 bytes starting at offset 8. - databaseFileAttributes_ = Integer.valueOf(BinaryConverter.byteArrayToUnsignedShort(outputData, 8)); - } - catch (AS400Exception e) { - throw e; - } - catch (AS400SecurityException e) { - throw e; - } - catch (IOException e) { - throw e; - } - catch (Exception e) { - Trace.log(Trace.ERROR, "Error while retrieving database file attributes.", e); - throw new ExtendedIOException(fd_.path_, ExtendedIOException.UNKNOWN_ERROR); + try + { + int bufferSizeProvided = 400; // the FILD0100-format structure occupies 400 bytes + ProgramParameter[] parameters = new ProgramParameter[] { + // Receiver variable, Output, Char(*) + new ProgramParameter(bufferSizeProvided), + // Length of receiver variable, Input, Binary(4) + new ProgramParameter(BinaryConverter.intToByteArray(bufferSizeProvided)), + // Qualified returned file name, Output, Char(20) + new ProgramParameter(20), + // Format name, Input, Char(8) : EBCDIC 'FILD0100' + new ProgramParameter(new byte[] { (byte)0xC6, (byte)0xC9, (byte)0xD3, (byte)0xC4, (byte)0xF0, (byte)0xF1, (byte)0xF0, (byte)0xF0 } ), + // Qualified file name, Input, Char(20) : fileName + libraryName + new ProgramParameter(composeQualifiedNameBytes()), + // Record format name, Input, Char(10) : 10 EBCDIC blanks + new ProgramParameter(new byte[] { (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40 } ), + // Override processing, Input, Char(1) : EBCDIC '0' (no override processing) + new ProgramParameter(new byte[] { (byte)0xF0 } ), + // System, Input, Char(10) : EBCDIC '*LCL' (local files only) + new ProgramParameter(new byte[] { (byte)0x5C, (byte)0xD3, (byte)0xC3, (byte)0xD3, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40 } ), + // Format type, Input, Char(10) : EBCDIC '*INT' + new ProgramParameter(new byte[] { (byte)0x5C, (byte)0xC9, (byte)0xD5, (byte)0xE3, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40, (byte)0x40 } ), + // Error Code, I/O, Char(*) + new ErrorCodeParameter() + }; + + // Create the pgm call object + if (rmtCmd_ == null) + setupRemoteCommand(); + + if (!rmtCmd_.runProgram("QSYS", "QDBRTVFD", parameters)) // conditionally threadsafe + throw new AS400Exception(rmtCmd_.getMessageList()); + + byte[] outputData = parameters[0].getOutputData(); + int bytesReturned = BinaryConverter.byteArrayToInt(outputData, 0); + if (bytesReturned < 10) + { + Trace.log(Trace.ERROR, "Insufficient output bytes returned from QDBRTVFD: " + bytesReturned); + throw new InternalErrorException(fd_.path_, InternalErrorException.UNKNOWN); + } + + // Grab the "attribute bytes". These are the 2 bytes starting at offset 8. + databaseFileAttributes_ = Integer.valueOf(BinaryConverter.byteArrayToUnsignedShort(outputData, 8)); + } + catch (AS400Exception|AS400SecurityException|IOException e) { + throw e; + } + catch (Exception e) { + Trace.log(Trace.ERROR, "Error while retrieving database file attributes.", e); + throw new ExtendedIOException(fd_.path_, ExtendedIOException.UNKNOWN_ERROR); + } } - } - return databaseFileAttributes_.intValue(); + return databaseFileAttributes_.intValue(); } - // Setup qualified file name program parameter object on first touch. Synchronized to protect instance variables. This method can safely be called multiple times because it checks for a previous call before changing the instance variables. + // Setup qualified file name program parameter object on first touch. Synchronized to protect instance variables. + // This method can safely be called multiple times because it checks for a previous call before changing the instance variables. private synchronized byte[] composeQualifiedNameBytes() throws IOException { - // If not already setup. - if (qualifiedFileName_ == null) - { - CharConverter converter = new CharConverter(37); // converts Unicode chars to EBCDIC bytes + // If not already setup. + if (qualifiedFileName_ == null) + { + CharConverter converter = new CharConverter(37); // converts Unicode chars to EBCDIC bytes - // Start with 20 EBCDIC spaces. - qualifiedFileName_ = new byte[] { 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 }; + // Start with 20 EBCDIC spaces. + qualifiedFileName_ = new byte[] { 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 }; - // Parse out the library and filename from the path. - QSYSObjectPathName qsysPath = new QSYSObjectPathName(fd_.path_); - String libraryName = qsysPath.getLibraryName(); - String fileName = qsysPath.getObjectName(); + // Parse out the library and filename from the path. + QSYSObjectPathName qsysPath = new QSYSObjectPathName(fd_.path_); + String libraryName = qsysPath.getLibraryName(); + String fileName = qsysPath.getObjectName(); - // Put the converted file name at the beginning of the array. - converter.stringToByteArray(fileName, qualifiedFileName_, 0); - // Put the converted library name at position ten. - converter.stringToByteArray(libraryName, qualifiedFileName_, 10); - } + // Put the converted file name at the beginning of the array. + converter.stringToByteArray(fileName, qualifiedFileName_, 0); + // Put the converted library name at position ten. + converter.stringToByteArray(libraryName, qualifiedFileName_, 10); + } - return qualifiedFileName_; + return qualifiedFileName_; } - - /** - Determines if the integrated file system object represented by this object is a directory. - **/ - public int isDirectory() - throws IOException, AS400SecurityException + @Override + public int isDirectory() throws IOException, AS400SecurityException { - // Ensure that we are connected to the server. - fd_.connect(); + // Ensure that we are connected to the server. + fd_.connect(); - int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; + int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; - if (attributesReply_ == null) - { - attributesReply_ = getAttributeSetFromServer(fd_.path_); - } + if (attributesReply_ == null) + attributesReply_ = getAttributeSetFromServer(fd_.path_); - //@B1A Added code to call determineIsDirectory(). - if (attributesReply_ != null) - { - if (determineIsDirectory(attributesReply_)) - returnCode = IFSReturnCodeRep.SUCCESS; - } + if (attributesReply_ != null) + if (determineIsDirectory(attributesReply_)) + returnCode = IFSReturnCodeRep.SUCCESS; - return returnCode; + return returnCode; } - - /** - Determines if the integrated file system object represented by this object is a "normal" file.
- A file is "normal" if it is not a directory or a container of other objects. - **/ - public int isFile() - throws IOException, AS400SecurityException + @Override + public int isFile() throws IOException, AS400SecurityException { - // Ensure that we are connected to the server. - fd_.connect(); + // Ensure that we are connected to the server. + fd_.connect(); - int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; + int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; - if (attributesReply_ == null) - { - attributesReply_ = getAttributeSetFromServer(fd_.path_); - } + if (attributesReply_ == null) + attributesReply_ = getAttributeSetFromServer(fd_.path_); - //@B1A Added code to call determineIsFile(). - if (attributesReply_ != null) - { - if (determineIsFile(attributesReply_)) - returnCode = IFSReturnCodeRep.SUCCESS; - } + if (attributesReply_ != null) + if (determineIsFile(attributesReply_)) + returnCode = IFSReturnCodeRep.SUCCESS; - return returnCode; + return returnCode; } - /** - Determines if the integrated file system object represented by this - object has its hidden attribute set. - **/ - // @D1 - new method because of changes to java.io.file in Java 2. - - public boolean isHidden() - throws IOException, AS400SecurityException + @Override + public boolean isHidden() throws IOException, AS400SecurityException { - // Ensure that we are connected to the server. - fd_.connect(); + // Ensure that we are connected to the server. + fd_.connect(); - boolean result = false; + boolean result = false; - if (attributesReply_ == null) - { - // Attempt to get the attributes of this object. - attributesReply_ = getAttributeSetFromServer(fd_.path_); - } + // Attempt to get the attributes of this object if we do not have them. + if (attributesReply_ == null) + attributesReply_ = getAttributeSetFromServer(fd_.path_); - // Determine if the file attributes indicate hidden. - if (attributesReply_ != null) - { - result = (attributesReply_.getFixedAttributes() & IFSListAttrsRep.FA_HIDDEN) != 0; - } + // Determine if the file attributes indicate hidden. + if (attributesReply_ != null) + result = (attributesReply_.getFixedAttributes() & IFSListAttrsRep.FA_HIDDEN) != 0; - return result; + return result; } - private boolean isInQsys() { - String lowercasePath = fd_.path_.toLowerCase().replaceAll("//+","/"); - return lowercasePath.equals("/qsys.lib") || lowercasePath.startsWith("/qsys.lib/"); + private boolean isInQsys() + { + // TODO This code is flawed, since it does not take into account iASP paths. Needs to be corrected. + + String lowercasePath = fd_.path_.toLowerCase().replaceAll("//+", "/"); + return lowercasePath.equals("/qsys.lib") || lowercasePath.startsWith("/qsys.lib/"); } - /** - Determines if the integrated file system object represented by this - object has its hidden attribute set. - **/ - // @D1 - new method because of changes to java.io.file in Java 2. - - public boolean isReadOnly() - throws IOException, AS400SecurityException + @Override + public boolean isReadOnly() throws IOException, AS400SecurityException { - // Ensure that we are connected to the server. - fd_.connect(); + // Ensure that we are connected to the server. + fd_.connect(); - boolean result = false; + boolean result = false; - if (attributesReply_ == null) - { - // Attempt to get the attributes of this object. - attributesReply_ = getAttributeSetFromServer(fd_.path_); - } + // Attempt to get the attributes of this object if we do not have them. + if (attributesReply_ == null) + attributesReply_ = getAttributeSetFromServer(fd_.path_); - // Determine if the file attributes indicate hidden. - if (attributesReply_ != null) - { - result = (attributesReply_.getFixedAttributes() & IFSListAttrsRep.FA_READONLY) != 0; - } + // Determine if the file attributes indicate hidden. + if (attributesReply_ != null) + result = (attributesReply_.getFixedAttributes() & IFSListAttrsRep.FA_READONLY) != 0; - return result; + return result; } - - /** - Determines if the integrated file system object represented by this object is a symbolic link. - **/ - public boolean isSymbolicLink() - throws IOException, AS400SecurityException + @Override + public boolean isSymbolicLink() throws IOException, AS400SecurityException { - // Ensure that we are connected to the server. - fd_.connect(); - - if (fd_.getSystemVRM() < 0x00050300) - { - if (Trace.traceOn_) Trace.log(Trace.WARNING, "Server is V5R2 or lower, so isSymbolicLink() will always report false."); - return false; - } + // Ensure that we are connected to the server. + fd_.connect(); - // Temporary workaround, until better File Server support is in place. - // if (attributesReply_ != null) - // { - // System.out.println("DEBUG IFSFileImplRemote.isSymbolicLink(): attributesReply_ != null"); - // result = attributesReply_.isSymbolicLink(fd_.serverDatastreamLevel_); - // } - // else - // - if (!determinedIsSymbolicLink_) - { - // QSYS doesn't support symbolic links, so no need to check - if(isInQsys()) { - isSymbolicLink_ = false; - determinedIsSymbolicLink_ = true; - return isSymbolicLink_; - } - // Note: As of V5R3, we can't get accurate symbolic link info by querying the attrs of a specific file. - // Instead, we must query the contents of the parent directory. - int pathLen = fd_.path_.length(); - if (pathLen <= 1) { - if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Path length is less than 2, so assuming not a symbolic link: " + fd_.path_); - isSymbolicLink_ = false; - determinedIsSymbolicLink_ = true; - } - else + if (fd_.getSystemVRM() < 0x00050300) { - // Do a wildcard search. - StringBuffer wildCardPatternBuf = new StringBuffer(fd_.path_); - wildCardPatternBuf.setCharAt(pathLen-1, '*'); - String wildCardPattern = wildCardPatternBuf.toString(); - String dirPath = wildCardPattern.substring(0,1+wildCardPattern.lastIndexOf('/')); - - byte[] pathBytes = fd_.converter_.stringToByteArray(wildCardPattern); - IFSCachedAttributes[] attrList = listDirectoryDetails(wildCardPattern, dirPath, NO_MAX_GET_COUNT, pathBytes, IS_RESTART_NAME, !SORT_LIST); + if (Trace.traceOn_) Trace.log(Trace.WARNING, "Server is V5R2 or lower, so isSymbolicLink() will always report false."); + return false; + } - IFSCachedAttributes attrs = null; - String filename = fd_.path_.substring(1+(fd_.path_.lastIndexOf('/'))); - for (int i=0; attrs == null && i> 8 != 0x00000502) // system is other than V5R2 @C1c - { // Attempt to list the attributes of the specified file. // Note: Do not use cached attributes, since they may be out of date. IFSListAttrsRep attrs = getAttributeSetFromServer(fd_.path_); - if (attrs != null) { - attributesReply_ = attrs; - size = attrs.getSize(fd_.serverDatastreamLevel_); + attributesReply_ = attrs; + modificationDate = attrs.getModificationDate(); } - } - else // the system is V5R2 (and therefore, datastream level is 3) - { - // Convert the path name to the server CCSID. - byte[] pathname = fd_.converter_.stringToByteArray(fd_.path_); - // Send the List Attributes request. Indicate that we want the "8-byte file size". - IFSListAttrsReq req = new IFSListAttrsReq(pathname, fd_.preferredServerCCSID_, - IFSListAttrsReq.NO_AUTHORITY_REQUIRED, NO_MAX_GET_COUNT, - null, true, null, 0, true, fd_.patternMatching_); // @C3c - Vector replys = fd_.listAttributes(req); + return modificationDate; + } - if (replys == null) { - if (fd_.errorRC_ != 0) { - throw new ExtendedIOException(fd_.path_, fd_.errorRC_); - } - else throw new InternalErrorException(InternalErrorException.UNKNOWN); - } - else if (replys.size() == 0) { - // Assume this simply indicates that the file does not exist. - if (Trace.traceOn_) { - Trace.log(Trace.WARNING, "Received no replies from listAttributes(req)."); - } - } - else + @Override + public long length() throws IOException, AS400SecurityException + { + // Ensure that we are connected to the server. + fd_.connect(); + + long size = 0L; + + if (fd_.getSystemVRM() >> 8 != 0x00000502) { - if ( replys.size() > 1 && - Trace.traceOn_ ) - { - Trace.log(Trace.WARNING, "Received multiple replies from listAttributes(req) (" + - replys.size() + ")"); - } - IFSListAttrsRep reply = (IFSListAttrsRep)replys.elementAt(0); // use first reply - size = reply.getSize8Bytes(/*fd_.serverDatastreamLevel_*/); + // Attempt to list the attributes of the specified file. + // Note: Do not use cached attributes, since they may be out of date. + IFSListAttrsRep attrs = getAttributeSetFromServer(fd_.path_); + + if (attrs != null) + { + attributesReply_ = attrs; + size = attrs.getSize(fd_.serverDatastreamLevel_); + } } - } - return size; - } + else // the system is V5R2 (and therefore, datastream level is 3) + { + // Convert the path name to the server CCSID. + byte[] pathname = fd_.converter_.stringToByteArray(fd_.path_); + + // Send the List Attributes request. Indicate that we want the "8-byte file size". + IFSListAttrsReq req = new IFSListAttrsReq(pathname, fd_.preferredServerCCSID_, + IFSListAttrsReq.NO_AUTHORITY_REQUIRED, NO_MAX_GET_COUNT, + null, true, null, 0, true, fd_.patternMatching_); + Vector replys = fd_.listAttributes(req); + if (replys == null) + { + if (fd_.errorRC_ != 0) + throw new ExtendedIOException(fd_.path_, fd_.errorRC_); + else + throw new InternalErrorException(InternalErrorException.UNKNOWN); + } + else if (replys.size() == 0) + { + // Assume this simply indicates that the file does not exist. + if (Trace.traceOn_) Trace.log(Trace.WARNING, "Received no replies from listAttributes(req)."); + } + else + { + if (replys.size() > 1 && Trace.traceOn_) + Trace.log(Trace.WARNING, "Received multiple replies from listAttributes(req) (" + replys.size() + ")"); + IFSListAttrsRep reply = (IFSListAttrsRep) replys.elementAt(0); // use first reply + size = reply.getSize8Bytes(/* fd_.serverDatastreamLevel_ */); + } + } + + return size; + } // Fetch list attributes reply(s) for the specified path. - private Vector listAttributes(String path, int maxGetCount, byte[] restartNameOrID, boolean isRestartName, boolean sortList) // @D4C @C3c + private Vector listAttributes(String path, int maxGetCount, byte[] restartNameOrID, boolean isRestartName, boolean sortList) throws IOException, AS400SecurityException { - // Assume connect() has already been done. + // Assume connect() has already been done. + + if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "list attributes for: " + path); - // Convert the pathname to the server CCSID. - byte[] pathname = fd_.converter_.stringToByteArray(path); + // Convert the pathname to the server CCSID. + byte[] pathname = fd_.converter_.stringToByteArray(path); - // Prepare the 'list attributes' request. - IFSListAttrsReq req = new IFSListAttrsReq(pathname, fd_.preferredServerCCSID_, // @D4A - IFSListAttrsReq.NO_AUTHORITY_REQUIRED, maxGetCount, // @D4A - restartNameOrID, // @D4A @C3c - isRestartName, // @C3a - null, 0, false, fd_.patternMatching_); + // Prepare the 'list attributes' request. + IFSListAttrsReq req = new IFSListAttrsReq(pathname, fd_.preferredServerCCSID_, + IFSListAttrsReq.NO_AUTHORITY_REQUIRED, maxGetCount, + restartNameOrID, isRestartName, null, 0, false, fd_.patternMatching_); - if (sortList) req.setSorted(true); - return fd_.listAttributes(req); // Note: This does setFD() on each returned IFSListAttrsRep.. + if (sortList) + req.setSorted(true); + + return fd_.listAttributes(req); // Note: This does setFD() on each returned IFSListAttrsRep.. } - // @A7A - // List the files/directories in the specified directory. - // Returns null if specified file or directory does not exist. - public String[] listDirectoryContents(String directoryPath) - throws IOException, AS400SecurityException + @Override + public String[] listDirectoryContents(String directoryPath) throws IOException, AS400SecurityException { - // Ensure that we are connected to the server. - fd_.connect(); + // Ensure that we are connected to the server. + fd_.connect(); - Vector replys = listAttributes(directoryPath, NO_MAX_GET_COUNT, null, NO_RESTART_NAME, sortLists_); - String[] names = null; + Vector replys = listAttributes(directoryPath, NO_MAX_GET_COUNT, null, NO_RESTART_NAME, sortLists_); + String[] names = null; - // Add the name for each file or directory in the specified directory, - // to the array of names. + // Add the name for each file or directory in the specified directory, + // to the array of names. - // @A1C - // Changed the behavior of the list() to conform to that of the JDK1.1.x - // so that a NULL is returned if and only if the directory or file represented - // by this IFSFile object doesn't exist. - // - // Original code: - // if (replys != null && replys.size() != 0) - if (replys != null) // @A1C - { - names = new String[replys.size()]; - int j = 0; - for (int i = 0; i < replys.size(); i++) + // Changed the behavior of the list() to conform to that of the JDK1.1.x + // so that a NULL is returned if and only if the directory or file represented + // by this IFSFile object doesn't exist. + if (replys != null) { - IFSListAttrsRep reply = (IFSListAttrsRep) replys.elementAt(i); - String name = fd_.converter_.byteArrayToString(reply.getName(/*dsl*/)); - if (!(name.equals(".") || name.equals(".."))) - { - names[j++] = name; - } - } + names = new String[replys.size()]; + int j = 0; + for (int i = 0; i < replys.size(); i++) + { + IFSListAttrsRep reply = (IFSListAttrsRep) replys.elementAt(i); + String name = fd_.converter_.byteArrayToString(reply.getName(/* dsl */)); + + if (!(name.equals(".") || name.equals(".."))) + names[j++] = name; + } - if (j == 0) - { - // @A1C - // - // Original code: - // names = null; - names = new String[0]; // @A1C - } - else if (names.length != j) - { - // Copy the names to an array of the exact size. - String[] newNames = new String[j]; - System.arraycopy(names, 0, newNames, 0, j); - names = newNames; + if (j == 0) + names = new String[0]; + else if (names.length != j) + { + // Copy the names to an array of the exact size. + String[] newNames = new String[j]; + System.arraycopy(names, 0, newNames, 0, j); + names = newNames; + } } - } - return names; + return names; } - - // @B1A Added this function to support caching attributes. - // @C3C Morphed this method by adding a parameter and making it private. + // Added this function to support caching attributes. // List the files/directories details in the specified directory. // Returns null if specified file or directory does not exist. - private IFSCachedAttributes[] listDirectoryDetails(String pathPattern, - String directoryPath, - int maxGetCount, // @D4A - byte[] restartNameOrID, // @C3C - boolean isRestartName, // @C3A - boolean sortList) - throws IOException, AS400SecurityException + private IFSCachedAttributes[] listDirectoryDetails(String pathPattern, String directoryPath, + int maxGetCount, byte[] restartNameOrID, boolean isRestartName, + boolean sortList) throws IOException, AS400SecurityException { - // Ensure that we are connected to the server. - fd_.connect(); - - IFSCachedAttributes[] fileAttributes = null; - - try - { - // Design note: Due to a limitation in the File Server, if we specify a "filename pattern", we cannot get OA1 or OA2 structures in the reply. - // Only "handle-based" requests can get OA* structures in the reply; and a handls is specific to a single file. - // This prevents us, for example, from obtaining the "name of file owner" values for an entire list of files at once; rather, we must obtain that attribute one file at a time. - Vector replys = listAttributes(pathPattern, maxGetCount, restartNameOrID, isRestartName, sortList); + // Ensure that we are connected to the server. + fd_.connect(); - // Add each file or directory in the specified directory, - // to the array of files. + IFSCachedAttributes[] fileAttributes = null; - int j = 0; - if (replys != null) + try { - fileAttributes = new IFSCachedAttributes[replys.size()]; - int dsl = fd_.serverDatastreamLevel_; - for (int i = 0; i < replys.size(); i++) - { - IFSListAttrsRep reply = (IFSListAttrsRep) replys.elementAt(i); - String name = fd_.converter_.byteArrayToString(reply.getName(/*dsl*/)); - if (!(name.equals(".") || name.equals(".."))) + // Design note: Due to a limitation in the File Server, if we specify a "filename pattern", we cannot get OA1 + // or OA2 structures in the reply. + // Only "handle-based" requests can get OA* structures in the reply; and a handls is specific to a single + // file. + // This prevents us, for example, from obtaining the "name of file owner" values for an entire list of files + // at once; rather, we must obtain that attribute one file at a time. + Vector replys = listAttributes(pathPattern, maxGetCount, restartNameOrID, isRestartName, sortList); + + // Add each file or directory in the specified directory, + // to the array of files. + + int j = 0; + if (replys != null) { - // isDirectory and isFile should be different unless the - // file is an invalid symbolic link (circular or points - // to a non-existent object). Such a link cannot - // be resolved and both determineIsDirectory and - // determineIsFile will return false. Regular symbolic links - // will resolve. For example, a symbolic link to a file will return - // true from isFile and false from determineIsDirectory. - boolean isDirectory = determineIsDirectory(reply); - boolean isFile = determineIsFile(reply); - IFSCachedAttributes attributes = new IFSCachedAttributes(reply.getAccessDate(), - reply.getCreationDate(), reply.getFixedAttributes(), reply.getModificationDate(), - reply.getObjectType(), reply.getSize(dsl), name, directoryPath, isDirectory, isFile, - reply.getRestartID(), reply.isSymbolicLink(dsl), reply.getFileSystemType(dsl)); //@B3A @C3C - fileAttributes[j++] = attributes; - } - } - }//end if + fileAttributes = new IFSCachedAttributes[replys.size()]; + int dsl = fd_.serverDatastreamLevel_; + + for (int i = 0; i < replys.size(); i++) + { + IFSListAttrsRep reply = (IFSListAttrsRep) replys.elementAt(i); + String name = fd_.converter_.byteArrayToString(reply.getName(/*dsl*/)); + if (!(name.equals(".") || name.equals(".."))) + { + // isDirectory and isFile should be different unless the + // file is an invalid symbolic link (circular or points + // to a non-existent object). Such a link cannot + // be resolved and both determineIsDirectory and + // determineIsFile will return false. Regular symbolic links + // will resolve. For example, a symbolic link to a file will return + // true from isFile and false from determineIsDirectory. + boolean isDirectory = determineIsDirectory(reply); + boolean isFile = determineIsFile(reply); + IFSCachedAttributes attributes = new IFSCachedAttributes(reply.getAccessDate(), + reply.getCreationDate(), reply.getFixedAttributes(), reply.getModificationDate(), + reply.getObjectType(), reply.getSize(dsl), name, directoryPath, isDirectory, isFile, + reply.getRestartID(), reply.isSymbolicLink(dsl), reply.getFileSystemType(dsl)); + fileAttributes[j++] = attributes; + } + } + } - if (j == 0) - { - fileAttributes = new IFSCachedAttributes[0]; //@B3C + if (j == 0) + fileAttributes = new IFSCachedAttributes[0]; + else if (fileAttributes.length != j) + { + //Copy the attributes to an array of the exact size. + IFSCachedAttributes[] newFileAttributes = new IFSCachedAttributes[j]; + System.arraycopy(fileAttributes, 0, newFileAttributes, 0, j); + fileAttributes = newFileAttributes; + } } - else if (fileAttributes.length != j) + catch (AS400SecurityException e) { - //Copy the attributes to an array of the exact size. - IFSCachedAttributes[] newFileAttributes = new IFSCachedAttributes[j]; //@B3C - System.arraycopy(fileAttributes, 0, newFileAttributes, 0, j); //@B3C - fileAttributes = newFileAttributes; + fileAttributes = null; + throw e; } - } - catch (AS400SecurityException e) - { - fileAttributes = null; - throw e; - } - return fileAttributes; + + return fileAttributes; } - - // @B1A Added this function to support caching attributes. - // @C3c Moved logic from this method into new private method. - // List the files/directories details in the specified directory. - // Returns null if specified file or directory does not exist. - public IFSCachedAttributes[] listDirectoryDetails(String pathPattern, - String directoryPath, - int maxGetCount, // @D4A - String restartName) // @D4A - throws IOException, AS400SecurityException + @Override + public IFSCachedAttributes[] listDirectoryDetails(String pathPattern, String directoryPath, + int maxGetCount, String restartName) throws IOException, AS400SecurityException { - byte[] restartNameBytes = fd_.converter_.stringToByteArray(restartName); // @C3M - return listDirectoryDetails(pathPattern, directoryPath, maxGetCount, restartNameBytes, IS_RESTART_NAME, sortLists_); //@D7C + byte[] restartNameBytes = fd_.converter_.stringToByteArray(restartName); + return listDirectoryDetails(pathPattern, directoryPath, maxGetCount, restartNameBytes, IS_RESTART_NAME, sortLists_); //@D7C } - // @C3a - // List the files/directories details in the specified directory. - // Returns null if specified file or directory does not exist. - public IFSCachedAttributes[] listDirectoryDetails(String pathPattern, - String directoryPath, - int maxGetCount, - byte[] restartID, - boolean allowSortedRequests) //@D7C - throws IOException, AS400SecurityException + + @Override + public IFSCachedAttributes[] listDirectoryDetails(String pathPattern, String directoryPath, + int maxGetCount, byte[] restartID, + boolean allowSortedRequests) throws IOException, AS400SecurityException { - boolean sortParameter = (allowSortedRequests ? sortLists_ : false); //@D7A - return listDirectoryDetails(pathPattern, directoryPath, maxGetCount, restartID, !IS_RESTART_NAME, sortParameter); //@D7C + boolean sortParameter = (allowSortedRequests ? sortLists_ : false); + return listDirectoryDetails(pathPattern, directoryPath, maxGetCount, restartID, !IS_RESTART_NAME, sortParameter); } - - - /** - Creates an integrated file system directory whose path name is specified by this object. - **/ - public int mkdir(String directory) - throws IOException, AS400SecurityException + @Override + public int mkdir(String directory) throws IOException, AS400SecurityException { - // Ensure that the path name is set. - fd_.connect(); + // Ensure that the path name is set. + fd_.connect(); - int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; + int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; - try - { - // Convert the directory name to the server CCSID. - byte[] pathname = fd_.converter_.stringToByteArray(directory); + try + { + // Convert the directory name to the server CCSID. + byte[] pathname = fd_.converter_.stringToByteArray(directory); - // Send a create directory request. - IFSCreateDirReq req = new IFSCreateDirReq(pathname, - fd_.preferredServerCCSID_); - ClientAccessDataStream ds = - (ClientAccessDataStream) fd_.server_.sendAndReceive(req); + // Send a create directory request. + IFSCreateDirReq req = new IFSCreateDirReq(pathname, fd_.preferredServerCCSID_); + ClientAccessDataStream ds = (ClientAccessDataStream) fd_.server_.sendAndReceive(req); - // Verify the reply. - if (ds instanceof IFSReturnCodeRep) + // Verify the reply. + if (ds instanceof IFSReturnCodeRep) + { + returnCode = ((IFSReturnCodeRep) ds).getReturnCode(); + if (returnCode == IFSReturnCodeRep.ACCESS_DENIED_TO_DIR_ENTRY + || returnCode == IFSReturnCodeRep.ACCESS_DENIED_TO_REQUEST) + throw new AS400SecurityException(directory, AS400SecurityException.DIRECTORY_ENTRY_ACCESS_DENIED); + } + else + { + Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); + throw new InternalErrorException(Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); + } + } + catch (ConnectionDroppedException e) { - returnCode = ((IFSReturnCodeRep) ds).getReturnCode(); - if (returnCode == IFSReturnCodeRep.ACCESS_DENIED_TO_DIR_ENTRY - || returnCode == IFSReturnCodeRep.ACCESS_DENIED_TO_REQUEST) - { - throw new AS400SecurityException(directory, AS400SecurityException.DIRECTORY_ENTRY_ACCESS_DENIED); - } - } - else + Trace.log(Trace.ERROR, "Byte stream server connection lost."); + fd_.connectionDropped(e); + } + catch (InterruptedException e) { - // Unknown data stream. - Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); - throw new - InternalErrorException(Integer.toHexString(ds.getReqRepID()), - InternalErrorException.DATA_STREAM_UNKNOWN); + Trace.log(Trace.ERROR, "Interrupted"); + InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); + throwException.initCause(e); + throw throwException; } - } - catch(ConnectionDroppedException e) - { - Trace.log(Trace.ERROR, "Byte stream server connection lost."); - fd_.connectionDropped(e); - } - catch(InterruptedException e) - { - Trace.log(Trace.ERROR, "Interrupted"); - InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); - throwException.initCause(e); - throw throwException; - } - return returnCode; + return returnCode; } - - /** - Creates an integrated file system directory whose path name is specified by this object. In addition, create all parent directories as necessary. - **/ - public int mkdirs() - throws IOException, AS400SecurityException + @Override + public int mkdirs() throws IOException, AS400SecurityException { - // Ensure that we are connected to the server. - fd_.connect(); + // Ensure that we are connected to the server. + fd_.connect(); - // Traverse up the parent directories until the first parent - // directory that exists is found, saving each parent directory - // as we go. - boolean success = false; - Vector nonexistentDirs = new Vector(); - String directory = fd_.path_; - int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; + // Traverse up the parent directories until the first parent + // directory that exists is found, saving each parent directory + // as we go. + Vector nonexistentDirs = new Vector(); + String directory = fd_.path_; + int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; - returnCode = exists(directory); - if (returnCode != IFSReturnCodeRep.SUCCESS) - { - do + returnCode = exists(directory); + if (returnCode != IFSReturnCodeRep.SUCCESS) { - nonexistentDirs.addElement(directory); - directory = IFSFile.getParent(directory); - } - while ((directory != null) && (exists(directory) != IFSReturnCodeRep.SUCCESS)); - } else - { - returnCode = IFSReturnCodeRep.DUPLICATE_DIR_ENTRY_NAME; - } + do + { + nonexistentDirs.addElement(directory); + directory = IFSFile.getParent(directory); + } + while ((directory != null) && (exists(directory) != IFSReturnCodeRep.SUCCESS)); + } + else + returnCode = IFSReturnCodeRep.DUPLICATE_DIR_ENTRY_NAME; - // Create each parent directory in the reverse order that - // they were saved. - for (int i = nonexistentDirs.size(); i > 0; i--) - { - // Get the name of the next directory to create. - //try //@B1D - //{ //@B1D - directory = (String) nonexistentDirs.elementAt(i - 1); - //} //@B1D - //catch(Exception e) //@B1D - //{ //@B1D - // Trace.log(Trace.ERROR, "Error fetching element from vector.\n" + //@B1D - // "length = " + nonexistentDirs.size() + " index = ", //@B1D - // i - 1); - // throw new InternalErrorException(InternalErrorException.UNKNOWN); //@B1D - //} - - // Create the next directory. - returnCode = mkdir(directory); - if (returnCode != IFSReturnCodeRep.SUCCESS) + // Create each parent directory in the reverse order that + // they were saved. + for (int i = nonexistentDirs.size(); i > 0; i--) { - // Unable to create a directory. - break; + directory = (String) nonexistentDirs.elementAt(i - 1); + + // Create the next directory. + returnCode = mkdir(directory); + if (returnCode != IFSReturnCodeRep.SUCCESS) + { + // Unable to create a directory. + break; + } } - } - return returnCode; + return returnCode; } - - /** - Renames the integrated file system object specified by this object to have the path name of file. Wildcards are not permitted in this file name. - @param file The new file name. - **/ - public int renameTo(IFSFileImpl file) - throws IOException, AS400SecurityException + @Override + public int renameTo(IFSFileImpl file) throws IOException, AS400SecurityException { - // Ensure that we are connected to the server. - fd_.connect(); + // Ensure that we are connected to the server. + fd_.connect(); - // Assume the argument has been validated by the public class. + // Assume the argument has been validated by the public class. - // Rename the file. - boolean success = false; - ClientAccessDataStream ds = null; - IFSFileImplRemote otherFile = (IFSFileImplRemote)file; - try - { - // Convert the path names to the server CCSID. - byte[] oldName = fd_.converter_.stringToByteArray(fd_.path_); - byte[] newName = fd_.converter_.stringToByteArray(otherFile.getAbsolutePath()); - - // Issue a rename request. - IFSRenameReq req = new IFSRenameReq(oldName, newName, - fd_.preferredServerCCSID_, - false); - ds = (ClientAccessDataStream) fd_.server_.sendAndReceive(req); - } - catch(ConnectionDroppedException e) - { - Trace.log(Trace.ERROR, "Byte stream server connection lost."); - fd_.connectionDropped(e); - } - catch(InterruptedException e) - { - Trace.log(Trace.ERROR, "Interrupted"); - InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); - throwException.initCause(e); - throw throwException; - } + // Rename the file. + boolean success = false; + ClientAccessDataStream ds = null; + IFSFileImplRemote otherFile = (IFSFileImplRemote)file; + try + { + // Convert the path names to the server CCSID. + byte[] oldName = fd_.converter_.stringToByteArray(fd_.path_); + byte[] newName = fd_.converter_.stringToByteArray(otherFile.getAbsolutePath()); - int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; - // Verify the reply. - if (ds instanceof IFSReturnCodeRep) - { - returnCode = ((IFSReturnCodeRep) ds).getReturnCode(); - if (returnCode == IFSReturnCodeRep.SUCCESS) - success = true; - else - if (Trace.traceOn_) Trace.log(Trace.ERROR, "Error renaming file: " + - "IFSReturnCodeRep return code", returnCode); - } - else - { - // Unknown data stream. - Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); - throw new - InternalErrorException(InternalErrorException.DATA_STREAM_UNKNOWN, - Integer.toHexString(ds.getReqRepID()),null); - } + // Issue a rename request. + IFSRenameReq req = new IFSRenameReq(oldName, newName, fd_.preferredServerCCSID_, false); + ds = (ClientAccessDataStream) fd_.server_.sendAndReceive(req); + } + catch(ConnectionDroppedException e) + { + Trace.log(Trace.ERROR, "Byte stream server connection lost."); + fd_.connectionDropped(e); + } + catch(InterruptedException e) + { + Trace.log(Trace.ERROR, "Interrupted"); + InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); + throwException.initCause(e); + throw throwException; + } - if (success) - { - fd_.path_ = otherFile.getAbsolutePath(); + int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; + // Verify the reply. + if (ds instanceof IFSReturnCodeRep) + { + returnCode = ((IFSReturnCodeRep) ds).getReturnCode(); + if (returnCode == IFSReturnCodeRep.SUCCESS) + success = true; + else if (Trace.traceOn_) + Trace.log(Trace.ERROR, "Error renaming file: IFSReturnCodeRep return code", returnCode); + } + else + { + Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); + throw new InternalErrorException(InternalErrorException.DATA_STREAM_UNKNOWN, Integer.toHexString(ds.getReqRepID()), null); + } - // Clear any cached attributes. - attributesReply_ = null; - } + if (success) + { + fd_.path_ = otherFile.getAbsolutePath(); - return returnCode; - } + // Clear any cached attributes. + attributesReply_ = null; + } + return returnCode; + } - /** - Sets the file's "data CCSID" tag. - **/ - public boolean setCCSID(int ccsid) - throws IOException, AS400SecurityException + + + @Override + public boolean setCCSID(int ccsid) throws IOException, AS400SecurityException { - // To change the file data CCSID, we need to get the file's current attributes (in an OA2 structure), reset the 'CCSID' field, and then send back the modified OA2 struct in a Change Attributes request. + // To change the file data CCSID, we need to get the file's current attributes (in an OA2 structure), reset the + // 'CCSID' field, and then send back the modified OA2 struct in a Change Attributes request. - fd_.connect(); - IFSListAttrsRep reply = fd_.listObjAttrs2(); // get current attributes (OA2 structure) - if (reply == null) { - if (fd_.errorRC_ != 0) { - throw new ExtendedIOException(fd_.path_, fd_.errorRC_); + fd_.connect(); + IFSListAttrsRep reply = fd_.listObjAttrs2(); // get current attributes (OA2 structure) + if (reply == null) + { + if (fd_.errorRC_ != 0) + throw new ExtendedIOException(fd_.path_, fd_.errorRC_); + else + throw new InternalErrorException(InternalErrorException.UNKNOWN); } - else throw new InternalErrorException(InternalErrorException.UNKNOWN); - } - - boolean success = false; - //IFSObjAttrs2 objAttrs = reply.getObjAttrs2(); // get the OA2* structure //@AA9D - //@AA9 Start - byte[] objAttrs2Null = new byte[reply.getObjAttrs2().getLength()]; - Arrays.fill(objAttrs2Null, (byte)0xFF); - IFSObjAttrs2 objAttrs = new IFSObjAttrs2(objAttrs2Null); - //@AA9 End - // Sanity-check the length: If it's an OA2a or OA2b, the length will be 144 bytes. If it's an OA2c, the length will be 160 bytes. - if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Length of returned OA2* structure (should be 144 or 160): " + objAttrs.length()); + boolean success = false; + byte[] objAttrs2Null = new byte[reply.getObjAttrs2().getLength()]; + Arrays.fill(objAttrs2Null, (byte) 0xFF); + IFSObjAttrs2 objAttrs = new IFSObjAttrs2(objAttrs2Null); - // Reset the "CCSID of the object" field in the OA2* structure. - objAttrs.setCCSID(ccsid, fd_.serverDatastreamLevel_); + // Sanity-check the length: If it's an OA2a or OA2b, the length will be 144 bytes. If it's an OA2c, the length + // will be 160 bytes. + if (Trace.traceOn_) + Trace.log(Trace.DIAGNOSTIC, "Length of returned OA2* structure (should be 144 or 160): " + objAttrs.length()); - // Issue a change attributes request. - ClientAccessDataStream ds = null; - try - { - // Convert the path name to the server CCSID. - byte[] pathname = fd_.converter_.stringToByteArray(fd_.path_); + // Reset the "CCSID of the object" field in the OA2* structure. + objAttrs.setCCSID(ccsid, fd_.serverDatastreamLevel_); - IFSChangeAttrsReq req = new IFSChangeAttrsReq(pathname, - fd_.preferredServerCCSID_, - objAttrs, - fd_.serverDatastreamLevel_); - ds = (ClientAccessDataStream) fd_.server_.sendAndReceive(req); - } - catch(ConnectionDroppedException e) - { - Trace.log(Trace.ERROR, "Byte stream server connection lost."); - fd_.connectionDropped(e); - } - catch(InterruptedException e) - { - Trace.log(Trace.ERROR, "Interrupted"); - InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); - throwException.initCause(e); - throw throwException; - } + // Issue a change attributes request. + ClientAccessDataStream ds = null; + try + { + // Convert the path name to the server CCSID. + byte[] pathname = fd_.converter_.stringToByteArray(fd_.path_); - if (ds instanceof IFSReturnCodeRep) - { - int rc = ((IFSReturnCodeRep) ds).getReturnCode(); - if (rc == IFSReturnCodeRep.SUCCESS) { - success = true; - fd_.setCCSID(ccsid); // update the cached CCSID value in the fd_ + IFSChangeAttrsReq req = new IFSChangeAttrsReq(pathname, fd_.preferredServerCCSID_, objAttrs, fd_.serverDatastreamLevel_); + ds = (ClientAccessDataStream) fd_.server_.sendAndReceive(req); } - else { - if (Trace.traceOn_) Trace.log(Trace.ERROR, "Error setting file data CCSID: " + - "IFSReturnCodeRep return code", rc); + catch (ConnectionDroppedException e) { + Trace.log(Trace.ERROR, "Byte stream server connection lost."); + fd_.connectionDropped(e); + } + catch (InterruptedException e) + { + Trace.log(Trace.ERROR, "Interrupted"); + InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); + throwException.initCause(e); + throw throwException; } - } - else - { - // Unknown data stream. - Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); - throw new - InternalErrorException(InternalErrorException.DATA_STREAM_UNKNOWN, - Integer.toHexString(ds.getReqRepID()),null); - } - - return success; - } - + if (ds instanceof IFSReturnCodeRep) + { + int rc = ((IFSReturnCodeRep) ds).getReturnCode(); + if (rc == IFSReturnCodeRep.SUCCESS) + { + success = true; + fd_.setCCSID(ccsid); // update the cached CCSID value in the fd_ + } + else if (Trace.traceOn_) + Trace.log(Trace.ERROR, "Error setting file data CCSID: IFSReturnCodeRep return code", rc); + } + else + { + Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); + throw new InternalErrorException(InternalErrorException.DATA_STREAM_UNKNOWN, Integer.toHexString(ds.getReqRepID()), null); + } - /** - Changes the fixed attributes (read only, hidden, etc.) of the integrated - file system object represented by this object to attributes. - - @param attributes The set of attributes to apply to the object. Note - these attributes are not ORed with the existing - attributes. They replace the existing fixed - attributes of the file. - @return true if successful; false otherwise. - **/ - // @D1 - new method because of changes to java.io.file in Java 2. + return success; + } - public boolean setFixedAttributes(int attributes) - throws IOException, AS400SecurityException + @Override + public boolean setFixedAttributes(int attributes) throws IOException, AS400SecurityException { - // Assume the argument has been validated by the public class. + // Assume the argument has been validated by the public class. - // Ensure that we are connected to the server. - fd_.connect(); + // Ensure that we are connected to the server. + fd_.connect(); - // Issue a change attributes request. - ClientAccessDataStream ds = null; - try - { - // Convert the path name to the server CCSID. - byte[] pathname = fd_.converter_.stringToByteArray(fd_.path_); + // Issue a change attributes request. + ClientAccessDataStream ds = null; + try + { + // Convert the path name to the server CCSID. + byte[] pathname = fd_.converter_.stringToByteArray(fd_.path_); - IFSChangeAttrsReq req = new IFSChangeAttrsReq(pathname, - fd_.preferredServerCCSID_, - attributes, - true, - fd_.serverDatastreamLevel_); - ds = (ClientAccessDataStream) fd_.server_.sendAndReceive(req); - } - catch(ConnectionDroppedException e) - { - Trace.log(Trace.ERROR, "Byte stream server connection lost."); - fd_.connectionDropped(e); - } - catch(InterruptedException e) - { - Trace.log(Trace.ERROR, "Interrupted"); - InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); - throwException.initCause(e); - throw throwException; - } + IFSChangeAttrsReq req = new IFSChangeAttrsReq(pathname, fd_.preferredServerCCSID_, attributes, true, + fd_.serverDatastreamLevel_); + ds = (ClientAccessDataStream) fd_.server_.sendAndReceive(req); + } + catch (ConnectionDroppedException e) { + Trace.log(Trace.ERROR, "Byte stream server connection lost."); + fd_.connectionDropped(e); + } + catch (InterruptedException e) { + Trace.log(Trace.ERROR, "Interrupted"); + InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); + throwException.initCause(e); + throw throwException; + } - // Verify the reply. - boolean success = false; - if (ds instanceof IFSReturnCodeRep) - { - int rc = ((IFSReturnCodeRep) ds).getReturnCode(); - if (rc == IFSReturnCodeRep.SUCCESS) - success = true; + // Verify the reply. + boolean success = false; + if (ds instanceof IFSReturnCodeRep) + { + int rc = ((IFSReturnCodeRep) ds).getReturnCode(); + if (rc == IFSReturnCodeRep.SUCCESS) + success = true; + else if (Trace.traceOn_) + Trace.log(Trace.ERROR, "Error setting file attributes: IFSReturnCodeRep return code", rc); + } else - if (Trace.traceOn_) Trace.log(Trace.ERROR, "Error setting file attributes: " + - "IFSReturnCodeRep return code", rc); - } - else - { - // Unknown data stream. - Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); - throw new - InternalErrorException(InternalErrorException.DATA_STREAM_UNKNOWN, - Integer.toHexString(ds.getReqRepID()),null); - } + { + Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); + throw new InternalErrorException(InternalErrorException.DATA_STREAM_UNKNOWN, Integer.toHexString(ds.getReqRepID()), null); + } - // Clear any cached attributes. - attributesReply_ = null; + // Clear any cached attributes. + attributesReply_ = null; - return success; + return success; } - - - /** - Alters the hidden attribute of the object. If attribute - is true, the bit is turned on. If attribute is turned off, - the bit is turned off. - - @param attribute The new state of the hidden attribute. The hidden - attribute is the second bit from the right. - - @return true if successful; false otherwise. - **/ - // @D1 - new method because of changes to java.io.file in Java 2. - - public boolean setHidden(boolean attribute) - throws IOException, AS400SecurityException + @Override + public boolean setHidden(boolean attribute) throws IOException, AS400SecurityException { - // Assume the argument has been validated by the public class. + // Assume the argument has been validated by the public class. - // Ensure that we are connected to the server. - fd_.connect(); - - boolean success = false; - - // Setting the fixed attributes of a file involves - // replacing the current set of attributes. The first - // set is to get the current set. - IFSListAttrsRep attributes = getAttributeSetFromServer(fd_.path_); + // Ensure that we are connected to the server. + fd_.connect(); - if (attributes != null) - { - // Now that we have the current set of attributes, figure - // out if the bit is currently on. - int currentFixedAttributes = attributes.getFixedAttributes(); - boolean currentHiddenBit = (currentFixedAttributes & 2) != 0; - - // If current does not match what the user wants we need to go - // to the server to fix it. - if (currentHiddenBit != attribute) - { - int newAttributes; - - // If the user wants hidden on set the bit else the - // user wants the bit off so clear it. - if (attribute) - newAttributes = currentFixedAttributes + 2; - else - newAttributes = currentFixedAttributes & 0x7ffffffd; + boolean success = false; - // Issue a change attributes request. - ClientAccessDataStream ds = null; - try - { - // Convert the path name to the server CCSID. - byte[] pathname = fd_.converter_.stringToByteArray(fd_.path_); - - IFSChangeAttrsReq req = new IFSChangeAttrsReq(pathname, - fd_.preferredServerCCSID_, - newAttributes, - true, - fd_.serverDatastreamLevel_); - ds = (ClientAccessDataStream) fd_.server_.sendAndReceive(req); - } - catch(ConnectionDroppedException e) - { - Trace.log(Trace.ERROR, "Byte stream server connection lost."); - fd_.connectionDropped(e); - } - catch(InterruptedException e) - { - Trace.log(Trace.ERROR, "Interrupted"); - InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); - throwException.initCause(e); - throw throwException; - } + // Setting the fixed attributes of a file involves + // replacing the current set of attributes. The first + // set is to get the current set. + IFSListAttrsRep attributes = getAttributeSetFromServer(fd_.path_); - if (ds instanceof IFSReturnCodeRep) - { - int rc = ((IFSReturnCodeRep) ds).getReturnCode(); - if (rc == IFSReturnCodeRep.SUCCESS) - success = true; - else - if (Trace.traceOn_) Trace.log(Trace.ERROR, "Error setting hidden attribute: " + - "IFSReturnCodeRep return code", rc); - } - else + if (attributes != null) + { + // Now that we have the current set of attributes, figure + // out if the bit is currently on. + int currentFixedAttributes = attributes.getFixedAttributes(); + boolean currentHiddenBit = (currentFixedAttributes & 2) != 0; + + // If current does not match what the user wants we need to go + // to the server to fix it. + if (currentHiddenBit != attribute) { - // Unknown data stream. - Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); - throw new - InternalErrorException(Integer.toHexString(ds.getReqRepID()), - InternalErrorException.DATA_STREAM_UNKNOWN); - } + int newAttributes; - // Clear any cached attributes. - attributesReply_ = null; + // If the user wants hidden on set the bit else the + // user wants the bit off so clear it. + if (attribute) + newAttributes = currentFixedAttributes + 2; + else + newAttributes = currentFixedAttributes & 0x7ffffffd; - } - else - success = true; - } - return success; + // Issue a change attributes request. + ClientAccessDataStream ds = null; + try + { + // Convert the path name to the server CCSID. + byte[] pathname = fd_.converter_.stringToByteArray(fd_.path_); + + IFSChangeAttrsReq req = new IFSChangeAttrsReq(pathname, fd_.preferredServerCCSID_, newAttributes, true, fd_.serverDatastreamLevel_); + ds = (ClientAccessDataStream) fd_.server_.sendAndReceive(req); + } + catch (ConnectionDroppedException e) { + Trace.log(Trace.ERROR, "Byte stream server connection lost."); + fd_.connectionDropped(e); + } + catch (InterruptedException e) { + Trace.log(Trace.ERROR, "Interrupted"); + InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); + throwException.initCause(e); + throw throwException; + } + + if (ds instanceof IFSReturnCodeRep) + { + int rc = ((IFSReturnCodeRep) ds).getReturnCode(); + if (rc == IFSReturnCodeRep.SUCCESS) + success = true; + else if (Trace.traceOn_) + Trace.log(Trace.ERROR, "Error setting hidden attribute: " + "IFSReturnCodeRep return code", rc); + } + else + { + Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); + throw new InternalErrorException(Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); + } + + // Clear any cached attributes. + attributesReply_ = null; + + } + else + success = true; + } + + return success; } - - // @B8c - /** - Changes the last modified time of the integrated file system object represented by this object to time. - @param time The desired last modification time (measured in milliseconds - since January 1, 1970 00:00:00 GMT), or -1 to set the last modification time to the current system time. - - @return true if successful; false otherwise. - **/ - - public boolean setLastModified(long time) - throws IOException, AS400SecurityException + @Override + public boolean setLastModified(long time) throws IOException, AS400SecurityException { - // Assume the argument has been validated by the public class. - - int fileHandle = UNINITIALIZED; - boolean success = false; + // Assume the argument has been validated by the public class. - // Ensure that we are connected to the server. - try - { - fd_.connect(); + int fileHandle = UNINITIALIZED; + boolean success = false; - if (time == -1) // @B8a + // Ensure that we are connected to the server. + try { - // We are setting modification time to "current system time". - // To do that, we will simply read and write-back the first byte in the file. - - // Open the file for read/write. - fileHandle = fd_.createFileHandle(IFSOpenReq.WRITE_ACCESS, IFSOpenReq.OPEN_OPTION_FAIL_OPEN); - if (fileHandle == UNINITIALIZED) return false; - else fd_.setOpen(true, fileHandle); // inform the descriptor of the file handle - - byte[] buffer = new byte[1]; // buffer for reading/writing a single byte - - // If we're setting timestamp to "current system time", we'll need to know how big the file is. - boolean fileIsEmpty = false; // @B8a - if (time == -1) fileIsEmpty = (length()==0 ? true : false); // @B8a + fd_.connect(); - if (fileIsEmpty) - { - // Update last-modification date by writing one byte (the value doesn't matter). - fd_.writeBytes(buffer, 0, 1, true); - - // Reset the file size to zero. - success = fd_.setLength(0); - } - else // the file is not empty - { - // Read the first byte. - if (1 == fd_.read(buffer, 0, 1)) + if (time == -1) { - // Write back the first byte. - fd_.setFileOffset(0); - fd_.writeBytes(buffer, 0, 1, true); - success = true; + // We are setting modification time to "current system time". + // To do that, we will simply read and write-back the first byte in the file. + + // Open the file for read/write. + fileHandle = fd_.createFileHandle(IFSOpenReq.WRITE_ACCESS, IFSOpenReq.OPEN_OPTION_FAIL_OPEN); + if (fileHandle == UNINITIALIZED) + return false; + else + fd_.setOpen(true, fileHandle); // inform the descriptor of the file handle + + byte[] buffer = new byte[1]; // buffer for reading/writing a single byte + + // If we're setting timestamp to "current system time", we'll need to know how big the file is. + boolean fileIsEmpty = false; // @B8a + if (time == -1) + fileIsEmpty = (length() == 0 ? true : false); // @B8a + + if (fileIsEmpty) + { + // Update last-modification date by writing one byte (the value doesn't matter). + fd_.writeBytes(buffer, 0, 1, true); + + // Reset the file size to zero. + success = fd_.setLength(0); + } + else // the file is not empty + { + // Read the first byte. + if (1 == fd_.read(buffer, 0, 1)) + { + // Write back the first byte. + fd_.setFileOffset(0); + fd_.writeBytes(buffer, 0, 1, true); + success = true; + } + else + { + if (Trace.traceOn_) Trace.log(Trace.ERROR, "Unable to read first byte of file."); + success = false; + } + } } - else + else // the caller specified a last-modified time { - if (Trace.traceOn_) Trace.log(Trace.ERROR, "Unable to read first byte of file."); - success = false; + // Issue a change attributes request. + ClientAccessDataStream ds = null; + try + { + // Convert the path name to the server CCSID. + byte[] pathname = fd_.converter_.stringToByteArray(fd_.path_); + + IFSChangeAttrsReq req = new IFSChangeAttrsReq(pathname, fd_.preferredServerCCSID_, 0, time, 0, fd_.serverDatastreamLevel_); + ds = (ClientAccessDataStream) fd_.server_.sendAndReceive(req); + } + catch (ConnectionDroppedException e) { + Trace.log(Trace.ERROR, "Byte stream server connection lost."); + fd_.connectionDropped(e); + } + catch (InterruptedException e) { + Trace.log(Trace.ERROR, "Interrupted"); + InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); + throwException.initCause(e); + throw throwException; + } + + // Verify the reply. + if (ds instanceof IFSReturnCodeRep) + { + int rc = ((IFSReturnCodeRep) ds).getReturnCode(); + if (rc == IFSReturnCodeRep.SUCCESS) + success = true; + else if (Trace.traceOn_) + Trace.log(Trace.ERROR, "Error setting last-modified date: IFSReturnCodeRep return code", rc); + } + else + { + Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); + throw new InternalErrorException(Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); + } } - } + + // Clear any cached attributes. + attributesReply_ = null; } - else // the caller specified a last-modified time + finally { - // Issue a change attributes request. - ClientAccessDataStream ds = null; - try - { - // Convert the path name to the server CCSID. - byte[] pathname = fd_.converter_.stringToByteArray(fd_.path_); - - IFSChangeAttrsReq req = new IFSChangeAttrsReq(pathname, - fd_.preferredServerCCSID_, - 0, time, 0, - fd_.serverDatastreamLevel_); - ds = (ClientAccessDataStream) fd_.server_.sendAndReceive(req); - } - catch(ConnectionDroppedException e) - { - Trace.log(Trace.ERROR, "Byte stream server connection lost."); - fd_.connectionDropped(e); - } - catch(InterruptedException e) - { - Trace.log(Trace.ERROR, "Interrupted"); - InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); - throwException.initCause(e); - throw throwException; - } - - // Verify the reply. - if (ds instanceof IFSReturnCodeRep) - { - int rc = ((IFSReturnCodeRep) ds).getReturnCode(); - if (rc == IFSReturnCodeRep.SUCCESS) - success = true; - else - if (Trace.traceOn_) Trace.log(Trace.ERROR, "Error setting last-modified date: " + - "IFSReturnCodeRep return code", rc); - } - else - { - // Unknown data stream. - Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); - throw new - InternalErrorException(Integer.toHexString(ds.getReqRepID()), - InternalErrorException.DATA_STREAM_UNKNOWN); - } + if (fileHandle != UNINITIALIZED) + fd_.close(fileHandle); } - // Clear any cached attributes. - attributesReply_ = null; - } - finally { - if (fileHandle != UNINITIALIZED) fd_.close(fileHandle); - } - - return success; + return success; } - // @B8a - /** - Sets the length of the integrated file system object represented by this object. The file can be made larger or smaller. If the file is made larger, the contents of the new bytes of the file are undetermined. - @param length The new length, in bytes. - @return true if successful; false otherwise. - **/ - public boolean setLength(int length) - throws IOException, AS400SecurityException + @Override + public boolean setLength(int length) throws IOException, AS400SecurityException { - // Assume the argument has been validated by the public class. + // Assume the argument has been validated by the public class. - // Ensure that we are connected to the server. - fd_.connect(); + // Ensure that we are connected to the server. + fd_.connect(); - // Clear any cached attributes. - attributesReply_ = null; + // Clear any cached attributes. + attributesReply_ = null; - return fd_.setLength(length); + return fd_.setLength(length); } - /** - Sets the file path. - @param path The absolute file path. - **/ + @Override public void setPath(String path) { - // Assume the argument has been validated by the public class. - - // Ensure that the path is not altered after the connection is - // established. - if (fd_.server_ != null) - { - throw new ExtendedIllegalStateException("path", - ExtendedIllegalStateException.PROPERTY_NOT_CHANGED); - } - - // If the specified path doesn't start with the separator character, - // add one. All paths are absolute for IFS. - String newPath; - if (path.length() == 0 || path.charAt(0) != IFSFile.separatorChar) - { - newPath = IFSFile.separator + path; - } - else - { - newPath = path; - } - - // Update the path value. - fd_.path_ = newPath; - } - + // Assume the argument has been validated by the public class. + + // Ensure that the path is not altered after the connection is + // established. + if (fd_.server_ != null) + throw new ExtendedIllegalStateException("path", ExtendedIllegalStateException.PROPERTY_NOT_CHANGED); + + // If the specified path doesn't start with the separator character, + // add one. All paths are absolute for IFS. + String newPath; + if (path.length() == 0 || path.charAt(0) != IFSFile.separatorChar) + newPath = IFSFile.separator + path; + else + newPath = path; - // Sets a ProgramParameter to "pass by reference". - private static final void setPassByReference(ProgramParameter parm) - { - try { parm.setParameterType(ProgramParameter.PASS_BY_REFERENCE); } - catch (PropertyVetoException pve) { Trace.log(Trace.ERROR, pve); } // should never happen + // Update the path value. + fd_.path_ = newPath; } - - /** - Sets the pattern-matching behavior used when files are listed by any of the list() or listFiles() methods. The default is PATTERN_POSIX. - @param patternMatching Either {@link IFSFile#PATTERN_POSIX PATTERN_POSIX}, {@link IFSFile#PATTERN_POSIX_ALL PATTERN_POSIX_ALL}, or {@link IFSFile#PATTERN_OS2 PATTERN_OS2} - **/ + @Override public void setPatternMatching(int patternMatching) { - fd_.patternMatching_ = patternMatching; + fd_.patternMatching_ = patternMatching; } - - /** - Alters the read only attribute of the object. If attribute - is true, the bit is turned on. If attribute is turned off, - the bit is turned off. - - @param attribute The new state of the read only attribute - - @return true if successful; false otherwise. - **/ - // @D1 - new method because of changes to java.io.file in Java 2. - - public boolean setReadOnly(boolean attribute) - throws IOException, AS400SecurityException + @Override + public boolean setReadOnly(boolean attribute) throws IOException, AS400SecurityException { - // Assume the argument has been validated by the public class. + // Assume the argument has been validated by the public class. - // Ensure that we are connected to the server. - fd_.connect(); + // Ensure that we are connected to the server. + fd_.connect(); - boolean success = false; - IFSListAttrsRep attributes = getAttributeSetFromServer(fd_.path_); + boolean success = false; + IFSListAttrsRep attributes = getAttributeSetFromServer(fd_.path_); - // Same as setHidden -- setting fixed attributes is a total replacement - // of the fixed attributes. So, we have to get the current set, fix up - // the readonly bit, then put them back. - if (attributes != null) - { - int currentFixedAttributes = attributes.getFixedAttributes(); - boolean currentReadOnlyBit = (currentFixedAttributes & 1) != 0; - - // If the bit is not currently set to what the user wants. - if (currentReadOnlyBit != attribute) - { - int newAttributes; - - // If the user wants readonly on, add to the current set. - // If the user wants it off, clear the bit. - if (attribute) - newAttributes = currentFixedAttributes + 1; - else - newAttributes = currentFixedAttributes & 0x7ffffffe; + // Same as setHidden -- setting fixed attributes is a total replacement + // of the fixed attributes. So, we have to get the current set, fix up + // the readonly bit, then put them back. + if (attributes != null) + { + int currentFixedAttributes = attributes.getFixedAttributes(); + boolean currentReadOnlyBit = (currentFixedAttributes & 1) != 0; - // Issue a change attributes request. - ClientAccessDataStream ds = null; - try - { - // Convert the path name to the server CCSID. - byte[] pathname = fd_.converter_.stringToByteArray(fd_.path_); - - IFSChangeAttrsReq req = new IFSChangeAttrsReq(pathname, - fd_.preferredServerCCSID_, - newAttributes, - true, - fd_.serverDatastreamLevel_); - ds = (ClientAccessDataStream) fd_.server_.sendAndReceive(req); - } - catch(ConnectionDroppedException e) - { - Trace.log(Trace.ERROR, "Byte stream server connection lost."); - fd_.connectionDropped(e); - } - catch(InterruptedException e) + // If the bit is not currently set to what the user wants. + if (currentReadOnlyBit != attribute) { - Trace.log(Trace.ERROR, "Interrupted"); - InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); - throwException.initCause(e); - throw throwException; - } + int newAttributes; - if (ds instanceof IFSReturnCodeRep) - { - int rc = ((IFSReturnCodeRep) ds).getReturnCode(); - if (rc == IFSReturnCodeRep.SUCCESS) - success = true; - else - if (Trace.traceOn_) Trace.log(Trace.ERROR, "Error setting read-only attribute: " + - "IFSReturnCodeRep return code", rc); + // If the user wants readonly on, add to the current set. + // If the user wants it off, clear the bit. + if (attribute) + newAttributes = currentFixedAttributes + 1; + else + newAttributes = currentFixedAttributes & 0x7ffffffe; + + // Issue a change attributes request. + ClientAccessDataStream ds = null; + try + { + // Convert the path name to the server CCSID. + byte[] pathname = fd_.converter_.stringToByteArray(fd_.path_); + + IFSChangeAttrsReq req = new IFSChangeAttrsReq(pathname, fd_.preferredServerCCSID_, + newAttributes, true, fd_.serverDatastreamLevel_); + ds = (ClientAccessDataStream) fd_.server_.sendAndReceive(req); + } + catch(ConnectionDroppedException e) + { + Trace.log(Trace.ERROR, "Byte stream server connection lost."); + fd_.connectionDropped(e); + } + catch(InterruptedException e) + { + Trace.log(Trace.ERROR, "Interrupted"); + InterruptedIOException throwException = new InterruptedIOException(e.getMessage()); + throwException.initCause(e); + throw throwException; + } + + if (ds instanceof IFSReturnCodeRep) + { + int rc = ((IFSReturnCodeRep) ds).getReturnCode(); + if (rc == IFSReturnCodeRep.SUCCESS) + success = true; + else if (Trace.traceOn_) + Trace.log(Trace.ERROR, "Error setting read-only attribute: IFSReturnCodeRep return code", rc); + } + else + { + Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); + throw new InternalErrorException(Integer.toHexString(ds.getReqRepID()), InternalErrorException.DATA_STREAM_UNKNOWN); + } + + // Clear any cached attributes. + attributesReply_ = null; } else - { - // Unknown data stream. - Trace.log(Trace.ERROR, "Unknown reply data stream", ds.data_); - throw new - InternalErrorException(Integer.toHexString(ds.getReqRepID()), - InternalErrorException.DATA_STREAM_UNKNOWN); - } - - // Clear any cached attributes. - attributesReply_ = null; - } - else - success = true; - } - return success; + success = true; + } + + return success; } - - /** - Sets the sorting behavior used when files are listed by any of the list() or listFiles() methods. The default is false (unsorted). - @param sort If true: Return lists of files in sorted order. - If false: Return lists of files in whatever order the file system provides. - **/ + @Override public void setSorted(boolean sort) { - sortLists_ = sort; + sortLists_ = sort; } - - /** - Sets the system. - @param system The server object. - **/ + @Override public void setSystem(AS400Impl system) { // Assume the argument has been validated by the public class. @@ -2909,31 +2438,266 @@ public void setSystem(AS400Impl system) fd_.system_ = (AS400ImplRemote)system; } - - // Setup remote service program object on first touch. Synchronized to protect instance variables. This method can safely be called multiple times because it checks for a previous call before changing the instance variables. + // Setup remote service program object on first touch. Synchronized to protect instance variables. + // This method can safely be called multiple times because it checks for a previous call before changing the instance variables. protected synchronized void setupRemoteCommand() throws IOException { - // If not already setup. - if (rmtCmd_ == null) - { + if (rmtCmd_ != null) + return; + if (fd_.system_.canUseNativeOptimizations()) { - try - { - rmtCmd_ = (RemoteCommandImpl)Class.forName("com.ibm.as400.access.RemoteCommandImplNative").newInstance(); - // Avoid direct reference - it can cause NoClassDefFoundError at class loading time on Sun JVM's. - } - catch (Throwable e) { - // A ClassNotFoundException would be unexpected, since canUseNativeOptions() returned true. - Trace.log(Trace.WARNING, "Unable to instantiate class RemoteCommandImplNative.", e); - } + try { + // Avoid direct reference - it can cause NoClassDefFoundError at class loading time on Sun JVM's. + rmtCmd_ = (RemoteCommandImpl) Class.forName("com.ibm.as400.access.RemoteCommandImplNative").newInstance(); + } + catch (Throwable e) { + Trace.log(Trace.WARNING, "Unable to instantiate class RemoteCommandImplNative.", e); + } } + + // Use remote implementation if not set. if (rmtCmd_ == null) + rmtCmd_ = new RemoteCommandImplRemote(); + + rmtCmd_.setSystem(fd_.system_); + } + + @Override + public String getDescription() throws IOException, AS400SecurityException + { + // We must use doQp0lGetAttr to get the description in order to get + // the description in CCSID of the job for QSYS.LIB objects, and not + // in the CCSID of the file server. That is how QSYS.LIB object + // gives back the description. So if you have NLS characters in + // the description, it will be converted to the file server job, which + // is not what we want. + String descr = (String)doQp0lGetAttr(QP0L_ATTR_TEXT); + + return (descr != null) ? descr : ""; + } + + /* + * INTERNAL USE ONLY + * Checks to see if names in path contain forward slash, which is problematic when + * interacting with file server. Quoted names for QSYS.LIB objects can have a forward slash. + */ + static boolean isPathProblematic(QSYSObjectPathName p) + { + return ( p.getLibraryName().indexOf('/') != -1 + || p.getObjectName().indexOf('/') != -1 + || p.getMemberName().indexOf('/') != -1); + } + + static String trimRight(String s) + { + if (s == null || s.length() == 0) + return ""; + + int endIndex = 0; + int len = s.length(); + for (endIndex=len -1; endIndex > -1; endIndex--) { - rmtCmd_ = new RemoteCommandImplRemote(); + char c = s.charAt(endIndex); + if (c != ' ') + break; } - rmtCmd_.setSystem(fd_.system_); - } + return s.substring(0, endIndex +1); } + + /* + * IFS has problems with getting description which is DBCS from QSYS objects. + */ + + private static final byte ebcdicDelim = 97; + private static final byte nullDelim = 0; + private static final byte[] hexZeros = new byte[50]; + private static final AS400Bin4 intConverter = new AS400Bin4(); + private static final AS400UnsignedBin4 uintConverter = new AS400UnsignedBin4(); + private static final AS400Bin8 longConverter = new AS400Bin8(); + + private static final int QP0L_ATTR_ASP = 13; + private static final int QP0L_ATTR_DATA_SIZE_64 = 14; + private static final int QP0L_ATTR_CCSID = 27; + private static final int QP0L_ATTR_TEXT = 48; + + private Object doQp0lGetAttr(int attr) throws IOException, AS400SecurityException + { + // Create the pgm call object + if (rmtCmd_ == null) + setupRemoteCommand(); + + Object result = null; + try + { + ByteArrayOutputStream bo = new ByteArrayOutputStream(); + + ConvTable conv = ConvTable.getTable(fd_.system_.getCcsid(), null); + + ProgramParameter[] parms = new ProgramParameter[7]; + + // ======= + // PARAMETER #1 ===== Path name format + + // QSYS.LIB paths may contain quoted object names that has '/' character in the name, + // such as '/qsys.lib/"new/lib".lib'. When using IFS APIs, we need to replace delimiter + // with something else, which in this case is hex 00. + byte[] pathBytes = null; + byte delim = nullDelim; + // + // if (sysObject.isQSYSObject() && isPathProblematic(sysObject.getQSYSPath())) + // { + // QSYSObjectPathName qsysPath = sysObject.getQSYSPath(); + // + // String asp = qsysPath.getAspName(); + // String lib = qsysPath.getLibraryName(); + // String obj = qsysPath.getObjectName(); + // String mbr = qsysPath.getMemberName(); + // + // // Use hex 00 as delimiter + // if (!asp.isEmpty()) + // { + // bo.write(delim); + // if (asp.charAt(0) == '/') + // bo.write(conv.stringToByteArray(asp.substring(1))); + // else + // bo.write(conv.stringToByteArray(asp)); + // } + // + // if (!lib.isEmpty()) + // { + // bo.write(delim); + // bo.write(conv.stringToByteArray(lib + ".LIB")); + // } + // + // if (!obj.isEmpty()) + // { + // bo.write(delim); + // bo.write(conv.stringToByteArray(obj + "." + qsysPath.getObjectType())); + // } + // + // if (!mbr.isEmpty()) + // { + // bo.write(delim); + // bo.write(conv.stringToByteArray(mbr + ".MBR")); + // } + // + // pathBytes = bo.toByteArray(); + // } + // else + { + delim = ebcdicDelim; + pathBytes = conv.stringToByteArray(fd_.path_); + } + + bo.reset(); + + bo.write(hexZeros, 0, 16); + bo.write(BinaryConverter.intToByteArray((int)pathBytes.length)); // length of path + bo.write(delim); // path delimiter character + bo.write(hexZeros, 0, 11); + bo.write(pathBytes); // path + + parms[0] = new ProgramParameter(ProgramParameter.PASS_BY_REFERENCE, bo.toByteArray()); + + // ======= + // PARAMETER #2 ===== attribute array + int numAttrs = 1; + bo.reset(); + bo.write(BinaryConverter.intToByteArray(numAttrs)); // Number of attributes to return + bo.write(BinaryConverter.intToByteArray(attr)); + + parms[1] = new ProgramParameter(ProgramParameter.PASS_BY_REFERENCE, bo.toByteArray()); + + // ======= + // PARAMETER #3 ===== output buffer + parms[2] = new ProgramParameter(ProgramParameter.PASS_BY_REFERENCE, 200); + + // ======= + // PARAMETER #4 ===== output buffer size + parms[3] = new ProgramParameter(ProgramParameter.PASS_BY_VALUE, BinaryConverter.intToByteArray((int)200)); + + // ======= + // PARAMETER #5 ===== output buffer size needed + parms[4] = new ProgramParameter(ProgramParameter.PASS_BY_REFERENCE, 4); + + // ======= + // PARAMETER #6 ===== number of bytes returned + parms[5] = new ProgramParameter(ProgramParameter.PASS_BY_REFERENCE, 4); + + // ======= + // PARAMETER #7 ===== follow symbolic link + parms[6] = new ProgramParameter(ProgramParameter.PASS_BY_VALUE, BinaryConverter.intToByteArray((int)1)); + + // Call the service program. + byte[] returnedBytes = rmtCmd_.runServiceProgram("QSYS", "QP0LLIB2", "Qp0lGetAttr", parms); + if (returnedBytes == null) + { + Trace.log(Trace.ERROR, "Call to Qp0lGetAttr() returned null."); + throw new AS400Exception(rmtCmd_.getMessageList()); + } + + int returnValue = BinaryConverter.byteArrayToInt(returnedBytes, 0); + if (returnValue != 0) + { + int errno = BinaryConverter.byteArrayToInt(returnedBytes, 4); + Trace.log(Trace.ERROR, "Qp0lGetAttr errno=: " + errno); + return null; + } + + /** + * Output buffer format + * 0 0 BINARY(4) Offset to next attribute entry + * 4 4 BINARY(4) Attribute identification + * 8 8 BINARY(4) Size of attribute data + * 12 C CHAR(4) Reserved + * 16 10 CHAR(*) Attribute data + */ + + byte[] outBuf = parms[2].getOutputData(); + + int offset=0; + long nextOffset=-1; + while (nextOffset != 0) + { + nextOffset = uintConverter.toLong(outBuf, offset+0); + long attrID = uintConverter.toLong(outBuf, offset+4); + long attrDataSize = uintConverter.toLong(outBuf, offset+8); + + if (attrDataSize > 0) + { + if (attrID == QP0L_ATTR_DATA_SIZE_64) + result = longConverter.toObject(outBuf, offset+16); // long long + else if (attrID == QP0L_ATTR_CCSID) + result = intConverter.toObject(outBuf, offset+16); + else if (attrID == QP0L_ATTR_ASP) + result = intConverter.toObject(outBuf, offset+16); + else if (attrID == QP0L_ATTR_TEXT) + { + String description = conv.byteArrayToString(outBuf, offset+16, (int)attrDataSize); // max of 50 + + // Cobol sets text field to hex zeros....sigh + description = description.replace('\0', ' '); + description = trimRight(description); + + result = description; + } + } + + if (result != null) + break; + + offset = (int)nextOffset; + } + } + catch (IOException | AS400SecurityException e) { + throw e; + } + catch (Exception e) { + if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "Qp0lGetAttr exception ", e); + } + + return result; + } } diff --git a/src/main/java/com/ibm/as400/access/IFSJavaFile.java b/src/main/java/com/ibm/as400/access/IFSJavaFile.java index 51582d26..4b51e7a1 100644 --- a/src/main/java/com/ibm/as400/access/IFSJavaFile.java +++ b/src/main/java/com/ibm/as400/access/IFSJavaFile.java @@ -137,336 +137,331 @@ public class IFSJavaFile extends java.io.File implements java.io.Serializable { static final long serialVersionUID = 4L; - private IFSFile ifsFile_ = new IFSFile(); - private static final char AS400_SEPARATOR = '/'; - private static final String URL_PROTOCOL = "file"; - - private static final boolean replace_ = (AS400_SEPARATOR != separatorChar); //@P2A - -// Because pathSeparator, pathSeparatorChar, separator and separatorChar are declared final in java.io.File, we cannot override them. - - private boolean absolute_; - -/** - * Creates a default IFSJavaFile instance. -**/ - public IFSJavaFile() - { - this(separator); // Default to the root directory. @A2C - absolute_ = false; // No path, so it can't be absolute. - } - -/** - * Creates a new IFSJavaFile instance whose path name is given by path. - * - * @param path The file path name where the IFSJavaFile is or will be stored. -**/ - private IFSJavaFile(String path) - { - super(path); - - try - { - ifsFile_.setPath(replace_ ? path.replace(separatorChar, AS400_SEPARATOR) : path); //@P2C - absolute_ = isAbsolutePath(path); - } - catch (PropertyVetoException e) {} // will never happen - } - - -/** - * Creates a new IFSJavaFile instance from a parent pathname string and a child pathname string. - * - * @param path The file path name where the IFSJavaFile is or will be stored. - * @param name The name of the IFSJavaFile object. -**/ - private IFSJavaFile(String path, String name) - { - super(path, name); - - try - { - String canon = canonicalizeDirectory(path) + name; //@P2A - ifsFile_.setPath(replace_ ? canon.replace(separatorChar, AS400_SEPARATOR) : canon); //@P2C - absolute_ = isAbsolutePath(canon); - } - catch (PropertyVetoException e) {} // will never happen - } - -/** - * Creates a new IFSJavaFile instance for the specified system, using a file pathname string. - * - * @param system The system that contains the IFSJavaFile. - * @param path The file path name where the IFSJavaFile is or will be stored. -**/ - public IFSJavaFile(AS400 system, String path) - { - this(path); - if (system == null) - throw new NullPointerException("system"); - - setSystem(system); - absolute_ = isAbsolutePath(path); - } - -/** - * Creates a new IFSJavaFile instance for the specified system, from a parent pathname string and a child pathname string. - * - * @param system The system that contains the IFSJavaFile. - * @param path The file path name where the IFSJavaFile is or will be stored. - * @param name The name of the IFSJavaFile object. -**/ - public IFSJavaFile(AS400 system, String path, String name) - { - this(path, name); - if (system == null) - throw new NullPointerException("system"); - - setSystem(system); - absolute_ = isAbsolutePath(path); - } - -/** - * Creates a new IFSJavaFile instance from a parent abstract pathname and a child pathname string. - *

- * The directory argument cannot be null. The constructed - * IFSJavaFile instance uses the following settings taken from - * directory: - *

    - *
  • system - *
  • path - *
- * The resulting file name is taken from the path name of directory, - * followed by the separator character, followed by name. - * - * @param directory The directory where the IFSJavaFile is or will be stored. - * @param name The name of the IFSJavaFile object. -**/ - public IFSJavaFile(IFSJavaFile directory, String name) - { - this(); - - if (directory == null) - throw new NullPointerException("directory"); - - if (name == null) - throw new NullPointerException("name"); - - String directoryPath = directory.getPath(); - try - { - String canon = canonicalizeDirectory(directoryPath) + name; //@P2A - ifsFile_.setPath(replace_ ? canon.replace(separatorChar, AS400_SEPARATOR) : canon); //@P2C - } - catch (PropertyVetoException e) {} // will never happen - - AS400 localSystem = directory.getSystem(); - if (localSystem != null) - { - setSystem(localSystem); - } - absolute_ = directory.isAbsolute(); - } - -/** - * Creates a new IFSJavaFile instance for the specified system, from a parent abstract pathname and a child pathname string. - * - * @param system The system that contains the IFSJavaFile. - * @param directory The directory where the IFSJavaFile is or will be stored. - * @param name The name of the IFSJavaFile object. -**/ - public IFSJavaFile(AS400 system, IFSJavaFile directory, String name) - { - this(directory, name); - if (system == null) - throw new NullPointerException("system"); - - setSystem(system); - absolute_ = directory.isAbsolute(); - } - - -/** - * Creates a new IFSJavaFile instance from an IFSFile object. - * - * @param file An IFSFile object. -**/ - public IFSJavaFile(IFSFile file) - { - super(file.getPath(), file.getName()); - ifsFile_ = file; - absolute_ = true; // all IFSFile objects have absolute paths - } - - /* if the directory doesn't end in a file separator, add one */ - private String canonicalizeDirectory(String directory) - { - // Assume the argument has been validated as non-null. //@A1C - int separatorIndex = directory.length() - separator.length(); - if (!directory.substring(separatorIndex).equals(separator)) - { - directory += separator; - } - return directory; - } - - - /** - Tests whether the application can execute the file denoted by this abstract pathname. - This method is supported for IBM i V5R1 and higher. For older releases, it simply returns false. - If the user profile has *ALLOBJ special authority (and system is V5R1 or higher), this method always returns true. - - @return true if and only if the abstract pathname exists and the application is allowed to execute the file. - For consistency with the behavior of java.io.File on IBM i JVM's: If a security error occurs simply because the user profile isn't allowed to access the file, the error is traced and false is returned. - @exception SecurityException If an unanticipated security error occurs. - **/ - public boolean canExecute() - throws SecurityException - { - try - { - return ifsFile_.canExecute(); - } - catch (IOException e) - { - Trace.log(Trace.ERROR, e); - throw new SecurityException(e); + private IFSFile ifsFile_ = new IFSFile(); + private static final char AS400_SEPARATOR = '/'; + private static final String URL_PROTOCOL = "file"; + + private static final boolean replace_ = (AS400_SEPARATOR != separatorChar); //@P2A + + // Because pathSeparator, pathSeparatorChar, separator and separatorChar are declared final in java.io.File, we cannot override them. + + private boolean absolute_; + + /** + * Creates a default IFSJavaFile instance. + **/ + public IFSJavaFile() + { + this(separator); // Default to the root directory. + absolute_ = false; // No path, so it can't be absolute. + } + + /** + * Creates a new IFSJavaFile instance whose path name is given by path. + * + * @param path The file path name where the IFSJavaFile is or will be stored. + **/ + private IFSJavaFile(String path) + { + super(path); + + try { + ifsFile_.setPath(replace_ ? path.replace(separatorChar, AS400_SEPARATOR) : path); + absolute_ = isAbsolutePath(path); + } + catch (PropertyVetoException e) { + } // will never happen + } + + /** + * Creates a new IFSJavaFile instance from a parent pathname string and a child pathname string. + * + * @param path The file path name where the IFSJavaFile is or will be stored. + * @param name The name of the IFSJavaFile object. + **/ + private IFSJavaFile(String path, String name) + { + super(path, name); + + try + { + String canon = canonicalizeDirectory(path) + name; + ifsFile_.setPath(replace_ ? canon.replace(separatorChar, AS400_SEPARATOR) : canon); + absolute_ = isAbsolutePath(canon); + } + catch (PropertyVetoException e) { + } // will never happen + } + + /** + * Creates a new IFSJavaFile instance for the specified system, using a file pathname string. + * + * @param system The system that contains the IFSJavaFile. + * @param path The file path name where the IFSJavaFile is or will be stored. + **/ + public IFSJavaFile(AS400 system, String path) + { + this(path); + if (system == null) + throw new NullPointerException("system"); + + setSystem(system); + absolute_ = isAbsolutePath(path); } - } - - -/** - * Indicates if the program can read from the file denoted by this abstract pathname. - * - * @return true if and only if the abstract pathname exists and the application is allowed to read the file. - * For consistency with the behavior of java.io.File on IBM i JVM's: If a security error occurs simply because the user profile isn't allowed to access the file, the error is traced and false is returned. - * @exception SecurityException If an unanticipated security error occurs. -**/ - public boolean canRead() - throws SecurityException - { - try - { - return ifsFile_.canRead(); - } - catch (IOException e) - { - Trace.log(Trace.ERROR, e); - throw new SecurityException(e); - } - } - -/** - * Indicates if the program can write to the file denoted by this abstract pathname. - * - * @return true if and only if the abstract pathname exists and the application is allowed to write the file. - * For consistency with the behavior of java.io.File on IBM i JVM's: If a security error occurs simply because the user profile isn't allowed to access the file, the error is traced and false is returned. - * @exception SecurityException If an unanticipated security error occurs. -**/ - public boolean canWrite() - throws SecurityException - { - try - { - return ifsFile_.canWrite(); - } - catch (IOException e) - { - Trace.log(Trace.ERROR, e); - throw new SecurityException(e); + + /** + * Creates a new IFSJavaFile instance for the specified system, from a parent pathname string and a child pathname + * string. + * + * @param system The system that contains the IFSJavaFile. + * @param path The file path name where the IFSJavaFile is or will be stored. + * @param name The name of the IFSJavaFile object. + **/ + public IFSJavaFile(AS400 system, String path, String name) + { + this(path, name); + if (system == null) + throw new NullPointerException("system"); + + setSystem(system); + absolute_ = isAbsolutePath(path); + } + + /** + * Creates a new IFSJavaFile instance from a parent abstract pathname and a child pathname string. + *

+ * The directory argument cannot be null. The constructed IFSJavaFile instance uses the following settings taken + * from directory:

    + *
  • system + *
  • path + *
+ * The resulting file name is taken from the path name of directory, followed by the separator character, + * followed by name. + * + * @param directory The directory where the IFSJavaFile is or will be stored. + * @param name The name of the IFSJavaFile object. + **/ + public IFSJavaFile(IFSJavaFile directory, String name) + { + this(); + + if (directory == null) + throw new NullPointerException("directory"); + + if (name == null) + throw new NullPointerException("name"); + + String directoryPath = directory.getPath(); + try + { + String canon = canonicalizeDirectory(directoryPath) + name; // @P2A + ifsFile_.setPath(replace_ ? canon.replace(separatorChar, AS400_SEPARATOR) : canon); // @P2C + } + catch (PropertyVetoException e) { + } // will never happen + + AS400 localSystem = directory.getSystem(); + if (localSystem != null) + setSystem(localSystem); + + absolute_ = directory.isAbsolute(); + } + + /** + * Creates a new IFSJavaFile instance for the specified system, from a parent abstract pathname and a child pathname + * string. + * + * @param system The system that contains the IFSJavaFile. + * @param directory The directory where the IFSJavaFile is or will be stored. + * @param name The name of the IFSJavaFile object. + **/ + public IFSJavaFile(AS400 system, IFSJavaFile directory, String name) + { + this(directory, name); + if (system == null) + throw new NullPointerException("system"); + + setSystem(system); + absolute_ = directory.isAbsolute(); + } + + /** + * Creates a new IFSJavaFile instance from an IFSFile object. + * + * @param file An IFSFile object. + **/ + public IFSJavaFile(IFSFile file) + { + super(file.getPath(), file.getName()); + ifsFile_ = file; + absolute_ = true; // all IFSFile objects have absolute paths + } + + /* if the directory doesn't end in a file separator, add one */ + private String canonicalizeDirectory(String directory) + { + // Assume the argument has been validated as non-null. //@A1C + int separatorIndex = directory.length() - separator.length(); + if (!directory.substring(separatorIndex).equals(separator)) + directory += separator; + + return directory; + } + + /** + * Tests whether the application can execute the file denoted by this abstract pathname. This method is supported + * for IBM i V5R1 and higher. For older releases, it simply returns false. If the user profile has *ALLOBJ special + * authority (and system is V5R1 or higher), this method always returns true. + * + * @return true if and only if the abstract pathname exists and the application is allowed to execute the file. For + * consistency with the behavior of java.io.File on IBM i JVM's: If a security error occurs simply because + * the user profile isn't allowed to access the file, the error is traced and false is returned. + * @exception SecurityException If an unanticipated security error occurs. + **/ + @Override + public boolean canExecute() throws SecurityException + { + try { + return ifsFile_.canExecute(); + } + catch (IOException e) { + Trace.log(Trace.ERROR, e); + throw new SecurityException(e); + } + } + + /** + * Indicates if the program can read from the file denoted by this abstract pathname. + * + * @return true if and only if the abstract pathname exists and the application is allowed to read the file. For + * consistency with the behavior of java.io.File on IBM i JVM's: If a security error occurs simply because + * the user profile isn't allowed to access the file, the error is traced and false is returned. + * @exception SecurityException If an unanticipated security error occurs. + **/ + @Override + public boolean canRead() throws SecurityException + { + try { + return ifsFile_.canRead(); + } + catch (IOException e) { + Trace.log(Trace.ERROR, e); + throw new SecurityException(e); + } + } + + /** + * Indicates if the program can write to the file denoted by this abstract pathname. + * + * @return true if and only if the abstract pathname exists and the application is allowed to write the file. For + * consistency with the behavior of java.io.File on IBM i JVM's: If a security error occurs simply because + * the user profile isn't allowed to access the file, the error is traced and false is returned. + * @exception SecurityException If an unanticipated security error occurs. + **/ + @Override + public boolean canWrite() throws SecurityException + { + try { + return ifsFile_.canWrite(); + } + catch (IOException e) { + Trace.log(Trace.ERROR, e); + throw new SecurityException(e); + } + } + + /** + * Compares the paths of two IFSJavaFiles. + *

+ * The following examples demonstrate the use of this method: + * + *

+ * In this example, returnCode would be less than 0 because the path of file is less than + * the path of file2. + * + *

+     *  IFSJavaFile file  = new IFSJavaFile(new AS400("enterprise"), path);
+     *  IFSJavaFile file2 = new IFSJavaFile(new AS400("enterprise"), path + "\\extra");
+     * 
+ * int returnCode = file.compareTo(file2); + *
+ * + *

+ * In this example, returnCode would be greater than 0 because the path of file is greater + * than the path of file2. + * + *

+     *  IFSJavaFile file  = new IFSJavaFile(new AS400("enterprise"), path + "\\extra");
+     *  IFSJavaFile file2 = new IFSJavaFile(new AS400("enterprise"), path);
+     * 
+ * int returnCode = file.compareTo(file2); + *
+ * + *

+ * In this example, returnCode would be less than 0 because the path of file is less than + * the path of file2. + * + *

+     *  IFSJavaFile file  = new IFSJavaFile(new AS400("enterprise"), "\\QSYS.LIB\\herlib");
+     *  IFSJavaFile file2 = new IFSJavaFile(new AS400("enterprise"), "\\QSYS.LIB\\hislib");
+     * 
+ * int returnCode = file.compareTo(file2); + *
+ * + *

+ * Note:
+ * The comparison is case sensitive. + * + * @param file The IFSJavaFile to be compared. + * + * @return 0 if this IFSJavaFile path equals file's path; a value less than 0 + * if this IFSJavaFile path is less than the file's path; and a value greater than + * 0 if this IFSJavaFile path is greater than the file's path. + * + * @since JDK1.2 + **/ + public int compareTo(IFSJavaFile file) { + return getPath().compareTo(file.getPath()); + } + + /** + * Compares the path of IFSJavaFile with a File's path. + * + *

+ * Note:
+ * The comparison is case sensitive. + * + * @param file The File to be compared. + * + * @return 0 if this IFSJavaFile path equals the argument's path; a value less than 0 if + * this IFSJavaFile path is less than the argument's path; and a value greater than 0 if this + * IFSJavaFile path is greater than the argument's path. + * + * @since JDK1.2 + **/ + @Override + public int compareTo(File file) { + return getPath().compareTo(file.getPath()); + } + + /** + * Compares the path of IFSJavaFile with a IFSFile's path. + * + *

+ * Note:
+ * The comparison is case sensitive. + * + * @param file The IFSFile to be compared. + * + * @return 0 if this IFSJavaFile path equals the argument's path; a value less than 0 if + * this IFSJavaFile path is less than the argument's path; and a value greater than 0 if this + * IFSJavaFile path is greater than the argument's path. + * + * @since JDK1.2 + **/ + public int compareTo(IFSFile file) { + return getPath().compareTo(file.getPath()); } - } - -/** - * Compares the paths of two IFSJavaFiles. - *

- * The following examples demonstrate the use of this method: - * - *

- * In this example, returnCode would be less than 0 because the - * path of file is less than the path of file2. - *

- *  IFSJavaFile file  = new IFSJavaFile(new AS400("enterprise"), path);
- *  IFSJavaFile file2 = new IFSJavaFile(new AS400("enterprise"), path + "\\extra");
- * 
- * int returnCode = file.compareTo(file2); - *
- * - *

- * In this example, returnCode would be greater than 0 because the - * path of file is greater than the path of file2. - *

- *  IFSJavaFile file  = new IFSJavaFile(new AS400("enterprise"), path + "\\extra");
- *  IFSJavaFile file2 = new IFSJavaFile(new AS400("enterprise"), path);
- * 
- * int returnCode = file.compareTo(file2); - *
- * - *

- * In this example, returnCode would be less than 0 because the - * path of file is less than the path of file2. - *

- *  IFSJavaFile file  = new IFSJavaFile(new AS400("enterprise"), "\\QSYS.LIB\\herlib");
- *  IFSJavaFile file2 = new IFSJavaFile(new AS400("enterprise"), "\\QSYS.LIB\\hislib");
- * 
- * int returnCode = file.compareTo(file2); - *
- * - *

Note:
The comparison is case sensitive. - * - * @param file The IFSJavaFile to be compared. - * - * @return 0 if this IFSJavaFile path equals file's path; - * a value less than 0 if this IFSJavaFile path is less than the file's - * path; and a value greater than 0 if this IFSJavaFile path is greater - * than the file's path. - * - * @since JDK1.2 -**/ - public int compareTo(IFSJavaFile file) - { - return getPath().compareTo(file.getPath()); - } - -// @A7a -/** - * Compares the path of IFSJavaFile with a File's path. - * - *

Note:
The comparison is case sensitive. - * - * @param file The File to be compared. - * - * @return 0 if this IFSJavaFile path equals the argument's path; - * a value less than 0 if this IFSJavaFile path is less than the argument's - * path; and a value greater than 0 if this IFSJavaFile path is greater - * than the argument's path. - * - * @since JDK1.2 -**/ - public int compareTo(File file) - { - return getPath().compareTo(file.getPath()); - } - -// @A8a -/** - * Compares the path of IFSJavaFile with a IFSFile's path. - * - *

Note:
The comparison is case sensitive. - * - * @param file The IFSFile to be compared. - * - * @return 0 if this IFSJavaFile path equals the argument's path; - * a value less than 0 if this IFSJavaFile path is less than the argument's - * path; and a value greater than 0 if this IFSJavaFile path is greater - * than the argument's path. - * - * @since JDK1.2 -**/ - public int compareTo(IFSFile file) - { - return getPath().compareTo(file.getPath()); - } // Note: The JDK 6.0 compiler doesn't like the following method signature. @@ -497,1663 +492,1458 @@ public int compareTo(IFSFile file) // } // } - - /** - * Atomically create a new, empty file. The file is - * created if and only if the file does not yet exist. The - * check for existence and the file creation is a - * single atomic operation. - * @return true if the file is created, false otherwise. - * @exception IOException If an I/O error occurs while communicating with the IBM i system. - **/ - public boolean createNewFile() - throws IOException - { - return ifsFile_.createNewFile(); - } - - - - -/** - * Deletes the IFSJavaFile. If the target is - * a directory, it must be empty for deletion to succeed. - * - * @return true if the file is successfully deleted; - * false otherwise. - * @exception SecurityException If the user is denied access to the file. -**/ - public boolean delete() - throws SecurityException - { - try - { - int returnCode = ifsFile_.delete0(); - if ((returnCode == IFSReturnCodeRep.ACCESS_DENIED_TO_DIR_ENTRY) - || (returnCode == IFSReturnCodeRep.ACCESS_DENIED_TO_REQUEST)) - { - throw new SecurityException(ResourceBundleLoader.getText(mapRC(returnCode))); - } - return (returnCode == IFSReturnCodeRep.SUCCESS); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, e); - throw new SecurityException(e); - } - catch (IOException e) - { - if (Trace.traceOn_) Trace.log(Trace.ERROR, e); - return false; - } - } - -/** - * Compares this IFSJavaFile against the specified object. - * Returns true if and only if the argument is - * not null and is an IFSJavaFile - * object whose path name is equal to the path name of - * this IFSJavaFile, - * and system names of the objects are equal. - * - * @param obj The object to compare with. - * - * @return true if the objects are the same; - * false otherwise. -**/ - public boolean equals(Object obj) - { - if (obj == null || !(obj instanceof IFSJavaFile)) - return false; - - // return getPath().equals(((IFSJavaFile)obj).getPath()); // @A4D - - // @A4A: - IFSFile otherIfsFile = ((IFSJavaFile)obj).getIfsFile(); - return (ifsFile_.equals(otherIfsFile)); - } - -/** - * Indicates if the IFSJavaFile exists. - * - * @return true if the file specified by this object - * exists; false otherwise. - * @exception SecurityException If the user is denied read access to the file. - * @exception SecurityException If the user is denied access to the file. -**/ - public boolean exists() - throws SecurityException - { - int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; - try - { - returnCode = ifsFile_.exists0(); //@A5c - if (returnCode == IFSReturnCodeRep.ACCESS_DENIED_TO_DIR_ENTRY - || returnCode == IFSReturnCodeRep.ACCESS_DENIED_TO_REQUEST) - { - throw new SecurityException(ResourceBundleLoader.getText(mapRC(returnCode))); - } - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, e); - throw new SecurityException(e); - } - catch (IOException e) - { - if (Trace.traceOn_) Trace.log(Trace.ERROR, e); - return false; - } - return (returnCode == IFSReturnCodeRep.SUCCESS); - } - -/** - * Returns An IFSJavaFile object based on the absolute path name of the - * current object. If the system property is set, it is copied to - * the returned object. - * - * @return an IFSJavaFile object based on the absolute path name - * of the current object. - * - * @see #getAbsolutePath() -**/ - public File getAbsoluteFile() - { - if (getSystem() != null) - return new IFSJavaFile(getSystem(), this.getAbsolutePath()); - else - return new IFSJavaFile(this.getAbsolutePath()); - } - - -/** - * Returns the absolute path name of the IFSJavaFile. - * This is the full path starting at the root directory. - * - * @return The absolute path name for this IFSJavaFile. - * All paths are absolute paths in the integrated file system. - * - * @see #isAbsolute() -**/ - public String getAbsolutePath() - { - String pathString = ifsFile_.getAbsolutePath(); - if (pathString != null && replace_) //@P2C - { - return pathString.replace(AS400_SEPARATOR, separatorChar); - } - return pathString; - } - - -/** - * Returns An IFSJavaFile object based on the canonical path name of the - * current object. If the system property is set, it is - * copied to the returned object. - * - * @return an IFSJavaFile object based on the canonical path name - * of the current object. - * - * @exception IOException If an I/O error occurs while communicating with the IBM i system. - * @see #getCanonicalPath -**/ - public File getCanonicalFile() throws IOException - { - if (getSystem() != null) - return new IFSJavaFile(getSystem(), this.getCanonicalPath()); - else - return new IFSJavaFile(this.getCanonicalPath()); - } - -/** - * Returns the path name in canonical form of IFSJavaFile path. - * This is the full path starting at the root directory. - * - * @return The canonical path name for this IFSJavaFile. - * - * @exception IOException If an I/O error occurs while communicating with the IBM i system. -**/ - public String getCanonicalPath() throws IOException - { - String pathString = ifsFile_.getCanonicalPath(); - if (pathString != null && replace_) //@P2C - { - return pathString.replace(AS400_SEPARATOR, separatorChar); - } - return pathString; - } - - - /** - Returns the number of unallocated bytes in the partition named by this abstract path name. -

- The returned number of unallocated bytes is a hint, but not a guarantee, that it is possible to use most or any of these bytes. The number of unallocated bytes is most likely to be accurate immediately after this call. It is likely to be made inaccurate by any external I/O operations including those made on the system outside of this virtual machine. This method makes no guarantee that write operations to this file system will succeed. - - @return The number of unallocated bytes on the partition; or 0L if the abstract pathname does not name a partition. This value will be less than or equal to the total file system size returned by getTotalSpace(). - @exception SecurityException If the user is denied access to the file. - **/ - public long getFreeSpace() - throws SecurityException - { - try - { - return ifsFile_.getAvailableSpace(false); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, e); - throw new SecurityException(e); - } - catch (IOException e) - { - if (Trace.traceOn_) Trace.log(Trace.ERROR, e); - return 0L; - } - } - - - /** - Returns the size of the partition named by this abstract pathname. - - @return The size, in bytes, of the partition; or 0L if this abstract pathname does not name a partition. - @exception SecurityException If the user is denied access to the file. - **/ - public long getTotalSpace() - throws SecurityException - { - try - { - return ifsFile_.getTotalSpace(false); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, e); - throw new SecurityException(e); - } - catch (IOException e) - { - if (Trace.traceOn_) Trace.log(Trace.ERROR, e); - return 0L; - } - } - - - /** - Returns the number of bytes available to this virtual machine on the partition named by this abstract pathname. When possible, this method checks for write permissions and other operating system restrictions and will therefore usually provide a more accurate estimate of how much new data can actually be written than getFreeSpace(). -

- The returned number of available bytes is a hint, but not a guarantee, that it is possible to use most or any of these bytes. The number of unallocated bytes is most likely to be accurate immediately after this call. It is likely to be made inaccurate by any external I/O operations including those made on the system outside of this virtual machine. This method makes no guarantee that write operations to this file system will succeed. -

- Note: If the user profile has a "maximum storage allowed" setting of *NOMAX, then getUsableSpace() returns the same value as {@link #getFreeSpace getFreeSpace()}. - - @return The number of available bytes on the partition; or 0L if the abstract pathname does not name a partition. - @exception SecurityException If the user is denied access to the file. - **/ - public long getUsableSpace() - throws SecurityException - { - try - { - return ifsFile_.getAvailableSpace(true); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, e); - throw new SecurityException(e); - } - catch (IOException e) - { - if (Trace.traceOn_) Trace.log(Trace.ERROR, e); - return 0L; - } - } - - -/** - * Returns the IFSFile object contained within this IFSJavaFile. - * - * @return The IFSFile object contained within this IFSJavaFile. -**/ - IFSFile getIfsFile() - { - return ifsFile_; - } - - -/** - * Returns the name of the IFSJavaFile. The name - * is everything in the path name after the last occurrence of the - * separator character. - *

- * The following example demonstrates the use of this method: - *

- * In this example, fileName would equal "file.dat". - *

- *  String path = "\\path\\file.dat";
- *  IFSJavaFile file  = new IFSJavaFile(new AS400("enterprise"), path);
- * 
- * String fileName = file.getName(); - *
- * - * @return The name (without any directory components) of this IFSJavaFile. -**/ - public String getName() - { - return ifsFile_.getName(); - } - -/** - * Returns the parent directory of the IFSJavaFile. The parent directory is everything in - * the path name before the last occurrence of the separator - * character, or null if the separator character does not appear in - * the path name. - *

- * The following example demonstrates the use of this method: - *

- * In this example, parentPath would equal "\test". - *

- *  String path = "\\test\\path";
- *  IFSJavaFile file  = new IFSJavaFile(new AS400("enterprise"), path);
- * 
- * String parentPath = file.getParent(); - *
- * - * @return The parent directory if one exists; null otherwise. - * @see #getParentFile() -**/ - public String getParent() - { - String parentString = ifsFile_.getParent(); - if (parentString != null && replace_) //@P2C - { - return parentString.replace(AS400_SEPARATOR, separatorChar); - } - return parentString; - } - -/** - * Returns an IFSJavaFile object that represents the parent of - * the current object. The parent is the path name before the - * last occurrence of the separator character. Null is returned - * if the separator character does not appear in the path - * or the current object is the file system root. - * If the system property is set, it is also copied to the returned object. - * - * @return an IFSJavaFile object representing the - * parent directory if one exists; null otherwise. - * - * @see #getParent() -**/ - public File getParentFile() - { - if (getParent() == null) - return null; - if (getSystem() != null) - return new IFSJavaFile(getSystem(), this.getParent()); - else - return new IFSJavaFile(this.getParent()); - } - - - -/** - * Returns the path name of the IFSJavaFile. - *

- * The following example demonstrates the use of this method: - *

- * In this example, thePath would equal "\test\path" the same value as path. - *

- *  String path = "\\test\\path";
- *  IFSJavaFile file  = new IFSJavaFile(new AS400("enterprise"), path);
- * 
- * String thePath = file.getPath(); - *
- * - * @return The file path name. -**/ - public String getPath() - { - String pathString = ifsFile_.getPath(); - if (pathString != null && replace_) //@P2C - { - return pathString.replace(AS400_SEPARATOR, separatorChar); - } - return pathString; - } - - - /** - Returns the pattern-matching behavior used when files are listed by any of the list() or listFiles() methods. The default is PATTERN_POSIX. - @return Either {@link IFSFile#PATTERN_POSIX PATTERN_POSIX}, {@link IFSFile#PATTERN_POSIX_ALL PATTERN_POSIX_ALL}, or {@link IFSFile#PATTERN_OS2 PATTERN_OS2} - * @throws IOException If an error occurs while communicating with the system. - **/ - public int getPatternMatching() - throws IOException - { - return ifsFile_.getPatternMatching(); - } - -/** - * Returns the system that this object references. - * - * @return The system object. -**/ - public AS400 getSystem() - { - return ifsFile_.getSystem(); - } - -/** - * Computes a hashcode for this object. - * - * @return A hash code value for this object. -**/ - public int hashCode() - { - return ifsFile_.hashCode(); - } - -/** - * Indicates if the path name of this IFSJavaFile is an - * absolute path name. - * - * @return true if the path name specification is absolute; false otherwise. -**/ - public boolean isAbsolute() - { - // Formerly, this method always reported true, since IFSFile.isAbsolute always reports true. - // In order for JFileChooser to work properly (when used in combination with IFSFileSystemView), instances of IFSJavaFile must remember whether they were created with an absolute path. The underlying IFSFile instance assumes it was created with an absolute path, so we can't rely on the IFSFile to keep track of that for us. - // More details: There is logic in javax.swing.plaf.basic.BasicFileChooserUI#ApproveSelectionAction.actionPerformed() that calls File.isAbsolute(). If not absolute, BasicFileChooserUI prepends the directory path and creates a new (absolute) File object. For that reason, each instance of IFSJavaFile needs to remember whether it was created with an absolute path or not. - - //return ifsFile_.isAbsolute(); - return absolute_; - } - - - // Utility method for determining whether a path is absolute. - static boolean isAbsolutePath(String path) { - if (path != null && path.length() != 0 && path.charAt(0) == separatorChar) { - return true; + /** + * Atomically create a new, empty file. The file is created if and only if the file does not yet exist. The check + * for existence and the file creation is a single atomic operation. + * + * @return true if the file is created, false otherwise. + * @exception IOException If an I/O error occurs while communicating with the IBM i system. + **/ + @Override + public boolean createNewFile() throws IOException { + return ifsFile_.createNewFile(); + } + + /** + * Deletes the IFSJavaFile. If the target is a directory, it must be empty for deletion to succeed. + * + * @return true if the file is successfully deleted; false otherwise. + * @exception SecurityException If the user is denied access to the file. + **/ + @Override + public boolean delete() throws SecurityException + { + try + { + int returnCode = ifsFile_.delete0(); + if ((returnCode == IFSReturnCodeRep.ACCESS_DENIED_TO_DIR_ENTRY) + || (returnCode == IFSReturnCodeRep.ACCESS_DENIED_TO_REQUEST)) + throw new SecurityException(ResourceBundleLoader.getText(mapRC(returnCode))); + + return (returnCode == IFSReturnCodeRep.SUCCESS); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, e); + throw new SecurityException(e); + } + catch (IOException e) { + if (Trace.traceOn_) Trace.log(Trace.ERROR, e); + return false; + } + } + + /** + * Compares this IFSJavaFile against the specified object. Returns true if and only if the argument is + * not null and is an IFSJavaFile object whose path name is equal to the path name of this IFSJavaFile, and system + * names of the objects are equal. + * + * @param obj The object to compare with. + * + * @return true if the objects are the same; false otherwise. + **/ + @Override + public boolean equals(Object obj) + { + if (obj == null || !(obj instanceof IFSJavaFile)) + return false; + + IFSFile otherIfsFile = ((IFSJavaFile) obj).getIfsFile(); + return (ifsFile_.equals(otherIfsFile)); + } + + /** + * Indicates if the IFSJavaFile exists. + * + * @return true if the file specified by this object exists; false otherwise. + * @exception SecurityException If the user is denied read access to the file. + * @exception SecurityException If the user is denied access to the file. + **/ + @Override + public boolean exists() throws SecurityException + { + int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; + try + { + returnCode = ifsFile_.exists0(); // @A5c + if (returnCode == IFSReturnCodeRep.ACCESS_DENIED_TO_DIR_ENTRY + || returnCode == IFSReturnCodeRep.ACCESS_DENIED_TO_REQUEST) + throw new SecurityException(ResourceBundleLoader.getText(mapRC(returnCode))); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, e); + throw new SecurityException(e); + } + catch (IOException e) { + if (Trace.traceOn_) Trace.log(Trace.ERROR, e); + return false; + } + + return (returnCode == IFSReturnCodeRep.SUCCESS); + } + + /** + * Returns An IFSJavaFile object based on the absolute path name of the current object. If the system + * property is set, it is copied to the returned object. + * + * @return an IFSJavaFile object based on the absolute path name of the current object. + * + * @see #getAbsolutePath() + **/ + @Override + public File getAbsoluteFile() + { + if (getSystem() != null) + return new IFSJavaFile(getSystem(), this.getAbsolutePath()); + + return new IFSJavaFile(this.getAbsolutePath()); + } + + /** + * Returns the absolute path name of the IFSJavaFile. This is the full path starting at the root directory. + * + * @return The absolute path name for this IFSJavaFile. All paths are absolute paths in the integrated file system. + * + * @see #isAbsolute() + **/ + @Override + public String getAbsolutePath() + { + String pathString = ifsFile_.getAbsolutePath(); + if (pathString != null && replace_) + return pathString.replace(AS400_SEPARATOR, separatorChar); + + return pathString; + } + + /** + * Returns An IFSJavaFile object based on the canonical path name of the current object. If the system + * property is set, it is copied to the returned object. + * + * @return an IFSJavaFile object based on the canonical path name of the current object. + * + * @exception IOException If an I/O error occurs while communicating with the IBM i system. + * @see #getCanonicalPath + **/ + @Override + public File getCanonicalFile() throws IOException + { + if (getSystem() != null) + return new IFSJavaFile(getSystem(), this.getCanonicalPath()); + + return new IFSJavaFile(this.getCanonicalPath()); + } + + /** + * Returns the path name in canonical form of IFSJavaFile path. This is the full path starting at the root + * directory. + * + * @return The canonical path name for this IFSJavaFile. + * + * @exception IOException If an I/O error occurs while communicating with the IBM i system. + **/ + @Override + public String getCanonicalPath() throws IOException + { + String pathString = ifsFile_.getCanonicalPath(); + if (pathString != null && replace_) // @P2C + return pathString.replace(AS400_SEPARATOR, separatorChar); + + return pathString; + } + + /** + * Returns the number of unallocated bytes in the partition named by this abstract path name. + *

+ * The returned number of unallocated bytes is a hint, but not a guarantee, that it is possible to use most or any + * of these bytes. The number of unallocated bytes is most likely to be accurate immediately after this call. It is + * likely to be made inaccurate by any external I/O operations including those made on the system outside of this + * virtual machine. This method makes no guarantee that write operations to this file system will succeed. + * + * @return The number of unallocated bytes on the partition; or 0L if the abstract pathname does not name a + * partition. This value will be less than or equal to the total file system size returned by + * getTotalSpace(). + * @exception SecurityException If the user is denied access to the file. + **/ + @Override + public long getFreeSpace() throws SecurityException + { + try { + return ifsFile_.getAvailableSpace(false); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, e); + throw new SecurityException(e); + } + catch (IOException e) { + if (Trace.traceOn_) Trace.log(Trace.ERROR, e); + return 0L; + } + } + + /** + * Returns the size of the partition named by this abstract pathname. + * + * @return The size, in bytes, of the partition; or 0L if this abstract pathname does not name a partition. + * @exception SecurityException If the user is denied access to the file. + **/ + @Override + public long getTotalSpace() throws SecurityException + { + try { + return ifsFile_.getTotalSpace(false); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, e); + throw new SecurityException(e); + } + catch (IOException e) { + if (Trace.traceOn_) Trace.log(Trace.ERROR, e); + return 0L; + } + } + + /** + * Returns the number of bytes available to this virtual machine on the partition named by this abstract pathname. + * When possible, this method checks for write permissions and other operating system restrictions and will + * therefore usually provide a more accurate estimate of how much new data can actually be written than + * getFreeSpace(). + *

+ * The returned number of available bytes is a hint, but not a guarantee, that it is possible to use most or any of + * these bytes. The number of unallocated bytes is most likely to be accurate immediately after this call. It is + * likely to be made inaccurate by any external I/O operations including those made on the system outside of this + * virtual machine. This method makes no guarantee that write operations to this file system will succeed. + *

+ * Note: If the user profile has a "maximum storage allowed" setting of *NOMAX, then getUsableSpace() returns the + * same value as {@link #getFreeSpace getFreeSpace()}. + * + * @return The number of available bytes on the partition; or 0L if the abstract pathname does not name a partition. + * @exception SecurityException If the user is denied access to the file. + **/ + @Override + public long getUsableSpace() throws SecurityException + { + try { + return ifsFile_.getAvailableSpace(true); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, e); + throw new SecurityException(e); + } + catch (IOException e) { + if (Trace.traceOn_) Trace.log(Trace.ERROR, e); + return 0L; + } + } + + /** + * Returns the IFSFile object contained within this IFSJavaFile. + * + * @return The IFSFile object contained within this IFSJavaFile. + **/ + IFSFile getIfsFile() { + return ifsFile_; + } + + /** + * Returns the name of the IFSJavaFile. The name is everything in the path name after the last occurrence of the + * separator character. + *

+ * The following example demonstrates the use of this method: + *

+ * In this example, fileName would equal "file.dat". + * + *

+     *  String path = "\\path\\file.dat";
+     *  IFSJavaFile file  = new IFSJavaFile(new AS400("enterprise"), path);
+     * 
+ * String fileName = file.getName(); + *
+ * + * @return The name (without any directory components) of this IFSJavaFile. + **/ + @Override + public String getName() { + return ifsFile_.getName(); + } + + /** + * Returns the parent directory of the IFSJavaFile. The parent directory is everything in the path name before the + * last occurrence of the separator character, or null if the separator character does not appear in the path name. + *

+ * The following example demonstrates the use of this method: + *

+ * In this example, parentPath would equal "\test". + * + *

+     *  String path = "\\test\\path";
+     *  IFSJavaFile file  = new IFSJavaFile(new AS400("enterprise"), path);
+     * 
+ * String parentPath = file.getParent(); + *
+ * + * @return The parent directory if one exists; null otherwise. + * @see #getParentFile() + **/ + @Override + public String getParent() + { + String parentString = ifsFile_.getParent(); + if (parentString != null && replace_) + return parentString.replace(AS400_SEPARATOR, separatorChar); + + return parentString; + } + + /** + * Returns an IFSJavaFile object that represents the parent of the current object. The parent is the path name + * before the last occurrence of the separator character. Null is returned if the separator character does not + * appear in the path or the current object is the file system root. If the system property is set, it is + * also copied to the returned object. + * + * @return an IFSJavaFile object representing the parent directory if one exists; null otherwise. + * + * @see #getParent() + **/ + @Override + public File getParentFile() + { + if (getParent() == null) + return null; + + if (getSystem() != null) + return new IFSJavaFile(getSystem(), this.getParent()); + + return new IFSJavaFile(this.getParent()); + } + + /** + * Returns the path name of the IFSJavaFile. + *

+ * The following example demonstrates the use of this method: + *

+ * In this example, thePath would equal "\test\path" the same value as path. + * + *

+     *  String path = "\\test\\path";
+     *  IFSJavaFile file  = new IFSJavaFile(new AS400("enterprise"), path);
+     * 
+ * String thePath = file.getPath(); + *
+ * + * @return The file path name. + **/ + @Override + public String getPath() + { + String pathString = ifsFile_.getPath(); + if (pathString != null && replace_) + return pathString.replace(AS400_SEPARATOR, separatorChar); + + return pathString; + } + + /** + * Returns the pattern-matching behavior used when files are listed by any of the list() or + * listFiles() methods. The default is PATTERN_POSIX. + * + * @return Either {@link IFSFile#PATTERN_POSIX PATTERN_POSIX}, {@link IFSFile#PATTERN_POSIX_ALL PATTERN_POSIX_ALL}, + * or {@link IFSFile#PATTERN_OS2 PATTERN_OS2} + * @throws IOException If an error occurs while communicating with the system. + **/ + public int getPatternMatching() throws IOException { + return ifsFile_.getPatternMatching(); + } + + /** + * Returns the system that this object references. + * + * @return The system object. + **/ + public AS400 getSystem() { + return ifsFile_.getSystem(); + } + + /** + * Computes a hashcode for this object. + * + * @return A hash code value for this object. + **/ + @Override + public int hashCode() { + return ifsFile_.hashCode(); + } + + /** + * Indicates if the path name of this IFSJavaFile is an absolute path name. + * + * @return true if the path name specification is absolute; false otherwise. + **/ + @Override + public boolean isAbsolute() + { + // Formerly, this method always reported true, since IFSFile.isAbsolute always reports true. + // In order for JFileChooser to work properly (when used in combination with IFSFileSystemView), instances of + // IFSJavaFile must remember whether they were created with an absolute path. The underlying IFSFile instance + // assumes it was created with an absolute path, so we can't rely on the IFSFile to keep track of that for us. + // More details: There is logic in + // javax.swing.plaf.basic.BasicFileChooserUI#ApproveSelectionAction.actionPerformed() that calls + // File.isAbsolute(). If not absolute, BasicFileChooserUI prepends the directory path and creates a new + // (absolute) File object. For that reason, each instance of IFSJavaFile needs to remember whether it was + // created with an absolute path or not. + + return absolute_; + } + + // Utility method for determining whether a path is absolute. + static boolean isAbsolutePath(String path) { + return (path != null && path.length() != 0 && path.charAt(0) == separatorChar); + } + + /** + * Indicates if the IFSJavaFile is a directory. + * + * @return true if the IFSJavaFile exists and is a directory; false otherwise. + * @exception SecurityException If the user is denied access to the file. + **/ + @Override + public boolean isDirectory() throws SecurityException + { + int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; + try + { + returnCode = ifsFile_.isDirectory0(); + if (returnCode == IFSReturnCodeRep.ACCESS_DENIED_TO_DIR_ENTRY + || returnCode == IFSReturnCodeRep.ACCESS_DENIED_TO_REQUEST) + throw new SecurityException(ResourceBundleLoader.getText(mapRC(returnCode))); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, e); + throw new SecurityException(e); + } + catch (IOException e) { + if (Trace.traceOn_) Trace.log(Trace.ERROR, e); + return false; + } + + return (returnCode == IFSReturnCodeRep.SUCCESS); + } + + /** + * Indicates if the IFSJavaFile is a "normal" file.
+ * A file is "normal" if it is not a directory or a container of other objects. + * + * @return true if the specified file exists and is a "normal" file; false otherwise. + * @exception SecurityException If the user is denied access to the file. + **/ + @Override + public boolean isFile() throws SecurityException + { + int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; + try + { + returnCode = ifsFile_.isFile0(); + if (returnCode == IFSReturnCodeRep.ACCESS_DENIED_TO_DIR_ENTRY + || returnCode == IFSReturnCodeRep.ACCESS_DENIED_TO_REQUEST) + throw new SecurityException(ResourceBundleLoader.getText(mapRC(returnCode))); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, e); + throw new SecurityException(e); + } + catch (IOException e) { + if (Trace.traceOn_) Trace.log(Trace.ERROR, e); + return false; + } + + return (returnCode == IFSReturnCodeRep.SUCCESS); + } + + /** + * Indicates if the IFSJavaFile is hidden. On the IBM i system, a file is hidden if its hidden attribute is set. + * + * @return true if the file is hidden; false otherwise. + * @exception SecurityException If the user is denied access to the file. + **/ + @Override + public boolean isHidden() throws SecurityException + { + try { + return ifsFile_.isHidden(); + } + catch (AS400SecurityException e) { + throw new SecurityException(e); + } + catch (IOException e) { + if (Trace.traceOn_) Trace.log(Trace.ERROR, e); + return false; + } + } + + /** + * Indicates the time that the IFSJavaFile was last modified. + * + * @return The time (measured in milliseconds since 01/01/1970 00:00:00 GMT) that the IFSJavaFile was last modified, + * or 0 if it does not exist. + * @exception SecurityException If the user is denied access to the file. + **/ + @Override + public long lastModified() throws SecurityException + { + try { + return ifsFile_.lastModified0(); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, e); + throw new SecurityException(e); + } + catch (IOException e) { + if (Trace.traceOn_) Trace.log(Trace.ERROR, e); + return 0L; + } + } + + /** + * Indicates the length of this IFSJavaFile. + * + * @return The length, in bytes, of the IFSJavaFile, or 0((IFSJavaFile) if it does not exist. + * @exception SecurityException If the user is denied access to the file. + **/ + @Override + public long length() throws SecurityException + { + try + { + // For the listFiles() methods, the IFS File Server reports the length of + // a symbolic link rather than the length of the target object. Circumvention + // is to clear the ifsFile cache and re-retrieve the attributes from the IFS + // File Server. When not using wild-cards the IFS File Server always follows + // symlnk objects and returns the attributes of the target object. + if (ifsFile_.isSymbolicLink()) + ifsFile_.clearCachedAttributes(); + return ifsFile_.length0(); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, e); + throw new SecurityException(e); + } + catch (IOException e) { + if (Trace.traceOn_) Trace.log(Trace.ERROR, e); + return 0L; + } + } + + /** + * Lists the files in this IFSJavaFile directory. + * + * @return An array of object names in the directory. This list does not include the current directory or the parent + * directory. If this IFSJavaFile is not a directory, null is returned. If this IFSJavaFile is an empty + * directory, an empty string array is returned. + * @see #listFiles() + * @exception SecurityException If the user is denied access to the file. + **/ + @Override + public String[] list() throws SecurityException + { + try { + return ifsFile_.list0(null, "*"); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, e); + throw new SecurityException(e); + } + catch (IOException e) { + if (Trace.traceOn_) Trace.log(Trace.ERROR, e); + return new String[0]; + } + } + + /** + * Lists the files in this IFSJavaFile directory that satisfy filter. + * + * @param filter The file name filter. + * + * @return An array of object names in the directory that satisfy the file name filter. This list does not include + * the current directory or the parent directory. If this IFSJavaFile is not a directory, null is returned. + * If this IFSJavaFile is an empty directory, or the file name filter does not match any files, an empty + * string array is returned. The IFSJavaFile object passed to the file name filter object have cached file + * attribute information. Maintaining references to these IFSJavaFile objects after the list operation + * increases the chances that their file attribute information will not be valid. + *

+ * The following example demonstrates the use of this method: + * + *

+     *  class AcceptClass implements java.io.FilenameFilter
+     *  {
+     *    public boolean accept(java.io.File dir, java.lang.String name)
+     *    {
+     *      if (name.startsWith("IFS"))
+     *        return true;
+     *      return false;
+     *    }
+     *  }
+     * 
+ * IFSJavaFile file = new IFSJavaFile(new AS400("enterprise"), path); + * AcceptClass ac = new AcceptClass(); + * file.list(ac); + *
+ * + * @exception SecurityException If the user is denied access to the file. + * @see #listFiles(FilenameFilter) + **/ + @Override + public String[] list(FilenameFilter filter) throws SecurityException + { + String names[] = null; + + try { + names = ifsFile_.list0(null, "*"); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, e); + throw new SecurityException(e); + } + catch (IOException e) { + if (Trace.traceOn_) Trace.log(Trace.ERROR, e); + return null; + } + + if (names == null) + return null; + + // Fill in the Vector + Vector v = new Vector(); + for (int i = 0; i < names.length; i++) + { + if ((filter == null) || filter.accept(this, names[i])) + v.addElement(names[i]); + } + + // Create the array + String files[] = new String[v.size()]; + v.copyInto(files); + + return files; + } + + /** + * Lists the files in the IFSJavaFile directory that satisfy file name filter. + * + * @param filter The file name filter. + * + * @return An array of object names in the directory that satisfy the file name filter. This list does not include + * the current directory or the parent directory. If this IFSJavaFile is not a directory, null is returned. + * If this IFSJavaFile is an empty directory, or the file name filter does not match any files, an empty + * string array is returned. The IFSFile object passed to the file name filter object have cached file + * attribute information. Maintaining references to these IFSFile objects after the list operation increases + * the chances that their file attribute information will not be valid. + *

+ * The following example demonstrates the use of this method: + * + *

+     *  class AcceptClass implements IFSFileFilter
+     *  {
+     *    public boolean accept(IFSFile file)
+     *    {
+     *      if (file.getName().startsWith("IFS"))
+     *        return true;
+     *      return false;
+     *    }
+     *  }
+     * 
+ * IFSJavaFile file = new IFSJavaFile(new AS400("enterprise"), path); + * AcceptClass ac = new AcceptClass(); + * file.list(ac); + * + *
+ * + * @exception SecurityException If the user is denied access to the file. + * @see #listFiles(IFSFileFilter) + **/ + public String[] list(IFSFileFilter filter) throws SecurityException + { + try { + return ifsFile_.list0(filter, "*"); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, e); + throw new SecurityException(e); + } + catch (IOException e) { + if (Trace.traceOn_) Trace.log(Trace.ERROR, e); + return new String[0]; + } + } + + /** + * Lists the files in this IFSJavaFile directory that satisfy filter and pattern. + * + *

+ * Note:
+ * If the file does not match pattern, it will not be processed by filter. + * + * @param filter The file name filter. + * @param pattern The pattern that all filenames must match. Acceptable characters are wildcards (* - matches + * multiple characters) and question marks (? - matches one character). Pattern must not be null. + * + * @return An array of object names in the directory that satisfy the file name filter and pattern. This list does + * not include the current directory or the parent directory. If this IFSJavaFile is not a directory, null + * is returned. If this IFSJavaFile is an empty directory, or the file name filter or pattern does not match + * any files, an empty string array is returned. The IFSFile object passed to the file name filter object + * have cached file attribute information. Maintaining references to these IFSFile objects after the list + * operation increases the chances that their file attribute information will not be valid. + * @exception SecurityException If the user is denied access to the file. + * @see #listFiles(IFSFileFilter,String) + **/ + public String[] list(IFSFileFilter filter, String pattern) throws SecurityException + { + if (pattern == null) + throw new NullPointerException("pattern"); + + try { + return ifsFile_.list0(filter, pattern); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, e); + throw new SecurityException(e); + } + catch (IOException e) { + if (Trace.traceOn_) Trace.log(Trace.ERROR, e); + return new String[0]; + } + } + + /** + * Lists the files in this IFSJavaFile directory that match pattern. + * + * @param pattern The pattern that all filenames must match. Acceptable characters are wildcards (* - matches + * multiple characters) and question marks (? - matches one character). + * + * @return An array of object names in the directory that match the pattern. This list does not include the current + * directory or the parent directory. If this IFSJavaFile is not a directory, null is returned. If this + * IFSJavaFile is an empty directory, or the pattern does not match any files, an empty string array is + * returned. + * @exception SecurityException If the user is denied access to the file. + * @see #listFiles(String) + **/ + public String[] list(String pattern) throws SecurityException + { + if (pattern == null) + throw new NullPointerException("pattern"); + + try { + return ifsFile_.list0(null, pattern); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, e); + throw new SecurityException(e); + } + catch (IOException e) { + if (Trace.traceOn_) Trace.log(Trace.ERROR, e); + return new String[0]; + } + } + + /** + * Lists the files in this IFSJavaFile directory. With the use of this function, attribute information is cached and + * will not be refreshed from the IBM i system. This means attribute information may become inconsistent with the + * IBM i system. + * + * @return An array of objects in the directory. This list does not include the current directory or the parent + * directory. If this IFSJavaFile is not a directory, null is returned. If this IFSJavaFile is an empty + * directory, an empty object array is returned. + * @exception SecurityException If the user is denied access to the file. + * @see #list() + **/ + @Override + public File[] listFiles() throws SecurityException { + return listFiles(null, "*"); + } + + /** + * Lists the files in this IFSJavaFile directory that satisfy filter. With the use of this function, + * attribute information is cached and will not be refreshed from the IBM i system. This means attribute information + * may become inconsistent with the IBM i system. + * + * @param filter The file name filter. + * + * @return An array of objects in the directory that satisfy the file name filter. This list does not include the + * current directory or the parent directory. If this IFSJavaFile is not a directory, null is returned. If + * this IFSJavaFile is an empty directory, or the file name filter does not match any files, an empty object + * array is returned. The IFSJavaFile object passed to the file name filter object has cached file attribute + * information. Maintaining references to these IFSJavaFile objects after the list operation increases the + * chances that their file attribute information will not be valid. + *

+ * The following example demonstrates the use of this method: + * + *

+     *  class AcceptClass implements java.io.FilenameFilter
+     *  {
+     *    public boolean accept(java.io.File dir, java.lang.String name)
+     *    {
+     *      if (name.startsWith("IFS"))
+     *        return true;
+     *      return false;
+     *    }
+     *  }
+     * 
+ * IFSJavaFile file = new IFSJavaFile(new AS400("enterprise"), path); + * AcceptClass ac = new AcceptClass(); + * file.listFiles(ac); + *
+ * + * @exception SecurityException If the user is denied access to the file. + * @see #list(FilenameFilter) + **/ + @Override + public File[] listFiles(FilenameFilter filter) throws SecurityException + { + IFSFile[] files = null; + try { + files = ifsFile_.listFiles0(null, "*"); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, e); + throw new SecurityException(e); + } + catch (IOException e) { + if (Trace.traceOn_) Trace.log(Trace.ERROR, e); + return null; + } + + if (files == null) + return null; + + // Fill in the Vector + Vector v = new Vector(); + for (int i = 0; i < files.length; i++) { + if ((filter == null) || filter.accept(this, files[i].getName())) + v.addElement(new IFSJavaFile(files[i])); + } + + // Create the array + IFSJavaFile newFiles[] = new IFSJavaFile[v.size()]; + v.copyInto(newFiles); + + return newFiles; + } + + /** + * Lists the files in this IFSJavaFile directory that satisfy filter. With the use of this function, + * attribute information is cached and will not be refreshed from the IBM i system. This means attribute information + * may become inconsistent with the IBM i system. + * + * @param filter The file filter. + * + * @return An array of objects in the directory that satisfy the file filter. This list does not include the current + * directory or the parent directory. If this IFSJavaFile is not a directory, null is returned. If this + * IFSJavaFile is an empty directory, or the file filter does not match any files, an empty object array is + * returned. The IFSJavaFile object passed to the file filter object has cached file attribute information. + * Maintaining references to these IFSJavaFile objects after the list operation increases the chances that + * their file attribute information will not be valid. + *

+ * The following example demonstrates the use of this method: + * + *

+     *  class AcceptClass implements java.io.FileFilter
+     *  {
+     *    public boolean accept(java.io.File file)
+     *    {
+     *      if (file.getName().startsWith("IFS"))
+     *        return true;
+     *      return false;
+     *    }
+     *  }
+     * 
+ * IFSJavaFile file = new IFSJavaFile(new AS400("enterprise"), path); + * AcceptClass ac = new AcceptClass(); + * file.listFiles(ac); + *
+ * + * @exception SecurityException If the user is denied access to the file. + **/ + @Override + public File[] listFiles(FileFilter filter) throws SecurityException + { + IFSFile[] files = null; + try { + files = ifsFile_.listFiles0(null, "*"); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, e); + throw new SecurityException(e); + } + catch (IOException e) { + if (Trace.traceOn_) Trace.log(Trace.ERROR, e); + return null; + } + + if (files == null) + return null; + + // Fill in the Vector + Vector v = new Vector(); + for (int i = 0; i < files.length; i++) + { + IFSJavaFile file = new IFSJavaFile(files[i]); + if ((filter == null) || filter.accept(file)) + v.addElement(file); + } + + // Create the array + IFSJavaFile newFiles[] = new IFSJavaFile[v.size()]; + v.copyInto(newFiles); + + return newFiles; + } + + /** + * Lists the files in the IFSJavaFile directory that satisfy file name filter. With the use of this function, + * attribute information is cached and will not be refreshed from the IBM i system. This means attribute information + * may become inconsistent with the IBM i system. + * + * @param filter The file name filter. + * + * @return An array of objects in the directory that satisfy the file name filter. This list does not include the + * current directory or the parent directory. If this IFSJavaFile is not a directory, null is returned. If + * this IFSJavaFile is an empty directory, or the file name filter does not match any files, an empty object + * array is returned. The IFSFile object passed to the file name filter object has cached file attribute + * information. Maintaining references to these IFSFile objects after the list operation increases the + * chances that their file attribute information will not be valid. + *

+ * The following example demonstrates the use of this method: + * + *

+     *  class AcceptClass implements IFSFileFilter
+     *  {
+     *    public boolean accept(IFSFile file)
+     *    {
+     *      if (file.getName().startsWith("IFS"))
+     *        return true;
+     *      return false;
+     *    }
+     *  }
+     * 
+ * IFSJavaFile file = new IFSJavaFile(new AS400("enterprise"), path); + * AcceptClass ac = new AcceptClass(); + * file.listFiles(ac); + * + *
+ * + * @exception SecurityException If the user is denied access to the file. + * @see #list(IFSFileFilter) + **/ + public File[] listFiles(IFSFileFilter filter) throws SecurityException { + return listFiles(filter, "*"); + } + + /** + * Lists the files in this IFSJavaFile directory that satisfy filter and pattern. With the use of this + * function, attribute information is cached and will not be refreshed from the IBM i system. This means attribute + * information may become inconsistent with the IBM i system. + * + *

+ * Note:
+ * If the file does not match pattern, it will not be processed by filter. + * + * @param filter The file name filter. + * @param pattern The pattern that all filenames must match. Acceptable characters are wildcards (* - matches + * multiple characters) and question marks (? - matches one character). Pattern must not be null. + * + * @return An array of objects in the directory that satisfy the file name filter and pattern. This list does not + * include the current directory or the parent directory. If this IFSJavaFile is not a directory, null is + * returned. If this IFSJavaFile is an empty directory, or the file name filter or pattern does not match + * any files, an empty object array is returned. The IFSFile object passed to the file name filter object + * has cached file attribute information. Maintaining references to these IFSFile objects after the list + * operation increases the chances that their file attribute information will not be valid. + * @exception SecurityException If the user is denied access to the file. + * @see #list(IFSFileFilter,String) + **/ + public File[] listFiles(IFSFileFilter filter, String pattern) throws SecurityException + { + if (pattern == null) + throw new NullPointerException("pattern"); + + try + { + IFSFile files[] = ifsFile_.listFiles0(filter, pattern); + IFSJavaFile newFiles[] = new IFSJavaFile[files.length]; + for (int i = 0; i < files.length; i++) { + newFiles[i] = new IFSJavaFile(files[i]); + } + + return newFiles; + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, e); + throw new SecurityException(e); + } + catch (IOException e) { + if (Trace.traceOn_) Trace.log(Trace.ERROR, e); + return new IFSJavaFile[0]; + } + } + + /** + * Lists the files in this IFSJavaFile directory that match pattern. With the use of this function, attribute + * information is cached and will not be refreshed from the IBM i system. This means attribute information may + * become inconsistent with the IBM i system. + * + * @param pattern The pattern that all filenames must match. Acceptable characters are wildcards (* - matches + * multiple characters) and question marks (? - matches one character). + * + * @return An array of object names in the directory that match the pattern. This list does not include the current + * directory or the parent directory. If this IFSJavaFile is not a directory, null is returned. If this + * IFSJavaFile is an empty directory, or the pattern does not match any files, an empty string array is + * returned. + * @exception SecurityException If the user is denied access to the file. + * @see #list(String) + **/ + public File[] listFiles(String pattern) throws SecurityException + { + if (pattern == null) + throw new NullPointerException("pattern"); + + return listFiles(null, pattern); + } + + /** + * Lists the file system roots for the integrated file system of the IBM i system. The IBM i integrated file system + * has only one root -- "/". + * + * @return An array of IFSJavaFile objects that represent the file system roots of the integrated file system of the + * IBM i system. Since the IBM i integrated file system has only one root, the returned array contains only + * one element. + **/ + public static File[] listRoots() + { + IFSJavaFile[] roots = new IFSJavaFile[1]; + roots[0] = new IFSJavaFile(File.separator); + return roots; + } + + // convert return code to string for mri file + private String mapRC(int returnCode) + { + if (returnCode == IFSReturnCodeRep.ACCESS_DENIED_TO_DIR_ENTRY) + return "EXC_ACCESS_DENIED"; + else if (returnCode == IFSReturnCodeRep.ACCESS_DENIED_TO_REQUEST) + return "EXC_REQUEST_DENIED"; + + return "EXC_UNKNOWN"; + } + + /** + * Creates a directory whose path name is specified by this IFSJavaFile. + * + * + * @return true if the directory could be created; false otherwise. + * @exception SecurityException If the user is denied access to the file. + **/ + @Override + public boolean mkdir() throws SecurityException + { + int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; + try { + returnCode = ifsFile_.mkdir0(ifsFile_.getAbsolutePath()); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, e); + throw new SecurityException(e); + } + catch (IOException e) { + if (Trace.traceOn_) Trace.log(Trace.ERROR, e); + return false; + } + + return (returnCode == IFSReturnCodeRep.SUCCESS); + } + + /** + * Creates a directory whose path name is specified by this IFSJavaFile, including any necessary parent directories. + * + * @return true if the directory (or directories) could be created; false otherwise. + * @exception SecurityException If the user is denied access to the file. + **/ + @Override + public boolean mkdirs() throws SecurityException + { + int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; + try { + returnCode = ifsFile_.mkdirs0(); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, e); + throw new SecurityException(e); + } + catch (IOException e) { + if (Trace.traceOn_) Trace.log(Trace.ERROR, e); + return false; + } + + return (returnCode == IFSReturnCodeRep.SUCCESS); + } + + /** + * Renames the IFSJavaFile to have the path name of dest. Wildcards are not permitted in this file name. + * + * @param dest The new filename. + * + * @return true if the renaming succeeds; false otherwise. + * @exception SecurityException If the user is denied access to the file. + **/ + public boolean renameTo(IFSJavaFile dest) throws SecurityException + { + if (dest == null) + throw new NullPointerException("dest"); + + int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; + IFSFile lFile = new IFSFile(); + + try + { + lFile.setSystem(dest.getSystem()); + String destPath = dest.getPath(); // @P2A + lFile.setPath(replace_ ? destPath.replace(separatorChar, AS400_SEPARATOR) : destPath); + returnCode = ifsFile_.renameTo0(lFile); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, e); + throw new SecurityException(e); + } + catch (PropertyVetoException e) { + } // will never happen + catch (IOException e) { + if (Trace.traceOn_) + Trace.log(Trace.ERROR, e); + return false; + } + + return (returnCode == IFSReturnCodeRep.SUCCESS); + } + + /** + * Renames the IFSJavaFile to have the path name of dest. Wildcards are not permitted in this file name. + * + * @param dest An object specifying the new filename. If this object is not an IFSJavaFile, the rename will fail. + * + * @return true if the renaming succeeds; false otherwise. + * @exception SecurityException If the user is denied access to the file. + **/ + @Override + public boolean renameTo(File dest) throws SecurityException + { + try { + return renameTo((IFSJavaFile) dest); + } + catch (ClassCastException e) { + Trace.log(Trace.ERROR, e); + return false; + } + } + + /** + * Sets the last modified time of the file named by this IFSJavaFile object. + * + * @param time The new last modified time, measured in milliseconds since 00:00:00 GMT, January 1, 1970. If -1, sets + * the last modified time to the current system time. + * @return true if the time is set; false otherwise. + * @exception SecurityException If the user is denied access to the file. + **/ + @Override + public boolean setLastModified(long time) throws SecurityException + { + try { + return ifsFile_.setLastModified0(time); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, e); + throw new SecurityException(e); + } + catch (IOException e) { + if (Trace.traceOn_) Trace.log(Trace.ERROR, e); + return false; + } + } + + /** + * Sets the length of the file named by this IFSJavaFile object. The file can be made larger or smaller. If the file + * is made larger, the contents of the new bytes of the file are undetermined. + * + * @param length The new length, in bytes. + * @return true if successful; false otherwise. + * @exception SecurityException If the user is denied access to the file. + **/ + public boolean setLength(int length) throws SecurityException + { + try { + return ifsFile_.setLength0(length); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, e); + throw new SecurityException(e); + } + catch (IOException e) { + if (Trace.traceOn_) Trace.log(Trace.ERROR, e); + return false; + } + } + + /** + * Sets the path for this IFSJavaFile. + * + * @param path The absolute file path. + * + * @return true if the path was set; false otherwise. + **/ + public boolean setPath(String path) + { + if (path == null) + throw new NullPointerException("path"); + + try { + ifsFile_.setPath(replace_ ? path.replace(separatorChar, AS400_SEPARATOR) : path); + absolute_ = isAbsolutePath(path); + } + catch (PropertyVetoException e) { + } // will never happen + + return true; + } + + /** + * Sets the pattern-matching behavior used when files are listed by any of the list() or + * listFiles() methods. The default is PATTERN_POSIX. + * + * @param patternMatching Either {@link IFSFile#PATTERN_POSIX PATTERN_POSIX}, {@link IFSFile#PATTERN_POSIX_ALL + * PATTERN_POSIX_ALL}, or {@link IFSFile#PATTERN_OS2 PATTERN_OS2} + * @throws IOException If an error occurs while communicating with the system. + * + * @exception ConnectionDroppedException If the connection is dropped unexpectedly. + * @exception ExtendedIOException If an error occurs while communicating with the system. + * @exception ServerStartupException If the host server cannot be started. + **/ + public void setPatternMatching(int patternMatching) throws IOException { + ifsFile_.setPatternMatching(patternMatching); + } + + /** + * Marks the file named by this IFSJavaFile object so that only read operations are allowed. On the IBM i system, a + * file is marked read only by setting the read only attribute of the file. + * + * @return true if the read only attribute is set; false otherwise. + * @exception SecurityException If the user is denied access to the file. + **/ + @Override + public boolean setReadOnly() throws SecurityException + { + try { + return ifsFile_.setReadOnly0(true); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, e); + throw new SecurityException(e); + } + catch (IOException e) { + if (Trace.traceOn_) Trace.log(Trace.ERROR, e); + return false; + } + } + + /** + * Sets the system. + * + * @param system The system object. + * + * @return true if the system was set; false otherwise. + **/ + public boolean setSystem(AS400 system) + { + if (system == null) + throw new NullPointerException("system"); + + try { + ifsFile_.setSystem(system); + } + catch (PropertyVetoException e) { + } // will never happen + + return true; + } + + /** + * A convenience method to set the owner's execute permission for this abstract pathname. This method is supported + * for IBM i V5R1 and higher. For older releases, it simply returns false. + *

+ * An invocation of this method of the form file.setExcutable(arg) behaves in exactly the same way as the + * invocation file.setExecutable(arg, true) + * + * @param executable If true, sets the access permission to allow execute operations; if false, to disallow execute + * operations. + * @return true if and only if the operation succeeded. The operation will fail if the user does not have permission + * to change the access permissions of this abstract pathname. + * @exception SecurityException If the user is denied access to the file. + **/ + @Override + public boolean setExecutable(boolean executable) throws SecurityException { + return setExecutable(executable, true); + } + + /** + * Sets the owner's or everybody's execute permission for this abstract pathname. This method is supported for IBM i + * V5R1 and higher. For older releases, it simply returns false. + * + * @param executable If true, sets the access permission to allow execute operations; if false, to disallow execute + * operations. + * @param ownerOnly If true, the execute permission applies only to the owner's execute permission; otherwise, it + * applies to everybody. + * @return true if and only if the operation succeeded. The operation will fail if the user does not have permission + * to change the access permissions of this abstract pathname. + * @exception SecurityException If the user is denied access to the file. + **/ + @Override + public boolean setExecutable(boolean executable, boolean ownerOnly) throws SecurityException + { + try { + return ifsFile_.setAccess(IFSFile.ACCESS_EXECUTE, executable, ownerOnly); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, e); + throw new SecurityException(e); + } + catch (IOException e) { + if (Trace.traceOn_) Trace.log(Trace.ERROR, e); + return false; + } + } + + /** + * A convenience method to set the owner's read permission for this abstract pathname. This method is supported for + * IBM i V5R1 and higher. For older releases, it simply returns false. + *

+ * An invocation of this method of the form file.setReadable(arg) behaves in exactly the same way as the + * invocation file.setReadable(arg, true) + * + * @param readable If true, sets the access permission to allow read operations; if false, to disallow read + * operations. + * @return true if and only if the operation succeeded. The operation will fail if the user does not have permission + * to change the access permissions of this abstract pathname. + * @exception SecurityException If the user is denied access to the file. + **/ + @Override + public boolean setReadable(boolean readable) throws SecurityException { + return setReadable(readable, true); + } + + /** + * Sets the owner's or everybody's read permission for this abstract pathname. This method is supported for IBM i + * V5R1 and higher. For older releases, it simply returns false. + * + * @param readable If true, sets the access permission to allow read operations; if false, to disallow read + * operations. + * @param ownerOnly If true, the read permission applies only to the owner's read permission; otherwise, it applies + * to everybody. + * @return true if and only if the operation succeeded. The operation will fail if the user does not have permission + * to change the access permissions of this abstract pathname. + * @exception SecurityException If the user is denied access to the file. + **/ + @Override + public boolean setReadable(boolean readable, boolean ownerOnly) throws SecurityException + { + try { + return ifsFile_.setAccess(IFSFile.ACCESS_READ, readable, ownerOnly); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, e); + throw new SecurityException(e); + } + catch (IOException e) { + if (Trace.traceOn_) Trace.log(Trace.ERROR, e); + return false; + } + } + + /** + * A convenience method to set the owner's write permission for this abstract pathname. This method is supported for + * IBM i V5R1 and higher. For older releases, it simply returns false. + *

+ * An invocation of this method of the form file.setWritable(arg) behaves in exactly the same way as the + * invocation file.setWritable(arg, true) + * + * @param writable If true, sets the access permission to allow write operations; if false to disallow write + * operations + * @return true if and only if the operation succeeded. The operation will fail if the user does not have permission + * to change the access permissions of this abstract pathname. + * @exception SecurityException If the user is denied access to the file. + **/ + @Override + public boolean setWritable(boolean writable) throws SecurityException { + return setWritable(writable, true); + } + + /** + * Sets the owner's or everybody's write permission for this abstract pathname. This method is supported for IBM i + * V5R1 and higher. For older releases, it simply returns false. + * + * @param writable If true, sets the access permission to allow write operations; if false, to disallow write + * operations. + * @param ownerOnly If true, the write permission applies only to the owner's write permission; otherwise, it + * applies to everybody. + * @return true if and only if the operation succeeded. The operation will fail if the user does not have permission + * to change the access permissions of this abstract pathname. + * @exception SecurityException If the user is denied access to the file. + **/ + @Override + public boolean setWritable(boolean writable, boolean ownerOnly) throws SecurityException + { + try { + return ifsFile_.setAccess(IFSFile.ACCESS_WRITE, writable, ownerOnly); + } + catch (AS400SecurityException e) { + Trace.log(Trace.ERROR, e); + throw new SecurityException(e); + } + catch (IOException e) { + if (Trace.traceOn_) Trace.log(Trace.ERROR, e); + return false; + } + } + + /** + * Returns a string representation of this object. + * + * @return A string giving the path name of this object. + **/ + @Override + public String toString() + { + if (replace_) + return ifsFile_.toString().replace(AS400_SEPARATOR, separatorChar); + + return ifsFile_.toString(); + } + + /** + * Converts the abstract path name into a file: URL. The IBM i file/directory will be accessed and if + * it is a directory the resulting URL will end with the IBM i separator character (forward slash). The system name + * will be obtained from the AS400 object. If the path name or AS400 object has not been set, a NullPointerException + * will be thrown. + * + * @return The URL form of the abstract path name of this object. + * + * @exception MalformedURLException If the URL cannot be formed. + * + **/ + @Override + public URL toURL() throws MalformedURLException + { + String objectName = null; + + if (isDirectory()) + objectName = getAbsolutePath() + separatorChar; + else + objectName = getAbsolutePath(); + + return new URL(URL_PROTOCOL, getSystem().getSystemName(), objectName); } - else return false; - } - -/** - * Indicates if the IFSJavaFile is a directory. - * - * @return true if the IFSJavaFile exists and is a directory; false otherwise. - * @exception SecurityException If the user is denied access to the file. -**/ - public boolean isDirectory() - throws SecurityException - { - int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; - try - { - returnCode = ifsFile_.isDirectory0(); - if (returnCode == IFSReturnCodeRep.ACCESS_DENIED_TO_DIR_ENTRY - || returnCode == IFSReturnCodeRep.ACCESS_DENIED_TO_REQUEST) - { - throw new SecurityException(ResourceBundleLoader.getText(mapRC(returnCode))); - } - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, e); - throw new SecurityException(e); - } - catch (IOException e) - { - if (Trace.traceOn_) Trace.log(Trace.ERROR, e); - return false; - } - return (returnCode == IFSReturnCodeRep.SUCCESS); - } - -/** - * Indicates if the IFSJavaFile is a "normal" file.
- * A file is "normal" if it is not a directory or a container of other objects. - * - * @return true if the specified file exists and is a "normal" file; false otherwise. - * @exception SecurityException If the user is denied access to the file. -**/ - public boolean isFile() - throws SecurityException - { - int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; - try - { - returnCode = ifsFile_.isFile0(); - if (returnCode == IFSReturnCodeRep.ACCESS_DENIED_TO_DIR_ENTRY - || returnCode == IFSReturnCodeRep.ACCESS_DENIED_TO_REQUEST) - { - throw new SecurityException(ResourceBundleLoader.getText(mapRC(returnCode))); - } - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, e); - throw new SecurityException(e); - } - catch (IOException e) - { - if (Trace.traceOn_) Trace.log(Trace.ERROR, e); - return false; - } - return (returnCode == IFSReturnCodeRep.SUCCESS); - } - - -/** - * Indicates if the IFSJavaFile is hidden. On the IBM i system, a file is - * hidden if its hidden attribute is set. - * - * @return true if the file is hidden; false otherwise. - * @exception SecurityException If the user is denied access to the file. -**/ - public boolean isHidden() - throws SecurityException - { - try - { - return ifsFile_.isHidden(); - } - catch (AS400SecurityException e) - { - throw new SecurityException(e); - } - catch (IOException e) - { - if (Trace.traceOn_) Trace.log(Trace.ERROR, e); - return false; - } - } - - -/** - * Indicates the time that the IFSJavaFile was last modified. - * - * @return The time (measured in milliseconds since - * 01/01/1970 00:00:00 GMT) that the IFSJavaFile was - * last modified, or 0 if it does not exist. - * @exception SecurityException If the user is denied access to the file. -**/ - public long lastModified() - throws SecurityException - { - try - { - return ifsFile_.lastModified0(); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, e); - throw new SecurityException(e); - } - catch (IOException e) - { - if (Trace.traceOn_) Trace.log(Trace.ERROR, e); - return 0L; - } - } - -/** - * Indicates the length of this IFSJavaFile. - * - * @return The length, in bytes, of the IFSJavaFile, - * or 0((IFSJavaFile) if it does not exist. - * @exception SecurityException If the user is denied access to the file. -**/ - public long length() - throws SecurityException - { - try - { - // For the listFiles() methods, the IFS File Server reports the length of - // a symbolic link rather than the length of the target object. Circumvention - // is to clear the ifsFile cache and re-retrieve the attributes from the IFS - // File Server. When not using wild-cards the IFS File Server always follows - // symlnk objects and returns the attributes of the target object. - if (ifsFile_.isSymbolicLink()) //@B1A - ifsFile_.clearCachedAttributes(); //@B1A - return ifsFile_.length0(); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, e); - throw new SecurityException(e); - } - catch (IOException e) - { - if (Trace.traceOn_) Trace.log(Trace.ERROR, e); - return 0L; - } - } - -/** - * Lists the files in this IFSJavaFile directory. - * - * @return An array of object names in the directory. - * This list does not include the current directory - * or the parent directory. If this IFSJavaFile is not - * a directory, null is returned. - * If this IFSJavaFile is an empty directory, - * an empty string array is returned. - * @see #listFiles() - * @exception SecurityException If the user is denied access to the file. -**/ - public String[] list() - throws SecurityException - { - try - { - return ifsFile_.list0(null, "*"); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, e); - throw new SecurityException(e); - } - catch (IOException e) - { - if (Trace.traceOn_) Trace.log(Trace.ERROR, e); - return new String[0]; - } - } - -/** - * Lists the files in this IFSJavaFile directory that satisfy filter. - * - * @param filter The file name filter. - * - * @return An array of object names in the directory that satisfy - * the file name filter. This list does not include the current - * directory or the parent directory. If this IFSJavaFile is not - * a directory, null is returned. If this IFSJavaFile is an empty - * directory, or the file name filter does - * not match any files, an empty string array is returned. - * The IFSJavaFile object passed to the file name filter object have cached - * file attribute information. Maintaining references to these - * IFSJavaFile objects after the list operation increases the - * chances that their file attribute information will not be valid. - *

- * The following example demonstrates the use of this method: - *

- *  class AcceptClass implements java.io.FilenameFilter
- *  {
- *    public boolean accept(java.io.File dir, java.lang.String name)
- *    {
- *      if (name.startsWith("IFS"))
- *        return true;
- *      return false;
- *    }
- *  }
- * 
- * IFSJavaFile file = new IFSJavaFile(new AS400("enterprise"), path); - * AcceptClass ac = new AcceptClass(); - * file.list(ac); - *
- * @exception SecurityException If the user is denied access to the file. - * @see #listFiles(FilenameFilter) -**/ - public String[] list(FilenameFilter filter) - throws SecurityException - { - String names[] = null; - - try - { - names = ifsFile_.list0(null, "*"); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, e); - throw new SecurityException(e); - } - catch (IOException e) - { - if (Trace.traceOn_) Trace.log(Trace.ERROR, e); - return null; - } - - if (names == null) - { - return null; - } - - // Fill in the Vector - Vector v = new Vector(); - for (int i = 0 ; i < names.length ; i++) - { - if ((filter == null) || filter.accept(this, names[i])) - { - v.addElement(names[i]); - } - } - - // Create the array - String files[] = new String[v.size()]; - v.copyInto(files); - - return files; - } - -/** - * Lists the files in the IFSJavaFile directory that satisfy file name filter. - * - * @param filter The file name filter. - * - * @return An array of object names in the directory that - * satisfy the file name filter. This list does not include the current - * directory or the parent directory. - * If this IFSJavaFile is not a directory, null is - * returned. If this IFSJavaFile is an empty directory, or - * the file name filter does not match any files, an empty string array - * is returned. The IFSFile object passed to the file name filter object - * have cached file attribute information. Maintaining - * references to these IFSFile objects after the list operation - * increases the chances that their file attribute information - * will not be valid. - *

- * The following example demonstrates the use of this method: - *

- *  class AcceptClass implements IFSFileFilter
- *  {
- *    public boolean accept(IFSFile file)
- *    {
- *      if (file.getName().startsWith("IFS"))
- *        return true;
- *      return false;
- *    }
- *  }
- * 
- * IFSJavaFile file = new IFSJavaFile(new AS400("enterprise"), path); - * AcceptClass ac = new AcceptClass(); - * file.list(ac); - * - *
- * @exception SecurityException If the user is denied access to the file. - * @see #listFiles(IFSFileFilter) -**/ - public String[] list(IFSFileFilter filter) - throws SecurityException - { - try - { - return ifsFile_.list0(filter,"*"); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, e); - throw new SecurityException(e); - } - catch (IOException e) - { - if (Trace.traceOn_) Trace.log(Trace.ERROR, e); - return new String[0]; - } - } - -/** - * Lists the files in this IFSJavaFile directory that satisfy filter and pattern. - * - *

Note:
If the file does not match pattern, it will not be processed by filter. - * - * @param filter The file name filter. - * @param pattern The pattern that all filenames must match. Acceptable characters are - * wildcards (* - matches multiple characters) and question marks (? - matches - * one character). Pattern must not be null. - * - * @return An array of object names in the directory that satisfy the file name filter - * and pattern. This list does not include the current directory or the parent - * directory. If this IFSJavaFile is not a directory, null is returned. If this - * IFSJavaFile is an empty directory, or the file name filter or pattern does not - * match any files, an empty string array is returned. The IFSFile object passed - * to the file name filter object have cached file attribute information. - * Maintaining references to these IFSFile objects after the list operation - * increases the chances that their file attribute information will not be valid. - * @exception SecurityException If the user is denied access to the file. - * @see #listFiles(IFSFileFilter,String) -**/ - public String[] list(IFSFileFilter filter, String pattern) - throws SecurityException - { - if (pattern == null) - throw new NullPointerException("pattern"); - - try - { - return ifsFile_.list0(filter, pattern); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, e); - throw new SecurityException(e); - } - catch (IOException e) - { - if (Trace.traceOn_) Trace.log(Trace.ERROR, e); - return new String[0]; - } - } - -/** - * Lists the files in this IFSJavaFile directory that match pattern. - * - * @param pattern The pattern that all filenames must match. - * Acceptable characters are wildcards (* - matches - * multiple characters) and question marks (? - matches - * one character). - * - * @return An array of object names in the directory that match - * the pattern. This list does not include the current - * directory or the parent directory. If this IFSJavaFile - * is not a directory, null is returned. If this IFSJavaFile - * is an empty directory, or the pattern does not match any - * files, an empty string array is returned. - * @exception SecurityException If the user is denied access to the file. - * @see #listFiles(String) -**/ - public String[] list(String pattern) - throws SecurityException - { - if (pattern == null) - throw new NullPointerException("pattern"); - - try - { - return ifsFile_.list0(null,pattern); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, e); - throw new SecurityException(e); - } - catch (IOException e) - { - if (Trace.traceOn_) Trace.log(Trace.ERROR, e); - return new String[0]; - } - } - - -//@A3A Added support for IFSFile.listFiles(). -/** - * Lists the files in this IFSJavaFile directory. - * With the use of this function, attribute information is cached and - * will not be refreshed from the IBM i system. This means attribute information may - * become inconsistent with the IBM i system. - * @return An array of objects in the directory. - * This list does not include the current directory - * or the parent directory. If this IFSJavaFile is not - * a directory, null is returned. - * If this IFSJavaFile is an empty directory, - * an empty object array is returned. - * @exception SecurityException If the user is denied access to the file. - * @see #list() -**/ - public File[] listFiles() - throws SecurityException - { - return listFiles(null,"*"); - } - -//@A3A Added support for IFSFile.listFiles(). -/** - * Lists the files in this IFSJavaFile directory that satisfy filter. - * With the use of this function, attribute information is cached and - * will not be refreshed from the IBM i system. This means attribute information may - * become inconsistent with the IBM i system. - * - * @param filter The file name filter. - * - * @return An array of objects in the directory that satisfy - * the file name filter. This list does not include the current - * directory or the parent directory. If this IFSJavaFile is not - * a directory, null is returned. If this IFSJavaFile is an empty - * directory, or the file name filter does - * not match any files, an empty object array is returned. - * The IFSJavaFile object passed to the file name filter object has cached - * file attribute information. Maintaining references to these - * IFSJavaFile objects after the list operation increases the - * chances that their file attribute information will not be valid. - *

- * The following example demonstrates the use of this method: - *

- *  class AcceptClass implements java.io.FilenameFilter
- *  {
- *    public boolean accept(java.io.File dir, java.lang.String name)
- *    {
- *      if (name.startsWith("IFS"))
- *        return true;
- *      return false;
- *    }
- *  }
- * 
- * IFSJavaFile file = new IFSJavaFile(new AS400("enterprise"), path); - * AcceptClass ac = new AcceptClass(); - * file.listFiles(ac); - *
- * @exception SecurityException If the user is denied access to the file. - * @see #list(FilenameFilter) -**/ - public File[] listFiles(FilenameFilter filter) - throws SecurityException - { - IFSFile[] files = null; - try - { - files = ifsFile_.listFiles0(null, "*"); // @D2C @C3C - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, e); - throw new SecurityException(e); - } - catch (IOException e) - { - if (Trace.traceOn_) Trace.log(Trace.ERROR, e); - return null; - } - - if (files == null) - { - return null; - } - - // Fill in the Vector - Vector v = new Vector(); - for (int i = 0 ; i < files.length ; i++) - { - if ((filter == null) || filter.accept(this, files[i].getName())) - { - //v.addElement(files[i]); // @A6d - v.addElement(new IFSJavaFile(files[i])); // @A6a - } - } - - // Create the array - IFSJavaFile newFiles[] = new IFSJavaFile[v.size()]; // @A6c -/* @A6d - for (int i = 0; i < files.length; i++) - { - newFiles[i] = new IFSJavaFile(files[i]); - } -*/ - v.copyInto(newFiles); // @A6a - - return newFiles; - } - -// @A7a -/** - * Lists the files in this IFSJavaFile directory that satisfy filter. - * With the use of this function, attribute information is cached and - * will not be refreshed from the IBM i system. This means attribute information may - * become inconsistent with the IBM i system. - * - * @param filter The file filter. - * - * @return An array of objects in the directory that satisfy - * the file filter. This list does not include the current - * directory or the parent directory. If this IFSJavaFile is not - * a directory, null is returned. If this IFSJavaFile is an empty - * directory, or the file filter does - * not match any files, an empty object array is returned. - * The IFSJavaFile object passed to the file filter object has cached - * file attribute information. Maintaining references to these - * IFSJavaFile objects after the list operation increases the - * chances that their file attribute information will not be valid. - *

- * The following example demonstrates the use of this method: - *

- *  class AcceptClass implements java.io.FileFilter
- *  {
- *    public boolean accept(java.io.File file)
- *    {
- *      if (file.getName().startsWith("IFS"))
- *        return true;
- *      return false;
- *    }
- *  }
- * 
- * IFSJavaFile file = new IFSJavaFile(new AS400("enterprise"), path); - * AcceptClass ac = new AcceptClass(); - * file.listFiles(ac); - *
- * @exception SecurityException If the user is denied access to the file. -**/ - public File[] listFiles(FileFilter filter) - throws SecurityException - { - IFSFile[] files = null; - try - { - files = ifsFile_.listFiles0(null, "*"); // @C3C - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, e); - throw new SecurityException(e); - } - catch (IOException e) - { - if (Trace.traceOn_) Trace.log(Trace.ERROR, e); - return null; - } - - if (files == null) - { - return null; - } - - // Fill in the Vector - Vector v = new Vector(); - for (int i = 0 ; i < files.length ; i++) - { - IFSJavaFile file = new IFSJavaFile(files[i]); - if ((filter == null) || filter.accept(file)) - { - v.addElement(file); - } - } - - // Create the array - IFSJavaFile newFiles[] = new IFSJavaFile[v.size()]; - v.copyInto(newFiles); - - return newFiles; - } - -//@A3A Added support for IFSFile.listFiles(). -/** - * Lists the files in the IFSJavaFile directory that satisfy file name filter. - * With the use of this function, attribute information is cached and - * will not be refreshed from the IBM i system. This means attribute information may - * become inconsistent with the IBM i system. - * @param filter The file name filter. - * - * @return An array of objects in the directory that - * satisfy the file name filter. This list does not include the current - * directory or the parent directory. - * If this IFSJavaFile is not a directory, null is - * returned. If this IFSJavaFile is an empty directory, or - * the file name filter does not match any files, an empty object array - * is returned. The IFSFile object passed to the file name filter object - * has cached file attribute information. Maintaining - * references to these IFSFile objects after the list operation - * increases the chances that their file attribute information - * will not be valid. - *

- * The following example demonstrates the use of this method: - *

- *  class AcceptClass implements IFSFileFilter
- *  {
- *    public boolean accept(IFSFile file)
- *    {
- *      if (file.getName().startsWith("IFS"))
- *        return true;
- *      return false;
- *    }
- *  }
- * 
- * IFSJavaFile file = new IFSJavaFile(new AS400("enterprise"), path); - * AcceptClass ac = new AcceptClass(); - * file.listFiles(ac); - * - *
- * @exception SecurityException If the user is denied access to the file. - * @see #list(IFSFileFilter) -**/ - public File[] listFiles(IFSFileFilter filter) - throws SecurityException - { - return listFiles(filter,"*"); - } - -//@A3A Added support for IFSFile.listFiles(). -/** - * Lists the files in this IFSJavaFile directory that satisfy filter and - * pattern. With the use of this function, attribute information is cached and - * will not be refreshed from the IBM i system. This means attribute information may - * become inconsistent with the IBM i system. - * - *

Note:
If the file does not match pattern, it will not be processed by filter. - * - * @param filter The file name filter. - * @param pattern The pattern that all filenames must match. Acceptable characters are - * wildcards (* - matches multiple characters) and question marks (? - matches - * one character). Pattern must not be null. - * - * @return An array of objects in the directory that satisfy the file name filter - * and pattern. This list does not include the current directory or the parent - * directory. If this IFSJavaFile is not a directory, null is returned. If this - * IFSJavaFile is an empty directory, or the file name filter or pattern does not - * match any files, an empty object array is returned. The IFSFile object passed - * to the file name filter object has cached file attribute information. - * Maintaining references to these IFSFile objects after the list operation - * increases the chances that their file attribute information will not be valid. - * @exception SecurityException If the user is denied access to the file. - * @see #list(IFSFileFilter,String) -**/ - public File[] listFiles(IFSFileFilter filter, String pattern) - throws SecurityException - { - if (pattern == null) - throw new NullPointerException("pattern"); - - try - { - IFSFile files[] = ifsFile_.listFiles0(filter,pattern); // @D2C @C3C - IFSJavaFile newFiles[] = new IFSJavaFile[files.length]; - for (int i = 0; i < files.length; i++) - { - newFiles[i] = new IFSJavaFile(files[i]); - } - return newFiles; - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, e); - throw new SecurityException(e); - } - catch (IOException e) - { - if (Trace.traceOn_) Trace.log(Trace.ERROR, e); - return new IFSJavaFile[0]; - } - } - -//@A3A Added support for IFSFile.listFiles(). -/** - * Lists the files in this IFSJavaFile directory that match pattern. - * With the use of this function, attribute information is cached and - * will not be refreshed from the IBM i system. This means attribute information may - * become inconsistent with the IBM i system. - * - * @param pattern The pattern that all filenames must match. - * Acceptable characters are wildcards (* - matches - * multiple characters) and question marks (? - matches - * one character). - * - * @return An array of object names in the directory that match - * the pattern. This list does not include the current - * directory or the parent directory. If this IFSJavaFile - * is not a directory, null is returned. If this IFSJavaFile - * is an empty directory, or the pattern does not match any - * files, an empty string array is returned. - * @exception SecurityException If the user is denied access to the file. - * @see #list(String) -**/ - public File[] listFiles(String pattern) - throws SecurityException - { - if (pattern == null) - throw new NullPointerException("pattern"); - - return listFiles(null, pattern); - } - - -/** - * Lists the file system roots for the integrated file system - * of the IBM i system. The IBM i integrated file system has - * only one root -- "/". - * - * @return An array of IFSJavaFile objects that represent the - * file system roots of the integrated file system - * of the IBM i system. Since the IBM i integrated file system - * has only one root, the returned - * array contains only one element. -**/ - public static File[] listRoots() - { - IFSJavaFile[] roots = new IFSJavaFile[1]; - //roots[0] = new IFSJavaFile(IFSFile.separator); // @A6d - roots[0] = new IFSJavaFile(File.separator); // @A6c - return roots; - } - - - -// convert return code to string for mri file - private String mapRC(int returnCode) - { - if (returnCode== IFSReturnCodeRep.ACCESS_DENIED_TO_DIR_ENTRY) - { - return "EXC_ACCESS_DENIED"; - } else - if (returnCode == IFSReturnCodeRep.ACCESS_DENIED_TO_REQUEST) - { - return "EXC_REQUEST_DENIED"; - } - return "EXC_UNKNOWN"; // Bad return code was provided. - } - -/** - * Creates a directory whose path name - * is specified by this IFSJavaFile. - - * - * @return true if the directory could be created; - * false otherwise. - * @exception SecurityException If the user is denied access to the file. -**/ - public boolean mkdir() - throws SecurityException - { - int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; - try - { - returnCode = ifsFile_.mkdir0(ifsFile_.getAbsolutePath()); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, e); - throw new SecurityException(e); - } - catch (IOException e) - { - if (Trace.traceOn_) Trace.log(Trace.ERROR, e); - return false; - } - return (returnCode == IFSReturnCodeRep.SUCCESS); - } - -/** - * Creates a directory whose path name is - * specified by this IFSJavaFile, including any necessary - * parent directories. - * - * @return true if the directory (or directories) could be - * created; false otherwise. - * @exception SecurityException If the user is denied access to the file. -**/ - public boolean mkdirs() - throws SecurityException - { - int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; - try - { - returnCode = ifsFile_.mkdirs0(); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, e); - throw new SecurityException(e); - } - catch (IOException e) - { - if (Trace.traceOn_) Trace.log(Trace.ERROR, e); - return false; - } - return (returnCode == IFSReturnCodeRep.SUCCESS); - } - -/** - * Renames the IFSJavaFile to have the path name of dest. - * Wildcards are not permitted in this file name. - * - * @param dest The new filename. - * - * @return true if the renaming succeeds; - * false otherwise. - * @exception SecurityException If the user is denied access to the file. -**/ - public boolean renameTo(IFSJavaFile dest) - throws SecurityException - { - if (dest == null) - throw new NullPointerException("dest"); - - int returnCode = IFSReturnCodeRep.FILE_NOT_FOUND; - IFSFile lFile = new IFSFile(); - - try - { - lFile.setSystem(dest.getSystem()); - String destPath = dest.getPath(); //@P2A - lFile.setPath(replace_ ? destPath.replace(separatorChar, AS400_SEPARATOR) : destPath); //@P2C - returnCode = ifsFile_.renameTo0(lFile); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, e); - throw new SecurityException(e); - } - catch (PropertyVetoException e) {} // will never happen - catch (IOException e) - { - if (Trace.traceOn_) Trace.log(Trace.ERROR, e); - return false; - } - return (returnCode == IFSReturnCodeRep.SUCCESS); - } - -// @A7a -/** - * Renames the IFSJavaFile to have the path name of dest. - * Wildcards are not permitted in this file name. - * - * @param dest An object specifying the new filename. - * If this object is not an IFSJavaFile, the rename will fail. - * - * @return true if the renaming succeeds; - * false otherwise. - * @exception SecurityException If the user is denied access to the file. -**/ - public boolean renameTo(File dest) - throws SecurityException - { - try { - return renameTo((IFSJavaFile)dest); - } - catch (ClassCastException e) { - Trace.log(Trace.ERROR, e); - return false; - } - } - - -/** - * Sets the last modified time of the file named by this - * IFSJavaFile object. - * - * @param time The new last modified time, measured in milliseconds since - * 00:00:00 GMT, January 1, 1970. - * If -1, sets the last modified time to the current system time. - * @return true if the time is set; false otherwise. - * @exception SecurityException If the user is denied access to the file. -**/ - public boolean setLastModified(long time) - throws SecurityException - { - try - { - return ifsFile_.setLastModified0(time); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, e); - throw new SecurityException(e); - } - catch (IOException e) - { - if (Trace.traceOn_) Trace.log(Trace.ERROR, e); - return false; - } - } - - // @B8a - /** - * Sets the length of the file named by this - * IFSJavaFile object. The file can be made larger or smaller. - * If the file is made larger, the contents of the new bytes - * of the file are undetermined. - * @param length The new length, in bytes. - * @return true if successful; false otherwise. - * @exception SecurityException If the user is denied access to the file. - **/ - public boolean setLength(int length) - throws SecurityException - { - try - { - return ifsFile_.setLength0(length); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, e); - throw new SecurityException(e); - } - catch (IOException e) - { - if (Trace.traceOn_) Trace.log(Trace.ERROR, e); - return false; - } - } - - -/** - * Sets the path for this IFSJavaFile. - * - * @param path The absolute file path. - * - * @return true if the path was set; - * false otherwise. -**/ - public boolean setPath(String path) - { - if (path == null) - { - throw new NullPointerException("path"); - } - - try - { - ifsFile_.setPath(replace_ ? path.replace(separatorChar, AS400_SEPARATOR) : path); //@P2C - absolute_ = isAbsolutePath(path); - } - catch (PropertyVetoException e) {} // will never happen - return true; - } - - - /** - Sets the pattern-matching behavior used when files are listed by any of the list() or listFiles() methods. The default is PATTERN_POSIX. - @param patternMatching Either {@link IFSFile#PATTERN_POSIX PATTERN_POSIX}, {@link IFSFile#PATTERN_POSIX_ALL PATTERN_POSIX_ALL}, or {@link IFSFile#PATTERN_OS2 PATTERN_OS2} - * @throws IOException If an error occurs while communicating with the system. - - @exception ConnectionDroppedException If the connection is dropped unexpectedly. - @exception ExtendedIOException If an error occurs while communicating with the system. - @exception ServerStartupException If the host server cannot be started. - **/ - public void setPatternMatching(int patternMatching) - throws IOException - { - ifsFile_.setPatternMatching(patternMatching); - } - - -/** - * Marks the file named by this IFSJavaFile object so that only - * read operations are allowed. On the IBM i system, a file is marked - * read only by setting the read only attribute of the file. - * - * @return true if the read only attribute is set; false otherwise. - * @exception SecurityException If the user is denied access to the file. -**/ - public boolean setReadOnly() - throws SecurityException - { - try - { - return ifsFile_.setReadOnly0(true); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, e); - throw new SecurityException(e); - } - catch (IOException e) - { - if (Trace.traceOn_) Trace.log(Trace.ERROR, e); - return false; - } - } - - - -/** - * Sets the system. - * - * @param system The system object. - * - * @return true if the system was set; - * false otherwise. -**/ - public boolean setSystem(AS400 system) - { - if (system == null) - { - throw new NullPointerException("system"); - } - - try - { - ifsFile_.setSystem(system); - } - catch (PropertyVetoException e) {} // will never happen - return true; - } - - - /** - A convenience method to set the owner's execute permission for this abstract pathname. - This method is supported for IBM i V5R1 and higher. For older releases, it simply returns false. -

- An invocation of this method of the form file.setExcutable(arg) behaves in exactly the same way as the invocation file.setExecutable(arg, true) - - @param executable If true, sets the access permission to allow execute operations; if false, to disallow execute operations. - @return true if and only if the operation succeeded. The operation will fail if the user does not have permission to change the access permissions of this abstract pathname. - @exception SecurityException If the user is denied access to the file. - **/ - public boolean setExecutable(boolean executable) - throws SecurityException - { - return setExecutable(executable, true); - } - - - /** - Sets the owner's or everybody's execute permission for this abstract pathname. - This method is supported for IBM i V5R1 and higher. For older releases, it simply returns false. - - @param executable If true, sets the access permission to allow execute operations; if false, to disallow execute operations. - @param ownerOnly If true, the execute permission applies only to the owner's execute permission; otherwise, it applies to everybody. - @return true if and only if the operation succeeded. The operation will fail if the user does not have permission to change the access permissions of this abstract pathname. - @exception SecurityException If the user is denied access to the file. - **/ - public boolean setExecutable(boolean executable, - boolean ownerOnly) - throws SecurityException - { - try - { - return ifsFile_.setAccess(IFSFile.ACCESS_EXECUTE, executable, ownerOnly); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, e); - throw new SecurityException(e); - } - catch (IOException e) - { - if (Trace.traceOn_) Trace.log(Trace.ERROR, e); - return false; - } - } - - - /** - A convenience method to set the owner's read permission for this abstract pathname. - This method is supported for IBM i V5R1 and higher. For older releases, it simply returns false. -

- An invocation of this method of the form file.setReadable(arg) behaves in exactly the same way as the invocation file.setReadable(arg, true) - - @param readable If true, sets the access permission to allow read operations; if false, to disallow read operations. - @return true if and only if the operation succeeded. The operation will fail if the user does not have permission to change the access permissions of this abstract pathname. - @exception SecurityException If the user is denied access to the file. - **/ - public boolean setReadable(boolean readable) - throws SecurityException - { - return setReadable(readable, true); - } - - - /** - Sets the owner's or everybody's read permission for this abstract pathname. - This method is supported for IBM i V5R1 and higher. For older releases, it simply returns false. - - @param readable If true, sets the access permission to allow read operations; if false, to disallow read operations. - @param ownerOnly If true, the read permission applies only to the owner's read permission; otherwise, it applies to everybody. - @return true if and only if the operation succeeded. The operation will fail if the user does not have permission to change the access permissions of this abstract pathname. - @exception SecurityException If the user is denied access to the file. - **/ - public boolean setReadable(boolean readable, - boolean ownerOnly) - throws SecurityException - { - try - { - return ifsFile_.setAccess(IFSFile.ACCESS_READ, readable, ownerOnly); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, e); - throw new SecurityException(e); - } - catch (IOException e) - { - if (Trace.traceOn_) Trace.log(Trace.ERROR, e); - return false; - } - } - - - /** - A convenience method to set the owner's write permission for this abstract pathname. - This method is supported for IBM i V5R1 and higher. For older releases, it simply returns false. -

- An invocation of this method of the form file.setWritable(arg) behaves in exactly the same way as the invocation file.setWritable(arg, true) - - @param writable If true, sets the access permission to allow write operations; if false to disallow write operations - @return true if and only if the operation succeeded. The operation will fail if the user does not have permission to change the access permissions of this abstract pathname. - @exception SecurityException If the user is denied access to the file. - **/ - public boolean setWritable(boolean writable) - throws SecurityException - { - return setWritable(writable, true); - } - - - /** - Sets the owner's or everybody's write permission for this abstract pathname. - This method is supported for IBM i V5R1 and higher. For older releases, it simply returns false. - - @param writable If true, sets the access permission to allow write operations; if false, to disallow write operations. - @param ownerOnly If true, the write permission applies only to the owner's write permission; otherwise, it applies to everybody. - @return true if and only if the operation succeeded. The operation will fail if the user does not have permission to change the access permissions of this abstract pathname. - @exception SecurityException If the user is denied access to the file. - **/ - public boolean setWritable(boolean writable, - boolean ownerOnly) - throws SecurityException - { - try - { - return ifsFile_.setAccess(IFSFile.ACCESS_WRITE, writable, ownerOnly); - } - catch (AS400SecurityException e) - { - Trace.log(Trace.ERROR, e); - throw new SecurityException(e); - } - catch (IOException e) - { - if (Trace.traceOn_) Trace.log(Trace.ERROR, e); - return false; - } - } - - - -/** - * Returns a string representation of this object. - * - * @return A string giving the path name of this object. -**/ - public String toString() - { - if (replace_) - { - return ifsFile_.toString().replace(AS400_SEPARATOR, separatorChar); - } - else { - return ifsFile_.toString(); - } - -// return replace_ ? ifsFile_.toString().replace(AS400_SEPARATOR, separatorChar) : ifsFile_.toString(); //@P2C - } - - -/** - * Converts the abstract path name into a file: URL. - * The IBM i file/directory will be accessed and if it is a directory the - * resulting URL will end with the IBM i separator character - * (forward slash). The system name will be obtained from - * the AS400 object. If the path name or AS400 object has - * not been set, a NullPointerException will be thrown. - * - * @return The URL form of the abstract path name of this object. - * - * @exception MalformedURLException If the URL cannot be formed. - * -**/ - public URL toURL() throws MalformedURLException - { - String objectName = null; - - if (isDirectory()) - objectName = getAbsolutePath() + separatorChar; - else - objectName = getAbsolutePath(); - - return new URL(URL_PROTOCOL, getSystem().getSystemName(), objectName); - } - - - } diff --git a/src/main/java/com/ibm/as400/access/IFSListAttrsRep.java b/src/main/java/com/ibm/as400/access/IFSListAttrsRep.java index 87c25b17..2f2231d1 100644 --- a/src/main/java/com/ibm/as400/access/IFSListAttrsRep.java +++ b/src/main/java/com/ibm/as400/access/IFSListAttrsRep.java @@ -18,448 +18,455 @@ /** -List file attributes reply. -**/ + * List file attributes reply. + **/ class IFSListAttrsRep extends IFSDataStream { - // Used for debugging only. This should always be false for production. - // When this is false, all debug code will theoretically compile out. @A3a - private static final boolean DEBUG = false; - - static final int FILE = 1; - static final int DIRECTORY = 2; - static final int SYMBOLIC_LINK = 3; - static final int AS400_OBJECT = 4; - static final int DEVICE_FIFO = 5; - static final int DEVICE_CHAR = 6; - static final int DEVICE_BLOCK = 7; - static final int SOCKET = 8; - - static final int FA_READONLY = 0x01; //@D1a - static final int FA_HIDDEN = 0x02; //@D1a - static final int FA_SYSTEM = 0x04; //@D1a - static final int FA_DIRECTORY = 0x10; - static final int FA_ARCHIVE = 0x20; //@D1a - - static final int OA_NONE = IFSListAttrsReq.OA_NONE; - static final int OA1 = IFSListAttrsReq.OA1; - static final int OA2 = IFSListAttrsReq.OA2; - - private static final int TEMPLATE_LENGTH_OFFSET = 16; - - private static final int HEADER_LENGTH = 20; - private static final int LLCP_LENGTH = 6; - - // Note: The following offsets are valid only if template length >= 61. - private static final int CREATE_DATE_OFFSET = 22; - private static final int MODIFY_DATE_OFFSET = 30; - private static final int ACCESS_DATE_OFFSET = 38; - private static final int FILE_SIZE_OFFSET = 46; - private static final int FIXED_ATTRS_OFFSET = 50; - private static final int OBJECT_TYPE_OFFSET = 54; - private static final int NUM_EXT_ATTRS_OFFSET = 56; - private static final int BYTES_EA_NAMES_OFFSET = 58; - private static final int BYTES_EA_VALUES_OFFSET = 62; - private static final int VERSION_NUMBER_OFFSET = 66; - private static final int AMOUNT_ACCESSED_OFFSET = 70; - private static final int ACCESS_HISTORY_OFFSET = 72; - private static final int NAME_CCSID_OFFSET = 73; // CCSID of the file/path name - private static final int CHECKOUT_CCSID_OFFSET = 75; - private static final int RESTART_ID_OFFSET = 77; - - // Additional fields if datastreamLevel >= 8: - private static final int LARGE_FILE_SIZE_OFFSET = 81; - private static final int SYMBOLIC_LINK_OFFSET = 91; - - //@AC7 - private static final int FILE_SYSTEM_TYPE_OFFSET = 89; - private static final int UNINITIALIZED = -1; + // Used for debugging only. This should always be false for production. + private static final boolean DEBUG = false; + + static final int FILE = 1; + static final int DIRECTORY = 2; + static final int SYMBOLIC_LINK = 3; + static final int AS400_OBJECT = 4; + static final int DEVICE_FIFO = 5; + static final int DEVICE_CHAR = 6; + static final int DEVICE_BLOCK = 7; + static final int SOCKET = 8; + + static final int FA_READONLY = 0x01; + static final int FA_HIDDEN = 0x02; + static final int FA_SYSTEM = 0x04; + static final int FA_DIRECTORY = 0x10; + static final int FA_ARCHIVE = 0x20; + + static final int OA_NONE = IFSListAttrsReq.OA_NONE; + static final int OA1 = IFSListAttrsReq.OA1; + static final int OA2 = IFSListAttrsReq.OA2; + + private static final int TEMPLATE_LENGTH_OFFSET = 16; + + private static final int HEADER_LENGTH = 20; + private static final int LLCP_LENGTH = 6; + + // Note: The following offsets are valid only if template length >= 61. + private static final int CREATE_DATE_OFFSET = 22; + private static final int MODIFY_DATE_OFFSET = 30; + private static final int ACCESS_DATE_OFFSET = 38; + private static final int FILE_SIZE_OFFSET = 46; + private static final int FIXED_ATTRS_OFFSET = 50; + private static final int OBJECT_TYPE_OFFSET = 54; + private static final int NUM_EXT_ATTRS_OFFSET = 56; + private static final int BYTES_EA_NAMES_OFFSET = 58; + private static final int BYTES_EA_VALUES_OFFSET = 62; + private static final int VERSION_NUMBER_OFFSET = 66; + private static final int AMOUNT_ACCESSED_OFFSET = 70; + private static final int ACCESS_HISTORY_OFFSET = 72; + private static final int NAME_CCSID_OFFSET = 73; // CCSID of the file/path name + private static final int CHECKOUT_CCSID_OFFSET = 75; + private static final int RESTART_ID_OFFSET = 77; + + // Additional fields if datastreamLevel >= 8: + private static final int LARGE_FILE_SIZE_OFFSET = 81; + private static final int SYMBOLIC_LINK_OFFSET = 91; + + private static final int FILE_SYSTEM_TYPE_OFFSET = 89; + private static final int UNINITIALIZED = -1; + + /** + * Construct a list file attributes reply. + **/ + IFSListAttrsRep() + { + } + /** + * Generate a new instance of this type. + * + * @return a reference to the new instance + **/ + public Object getNewDataStream() { + return new IFSListAttrsRep(); + } -/** -Construct a list file attributes reply. -**/ - IFSListAttrsRep() - { - } + /** + * Get the date/time that the file was last accessed. + * + * @return the date/time (measured as milliseconds since midnight January 1, 1970) of the last access + **/ + long getAccessDate() { + return getDate(ACCESS_DATE_OFFSET); + } -/** -Generate a new instance of this type. -@return a reference to the new instance -**/ - public Object getNewDataStream() - { - return new IFSListAttrsRep(); - } + /** + * Get the CCSID value for the IFS file on the server. + * + * @return the CCSID value for the IFS file on the server + **/ + int getCCSID(int datastreamLevel) { + // Get the 'CCSID of the object' field from the OA2 structure in the reply. + return getObjAttrs2().getCCSID(datastreamLevel); + } -/** -Get the date/time that the file was last accessed. -@return the date/time (measured as milliseconds since midnight January 1, 1970) of the last access -**/ - long getAccessDate() - { - return getDate(ACCESS_DATE_OFFSET); - } - - - /** - Get the CCSID value for the IFS file on the server. - @return the CCSID value for the IFS file on the server - **/ - int getCCSID(int datastreamLevel) // @A1A - { - // Get the 'CCSID of the object' field from the OA2 structure in the reply. - return getObjAttrs2().getCCSID(datastreamLevel); - } + /** + * Get the date/time that the file was created. + * + * @return the date/time (measured as milliseconds since midnight January 1, 1970) of creation + **/ + long getCreationDate() { + return getDate(CREATE_DATE_OFFSET); + } -/** -Get the date/time that the file was created. -@return the date/time (measured as milliseconds since midnight January 1, 1970) of creation -**/ - long getCreationDate() - { - return getDate(CREATE_DATE_OFFSET); - } + /** + * Get the extended attribute values, as a hashtable. + * + * @return The extended attribute values. + **/ + Hashtable getExtendedAttributeValues() + { + Hashtable results = new Hashtable(); + + // The offset to the start of the "optional/variable section" depends on the datastream level. + int optionalSectionOffset = HEADER_LENGTH + get16bit(TEMPLATE_LENGTH_OFFSET); + + // Step through the optional fields, looking for the "EA list" field (code point 0x0009). + + int curLL_offset = optionalSectionOffset; + int curLL = get32bit(curLL_offset); // list length + int curCP = get16bit(curLL_offset + 4); // code point + int eaListOffset; // offset to start of Extended Attr list + + while (curCP != 0x0009 && (curLL_offset + curLL + 6 <= data_.length)) + { + curLL_offset += curLL; + curLL = get32bit(curLL_offset); + curCP = get16bit(curLL_offset + 4); + } + + if (curCP == 0x0009) + { + // We found the start of the Extended Attributes list. + eaListOffset = curLL_offset; // offset to "EA List Length" field + } + else + { + if (Trace.isTraceOn()) Trace.log(Trace.DIAGNOSTIC, "No Extended Attributes were returned."); + return results; + } + + byte[] eaVal = null; + int eaCount = get16bit(eaListOffset + 6); // number of EA structures returned + + if (DEBUG) System.out.println("DEBUG Number of EA structures returned: " + eaCount); + // Advance the offset, to point to the start of first repeating EA struct. + int offset = eaListOffset + 8; -/** -Get the extended attribute values, as a hashtable. -@return The extended attribute values. -**/ - Hashtable getExtendedAttributeValues() - { - Hashtable results = new Hashtable(); - - // The offset to the start of the "optional/variable section" depends on the datastream level. - int optionalSectionOffset = HEADER_LENGTH + get16bit(TEMPLATE_LENGTH_OFFSET); - - // Step through the optional fields, looking for the "EA list" field (code point 0x0009). - - int curLL_offset = optionalSectionOffset; - int curLL = get32bit(curLL_offset); // list length - int curCP = get16bit(curLL_offset+4); // code point - int eaListOffset; // offset to start of Extended Attr list - while (curCP != 0x0009 && (curLL_offset+curLL+6 <= data_.length)) - { - curLL_offset += curLL; - curLL = get32bit(curLL_offset); - curCP = get16bit(curLL_offset+4); - } + for (int i = 0; i < eaCount; i++) + { + int eaCcsid = get16bit(offset); // The 2-byte CCSID for the EA name. + int eaNameLL = get16bit(offset + 2); // The 2-byte length of the EA name. + // Note: eaNameLL does *not* include length of the LL field itself. + // int eaFlags = get16bit(offset+4); // The flags for the EA. + int eaValLL = get32bit(offset + 6); // The 4-byte length of the EA value. + // Note: eaValLL includes the 4 "mystery bytes" that precede the name. + byte[] eaName = new byte[eaNameLL]; // The EA name. + System.arraycopy(data_, offset + 10, eaName, 0, eaNameLL); + if (eaValLL <= 4) + { + if (DEBUG) System.out.println("DEBUG Warning: eaValLL<=4: " + eaValLL); + } + else + { + eaVal = new byte[eaValLL - 4]; // omit the 4 leading mystery bytes + System.arraycopy(data_, offset + 10 + eaNameLL + 4, eaVal, 0, eaValLL - 4); + try + { + String eaNameString = CharConverter.byteArrayToString(eaCcsid, eaName); + results.put(eaNameString, eaVal); + + if (Trace.isTraceOn()) Trace.log(Trace.DIAGNOSTIC, "Extended Attribute returned: " + eaNameString, eaVal); + } + catch (java.io.UnsupportedEncodingException e) { + Trace.log(Trace.ERROR, e); + } + } + + // Advance the offset, to point to the start of next EA struct. + offset += (10 + eaNameLL + eaValLL); + } - if (curCP == 0x0009) - { - // We found the start of the Extended Attributes list. - eaListOffset = curLL_offset; // offset to "EA List Length" field + return results; } - else - { - if (Trace.isTraceOn()) Trace.log(Trace.DIAGNOSTIC, "No Extended Attributes were returned."); - return results; // empty hashtable - } - byte[] eaVal = null; - int eaCount = get16bit(eaListOffset+6); // number of EA structures returned - if (DEBUG) System.out.println("DEBUG Number of EA structures returned: " + eaCount); + /** + * Get the fixed attributes. + * + * @return fixed attributes + **/ + int getFixedAttributes() { + return (get32bit(FIXED_ATTRS_OFFSET)); + } - // Advance the offset, to point to the start of first repeating EA struct. - int offset = eaListOffset+8; + /** + * Get the date/time that the file was last modified. + * + * @return the date/time (measured as milliseconds since midnight January 1, 1970) of the last modification + **/ + long getModificationDate() { + return getDate(MODIFY_DATE_OFFSET); + } - for (int i=0; i