May 17 2010

Open the mac finder with a file/folder selected in eclipse.

It’s a common operation for eclipse users to try and open a file/folder in the mac finder. Unfortunately, there is no direct way to do it in eclipse. For windows users, this article addresses this issue. For mac users, however – a little difference is present. So how do we solve this problem?

Summary: Create an external tool with location /usr/bin/osascript and arguments -e "tell application \"Finder\"" -e "reveal POSIX file \"${resource_loc}\"" -e "activate" -e "end tell" . Any selected file or directory can now be shown in the mac finder.

Details: Create a new external tool:

(1) Create a new Program (select Program in the tree)
(2) Name it shell
(3) Set the location to /usr/bin/osascript
(4) The arguments to -e "tell application \"Finder\"" -e "reveal POSIX file \"${resource_loc}\"" -e "activate" -e "end tell"
(5) Run it:

Open the mac finder with a file or folder selected in eclipse

The argument that we passed is basically a script which tells apple finder to open the containing folder in the finder with the file selected.
If we just wanted the folder to be opened (without the file being highlighted), we could have used location as /usr/bin/open and arguments as ${container_loc}. That would tell the finder to execute “open” with the container location of the selected file.


Mar 11 2010

Why IE6 must die

And why doesn’t it make sense to still support the evil browser



As a web developer, I have been disappointed, disheartened, frustrated, and mostly infuriated by IE6. If you don’t know what is IE6, most probably you are using it right now. Now, I don’t want to get into the technical details of IE6 and why it sucks. I’ll just logically prove to you why supporting IE6 won’t help your business. Without any doubt we can assume that the only people who use IE6 are:
1) People who are just plain stupid (aka fools): These people don’t know what a browser is, and just click on the start button of their XP boxes and click on “Internet”.
2) Grandmas (aka grandmas): I wouldn’t say they are stupid, but they are likely to use IE6 for the same reason as above.
3) People who surf the net from cyber cafes(aka ‘poor people, hungry people’ or pphp ): They don’t have any other options in many cases. Too poor to own a computer, and too naive to demand a better browser.
4) People whose companies have blocked installation of other browsers and applications (aka handcuffed): Tch tch… sometimes these good old normal people (even internet savvy, you may say) might not be able to use another browser because of their companies. Enterprise apps are many a times built for IE6.
5) People who develop and test their sites on IE6(aka developers): Poor people like us, who have a job to protect their site on IE6, and still make it work on other browsers.

After we have established the users for IE6, we can analyse the web to see why it’s used. And why making your site work in IE6 is not helping you in any way.

1) E-commerce – Suppose you’re running your e-commerce site, do you think anyone using a paleolithic browser like IE6 is going to run his/her card through your payment gateway? E-commerce doesn’t work for fools – they would select mastercard instead of visa. It doesn’t work for grandmas – they won’t know what a credit card is. Of course it doesn’t work for pphp- Remember, they are poor people, hungry people. Handcuffed people won’t be allowed to visit an e-commerce site anyway, and developers are too busy making that site.

2) Building a Brand: Rolexes and Ferraris don’t sell on the web, but still have well maintained websites. The reason is that they want to build or enhance their brand through a slick website and substantial web presence. Branding doesn’t work for fools – that’s their definition. Might work for grandmas, but they would forget the brand name during lunch time. I’m assuming no branding is necessary for pphp, as they’re not in any target group – they never are. Handcuffed people won’t be allowed to visit a branding site anyway, and developers are too busy making that site.

3) Content: People also use internet to read some free content online. If you have any serious content that’s not about fools or grandmas, then your site is not going to be used by them anyway. Pphp may come to your site, but being too time conscious, before they click on an ad which helps you earn profit,  they’ll either pack up and leave or use their remaining minutes watching desibaba. Handcuffed people won’t be allowed to visit a content site anyway, and developers are too busy making that site.

4) Networking: Who wants fools to be a part of their social or business network? You got it – other fools. If your site analytics shows that IE6 users make 40% of your total users, you know that your networking site is going to die – soon. Grandmas and pphp- ditto. And of course :) Handcuffed people won’t be allowed to visit a networking site anyway, and developers are too busy making that site.

5) Mail, apps and other useful sites: You can hold IE6 users to ransom and refuse supporting it. If your product is good enough(e.g. youtube, google apps, 37signals), people will upgrade their browsers and come to your site anyway.

Moral of the story: Let it dIE

–Cross posted from http://www.anujrathi.com


Jan 8 2010

velocity: Loading templates using absolute path

Velocity is an awesome java templating engine, which I’m currently using in my web-app. As easy it is to follow the ‘hello world’ example, I just could not access the template using my java code. The problem here is that velocity is not designed to only cater to web applications. It assumes that the default directory in which your templates are posted is the one from which your application started. And no matter how hard you try, it just wouldn’t pick up the templates from an absolute path.
In my case, it was the jboss bin directory, which was hardly the place I’d place my velocity templates. A little bit of searching and researching, and I could figure out a solution to make it pick up templates using an absolute path.
Here’s the solution: You have to configure your velocity.properties file to include a bit of resource management.Include these few lines in your velocity.properties (and remove any other resource management bit, if you have it):

