Discussion:
[FreeMarker-user] how to call java.util.Date.getTime()
Joe Hudson
2005-06-07 01:41:34 UTC
Permalink
Hello, I am unable to figure out how to call getTime() on a Date object.

I have tried ${date.time} which produces an error.

I see no reference to do this on
http://www.freemarker.org/docs/ref_builtins_date.html

Could somebody please tell me how this can be done? Thank you very much.

Joe
Jonathan Revusky
2005-06-07 12:43:35 UTC
Permalink
Post by Joe Hudson
Hello, I am unable to figure out how to call getTime() on a Date object.
Joe,

FreeMarker has a different approach in that it is not based on simply
dropping in Java API to the template layer. In fact, when working on a
FreeMarker template, you should try to temporarily forget that you are a
java programmer and know anything about a java API. So, a FreeMarker
data object is not a java.util.Date.

(Note that a java.util.Date is just a very thin wrapper around a long
that contains the number of milliseconds elapsed since the new year of
1970, UTC. (What should actually be called Date probably is
java.util.Calendar. The whole java API regarding time/date is not well
designed or well named...))

Anyway, Date.getTime() just returns the number of milliseconds since
1/1/70. Why would a template writer want that?

We try to expose generally useful built-ins that people would use when
producing web pages or other human readable output. So, while exposing
Date.getTime() would be very easy, would anybody want it? Or really,
getting to first principles, isn't a template about converting
computerized data into a format that is readable to humans -- as opposed
to the other way round????

Actually, why do you want it? (If you want it for sorting/comparison
purposes, which is the only thing that occurs to me, we have
sorting/comparison on dates working anyway.)

Of course, if you really do need this, you can expose any java object
directly to the template by explicitly using the beanswrapper for this
purpose. Something like:

model.expose("myDate", BeansWrapper.getDefaultInstance().wrap(new Date()));

And then date.getTime() or more simply date.time would provide the
number of milliseconds since 1/1/70.

Regards,

Jonathan Revusky
Post by Joe Hudson
I have tried ${date.time} which produces an error.
I see no reference to do this on
http://www.freemarker.org/docs/ref_builtins_date.html
Could somebody please tell me how this can be done? Thank you very much.
Joe
Joe Hudson
2005-06-07 12:55:59 UTC
Permalink
Thank you very much Jonathan, I'll take a look at that.

The reason I want this value is because I always pass a value in my forms
that represents the timestamp (essentially System.currentTimeInMillis()) of
the time the form was posted. That way, I can determine if a refresh
occurred and not perform actions again if any occurred (like creating a new
record in a database). Thanks.

Joe

-----Original Message-----
From: freemarker-user-***@lists.sourceforge.net
[mailto:freemarker-user-***@lists.sourceforge.net] On Behalf Of Jonathan
Revusky
Sent: Tuesday, June 07, 2005 8:44 AM
To: freemarker-***@lists.sourceforge.net
Subject: [FreeMarker-user] Re: how to call java.util.Date.getTime()
Post by Joe Hudson
Hello, I am unable to figure out how to call getTime() on a Date object.
Joe,

FreeMarker has a different approach in that it is not based on simply
dropping in Java API to the template layer. In fact, when working on a
FreeMarker template, you should try to temporarily forget that you are a
java programmer and know anything about a java API. So, a FreeMarker
data object is not a java.util.Date.

(Note that a java.util.Date is just a very thin wrapper around a long
that contains the number of milliseconds elapsed since the new year of
1970, UTC. (What should actually be called Date probably is
java.util.Calendar. The whole java API regarding time/date is not well
designed or well named...))

Anyway, Date.getTime() just returns the number of milliseconds since
1/1/70. Why would a template writer want that?

We try to expose generally useful built-ins that people would use when
producing web pages or other human readable output. So, while exposing
Date.getTime() would be very easy, would anybody want it? Or really,
getting to first principles, isn't a template about converting
computerized data into a format that is readable to humans -- as opposed
to the other way round????

Actually, why do you want it? (If you want it for sorting/comparison
purposes, which is the only thing that occurs to me, we have
sorting/comparison on dates working anyway.)

Of course, if you really do need this, you can expose any java object
directly to the template by explicitly using the beanswrapper for this
purpose. Something like:

model.expose("myDate", BeansWrapper.getDefaultInstance().wrap(new Date()));

And then date.getTime() or more simply date.time would provide the
number of milliseconds since 1/1/70.

Regards,

Jonathan Revusky
Post by Joe Hudson
I have tried ${date.time} which produces an error.
I see no reference to do this on
http://www.freemarker.org/docs/ref_builtins_date.html
Could somebody please tell me how this can be done? Thank you very much.
Joe
-------------------------------------------------------
This SF.Net email is sponsored by: NEC IT Guy Games. How far can you
shotput
a projector? How fast can you ride your desk chair down the office luge
track?
If you want to score the big prize, get to know the little guy.
Play to win an NEC 61" plasma display: http://www.necitguy.com/?r=20
Joe Hudson
2005-06-07 13:09:37 UTC
Permalink
Hi Jonathan, I will try to stop bothering you real soon, I promise!

In regard to this answer, I really like the "built in" functionality that I
would loose if I used the bean wrapper. Is there any way I can extend the
TemplateDateModel (and tell freemarker to use my class for date objects) to
add the functionality that I need but keep the cool functionality that
already exists? Thanks.

Joe

-----Original Message-----
From: freemarker-user-***@lists.sourceforge.net
[mailto:freemarker-user-***@lists.sourceforge.net] On Behalf Of Jonathan
Revusky
Sent: Tuesday, June 07, 2005 8:44 AM
To: freemarker-***@lists.sourceforge.net
Subject: [FreeMarker-user] Re: how to call java.util.Date.getTime()
Post by Joe Hudson
Hello, I am unable to figure out how to call getTime() on a Date object.
Joe,

FreeMarker has a different approach in that it is not based on simply
dropping in Java API to the template layer. In fact, when working on a
FreeMarker template, you should try to temporarily forget that you are a
java programmer and know anything about a java API. So, a FreeMarker
data object is not a java.util.Date.

(Note that a java.util.Date is just a very thin wrapper around a long
that contains the number of milliseconds elapsed since the new year of
1970, UTC. (What should actually be called Date probably is
java.util.Calendar. The whole java API regarding time/date is not well
designed or well named...))

Anyway, Date.getTime() just returns the number of milliseconds since
1/1/70. Why would a template writer want that?

