Background: I am meddling with Twitter4j – http://twitter4j.org/ – an open source library to interact with Twitter API. I am using version 2.1.3 I am using this API together with Struts2 framework.
For the simplicity of this post, which happens to be my NOTE as well… let’s say I am pulling a lot of twiter status via getUserTimeline() method http://twitter4j.org/en/javadoc/twitter4j/Twitter.html#getUserTimeline()
This method will return me a list of status which I will then push to jsp page (view). Iterating through the status is rather easy.
The execution() method in .java action class will be something like
public String execute() throws Exception {
Twitter twitter = new TwitterFactory().getInstance("<change to twitterusername>",
"<change to twitter password">); //how simple is this API
//set to retrieve first page, in which each page will contain 200 tweets (max tweets per page)
//twitter allows people to download up to 3200 latest tweets via API
Paging paging = new Paging(1, 200);
statusList = twitter.getUserTimeline("adityalesmana", paging);
//iterating the result via console for verification purpose (just for fun - purely optional)
for (Status status : statusList) {
System.out.println(status.getUser().getName() + ":" + status.getText());
}
return SUCCESS;
}
Notice getUserTimeline() will return an array of Status – http://twitter4j.org/en/javadoc/twitter4j/Status.html
The JSP portion that iterate through the array, using Struts2 tags, will be something like
<s:if test="statusList.size > 0">
<ol>
<s:iterator value="statusList">
<li>
<s:property value="id" />
| <s:property value="createdAt" /> <s:property value="createdAt.Hours" />:<s:property value="createdAt.Minutes" />
| by <s:property value="user.name" />
| <s:property value="user.text" />
</li>
</s:iterator>
</ol>
</s:if>
In case you do not know, a small number of tweets also contains location information. Such as longitude and latitude of the place where the tweet was sent. This API by default also retrieve such information, assuming such information is available. Displaying such information is as easy as adding the following struts tag between main s:iterator
Lat <s:property value="geoLocation.latitude" />
Long <s:property value="geoLocation.longitude" />
Now to make things more complicated, twitter may not always know the exact geo long/latitude location where the tweet was sent. In fact, most of the time, those location is just some approximate Place (http://twitter4j.org/en/javadoc/twitter4j/Place.html) defined by set of coordinates that represent smallest rectangular area from which the tweet was sent (boundingBox) OR coordinates that represent polygonal area from which the tweet was sent (geometryCoordinates).
Remember that getUserTimeline() method returns array of list which could contain place (getPlace()) information.
However, upon closer examination, getBoundingBoxCoordinates() returns a MULTIdimensional array of GeoLocation[][]
How to iterate multidimensional array? I could not use place.1 as the starting point of iteration.
Solution: After looking at struts tutorial documentation, and trying to ‘infer’ what it means, I can safely conclude that using “top” value is the way to iterate through that unknown [][] array.
The simplified solution is something like
<s:iterator value="statusList">
<s:property value="id" />
| <s:property value="createdAt" /> <s:property value="createdAt.Hours" />:<s:property value="createdAt.Minutes" />
| by <s:property value="user.name" />
| <s:property value="user.text" />
<s:iterator value="place.BoundingBoxCoordinates">
<s:iterator value="top">
<s:iterator value="top">
[<s:property value="latitude" /> , <s:property value="longitude" /> ]
</s:iterator>
</s:iterator>
</s:iterator>
<br />
</s:iterator>
notice I use two iterators using value=”top” to iterate each value of GeoLocation[][] returned by getPlace().getBoundingBoxCoordinates() one by one.