You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@sis.apache.org by Martin Desruisseaux <ma...@geomatys.fr> on 2013/03/30 00:29:22 UTC

On null collections

Hello all

This is a minor note mostly for information purpose. In my attempt to 
fix some known shortcomings that we had with metadata, I was trying 
today to enforce some ISO 19115 conditions. The standard often defines 
two properties, said A and B, with a constraint of the kind "Only one of 
A or B can be set". When A and B are not collection, this is 
straightforward: if A is non-null, then B must be null, and conversely.

However this become more tricky with collections. We are encouraged by 
numerous books (e.g. "Effective Java") to prefer empty collections over 
null collections. This work well in 90% of cases. But it is a bit 
problematic with conditional properties in metadata objects. This is 
because properties of type Collection in org.apache.sis.metadata are by 
design modifiable. This allow us to write:

     dataQuality.getReports().add(myReport);

instead of the slightly more tedious:

     dataQuality.setReports(Collections.singleton(myReport));

It also allows users to add information instead than replacing it. 
However DataQuality [1] have another property, "lineage", and ISO 19115 
said that those two properties are mutually exclusive. If the "lineage" 
property is set, what should getReports() returns? If it returns an 
empty collection, then the user may have the false feeling that he can 
add elements to it since this is the pattern in most of the SIS metadata 
API. Returning 'null' make clears that this property can not be used, 
unless the user clears the lineage property. However users who rely on 
the "always prefer empty collections over null" recommendation could get 
a NullPointerException.

However I didn't found simple alternative yet (we could create yet 
another custom collection implementation, but we may not need such 
complication), so I'm tempted to go with null collections in this 
particular kind of situations, with clear javadoc...

     Martin

[1] 
http://www.geoapi.org/snapshot/javadoc/org/opengis/metadata/quality/DataQuality.html


Re: On null collections

Posted by Adam Estrada <es...@gmail.com>.
Thanks Martin!

A


On Sun, Mar 31, 2013 at 5:09 PM, Martin Desruisseaux <
martin.desruisseaux@geomatys.fr> wrote:

> Hello all
>
> Le 30/03/13 22:26, Mattmann, Chris A (388J) a écrit :
>
>  1. Ignore this subtle difference (Pro: simplest approach except for
>>>     XML. Con: users may be puzzled about why he can not add elements in
>>>     his modifiable metadata).
>>> 2. Return null (Pro: simplest approach including for XML, except that
>>>     it requires more javadoc. Con: users who don't read javadoc may get
>>>     NullPointerException).
>>> 3. Returns something that replicate Collections.emptyList() except for
>>>     the more accurate exception message. (Pro: as 1 without the puzzling
>>>     part).
>>>
>> I've never been a fan of returning a null list, mainly b/c I'm the guy
>> that
>> usually does Method.getList().add(some new List element). ;)
>>
>> That said, 1-3 are all feasible to me, so whichever one you pick I'm +1
>> for.
>>
>
> Thanks for the feedback. So I will try to go with option 3.
>
>     Martin
>
>

Re: On null collections

Posted by Martin Desruisseaux <ma...@geomatys.fr>.
Hello all

Le 30/03/13 22:26, Mattmann, Chris A (388J) a écrit :
>> 1. Ignore this subtle difference (Pro: simplest approach except for
>>     XML. Con: users may be puzzled about why he can not add elements in
>>     his modifiable metadata).
>> 2. Return null (Pro: simplest approach including for XML, except that
>>     it requires more javadoc. Con: users who don't read javadoc may get
>>     NullPointerException).
>> 3. Returns something that replicate Collections.emptyList() except for
>>     the more accurate exception message. (Pro: as 1 without the puzzling
>>     part).
> I've never been a fan of returning a null list, mainly b/c I'm the guy that
> usually does Method.getList().add(some new List element). ;)
>
> That said, 1-3 are all feasible to me, so whichever one you pick I'm +1
> for.

Thanks for the feedback. So I will try to go with option 3.

     Martin


Re: On null collections

Posted by "Mattmann, Chris A (388J)" <ch...@jpl.nasa.gov>.
Hey Martin,

-----Original Message-----

From: Martin Desruisseaux <ma...@geomatys.fr>
Organization: Geomatys
Reply-To: "dev@sis.apache.org" <de...@sis.apache.org>
Date: Saturday, March 30, 2013 2:21 PM
To: "dev@sis.apache.org" <de...@sis.apache.org>
Subject: Re: On null collections

>Hello Chris
>
>Le 30/03/13 21:28, Mattmann, Chris A (388J) a écrit :
>>> In this context, it would be Collections.empty{Set|List}. The point was
>>> that we could see a nuance between "no elements", and "elements can not
>>> exist here in current context". In the first case, users can add
>>> elements. In the second case, they can not. Returning a null value in
>>> the second case would be a way to differentiate them.
>> Well that's my point -- Collections.unmodifiableList [1] for example,
>> handles the 2nd case well and would avoid having to return null (and
>> the XML marshaling issue you mention below). Right?
>
>I don't see how? Collections.emptyList() can be seen as a special case
>of Collections.unmodifiableList(...) with zero element.