We try to expose generally useful built-ins that people would use when
producing web pages or other human readable output. So, while exposing
Date.getTime() would be very easy, would anybody want it? Or really,
getting to first principles, isn't a template about converting
computerized data into a format that is readable to humans -- as opposed
to the other way round????

Actually, why do you want it? (If you want it for sorting/comparison
purposes, which is the only thing that occurs to me, we have
sorting/comparison on dates working anyway.)

Of course, if you really do need this, you can expose any java object
directly to the template by explicitly using the beanswrapper for this
purpose. Something like:

model.expose("myDate", BeansWrapper.getDefaultInstance().wrap(new Date()));

And then date.getTime() or more simply date.time would provide the
number of milliseconds since 1/1/70.

Regards,

Jonathan Revusky
Post by Joe Hudson
I have tried ${date.time} which produces an error.
I see no reference to do this on
http://www.freemarker.org/docs/ref_builtins_date.html
Could somebody please tell me how this can be done? Thank you very much.
Joe
-------------------------------------------------------
This SF.Net email is sponsored by: NEC IT Guy Games. How far can you
shotput
a projector? How fast can you ride your desk chair down the office luge
track?
If you want to score the big prize, get to know the little guy.
Play to win an NEC 61" plasma display: http://www.necitguy.com/?r=20
Jonathan Revusky
2005-06-07 14:48:49 UTC
Permalink
Post by Joe Hudson
Hi Jonathan, I will try to stop bothering you real soon, I promise!
No problem. This list exists for this purpose.
Post by Joe Hudson
In regard to this answer, I really like the "built in" functionality that I
would loose if I used the bean wrapper. Is there any way I can extend the
TemplateDateModel (and tell freemarker to use my class for date objects) to
add the functionality that I need but keep the cool functionality that
already exists? Thanks.
Well, I'm going to give you various long-winded answers, more than you
actually need, to help you get a conceptual model of how FM works and
how to solve such problems.

The first answer to your question is that if you want the methods on the
object to be exposed (IMO, you should only do this if necessary because
you should try to keep your template's underlying data model simple and
exposing a boatload of java API to it runs against that) you can use
certain parallel objects in the freemarker.ext.beans package. For
example, by default, when you expose a date to a freemarker template, it
is an instance of freemarker.template.SimpleDate, but you could
alternatively use freemarker.ext.beans.DateModel. See:

http://freemarker.org/docs/api/freemarker/ext/beans/DateModel.html

You'll actually get vended one if you use the BeansWrapper, so you can go:

TemplateModel myDate = BeansWrapper.getDefaultInstance().wrap(new Date());

dataModel.put("myDate", myDate);

and in the template ${date.getTime()) or ${date.time} should work.

In general, note that there are parallel implementations of the core
freemarker interfaces in freemarker.ext.beans that tend to expose full
java API as opposed to the SimpleXXX implementations in freemarker.template.

That's the first answer and the easiest, because it's a ready-made
out-of-the-box solution.

Here's a second answer. Preamble: FreeMarker's design is such that the
type system in the template language is based on a set of interfaces in
the freemarker.template package, the classnames following the naming
convention TemplateXXXModel. These tend to be very lean interfaces.
TemplateDateModel, for example, only has two methods. If you want
something to be interpretable as a hash in the right context, you can
have it implement TemplateHashModel. So, let's say you write your
own little class that is a FreeMarker SimpleDate but also has a hashkey
called "timeStamp". Really quite easy.

