Thursday, September 25, 2008

Kalamon's Car Reviews #3 - Subaru Impreza 2.0 RC

This was actually the first car I tried when I started my "quest for a new vehicle". And it sort of inspired me to look for something cool rather than purely functional. The Subaru dealership is located 2 minutes away from our office, so I pass by it every day. Funny thing is - Mitsubishi dealer is also located there - as if they had decided to go for a 1:1 duel from the very start :).

Anyway, upon entering the place, I noticed a car (which turned out to be the Impreza I would be test-driving later that day) that was amazingly ugly. I mean - the back side is in my opinion actually not that bad (despite complains that it looks like a Daewoo Lanos) - I happen to like it a lot. But the front is undoubtedly a major disaster. The dealership also had the "profi" version of Impreza on display - called WRX STi - which looked marginally better, but was still not a work of art. Not being easily discouraged by loks alone, I got inside the profi model and started adjusting myself in the driver seat. Apparently this caught the attention of the sales guy. Who was a weird looking individual - dressed in proper salesman suit, but at the same time, tattooed all over his body. He offered me a test drive, I accepted.

The interior of the Impreza is much better than its exterior. It has this spartan feel to it - no obvious luxury or numerous buttons and dials to be found - but at the same time, it is solid and feels like it is designed with a driver in mind. Seats are comfortable, but sporty, the car "just fits".

But the real question is how it drives, isn't it? Well, it actually is a great car to drive. I love the 4-wheel drive - no over- or understeering on this car, even when I tried aggressive turns at speeds that were positively dangerous :). The suspension is also great - we have tried in on the crappiest road we could find in the neighbourhood and the car passed the test with flying colors.

The feature I liked most though is the "gear reductor" thingy, next to the gear stick. It gives the car an amazing accelleration boost, which you might need sometime, by cutting the gear shift ratio in half.

Another fature I liked is the "growly", roaring sound of the boxer engine, which is quite delicious.

Any negatives (apart from the looks)? Well, the loading space is quite limited (ca 300 liters), but like I said previously - I don't need another family car. I need something with a sapce for just one person, which is cool and not overly expensive.

Overall, I liked the car very much. But for godness sake - please Subaru, give the front-end a bit of a facelift. If you do, I will absolutely purchase this baby. But as of today - the competition from your arch-rival is a bit too tempting to pass on.

Next time - The Rival - Mitsubishi Lancer Sedan Intense 1.8

Monday, September 22, 2008

Kalamon's Car Reviews #2 - Mini Cooper

After my failed attempt at test-driving the Smart, I have decided to go the Mercedes' arch-rival's headquarters and try out the Mini. This turned out to be a really pleasant experience. Read and learn Mercedes sales people - that's how you should treat guys who can potentially leave a handsome wad of money in your bank account.

I entered the premises and was immediately greeted by a sales guy. Upon noticing my interest in the Mini (it was prominently displayed in the dealership), he offered me a test-drive right away, despite very late hour (it was something like 10 minutes before closing time). And what a test drive this was indeed - we spent something like a full hour driving in many places, including a crowded city streets, a highway, abandoned and empty road, whatever came to mind. Basically he let me try the vehicle inside and out. Kudos to this guy. If his boss is reading this: man, you should give this bloke a raise.

Ok, so what do I think about the Mini, after trying it out? Well, it is not so simple. Despite obvious flaw of not having any sort of usable backseats (you have to chop your legs off at the knees to be able to sit there), the car is pretty awesome. It has all it takes to be cool - very powerful, turbocharged engine, splendid brakes, traction control, great suspension. It handles very well and is quite fast. This is matched by the features of the interior - awesome quality of the materials as well as all sorts of gizmos and gadgets. Like the auto engine switch on/off when you stop on the lights (this is supposed to conserve fuel). Like the fact that it will play music right off the USB stick you plug into the dashboard. Like the cool (but sort of pointless) fact that you can actually change the color of the dashboard lights. Whatever you want, this car has it. The styling of the interior is flawless. It is all basically pretty awesome.