Is Collections.emptyList() returning a list that throws an exception when
it's modified? If so, then I get what you mean:

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Collections.html#emp
tyList()


Yep I get it -- same thing, you're right.


>I don't see 
>which difference Collections.unmodifiableList(...) could bring? (unless
>the proposal is to return singleton containing the null element).

Yeah that was sort of my proposal -- making a singleton to return the null
element.

>
>
>>> Returning Collections.empty{Set|List} means that it is not worth to
>>> distinguish those two possibilities, which is a perfectly valid
>>>decision
>>> for keeping the API simpler. Eventually, the exception thrown by
>>> Collection.add(...) could contains a message saying why elements can't
>>> be added.
>> Isn't that just replicating what [1] does?
>
>It would just replicate what Collections.emptyList() does, with the only
>difference that the message in the exception would be different.

+1 for me.

>
>The reason for that is that UnsupportedOperationException in the
>collection framework are usually thrown for unmodifiable collections.
>This happen when the metadata has been declared unmodifiable (the API
>allows that). But in this particular case, the
>UnsupportedOperationException would be thrown because a particular
>property is mutually exclusive with another property, despite the
>metadata being modifiable. Some choices are:
>
> 1. Ignore this subtle difference (Pro: simplest approach except for
>    XML. Con: users may be puzzled about why he can not add elements in
>    his modifiable metadata).
> 2. Return null (Pro: simplest approach including for XML, except that
>    it requires more javadoc. Con: users who don't read javadoc may get
>    NullPointerException).
> 3. Returns something that replicate Collections.emptyList() except for
>    the more accurate exception message. (Pro: as 1 without the puzzling
>    part).

I've never been a fan of returning a null list, mainly b/c I'm the guy that
usually does Method.getList().add(some new List element). ;)

That said, 1-3 are all feasible to me, so whichever one you pick I'm +1
for.

Thanks dude.

Cheers,
Chris


Re: On null collections

Posted by Martin Desruisseaux <ma...@geomatys.fr>.
Hello Chris

Le 30/03/13 21:28, Mattmann, Chris A (388J) a écrit :
>> In this context, it would be Collections.empty{Set|List}. The point was
>> that we could see a nuance between "no elements", and "elements can not
>> exist here in current context". In the first case, users can add
>> elements. In the second case, they can not. Returning a null value in
>> the second case would be a way to differentiate them.
> Well that's my point -- Collections.unmodifiableList [1] for example,
> handles the 2nd case well and would avoid having to return null (and
> the XML marshaling issue you mention below). Right?

I don't see how? Collections.emptyList() can be seen as a special case 
of Collections.unmodifiableList(...) with zero element. I don't see 
which difference Collections.unmodifiableList(...) could bring? (unless 
the proposal is to return singleton containing the null element).


>> Returning Collections.empty{Set|List} means that it is not worth to
>> distinguish those two possibilities, which is a perfectly valid decision
>> for keeping the API simpler. Eventually, the exception thrown by
>> Collection.add(...) could contains a message saying why elements can't
>> be added.
> Isn't that just replicating what [1] does?

It would just replicate what Collections.emptyList() does, with the only 
difference that the message in the exception would be different.

The reason for that is that UnsupportedOperationException in the 
collection framework are usually thrown for unmodifiable collections. 
This happen when the metadata has been declared unmodifiable (the API 
allows that). But in this particular case, the 
UnsupportedOperationException would be thrown because a particular 
property is mutually exclusive with another property, despite the 
metadata being modifiable. Some choices are:

 1. Ignore this subtle difference (Pro: simplest approach except for
    XML. Con: users may be puzzled about why he can not add elements in
    his modifiable metadata).
 2. Return null (Pro: simplest approach including for XML, except that
    it requires more javadoc. Con: users who don't read javadoc may get
    NullPointerException).
 3. Returns something that replicate Collections.emptyList() except for
    the more accurate exception message. (Pro: as 1 without the puzzling
    part).


     Martin


Re: On null collections

Posted by "Mattmann, Chris A (388J)" <ch...@jpl.nasa.gov>.
Hey Martin,

-----Original Message-----

From: Martin Desruisseaux <ma...@geomatys.fr>
Organization: Geomatys
Reply-To: "dev@sis.apache.org" <de...@sis.apache.org>
Date: Saturday, March 30, 2013 1:00 PM
To: "dev@sis.apache.org" <de...@sis.apache.org>
Subject: Re: On null collections

>Hello Chris
>
>Le 30/03/13 00:35, Mattmann, Chris A (388J) a écrit :
>>> (...snip...)
>>> However DataQuality [1] have another property, "lineage", and ISO 19115
>>> said that those two properties are mutually exclusive. If the "lineage"
>>> property is set, what should getReports() returns?
>> How about Collections.unmodifiable{List|Map|etc}?
>
>In this context, it would be Collections.empty{Set|List}. The point was
>that we could see a nuance between "no elements", and "elements can not
>exist here in current context". In the first case, users can add
>elements. In the second case, they can not. Returning a null value in
>the second case would be a way to differentiate them.

