
Hi all, The specification of the constructor of ns_entry confuses me a bit. What happens if the provided URL points to an existing directory? At page 205, the SAGA spec says: - the default flags are ’None’ (0) - the constructor performs an open of the entry - all notes to the respective open call (on namespace_directory) apply. But at page 233, the first note of ns_directory.open() says: - a ’BadParameter’ exception is thrown if ’name’ points to a directory, or is an invalid entry name. Together, these notes imply that the constructor of ns_entry should throw a 'BadParameter' exception if it gets a URL that points to a directory. The Java SAGA implementation of the Vrije Universiteit indeed checks this case explicitly. I'm not sure what the other implementations do. However, if no ns_entry object can point to a directory, the method ns_entry.is_dir() will always return false and is therefore pointless. Either way, the spec seems to contain an inconsistency... Or am I missing something? Mathijs

You are right: open should be able to open entries and directories (which *are* entries). open_dir should work only for directories. Same holds then indeed for the entry and dir constructors. Thanks, Andre. Quoting [Mathijs den Burger] (Aug 11 2009):
From: Mathijs den Burger <mathijs@cs.vu.nl> To: saga-rg@ogf.org Date: Tue, 11 Aug 2009 17:55:14 +0200 Subject: [SAGA-RG] Semantics of the ns_entry constructor
Hi all,
The specification of the constructor of ns_entry confuses me a bit. What happens if the provided URL points to an existing directory?
At page 205, the SAGA spec says: - the default flags are ???None??? (0) - the constructor performs an open of the entry - all notes to the respective open call (on namespace_directory) apply.
But at page 233, the first note of ns_directory.open() says: - a ???BadParameter??? exception is thrown if ???name??? points to a directory, or is an invalid entry name.
Together, these notes imply that the constructor of ns_entry should throw a 'BadParameter' exception if it gets a URL that points to a directory. The Java SAGA implementation of the Vrije Universiteit indeed checks this case explicitly. I'm not sure what the other implementations do.
However, if no ns_entry object can point to a directory, the method ns_entry.is_dir() will always return false and is therefore pointless.
Either way, the spec seems to contain an inconsistency... Or am I missing something?
Mathijs -- Nothing is ever easy.

Andre Merzky wrote:
You are right: open should be able to open entries and directories (which *are* entries). open_dir should work only for directories. Same holds then indeed for the entry and dir constructors.
Are you sure? I have an issue with what you are saying about the entry constructor. I think that if a ns_entry object represents a directory, it should in fact be a ns_directory object. Cheers, Ceriel

Hi, As a side comment, my use case was "test whether an arbitrary URL points to a file or a directory". My first idea was (in pseudo code): url u = new url(<string to test>); ns_entry e = new ns_entry(u); print e.is_dir() This does not work in general, since the constructor of ns_entry throws a BadParameter exception when the URL denotes a directory. But since that exception may also be thrown in other error conditions, it cannot be used to recognize a directory. Similarly, creating a ns_directory instead of an ns_entry doesn't work either. The only generic way seems to manually split the URL in a parent directory and a suffix, create an ns_directory object for the parent and use ns_directory.is_dir(suffix). Not really Simple... best, -Mathijs On Mon, 2009-08-17 at 07:48 +0200, Ceriel Jacobs wrote:
Andre Merzky wrote:
You are right: open should be able to open entries and directories (which *are* entries). open_dir should work only for directories. Same holds then indeed for the entry and dir constructors.
Are you sure? I have an issue with what you are saying about the entry constructor. I think that if a ns_entry object represents a directory, it should in fact be a ns_directory object.
Cheers, Ceriel

Quoting [Ceriel Jacobs] (Aug 17 2009):
Andre Merzky wrote:
You are right: open should be able to open entries and directories (which *are* entries). open_dir should work only for directories. Same holds then indeed for the entry and dir constructors.
Are you sure? I have an issue with what you are saying about the entry constructor. I think that if a ns_entry object represents a directory, it should in fact be a ns_directory object.
Well, directory inherits entry, so you can alw2ays do: saga::url u ("file://localhost/etc/") saga::file::dir d (u); saga::file::entry e = d; // downcast should always work std::cout << u << " is dir: " << e.is_dir () << std::endl; std::cout << u << " is entry: " << e.is_dir () << std::endl; is_dir would return true, is_entry would return false. Sure, sounds strange that is_entry() can return false on an entry, but it is defined as: - the method returns false if the entry is a link or a directory (although an ns_directory IS_A ns_entry, false is returned on a test on an ns_directory) - otherwise true is returned. If the above works, I don't see why saga::file::entry e (u); should not work. Or am I missing something? The same then also holds for the open methods - the origin of Matijs' complain. Best, Andre.
Cheers, Ceriel
-- Nothing is ever easy.