So what's wrong then? The problem I am having with this car is that is sort of feels "fake". It is as if some corporate committee at BMW had decided to create a product with a strict mission of being attractive to aging but wealthy ex-hippies. You know, the ones who would these days normally drive a BMW or a Lexus, but sort of long for the old days when they owned an old and really hopelessly crappy Mini or a VW bug, had lots of casual sex, did plenty of LSD and pot. But - they would not really want to sacrifice the comfort their current income affords them, so the real Mini is out of the question as a mode of transportation (well, I don't blame them - it is a piece of shit :)). The whole car looks like it has been designed by some overly homosexual fashion designer - like the bloke who won Project Runway. Or one of the runner-ups. I can totally envision these guys drawing the concept sketches for the Mini.

Well, this is not my crowd. I don't really remember the sixties. The nostalgia the Mini is supposed to invoke does not work on me (even though I think Led Zeppelin is the best ban Evar and Jimmy Hendrix is a minor deity). And even if I did remember the sixties - I am sorry, but manufactured coolness is not something I enjoy.

I guess I am just not old enough for this car :)

Next two installments will be devoted to the two sworn enemies - Subaru Impreza and Mitsubishi Lancer.

Friday, September 19, 2008

Kalamon's Car Reviews #1 - Smart ForFour

In the first installment of my Clarkson impersonation, I will review my experiences with test-driving a Smart. Well - to be precise - trying to test-drive a Smart, with unexpected and very telling result.

So, on my way home from work, I am usually passing a local Daimler-Chrysler car dealership (as well as their arch-rival - BMW, but that will be the subject of my next review). Recently, I have noticed a prominently displayed "Smart" logo on their banners. Having seen Smart cars and pre-deciding that they indeed do look cool, I wanted to try one out. Specifically, I liked the "ForFour" model, not being aware of the fact that sadly it is no longer in production (sorry Mercedes folks - I am not exactly a fan and don't follow your production cycles on a regular basis).

I entered the dealership. Now, in a typical place like that (at least in my country) you would be immediately approached by a salesperson, desperately trying to sell you a new car, knowing that you are much more likely to get one from someplace in EU for half a price, than buying form them. They would be insanely polite, offer all sorts of propaganda materials, test drive, coffee, basically be at your service. Well... - not at Mercedes apparently. There were two or three sales dudes visible. One of them yapping on the phone, two looking bored and tired. None of them even trying to approach me. It was like I didn't even exist. What's more, there was absolutely no way to even evaluate any of the numerous cars displayed (including a pretty awesomely looking Mercedes SLK) - they were all shut close. My attempts to forcefully open some of them were not met with even a slightest attention of the sales drones. And there even was a Smart there - the small ForTwo. Not the one I wanted, but still, could be worth a try. It could have even turned out to be the one I would want to buy. But this one was not accessible also, so I finally gave up and went across the street to the BMW-land.

The question is: WTF was this all about? Did they not want to get a potential customer? Did I look like "not our customer" type (damn, I even happened to wear a proper formal work dress on that day)? I have no idea and I don't really care. I was their customer, they didn't give a damn about me.

So, if any of the Mercedes dealers are reading this (especially you guys) - I have this to say to you:

Fuck you too

Sorry folks, I won't be buying from you. Ever. Even though your cars seem to be quite awesome (or so I hear from my friends owning them). I will much rather car-shop at some other places, where I am treated like a customer, rather than a nuisance and maybe even a potential thief - like the one just across the street from you which turned out to be MUCH friendlier.

Alt key on MacOSX X11 server

Performance of the IntelliJ IDEA on my MAC has recently been far from optimal (despite 4Gigs of RAM, without which it just did not run), so I decided to steal some cycles from my colleagues Quad Core server.

All seemed fine (after installing half of dev environment, thanks Lukasz for claiming the machine is ready while it didn't even had sshd or java ;-) ) except for one tiny detail: X11 server on Mac did not pass the Alt key, which IDEA on Linux seems to like a lot.

After half a day of googling (lunch included) I managed to find the solution:
  1. make sure X11 works at all (beyond scope of this post)
  2. enable plain X11 network access (ssh tunneling causes too much latency to use it comfortably):
    after starting the X11 server:
    xhost +paulaner (where paulaner is the name or the address of the server)
  3. get the Alt keys working (inspired by this post)
    prepare ~/.xmodmap according to the post
    run xmodmap ~/.xmodmap when suitable to have your Alt keys (hint with .xinitrc did not work for me, though - it destroyed more than it fixed)

All of this is obvious once you know what exactly you need to do.
Happy development over X11 :-)

Wednesday, September 17, 2008

Impersonating Clarkson - or - Kalamon's Car Reviews. Intro

The time is near when my beaten and battered Toyota Yaris will have to be replaced with something new. It is not an urgent thing to do - it still has a year or so of useful life in it, but I have decided to start slowly looking for a new car.

Approaching 40, which is awfully close to a midlife crisis, I need a car that has one very important feature - it has to be "cool". Its coolness may manifest itself in various ways, but it absolutely has to be there :). Which means that I will absolutely not want yet another Yaris. Or, God forbid, Corolla Verso. Don't get me wrong, Verso is an awesome family car and I have already purchased two over the last four years (one of which died a sudden and unexpected death in a violent crash with a modded Honda driven by some youngster with too much adrenaline in his blood). But - I don't need another family car - I need something that will compensate for my receding harline.

