Adding getCreated() / getLastChanged() / getLastAccessed() where appropriate

Project:JNode Core
Component:Code
Category:feature request
Priority:normal
Assigned:Daniel Noll
Status:closed
Description

Adding getLastAccessed(), getLastChanged(), getCreated() to implementations of FSEntry where appropriate, but not to the interface itself.

Something I've been

Something I've been wondering for a while... who's supposed to setLastModified and setLastAccessed? The associated FSFile for the FSEntry on read and write? Or the implementations outside that which provides streams and random access?

The reason I wonder is, if it's done from the inside, then it's nicely self-contained but it opens up the possibility for a read-only filesystem to try and modify itself. And also, it would result in enormous code duplication.

Do we need this?

I think before extending our FS interfaces we should ask ourselves if we really need to do so.
If we try to aggregate all the special features of the various filesystem types that implement FSEntry we will run into trouble since some things cannot be implemented in certain filesystems and we will end up with a lot of iterface methods which implementation will be not more than throwing an unsupported operation exception.
I would take an approach with our generic file system interface (including FSEntry) closer to lowest common denominator of the supported filesystem types.
On the other hand I would think of a solution for being able to access the underlying filesystem features in a uniform way. Maybe we could use a pattern similar to the 'service provider interface' used at so many places in the JDK to provide a standard way for accessing the underlying file system API.

Well

Thing is, the number of filesystems which support getLastAccessed() is pretty much identical to the number which support getLastModified(). Are we planning to remove getLastModified(), then?

An update, please

Has anything changed since the time I raised this?

I have already implemented getting the last accessed time on our own local branch, and am considering putting up the patch, but has JNode resolved the issues with figuring out the correct place to put these methods?

Should I just put the patch up anyway? The get* methods can always be refactored into getFoo().get* later if need be.

The reason I ask is that I'm considering implementing created/changed as well.

JSR 203

JSR 203 is an effort to extend further the IO capabilities of Java by providing among other things bulk access to file atributes.
We want to revisit this topic when we provid support for JSR 203, assumning that it will be sucecssfully implemented and included into Java 7. Untill then as the only standard Java way there is only java.io.File which has very limited capabilities in this respect. So using your extension will need JNode spcific code on the client side.

In spite of this situation I encurage you to implement on specif file system level as many things as it makse sense for that particular type of file system. Then we will have later a rich pool of features to revisit and consider when the time of JSR 203 will come.
Then we can think about what to inculde into FSFile but probably not too many things since that is inteneded to be a common denominator for file object of various file systems.

So if you agree, along these lines feel free to submit your patches.

Are you implementing lastAccessed on every file system typeJNode currently has? Have you started working beyond the domain of NTFS too?

Regards, Levente

#1

Title:I'm working on adding getLastAccessed() to» JSR 203 - NIO 2 progress

You can follow the porgress of JSR-203 aka NIO 2 here: http://openjdk.java.net/projects/nio/

#2

Title:JSR 203 - NIO 2 progress» I'm working on adding getLastAccessed()

#3

Title:I'm working on adding getLastAccessed()» Progress report

I have just implemented created/lastChanged/lastAccessed on every filesystem available in 0.2.6.

What I've actually done:

  • Added FSEntry.get/set for the new three filetimes (messy for filesystem implementors perhaps, but convenient for us.)
  • Added proper implementations, where proper implementations already existed for last modified. Notably for HFS+ there was no implementation I could see, so I left it blank. But we'll be using HFS+ ourselves sooner or later so the way things are, I might end up writing those anyway.
  • Changed the getters to return -1 in event that the method makes no sense, to be proactively consistent with NIO2.

As far as improving the API, my initial thought is to have getFileTimes() returning FileTimes, which only has get/setLastModified(). Then you have a few choices:

  1. Stack interfaces for get/setLastAccessed on a LastAccessedFileTimes interface which you put on the object you return so that the caller can check for each interface in turn and cast to it.
  2. Add interfaces for PosixFileTimes, DosFileTimes and so forth, which return the appropriate subset.
  3. Standardise around AbstractFSEntry for all filesystems to reduce the impact in the first place.

I think option 1 is simpler and more fine-grained, but the way NIO2 does it is similar to #2, you have a BasicFileAttributes with the most common stuff, and then further views add information on top (e.g. DosFileAttributes adds DOS's boolean flags, PosixFileAttributes would add last change time, etc.)

Oh and we've been using FAT and Ext2 for some time as well. I've only been focused on NTFS because the driver for that was missing the most features. In actual fact, the person who noticed that this was missing was loading a FAT-32 image at the time.

#4

Title:Progress report» Adding getCreated() / getLastChanged() / getLastAccessed() where appropriate

Attached patch is against current trunk.

There are a couple of open issues.
1. NFS2 didn't appear to have a way to set change time despite having a way to set the other two (even at the underlying level.)
2. It's still unclear "who" is supposed to update the timestamps. Obviously it makes more sense to expose setters and have the code which uses this API call them as appropriate, but I have noticed that some of the APIs update them internally.

Otherwise this includes implementations for each case which makes sense across all filesystems.

I removed a few redundant Javadoc comments which were either repeating the documentation of the interface in a less useful fashion, or adding a @see for the method it was implementing. If the latter isn't a good idea I can revert it, but if you generate Javadoc for a method with no Javadoc comment, it already links to the method it's implementing.

Additionally, I standardised getLastModified() so that it does the same thing in all situations, returning 0. I also documented this. It can be changed to -1 if that seems like a better value.

AttachmentSize
filetimes.patch29.97 KB

#5

Can't seem to see the patch after attaching it, trying again. (Maybe I'm just misunderstanding where the file goes.)

AttachmentSize
filetimes.patch_.txt29.97 KB

#6

don't worry, I can see the 2 attachments you sent.

#7

Thanks, Daniel. I hope on the weekend I can check this out.

#8

The patch looks fine. I committed it. Thank you!

My comment to 2. above is that while it looks reasonable to expose setters the best would be if beside that the filesystems internally updated their various times. Certain times are file system speciffic and generally these look like operations which are best performed internally by the FS driver. For a more accurate handling of these times we might need to extend the file system interface, so that for instance the driver gets notification when a file is opened or closed.

I think the @see tags can stay in the code. For the rest I don't like either repeating the standard documentation of methods in the sources.

#9

Status:active» closed

Closing as it was committed.

I hope I'm doing the right thing, I was originally expecting the committer to close the issue record.

#10

The normal procedure is to mark an issue as "fixed" and let the auto-close mechanism close it after 2 weeks. But in this case, what you have done is sensible and reasonable ... IMO.