public class MyDate extends SimpleDate implements TemplateHashModel {

public MyDate(Date d) {
super(d);
}

public TemplateHashModel get(String key) throws
TemplateModelException {

if ("timeStamp".equals(key)) {
return new SimpleScalar(""+ this.getAsDate().getTime());
}
throw new TemplateModelException("only accepts 'timeStamp' as
key");

}
}


And then:

dateModel.put("myDate", new MyDate(new Date()));

and in the template:

${myDate.timeStamp}

should work, myDate.timeStamp will be a string like "1118155003281" or
something.

Now, here is a third way to get what you want: Stick a helper method in
the context that gets the timestamp you want. It would have to implement
TemplateMethodModel.

class TimeStampExtractor implements TemplateMethodModelEx {
public Object exec(List args) throws TemplateModelException {
if (args.size() != 1) throw new
TemplateModelException("expecting 1 arg");
Object arg = args.get(0);
if (!(arg instanceof TemplateDateModel)) throw new
TemplateModelException("This method only deals with dates. You passed in
a " + arg.getClass().getName());
TemplateDateModel tdm = (TemplateDateModel) arg;
long t = tdm.getAsDate().getTime();
return new SimpleScalar("" + t);

// or possibly: return new SimpleNumber(new Long(t));
// This would return a number rather than a string.
// YOu probably just want a string for your purposes though.
}
}

dataModel.put("extractTimeStamp", new TimeStampExtractor());

and then in the template:

${extractTimeStamp(myDate)}

would work just fine.

I hope that's helpful. All you needed was the first answer, but the
second two answers give you tools to resolve things when there is not an
immediate out-of-the-box solution.

Jonathan
Post by Joe Hudson
Joe
-----Original Message-----
Revusky
Sent: Tuesday, June 07, 2005 8:44 AM
Subject: [FreeMarker-user] Re: how to call java.util.Date.getTime()
Post by Joe Hudson
Hello, I am unable to figure out how to call getTime() on a Date object.
Joe,
FreeMarker has a different approach in that it is not based on simply
dropping in Java API to the template layer. In fact, when working on a
FreeMarker template, you should try to temporarily forget that you are a
java programmer and know anything about a java API. So, a FreeMarker
data object is not a java.util.Date.
(Note that a java.util.Date is just a very thin wrapper around a long
that contains the number of milliseconds elapsed since the new year of
1970, UTC. (What should actually be called Date probably is
java.util.Calendar. The whole java API regarding time/date is not well
designed or well named...))
Anyway, Date.getTime() just returns the number of milliseconds since
1/1/70. Why would a template writer want that?
We try to expose generally useful built-ins that people would use when
producing web pages or other human readable output. So, while exposing
Date.getTime() would be very easy, would anybody want it? Or really,
getting to first principles, isn't a template about converting
computerized data into a format that is readable to humans -- as opposed
to the other way round????
Actually, why do you want it? (If you want it for sorting/comparison
purposes, which is the only thing that occurs to me, we have
sorting/comparison on dates working anyway.)
Of course, if you really do need this, you can expose any java object
directly to the template by explicitly using the beanswrapper for this
model.expose("myDate", BeansWrapper.getDefaultInstance().wrap(new Date()));
And then date.getTime() or more simply date.time would provide the
number of milliseconds since 1/1/70.
Regards,
Jonathan Revusky
Post by Joe Hudson
I have tried ${date.time} which produces an error.
I see no reference to do this on
http://www.freemarker.org/docs/ref_builtins_date.html
Could somebody please tell me how this can be done? Thank you very much.
Joe
-------------------------------------------------------
This SF.Net email is sponsored by: NEC IT Guy Games. How far can you
shotput
a projector? How fast can you ride your desk chair down the office luge
track?
If you want to score the big prize, get to know the little guy.
Play to win an NEC 61" plasma display: http://www.necitguy.com/?r=20
_______________________________________________
FreeMarker-user mailing list
https://lists.sourceforge.net/lists/listinfo/freemarker-user
-------------------------------------------------------
This SF.Net email is sponsored by: NEC IT Guy Games. How far can you shotput
a projector? How fast can you ride your desk chair down the office luge track?
If you want to score the big prize, get to know the little guy.
Play to win an NEC 61" plasma display: http://www.necitguy.com/?r=20
_______________________________________________
FreeMarker-user mailing list
https://lists.sourceforge.net/lists/listinfo/freemarker-user
Daniel Dekany
2005-06-07 15:04:07 UTC
Permalink
Post by Joe Hudson
Hi Jonathan, I will try to stop bothering you real soon, I promise!
In regard to this answer, I really like the "built in" functionality that I
would loose if I used the bean wrapper. Is there any way I can extend the
TemplateDateModel (and tell freemarker to use my class for date objects) to
add the functionality that I need but keep the cool functionality that
already exists? Thanks.
Joe
Yes, just not on the way you try to do it. There are two approaches for
the solution, if you want to print the milliseconds stored in a date:

a) Write a TemplateMethodModelEx implementation that extracts that from
a date variable passed to it as argument, and drop an instance of that
TemplateMethodModelEx into the data model (maybe preferably as shared
variable, which are very similar to Velocity's "tools" concept; see in
the API of the Configuration class), for example with name
"time_millis". Then you can do ${time_millis(theDate)}. It's pretty much
the same as using a built-in, but its syntax is a bit different (i.e.
it's not written as ${theDate?time_millis}). (Technically we could
introduce time_millis as built-in, but I guess there is no big enough
demand for it that justifies adding one more built-in. However, I'm one
who often criticize the philosophy that we don't add built-ins without
big demand for it... we had 3 times more built-ins... so what? Totally
lexical info... If you need something, you search the built-in
reference, otherwise you don't read it.)

b) You wrap Date-s into your own TemplateDateModel implementation (it's
normal to use custom wrappers, not a hacking) that has a timeMillis
subvariable, so you can write ${theDate.timeMillis}.

I think a) is better, because it is easier as it will work with all date
variables, and also it is IMO a bit philosophically nicer.
--
Best regards,
Daniel Dekany
Barrie Selack
2005-08-03 19:30:57 UTC
Permalink
Actually I'd like to see the ?time_millis added as a built-in. I working
with some objects (from a third party library) which contain dates and
I'd like to do date math to show the difference in the dates (end-start)
and be able to format that nicely (e.g. 7 minutes, or 2 hours) I could
wrap the objects with my own object and do the conversions in the
controller, but that seems like unnecessary work.

If you have a good example of the TemplateMethodModelEx you describe
below, that would be a stop gap, but I'd stll like to see the built-in added.

Thanks,

Barrie
Post by Daniel Dekany
Post by Joe Hudson
Hi Jonathan, I will try to stop bothering you real soon, I promise!
In regard to this answer, I really like the "built in" functionality that I
would loose if I used the bean wrapper. Is there any way I can extend the
TemplateDateModel (and tell freemarker to use my class for date objects) to
add the functionality that I need but keep the cool functionality that
already exists? Thanks.
Joe
Yes, just not on the way you try to do it. There are two approaches for
a) Write a TemplateMethodModelEx implementation that extracts that from
a date variable passed to it as argument, and drop an instance of that
TemplateMethodModelEx into the data model (maybe preferably as shared
variable, which are very similar to Velocity's "tools" concept; see in
the API of the Configuration class), for example with name
"time_millis". Then you can do ${time_millis(theDate)}. It's pretty much
the same as using a built-in, but its syntax is a bit different (i.e.
it's not written as ${theDate?time_millis}). (Technically we could
introduce time_millis as built-in, but I guess there is no big enough
demand for it that justifies adding one more built-in. However, I'm one
who often criticize the philosophy that we don't add built-ins without
big demand for it... we had 3 times more built-ins... so what? Totally
lexical info... If you need something, you search the built-in
reference, otherwise you don't read it.)
b) You wrap Date-s into your own TemplateDateModel implementation (it's
normal to use custom wrappers, not a hacking) that has a timeMillis
subvariable, so you can write ${theDate.timeMillis}.
I think a) is better, because it is easier as it will work with all date
variables, and also it is IMO a bit philosophically nicer.
--
Best regards,
Daniel Dekany
-------------------------------------------------------
This SF.Net email is sponsored by: NEC IT Guy Games. How far can you shotput
a projector? How fast can you ride your desk chair down the office luge
track?
Post by Daniel Dekany
If you want to score the big prize, get to know the little guy.
Play to win an NEC 61" plasma display: http://www.necitguy.com/?r=20
_______________________________________________
FreeMarker-user mailing list
https://lists.sourceforge.net/lists/listinfo/freemarker-user
Daniel Dekany
2005-08-04 11:17:19 UTC
Permalink
Post by Barrie Selack
Actually I'd like to see the ?time_millis added as a built-in. I working
with some objects (from a third party library) which contain dates and
I'd like to do date math to show the difference in the dates (end-start)
and be able to format that nicely (e.g. 7 minutes, or 2 hours) I could
wrap the objects with my own object and do the conversions in the
controller, but that seems like unnecessary work.
If you have a good example of the TemplateMethodModelEx you describe
below, that would be a stop gap, but I'd stll like to see the built-in added.
Well, date math is too tricky to be done in a view template, don't you
think? And even if you have ?time_millis, you will need to convert the
time duration value to String, and you will need a Java method that can
do that (BTW I don't remember I have seen anything in the Java platform
that can format time durations... is there a such facility?). So, if I
understand well, you want to do this (where formatTimeDuration was
created by you):

${formatTimeDuration(t2?time_millis - t1?time_millis)}

