Re: JDom and Java5

Rolf <[email protected]>
Newsgroups gmane.comp.java.jdom.general
Message-ID <[email protected]>
Hi Mattias.

Thanks for that. I's made me look further in to things than I had 
before. I put together some test code and I see what you mean about 
casting the results. I have been in the habit of coding using eclipse, 
and I set strict compiler warnings and as a result I see lots of 
errors/warnings generated by eclipse. I always try to resolve every 
issue in my code..... and using raw types always produces warnings. This 
would explain my reluctance for returning just plain List. It is a raw 
type and should be avoided. At the same time, I realize now that 
returning List<Object> has it's drawbacks in that you can't cast it to 
anything directly either... although you can actually get away with a 
double-cast .... List<Element> mylist = (List<Element>)(List<?>)(new 
ArrayList<Object>());

By using plain List it introduces compile-time warnings in to JDom. I 
would prefer to avoid that at all costs. It should be the client side 
that encounters the warnings, not the API side.

I am content with returning List<?> or List<? extends Object> for the 
return type. It indicates that the process has been thought through. It 
would also be real interesting to explore turning the entire XPath class 
in to a generic object.... I'm going to play a little bit and get back.

I think there is a fair amount of food for thought. Right now the API 
returns List<?> and this should remove any compile-time issues anyone 
has with the jar, so, for those interested, it is not a hurdle....

Rolf