Well that's my point -- Collections.unmodifiableList [1] for example,
handles the 2nd case well and would avoid having to return null (and
the XML marshaling issue you mention below). Right?

Or am I missing something?

>
>Returning Collections.empty{Set|List} means that it is not worth to
>distinguish those two possibilities, which is a perfectly valid decision
>for keeping the API simpler. Eventually, the exception thrown by
>Collection.add(...) could contains a message saying why elements can't
>be added.

Isn't that just replicating what [1] does?

>
>Returning null make the job a little bit easier in some situations like
>XML marshalling, where empty XML element is not the same than no XML
>element. But this can be considered as an implementation details.

Yep agreed -- let me know what you think.

Cheers,
Chris

[1] http://s.apache.org/Dnu

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Chris Mattmann, Ph.D.
Senior Computer Scientist
NASA Jet Propulsion Laboratory Pasadena, CA 91109 USA
Office: 171-266B, Mailstop: 171-246
Email: chris.a.mattmann@nasa.gov
WWW:  http://sunset.usc.edu/~mattmann/
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adjunct Assistant Professor, Computer Science Department
University of Southern California, Los Angeles, CA 90089 USA
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++




Re: On null collections

Posted by Martin Desruisseaux <ma...@geomatys.fr>.
Hello Chris

Le 30/03/13 00:35, Mattmann, Chris A (388J) a écrit :
>> (...snip...)
>> However DataQuality [1] have another property, "lineage", and ISO 19115
>> said that those two properties are mutually exclusive. If the "lineage"
>> property is set, what should getReports() returns?
> How about Collections.unmodifiable{List|Map|etc}?

In this context, it would be Collections.empty{Set|List}. The point was 
that we could see a nuance between "no elements", and "elements can not 
exist here in current context". In the first case, users can add 
elements. In the second case, they can not. Returning a null value in 
the second case would be a way to differentiate them.

Returning Collections.empty{Set|List} means that it is not worth to 
distinguish those two possibilities, which is a perfectly valid decision 
for keeping the API simpler. Eventually, the exception thrown by 
Collection.add(...) could contains a message saying why elements can't 
be added.

Returning null make the job a little bit easier in some situations like 
XML marshalling, where empty XML element is not the same than no XML 
element. But this can be considered as an implementation details.

     Martin


Re: On null collections

Posted by "Mattmann, Chris A (388J)" <ch...@jpl.nasa.gov>.
Hey Martin,


-----Original Message-----
From: Martin Desruisseaux <ma...@geomatys.fr>
Organization: Geomatys
Reply-To: "dev@sis.apache.org" <de...@sis.apache.org>
Date: Friday, March 29, 2013 4:29 PM
To: Apache SIS <de...@sis.apache.org>
Subject: On null collections

>Hello all
>
>This is a minor note mostly for information purpose. In my attempt to
>fix some known shortcomings that we had with metadata, I was trying
>today to enforce some ISO 19115 conditions. The standard often defines
>two properties, said A and B, with a constraint of the kind "Only one of
>A or B can be set". When A and B are not collection, this is
>straightforward: if A is non-null, then B must be null, and conversely.
>
>However this become more tricky with collections. We are encouraged by
>numerous books (e.g. "Effective Java") to prefer empty collections over
>null collections. This work well in 90% of cases. But it is a bit
>problematic with conditional properties in metadata objects. This is
>because properties of type Collection in org.apache.sis.metadata are by
>design modifiable. This allow us to write:
>
>     dataQuality.getReports().add(myReport);
>
>instead of the slightly more tedious:
>
>     dataQuality.setReports(Collections.singleton(myReport));
>
>It also allows users to add information instead than replacing it.
>However DataQuality [1] have another property, "lineage", and ISO 19115
>said that those two properties are mutually exclusive. If the "lineage"
>property is set, what should getReports() returns?

How about Collections.unmodifiable{List|Map|etc}?

>If it returns an 
>empty collection, then the user may have the false feeling that he can
>add elements to it since this is the pattern in most of the SIS metadata
>API. Returning 'null' make clears that this property can not be used,
>unless the user clears the lineage property. However users who rely on
>the "always prefer empty collections over null" recommendation could get
>a NullPointerException.
>
>However I didn't found simple alternative yet (we could create yet
>another custom collection implementation, but we may not need such
>complication), so I'm tempted to go with null collections in this
>particular kind of situations, with clear javadoc...

Let me know what you think about the un-modifiable option. Thanks!

Cheers,
Chris

>
>     Martin
>
>[1] 
>http://www.geoapi.org/snapshot/javadoc/org/opengis/metadata/quality/DataQu
>ality.html
>

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Chris Mattmann, Ph.D.
Senior Computer Scientist
NASA Jet Propulsion Laboratory Pasadena, CA 91109 USA
Office: 171-266B, Mailstop: 171-246
Email: chris.a.mattmann@nasa.gov
WWW:  http://sunset.usc.edu/~mattmann/
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adjunct Assistant Professor, Computer Science Department
University of Southern California, Los Angeles, CA 90089 USA
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++