But then, why not write the formatTimeDuration so it accepts 2
java.util.Date argument, so you could do this:

${formatTimeDuration(t1, t2)}
Post by Barrie Selack
Thanks,
Barrie
--
Best regards,
Daniel Dekany
Joe Hudson
2005-06-07 14:55:00 UTC
Permalink
Thank you very much, I can't tell you how helpful this has been to me,
Jonathan.

Joe

-----Original Message-----
From: freemarker-user-***@lists.sourceforge.net
[mailto:freemarker-user-***@lists.sourceforge.net] On Behalf Of Jonathan
Revusky
Sent: Tuesday, June 07, 2005 10:49 AM
To: freemarker-***@lists.sourceforge.net
Subject: Re: [FreeMarker-user] Re: how to call java.util.Date.getTime()
Post by Joe Hudson
Hi Jonathan, I will try to stop bothering you real soon, I promise!
No problem. This list exists for this purpose.
Post by Joe Hudson
In regard to this answer, I really like the "built in" functionality that
I
Post by Joe Hudson
would loose if I used the bean wrapper. Is there any way I can extend the
TemplateDateModel (and tell freemarker to use my class for date objects)
to
Post by Joe Hudson
add the functionality that I need but keep the cool functionality that
already exists? Thanks.
Well, I'm going to give you various long-winded answers, more than you
actually need, to help you get a conceptual model of how FM works and
how to solve such problems.

The first answer to your question is that if you want the methods on the
object to be exposed (IMO, you should only do this if necessary because
you should try to keep your template's underlying data model simple and
exposing a boatload of java API to it runs against that) you can use
certain parallel objects in the freemarker.ext.beans package. For
example, by default, when you expose a date to a freemarker template, it
is an instance of freemarker.template.SimpleDate, but you could
alternatively use freemarker.ext.beans.DateModel. See:

http://freemarker.org/docs/api/freemarker/ext/beans/DateModel.html

You'll actually get vended one if you use the BeansWrapper, so you can go:

TemplateModel myDate = BeansWrapper.getDefaultInstance().wrap(new Date());

dataModel.put("myDate", myDate);

and in the template ${date.getTime()) or ${date.time} should work.

In general, note that there are parallel implementations of the core
freemarker interfaces in freemarker.ext.beans that tend to expose full
java API as opposed to the SimpleXXX implementations in freemarker.template.

That's the first answer and the easiest, because it's a ready-made
out-of-the-box solution.

Here's a second answer. Preamble: FreeMarker's design is such that the
type system in the template language is based on a set of interfaces in
the freemarker.template package, the classnames following the naming
convention TemplateXXXModel. These tend to be very lean interfaces.
TemplateDateModel, for example, only has two methods. If you want
something to be interpretable as a hash in the right context, you can
have it implement TemplateHashModel. So, let's say you write your
own little class that is a FreeMarker SimpleDate but also has a hashkey
called "timeStamp". Really quite easy.