Another fature for the car to be is its price - no more than some 22-25k Euro or thereabout (I am not that wealthy yet - but it's coming ;)) - which means "no" to either Lotus Elise or Mitsubishi Lancer Evo X unfortunately :(.

So I will be doing my Clarkson impersonations in a couple of my next blog posts, describing my impressions from test-driving candidate cars.

So far, I have tested the following models:
  • Smart Forfour (well... - more about that one in the next installment)
  • Mini Cooper
  • Subaru Impreza ("pedestrian" version, not STi)
  • Mitsubishi Lancer Sedan (no, not Evo unfortunately)
  • Honda Civic type S
All of the above models I assumed to have a potential of coolness in them.

I am looking around for other alternatives, so if any of the readers have suggestions and proposals of cool cars to try out, please, by all means, speak up.

Monday, September 8, 2008

PoisonInspection for IntelliJ IDEA

I was refactoring quite a big piece of code that I had inherited when I noticed a repeating problem:

Every time I introduced a setter or a getter for a field, I had to search for field references to update them to the proper setter/getter invocation.
More often than not, I forgot to do this and spent lots of debugging time to find out where my code assigns one field without updating other or reads field without proper validation.

The idea of the PoisonInspection IDEA plugin was born.
It took me some time to put the code together, but here you go.

The inspection would detect field access that bypasses your getter or setter and mark it as an error.
I made some effort to reduce false alarms, so don't be afraid to try.
It's interesting how many setter problems I found in JDK's code itself ;-)

BTW, I also learned that writing language-aware plugins for IDEA is really easy - the PsiModel is really powerful. Good job, JetBrains :-)

Wednesday, September 3, 2008

A few hopefully useful things for Jetbrains Intellij IDEA plugin writers

Having worked recently on a plugin for Intellij IDEA 7 I used a few things not necessarily so obvious for IDEA plugin writers as documentation around writing plugins is far from perfect :)

Here they are. Maybe this stuff will be useful also in incoming IDEA 8 release.

1.Rule one - don't use singletons in your plugin
Singletons are evil. In IDEA they are evil even more as you must support multiframe environment (where each project is opened in a separate frame). If you, foolishly, start using singletons for your windows, models, panels, configuration you will end up with nasty interference between all IDEA frames. IDEA provides you all the tools to avoid using of singletons: application, project and module components (they have to implement special interfaces though), hierarchical Pico container (you may put there any object there without special requirements for the interface) and easy access to it, e.g.:

// getting component registered in Pico container
public static T getProjectComponent(final Project project, final Class clazz) {
return clazz.cast(project.getPicoContainer().getComponentInstanceOfType(clazz));
}

The only reasonable excuse for using singletons is establishing really global components for the whole IDEA platform (which must be shareable between IDEA frames), but still you should do is via interfaces and dependency injection everywhere (or pulling your global component from Pico as a last resort) than creating anti-pattern MySingleton.getInstance().
Sometimes you may be tempted to use singletons due to IDEA Action System (IDEA actions cannot normally injected dependencies). Do NOT do it. Instead inject your domain objects to data context (see below) or use helper methods to fetch your current project or module and then retrieve desired component from it or its Pico container. Normally it's enough to use AnActionEvent to find out which project given action should refer to, e.g.:

@Nullable
public static Project getCurrentProject(DataContext dataContext) {
return DataKeys.PROJECT.getData(dataContext);
}

@Nullable
public static Project getCurrentProject(AnActionEvent e) {
return getCurrentProject(e.getDataContext());
}

