Java Thinks There Are 13 Months

I was working on a component for credit card processing where I needed to get the months of the year. Trying to plan ahead, I decided to use the DateFormatSymbols so it could easily handle localization if it ever needed to be used in a different language.

It wasn’t doing what I expected and I finally found the problem with the following code:

DateFormatSymbols symbols = new DateFormatSymbols();
String[] months = symbols.getMonths();
int numOfMonths = months.length
System.out.println(numOfMonths);

The output is 13. If you list all of the strings in the months array, you’ll find the first 12 are what you’d expect, but there is a 13th blank month at the end.

It turns out that there are some lunar based calendars that have to add a “leap month” every so many years. This month is called Undecimber and comes after December. However, I’m not clear why Java is giving me a blank month. If the given locale only has 12 months, what is the value of giving back a 13 item array and just leaving one blank?

Adding Context to Links in Tapestry

Introduction

Tapestry looks at the URL and assumes that anything after the page name is the context that is being passed to the page. So a URL like:

http://www.site.com/MyPage/5

Is going to expect that the number 5 is the context needed on MyPage.  You can have multiple contexts passed to a page like this:

http://www.site.com/MyPage/5/foo

This will pass two contexts to the page.  Depending on what the page is expecting to receive in the context, these values may be uses as they are or they might be coerced into something else.  For example, the five might represent the ID of some object that will be retrieved from the Hibernate.

In the case of a single context value being passed, MyPage can get the value into a page property by doing something like this:

@PageActivationContext
@Property
private int myNumber;

The PageActivationContext annotation tells Tapestry to put the value on the URL that comes after the page into that variable. With Hibernate involved you can do something like this:

@PageActivationContext
@Property
private Person aPerson;

Tapestry will tell Hibernate to get the person object with an id of 5 and assign it to the variable aPerson.

If the page has multiple context values being passed, they are handled through the onActivate method:

public void onActivate(int myNumber, String myString) {
//set appropriate page properties
}

PageLink

Thats a little background. The main thing I wanted to look at in this post is how to get links that pass in these context values in the first place.

This snippet shows a pagelink that will give us something of the form:
http://www.site.com/MyPage/5
Assuming that the person.id is 5.

<t:pagelink page="MyPage" context="person.id">${person.name}</t:pagelink>

If we need to pass multiple context values it can be done like this.

<t:pagelink page="MyPage" context="[person.id,order.id]">view order</t:pagelink>

If person.id is 5 and order.id is 22 this link will produce:
http://www.site.com/MyPage/5/22

Returning Page and Context from a Method

Tapestry lets us return values in Java that specify the next page to load. This is commonly seen in the onSuccess method which can look like this:


    public Object onSuccess() {
       //Do what needs to be done
       return "MyPage";
    }

At first it looks like we can simply append the values like:


    public Object onSuccess() {
       //Do what needs to be done
       return "MyPage/" + person.id + "/" + order.id;
    }

But this does not work because Tapestry can’t find the page “MyPage/5/22”. It only knows about “MyPage”. To add a context you will need to inject the pageRenderLinkSource and use it to build the context.

    @Inject
    private PageRenderLinkSource pageRenderLS;

    public Object onSuccess() {
       //Do what needs to be done
       return pageRenderLS.createPageRenderLinkWithContext("MyPage", person.id);
    }

You can add additional context values to the parameters as well.

    @Inject
    private PageRenderLinkSource pageRenderLS;

    public Object onSuccess() {
       //Do what needs to be done
       return pageRenderLS.createPageRenderLinkWithContext("MyPage", person.id, order.id);
    }

No Gamer Left Behind

I’m not too much of a gamer, but I think there is a serious problem with our society when it economically makes sense to release a game where you can possibly win by doing nothing. Actually when it comes to games, I don’t really care. The problem is that this is the same mentality that thinks education is more about making kids feel good about themselves and less about achieving any real useful skills.

The amount of effort the guy in this video game makes in order to get 3rd place is far to similar to what some kids have to put into getting a diploma.

From Reddit

X: Wife moved out, took everything, I just put a pizza in the oven but realized I don’t have a pizza cutter or knife..
Y: Did she leave because you start things without thinking them through?
X: Perhaps…