Tuesday, September 13, 2011

A super smart way to rotate graphics

Wanted to share a very usable way for rotating graphics that I found at zwibbler.com. I'll show you an example -



I placed the arrow and as is typical in drawing environments like this, I got a handle to use to rotate the arrow (this is the green G like thing you see on the canvas - highlighted by the red ellipse). The neat thing is you can drag the handle so that the further away you drag the handle (indicated by the thin blue line in the UI), the finer is the rotation so you can decide how much control you want over the rotation. Compare this to Powerpoint (which is a pretty good regular use graphics program for me) and the rotation is not as intuitive or easy and requires very careful mouse manipulation to rotate things right.

Very smart!

This does have a problem that you are limited by the canvas and in a rectangular canvas if your rotation arc (after you have extended it to almost the edge) passes over the edge, the rotation stops. But it seems to work well - give it at try.

Saturday, July 23, 2011

HoverPopup - a JQuery UI Plugin

Fiddling around with JQuery, JavaScript and assorted web development goodies in my spare time, I finally have a JQuery UI plugin I can call my own. This one mimics the behaviour you can find in the Gmail chat window. When you hover over a user, you'll get a panel that has additional details and actions for that context.


You can try out the plug-in here which is an easier way to understand what it does.

It wasn't all that hard and while I was mucking my application code with this UI logic, I figured I would write it as a JQueryUI plugin so it is re-usable and has the added advantage of keeping my code clean. It turned out to be a very fun and satisfying experience. Many thanks to this article for helping me understand what needed to be done - http://bililite.com/blog/understanding-jquery-ui-widgets-a-tutorial/

Disclaimer: My first JQueryUI plug-in and not too much after having learnt JavaScript, so use this at your own risk - I expect that an expert in either will be able to provide me good feedback on how things can be improved or written much better.

Here's the code for the plug-in. To use JQueryUI you need to follow the guidelines here. Thanks to the wonderful http://www.tohtml.com for syntax highlighting.

/*
* $(selector).hoverpopup({
leftMargin: [optional] - specify how much to the left of the trigger element the hover popup should appear
getTriggers: function that should return a list of elements to base the popup trigger on.
getPopupContents: function that is called to populate the popup
});
*
*/
var HoverPopup = {
options: {
leftMargin: 3,
},

_init: function() {
var _this = this;
var elem = this.element;
var triggers = this.options.getTriggers(elem);
_this.options.popup = $('#hover-popup-1');
if (_this.options.popup.length == 0) {
$('body').append("<div id='hover-popup-1' class='hover-popup'></div>");
_this.options.popup = $('#hover-popup-1');
_this.options.popup.hover(function(evt) {
clearTimeout(_this.options.t);
}, function(evt) {
});
_this.options.popup.hide();
$('html').click(_this.options.clickHandler = function(evt) {
if ($('#hover-popup-1:visible').length > 0) {
var o = _this.options.popup.offset();
var h = _this.options.popup.height();
var w = _this.options.popup.width();
if ((evt.pageX >= o.left && evt.pageX < o.left + w) &&
(evt.pageY >= o.top && evt.pageY < o.top + h)) {
// do nothing
} else {
_this.options.popup.fadeOut(_this.options.hideCallback);
}
}
});
}

for (var i = 0; i < triggers.length; i++) {
$(triggers[i]).hover(function(evt) {
_this.options.enter = setTimeout(function() {
var src = evt.currentTarget;
_this.options.popup.empty();
_this.options.popup.append(_this.options.getPopupContents(src));
clearTimeout(_this.options.t);
_this.options.popup.fadeIn(_this.options.showCallback);
_this.options.popup.offset(_this._calculateOffset(src));
}, 200);
}, function(evt) {
clearTimeout(_this.options.enter);
_this.options.t = setTimeout(function() {
_this.options.popup.fadeOut(_this.options.hideCallback);
}, 300);
});
}
},

destroy: function() {
$.Widget.prototype.destroy.apply(this, arguments);
_this.options.popup.unbind();
$('body').remove(_this.options.popup);
$('html').unbind(_this.options.clickHandler);

},

_calculateOffset: function(src) {
var w = this.options.popup.width();
var h = this.options.popup.height();
var jsrc = $(src);
var off = jsrc.offset();
var l = off.left - w - this.options.leftMargin;
if (l < 0) {
l = off.left + jsrc.width() + this.options.leftMargin;
}
var t = off.top;
var pageH = $(window).height();
if (t + h > pageH) {
t -= (t + h - pageH - 5);
}
return { "top" : t, "left" : l};
},
}

$.widget("ui.hoverpopup", HoverPopup);

The CSS code follows - which is not much really. You can style the contents of the popup which is your UI code. I suppose I could add this to the component itself and reduce the number of files.

#hover-popup-1 {
display: block;
position: absolute;
z-index: 10000;
}



Usage:
Apply hoverpopup on the jquery object - an instance will get instantiated for each element in the jquery object. The "getTriggers" function is called which gets the context element to work with. This function is expected to return a jquery object that has all the triggers in it. When the mouse hovers over one of the triggers, the popup is shown and its contents are populated by calling "getPopupContents" which can return anything that works in the JQuery "append" function.
leftMargin just controls where the popup is located - maybe this should be in a function of its own

Here's an example -

$("#div1").hoverpopup({
getTriggers: function(elem) {
return $(elem).find('.hp-test-tr');
},
getPopupContents: function(src) {
return '<div>' + $(src).find('.data').html() + '<div>';
},
leftMargin: 10,
});