Andre Merzky wrote:
Quoting [Ceriel Jacobs] (Aug 17 2009):
Andre Merzky wrote:
You are right: open should be able to open entries and directories (which *are* entries). open_dir should work only for directories. Same holds then indeed for the entry and dir constructors. Are you sure? I have an issue with what you are saying about the entry constructor. I think that if a ns_entry object represents a directory, it should in fact be a ns_directory object.
Well, directory inherits entry, so you can alw2ays do:
saga::url u ("file://localhost/etc/") saga::file::dir d (u); saga::file::entry e = d; // downcast should always work
Yes, but upcast does not. My point is that the ns_entry constructor cannot create a ns_directory. It is a constructor, after all.
If the above works, I don't see why
saga::file::entry e (u);
should not work. Or am I missing something? The same then also holds for the open methods - the origin of Matijs' complain.
It is a major semantics change. If you do that, all methods in the ns_entry implementations now have to consider the possibility that the entry in fact is a directory, whereas earlier they could just be hidden by ns_directory implementations. Also, I think it is confusing that you can have a ns_entry object that represents a directory but cannot be casted to a ns_directory. Note that I don't have an issue with the change in the ns_directory.open method, only with the change in the ns_entry constructor which, being a constructor, cannot deliver a ns_directory. Cheers, Ceriel

Quoting [Ceriel Jacobs] (Aug 17 2009):
If the above works, I don't see why
saga::file::entry e (u);
should not work. Or am I missing something? The same then also holds for the open methods - the origin of Matijs' complain.
It is a major semantics change. If you do that, all methods in the ns_entry implementations now have to consider the possibility that the entry in fact is a directory, whereas earlier they could just be hidden by ns_directory implementations.
But yes, that is how it is supposed to work, IMHO. For example, the spec states what happens on entry.copy() if the entry happens to be a directory. And similar for other calls on entry.
Also, I think it is confusing that you can have a ns_entry object that represents a directory but cannot be casted to a ns_directory. Note that I don't have an issue with the change in the ns_directory.open method, only with the change in the ns_entry constructor which, being a constructor, cannot deliver a ns_directory.
No, it does not deliver an ns_directory. The following would *not* work: saga::url u ("file://localhost/etc/"); saga::file::dir * f = new saga::file::entry (u); That would be technically impossible I think. But (again) the following should work: saga::url u ("file://localhost/etc/"); saga::file::entry * e = new saga::file::entry (u); I still don't see a reason why that should be invalid. Matijs' use case seems very valid to me: saga::url u ("file://localhost/etc/"); saga::file::entry * e = new saga::file::entry (u); if ( e->is_dir () ) { saga::file::dir * f = new saga::file::directory (u); } Cheers, Andre. -- Nothing is ever easy.

If the above works, I don't see why
saga::file::entry e (u);
should not work. Or am I missing something? The same then also holds for the open methods - the origin of Matijs' complain.
It is a major semantics change. If you do that, all methods in the ns_entry implementations now have to consider the possibility that the entry in fact is a directory, whereas earlier they could just be hidden by ns_directory implementations.
But yes, that is how it is supposed to work, IMHO. For example, the spec states what happens on entry.copy() if the entry happens to be a directory. And similar for other calls on entry.
Also, I think it is confusing that you can have a ns_entry object that represents a directory but cannot be casted to a ns_directory. Note that I don't have an issue with the change in the ns_directory.open method, only with the change in the ns_entry constructor which, being a constructor, cannot deliver a ns_directory.
No, it does not deliver an ns_directory. The following would *not* work:
saga::url u ("file://localhost/etc/"); saga::file::dir * f = new saga::file::entry (u);
That would be technically impossible I think. But (again) the following should work:
saga::url u ("file://localhost/etc/"); saga::file::entry * e = new saga::file::entry (u);
I still don't see a reason why that should be invalid. Matijs' use case seems very valid to me:
saga::url u ("file://localhost/etc/"); saga::file::entry * e = new saga::file::entry (u);
if ( e->is_dir () ) { saga::file::dir * f = new saga::file::directory (u); }
What should be the outcome of the following: saga::url u ("file://localhost/etc/"); saga::file::entry e(u); if (e.get_type() == saga::object::File) cout << "e is an entry"; else if (e.get_type() == saga::object::Directory)) cout << "e is a directory"; ? IOW, what's the type of the created object? I think in our implementation it will report to be a directory, actually. Regards Hartmut

Quoting [Hartmut Kaiser] (Aug 17 2009):
What should be the outcome of the following:
saga::url u ("file://localhost/etc/"); saga::file::entry e(u); if (e.get_type() == saga::object::File) cout << "e is an entry"; else if (e.get_type() == saga::object::Directory)) cout << "e is a directory";
? IOW, what's the type of the created object? I think in our implementation it will report to be a directory, actually.
But, the object type *is* entry, and actually that is also what our implementation reports: ------------------------------------------------------------ Jonas merzky ~/test : cat entry.cpp #include <saga/saga.hpp> int main () { saga::url u ("file://localhost/etc/"); saga::name_space::entry e (u); if ( e.get_type () == saga::object::File ) { std::cout << "e is an entry" << std::endl; } else if ( e.get_type () == saga::object::Directory ) { std::cout << "e is a directory" << std::endl; } return 0; } Jonas merzky ~/test : make entry make: `entry' is up to date. Jonas merzky ~/test : ./entry e is an entry ------------------------------------------------------------ Otherwise the entry c'tor would indeed create an c++ dir object - how could that work? Andre. -- Nothing is ever easy.

Andre Merzky wrote:
Quoting [Ceriel Jacobs] (Aug 17 2009):
If the above works, I don't see why
saga::file::entry e (u);
should not work. Or am I missing something? The same then also holds for the open methods - the origin of Matijs' complain. It is a major semantics change. If you do that, all methods in the ns_entry implementations now have to consider the possibility that the entry in fact is a directory, whereas earlier they could just be hidden by ns_directory implementations.
But yes, that is how it is supposed to work, IMHO. For example, the spec states what happens on entry.copy() if the entry happens to be a directory. And similar for other calls on entry.
Yes, of course, but up until now, an implementation could do this by redefining f.i. the copy method in its ns_directory implementation.
Also, I think it is confusing that you can have a ns_entry object that represents a directory but cannot be casted to a ns_directory. Note that I don't have an issue with the change in the ns_directory.open method, only with the change in the ns_entry constructor which, being a constructor, cannot deliver a ns_directory.
No, it does not deliver an ns_directory. The following would *not* work:
saga::url u ("file://localhost/etc/"); saga::file::dir * f = new saga::file::entry (u);
That would be technically impossible I think. But (again) the following should work:
saga::url u ("file://localhost/etc/"); saga::file::entry * e = new saga::file::entry (u);
I still don't see a reason why that should be invalid.
It WAS invalid, because the specs say so explicitly. If an ns_entry can represent a directory, can a SAGA file object do so as well? IMHO, the intention of ns_entry has clearly been that it does not represent a directory. For that, you have ns_directory. If you change that, what should ns_directory.open() create when the requested entry does not exist? And what happens with directory.open()? Its notes refer to the ones from ns_directory.open(). So those are wrong as well? and logical_directory.open()?
Matijs' use case seems very valid to me:
saga::url u ("file://localhost/etc/"); saga::file::entry * e = new saga::file::entry (u);
if ( e->is_dir () ) { saga::file::dir * f = new saga::file::directory (u); }
I agree that the use-case is valid, I just have the impression that allowing directories to be represented by ns_entry may open a can of worms in the SAGA specs ... Also, the use case could be expressed differently: saga::url u ("file://localhost/etc/"); saga::file::entry *e; try { e = new saga::file::entry (u); } catch(BadParameter ex) { try { e = new saga::file::directory (u); } catch(Throwable ex2) { ... deal with exception } } Ceriel

Can of worms indeed... A. Quoting [Ceriel Jacobs] (Aug 17 2009):
Date: Mon, 17 Aug 2009 15:54:15 +0200 From: Ceriel Jacobs <ceriel@cs.vu.nl> To: Andre Merzky <andre@merzky.net> CC: Mathijs den Burger <mathijs@cs.vu.nl>, saga-rg@ogf.org Subject: Re: [SAGA-RG] Semantics of the ns_entry constructor
Andre Merzky wrote:
Quoting [Ceriel Jacobs] (Aug 17 2009):
If the above works, I don't see why
saga::file::entry e (u);
should not work. Or am I missing something? The same then also holds for the open methods - the origin of Matijs' complain. It is a major semantics change. If you do that, all methods in the ns_entry implementations now have to consider the possibility that the entry in fact is a directory, whereas earlier they could just be hidden by ns_directory implementations.
But yes, that is how it is supposed to work, IMHO. For example, the spec states what happens on entry.copy() if the entry happens to be a directory. And similar for other calls on entry.
Yes, of course, but up until now, an implementation could do this by redefining f.i. the copy method in its ns_directory implementation.
Also, I think it is confusing that you can have a ns_entry object that represents a directory but cannot be casted to a ns_directory. Note that I don't have an issue with the change in the ns_directory.open method, only with the change in the ns_entry constructor which, being a constructor, cannot deliver a ns_directory.
No, it does not deliver an ns_directory. The following would *not* work:
saga::url u ("file://localhost/etc/"); saga::file::dir * f = new saga::file::entry (u);
That would be technically impossible I think. But (again) the following should work:
saga::url u ("file://localhost/etc/"); saga::file::entry * e = new saga::file::entry (u);
I still don't see a reason why that should be invalid.
It WAS invalid, because the specs say so explicitly.
If an ns_entry can represent a directory, can a SAGA file object do so as well? IMHO, the intention of ns_entry has clearly been that it does not represent a directory. For that, you have ns_directory. If you change that, what should ns_directory.open() create when the requested entry does not exist? And what happens with directory.open()? Its notes refer to the ones from ns_directory.open(). So those are wrong as well? and logical_directory.open()?
Matijs' use case seems very valid to me:
saga::url u ("file://localhost/etc/"); saga::file::entry * e = new saga::file::entry (u);
if ( e->is_dir () ) { saga::file::dir * f = new saga::file::directory (u); }
I agree that the use-case is valid, I just have the impression that allowing directories to be represented by ns_entry may open a can of worms in the SAGA specs ...
Also, the use case could be expressed differently:
saga::url u ("file://localhost/etc/"); saga::file::entry *e; try { e = new saga::file::entry (u); } catch(BadParameter ex) { try { e = new saga::file::directory (u); } catch(Throwable ex2) { ... deal with exception } }
Ceriel
-- Nothing is ever easy.

Mathijs den Burger wrote:
Hi all,
The specification of the constructor of ns_entry confuses me a bit. What happens if the provided URL points to an existing directory?
At page 205, the SAGA spec says: - the default flags are ’None’ (0) - the constructor performs an open of the entry - all notes to the respective open call (on namespace_directory) apply.
But at page 233, the first note of ns_directory.open() says: - a ’BadParameter’ exception is thrown if ’name’ points to a directory, or is an invalid entry name.
Together, these notes imply that the constructor of ns_entry should throw a 'BadParameter' exception if it gets a URL that points to a directory. The Java SAGA implementation of the Vrije Universiteit indeed checks this case explicitly. I'm not sure what the other implementations do.
However, if no ns_entry object can point to a directory, the method ns_entry.is_dir() will always return false and is therefore pointless.
No, it is not. An ns_directory is also an ns_entry, and it may (should) redefine the is_dir() method. And an ns_entry object CAN point to a directory, but in that case it is an ns_directory object.
Either way, the spec seems to contain an inconsistency... Or am I missing something?
I don't see the inconsistency. Am I missing something :-? Ceriel
participants (5)
-
'Andre Merzky'
-
Andre Merzky
-
Ceriel Jacobs
-
Hartmut Kaiser
-
Mathijs den Burger