public class MyDate extends SimpleDate implements TemplateHashModel {

public MyDate(Date d) {
super(d);
}

public TemplateHashModel get(String key) throws
TemplateModelException {

if ("timeStamp".equals(key)) {
return new SimpleScalar(""+ this.getAsDate().getTime());
}
throw new TemplateModelException("only accepts 'timeStamp' as
key");

}
}


And then:

dateModel.put("myDate", new MyDate(new Date()));

and in the template:

${myDate.timeStamp}

should work, myDate.timeStamp will be a string like "1118155003281" or
something.

Now, here is a third way to get what you want: Stick a helper method in
the context that gets the timestamp you want. It would have to implement
TemplateMethodModel.

class TimeStampExtractor implements TemplateMethodModelEx {
public Object exec(List args) throws TemplateModelException {
if (args.size() != 1) throw new
TemplateModelException("expecting 1 arg");
Object arg = args.get(0);
if (!(arg instanceof TemplateDateModel)) throw new
TemplateModelException("This method only deals with dates. You passed in
a " + arg.getClass().getName());
TemplateDateModel tdm = (TemplateDateModel) arg;
long t = tdm.getAsDate().getTime();
return new SimpleScalar("" + t);

// or possibly: return new SimpleNumber(new Long(t));
// This would return a number rather than a string.
// YOu probably just want a string for your purposes though.
}
}

dataModel.put("extractTimeStamp", new TimeStampExtractor());

and then in the template:

${extractTimeStamp(myDate)}

would work just fine.

I hope that's helpful. All you needed was the first answer, but the
second two answers give you tools to resolve things when there is not an
immediate out-of-the-box solution.

Jonathan
Post by Joe Hudson
Joe
-----Original Message-----
Revusky
Sent: Tuesday, June 07, 2005 8:44 AM
Subject: [FreeMarker-user] Re: how to call java.util.Date.getTime()
Post by Joe Hudson
Hello, I am unable to figure out how to call getTime() on a Date object.
Joe,
FreeMarker has a different approach in that it is not based on simply
dropping in Java API to the template layer. In fact, when working on a
FreeMarker template, you should try to temporarily forget that you are a
java programmer and know anything about a java API. So, a FreeMarker
data object is not a java.util.Date.
(Note that a java.util.Date is just a very thin wrapper around a long
that contains the number of milliseconds elapsed since the new year of
1970, UTC. (What should actually be called Date probably is
java.util.Calendar. The whole java API regarding time/date is not well
designed or well named...))
Anyway, Date.getTime() just returns the number of milliseconds since
1/1/70. Why would a template writer want that?
We try to expose generally useful built-ins that people would use when
producing web pages or other human readable output. So, while exposing
Date.getTime() would be very easy, would anybody want it? Or really,
getting to first principles, isn't a template about converting
computerized data into a format that is readable to humans -- as opposed
to the other way round????
Actually, why do you want it? (If you want it for sorting/comparison
purposes, which is the only thing that occurs to me, we have
sorting/comparison on dates working anyway.)
Of course, if you really do need this, you can expose any java object
directly to the template by explicitly using the beanswrapper for this
model.expose("myDate", BeansWrapper.getDefaultInstance().wrap(new
Date()));
Post by Joe Hudson
And then date.getTime() or more simply date.time would provide the
number of milliseconds since 1/1/70.
Regards,
Jonathan Revusky
Post by Joe Hudson
I have tried ${date.time} which produces an error.
I see no reference to do this on
http://www.freemarker.org/docs/ref_builtins_date.html
Could somebody please tell me how this can be done? Thank you very much.
Joe
-------------------------------------------------------
This SF.Net email is sponsored by: NEC IT Guy Games. How far can you
shotput
a projector? How fast can you ride your desk chair down the office luge
track?
If you want to score the big prize, get to know the little guy.
Play to win an NEC 61" plasma display: http://www.necitguy.com/?r=20
_______________________________________________
FreeMarker-user mailing list
https://lists.sourceforge.net/lists/listinfo/freemarker-user
-------------------------------------------------------
This SF.Net email is sponsored by: NEC IT Guy Games. How far can you
shotput
Post by Joe Hudson
a projector? How fast can you ride your desk chair down the office luge
track?
Post by Joe Hudson
If you want to score the big prize, get to know the little guy.
Play to win an NEC 61" plasma display: http://www.necitguy.com/?r=20
_______________________________________________
FreeMarker-user mailing list
https://lists.sourceforge.net/lists/listinfo/freemarker-user
-------------------------------------------------------
This SF.Net email is sponsored by: NEC IT Guy Games. How far can you
shotput
a projector? How fast can you ride your desk chair down the office luge
track?
If you want to score the big prize, get to know the little guy.
Play to win an NEC 61" plasma display: http://www.necitguy.com/?r=20
Joe Hudson
2005-06-07 14:59:07 UTC
Permalink
Say I create an extension of the freemarker.template.SimpleDate object. Is
there an environmental setting that I can use to tell FreeMarker to always
use my custom class as the date wrapper as opposed to the
freemarker.template.SimpleDate class? This sounds like the best idea for
me. Thanks.

Joe

-----Original Message-----
From: freemarker-user-***@lists.sourceforge.net
[mailto:freemarker-user-***@lists.sourceforge.net] On Behalf Of Jonathan
Revusky
Sent: Tuesday, June 07, 2005 10:49 AM
To: freemarker-***@lists.sourceforge.net
Subject: Re: [FreeMarker-user] Re: how to call java.util.Date.getTime()
Post by Joe Hudson
Hi Jonathan, I will try to stop bothering you real soon, I promise!
No problem. This list exists for this purpose.
Post by Joe Hudson
In regard to this answer, I really like the "built in" functionality that
I
Post by Joe Hudson
would loose if I used the bean wrapper. Is there any way I can extend the
TemplateDateModel (and tell freemarker to use my class for date objects)
to
Post by Joe Hudson
add the functionality that I need but keep the cool functionality that
already exists? Thanks.
Well, I'm going to give you various long-winded answers, more than you
actually need, to help you get a conceptual model of how FM works and
how to solve such problems.

The first answer to your question is that if you want the methods on the
object to be exposed (IMO, you should only do this if necessary because
you should try to keep your template's underlying data model simple and
exposing a boatload of java API to it runs against that) you can use
certain parallel objects in the freemarker.ext.beans package. For
example, by default, when you expose a date to a freemarker template, it
is an instance of freemarker.template.SimpleDate, but you could
alternatively use freemarker.ext.beans.DateModel. See:

http://freemarker.org/docs/api/freemarker/ext/beans/DateModel.html

You'll actually get vended one if you use the BeansWrapper, so you can go:

TemplateModel myDate = BeansWrapper.getDefaultInstance().wrap(new Date());

dataModel.put("myDate", myDate);

and in the template ${date.getTime()) or ${date.time} should work.

In general, note that there are parallel implementations of the core
freemarker interfaces in freemarker.ext.beans that tend to expose full
java API as opposed to the SimpleXXX implementations in freemarker.template.

That's the first answer and the easiest, because it's a ready-made
out-of-the-box solution.

Here's a second answer. Preamble: FreeMarker's design is such that the
type system in the template language is based on a set of interfaces in
the freemarker.template package, the classnames following the naming
convention TemplateXXXModel. These tend to be very lean interfaces.
TemplateDateModel, for example, only has two methods. If you want
something to be interpretable as a hash in the right context, you can
have it implement TemplateHashModel. So, let's say you write your
own little class that is a FreeMarker SimpleDate but also has a hashkey
called "timeStamp". Really quite easy.

public class MyDate extends SimpleDate implements TemplateHashModel {

public MyDate(Date d) {
super(d);
}

public TemplateHashModel get(String key) throws
TemplateModelException {

if ("timeStamp".equals(key)) {
return new SimpleScalar(""+ this.getAsDate().getTime());
}
throw new TemplateModelException("only accepts 'timeStamp' as
key");

}
}


And then:

dateModel.put("myDate", new MyDate(new Date()));

and in the template:

${myDate.timeStamp}

should work, myDate.timeStamp will be a string like "1118155003281" or
something.

Now, here is a third way to get what you want: Stick a helper method in
the context that gets the timestamp you want. It would have to implement
TemplateMethodModel.

class TimeStampExtractor implements TemplateMethodModelEx {
public Object exec(List args) throws TemplateModelException {
if (args.size() != 1) throw new
TemplateModelException("expecting 1 arg");
Object arg = args.get(0);
if (!(arg instanceof TemplateDateModel)) throw new
TemplateModelException("This method only deals with dates. You passed in
a " + arg.getClass().getName());
TemplateDateModel tdm = (TemplateDateModel) arg;
long t = tdm.getAsDate().getTime();
return new SimpleScalar("" + t);

// or possibly: return new SimpleNumber(new Long(t));
// This would return a number rather than a string.
// YOu probably just want a string for your purposes though.
}
}

dataModel.put("extractTimeStamp", new TimeStampExtractor());

and then in the template:

${extractTimeStamp(myDate)}

would work just fine.

I hope that's helpful. All you needed was the first answer, but the
second two answers give you tools to resolve things when there is not an
immediate out-of-the-box solution.

Jonathan
Post by Joe Hudson
Joe
-----Original Message-----
Revusky
Sent: Tuesday, June 07, 2005 8:44 AM
Subject: [FreeMarker-user] Re: how to call java.util.Date.getTime()
Post by Joe Hudson
Hello, I am unable to figure out how to call getTime() on a Date object.
Joe,
FreeMarker has a different approach in that it is not based on simply
dropping in Java API to the template layer. In fact, when working on a
FreeMarker template, you should try to temporarily forget that you are a
java programmer and know anything about a java API. So, a FreeMarker
data object is not a java.util.Date.
(Note that a java.util.Date is just a very thin wrapper around a long
that contains the number of milliseconds elapsed since the new year of
1970, UTC. (What should actually be called Date probably is
java.util.Calendar. The whole java API regarding time/date is not well
designed or well named...))
Anyway, Date.getTime() just returns the number of milliseconds since
1/1/70. Why would a template writer want that?
We try to expose generally useful built-ins that people would use when
producing web pages or other human readable output. So, while exposing
Date.getTime() would be very easy, would anybody want it? Or really,
getting to first principles, isn't a template about converting
computerized data into a format that is readable to humans -- as opposed
to the other way round????
Actually, why do you want it? (If you want it for sorting/comparison
purposes, which is the only thing that occurs to me, we have
sorting/comparison on dates working anyway.)
Of course, if you really do need this, you can expose any java object
directly to the template by explicitly using the beanswrapper for this
model.expose("myDate", BeansWrapper.getDefaultInstance().wrap(new
Date()));
Post by Joe Hudson
And then date.getTime() or more simply date.time would provide the
number of milliseconds since 1/1/70.
Regards,
Jonathan Revusky
Post by Joe Hudson
I have tried ${date.time} which produces an error.
I see no reference to do this on
http://www.freemarker.org/docs/ref_builtins_date.html
Could somebody please tell me how this can be done? Thank you very much.
Joe
-------------------------------------------------------
This SF.Net email is sponsored by: NEC IT Guy Games. How far can you
shotput
a projector? How fast can you ride your desk chair down the office luge
track?
If you want to score the big prize, get to know the little guy.
Play to win an NEC 61" plasma display: http://www.necitguy.com/?r=20
_______________________________________________
FreeMarker-user mailing list
https://lists.sourceforge.net/lists/listinfo/freemarker-user
-------------------------------------------------------
This SF.Net email is sponsored by: NEC IT Guy Games. How far can you
shotput
Post by Joe Hudson
a projector? How fast can you ride your desk chair down the office luge
track?
Post by Joe Hudson
If you want to score the big prize, get to know the little guy.
Play to win an NEC 61" plasma display: http://www.necitguy.com/?r=20
_______________________________________________
FreeMarker-user mailing list
https://lists.sourceforge.net/lists/listinfo/freemarker-user
-------------------------------------------------------
This SF.Net email is sponsored by: NEC IT Guy Games. How far can you
shotput
a projector? How fast can you ride your desk chair down the office luge
track?
If you want to score the big prize, get to know the little guy.
Play to win an NEC 61" plasma display: http://www.necitguy.com/?r=20
Jonathan Revusky
2005-06-07 15:23:00 UTC
Permalink
Post by Joe Hudson
Say I create an extension of the freemarker.template.SimpleDate object. Is
there an environmental setting that I can use to tell FreeMarker to always
use my custom class as the date wrapper as opposed to the
freemarker.template.SimpleDate class? This sounds like the best idea for
me. Thanks.
Look at our ObjectWrapper API.

If you get a FreeMarker Configuration object, you can set the object
wrapper.

So, you can define your own ObjectWrapper like:

class MyObjectWrapper extends DefaultObjectWrapper {

public TemplateModel wrap(Object obj) throws TemplateModelException {
if (obj instanceof Date) {
return new MyCustomDate((Date) obj);
}
if (obj instanceof Calendar) {
return new MyCustomDate(((Calendar)obj).getTime());
}
return super.wrap(obj);
}
}

conf.setObjectWrapper(new MyObjectWrapper());

And then whenever you expose a date to your datamodel, assuming that the
configuration object in question is in use, the thing will expose it to
the template using your custom date object.

One little caveat to this is that if you create a new time/date object
in FTL using the ?date built-in, it will create a SimpleDate object, not
your custom object. This maybe should be revisited. Probably when a
built-in creates a date or string or number, it should create one using
the object wrapper from the configuration. Currently, it pretty much
just uses the SimpleXXX objects.

That said, there has been very little feedback on this kind of thing, so
it is working well for most people. Anyway, that's a little wrinkle
that I maybe shouldn't even mention in this instance because it
complicates the story.

Basically, if you use an ObjectWrapper as above that vends instances of
your custom date you will likely be A-OK.

BTW, why do you prefer this solution rather than my solution #3 of the
previous mail, which was just to stick a TimeStampExtractor helper
method in the context? I would have thought that was cleaner than
creating your own SimpleDate subclass. I mean, having the thing
implement TemplateHashModel, i.e. be a hash as well as a date solely in
order to have one hash key hardly seems so great. (Though, you might
intend to add a bunch more special keys in which case it starts to make
sense.)

Also, the TimeStampExtractor has the advantage that it works with any
date objects, not just your custom date.

Cheers,

Jonathan
Post by Joe Hudson
Joe
Joe Hudson
2005-06-07 15:36:59 UTC
Permalink
Thanks you, this is exactly what I needed to know.

I probably (since the ?date would never return an instance of my custom
class) will create the helper method. If I could do what I wish, I would
like to be able to implement my own date wrapper class and be able to add
built-in support myself so I could do ${myDate?time_millis}.

I certainly understand you guys not wanting to add stuff that only one
person needs. I would do it myself if I had that functionality in the
interface.

But, even with these few issues that I have run into (which are mostly must
learning curve on my part), I can't tell you how impressed I am with this
language. It blows Velocity out of the water! I'm just sorry I didn't
stumble onto it before now. Thanks so much for creating this.

Joe

-----Original Message-----
From: freemarker-user-***@lists.sourceforge.net
[mailto:freemarker-user-***@lists.sourceforge.net] On Behalf Of Jonathan
Revusky
Sent: Tuesday, June 07, 2005 11:23 AM
To: freemarker-***@lists.sourceforge.net
Subject: Re: [FreeMarker-user] Re: how to call java.util.Date.getTime()
Post by Joe Hudson
Say I create an extension of the freemarker.template.SimpleDate object.
Is
Post by Joe Hudson
there an environmental setting that I can use to tell FreeMarker to always
use my custom class as the date wrapper as opposed to the
freemarker.template.SimpleDate class? This sounds like the best idea for
me. Thanks.
Look at our ObjectWrapper API.

If you get a FreeMarker Configuration object, you can set the object
wrapper.

So, you can define your own ObjectWrapper like:

class MyObjectWrapper extends DefaultObjectWrapper {

public TemplateModel wrap(Object obj) throws TemplateModelException {
if (obj instanceof Date) {
return new MyCustomDate((Date) obj);
}
if (obj instanceof Calendar) {
return new MyCustomDate(((Calendar)obj).getTime());
}
return super.wrap(obj);
}
}

conf.setObjectWrapper(new MyObjectWrapper());

And then whenever you expose a date to your datamodel, assuming that the
configuration object in question is in use, the thing will expose it to
the template using your custom date object.

One little caveat to this is that if you create a new time/date object
in FTL using the ?date built-in, it will create a SimpleDate object, not
your custom object. This maybe should be revisited. Probably when a
built-in creates a date or string or number, it should create one using
the object wrapper from the configuration. Currently, it pretty much
just uses the SimpleXXX objects.

That said, there has been very little feedback on this kind of thing, so
it is working well for most people. Anyway, that's a little wrinkle
that I maybe shouldn't even mention in this instance because it
complicates the story.

Basically, if you use an ObjectWrapper as above that vends instances of
your custom date you will likely be A-OK.

BTW, why do you prefer this solution rather than my solution #3 of the
previous mail, which was just to stick a TimeStampExtractor helper
method in the context? I would have thought that was cleaner than
creating your own SimpleDate subclass. I mean, having the thing
implement TemplateHashModel, i.e. be a hash as well as a date solely in
order to have one hash key hardly seems so great. (Though, you might
intend to add a bunch more special keys in which case it starts to make
sense.)

Also, the TimeStampExtractor has the advantage that it works with any
date objects, not just your custom date.

Cheers,

Jonathan
Post by Joe Hudson
Joe
-------------------------------------------------------
This SF.Net email is sponsored by: NEC IT Guy Games. How far can you
shotput
a projector? How fast can you ride your desk chair down the office luge
track?
If you want to score the big prize, get to know the little guy.
Play to win an NEC 61" plasma display: http://www.necitguy.com/?r=20
Daniel Dekany
2005-06-07 15:48:42 UTC
Permalink
Post by Joe Hudson
Thanks you, this is exactly what I needed to know.
I probably (since the ?date would never return an instance of my custom
class) will create the helper method. If I could do what I wish, I would
like to be able to implement my own date wrapper class and be able to add
built-in support myself so I could do ${myDate?time_millis}.
If you would be able to add new built-ins, the point of built-ins should
be gone. It's that they are in "name-space" that is reserved for the
FreeMarker core, so adding new ones doesn't break backward compatibility
(and also of course they don't interfere with the names of the variables
in the data model).
Post by Joe Hudson
I certainly understand you guys not wanting to add stuff that only one
person needs. I would do it myself if I had that functionality in the
interface.
But, even with these few issues that I have run into (which are mostly
must learning curve on my part), I can't tell you how impressed I am
with this language. It blows Velocity out of the water! I'm just sorry
I didn't stumble onto it before now. Thanks so much for creating this.
Joe
--
Best regards,
Daniel Dekany
Attila Szegedi
2005-06-07 16:17:55 UTC
Permalink
I believe that this is because DefaultObjectWrapper (the default object
wrapper in FM) hijacks creation of date wrappers from the BeansWrapper.

If you set BeansWrapper to be your Configuration's object wrapper, you
will be able to use ${date.time}.

Attila.
Post by Joe Hudson
Hello, I am unable to figure out how to call getTime() on a Date object.
I have tried ${date.time} which produces an error.
I see no reference to do this on
http://www.freemarker.org/docs/ref_builtins_date.html
Could somebody please tell me how this can be done? Thank you very much.
Joe
Daniel Dekany
2005-06-07 17:33:15 UTC
Permalink
Post by Attila Szegedi
I believe that this is because DefaultObjectWrapper (the default object
wrapper in FM) hijacks creation of date wrappers from the BeansWrapper.
If you set BeansWrapper to be your Configuration's object wrapper, you
will be able to use ${date.time}.
Attila.
It would be better to say that the DefaultObjectWrapper passes things
that it can't handle to the BeansWrapper, such as the wrapping of custom
beans. So this is just an addition to the DefaultObjectWrapper. However
it has led to a problem that SimpleXxx stuff don't get unwrapped when
you call a Java method via BeansWrapper, because they don't implement
freemarker.ext.util.WrapperTemplateModel. Maybe they should?
Post by Attila Szegedi
Post by Joe Hudson
Hello, I am unable to figure out how to call getTime() on a Date object.
I have tried ${date.time} which produces an error.
I see no reference to do this on
http://www.freemarker.org/docs/ref_builtins_date.html
Could somebody please tell me how this can be done? Thank you very much.
Joe
--
Best regards,
Daniel Dekany
Jonathan Revusky
2005-06-07 22:15:01 UTC
Permalink
Post by Daniel Dekany
Post by Attila Szegedi
I believe that this is because DefaultObjectWrapper (the default object
wrapper in FM) hijacks creation of date wrappers from the BeansWrapper.
If you set BeansWrapper to be your Configuration's object wrapper, you
will be able to use ${date.time}.
Attila.
It would be better to say that the DefaultObjectWrapper passes things
that it can't handle to the BeansWrapper, such as the wrapping of custom
beans. So this is just an addition to the DefaultObjectWrapper. However
it has led to a problem that SimpleXxx stuff don't get unwrapped when
you call a Java method via BeansWrapper, because they don't implement
freemarker.ext.util.WrapperTemplateModel. Maybe they should?
Yeah, I think it's so trivial to implement this API, they probably should.

I can't really see any disadvantage.

Of course, that said, it's not as if the issue has come up much on this
list or anything.

But now that webwork is switching to FM as its default UI, we may be
getting a flood of Velocity refugees showing up, who are accustomed to
just passing off all kinds of objects to a java API from the template.
We should probably tweak some things like this to adhere to the
principle of least surprise to the extent that's reasonable.

JR
Post by Daniel Dekany
Post by Attila Szegedi
Post by Joe Hudson
Hello, I am unable to figure out how to call getTime() on a Date object.
I have tried ${date.time} which produces an error.
I see no reference to do this on
http://www.freemarker.org/docs/ref_builtins_date.html
Could somebody please tell me how this can be done? Thank you very much.
Joe
Joe Hudson
2005-06-07 19:08:44 UTC
Permalink
It's me again :)

Is there any way to allow bean property access starting with an upper case
letter?

For example if my object has a method called getFoo()

Can I call ${obj.Foo} instead of ${obj.foo}? I would very much like to do
this. Thanks.

Joe
Daniel Dekany
2005-06-07 19:36:00 UTC
Permalink
Post by Joe Hudson
It's me again :)
Is there any way to allow bean property access starting with an upper case
letter?
None out-of-the-box. The BeansWrapper works according the Java Beans
Specification, which also decides what case is used when. In principle
of course you could use your own ObjectWrapper... if you start out from
BeansWrapper, maybe that's not even hard.

Why is this needed anyway?
Post by Joe Hudson
For example if my object has a method called getFoo()
Can I call ${obj.Foo} instead of ${obj.foo}? I would very much like to do
this. Thanks.
Joe
--
Best regards,
Daniel Dekany
Attila Szegedi
2005-06-09 15:22:36 UTC
Permalink
Post by Joe Hudson
It's me again :)
Is there any way to allow bean property access starting with an upper case
letter?
Sure. Write your own object wrapper :-) BeansWrapper is quite strict about
adhering to JavaBeans specification. Actually, all it does is use the
information discovered using the stock java.beans.Introspector, so it's
100% JavaBeans compliant, which means properties start with a lowercase
letter.

Come to think about it, if you deployed custom BeanInfo classes along your
classes, you could rename the bean properties to start with uppercase.
Yes, I guess I'm joking :-)

Attila.
--
home: http://www.szegedi.org
weblog: http://www.jroller.com/page/aszegedi
Visit Szegedi Butterfly fractals at:
http://www.szegedi.org/fractals/butterfly/index.html
Joe Hudson
2005-06-07 19:44:04 UTC
Permalink
It's just personal preference... that's all :)

-----Original Message-----
From: freemarker-user-***@lists.sourceforge.net
[mailto:freemarker-user-***@lists.sourceforge.net] On Behalf Of Daniel
Dekany
Sent: Tuesday, June 07, 2005 3:36 PM
To: Joe Hudson
Subject: Re: [FreeMarker-user] bean property access starting with upper case
Post by Joe Hudson
It's me again :)
Is there any way to allow bean property access starting with an upper case
letter?
None out-of-the-box. The BeansWrapper works according the Java Beans
Specification, which also decides what case is used when. In principle
of course you could use your own ObjectWrapper... if you start out from
BeansWrapper, maybe that's not even hard.

Why is this needed anyway?
Post by Joe Hudson
For example if my object has a method called getFoo()
Can I call ${obj.Foo} instead of ${obj.foo}? I would very much like to do
this. Thanks.
Joe
--
Best regards,
Daniel Dekany



-------------------------------------------------------
This SF.Net email is sponsored by: NEC IT Guy Games. How far can you
shotput
a projector? How fast can you ride your desk chair down the office luge
track?
If you want to score the big prize, get to know the little guy.
Play to win an NEC 61" plasma display: http://www.necitguy.com/?r=20
Jonathan Revusky
2005-06-07 22:25:00 UTC
Permalink
Post by Joe Hudson
It's just personal preference... that's all :)
Well, now that you know about writing custom subclasses of our objects
and plugging in your custom ObjectWrapper to vend those custom
subclasses, it would be a fairly simple exercise to get this working.
You subclass freemarker.ext.beans.BeanModel so that it tries both key
and Key.

TemplateModel get(String key) throws TemplateModelException {
TemplateModel result = super.get(key);
if (result == null) {
result = super.get(key.substring(0,1).toUpperCase() +
key.substring(1));
}
return result;
}

And then you have a custom object wrapper that vends your custom
subclass instead of BeanModel.

But frankly, it doesn't seem like it's worth it. I think you should
maybe just get used to how it works in FM. Isn't the desire to write
obj.Foo instead of obj.foo a little bit on the frivolous side?

JR
Post by Joe Hudson
-----Original Message-----
Dekany
Sent: Tuesday, June 07, 2005 3:36 PM
To: Joe Hudson
Subject: Re: [FreeMarker-user] bean property access starting with upper case
Post by Joe Hudson
It's me again :)
Is there any way to allow bean property access starting with an upper case
letter?
None out-of-the-box. The BeansWrapper works according the Java Beans
Specification, which also decides what case is used when. In principle
of course you could use your own ObjectWrapper... if you start out from
BeansWrapper, maybe that's not even hard.
Why is this needed anyway?
Post by Joe Hudson
For example if my object has a method called getFoo()
Can I call ${obj.Foo} instead of ${obj.foo}? I would very much like to do
this. Thanks.
Joe
Joe Hudson
2005-06-07 23:04:58 UTC
Permalink
Yes, it is not necessary... I'm using the lowercase property name. I was
just answering the "Why is this needed anyway?" question. Thanks very much
for everybody's help.

Joe

-----Original Message-----
From: freemarker-user-***@lists.sourceforge.net
[mailto:freemarker-user-***@lists.sourceforge.net] On Behalf Of Jonathan
Revusky
Sent: Tuesday, June 07, 2005 6:25 PM
To: freemarker-***@lists.sourceforge.net
Subject: [FreeMarker-user] Re: bean property access starting with upper case
Post by Joe Hudson
It's just personal preference... that's all :)
Well, now that you know about writing custom subclasses of our objects
and plugging in your custom ObjectWrapper to vend those custom
subclasses, it would be a fairly simple exercise to get this working.
You subclass freemarker.ext.beans.BeanModel so that it tries both key
and Key.