Some more details
The reason I added in getTriggers, which is probably a deviation from the JQuery way of doing this - i.e. the pattern $(selector).hoverpopup would normally apply on the selector, was because I felt that instantiating a HoverPopup object for each trigger was excessive. Take a look at the demo page source to get an idea of how it was used.

Let me know what you think and I am open to suggestions on improvements and feedback on the code.

Sunday, November 01, 2009

Something product feature comparisons won't tell...

Try this in Idea -

public class MyClass {
private static abstract class MyAbstractClass {
public void method() {
someMethod(); <--- hit alt enter on someMethod
}
}
}

When you hit alt-enter at someMethod and hit enter without looking at the list of options, the sheer brilliance of the implementation is to create an abstract method "someMethod" - absolutely lovely! The actual list demotes the usual default "create method someMethod()" as a second option while promoting to first (and default because of the enclosing abstract class) option "create abstract method someMethod()".

Ya I'm sure sometimes one doesn't want abstract method but the point is that it works surprisingly well and its a choice someone though was worth promoting above the plain simple "create method someMethod()" option. Love it!

The problem with product comparisons is that someone
is bound to turn around and say - oh you can do this in Eclipse - but you really can't. Maybe you can generate abstract methods - but the sheer joy and surprise of having your IDE generate the exact thing you wanted without any additional user gestures cannot be captured in a product comparison where you go specifically choose the option. There might be a feature to do the exact same thing but when it pops up and the defaults the system uses makes it stand apart.

Oh and yeah - IntelliJ Idea is free and open source now.

Wednesday, May 20, 2009

FUSE Integration Designer 1.2 is out!

FUSE Integration Designer 1.2 has released. This product marks a significant improvement in the capabilities from the preview release. The product is designed specifically for development on the Progress FUSE products which are based on the Apache Camel, ApacheMQ, Apache ServiceMix and Apache CXF products.

I am very proud of this release. We have built this product from scratch at Progress Software India (amongst many others) but what has been achieved in this product in the short time that we have worked on it makes it special!

The product is an Eclipse SOA development toolkit focused around the FUSE product set and includes a full-featured Enterprise Integration Patterns editor specifically meant for FUSE Mediation Router (Apache Camel). Here's a screen shot of how a route will look. The editor now supports almost all the processors and patterns in Camel. We are actively working on adding additional endpoint support and enhancing it via usability tests and other feedback.

We also have a host of features and improvements we are planning in the coming releases. In addition to creating routes and exporting them to Spring you can also -
a. Deploy them to FUSE ESB (ServiceMix)
b. Run and Debug them - we have full Eclipse debug integration.
c. Import existing routes from Spring into the editor and view/edit them

In addition to the center piece EIP editor the product has some key features for FUSE developers -
a. Support for Java DSL based development
b. Support for ESB 4.x and 3.x deployment (all JBI packaging aspects are taken care of automatically)
c. Support for CXF deployment on ESB in addition to Tomcat
d. JMS Tooling for ActiveMQ (this is actually based on a completely extensible framework so it can support any JMS vendor - more on this in another blog).
e. Improved documentation to help you along with cheat sheets and stuff!

Give the product a spin and let us know what you think here.

Tuesday, January 13, 2009

Eclipse Development at Progress Software India

I keep seeing google keyword searches for jobs at Progress land at this site. My group is hiring and we are looking for smart and capable Java people who would love to make a dent in the Eclipse world. We are working on FUSE tooling amongst many other things. If you like being challenged and would like to work in a high caliber team - We are hiring!

Some of the things we have worked on in the recent past - SDO, DAS, XSL/XQuery Mapper tools, Refactoring tools, JMS Tooling, Distributed Debugging, Tracking tools, Camel, BPEL, Asynchronous Web-Services, Actional. My group is very active in the local Hyderabad Eclipse community with frequent talks and demo-camps.

We do some pretty amazing ActionScript and Web development work here at PSI (Progress Software India). So if you are a top-notch web developer, we would love to talk to you.

We are based in Hyderabad, Andhra Pradesh. The Progress bill board above is up on a uni-pole on Road# 36 Jubilee Hills all this month. Look at my blog on our previous job posting for some additional details.

Check out Ramesh's blog while you are at it.

Interested? Apply here.

Sunday, January 11, 2009

Extending the Java Console

The lack of a good way to be able to interact with the console in Java is extremely annoying. I have been working on a small project (hopefully the content of another blog eventually) which would work best if it had good access to the console. It is frustrating that even after all these years, Java has no good way of writing a decent console based application. I can only guess that the reason for this is perhaps WORA goals are compromised? I have created an extension to the Console API which allows for better access and additional features. This blog entry is about that project.

The limitations
Java has no equivalent of the C getch() API which allows you to read a single character from the input buffer. The only way to get System.in.read() to return is to hit enter after typing in your input which makes it an extremely clunky way to read characters and every character is then on a new line – like a newbie Java program. Java is just not meant for console input unless you are doing simple things like “Enter Name : “.


If you did somehow get past the lim
itations (and if you know a way how to do this with plain ol’ Java 6.0, please educate me) you get stuck with the lack of ability to be able to control your output. The introduction of Console.printf does add some significant output formatting capabilities, however there is no ability to move the cursor around to position your text right. Say you wanted to overwrite the current word under the cursor when Tab is pressed (like the command prompt does when you want to complete paths) – you can’t do that.
There have been a couple of solutions to these problems - there is a hack which partially works. Maven does this neat thing when downloading anything significant from a repository where it shows the download progress.

Maven does this by using \r at the end of the System.out.print() which allows it to overwrite the previous line. Another hack - If you wanted to do the Tab-should-overwrite-current-word-under-the-cursor thing you could do System.out.print(“\b”) as many times are required to overwrite the letters under the cursor. This would work BUT both these techniques are limited by the start of the current line – i.e. they are unable to go to the previous line which limits their usage.


What is really required is an addition to the Console API in Java. The Console API was introduced in Java 6.0 and provides some much needed additions to Java’s capabilities to deal with character based applications. Console introduces methods to read passwords (without echo) and adds the printf method I talked about earlier. However, it still lacks the ability to read individual characters and to position the cursor and therefore was still insufficient for me.

The solutions

Like every lazy developer, I did Google away for a Java curses or Console implementation. The most promising one I found was JCurses – a Java Curses implementation for Windows and Unix (using JNI).


This is a nice little project that provides the curses API in Java. It provides a bunch of widgets and layouts and containers for creating UI in character mode. It’s nice but that’s not what I wanted. However, it did have a lower level API (that was not recommended for use but that’s just an invitation, isn’t it?) that allowed character input and character output. The input could be retrieved one character at a time just like I wanted but the output forced me to provide an x, y location. That in it self would be fine if I had an idea of where I was on the screen. The API lacked the ability to get and set the cursor location – basically I think the idea was to create character UIs (probably full-screen) so it wasn’t that important in the context of the JCurses project. Also, the output methods did not move the cursor which made the whole thing look and feel rather weird. I wanted something that will make the user retain his feel of the command line – not a character mode UI.

There has been a similar project in the past which seems to have moved or died - at least I couldn't find it - here's the link.
Sun has been introducing features bit by bit as mentioned above. Here's the link to the discussion on the password entry. This is nothing close to what I want and continues to have the clunky enter-for-input behaviour.

Then I figured what I only wanted was really a small Console API with supporting classes. I got the Windows SDK and looked up the Console support and Windows has Console API that did exactly what I wanted that would work just fine. Writing the JNI library to get the basic console API wasn’t that hard.

The next step was to have the Java API that provided basic extensions to the Console. It has very few methods –

  • to read characters with or without echo
  • to output characters at the cursor location or at a specified location
  • to retrieve the current cursor location
  • to set the cursor location
  • to retrieve the screen size.
The Console library has all capabilities to let me do console input and output. What I have is lean and does exactly what I want – a useful Console extension that provides basic capabilities that were missing.

Project - help wanted!
The project is available on Google Code here. I will try contributing back to the JCurses project when I am done. If you are interested look at console.Console. console.ConsoleBuffer provides a higher level abstraction allowing the console to be treated as a text field with an index into the text instead of dealing with the row-column nature of the cursor.

