
com.ibm.as400.access.IFSFileDescriptor Maven / Gradle / Ivy
///////////////////////////////////////////////////////////////////////////////
//
// JTOpen (IBM Toolbox for Java - OSS version)
//
// Filename: IFSFileDescriptor.java
//
// The source code contained herein is licensed under the IBM Public License
// Version 1.0, which has been approved by the Open Source Initiative.
// Copyright (C) 1997-2004 International Business Machines Corporation and
// others. All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
// @A1 2008-02-22 Change setFileOffset() parameter from int to long
// This is a private method and calls the impl.setFileOffset which already
// takes a long.
// setFileOffset() is called from IFSRandomAccessFile.seek(long)
///////////////////////////////////////////////////////////////////////////////
package com.ibm.as400.access;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Vector;
/**
* 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;
// Semaphore for synchronizing access to fileOffset_.
private transient Object fileOffsetLock_ = new Object();
private transient IFSFileDescriptorImpl impl_;
/**
* Constructs an IFSFileDescriptor object.
**/
public IFSFileDescriptor()
{
}
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;
}
/**
Chooses the appropriate implementation.
**/
void chooseImpl ()
{
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.
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());
}
void close()
{
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.
**/
static void fireClosedEvents(Object source, Vector fileListeners)
{
FileEvent event = new FileEvent(source, FileEvent.FILE_CLOSED);
synchronized (fileListeners)
{
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.
**/
static void fireModifiedEvents(Object source, Vector fileListeners)
{
FileEvent event = new FileEvent(source, FileEvent.FILE_MODIFIED);
synchronized (fileListeners)
{
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.
**/
static void fireOpenedEvents(Object source, Vector fileListeners)
{
FileEvent event = new FileEvent(source, FileEvent.FILE_OPENED);
synchronized (fileListeners)
{
Enumeration e = fileListeners.elements();
while (e.hasMoreElements())
{
FileListener listener = (FileListener) e.nextElement();
listener.fileOpened(event);
}
}
}
// Design note: The policy for 'get' and 'is' methods is:
// If impl_ is null, or the field is never reset by the ImplRemote,
// simply return the local copy of the data member.
// If impl_ is non-null, and the field can be reset by the ImplRemote,
// get the value from impl_ (and disregard the local value).
// Note that various IFSxxxImplRemote classes are given direct access to impl_.
IFSFileDescriptorImpl getImpl()
{
if (impl_ == null)
chooseImpl();
return impl_;
}
/**
* Returns the file's "data CCSID" setting.
**/
int getCCSID() throws IOException
{
if (impl_ == null)
chooseImpl();
return impl_.getCCSID();
}
long getFileOffset()
{
if (impl_ == null)
return fileOffset_;
return impl_.getFileOffset();
}
String getPath() {
return path_; // 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
}
void incrementFileOffset(long fileOffsetIncrement)
{
if (impl_ == null)
{
synchronized (fileOffsetLock_) {
fileOffset_ += fileOffsetIncrement;
}
}
else
impl_.incrementFileOffset(fileOffsetIncrement);
}
boolean isClosed() {
return closed_;
}
boolean isOpen()
{
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
**/
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;
}
void setFileOffset(long fileOffset) // @A1C - Change parameter from int to long
{
if (impl_ == null)
{
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);
}
void setShareOption(int shareOption)
{
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);
}
/**
* 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)
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
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();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy