Creating an polish.dic for IntelliJ IDEA

Posted by Ktoso under coding, english, java, polish, terminal heroes (No Respond)

I’ve been coding a lot GWT/Android lately, and was using IntelliJ IDEA for this – a very nice IDE. (Yup, I’ve even got an personal license now). That said, the spellchecking is really important to me, sadly I couldnt find an ready do download polish.dic file which IntelliJ would then use to spellcheck our i18n strings – bur fear not, hese is an cool one liner that will create such polish dictionary:

aspell --lang pl dump master | aspell --lang pl expand | tr ' ' '\n' > polish.dic

You’ll have to install the polish aspell package of your distro of course before you launch this command ;-) Then just create an dedicated folder dor *.dic files and show IntelliJ to use it. Done – perfect spell checking in your IDE… and even while committing changes: http://blogs.jetbrains.com/idea/2010/08/no-more-misspellings-in-your-vcs-commit-comments/

[song] Follow the GNU – Void Main feat. Richard ‘rms’ Stallman

Posted by Ktoso under null (No Respond)

Todays fun-friday will be about my most super favourite geek song of all time. It’s basically just a part from Richard Stallman‘s speech from NY from 2001 with neat music added to it. I really like this speech as it is both powerful and easy to understand for licensing newbies. That said, here is the ogg file and some of the lyrics. Why ogg? Because it’s an free (as in Freedom) alternative to MP3s, and sometimes ofers even better quality than mp3s. :-)

Void Main feat. Richard Stallman – Follow the GNU .ogg

Now, some of you may not ever write computer programs, but perhaps you
cook.  And if you cook, unless you're really great, you probably use
recipes.  And, if you use recipes, you've probably had the experience of
getting a copy of a recipe from a friend who's sharing it.  And you've
probably also had the experience -- unless you're a total neophyte -- of
changing a recipe.  You know, it says certain things, but you don't have
to do exactly that.  You can leave out some ingredients.  Add some
mushrooms, 'cause you like mushrooms.  Put in less salt because your
doctor said you should cut down on salt -- whatever.  You can even make
bigger changes according to your skill.  And if you've made changes in a
recipe, and you cook it for your friends, and they like it, one of your
friends might say, "Hey, could I have the recipe?"  And then, what do you
do?  You could write down your modified version of the recipe and make a
copy for your friend.  These are the natural things to do with
functionally useful recipes of any kind.

Now a recipe is a lot like a computer program.  A computer program's a lot
like a recipe: a series of steps to be carried out to get some result
that you want.  So it's just as natural to do those same things with
computer programs -- hand a copy to your friend.  Make changes in it
because the job it was written to do isn't exactly what you want.  It did
a great job for somebody else, but your job is a different job.  And
after you've changed it, that's likely to be useful for other people.
Maybe they have a job to do that's like the job you do.  So they ask, "Hey,
can I have a copy?"  Of course, if you're a nice person, you're going to
give a copy.  That's the way to be a decent person.

So imagine what it would be like if recipes were packaged inside black
boxes.   You couldn't see what ingredients they're using, let alone change
them, and imagine if you made a copy for a friend, they would call you
a pirate and try to put you in prison for years.  That world would create
tremendous outrage from all the people who are used to sharing recipes.
But that is exactly what the world of proprietary software is like.  A
world in which common decency towards other people is prohibited or
prevented.

The above text was taken from: http://www.gnu.org/events/rms-nyu-2001-transcript.txt Feel free to spread the love of free software + music… and of course, follow the GNU! :-)

If you got interested in Stallman’s views, and would like to know a little more about his view on the music industry etc, feel free to take a look at this video that I have recorded on 2009′s IT Giants at Cracow AGH University:

[song] Every OS sucks!

Posted by Ktoso under freedom, fun (No Respond)

An very amazing and beautiful song I just had to share with you guys! It’s by http://www.deadtroll.com/ so feel free to get over to their site if you liked it :-) It’s my second favourite GeekSong – I’ll link my favourite next week (by VoidMain and an special guest!)… :-)

Download the MP3 file: three_dead_trolls_in_a_baggie-every_os_sucks.mp3

And here are the lyrics:

(spoken introduction)

You see, I come from a time in the nineteen-hundred-and-seventies when computers were used for two things – to either go to the moon, or play Pong… nothing in between. Y’see, you didn’t need a fancy operating system to play Pong, and the men who went to the moon–God Bless ‘em–did it with no mouse, and a plain text-only black-and-white screen, and 32 kilobytes of RAM.

But then ’round ’bout the late 70′s, home computers started to do a little more than play Pong… very little more. Like computers started to play non-Pong-like games, and balance checkbooks, and why… you could play Zaxxon on your Apple II, or… write a book! All with a computer that had 32 kilobytes of RAM! It was good enough to go to the moon, it was good enough for you.

It was a golden time. A time before Windows, a time before mouses, a time before the internet and bloatware, and a time… before every OS sucked.

*sigh*

(singing)

Well, way back in the olden times,
my computer worked for me.
I’d laugh and play, all night and day,
on Zork I, II and III.

The Amiga, VIC-20 and the Sinclair II,
The TRS 80 and the Apple II,
they did what they were supposed to do,
wasn’t much… but it was enough.

But then Xerox made a prototype,
Steve Jobs came on the scene,
read “Of Mice and Menus,” Windows, Icons
a trash, and a bitmap screen.

Well Stevie said to Xerox,
“Boys, turn your heads and cough.”
And when no-one was looking,
he ripped their interfaces off.

Stole every feature that he had seen,
put it in a cute box with a tiny little screen,
Mac OS 1 ran that machine,
only cost five thousand bucks.

But it was slow, it was buggy,
so they wrote it again,
And now they’re up to OS 10,
they’ll charge you for the Beta, then charge you again,
but the Mac OS still sucks.

Every OS wastes your time,
from the desktop to the lap,
Everything since Apple Dos,
Just a bunch of crap.

From Microsoft, to Macintosh,
to Lin– line– lin– lie… nux,
Every computer crashes,
’cause every OS sucks.

Well then Microsoft jumped in the game,
copied Apple’s interface, with an OS named,
“Windows 3.1″ – it was twice as lame,
but the stock price rose and rose.

Then Windows 95, then 98,
man solitaire never ran so great,
and every single version came out late,
but I guess that’s the way it goes.

But that bloatware’ll crash and delete your work,
NT, ME, man, none of ‘em work.
Bill Gates may be richer than Captain Kirk,
but the Windows OS blows!

And sucks!

At the same time!

I’d trade it in, yeah right… for what?
It’s top of the line from the Compuhut.
The fridge, stove and toaster, never crash on me,
I should be able to get online, without a PHD.

My phone doesn’t take a week to boot it,
my TV doesn’t crash when I mute it,
I miss ASCII text, and my floppy drive,
I wish VIC-20 was still alive…

But it ain’t the hardware, man.

It’s just that every OS sucks… and blows.

Now there’s lih-nux or lie-nux,
I don’t know how you say it,
or how you install it, or use it, or play it,
or where you download it, or what programs run,
but lih-nux, or lie-nux, don’t look like much fun.

However you say it, it’s getting great press,
though how it survives is anyone’s guess,
If you ask me, it’s a great big mess,
for elitist, nerdy shmucks.

“It’s free!” they say, if you can get it to run,
the Geeks say, “Hey, that’s half the fun!”
Yeah, but I got a girlfriend, and things to get done,
the Linux OS SUCKS.
(I’m sorry to say it, but it does.)

Every OS wastes your time,
from the desktop to the lap,
Everything since the abacus,
Just a bunch of crap.

From Microsoft, to Macintosh,
to lin– line– lin– lie… nux.
Every computer crashes,
’cause every OS sucks.

Every computer crashes… ’cause every OS sucks!

Tags: , , , ,

GWT Firefox 3.6+ plugin on 64bit Fedora 13

Posted by Ktoso under coding, guide, java (3 Responds)

Hi again, this time a short code snippet – but a very useful one.

At work I’m working on an Ubuntu 10.4 (love you guys for getting me a PC with Linux with no problems!) my laptop is on Fedora 13 i586 and my home PC is running Fedora 13 x64. Thank goodnes they’re all linux… ;-) The problem is was that the Google Web Toolkit plugin isn’t working with Firefox 3.6.4 on an x64 system on linux! So… can’t I develop GWT stuff on my super powerful home PC? Of course I can, the only thing I needed to do, is to get the latest sources for the plugin and compile it for myself ;-) Here’s how:

mkdir gwt-source
  1. cd gwt-source
  2. svn checkout http://google-web-toolkit.googlecode.com/svn/trunk/ trunk
  3. svn checkout http://google-web-toolkit.googlecode.com/svn/plugin-sdks/ plugin-sdks
  4. cd trunk/plugins/xpcom
  5. export BROWSER=ff36
  6. export DEFAULT_FIREFOX_LIBS=/usr/lib/xulrunner-devel-1.9.2/sdk/lib/
  7. make clean
  8. make
  9. firefox prebuilt/gwt-dev-plugin.xpi

And we’re done — off to GWT development!

Tags: , , , , ,

Git @ “Fridays at XSolve”

Posted by Ktoso under coding, english, fun, java (2 Responds)

I’m curently doing an internship (It’s called: “Poławiamy perły, szlifujemy diamenty” == “Pooling pearls, polishing diamonds” — very cool :-)) at XSolve – we’re doing some GWT coding and I really like it. The team is great and everyone is really helpful and fun to talk to — the company’s “look and feel” reminds me very much of Google by the way… It’s very friendly, everyone is calling others by their names and we often play together after some chunk of work. We’ve even stayed until 20:00 one time, while mounting some servers and having fun in the process – I actually didn’t mind staying so long thanks to this… :-)

Having that said… there is one thing I don’t like there… it’s SVN ;-) Of course I knew that I can’t be running from SVN all my life and that I’d end up using it someday in some company… As some may know, I’m a big Git (or mercurial) fan, thus – I kinda see what SVN is doring wrong. At XSolve we have this weekly-event called “Fridays at XSolve”, where one can present in a short 30min session, something he’s been interested in lately etc. It’s a really cool idea, that allows ideas do spread throughout the company – the HR team seems to really care to keep this atmosthere in the company… :-) This Friday I was given the honour and joy to be presenting Git – as we’ve been talking about it a few times during my first week here. Below is the presentation I’ve used:

You can download the presentation or the sources for the presentation here as they are also a simple (I’ve made one about Guava that’s a little more interesting from the TeX viewpoint) example of the LaTeX beamer – which apparently is also an favourite tool of some team members… :-) I’ve also talked a moment after the event with an v. good (so it seems) developer who knew really a lot about many different SCMs – we mentioned “cherry picking” which is really interesting but I don’t know much about it yet. If you don’t know much about Git – take a look at the above presentation, or better, start out your new (better) life with git by visiting these links:

The presentation worked quite well I guess – some team members who knew about Git/SVN/Mecurial/Bzr etc, where adding their bits of knowledge which really made the presentation a lot more than just a bunch of boring slides… ;-) All in all it was all of those: fun, interesting and yet another occasion for me to train presenting stuff (I’m still bad at it, but well… life is study, right? :-)) I’m really happy to have the opportunity to be working in such a environment – I’ll post whatever is inseresting on this blog (if I have the time to do so :<), so keep an eye ot for some Java/GWT posts… :-)

Tags: , , , , , ,

ip2cntry – ex-appengine app (mainly JAX-RS)

Posted by Ktoso under coding, guide, java (No Respond)

I’ve been coding an simple RESTful “ip to country” conversion service. I’ve decided to put it up to appengine – so that everybody may use it freely even if I’d change my server etc… And if looked quite nice the first day – buw when I got to do some “real stuff” app engine started to get in my way, here’s a quick rundown of the problems I’ve found with appengine:

  1. I need to download and update the ip<->country database every few days. I’d use an GZIPInputStream and BufferedReader to get the file I was interested in and update the database. Did appengine allow me to use such an simple aparoach?
    1. pro: appengine provides a very nice cron-like mechanism. So I just had to create an cron.xml in WEB-INF and this part was ready to go! This was in fact easier and more fun than in classic Spring + Open Symphony Quartz.
    2. con:I checked if this tactic was OK with the JRE whilelist and checked the Quotas – http://code.google.com/appengine/docs/quotas.html#UrlFetch, “seems ok” – I thought – “nothing about per connection limits, only daily quotas.”. After writing the code, I discovered that even though on the main quota page there was no word about per connection limits, in fact there are such quotas, but a little more hidden: http://code.google.com/appengine/docs/java/urlfetch/overview.html Max request/response sizes are capped at exactly 1MB.
      As my gzipped file is around 1.1MB, appengine killed my simple idea… I’d have to split the file into separate ones – on another server, and then fetch the separated files onto appengine.
    3. con:The mentione CRON mechanism is quite funny. You don’t call methods but URLs – and they are normally called as if one would launch them from the browser – thus, traffic and “max time” quotas do count there as well. So rather than calling an method, as you’d do with OpenSymphony – you create an Servlet that does all the work. This may me both good, and bad… You cound do all the CRON stuff by hand if it got out of sync etc… I didn’t really like it, and as mentioned… When doing my “big batch database update” the servlet would simply timeout…
  2. Let’s talk about the dataStore. As you all probably know… AppEngine does not provide and “database” per se. It’s not relational and has quite some limitations. BUT! That’s quite ok, as it’s very quick and very very scalable! And most of the time… Do you really need all those fancy relations? ;-) It was an ideal place to hold my super simple data: “ip region = country” mapping in a persistent way. “Another nice thing on appengine for this application I’m going to write.” – I thought. Was I right?
    1. pro/con: Not really… I used JPA but JDO (which is prefered by appengine from what I’ve seen) also works nice on GAE. The setup did run quite ok while I was running tests on my local machine. Deployment is also an breeze and I didn’t have to use any complicated dependencies to get it running – “yay, no maven!”. You just have to enchance the classes you want to make persistent (just as hibernate does).
    2. con:The problems started when I wanted to clear my datastore. Nothing easier than that, right…? “delete from BlaBla” and we’re done. Yeah, but not on GAE. As even the “max rows a query touches” are limited – to 500. So there I am, with my 100.000 rows, and I have to delete them in 500 rows per query… Of course I can’t call this in an loop – as the timeout quota would get in my way and kill the app.From what I’ve seen, people do solve this using a CRON task that calls this “clearDatabase” servlet until it’s  done – ugh, not a nice solution but I can’t think of any other solution :\
    3. con:The only query I need to do in this app is basically:
      SELECT range FROM RemoteIpData as range
                   WHERE range.ipFrom <= ?1
                     AND range.ipTo >= ?2
      #and this would always return 1 entry!
      

      And guess what… AppEngine does not support multiple “less/more than” operands in one query! If you think hard about what BigTable is, it does make some sense. More information about “GQL” can be found here: http://code.google.com/appengine/docs/python/datastore/gqlreference.html All the restrictions about the Queries you can do are documented here – some are really counter intuitive when you come from an RDBMS enviroment… Ah well ;-) Oh, and yet another great link about GAE limitations.

      Having this limitation, really sucks for my normally “super simple query”, and I’d have to change the data structure somehow or do some awful 2 queries and then combine them in Java (omg teh terrorr… :<). So, while developing on appengine, keep in ming – simple things might turn out quite complicated due to the nature of BigTable. If you know all the limitations when designing the system and not while finishing it, you’ll be a happier man… ;-)

    4. neutral: Primary keys can’t be Integers etc, as AppEngine uses it’s own “Key” type. :-)
  3. Having that all said. Appengine’s administration panel is quite ok. And the not-so-newly-added log search etc are really fine tools. Something an plain old tomcat can not offer. On the other hand, the limitations can really be a deal breaker! My app was really fairly simple, and yet appengines quotas managed to really get in my way. Keep this in mind while thinking about using it. You may also try Amazon’s cloud or CloudForce from SalesForce etc… They all do offer a quite less restrictive enviroment.
  4. If you’re interested, deployment does take about 5-7 minutes before the new version is visible on the web – so don’t panic if you’re still seeing the old version after deploying the new one.
  5. My opinion about GAE…? (semi serious ;-))

“Screw you clouds, I’m going /home!”
(intended southpark pun)

I’ll finish this project using my ol’ pal, Tomcat6 which I’ve already got running for netbeans.edu.pl (but that was an grails app).

I’ve also decided to use Spring, which I didn’t really need on appengine – as the only thing I was doing was so small that all the logic was around 10 lines in the servlets… But if using hibernate and all the other “real” JEE stuff, I felt I’d need to “do this right” so I’ve decided for Spring 3 and Maven2… I’ll try to build this project from gradle soon too!

ALSO! If interested in an more experienced programmers view on appengine (I’m still a novice), go and read this blog post about GAE on Sławek Sobótkas blog. All in all we seem to agree that the limitations can be an pain in the a… ;-)

The source for the appengine version is on my github account. I’m porting it to an plain old tomcat environment and will post this version there too when it’s ready to run (tomcat deployment is somehow hell with such apps for me… Any tips are really welcome :-))

Tags: , , , , , , , , , ,

GitHub Diff in Gmail

Posted by Ktoso under coding, english, fun (3 Responds)

Hi there, below is the (horribly trashy and chaotic – as it was hacked up in about 2/3 hours) source for my Google Gmail Contextual Gadget.

It extends Gmail by parsing all links passed in an email, and if an github commit link is found it displays the diff for this commit. With coloring etc – just as github would. It’s really fairly easy to get this kind of things going, and if your working with Google Apps (using gmail in your domain etc) you can use this, and many more gadgets (though I didn’t find much of them really useful – that’s why I’ve written this one).

The source can be downloaded, and fixed (which I hopefuly will have time to do! As it’s a mess, let’s say, “proof of concept”): http://github.com/ktoso/GitHubDiff (It’s on the MIT license).

Read the full story to see instalation instructions as well as documentation links…
Read More…

Tags: , , , , , ,

JavaCamp #4

Posted by Ktoso under coding, english, java, review (2 Responds)

Polish Java User GroupYup, last Saturday we’ve had yet another JavaCamp in Cracow. It was in my opinion the best yet – mostly due to our awesome speakers. One could call this “JavaCamp” an “ScalaCamp” if you think about it – as most of the topics (3/4) where mostly about scala (AKKA is avaiable as both Java and Scala API, but the Scala API is a little “cleaner” – well, as everything written in Scala I guess :-))

Łukasz KuczeraScala the next Java?

Łukasz’s presentation really did fit the topic and did a really good job in setting the “mood and feel” for the rest of the day. People who didn’t know any scala before – now did know it enough to understand all the code Jonas displayed later, and people who’ve known some scala before – might have got some nice information from this. I really liked it and am now more tha ever convinced of scala’s “perfect fit” nature in the JVM lanugages team. As I was sitting with my friend Temporal – who’s a real Erlang and Lisp hacker ;-) - I’ve got some interesting insights about what scala took from Lisp and later on, what Akka took from Lisp and Erlang. A very good presentation in my opinion. :-)

Jonas Bonér (private site) – Akka: Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

A very very awesome speech and topic. Akka seems to do Actors and Parallelism very well. Also, thanks to my lisp/erlang friend, I’ve had some amazing insights about where Jonas got some of the implementation ideas. Also, we’d both like to note that some things are done even cleaner in Akka than in Erlang: in erlang you’d pass an actors PID around in order to “link” with another, and the links are always bidirectional. The actor pattern really powerful and scalable from what I’ve seen. It’s also implemented by Vaclav Pech in his GPars library (“Groovy Parallelism”).

This should have been just another presentation in a series of them as Jonas already had presented it on both Scala Days 2010 and GeeCON2010. But! As the present programmers really where into this topic we’ve had a lot of pauses with some chit-chat. A very valuable thing for both akka and our community :-) Too bad that Jonas didn’t have the time to go more into STM, as I still dont really know what it essetialy is “in practice”. Later we got a glimpse of Agents and what they could be useful for. All in all… go checkout the movie – it’s worth your time if you don’t know about parallelism and akka (I guarantee it ;-)): jc4-1-scala-min.mp4

Jonas covered and built upon the previous presentation, and we got to see some more scala in action – feels really natural. The transition from Java->Scala seems to be as painless as the transition from Java->Groovy. That’s a really nice thing I guess. There’s also an Java API for most the things in AKKA – so if you don’t want to adopt Scala in your project – no problems here. If you’d like to read more about AKKA, just goto their website at: http://akkasource.org/ – and yes, it’s open source. :-)

Oh, and if you’d like to see the slides Jonas used: they’re online on his slideshare: http://www.slideshare.net/jboner/akka-scala-days-2010
Also feel free to read this very in-depth post on his blog: Introducing Akka – Simpler Scalability, Fault-Tolerance, Concurrency & Remoting through Actors

Pizza

In the break we had some chats about the usual stuff – programming, companies, and of course a little something about the gaming industry ;-) The pizza was quite tasty – as always – so let’s move on to the next presentation ;-)

Bartosz KowalewskiIs OSGi ready for enterprise use?

Yet another go with “grasping wtf OSGi is and WTF would I use it?!”. This topic was kinda new to Temporal, as he’s not into JEE Java, where OSGi now seems to be “trendy”. So after a short intro into maven/dependency stuff from me we focused on Bartosz’s presentation. I was immensly happy to see that his thoughts and presentation focused on “what OSGi should solve, and why it sometimes does NOT”. His code examples really cleared up what the problem is, and displayed why OSGi is sometimes a much harder to force to work properly than we’d think it should.

All in all, he described it as an amazing technology to play with, but if one would to use it IRL, with real deadlines etc – one should better know what he’s getting into, as OSGi does solve some things, but in exchange it introduces a lot of more compicated problems. The presentation was really good – as it focused, and really showed how/why OSGi should be awesome, and why sometimes it’s not – most of the time with needless complexity (!).

UPDATE: If your interested in the examples Bartosz has shown during his presentation – download this this zip file that he has made available. It includes the presentation, as well as the sources he used (plus the maven artifacts needed to run the app). Don’t worry if some tests fail – they’re designed to… :-)

Łukasz KuczeraLift – simply functional web framework

The last presentation was again Łukasz, continuing in the spirit of this “Scala-flavoured-JavaCamp”, with Lift, an web framework with quite some nice contepts – as view first etc. As it was more of a code-trip, showing the basics of lift, there’s not much to comment on here.

I was kind of disappointed with Lift. It really didn’t seem to be as powerful or mature as Grails of Symfony for example. The “view first” pattern is of course nice and quite well “forced”, but it didn’t strike me to be any different than just Django templates. The CRUD also does not impress someone who’s been using Rail-ish stuff for quite some time. There was not much said about the ORM, but I feel quite comfortable with GORM and the routing system is waaaay overgrown – just look at symfony/grails/rails routing files – they’re short and easy – what I’ve seen in Lift does not seem to be short – it’s quite long and with lots of empty [] etc… I may come back and take a look at lift when I have the time, but it really didn’t impress.

Videos and sources from the meeting

The 4th edition for our JavaCamp was truly amazing in my opinion, and this time, we’ve even got an amazing place, sponsors and great speakers. Have a nice holiday all! And if you didn’t manage to be there live, you can always go to the page bellow and watch the video’s I’ve recorded from the meeting :-)

All videos are temporarily available on my server – here: http://pjug.project13.pl/
I’m hoping to get them up on the java.pl server soon, or better, on parleys.com – but we’ll see about that. :-)

PS: The next camp, won’t be organized so soon – but from what we’ve planed, we’ll be goring into some groovy topics most probably… But don’t take my word for it ;-)

Tags: , , , , , , , , , , ,

The Grails way #0: Simple Twitter TagLib

Posted by Ktoso under coding, java (No Respond)

Let’s skip the introduction of taglibs, (since anyone knows what they are), and get to the code really quickly! If you’ve seen netbeans.edu.pl you probably noticed the twitter part on the right. As twitter’s API is really simple to use, one could implement this on ones own, but why do so if we’re in the Grails -> Groovy -> Java world, where there are amazing libraries for most things.

I used 2 libs to create this tag:

Anyways, first the source of the actuall taglib. We simply call the methods, get the response fill out the content of the tag with the variables we got:

package pl.project13
  1.  
  2. import com.twitter.Autolink
  3. import twitter4j.*
  4.  
  5. class TweetsTagLib {
  6.   static namespace = 'tweets'
  7.  
  8.   /**
  9.    * Performs an twitter search and displays the result as an
  10.    */
  11.   def fromSearch = {attrs, body -&gt;
  12.     Twitter twitter = new TwitterFactory().getInstance()
  13.     Query query = new Query(attrs.query)
  14.  
  15.     QueryResult result = twitter.search(query)
  16.  
  17.     def tweetz = result.tweets.subList(0, Integer.parseInt(attrs.count))
  18.     tweetz.each {Tweet tweet -&gt;
  19.       Autolink parser = new Autolink()
  20.       tweet.text = parser.autoLink(tweet.text)
  21.  
  22.       pageScope.tweet = tweet
  23.       out &lt; &lt; body(tweet)
  24.     }
  25.   }
  26.  
  27.   //some other stuff…
  28.  
  29. }

Super easy, ain’t it? More stuff about taglibs in grails can be found here. Now let’s go over to our view and see how to use this taglib – it’s (once again) amazingly simple:

  1. <g :set var="query" value="netbeans"/>
  2.  
  3. <h3>Twitter #${query}</h3>
  4. <div id="twitter" class="menubox">
  5.   <ul>
  6.     <tweets :fromSearch query="#${query}" count="8">
  7.       <li>
  8.         <a href="http://www.twitter.com/${it.fromUser}" target="_blank" class="twitter-author">
  9.           <img src="${it.profileImageUrl}" alt="${it.fromUser}" title="${it.fromUser}" style="float:left; padding:2px; width:25px; height:25px"/>
  10.           %{–${it.fromUser}:–}%
  11.         </a>
  12.         ${it.text}<br />
  13.         <span style="font-size:0.75em" class="twitter-date">${it.createdAt}</span>
  14.       </li>
  15.     </tweets>
  16.   </ul>
  17.  
  18.   &#187;&nbsp;<a href="http://twitter.com/#search?q=${query}" target="_blank">więcej</a>
  19.  
  20. </div>

All we need to do here, is set an variable thanks to some nice GSP tag, and then use it to query and echo our data the taglib is supplying us with. Note that the tweets:fromSearch acts like an foreach – no need for any extra loops here :-) That’s just a very simple tag but it’s quite nice to use, hope you enjoied it and will be more than happy to see the sources of netbeans.edu.pl published on github soon… :-)

Tags: , , , , , , ,

NetBeans Platform Lookups as communication method

Posted by Ktoso under coding, english, guide (2 Responds)

Traveling Salesman on NetBeansPlatform

Helo again! Today’s post will be an super quick usage scenario for NetBeans Platform Lookups – the probably most essential part of the Platform. An super simple explanation of them is “an Map<Class, Object>”. Sounds simple right? Well it is, and it’s quite powerful at the same time. It enables you to loosely couple parts of your app, create extension points etc. Another use case is passing some date around in the app, but you don’t know where the modules interested in this data are (because you’re loosely coupled, right?). In an app I’ve been writing for my Uni since some days, I’ve used the Lookup to do exactly this – pass data from an algorithm to an LineChartDrawer that then will update it’s chart each time the data is being updated.

This is going to be quite similar to an  Observer Pattern implementation, but using the lookup as notification mechanism. Let’s start out with our Algorithm class (and module – note that this module is not dependent on the chart drawing module!)

package pl.edu.netbeans.algorithms;
  1.  
  2. import org.openide.util.Exceptions;
  3. import org.openide.util.Lookup;
  4. import org.openide.util.LookupListener;
  5. import org.openide.util.lookup.AbstractLookup;
  6. import org.openide.util.lookup.InstanceContent;
  7. import org.openide.windows.TopComponent;
  8. import org.openide.windows.WindowManager;
  9. import pl.edu.netbeans.algorithms.genetic.Chromosom;
  10. import pl.edu.netbeans.algorithms.genetic.Population;
  11. import pl.edu.netbeans.toolbox.ChartDataDTO;
  12. import prefuse.data.Graph;
  13.  
  14. /**
  15.  * The algorithm implementation, does some stuff and throws the data into an DTO which is packed into the lookup
  16.  * @author ktoso
  17.  */
  18. public class FirstTSSolverAction extends SolverAction implements TSSolverAction, Lookup.Provider {
  19.     private final Population population;
  20.  
  21.     //just to get us some fancy names for this algorithm
  22.     private static int simcount = 1;
  23.     private final String SIMULATION_ID = "symulacja " + FirstTSSolverAction.simcount++;
  24.  
  25.     /*
  26.      * Here we're setting up the Lookup, to work with dynamic content, thanks to this,
  27.      * we'll be able to modify it's contents and notify all listeners after some change has happened
  28.      */
  29.     private InstanceContent dynamicContent = new InstanceContent();
  30.     private Lookup myLookup = new AbstractLookup(dynamicContent); //AbstractLookup is NOT an abstract class, it's an "general purpose lookup"
  31.     private Lookup.Result res; //this is only here because I want to use allItems down there bellow, otherwise it would be just a variable in the method bellow
  32.  
  33.     public FirstTSSolverAction(Graph graph) {
  34.         super(graph);
  35.         //…
  36.     }
  37.  
  38.     /**
  39.      * This is not an Runnable class but the run method will act quite the same as if it was,
  40.      * as our framework will call it in constant time delays. We do all the computing here.
  41.      */
  42.     @Override
  43.     public void run(double frac) {
  44.         if (population.shouldStop()) {
  45.             //… stop the execution etc.
  46.             return;
  47.         }
  48.  
  49.         population.nextGeneration();
  50.         Chromosom ch = population.getBestChromosom();
  51.         int numerGeneracji = population.getNumerGeneracji();
  52.         double avgFitness = population.getAvgFitness();
  53.         double maxFitness = population.getWorstFittness();
  54.         double minFitness = population.getBestFitness();
  55.  
  56.         log("Generacja " + numerGeneracji + ": naj. chromosom: " + ch + " (" + avgFitness + ")");
  57.  
  58.         /* Słuchający tego lookup zostaną powiadomieni o zmianie, przerysują wykres */
  59.         dynamicContent.add(new ChartDataDTO(SIMULATION_ID, numerGeneracji, avgFitness, maxFitness, minFitness));
  60.         res.allItems();//I found it quite helpful in order to be sure that the listeners will notice the change
  61.     }
  62.  
  63.     //…
  64.  
  65.     /**
  66.      * Since we're an Lookup.Provider, let's provide our lookup!
  67.      * It can be implemented in multiple ways, but let's just return our lookup this time.
  68.      */
  69.     @Override
  70.     public Lookup getLookup() {
  71.         return myLookup;
  72.     }
  73.  
  74.     /**
  75.      * Poszukuje oraz ustawia listenera implementującego LineChartDrawer
  76.      * aby ten reagował na każdorazową zmianę w naszym lookup – aktualizował wykres
  77.      */
  78.     @SuppressWarnings("unchecked")
  79.     private void setupLineGraphDrawerListener() {
  80.         //a sucky but good enough implementation for our usecase
  81.         //Better solution: You could use another Lookup to find implementations of the "LineGrapghDrawer" interface and then use this instance here!
  82.         TopComponent drawer = WindowManager.getDefault().findTopComponent("FitnessGraphTopComponent");
  83.  
  84.         if (drawer == null) {
  85.             //depending on if you need this or not, throw exceptions or just ignore this if you dont need it
  86.             //throw new RuntimeException("Nie znaleziono implementacji FitnessGraphTopComponent. Nikt mnie nie słucha!");
  87.             //or…
  88.             log("No FittnessGraphTopComponent found. That's OK, so I will continue without it…");
  89.             return;
  90.         }
  91.  
  92.         //below is the actual settup of our "observer"
  93.         res = myLookup.lookup(new Lookup.Template(ChartDataDTO.class)); //setup the resultset to react to changes of ChartDataDTOs in it
  94.         res.allItems();//THIS IS IMPORTANT! Help out the lookup by "refreshing" its contents
  95.         res.addLookupListener((LookupListener) drawer);//setup the listener to the drawer we found
  96.     }
  97. }

The code is well commented for this post so take a moment and read through it. It’s just some pieces of the actual class we’re using – so no actual computing stuff is shown here, let’s focus on the lookups. Note that I’m getting the TopComponent that I’ll add as an listener “by name”, it’s super simple but would you need to “find some implementation of some drawer interface” just use an lookup and get the instance, or even all the instances of such interface implementations. That said, this solution is not the most universal here (getting the instance) but it’s good enough for our app since it’s a very small application. No let’s look at the “Observer”, better named as “LookupListener”:

package pl.edu.netbeans.visualization;
  1.  
  2. import java.awt.BorderLayout;
  3. import java.util.ArrayList;
  4. import java.util.Collection;
  5. import java.util.Iterator;
  6. import java.util.List;
  7. import java.util.logging.Logger;
  8. import org.jfree.chart.ChartFactory;
  9. import org.jfree.chart.ChartPanel;
  10. import org.jfree.chart.JFreeChart;
  11. import org.jfree.chart.axis.ValueAxis;
  12. import org.jfree.chart.plot.PlotOrientation;
  13. import org.jfree.chart.plot.XYPlot;
  14. import org.jfree.data.xy.XYDataset;
  15. import org.jfree.data.xy.XYSeries;
  16. import org.jfree.data.xy.XYSeriesCollection;
  17. import org.openide.util.NbBundle;
  18. import org.openide.windows.TopComponent;
  19. import org.openide.windows.WindowManager;
  20. import org.netbeans.api.settings.ConvertAsProperties;
  21. import org.openide.util.Lookup;
  22. import org.openide.util.LookupEvent;
  23. import org.openide.util.LookupListener;
  24. import pl.edu.netbeans.toolbox.ChartDataDTO;
  25. import pl.edu.netbeans.toolbox.LineChartDrawer;
  26. import prefuse.Visualization;
  27.  
  28. /**
  29.  * Top component which will draw graphs for all the data it gets…
  30.  */
  31. @ConvertAsProperties(dtd = "-//pl.edu.netbeans.visualization//FitnessGraph//EN",
  32. autostore = false)
  33. public final class FitnessGraphTopComponent extends TopComponent implements LookupListener, LineChartDrawer {
  34.  
  35.     private static FitnessGraphTopComponent instance;
  36.     private static final String PREFERRED_ID = "FitnessGraphTopComponent";
  37.     //… skipped all the computing/drawing stuff
  38.  
  39.     public FitnessGraphTopComponent() {
  40.         initComponents();
  41.         setupChart();
  42.  
  43.         setName(NbBundle.getMessage(FitnessGraphTopComponent.class, "CTL_FitnessGraphTopComponent"));
  44.         setToolTipText(NbBundle.getMessage(FitnessGraphTopComponent.class, "HINT_FitnessGraphTopComponent")); //note how easy it will be to internationalize this app :-)
  45. //        setIcon(ImageUtilities.loadImage(ICON_PATH, true));
  46.         putClientProperty(TopComponent.PROP_CLOSING_DISABLED, Boolean.TRUE);
  47.         putClientProperty(TopComponent.PROP_MAXIMIZATION_DISABLED, Boolean.FALSE);
  48.         putClientProperty(TopComponent.PROP_SLIDING_DISABLED, Boolean.TRUE);
  49.     }
  50.     //…
  51.     //skipped graph drawing/setup parts, this post is about lookups only ;-)
  52.    //…
  53.  
  54.     @Override
  55.     protected String preferredID() {
  56.         return PREFERRED_ID;
  57.     }
  58.  
  59.     /**
  60.      * This is our resultChanged listener. It will be called if the resultSet we're observing is changed.
  61.      * Note that "changed" means all CRUD operations on it.
  62.      */
  63.     @Override
  64.     public void resultChanged(LookupEvent ev) {
  65.         Lookup.Result res = (Lookup.Result) ev.getSource(); //this is always an safe cast!
  66.         Collection instances = res.allInstances(); //we get all instances from the lookup
  67.  
  68.         if (!instances.isEmpty()) {
  69.             Iterator it = instances.iterator();
  70.             while (it.hasNext()) {
  71.                 Object o = it.next();
  72.                 if(o instanceof ChartDataDTO){//you might wan to use this – better safe than sorry, check if you got what you expected!
  73.                     ChartDataDTO o = (ChartDataDTO) it.next(); //If not sure if this will always be the case, use an if( instanceof ) here!
  74.                     addDTO2Series(o);
  75.                 }
  76.             }
  77.         }
  78.     }
  79.  
  80.     private void addDTO2Series(ChartDataDTO chartDataDTO) {
  81.         //…add the stuff to the graphs…
  82.     }
  83.     //…
  84. }

That’s about it. We simply have an resultChanged() method that will be called if the contents of the resultset are changed. We might also want to arr more lookups to be observed, so it’s better to check this instanceof I think than not, since there might be some unexpected stuff inside of it…

All in all, you write an Lookup.Provider and LookupListener, implement both’s methods and then at some place in your app hook them up. It doesn’t really matter “who looks for who” as long as it’s consistent and logical. In this case, the algorithm is looking for people interested in his data. Note that at any moment in time, we can add another listener, no problems here. Note that the Lookup.Provider and LookupListener are quite similar to the Observer and Observables mentioned before.And the good thing is, the algorithm does not know about any concrete drawer, and the drawer has no idea about some algorithm. They just have one shared API module – the toolbox, in which there is the DataTransferObject we’re using to pass the data from one to another – yay, an loosely coupled system. (yeah, I know our code is tightly coupled at some other places, but this part is quite ok :-))

If you have anything you’d like to comment on this code, feel free to do so. It’s just parts taken from http://github.com/ktoso/TravelingSalesman-NBP our implementation and visualization of the Traveling Salesman Problem being solved by Genetic Algorithms.

For more information about lookups goto: a nice post by Anton Epple on dzone.com or to Geertjan’s post with some good links or http://www.antonioshome.net/blog/2008/20081023-1.php


Update! Geertjan contacted me and suggested I’d post this on netbeans.dzone.com as it’s quite an interesting post – and so I did :-) You can read and comment it now on dzone.com. Hope to get some feedback if this is good or bad code, would be quite helpful :-)

Tags: , , , , , , ,