I would like some help with a few things though –
  1. I used to be a good C programmer but am significantly rusty so my C code could use a good code review to look for leaks and such or any suggestions on doing thing better.
  2. I am basically on Windows so I didn’t write anything for Linux – so someone to provide a Linux port and build would be great.
  3. I need to get the Maven build working completely. It builds the Java part but I had trouble with the native-maven-plugin to get it compile the native parts. So that is done as a bunch of batch files right now :-(
If someone would like to help me with these please drop me a line. The project is using Apache License 2.0 so is available for re-use in other projects.

If you do use the library and have any feedback, I would love to hear it.


I really think functionality should be added to the Console class in Java. There are a couple of RFE’s in the Java Bug Database that request for more capabilities in the Console API – 6672641, 6552816, 4050435.

Tuesday, December 30, 2008

Pure Idea Joy

One of the reasons why I love IntelliJ Idea. Look at the text in red below.

package com.msh.ui;

import java.util.ArrayList;
import java.util.List;

/**
* User: sachinh
* Date: 28-Dec-2008
* Time: 17:22:38
*/
public class ParsedCommand {
private List<Property> props = new ArrayList<Property>(5);
private List<PluginInfo> mojos =
new
ArrayList<PluginInfo>(5);

public ParsedCommand(String cmd) {
parseCommand(cmd);
}

public List<Property> getUnusedProperties() {
for (PluginInfo p : <ctrl+shift+space> fills in mojos) {

}


Just brilliant - the fact that it picks up the right collection field
based on the Iterator's type. I think its called Smart Code Completion.

Thursday, August 02, 2007

Rising to the top

Recently, I posted a one line, grammatically incorrect (actually it just had a typo - a missing 'of') blog in which all I did was praise Seth Godin's article and point to it. I didn't think anything I had to say about the topic could really add any additional value so I refrained from putting in any of my comments. I didn't think much about it then but afterwards I found out, interestingly, this article had reached the top of the Popular Entries for the last 24 hours at JavaBlogs.com. This is not really such a big deal but I have an RSS feed to the popular entries and it is always interesting to see what rises to the top in that list. Because Mozilla's Live Bookmarks shows only the title, I have to judge whether I want to read the article based on the title.

Despite it being a collection of Java blogs, it is infrequent that anything seriously technical about Java manages to hold popular attention. It is always the more interestingly worded title that starts to move up rapidly (perhaps the only exceptions are the latest buzzwords and the word 'performance'). More technical titles generally languish somewhere in the middle of the list which at the top is crowded by articles that are inflammatory in their title or simply very vague about their content. The advantage of the latter (which mine must've inadvertently become) is that you have to click on the link to find out what's in the blog. This makes the blog more 'popular'. This, of course, makes it go up higher in the list allowing reaching more people and setting off a chain reaction.

So, here's (deliberately this time) a rather vague title for this blog to test this theory :-)

Tuesday, July 31, 2007

Managing Expectations

Seth Godin has this truly wonderful blog which is always very interesting to read and this piece advice is true gold.

Wednesday, July 18, 2007

Another reason to have X-GOOGLE-TOKEN?

In my previous post here about XMPP I had linked to a blog (here) that describes the X-GOOGLE-TOKEN mechanism of authentication. dJOEk asks a question "Why does Google use a proprietary authentication mechanism" and then goes on to make a point about how X-GOOGLE-TOKEN could be one of the first steps twoards a Single Sign On solution from Google. This point of view has received a lot of coverage with a several people commenting about the merits of this idea or its feasibility.

I have recently noticed another possible reason for X-GOOGLE-TOKEN to be made available and this is what I am putting forth here -
I had written in my blog that when I tried to sniff out the conversation between Google Talk and the server using Ethereal I found that it was using TLS and not X-GOOGLE-TOKEN and therefore all conversation was encrypted. Several people have since asked for ways around this but the whole point of TLS is to prevent such sniffing and decryption is practically (at least to me) impossible.

Since then my current company has installed an auditing software (I know :-() for compliance reasons and interestingly Google Talk is back to using X-GOOGLE-TOKEN. When using X-GOOGLE-TOKEN only the authentication part goes over TLS while the rest of the conversation does not which means that conversations are in plain text and can be intercepted, audited and archived. So, another possible reason for supporting a different authentication mechanism could be to be able to support auditing and monitoring software?

Friday, June 29, 2007

Progress job posting on Joel India Jobs Board

Joel from JoelOnSoftware has this jobs board specific to India jobs which we are trying for the first time. The idea is that we will either get a bunch of resumes from the kind of people we like to hire or hear from or we will not get anything at all. Our usual experience from recruitment agencies and job sites like Monster is that we get a lot of resumes (with less than 10 percent being the ones we seriously consider and interview) and sifting through them just kills us.

Here's the link to the job post http://jobs.joelonsoftware.com/?2202

I would love to hear from people who have tried the Joel India Jobs Board and hear their experiences. If this works for us we'll do more job posts here.

This is the text of the job post -

Software Engineer

at Progress Software

Hyderabad, India

We are a small and focussed engineering team in Hyderabad developing the next wave of SOA development tools for our product, the Sonic Enterprise Service Bus. We have been involved in writing Eclipse based high-end editor plug-ins for open standards based technologies such as XML, XPath, WSDL, etc using a variety of Eclipse frameworks such as EMF, GEF, etc. We have developed code generators and graphical tools for generic mapping capabilities, developing BPEL, etc, amongst many others.

We are looking for smart and competent people to join and enhance the experience of SOA development for our users. The next few releases are going to be very exciting as we add features to improve developer productivity, including refactoring distributed applications, visual development, and on-line assistants.

We are looking for excellent programmers in Java with up to 3 years in experience who also possess these qualities -
Creativity - we like people who can think of new features for our products and make a difference to our users
Capability - we want people who are very good at programming and can demonstrate it to us
Self-driven - we are self-driven people who are expected to work with minimal supervision and get things done

Any in-depth Swing or Eclipse development experience is a plus but not a requirement.

The team is completely based out of Hyderabad and has a QA to developer ratio of over 1-to-1. We participate in local college internship programs and in various forums.

Comments about the Joel Test: We fix all test blockers before we write new code. The "quiet working conditions" implies offices as per the Joel Test - we have workspaces and we like to mingle and have some fun.


Our interview process is heavily biased towards programming skills so please apply only if you are serious and think of yourself to be an excellent programmer.

Joel Test Score: 11/12

The Joel Test is a twelve-question measure of the quality of a software team.

Yes! Do you use source control?
Yes! Can you make a build in one step?
Yes! Do you make daily builds?
Yes! Do you have a bug database?
Yes! Do you fix bugs before writing new code?
Yes! Do you have an up-to-date schedule?
Yes! Do you have a spec?
No. Do programmers have quiet working conditions?
Yes! Do you use the best tools money can buy?
Yes! Do you have testers?
Yes! Do new candidates write code during their interview?
Yes! Do you do hallway usability testing?

Interested?

If working with a small, focussed, informal team that is completely engaged in every aspect of product development starting from product direction and requirements gathering to engineering excites you then send us your resume at joeljobs@progress.com

Friday, March 09, 2007

Who cares about the chronological ordering of blogs?

There is a new way of designing blogs at Blogger and in general it is very easy - point and click, move around, group - the usual goodies associated with good Web-UI these days. The new blogger re-design also has a different mechanism of listing previous posts. They now group it by chronological order. I have spent some time trying to understand why this is useful to people who come to my site? And I have been completely defeated in understanding its purpose. Before I go into a litany of my issues with this new way of organizing posts I want to show what I mean -

This is the old way it used to be -

And this is the new format (which you can see in the right pane of this page if you are at the original blog site and not seeing this through a reader) -

I don't see why this useful for anyone other the blog author - and even for the author it is only informative (ah February 2007 was a good month for me - Oh Gosh! I didn't post a single thing between October 2005 and August 2006).

Here's what is lost by going to this format -
a. Earlier visitors (especially first-time visitors which are the majority of the visitors according to Statcounter's indication of the abysmal popularity of this blog :-)) cannot see a quick list of other posts which might catch their attention. They now have to do a deliberate task of expanding those date nodes to see what I might have written previously. I might just stop putting in titles altogether.
b. And really what is the reason to group it by month or date - do any of my readers really relate to the dates that I published my articles? How is August 2006 any more important than Jan 2007?

I am sure that there is way somewhere to hack out of it and maybe I'll have to sit down and hunt for it. I searched for it in the options and could not find a way to switch this off.

Monday, February 26, 2007

Accepting the Q factor

http://www.w3.org/2000/09/xmldsig# is the namespace for the schema for XML Signatures - one of the many, many schemas you end up accessing if you do XML Schema based completion for WS-SecurityPolicy (2005) (part of our WSDL policy editor in the Eclipse plugins for Sonic ESB Workbench). Why is this one special? For the following reason -

If you access http://www.w3.org/2000/09/xmldsig# from Mozilla Firefox you will get back the schema at http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd (through an HTTP re-direct response code 303) but if you use Java's java.net.URL.openConnection() (basically through HttpURLConnection) you get an HTML page and not the Schema (XML) which our Schema loader does not particularly appreciate.

It took a while for me to understand why the same URL is behaving differently. Using Eclipse 's TCP/IP Monitor I captured the headers sent by my code and used LiveHTTPHeaders for Firefox.

This is what Firefox sends -

GET /2000/09/xmldsig HTTP/1.1
Host: www.w3.org
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2) Gecko/20070219 Firefox/2.0.0.2
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive

and this is what it receives -

HTTP/1.x 303 See Other
Date: Mon, 26 Feb 2007 11:50:20 GMT
Server: Apache/1.3.37 (Unix) PHP/4.4.5
WWW-Authenticate: Basic realm="W3CACL"
Location: http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd
Keep-Alive: timeout=2, max=99
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=iso-8859-1



But when HttpURLConnection sends the request this is what it sends -

GET /2000/09/xmldsig HTTP/1.1
User-Agent: Java/1.4.2_12
Host: www.w3.org
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive


and this is what it receives -

HTTP/1.1 303 See Other
Date: Mon, 26 Feb 2007 11:56:47 GMT
Server: Apache/1.3.37 (Unix) PHP/4.4.5
WWW-Authenticate: Basic realm="W3CACL"
Location: http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/Overview.html
Keep-Alive: timeout=2, max=99
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=iso-8859-1


Notice the difference in the Location header
Firefox : Location: http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd
Java URLConnection : Location: http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/Overview.html

The problem turns out to be in the Accept header set by Java URLConnection by default (or I guess the Sun HttpURLConnection implementation).

Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2


Note no text/xml as in Firefox. Although there is a */* its 'q' value is lower than text/html and the nice server at www.w3.org uses this to change its output to suit what is best accepted by the user-agent. I guess since they are the standards organization they should do this :-). Fixing the accept header fixes this behaviour. Is there something I am missing in my understanding of how URLConnection works?

Saturday, February 24, 2007

Experiments with development on the Nokia 6265

I recently got myself the Nokia 6265 CDMA phone. It is a nice phone and I intend to write a reveiw of it in my other blog one of these days. The phone supports the Nokia's Series 40 3rd Edition development platform and I am trying out developing Java Micro Edition applications for it. I hit some interesting problems and found some solutions - I am trying to chronicle them here.

Firstly, I have never done development for a mobile phone so I had to start from scratch. I wanted to know what I could do with my phone and Nokia had quite a lot of information. They have these videos of their Eclipse integration called Carbide.j which seemed interesting although a little painful (being a graphical modeling like UI and all).

I found the Nokia site a tad vague about what exactly is needed for what but eventually I figured I needed the Nokia Series 40 3rd Edition SDK. Now, Nokia has 3rd Edition Feature Pack 1 and 3rd Edition Feature Pack 2. It wasn't very clear to me which one would work and I chose the base version and thankfully that is the right one. Only one phone so far supports Feature pack 1 as far as I know.

After installing the SDK, the documentation said that I need a JDK, Eclipse, NDS for Java ME, and then I should install SDK. Did I mention that the Nokia site is slightly confusing? :-) I went off in search for NDS and found out that it is now renamed to Carbide.j and is a 135+ MB download. While it was downloading, I thought I would try and locate J2ME support in IntelliJ Idea.

IntelliJ Idea J2ME integration

Now, this is the nice part.

I went through the IntelliJ Idea documentation which described how to set up a J2ME module and the only part that looked a little hard was the Mobile JDK configuration. I crossed my fingers and pointed at the Nokia installation and IntelliJ found all it needed - bootclasspath, javadocs, emulator, etc. It is really sweet!!

Everything works out of the box - compile works great, and when you run it runs against the Nokia emulator. Even debugging is seamlessly supported!! Fantastic - and no need for Eclipse or the Eclipse plugins! Needless to say I cancelled my Carbide.j download. You do not need it for development on the Nokia phones. I hope the Nokia guys put this on their documentation.

One strange problem so far (in my HelloWorld application) has been that the jad and jar generated by IntelliJ is not working on my phone or on the emulator. It fails with an error message saying "Application invalid. Delete?". There is a temporary file that Idea is generating which seems to work. I think I am missing something here. I would appreciate any help.


Annoying UI Change in Firefox 2.0

Firefox 2.0 is out and I upgraded from 1.5.x to 2.0. While closing a tab I realized something was amiss. In 1.5.0 there are two ways to close a tab - each tab is associated with a close button and the tab bar has a close button at its extreme right which is applicable to the most active tab. That is the button I use the most and that is gone from 2.0.



Why do I think this is an annoying change? The old button on the right of the task bar never moved - which meant irrespective of which tab I was on I could aim my mouse over it (a centimeter square area that my hand and wrist manage to reach magically) and close without having to think too much about it. Now, I have to look for the close button and my target has just expanded horizontally to unpredictably include my entire horizontal resolution. Another reason was I could close many consecutive windows one after the other just pressing the button multiple times because the selection automatically moves to the next tab. No longer possible. Arghhh! Hopefully there is a preference somewhere which can get it back - but so far I haven't found it. In its place there is a drop down of all windows to quickly navigate to it.

Well...sigh...I still love Firefox and I'll just use Ctrl+F4 more frequently...

Sunday, January 14, 2007

What I don't like about the iPhone

Apple has hit that elusive textbook-class marketing success. iPhone has the same buzz that Gmail had when Google decided that their Beta product is available only by invitation. iPhone is 6 months away from release but look at the talk around it. Everyone has heard of it now because everyone wants to talk to someone else about it . And everyone is blogging about the iPhone - and here's my two cents on it.

You've heard the comments - it is a gorgeously styled phone but has not much new to offer - it is just slickly packaged and marketed. It is quite possible that the actual product might be fantastic. A lot of the magic is in the User Interface and there is only so much you can say about it - like the Apple iPod. The fact that the click wheel makes a clicking sound (by the small speaker only for it) is best when used and not when you read it. So, final judgements on how great it is can probably only be passed once the product comes out. It does look very nice.


So, what is this blog about - just a couple of points about the UI from the demos I saw on the apple site.

Take a look at this screen - I know the iPhone does not have a keyboard and provides a software keyboard which you can use like a regular one. That is a fine idea but look at the keyboard.

What I don't like about it is that although it is a QWERTY keyboard it does not have a full keyboard - the digits and symbols have to be accessed much like an old phone which had menu options for 123, Symbols, etc. Unfortunate.

Blackberry keyboard and screen togetherThe next thing that strikes me is that there is not enough space to see or read what is on the screen after the keyboard pops up - most of the screen is taken up by the keyboard and the effective space is down to a couple of lines. My age-old phone has more space than that. My wife's Blackberry (left - I couldn't capture a better image of email and keyboard together - it isn't meant to be Blackberry marketing! :), despite its not so good-looks, has a practical amount of screen real-estate. Definitely a win for the Blackberry here. Usually, phones in this category support hand-writing recognition using a stylus which allows them to provide larger screen estate without the keyboard in the way or they do it the Blackberry way. With no stylus the iPhone loses space.

This is the SMS screen (right). Looks cute but if the demo follows the product faithfully the ordering of messages seems wrong. I believe it should be in reverse chronological order so that the most relevant messages (the recent ones) are on top versus having to scroll down. Also, this is perhaps the most wasteful of screen layout designs - nice but wasteful. Hardly a good idea considering how little of it you have. But then perhaps these are just preferences that you can set - like Google Talk.

What I like is the interface you get when you are in a call. The large buttons that come up for Speaker, Mute, Hold, etc are excellent for usability. I have the hardest time figuring out which button is which on my phone and even on the Blackberry you have to know what button does what - this is so much more elegant and usable.

All said, the Apple iPhone is definitely going to be a serious contender in the phone market and like in the case of music players might cause the other competition to provide a host of new features. Most people have predicted that the iPhone will not have the same impact that iPod did - which is probably very easy to predict because the phone market is quite mature and a tie in to a service provide (Cingular) restricts the user-base but I still expect the iPhone to make quite an impact. Whether the Blackberry users switch - can't say - those things are quite addictive.

The overall iPhone UI theme is large, informal text which looks aesthetically pleasing and is very readable but wastes space. In contrast, business phones like the Blackberry are all business-like keeping everything to efficient levels while compromising on looks, jazz and style.

Btw, I wonder if I am the only one who finds QWERTY keyboards a strange feature on mobile phones when people type with their thumbs. So quickly now - Where is the D key, the P key, or the N key, the X key - can you answer without looking at the keyboard? For people who can type with all fingers it is quite useless because the fingers keep the memory of the letters they type and not the thumbs (in fact the thumb only knows the space key) and definitely not the eyes so they have to hunt for the letters. For people who can't type and look at the keys when they type, I wonder if they do they find QWERTY layout any easier than a ABCDEF layout? Seems to me that for either group the ABCDEF layout makes more sense than having to hunt the entire screen.

Tuesday, October 24, 2006

Part 3: Jabbering with Google Talk over XMPP

This is part 3 of a series of blogs on getting IM working with a Google Talk client using XMPP. Parts 1 and 2 are here -
Jabbering with Google Talk over XMPP
Part2: Jabbering with Google Talk over XMPP

This one is going to be short one because I managed the last part of the Google Talk basic IM interaction which was presence and messaging without too much effort.

Presence
Presence is how you announce that you are available/unavailable/busy/whatever. It is through presence that people tell you that they have stepped away for a quick cuppa mocha - the part where you can have witty remarks show up against your name - basically your network availability.

The basic presence part is easy - requiring sending only a stanza. If you are already on the "roster" (XMPP's name for a buddy list) then your presence will be indicated by your id going "online" in Google Talk. You would have to be invited and on the users' roster for that.

Doing the presence part itself is optional - you can still send messages even if you have not announed your presence. The only difference is that messages directed to you are not sent by Google Talk because it is not aware of your avaiability and your friends won't know if you are online.

Presence has a bunch of interesting details which I won't go into mostly because I skipped most of them :-) but here's a quick list of what it can do -

  • announce availability/unavailability plus a bunch of sub-states
  • provide comments along with status
  • allow for subscription (notification of presence of others on the server)
  • change subscription
  • etc
Instant Messaging
The whole IM bit is where I was leading through and here it is. I did cover in Part 2 the messaging part which was basically

<message from=\"XXXXXXXX@gmail.com/D922F673\" to=\"YYYY@gmail.com\" type='chat' xml:lang=\"en\"><body>TESTING!!!</body></message>

and this is pretty much it actually. You can have the following in the message though - subject(s), body and a thread.

So once you have set up a Thread reading from your response stream you get message stanzas from all your friends and you can send them your messages on the request stream - thats it. Google Talk behaves just fine identifying the program as a non-Google Talk client.

Here's a silly picture of the two clients talking to each other.

Saturday, October 07, 2006

Answers to some seemingly common Java questions

Whenever I go through the Keyword Analysis page of Statcounter, which manages my blog web usage statistics for me, I see a bunch of Java questions which I can answer. However the page that people land on to never has the relevant answer to the query. With my recent Repetitive Stress Injury I am pretty much staying away from doing any more work than is required to help my hands heal faster. This is keeping me from working on my Google Talk programs. So, having nothing better to do I am going to try and answer some of the questions or searches that I saw coming to my blog.

Search Keywords: Java printStackTrace does not show line number
Happens if the classes that are part of the stack trace have not been compiled with the debugging option (-g) on. Here's the link for details on javac's options. The solution is to re-compile the classes with this option on and then recreate the exception. If it is not code you can build then there is not much you can do here unfortunately - you will have to analyze the code to figure out where it went wrong. Not having debug information while compiling usually also means that you won't get any local variable information while debugging in a JPDA debugger (to be complete precise that would mean that the -g:vars option has not been specified).

Search Keywords: how can i tell what caused a concurrentmodificationexception?
A ConcurrentModificationException happens if a java.util.Collection is modified while an Iterator is iterating over it. There are many ways you can end up doing this - I am going to try and list the situations that I believe are most common.

Disclaimer: Code snippets do not use generics which won't make any difference anyway.
1.] Listeners
Consider this listener interface -


XYZListener.java
1 public interface XYZListener {
2 void eventOccurred(Event evt);
3 }



and this implementation -

XYZListenerImpl.java
4 public class XYZListenerImpl.java {
5 public void eventOccurred(Event evt) {
6 evt.getEventSource().removeXYZListener*this);
7 // do something useful
8 }
9 }

where Event.getEventSource() returns the object against whict XYZListenerImpl's instance was registed as a listener.

Now, you will get a ConcurrentModificationException if the EventSource is implemented this way -

EventSource.java
10 public class EventSource {
11 private List listeners = Collections.synchronizedList(new LinkedList());
12 public void addXYZListener(XYZListener l) {
13 if (!listeners.contains(l))
14 listeners.add(l)
15 }
16
17 public void removeXYZListener(XYZListener l) {
18 listeners.remove(l);
19 }
20
21 protected void fireEvent(Event evt) {
22 for (Iterator iter = listeners.iterator(); iter.hasNext();) {
23 XYZListener listener = (XYZListener)iter.next();
24 listener.eventOccurred(evt);
25 }
26 }
27 }

This is going to cause a ConcurrentModificationException at line 24 (assuming that there are more than one listeners registered and XYZListenerImpl is not the last one ;-)) because in line 6 the listeners List is modified while it is being iterated over in EventSource.fireEvent's Iterator.
The solution in this case is to use the right pattern for firing events -

protected void fireEvent(Event evt) {
List clonedList = new ArrayList(listeners);
for (Iterator iter = clonedList.iterator(); iter.hasNext();) { // [19 Dec] edited - thanks to Anon comment
XYZListener listener = (XYZListener)iter.next();
try {
listener.eventOccurred(evt);
} catch(Exception ex) {
// this prevents one bad listener from preventing the event from going to others
// log the exception
ex.printStackTrace();
}
}
}

2.] Incorrect coding
This will cause a ConcurrentModificationException -

public void someMethod(List l) {
for (Iterator iter = l.iterator(); iter.hasNext();) {
Object o = iter.next();
if (someCondition()) {
l.remove(o);
}
}



Fix this by using Iterator.remove() instead of doing a list.remove()

3.] Concurrency
The trickiest one is when the Collection gets modified by another thread while it is being iterated upon. One solution is to clone the collection (e.g. new ArrayList(list)) and then iterate upon it. To find out where the List got modified -
  1. Create a wrapper List similar to Collections.SynchronizedList which delegates all methods to the enclosed List.
  2. In the add/remove and any other method that modifies the List dump the current Thread's stacks using Thread.dumpStack. Refer to this. I suggest printing the current timestamp and the Thread's id for easy collating and the List's hashCode() to identify operations against each List instance.
  3. When you get the ConcurrentModificationException print the List's hashCode and look for the last print from the List modification logs for a list of this hashCode and you should know which two threads are the "culprits".

Search Keywords: how do you add a print statement ever 5 minutes in java
This is quite easy. Create a java.util.Timer class and add a TimerTask and set it to fire every 5 minutes and write the print statements in the TimerTask.

Search Keywords: using ethereal to capture google talk
This is not really possible after TLS is set up as I discussed in the comments here. Google Talk mandates TLS and once the stream gets encrypted the whole point of that is to not be able to sniff out the contents using something pretty much like Ethereal.

There are a couple of other interesting queries that I have not taken up
what are some things that made java so popular?
java 5 why
(I would say - Generics)
why isn't java used for games
(I really don't know if it is or it is not used for games and what kind of games?)


Saturday, August 26, 2006

Part 2: Jabbering with Google Talk over XMPP

This is Part 2 of the posts that describe my attempts to do something interesting (eventually) with Google Talk using XMPP. Part 1 is here.

So finally I had my test Google Talk account successfully send a test message to my regular Google Talk account. The XML for that is

<message from=\"XXXXXXXX@gmail.com/D922F673\" to=\"YYYY@gmail.com\" type='chat' xml:lang=\"en\"><body>TESTING!!!</body></message>

Note that the from value is the JID returned by the Gmail server.


I am still quite far from where I want this to go. However, I am glad I am making progress. The last time (in Part 1) my quickly-put-together test code was reaching a point where it could no longer be used because I needed to save conversation state like the jid which it didn't allow.

Now, with a design and a framework in place I hope I can move on to newer things with Google Talk. Here's a brief class design diagram. I am not very formal with UML diagrams - I pick and choose what I like from UML so if it is not classic UML I apologize to those who may get irked by it. Let me know what you think of the design. I haven't seen what the Jive XMPP library design looks like yet.


XML Parsing Challenges
An interesting implementation challenge was XML Pull Parsing. I tried (briefly) the Stax parser in J2SE but I found it to be a little inconvenient with its event id based mechanism. I might be quite wrong though because I am sure I didn't spend as much time exploring its fit into my solution as I should have. I found myself thinking in terms of iterating over available pieces of XML as required.

The XMPP response stream is like an XML document where each response is another child of the document element. And you don't get the next child until you have sent a request. (I don't know how one receives messages yet so there might be some twist to this story later).

So, an XMLIterator which allowed me get the details of the current element and then waited until I asked it move to the next one was what I wanted and this open source project does pretty much that. Thank you very much Mark.

What I also wanted was an API that returned DOM nodes (preferably) as it saw them in the stream. Of course, the document element node will remain incomplete until the end is reached but thats just a technicality because all that is required to "complete" it is the end-tag which has no real information. I was looking for something like this -

XmlIterator iter = new XmlIterator(source);
iter.advance();
// we are now on the document element node
XmlIterator children = iter.children();
while (children.advance()) {
Node node = children.next();
}

I have a simple XML Node structure built over XmlIterator which works for me - maybe that's a project for later.



Next post I aim to be able to maintain a conversation with a Google Talk client and hope to have enhanced the framework to be able to do more things than just chat.

Monday, August 07, 2006

Jabbering with Google Talk over XMPP

I am writing an XMPP client that can talk to Google and maybe implement some cool things on top of it. So this weekend I began exploring the specs and intend to maintain an account of how it is going. XMPP is a widely discussed/implemented topic and has many many clients - so it is no research topic. Why did I choose to do this? Just for fun to try something new (for me) out. I know I can get the XMPP library from Jive Software but thats no fun. Sometimes re-inventing the wheel has its own pleasures :-).

The XMPP specs are an open standard on which Jabber and Google Talk are based. There are a number of extensions which are under consideration and most of the cool things have already been thought of such as RPC over XMPP.

So far as a prototype, I have managed to get connected to talk.google.com, perform starttls and authenticate myself followed by resource binding and initiating a session. Now, my prototype code is hitting its limitations and I will have to spend some time fixing it to be able to do some serious talking with XMPP. I have also managed to get my account successfuly blocked for authenticating incorrectly as well - but got out of that mess. :-)

I was hoping to sniff out the conversation that the Google Talk client is having with the server using Ethereal as per this blog that describes X-GOOGLE-TOKEN, a Google mechanism for Single Sign-on. As per that blog, the Google Chat client does not do starttls but does an XMPP authentication over an un-secure socket using a Google generated token (the actual authentication with the Google token server is over https) so all the communication can be sniffed. However, my client seems to be doing a starttls and I can't sniff any details out after the proceed response. Too bad - appears that Google Talk has changed since the blog was written.

Here's the sequence of communication with the Google Talk server - (formatted for readability with text sent from me in this colour and the response in this colour and comments in this colour).



<stream:stream
to='gmail.com'
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
version='1.0'>
<?xml version="1.0" encoding="UTF-8"?>
<stream:stream from="gmail.com" id="X0B367FC8A9597BA4" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client">
<stream:features>
<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>
<mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
<mechanism>X-GOOGLE-TOKEN</mechanism>
</mechanisms>
</stream:features>

<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls" /> <--- Start TLS - basically the rest of the communication is over SSL
<proceed xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>

TLS Succeeded - we are good to go...

<stream:stream
to='gmail.com'
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
version='1.0'>
<?xml version="1.0" encoding="UTF-8"?>
<stream:stream from="gmail.com" id="X1A565C1E8E3FD7CA" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client">
<stream:features>
<mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
<mechanism>PLAIN</mechanism>\
<mechanism>X-GOOGLE-TOKEN</mechanism>
</mechanisms>
</stream:features>

Now we get the PLAIN auth mechanism which is basically base64 encoded \u0000username\u0000password string which I have blacked out here.
<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>XXXXXXXXXXXXXXXXXX</auth>
<success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/> <--- authenticated

<stream:stream
to='gmail.com'
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
version='1.0'>
<?xml version="1.0" encoding="UTF-8"?>
<stream:stream from="gmail.com" id="X77D6827CD0B365BA" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client">
<stream:features>
<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/><session xmlns="urn:ietf:params:xml:ns:xmpp-session"/>
</stream:features>

<iq type='set' id='bind_1'>
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>
</iq>
<iq id="bind_1" type="result">
<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
<jid>XXXXXXXX@gmail.com/D922F673</jid>
</bind>
</iq>


<iq to='gmail.com' type='set' id='sess_1'><session xmlns='urn:ietf:params:xml:ns:xmpp-session'/></iq>
<iq from="gmail.com" type="result" id="sess_1"/>

Authenticated, Resource bound and Session created. Now, I need to send a message!

</stream:stream>



Next article on this, I hope to have successfully sent a message.