AFAIK if you want to use actions defined via your plugin.xml file, there is no way to inject anything to them (in DI sense - action objects are after all single instance objects serving in various contexts - e.g. for various buttons, menus or even projects). Thus you have to resign from “Hollywood call” mode (as it would make your object stateful) and starting pulling your dependencies using techniques (without storing them as instance variable - as it would make actions stateful) described above, e.g.:

public class MyAction extends AnAction {
// ...
@Override
public void actionPerformed(final AnActionEvent e) {
// fetch a project compoment defined in plugin.xml
MyComponent myProjectComponent = project.getComponent(MyComponent.class);
// fetch custom project component registered manually
// (outside plugin.xml) on project level - see helper method above
MyCustomComponent myCustomComponent = getProjectComponent(
final Project project, MyCustomComponent.class)
// ... do something now with your components
}
}

2.Finding current project from your ComboBoxAction
Getting Project reference here may be more challenging as we don't have access to AnActionEvent while deciding what options should be available in the combo box. However IDEA internally seems to use the following trick:

public class ComboBoxAction extends ComboBoxAction {

@NotNull
@Override
protected DefaultActionGroup createPopupActionGroup(JComponent jComponent) {

final Project project = DataKeys.PROJECT.getData(
DataManager.getInstance().getDataContext(jComponent));

final DefaultActionGroup g = new DefaultActionGroup();
// knowing your project populate g
// ...
return g;
}

3.“Injecting” your own domain objects into Action system
It turns out that Action system is very powerful and it's easy to make actions aware of your own objects if they are “in scope” (e.g. to enable/disable an icon or respond to user click when an element of your domain object model is selected in some editor).
We want to achieve the following:

public class MyAction extends AnAction {
@Override
public void actionPerformed(AnActionEvent event) {
MyObject myObject = event.getData(MY_OBJECT_KEY);
if (myObject != null) {
// do something with your domain object
}
}

@Override
public void update(final AnActionEvent event) {
MyObject myObject = event.getData(MY_OBJECT_KEY);
// e.g. action must be enabled if MyObject is really available in the context
event.getPresentation().setEnabled(myObject != null);
}

To achieve it, it's enough to:

  • define MY_OBJECT_KEY, e.g.:

    public static final DataKey<MyObject> MY_OBJECT_KEY = DataKey.create(“some-unique-key”);


  • implement com.intellij.openapi.actionSystem.DataProvider interface in your UI components which are responsible for displaying your model objects (e.g. some tree or table)

    public final class MyTreePanel extends JPanel implements TreeSelectionListener, DataProvider {
    private JTree myTree;
    private MyModel model;
    // your normal UI logic goes here

    @Nullable
    public Object getData(@NonNls final String dataId) {
    if (dataId.equals(MY_OBJECT_KEY.getName())) {
    // return appropriate domain object model of MyObject type
    // (e.g. the one which is currently selected in the tree
    // or return null if there is no reasonable candidate
    // (e.g. nothing is selected)
    }
    return null;
    }
    }


You can easily stack your DataProviders and getData() implementation (e.g. composite may delegate the search one or several to its children).

4.Fetching revision X of selected virtual file ...
... without resorting to fetch whole file history (extremely painful in IDEA with remote SVN repository)

@Nullable
private static VirtualFile getVirtualFileRevision(
@NotNull final Project project, @NotNull final VirtualFile virtualFile,
@NotNull String revision) throws VcsException {
AbstractVcs vcs = VcsUtil.getVcsFor(project, virtualFile);
if (vcs == null) {
return null;
}
VcsRevisionNumber vcsRevisionNumber = vcs.parseRevisionNumber(revision);
DiffProvider diffProvider = vcs.getDiffProvider();
if (diffProvider == null) {
return null;
}
ContentRevision contentRevision = diffProvider.createFileContent(vcsRevisionNumber, virtualFile);
if (contentRevision == null) {
return null;
}
// this operation is typically quite costly (unless revision points to checked out file)
final String content = contentRevision.getContent();
if (content == null) {
return null;
}
return new VcsVirtualFile(contentRevision.getFile().getPath(), content.getBytes(),
vcsRevisionNumber.asString(), virtualFile.getFileSystem());
}

Thank you Dmitry Jemerov for your help while solving our issues with OpenAPI and helping us where IDEA documentation did not.