Mattias Jiderhamn wrote:
> (To be completely honest I have not read the whole post Rolf...)
>
> Without having analyzed if this depends on some compiler parameter or 
> other project setting, here is what I experienced.
>
> With return type List (as JDOM is today) I could do
> List<Element> elements = XPath.selectNodes(doc, path)
> and only get compiler warnings
>
> With return type List<?> (Rolfs second version;  which I believe are 
> equivalent to List<? extends Object>) I could do
>  List<Element> elements = (List<Element>) XPath.selectNodes(doc, path)
>
> With return type List<Object> I cannot cast but have to do
> List<Element> elements = new ArrayList<Element>();
> for(Object o : XPath.selectNodes(doc, path))
>  elements.add((Element)o);
>
> I think the last option is by far the least appealing (unless, as I 
> said, there is some setting to fix this).
> In the choice between List and List<?>/List<? extends Object> the 
> plain List has the advantage of making the Java5 port more of a JAR 
> replacement. It does not require modifying the code to add the cast. 
> Also, Gregor points out that List is for "pre-generics legacy code" 
> and certainly, in this case it could be used to indicate that behinds 
> the scenes there is pre-generics legacy code, which in this case is 
> Jaxen.
>
> Therefore I personally vote for "List".
>
> BUT there is actually a fourth alternative; add the expected output 
> type as a parameter to the method.
> List<Element> elements = XPath.selectNodes(doc, path, Element.class);
> List<Attribute> elements = XPath.selectNodes(doc, path, Attribute.class);
> List<Object> elements = XPath.selectNodes(doc, path, Object.class); // 
> Mix of different types
> This may be the most beautiful solution, but also the most noticeable 
> change with a new parameter. What about an overload with one legacy 
> version with List and one with the third parameter???
>
> /Mattias
>
>
> Rolf wrote (2008-02-23 15:51):
>> Hi Gregor
>>
>> Hmm... actually, I somewhat disagree (in this particular 
>> circumstance). I have been thinking about this a bit more
>>
>> Here's the 'current' code behind the method (after I modified it 
>> yesterday)...
>>
>>   public List<?> selectNodes(Object context) throws JDOMException {
>>      try {
>>         currentContext = context;
>>         return xPath.selectNodes(context);
>>      } catch (JaxenException ex1) {
>>         throw new JDOMException("XPath error while evaluating \"" + 
>> xPath.toString() + "\": " + ex1.getMessage(), ex1);
>>      } finally {
>>         currentContext = null;
>>      }
>>   }
>>
>> Here's the signature on the xPath method that is supplied by Jaxen:
>>
>> List <http://java.sun.com/j2se/1.4.2/docs/api/java/util/List.html> 
>> *selectNodes*(Object 
>> <http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html> 
>> context) throws JaxenException 
>> <http://jaxen.codehaus.org/apidocs/org/jaxen/JaxenException.html>
>>
>> Given that XPath can return all sorts of values (not all of them are 
>> JDom Content (like Attribute which is not Content)), then we have a 
>> real problem with this method.
>>
>> There is no way I can see (even by modifying Jaxen) to return a list 
>> of any specific type other than Object. It would be real nice if an 
>> xpath that returned just Elements would have a return type of 
>> List<Element>, but that just isn't feasible.
>>
>> The next best thing is to return something appropriate, and that 
>> should be the same as what Jaxen would return if it were Generified.
>>
>> Thus, the best thing would be to consider things from Jaxen's POV, 
>> and let the 'client' sort it out.
>>
>> Since Jaxen does not know anything about the actual content in the 
>> 'context' (it is all delegated to a JDom specific implementation), 
>> and that implementation has to be able to return both Attribute and 
>> Content, the best that Jaxen could do is return List<Object>.
>>
>> The Jaxen code would have no option but to look something like:
>>
>> List<Object> ret = new XXXList<Object>();
>> for (..... nodes in context ...) {
>>  if (... node matches the xpath ...) {
>>     ret.add(node);
>>  }
>> }
>>
>>
>> because it will potentially have to add Attributes, Elements, Text, 
>> etc. (and that's just for JDom, for other API's it will need other 
>> constructs).
>>
>> As a consequence, the Jaxen code, if it were Generified, would have 
>> no option but to return List<Object> from the method, just like it 
>> returns Object from the method selectSingleNode();
>>
>> Object 
>> <http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html> 
>> *selectSingleNode*(Object 
>> <http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html> 
>> context) throws JaxenException 
>> <http://jaxen.codehaus.org/apidocs/org/jaxen/JaxenException.html>
>>
>> In other words, I have come back around the circle and I believe that 
>> the method should return exactly List<Object> rather than List<?> or 
>> List<? extends Object>.
>>
>> As further considerations against the alternatives:
>>
>> returning List<? extends Object> implies that the actual returned 
>> list may be any other specific type as well, e.g. List<String> or 
>> List<Element> or even something silly like List<System>. This will 
>> not be the case, the actual returned type will in fact be 
>> List<Object> and there is no point in making it more obscure by 
>> saying List<? extends Object> because that actually reduces the meaning.
>>
>> returning List<?> implies that we have no idea what's in the list, 
>> but we do.
>>
>> The logical answer appears to be returning List<Object>. This makes 
>> the most sense until Jaxen finds a way for the method 
>> returnSingleNode(Context) to return a type other than Object. Here's 
>> the Jaxen code:
>>
>>    public Object selectSingleNode(Object node) throws JaxenException {
>>        List results = selectNodes( node );
>>        if ( results.isEmpty() ) {
>>            return null;
>>        }
>>        return results.get( 0 );
>>    }
>>
>> If Jaxen can be generified to have something like:
>>
>>    public T <T extends Object> selectSingleNode(Object node) throws 
>> JaxenException {
>>        List<T> results = selectNodes( node );
>>        if ( results.isEmpty() ) {
>>            return null;
>>        }
>>        return results.get( 0 );
>>    }
>>
>> only then should we consider the alternatives....
>>
>> On the other hand, the client-side code calling the XPath method is 
>> going to have to jump through all sorts of instanceof hoops anyways, 
>> and the return type does not really affect that in any way.
>>
>> As for Mattias's original claim that List<?> can be cast to 
>> List<Element> if you know the content will be only Elements, then, I 
>> believe that lends a certain weight to List<?>, but, is the same not 
>> true for List<Object>? At some point you will have a compile-time 
>> warning about unchecked types... unless you do individual casts to 
>> Element on the contents of the List anyway.
>>
>> Does this make sense? This whole topic is somewhat interesting, and I 
>> do see the value in different implementations. There appears to be 
>> more than one right answer, all with different compromises. At the 
>> moment I am more in the List<Object> camp but am willing to be 
>> convinced otherwise....
>>
>> Rolf
>>
>> Gregor Zeitlinger wrote:
>>> I think List<? extends Object> is more appropriate.
>>>
>>> It shows that the code has been generified (as opposed to using a 
>>> plain List).
>>> It's similiar to List<?>, but shows that Object is indeed the least
>>> common denomiator.
>>> _______________________________________________
>>> To control your jdom-interest membership:
>>> http://www.jdom.org/mailman/options/jdom-interest/[email protected]
>>>
>>>   
>>
>

_______________________________________________
To control your jdom-interest membership:
http://www.jdom.org/mailman/options/jdom-interest/[email protected]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.