Jérémi:
You make it look easy, but it took me a good long bit of searching and trial-and-error
investigation to figure out how to get a real Date object out of an XWiki object field.
And you perform a little leger-de-main which I have not found explained anywhere: the
expression $obj.XWikiObject.date.value is equivalent to
$obj.XWikiObject.getDateValue("date"). Unfortunately, this is not suitable for
use as an lvalue, but it makes a nice shorthand. Is this documented anywhere (other than
in the source)?
I noted the same thing when I found, in some sample code, a call to a (seemingly)
nonexistent method $xwiki.getCalendar(). Happily, simply writing $xwiki.calendar in a
document yielded an object identifier containing the classname
com.xpn.xwiki.plugin.calendar.CalendarAPI, so it seems that XWiki was fiddling my call
into $xwiki.get("calendar"), which is documented to return a plugin API, which
before this had meant nothing to me (either that, or the plugin augmented
com.xpn.xwiki.api.XWiki with a getCalendar() method, which is what I thought before I saw
the above).
Velocity, of course, turns any rvalue reference to $obj.foo into a call to $obj.getFoo()
or $obj.getfoo(), and likewise any lvalue reference in a #set into a call to
$obj.set[Ff]oo() with the RHS as its argument. But this trick is different, because at
least in the first case it has to know the navigation of a particular XWiki-specific class
hierarchy.
Nice shorthand; would be nicer if it were explained somewhere... Okay, I'll do it...
By the way, that $xwiki.calendar property finally got me to an answer to my date
arithmetic problem, thanks to Java reflection.
The task was in a project status reporting page, where I wanted to ignore records more
than a week old. The problem was that I could find no way at all to do date arithmetic in
a Velocity script, because the time value returned from java.util.Date.getTime() is a long
integer, which (until the next release of Velocity, at least) can't be used in an
arithmetic expression. I could have used the Date functions to format a date, manipulate
the string version, and then parse it, but that would be far too difficult, inflexible,
and error-prone even ignoring the fact that those methods were deprecated. It works like
this, for those who are interested:
First, $xwiki.calendar has a method getCalendar() which, in the version without arguments,
returns a java.util.Calendar initialized with the current date. Because it inherits from
java.lang.Object, it is Cloneable, so I clone()d it to get a copy that I could set back
seven days, without disturbing the original object (I learned this the hard way: the
returned object was a reference, and changes via the copied reference changed the
original).
Turning back the clock in a java.util.Calendar by seven days is quite simple in Java -
formally speaking, it's java.util.Calendar.add(java.util.Calendar.DAY_OF_YEAR, -7).
However, this isn't Java exactly; we can call the add() method easily enough, because
we have a Calendar object, but that DAY_OF_YEAR symbolic constant isn't accessible
that way, because apparently Velocity doesn't translate field references, only method
calls. The final expression was
$xwiki.calendar.calendar.class.getField("DAY_OF_YEAR").int
#set($wcal = $xwiki.calendar.calendar.clone()) ## copy of java.util.Calendar with
current time
$wcal.add($wcal.class.getField("DAY_OF_YEAR").int, -7) ## set the calendar
back one week.
#set($weekago = $wcal.time) ## get the resulting date as a java.util.Date object
After this, when I wanted to see whether date "donedate" from an object was more
than a week old, I wrote something like this:
#set($weekold = $obj.xWikiObject.donedate.value.before($weekago))
which worked just fine.
Of course, since I also wanted to sort those records on other than the default field, I
needed to do an $xwiki.search() call with a custom query, and SQL can easily do date
arithmetic.
That brings up another topic, because I was foolish enough to try it...
brain[sic]
-----Original Message-----
From: jeremi joslin [mailto:jeremi23@gmail.com]
Sent: Wednesday, March 22, 2006 8:25 AM
To: xwiki-users(a)objectweb.org
Subject: Re: [xwiki-users] Date value compare
On 3/22/06, jjanssen(a)nl.swets.com <jjanssen(a)nl.swets.com> wrote:
Hello,
I've got several classes in which I use date attributes. Is there a
way to list objects of such a class, but only those in which the value
of the date attribute is before current date?
I do it a while ago using the before function:
#if ($obj.XWikiObject.date.value.before($xwiki.getCurrentDate()))
Jérémi
--
Blog:
http://www.jeremi.info
LinkedIn:
https://www.linkedin.com/profile?viewProfile=&key=1437724
Project Manager XWiki:
http://www.xwiki.org
skype: jeremi23 -- msn et gtalk : jeremi23(a)gmail.com