TemplateModel get(String key) throws TemplateModelException {
TemplateModel result = super.get(key);
if (result == null) {
result = super.get(key.substring(0,1).toUpperCase() +
key.substring(1));
}
return result;
}

And then you have a custom object wrapper that vends your custom
subclass instead of BeanModel.

But frankly, it doesn't seem like it's worth it. I think you should
maybe just get used to how it works in FM. Isn't the desire to write
obj.Foo instead of obj.foo a little bit on the frivolous side?

JR
Post by Joe Hudson
-----Original Message-----
Dekany
Sent: Tuesday, June 07, 2005 3:36 PM
To: Joe Hudson
Subject: Re: [FreeMarker-user] bean property access starting with upper
case
Post by Joe Hudson
Post by Joe Hudson
It's me again :)
Is there any way to allow bean property access starting with an upper case
letter?
None out-of-the-box. The BeansWrapper works according the Java Beans
Specification, which also decides what case is used when. In principle
of course you could use your own ObjectWrapper... if you start out from
BeansWrapper, maybe that's not even hard.
Why is this needed anyway?
Post by Joe Hudson
For example if my object has a method called getFoo()
Can I call ${obj.Foo} instead of ${obj.foo}? I would very much like to do
this. Thanks.
Joe
-------------------------------------------------------
This SF.Net email is sponsored by: NEC IT Guy Games. How far can you
shotput
a projector? How fast can you ride your desk chair down the office luge
track?
If you want to score the big prize, get to know the little guy.
Play to win an NEC 61" plasma display: http://www.necitguy.com/?r=20
Continue reading on narkive:
Loading...