resource.loader = file

file.resource.loader.description = Velocity File Resource Loader
file.resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader
file.resource.loader.path = .
file.resource.loader.cache = false
file.resource.loader.modificationCheckInterval = 2

The ‘file.resource.loader.path’ tells velocity to pick up templates from the absolute path. So, supposing your template’s path is /srv/test/Template.vm, you should try

Template template = velocityEngine.getTemplate("./srv/test/Template.vm");


Sep 24 2009

Client side Internationalization in struts application with javascript

Struts gives a straightforward way to internationalize your application. Using properties files, you can display different messages to users with different locales. For details on how to internationalize your application, view the struts 1.x site. However, this kind of internationalization works best only for non-dynamic sites. For even slightly dynamic sites, where you have a client side javascipt validation, you would run into a problem.

The problem with javascipt is that you typically cannot pick up messages from a resource bundle (from the server) depending on user’s locale. I would discuss here how to get the properties file to client side (javascript) in a usable form. The idea is, we convert the properties file as a JSON which is readily available for use in javascript.

Suppose we have a file named MessageResources.properties for the default locale (EN). And another file named MessageResources_de.properties for the german locale. Struts i18n will take care of the internationalization in the JSP side, but for javascript, we need to make the properties available on the outputted HTML as a javascript variable.

Here is a sample code which accomplishes the same in struts action class:


import java.util.Enumeration;
import java.util.Locale;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;

public class ActionInitializer extends Action{
	public void execute(HttpServletRequest request, HttpServletResponse response){
		Locale locale= request.getLocale();
		ResourceBundle resourceBundle = (PropertyResourceBundle) ResourceBundle.getBundle("MessageResources",locale);
		StringBuilder resourceJson = new StringBuilder();
		resourceJson.append("{");
		Enumeration<String>keys=resourceBundle.getKeys();
		while(keys.hasMoreElements()) {
			resourceJson.append("\"");
			String key=keys.nextElement();
			String value=resourceBundle.getString(key);
			resourceJson.append(key);
			resourceJson.append("\":\"");
			resourceJson.append(value);
			resourceJson.append("\",\n");
		}
		resourceJson.append("\"complete\":\"completed json text\"");
		resourceJson.append("}");
		request.setAttribute("resourceJson", resourceJson);
                //
                //Your business logic goes here
                //
                return mapping.findForward("success");
	}
}

Couple of things to note, don’t forget to escape the double quotes, and don’t finish your JSON with a comma (which is why I have added a dummy element – ‘complete’) otherwise the generated JSON will throw a javascript error in IE6.

The above code will generate a JSON object which is stored as an attribute, accessible in the JSP. This sample code illustrates how to use this JSON to store the properties

<script type="text/javascript">
         var resourceJson=eval(${requestScope.resourceJson});
         alert(resourceJson["complete"]);
</script>

Note that in the first line, var resourceJson=eval(${requestScope.resourceJson});, the el is evaluated at the server side, so the outputted HTML will look something like this:

<script type="text/javascript">
         var resourceJson=eval({
              "text.hello":"Willkommen",
              "text.contact":"Kontact",
              "complete":"complete"});
         alert(resourceJson["complete"]);
</script>

The ‘alert’ is only for demonstrating how you can access your locale specific message from the JSON. Happy i18n :)


Sep 18 2009

Difference between request.getAttribute and request.getParameter

Okay, so going by the name of this blog, one post regarding request.getAttribute was due, and here it is. It’s a newbie question which I will answer in this post.

Difference between request.getAttribute() and request.getParameter()

First of all, what is a parameter? If you are posting a form to the server (using get or post), then the name/value pairs are passed as parameters. e.g.: Your form looks like this:


<form method="post" action="/blah/"  name="loginForm">

Email ID:
<input name="email" id="email"type="text"/> <br/>
Password:
<input id="password" name="password" type="password" />
<input type="submit" value="LOG IN"/>
</form>

When this form is posted to the server, to fetch the values of “email” and “password” in your serlvet, you would need to use:

String email=request.getParameter("email");
String password=request.getParameter("password");

Note that the request.getParameter() method returns you a String. Simple enough!

Coming to request.getAttribute(), first let us look at what a request attributes. A request object can store objects in its attribute, which can be set as

request.setAttribute("user", userObject);

This is typically required when your servlet needs to pass on an object to another servlet/jsp. And the servlet needing this object can get it throught request.getAttribute(“blah”);
Note that this returns an object, which will need to be type-casted back. i.e. In your servlet, you will need to use the a similar code as:

User user = (User)request.getAttribute("user");

In this way, you can get back the object in your present servlet/jsp which you stored in another servlet/jsp.
Also note, that attributes can be passed in the request only on server, and cannot be passed to the client in this way.