<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-18663041</id><updated>2011-10-22T14:08:17.982-07:00</updated><category term='WebApps'/><category term='GroovyMonkey'/><category term='OSGi'/><category term='software'/><category term='EclipseMonkey'/><category term='software engineering'/><category term='Eclipse'/><category term='Eclipse Monkey'/><category term='GroovyEclipse'/><category term='Grails'/><category term='Dynamic Languages'/><category term='JUnit'/><category term='Monkey'/><category term='Java'/><category term='Groovy Eclipse'/><category term='J2EE'/><category term='Google'/><category term='Groovy'/><category term='Web'/><title type='text'>Iacobus</title><subtitle type='html'>A blog on things Eclipse, Java, Groovy, Groovy Monkey and anything else I find interesting.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>31</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-18663041.post-6649987082520049999</id><published>2009-04-29T09:01:00.000-07:00</published><updated>2009-04-29T10:01:28.624-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><title type='text'>Eclipse PDE Target Platform Provisioning</title><content type='html'>Now finally something that I think P2 will do that will kick butt. Chris Aniszczyk, Eclipse PDE *co-lead, has announced on his &lt;a href="http://eclipsesource.com/blogs/2009/04/29/target-platform-provisioning/"&gt;blog &lt;/a&gt; that Eclipse 3.5 M7 will have a feature that can provision your Eclipse Platform Target for your Eclipse Plugin/RCP based work.  Why could this be cool?  Well one of the headaches in writing Eclipse plugins(bundles) is the need to establish the target platform. You can try a maven repository or the like, but as everyone knows, the best way to write an Eclipse plugin is to use the Eclipse PDE, or more succinctly, use Eclipse to build Eclipse.&lt;br /&gt;&lt;br /&gt;So up until now the only way to do this was to setup an alternate installation of Eclipse and point your target platform setting at it.  This works moderately well if you only need something like the Eclipse SDK or the Eclipse RCP packages.  The problem is often setting up your platform when you need other bundles (particularly when you need something like Eclipse WTP or BIRT for instance).  You need to go download all the bundles required for you to develop and build your Eclipse based product.  What you wind up doing (especially if you are me) is going to download all the SDK archives that are likely to contain all the bundles you require.  This leads to bloat, is a bit sloppy, makes management of that platform a pain, but it has the advantage of working quickly.&lt;br /&gt;&lt;br /&gt;Never heard of a Eclipse Platform target for Plugin development and you have written any number of Eclipse plugins? Well that is because by default the platform target is set to your current Eclipse installation.  Also I believe you probably have not had to support a plugin in the field for real. Why?  Because if you have never heard of a Target platform, you have never had to worry about the version of Eclipse your plugin is running in. Another factor is if you are like me and like to run the later milestone versions of Eclipse, while deploying your Plugin/RCP Application on the current released version of Eclipse.&lt;br /&gt;&lt;br /&gt;So enough background, this blog entry describes that as of Eclipse 3.5M7 it will use the Eclipse P2 Update mechanism to allow you to point at a URL for a platform that you are developing against. The new Eclipse PDE will take care of downloading all those plugins for you. That is cool beyond description, well unless you like creating target platforms and going through the extra mile to remove unneeded plugins.  In fact, this is the kind of coolness I felt when I first saw how Maven can download all your project dependencies for you (I know Maven does far more, but for me it is far and away the killer app).&lt;br /&gt;&lt;br /&gt;I know that an Eclipse RCP application I have worked on in the past had a target platform that was huge, where 80%+ was unneeded, but paring that down had to be balanced against the time required to remove unnecessary components and having it work correctly. This has the promise of doing 90%+ of that work for you. Taking the downloading out is one major step forward.  I am hoping that you can use it to pare down the collection of bundles in your target platform.  That would absolutely rock...&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Update: I think this will pare things down if paired (love the pun there) with a new feature in Eclipse JDT called &lt;a href="http://download.eclipse.org/eclipse/downloads/drops/S-3.5M5-200902021535/eclipse-news-M5.html#JDT"&gt;'Runnable Jar-in-Jar Exporter'&lt;/a&gt; Nice... Nice...  Just wondering who the heck named that feature?  Runnable Jar-in-Jar Exporter?  Oh well as my grandmother used to say, "If wishes were horses, beggars would ride..."&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Update: I have been corrected, Chris Aniszczyk is the Eclipse PDE co-lead along with Darin Wright.  Lord knows, since I work alot with Eclipse, I don't want either one of those dudes annoyed at me. ;)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18663041-6649987082520049999?l=iacobus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/6649987082520049999/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18663041&amp;postID=6649987082520049999' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/6649987082520049999'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/6649987082520049999'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/2009/04/eclipse-pde-target-platform.html' title='Eclipse PDE Target Platform Provisioning'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18663041.post-5704019161401235264</id><published>2008-12-02T07:56:00.000-08:00</published><updated>2008-12-02T09:15:20.023-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Groovy Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='GroovyEclipse'/><title type='text'>Groovy Eclipse Release</title><content type='html'>The time has come finally for a release of the Groovy Eclipse plugin.  The plugin has been published to the &lt;a href="http://dist.codehaus.org/groovy/distributions/update/"&gt;update site.&lt;/a&gt;  &lt;br /&gt;&lt;br /&gt;There are a few notes to make.  &lt;br /&gt;&lt;br /&gt;First off there is now refactoring support inside the plugin for your Groovy Code.  To see this demonstrated head over to this &lt;a href="http://groovy.codehaus.org/Eclipse+Plugin+Refactoring"&gt;wiki page.&lt;/a&gt;  Besides documentation there are some pretty cool flash demos of the features which should entice.  &lt;br /&gt;&lt;br /&gt;Second, the groovy plugin now supports the 1.5.7 version of Groovy.&lt;br /&gt;&lt;br /&gt;Third, this release does not contain support for the joint compilation of Java and Groovy code by the Groovy compiler.  This is a priority for the next release, and is a perfect segue to the next note.&lt;br /&gt;&lt;br /&gt;Fourth, please feel free to visit the wiki page &lt;a href="http://groovy.codehaus.org/Groovy+Eclipse+Roadmap"&gt;Groovy Eclipse Roadmap.&lt;/a&gt;  There the Groovy Eclipse team is collecting priorities and feedback for features to be added to future versions of Groovy Eclipse.  The plan is to release another version here before the end of the year or soon after the new year, depending on the issues that are resolved, feedback from the community of users and the release schedule of new versions of Groovy.&lt;br /&gt;&lt;br /&gt;Fifth, if you are having issues with the plugin, please contact either the Groovy Eclipse mailing list (you can subscribe &lt;a href="http://xircles.codehaus.org/lists/eclipse-plugin-dev@groovy.codehaus.org"&gt;here&lt;/a&gt;), follow Groovy Eclipse on &lt;a href="http://twitter.com/GroovyEclipse"&gt;Twitter.&lt;/a&gt; or browse/add JIRA issues &lt;a href="http://jira.codehaus.org/browse/GRECLIPSE"&gt;here.&lt;/a&gt;  Your feedback is much appreciated.&lt;br /&gt;&lt;br /&gt;Finally, as the Groovy Eclipse project lead, I would like to thank our contributors that made this release possible, in particular Thorsten Kamann, Michael Klenk, and Heiko Bottger.  Finally a shout out to Guillaume Laforge, for helping to keep Groovy Eclipse afloat and me on track.  Thanks everyone!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18663041-5704019161401235264?l=iacobus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/5704019161401235264/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18663041&amp;postID=5704019161401235264' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/5704019161401235264'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/5704019161401235264'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/2008/12/groovy-eclipse-release.html' title='Groovy Eclipse Release'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18663041.post-3215683254059032518</id><published>2008-11-23T20:20:00.001-08:00</published><updated>2008-11-23T20:21:02.500-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse Monkey'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='GroovyMonkey'/><title type='text'>Introduction to Groovy Monkey Presentation</title><content type='html'>&lt;div&gt;&lt;br /&gt;                  &lt;span class="slideshow-title" style="font-size:14px;"&gt;Introduction to Groovy Monkey&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;                  From: &lt;a href="http://www.slideshare.net/jervin" class="slideshow-author"&gt;jervin&lt;/a&gt;,&lt;br /&gt;                  &lt;span class="ago"&gt;2 minutes ago&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;                  &lt;div class="slideshow-embed"&gt;&lt;div style="width:425px;text-align:left" id="__ss_781806"&gt;&lt;a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/jervin/introduction-to-groovy-monkey-presentation?type=powerpoint" title="Introduction to Groovy Monkey"&gt;Introduction to Groovy Monkey&lt;/a&gt;&lt;object style="margin:0px" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=groovymonkey1-1227499965897903-9&amp;stripped_title=introduction-to-groovy-monkey-presentation" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=groovymonkey1-1227499965897903-9&amp;stripped_title=introduction-to-groovy-monkey-presentation" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;"&gt;View SlideShare &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/jervin/introduction-to-groovy-monkey-presentation?type=powerpoint" title="View Introduction to Groovy Monkey on SlideShare"&gt;presentation&lt;/a&gt; or &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/upload?type=powerpoint"&gt;Upload&lt;/a&gt; your own.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;                  &lt;div class="slideshow-description"&gt;Introduction to the Eclipse scripting tool Groovy Monkey.  Groovy Monkey allows for you to engage in API exploration, Task Automation, Plugin prototyping and collaboration in a lightweight and simple way.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;                  &lt;a href="http://www.slideshare.net/jervin/introduction-to-groovy-monkey-presentation" class="slideshow-link"&gt;SlideShare Link&lt;/a&gt;&lt;br /&gt;                &lt;/div&gt;&lt;br /&gt;              &lt;img style="visibility:hidden;width:0px;height:0px;" border=0 width=0 height=0 src="http://counters.gigya.com/wildfire/IMP/CXNID=2000002.0NXC/bHQ9MTIyNzUwMDM4MDczMCZwdD*xMjI3NTAwNDAwNDY3JnA9MTAxOTEmZD*mbj1ibG9nZ2VyJmc9MSZ*PSZvPWI5NjdhOWQwMTUyMTRhZDFiMTAyNGU*NTg2ZTUyNGJm.gif" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18663041-3215683254059032518?l=iacobus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/3215683254059032518/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18663041&amp;postID=3215683254059032518' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/3215683254059032518'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/3215683254059032518'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/2008/11/introduction-to-groovy-monkey.html' title='Introduction to Groovy Monkey Presentation'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18663041.post-314405889506842454</id><published>2008-07-16T16:10:00.001-07:00</published><updated>2008-07-16T16:28:42.925-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Groovy Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='GroovyEclipse'/><title type='text'>Roadmap for Groovy Eclipse work</title><content type='html'>Hello everyone.  I know Ed Povazan has not been active, so I will try and step in to fill the void.  There has been activity on the Groovy Eclipse development mailing list requesting a roadmap for the future of plugin work.  I know that I have been on a soapbox for a while now about how we need full time and paid work to support the plugin, but I think I should take a stab at what I think that the near future of the plugin should be.  I think that the current trunk (or what is out on the dev update site) is a viable candidate for a release.  I know I have been telling people over the last couple of months to use the &lt;a href="http://dist.codehaus.org/groovy/distributions/updateDev/"&gt;updateDev &lt;/a&gt;site and not the main release &lt;a href="http://dist.codehaus.org/groovy/distributions/update/"&gt;update site&lt;/a&gt;.  This is not an acceptable circumstance, the dev site is for internal or beta testing only, but the current release version of the plugin leaves me with no option.  I know that there may be some refactoring coolness out there and I do not want to discourage progress in any way, but the current version of the plugin on the release site is quite frankly an embarrassment. &lt;br /&gt;&lt;br /&gt;So given this state, I propose that we cut a release that includes Groovy 1.5.6 oand represents what is out there on the &lt;a href="http://dist.codehaus.org/groovy/distributions/updateDev/"&gt;update development site&lt;/a&gt;, so that we can in good conscience tell people to point at the release update site.  After the release of Groovy 1.5.7 so that we can accommodate the refactoring, we can include the new stuff and then release it to the development update site for evaluation.  This is based on what I understood from the earlier emails that the refactoring work requires Groovy 1.5.7.  After a time, a couple of weeks say, if it proves itself stable and ready, then lets push out a version to the main release site.  This is relatively standard practice and I see no reason to circumvent it.  &lt;br /&gt;&lt;br /&gt;This does bring up an interesting point, a couple of years ago it was possible to get new versions of the plugin out quickly because there was a reliable set of beta testers that could give us feedback quickly.  Scott Hickey's (the previous Groovy Eclipse lead) team working on a project would download the plugin and put it through its trials and we could find out trouble quickly.  It would be interesting to discover if there is anyone out there who could fill this function.  As an Eclipse developer, it is amazing how new eyes can find configuration, provisioning, installation and general plugin bugs when you thought everything was fine.  This sort of feedback and work is vital.&lt;br /&gt;&lt;br /&gt;If we can get regular activity restarted on the plugin (ahem... listening G2One?), I think that releases should occur at regular intervals of between 4 to 6 weeks, in line with common Agile iteration or spring intervals.&lt;br /&gt;&lt;br /&gt;If no one has an issue with this, I will go ahead and build a new release and promote it to the main release update site.&lt;br /&gt;&lt;br /&gt;As far as a roadmap goes, I had a brief chat with Scott Hickey (the old Groovy Eclipse plugin lead) and I think we came to a simple understanding. &lt;br /&gt;&lt;br /&gt;* First, there is some major work that needs to be done under the hood to not have the plugin use the version of the groovy runtime installed in the workbench, but rather use the one that is set for the workspace. &lt;br /&gt;&lt;br /&gt;* Second, there needs to be a structure like IJavaElement, or the equivalent, to allow the Groovy Eclipse plugin to support different versions of the Groovy libraries for different projects.  The second issue is related to the first issue to some degree. &lt;br /&gt;&lt;br /&gt;* Third, there needs to be better integration of the groovy compiler with Eclipse JDT support.  I saw an example in the Scala Eclipse plugin where the project has the Eclipse Java nature added to the project, but the Java Builder was not added.  This allows the Scala plugin to provide the scala tools to build the class files.  I think that something like this should be done for Groovy Eclipse, especially since the groovy compiler will now compile java as well.  This will also prevent collisions between the Java builder and the groovy builder. &lt;br /&gt;&lt;br /&gt;* Fourth, we need to be chasing the standard that the good folks at IntelliJ have been blazing.  The Groovy Eclipse plugin should try and provide most, if not all, the kind of support that IntelliJ is giving to Groovy now.  I think what it does for dynamic methods is awesome.&lt;br /&gt;&lt;br /&gt;* Fifth, refactoring tools need to be provided that are robust and first class.  Hey great job y'all on this one, this kind of work aint easy.  I am still intrigued by this notion, because I would love to see good dynamic language refactoring that is more than just grep and replace.&lt;br /&gt;&lt;br /&gt;* Sixth, provide at least a basic level of support for Grails development.  I know that there has been some work on providing Grails support, but I know it could only be of the very basic sort and there is so much in Grails that screams for IDE support.  I mean how cool could it be to get help with writing those GORM domain classes for instance?&lt;br /&gt;&lt;br /&gt;* Seventh, enable Eclipse Plugin Development using the Groovy language.  This is really more of a personal desire, I think that Grails support or any of the other points I have listed would affect far more people.  Still it would be nice to be able to do more and more Groovy Eclipse work in Groovy, right?  I think so.  As part of this effort we could try to leverage and improve Groovy support for EMF.  Heck maybe we could make EMF usable! (*duck*)&lt;br /&gt;&lt;br /&gt;* Eighth, as I stated above, if regular work can be restarted on the plugin, there should be regular releases on the order of 4 to 6 weeks apart.&lt;br /&gt;&lt;br /&gt;* Ninth, after getting the plugin in a better state, we need to get companies like Genuitech, eBay and other eclipse distribution providers to start including the plugin, if not included by default, at least as an option.  I will make a point to get it in to Genuitech's Pulse service.&lt;br /&gt;&lt;br /&gt;Most of the points I came up with really were off the cuff, so if you can think of others, please don't keep it to yourself!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18663041-314405889506842454?l=iacobus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/314405889506842454/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18663041&amp;postID=314405889506842454' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/314405889506842454'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/314405889506842454'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/2008/07/roadmap-for-groovy-eclipse-work.html' title='Roadmap for Groovy Eclipse work'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18663041.post-3112970265683410185</id><published>2008-06-27T13:17:00.001-07:00</published><updated>2008-06-28T14:30:14.610-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse Monkey'/><category scheme='http://www.blogger.com/atom/ns#' term='EclipseMonkey'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Google'/><title type='text'>Notes from Eclipse Day at Googleplex</title><content type='html'>Before I go into any details, I want to say that the Google t-shirt that I got for attending was almost worth the airfare, hotel stay and car rental.  Man am I a cheap date or what?  Also I would be remiss if I didn't thank Robert Konigsberg and the rest of the Google Open Source Office for organizing the event. &lt;br /&gt;&lt;br /&gt;It was great to meet &lt;a href="http://ianskerrett.wordpress.com/"&gt;Ian Skerrett&lt;/a&gt;, &lt;a href="http://eclipse-projects.blogspot.com/"&gt;Bjorn Freeman-Benson&lt;br /&gt;&lt;/a&gt;, and others that I have only had opportunity to communicate with over blogs or mailing lists.  It was also nice to catch up with Chris Aniszczyk and Wes Isberg there as well.  Of course while this is all nice and dandy, lets get to the actual event.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Eclipse @ eBay: Michael Galpin&lt;/span&gt;&lt;br /&gt;Mr. &lt;a href="http://fupeg.blogspot.com"&gt;Michael Galpin&lt;/a&gt; did what amounted to the "keynote" address of the event.  He went into a brief history of eBay and the technologies used to develop the site and then went into some of the work that has been done at eBay with Eclipse.  Before I continue, I should mention that I worked as a contractor for eBay for a little over a year and that I have a better perspective than most on what is going on there.  eBay is HUGE into Eclipse, in fact, I wonder if there are many organizations more committed to using Eclipse and working on creating developer tools using Eclipse.  Still I found the presentation on what eBay is doing with V4 in the presentation layer quite eye opening.  I was working on an Eclipse plugin to support their internal SOA framework, so I was a bit segregated from V4 work.  Now I kinda wish I wasn't so segregated, some of it is quite cool.  I mean I know I always wanted to leverage Dervlets, but Spyglass is pretty cool.  There is a nice PDF of the presentation notes available at this &lt;a href="http://wiki.eclipse.org/images/a/a2/EclipseAteBay.pdf"&gt;link&lt;/a&gt;.  One thing to note is how Java centric eBay really is, just about everything is a Java class.  I wish I had asked during my time there why the decision was made to do that, particularly the tradeoffs.  One other thing, I wish my plugin work and the SOA framework had garnered a bullet in that presentation somewhere, oh well.  I mean Wes Isberg's simple, but cool, Auto-configuration plugin got a mention.  Not that I am jealous or anything. ;)&lt;br /&gt;&lt;br /&gt;One final note, Mr. Galpin literally said that there are plans to open source all the tools shown during that presentation.  People should hold them to that promise.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;How Mylyn Changes the Way I Develop: Bjorn Freeman-Benson&lt;/span&gt;&lt;br /&gt;After the eBay session, the event bifurcated into two parallel tracks.  The net effect was that you needed to choose which event to attend.  While I have an abstract interest in CDT at the current moment, I was more intrigued by the session on Mylyn.  I mean I have tried to use it and I see the arguments for something like that.  What I haven't done is well, get it.  I have tried it and never managed to successfully integrate it into my workflows.  I have gotten to know and respect Mr. Freeman-Benson while interacting with him over at the Eclipse Dash project, so I was hopeful he might allow me to 'get it' or at least motivate me to try again.&lt;br /&gt;&lt;br /&gt;Before I get into the notes I have from the presentation I need to pass off some advice.  This goes to Bjorn or anyone else giving a presentation, don't ever give a presentation that someone else prepared, period.  I know it was probably due to the fact that Bjorn was stepping in for someone else, but yikes.&lt;br /&gt;&lt;br /&gt;In the beginning Bjorn covered the motivation for Mylyn, things that I think everyone will admit that modern software engineers have to deal with even with a nice IDE like Eclipse.  The problems are the need to context switch, to mulitask and to manage information overload.  He did not go into the traditional ways that developers in Eclipse try to manage this, but it bears mentioning.  Eclipse users usually use multiple workspaces, multiple workbench instances and try to make use of things like project/team sets.  None of the traditional ways are satisfactory.  So what is Mylyn's approach?  First off, I love this, Mylyn allows you to keep all your stuff in just one workspace.  Mylyn's focus is on cutting down the full workspace to only those elements that you need at a given time.&lt;br /&gt;&lt;br /&gt;So how does Mylyn accomplish some of this?  Well in Mylyn the notion of a task is made a first class citizen.  Before you do anything in Eclipse using Mylyn, you need to do it in the context of a task.  Mylyn has stuff to manage tasks and to integrate with common issue tracking packages like Bugzilla and JIRA, among others.  Mylyn also allows you to be able to acquire your tasks from multiple sources.  So once you have a task, Mylyn stores contextual information about what elements in the workspace you associate with a given task.  This is where some of the black magic kicks in, Mylyn has a Degree of Interest Model that it maintains in order to know what to filter out of your views.  This has always been the rub for me to start with Mylyn, everything is hidden at first and you must start from a task.&lt;br /&gt;&lt;br /&gt;The cool thing though is that once a context is created, it is possible to share that easily with other team members.  Now the cool thing for me is that the context is not shared via a team provider, but that Mylyn will create an attachment in the issue tracker that another team member can use automatically in their Eclipse workbench using Mylyn.  I love that since it is logically associated with the task and that they did not punt the trouble to the team provider. &lt;br /&gt;&lt;br /&gt;Another cool item, in fact, a killer app type item for those who like Agile software development methodologies, is the automatic time tracker.  When you are using Eclipse with Mylyn, you are always with in the context of a task, so when you are doing stuff in the IDE then, Mylyn will keep a timer.  This is a killer app, since anyone who does agile knows that the most difficult thing to do is to estimate the time to implement a given feature.  In fact, it is so difficult that XP for instance tells you to use 'yesterday's weather', in other words, look at the last time you had to implement a given feature, and use that time.  Well that only works if you accurately track your time on task.  Mylyn could make this seamless and easy.  This feature alone makes me want to use Mylyn, even if I leave the filtering off all the time.&lt;br /&gt;&lt;br /&gt;I want to make one more comment about the presentation on Mylyn concerning workspace provisioning.  Bjorn went into alot of Q&amp;A with the audience and did cover more details of Mylyn.  Still, what struck me about the presentation was how close Mylyn is to a full workspace provisioning solution.  I need to look at Eclipse Buckminster and check out Genuitech's Pulse product again.  Workspace provisioning for me is almost as big a deal as P2 and the Eclipse provisioning effort.  I mean how long does it take for new people to be able to install Eclipse and get all they need to be able to check out the code from SCM and start working with it?  I mean really, how long, do you even know?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Building Great RIA with ATF: Philippe Ombredanne&lt;/span&gt;&lt;br /&gt;First off, I want to say I got the chance to meet Philippe at this event and I really like him.  Second, is there any Eclipse project that he hasn't been intimately involved with?  I think the list of projects at Eclipse he has been involved with would rival some of my earliest Christmas wish lists to Santa, I mean wow!  Most of the presentation (at least the part that I was able to grok) covered the ATF project's live Javascript debugger.  I am not an AJAX developer, so I admit much of what he showed was a bit lost on me, but even I admit the fact that you could monitor requests easily.  He demonstrated how a click in the ATF embedded browser to Google Maps would show up as request response pairs in a nice viewer inside Eclipse.  Makes me want to try and do some Web mashups (me even!).  The other thing that struck me was the fact that they took the Mozilla Firefox XUL Runner build and embedded it as a bundle inside of Eclipse.  I thought that was cool, since it provides an embedded browser to play with that is not the Eclipse default browser and I wonder what kind of API I could potentially play with.  You know I am thinking a Groovy/Eclipse Monkey script to try it out.  Awww yeah!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Wiring Hacker Synapses: Collaborative Coding and Team Tooling in Eclipse: Scott Lewis &amp; Mustafa K. Isik&lt;/span&gt;&lt;br /&gt;First off I want to say that I love what this demo and plugin could entail.  Being able to do shared sessions on the same document is the first step towards better collaboration and hopefully better software development in general.  If you haven't seen the video, go Google for Cola and ECF and check it out.  The simple demo that Mustafa did there was in the most part better than attending this presentation.  I wish he had done some more demo instead of theory.  Still this is a good first step.  The problem comes later.  With shared sessions, how do you integrate properly with Team providers and make sure that the workspaces are provisioned correctly?  I think that they should focus on allowing a remote Eclipse user to "shadow" the workspace of a local Eclipse user.  This way you have a "master" workspace that the local user is responsible for provisioning and the responsibility is removed from the remote user.  Still ECF is very cool, I wish them the best of luck.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Concluding Remarks&lt;/span&gt;&lt;br /&gt;At the end of the sessions, there was free food and adult beverages for all.  I ran one of the two demo stations there.  In hindsight, I think that expecting people to really have any more brainpower to devote to Eclipse after five continuous hours of sessions was a bit much.  Still I really want to thank those that came over and gave me the chance to show off Groovy Monkey and discuss my plans for Eclipse Monkey.&lt;br /&gt;&lt;br /&gt;Once again thanks to Google and to the folks at the Eclipse foundation for showing up.  Thanks to all the participants who attended.  The event was, for the most part, packed, not the smaller affairs that Eclipse Democamps that I have attended in the past have been.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18663041-3112970265683410185?l=iacobus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/3112970265683410185/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18663041&amp;postID=3112970265683410185' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/3112970265683410185'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/3112970265683410185'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/2008/06/notes-from-eclipse-day-at-googleplex.html' title='Notes from Eclipse Day at Googleplex'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18663041.post-564497674089003418</id><published>2008-06-23T15:08:00.000-07:00</published><updated>2008-06-27T15:28:23.521-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Dynamic Languages'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><title type='text'>Don't call it a static or dynamic language!</title><content type='html'>I was talking the other day with someone recruiting me for a position.  Smart organizations will contact you with someone who can try and sift the wheat from the chaff.  In other words, they'll ask you questions in particular computer science or even, *gasp*, Java questions.  Well this one guy asked me a standard question, 'what are the advantages and disadvantages of statically typed versus dynamically typed languages?'  Now the full debate on that question could not only fill a whole series of blog entries, but could be a book by itself, which I will not get into here.  Still as I was giving my answer I prefaced my comments by saying something that I have put a fair bit of thought into, which was: 'I don't like the name static or dynamic typing, I prefer the notion of implicitly typed and explicitly typed languages.' &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Definitions&lt;/span&gt;&lt;br /&gt;First off let me start with the definitions of explicit and implicit, both of these are horked from Merriam Webster Online.  Implicit is defined as "capable of being understood from something else though unexpressed : implied &lt;an implicit="" assumption=""&gt; or involved in the nature or essence of something though not revealed, expressed, or developed."  Explicit would be defined as "fully revealed or expressed without vagueness, implication, or ambiguity : leaving no question as to meaning or intent" or as "fully developed or formulated &lt;an explicit="" plan=""&gt; &lt;an explicit="" notion="" of="" our="" objective=""&gt;."  I think a good way to think about this is to consider the following question, "are details hidden from you or not?"&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;WTF (What The Friendly) does this have to do with Programming Languages?&lt;/span&gt;&lt;br /&gt;I think if you consider it for a while, the language debate between statically and dynamically typed is clearer when it is considered in terms of whether it emphasizes implicitness or explicitness.  First off, all languages and programming platforms are implicit to some degree, since there is no way to encapsulate all of the factors that go into programming a software system to a developer.  If they did, the resulting interface to the developer would probably be enough to make an airline pilot's jaw drop.  Still the point applies if you focus on types.  Most of the debate about programming languages focuses on the issues of types, so it is a good area to concern ourselves with.  By my reckoning, a strongly/statically typed language, like Java for instance, would be considered 'explicitly typed' in this nomenclature.  A dynamically/weakly typed language, like Python or Ruby for instance, would be called an 'implicitly typed' language from now on.  An optionally typed language like Groovy would be optionally explicit or optionally implicit, depending on the developers mood that day. ;) &lt;br /&gt;&lt;br /&gt;Actually in my opinion, most of the interest in Groovy is due to its 'implicit' capabilities and therefore I would really put in that category.  I know you can explicitly type things in Groovy, but that is really an enabling feature.  Enabling feature, you say?  Yeah, an enabling feature, kinda like (Note: I have no personal experience with the following analogy, really...) how a drug dealer might give out free samples to hook you in and then afterwords start charging.  So being able to specify types in Groovy gives Java developers, like myself, a warm fuzzy about trying out the new features and, therefore, try out the Groovy language.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Ok this is awfully pedantic, so what?&lt;/span&gt;&lt;br /&gt;So the question that might be formulating in your mind is, "ok so you have a new definition, how does this help anything?"  Well for one thing, no matter what you do with software code, the types are there, period.  The difference is if they are hidden or not.  In the next few sections I am going to compare equivalent sections of code in Java and in Groovy, but I think that the point holds if we were in Ruby, Smalltalk or Python, even though the examples would vary.&lt;br /&gt;&lt;br /&gt;I want to show a quick example from groovy and Java, in this I am going to create an instance of ArrayList:&lt;br /&gt;&lt;br /&gt;Java(5.0+):&lt;br /&gt;List&lt;&gt; list = new ArrayList&lt;&gt;();&lt;br /&gt;&lt;br /&gt;Groovy:&lt;br /&gt;def list = []&lt;br /&gt;&lt;br /&gt;So let me ask you a question?  What is the difference in this case?  Well for one the amount of actual keystrokes to write the examples.  Beyond that, there is not much difference, in both cases you have a variable declaration of list that is initialized with a java.util.ArrayList instance.  So what is the advantage of the Java version?  Well Java's explicitness is key here, you know straight away that list is of type java.util.List and that it is an instance of java.util.ArrayList.   Therefore, someone new to the Java platform would probably have an easier time figuring out what is going on in the Java line(at least not including generics, which is another post entirely) than with the Groovy line.  To understand the groovy line you need to know that the array notation is shorthand for instantiating a List object and that by default an ArrayList is used, therefore I would term Groovy an "implicit" language in this case. &lt;br /&gt;&lt;br /&gt;One other not so small point, if I was looking at this from a tool developer's viewpoint, I prefer the Java version to the Groovy version, in probably just about every case.  In general, it is easier to write tools to analyze and provide support to base Java (or other explicitly typed language) than it is to any implicitly (read: dynamic) typed language.&lt;br /&gt;&lt;br /&gt;Another example, I am going to do the simple "HelloWorld" application in both Groovy and Java:&lt;br /&gt;&lt;br /&gt;Java: HelloWorld.java&lt;br /&gt;public class HelloWorld&lt;br /&gt;{&lt;br /&gt;     public static void main( String[] args )&lt;br /&gt;        {&lt;br /&gt;        System.out.println( "Hello World!" );&lt;br /&gt;        }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Groovy: HelloWorld.groovy&lt;br /&gt;println "Hello World!"&lt;br /&gt;&lt;br /&gt;This is the example that should drive the point home.  What is the difference?  In the end the bytecode will be functionally the same in both the Groovy and Java cases (Notice I don't say that the bytecode would be exactly the same).  The big difference is that the Java version is explicit, not only about types, but also in requiring a class definition and explicit main method.  In Groovy, the type is inferred implicitly from the file name and the main method is also implied.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What about the tools man?&lt;/span&gt;&lt;br /&gt;The final example I want to consider is the Domain Specific Language (DSL) in the two kinds of languages.  Actually, I lied, I am only going to show an example of a builder in Groovy and skip showing the example in Java, because the example for Java would be far too painful to consider.  I want to consider the following example because I want to get to the point about what 'explicit' versus 'implicit' means for tool developers.&lt;br /&gt;&lt;br /&gt;Example: AntBuilder (Groovy)&lt;br /&gt;// Going to zip up a file&lt;br /&gt;def ant = new AntBuilder()&lt;br /&gt;ant.zip( destfile:"${zip.location}", basedir:"${project.location}" )&lt;br /&gt;&lt;br /&gt;What all is going on here?  You have an instance of AntBuilder being created and a method called zip being invoked.  There is an example of named parameters, which is a very cool feature for Groovy I think.  Finally, you see there two GStrings (Groovy Strings, quite the name no?) with its built in templating.  There is a lot going on here, someone wanting to write a tool would probably take a deep breath, but envision that he/she will be able to do it.  The trick is what about the zip method.  What about the zip method?  Lets get to that next.&lt;br /&gt;&lt;br /&gt;In the previous examples, the types and their signatures are just below the surface so to speak.  The notation '[]' is a shorthand for java.util.List and in the case where the statements are just put into the Groovy file without a class definition, means there is an implicit class definition and static main method.  In the above example, there is no such nicety.  Why would I say that?  I mean the variable ant is an instance of AntBuilder right?  Yes, but look at the javadoc for AntBuilder, where is the method definition for zip?  There is not one, but if you want to see for yourself go ahead and &lt;a href="http://groovy.codehaus.org/api/groovy/util/AntBuilder.html"&gt;look&lt;/a&gt;, I'll wait.&lt;br /&gt;&lt;br /&gt;The AntBuilder class is an example of a Builder in Groovy which does something like what java.lang.reflect.Proxy does.  Proxy provides an InvocationHandler, which has a method called invoke() which the Java platform provides as a hook to allow you to provide runtime implementations of arbitrary types.  The Groovy Builder support allows for creation of nodes and invocation of methods on those nodes.  All of this means that not only is the full type definition for AntBuilder implicit, but that there is really no way at compile time to figure it out.  What I mean is that there is no way for a source code tool developer to write general tools to provide the kind of language support that is available in explicitly typed languages for DSLs.  In the first two examples, you could easily imagine being able to provide tooling support for those cases, the types and signatures were implicit, but they could be figured out relatively simply, there is no real way to do it in the last case. &lt;br /&gt;&lt;br /&gt;Tooling support is an area that is usually skipped in alot of discussions on explicitly typed versus implicitly typed languages.  It is dismissed by implicit proponents with, "well tooling will just catch up."  I don't consider it trivial and, having dabbled a bit in providing IDE support for Groovy, I don't assume that the tooling will just be there in the future.  Implicitly typed language designers and proponents need to give this its full consideration, elsewise the best your language could hope for is to be the next Lisp, praised by some and used by none.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;So the difference between the two languages in the above examples is best exemplified by asking three questions.  First, which version do you think someone new to your codebase or the Java platform would understand better?  Usually an explicitly typed language like Java (or maybe Scala/Haskell) would be favored.   Second, which version do you think someone with experience with your codebase or the Java platform would prefer to write?  Usually, I would think that an implicit language like Groovy, Ruby or even Python would be preferred.   Third, what kind of tool, particularly IDE support do you want or need?  If your project thinks that the first question is more important than the second one, then an explicit language like Java should be your choice.  If the second question seems more important, then an implicit language like Groovy should be your choice.  The third question can only be answered by surveying what is available and trying it out to see if it is good enough.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/an&gt;&lt;/an&gt;&lt;/an&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18663041-564497674089003418?l=iacobus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/564497674089003418/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18663041&amp;postID=564497674089003418' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/564497674089003418'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/564497674089003418'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/2008/06/dont-call-it-static-or-dynamic-language.html' title='Don&apos;t call it a static or dynamic language!'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18663041.post-5807497834644195720</id><published>2008-06-19T12:18:00.000-07:00</published><updated>2008-06-19T14:09:32.534-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='Grails'/><title type='text'>JRuby on Rails good or bad for Java?</title><content type='html'>I am going to apologize for the incendiary title.  I think the work the JRuby team has been doing at Sun, particularly with enhancing the JVM for dynamic languages, is great and a service to the entire Java community.  The real point of this post is a question to Sun and the rest of the Java community.  What is the question?  Simple.  Y'all why all the emphasis on JRuby and JRuby on Rails and not an equivalent amount of love (read: &lt;span style="font-weight:bold;"&gt;attention/resources&lt;/span&gt;) to the Groovy/Grails platform?  I am combining consideration of both Ruby and Groovy with their equivalent Web frameworks RoR and Grails since they really are the killer apps (read: primary motivation for developers to try them) for both languages at this time.&lt;br /&gt;&lt;br /&gt;So why all the attention at Sun to JRuby?  Well I think there is probably a mentality at Sun to think they need to win more people over to the Java platform.  That thinking leads them to wanting to support Ruby and Ruby on Rails on the Java platform.  This is not the end of the world or necessarily bad thinking.  Why?  Well you would think the more developers on the Java platform the "mo' better" right?  I admit that being a Groovy/Grails proponent, the attention leaves me a bit jealous, but as I said earlier, they have been doing good work and, you know, envy gets you nowhere.  Still it begs the question, what about the people who are already on the Java platform doing their work?  What is being done to improve their experience and to keep them happy working with the Java platform? &lt;br /&gt;&lt;br /&gt;Note: I keep referring to the Java platform since Java really encompasses three components, the JVM runtime, the platform libraries and the Java language.  I think of the platform as the libraries and the JVM, in other words, the full Java runtime minus the development time Java language support.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Give Groovy Some More Love Everyone!&lt;/span&gt;&lt;br /&gt;Groovy/Grails is native to the Java ecosystem and should be (read: &lt;span style="font-weight:bold;"&gt;is&lt;/span&gt;) easier to support on the Java platform.  Groovy/Grails has a far flatter (read: &lt;span style="font-weight:bold;"&gt;easier&lt;/span&gt;) learning curve for existing Java developers.  How do I know that it is an easier learning curve?  Simple, Groovy is the single reason I have not really tried to do development work in Ruby or another dynamic language.  Every time I started to drift off the reservation, for one reason or another, I found that Groovy had it already.  So why give up the JVM or platform libraries of which I am very familiar?  Grails, the Groovy Web Framework, is still a relatively young technology, but is already showing signs of being one of the, if not the, best Java web frameworks out there.  It is amazing how Grails is picking up speed right now.  &lt;span style="font-weight:bold;"&gt;&amp;lt;sarcasm&amp;gt;&lt;/span&gt;Its like people want a better way to do Java Web applications and, get this, don't seem to be willing to dump all their previous experience with Java or their previous Java work in the trash.  Isn't that just crazy??&lt;span style="font-weight:bold;"&gt;&amp;lt;/sarcasm&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So therefore, I think Groovy/Grails is something that should be better supported, particularly with tooling.  A better Groovy/Grails would help keep developers on the Java platform, how?  Well remember there does not exist a Groovy/Grails platform outside the JVM and Java platform libraries.  &lt;br /&gt;&lt;br /&gt;Besides the fact that Groovy/Grails support should be far easier to achieve than Ruby/RoR support, there is the converse argument about JRuby and JRuby on Rails (JRoR?) bringing people to the Java platform.  JRuby on Rails could also be viewed as a conduit for allowing development to leave the Java platform as well.  Why?  Well all new work could feasibly be run on native Ruby platforms if run on JRuby and, in fact, would probably run better on native Ruby platforms than inside the JVM.  So unless you have lots of legacy with J2EE, there would be no hook to staying with the JVM or Java platform.  Now I hate vendor lock-in, but Java has no &lt;span style="font-weight:bold;"&gt;vendor&lt;/span&gt; to speak of.  I am all for allowing existing Ruby/RoR developers to try the Java world, but the question is where should your emphasis lie?  I don't think that the Ruby world is anywhere near the size of the Java world, even on the Web.&lt;br /&gt;&lt;br /&gt;So, in conclusion, the question is, is it more important to convert others to the Java platform or is it more important to keep and take care of the large Java developer base on the Java platform?  My answer is &lt;span style="font-weight:bold;"&gt;yes&lt;/span&gt;.  What do I mean?  Well you can't just grow a community, you must also take care of what is already there, both aspects are important to a thriving community.&lt;br /&gt;&lt;br /&gt;So please Sun, get past the NIH (Not Invented Here) syndrome and go hire a Groovy guy next to Mr. Nutter (no complaints for Mr. Nutter, he has been doing good stuff on the JVM for all dynamic languages).  While you are at it, I am going to suggest (even though I am an Eclipse guy) putting better support in Netbeans for Groovy.  I am getting a little tired of hearing how IntelliJ is by far the best environment for writing Groovy.  I would also suggest improving the Eclipse plugin, but I don't think y'all will go for that(would you?).  Any help to Groovy would be in your interests, you wont regret it.  &lt;br /&gt;&lt;br /&gt;For the rest of the Java community (especially the Groovy/Grails subset), I think I am going to start sounding like Public Broadcasting in the United States during sweeps.  If you don't know what I talking about, they are officially called "Pledge Drives", unofficially they are called "Beg For Money Drives."  So here goes in my PBS pledge drive voice**:&lt;br /&gt;&lt;br /&gt;"Please pledge your support to Groovy Eclipse today.  At the 1+ full-time developer level we'll get you an Eclipse mug and sticker.  Show your Eclipse pride everywhere you drive or compute, your choice.  At the 2+ full-time position level, in addition to the mug and sticker, we'll get a Groovy Eclipse shirt made up for you from somewhere.  You know you have been enjoying Groovy/Grails for some time now and been looking for your opportunity to contribute, here is your opportunity.  You wont regret it, I promise*."&lt;br /&gt;&lt;br /&gt;Seriously, the Java developer world today is on Eclipse (not IntelliJ or Netbeans or whatever), so for Groovy/Grails to grow and be taken seriously by the vast majority of Java developers, Groovy Eclipse has to be first class.  Like I overheard once while talking about this subject to a group of people, "People will change languages faster than they will change their IDE(s), so for me to introduce Groovy to my Java developers, I need it on Eclipse."&lt;br /&gt;&lt;br /&gt;* If you do regret it anyway, just remember two things.  First, I thank you for your support.  Two, you may rant and rave at me, but limit it to emails, no 2am crank calls, please. :)&lt;br /&gt;&lt;br /&gt;** I think I watched way way too much PBS as a child or something, but where else could I watch Dr. Who before the Sci-Fi network existed??&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18663041-5807497834644195720?l=iacobus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/5807497834644195720/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18663041&amp;postID=5807497834644195720' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/5807497834644195720'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/5807497834644195720'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/2008/06/jruby-on-rails-good-or-bad-for-java.html' title='JRuby on Rails good or bad for Java?'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18663041.post-5051705391009130623</id><published>2008-06-16T18:46:00.000-07:00</published><updated>2008-06-17T13:50:06.483-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OSGi'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><title type='text'>Versioning: My Happy Place</title><content type='html'>There has been alot of discussion about the JSR-277 and OSGi versioning standards.  I wont revisit the arguments here since people far &lt;a href="http://alblue.blogspot.com/2008/05/version-numbers-and-jsr277.html"&gt;more&lt;/a&gt; &lt;a href="http://www.osgi.org/blog/2008/05/is-9903520300447984150353281023-too.html"&gt;intelligent&lt;/a&gt; &lt;a href="http://ianskerrett.wordpress.com/2008/06/05/the-politics-of-osgi-and-jsr-277/"&gt;than&lt;/a&gt; me have lots to say on that matter.  If you want to dive in, go ahead and Google it, and I will talk to you later since you will have forgotten to go back to this blog entry once you are done.  For the rest of you, I have to beg your indulgence, I am going to assume that I actually have the qualifications to pontificate on this matter.  So here goes.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Defining Versioning&lt;/span&gt;&lt;br /&gt;Why do you want to version something?  There are alot of reasons for it, particularly when it comes to Source Control Management (SCM) or Version Control.  You need to know the version of a particular class that you are working on in that case.  Using version control when you are working on software is an idea that goes without saying.  There are no debates on versioning or the formats of those versions, you get the one that comes with the SCM you are using, period end of story.  No, the issue comes up when you are considering versioning a component, which for OSGi/Eclipse is a bundle and for JSR 277 is called a module.  So what does a version stand for in this case?  &lt;br /&gt;&lt;br /&gt;I like the &lt;a href="http://en.wikipedia.org/wiki/Software_versioning"&gt;wikipedia definition&lt;/a&gt; of a version in this case.  It is pretty generic, but it goes something like this, "Software versioning is the process of assigning either unique version names or unique version numbers to unique states of computer software."  The definition tries to cover all cases, so the point to focus in on is the unique identifier of the unique state of the software.  So what kind of state are we trying uniquely identify?  Well changes to the software you as a developer have made of course, but I think that they fall into two categories at least at the component level.  One category are those changes that affect dependency management because the external API on which clients rely has been altered.  The second category, I will term bookkeeping for this blog entry.  I term it bookkeeping, because it denotes internal changes that should, notice I say should, not affect clients using the external API.  "Bookkeeping" comes into play because Software developers are human, and even though a change should not impact clients adversely, they still do.  "Bookkeeping" lets a system integrator/admin note that a version of the component X worked, but X+1 sure did not, which is exactly the information someone providing support wants to hear.  It is really difficult to say one category matters more than the other.  Changes in the first category will prevent a system from coming up correctly, whereas changes in the second category could help explain why the system later goes haywire.&lt;br /&gt;&lt;br /&gt;I like to view a version as a shortcut, so that a client does not have to check the full external API at runtime to know if there are changes that it should concern itself with.  In fact, ideally the "external API" version should be some sort of "hash", if you will, of the external API that could be automatically maintained.  More on the ideal answer later.  The "bookkeeping" component is in effect like a branch in version control, it lets the developer go back and retrieve the previous version when problems come in from the users.&lt;br /&gt;&lt;br /&gt;I could go on about how many coordinates are needed for this or that or what have you, but there are many many people far more qualified to comment on this and, you know what?  They have commented, so if you are interested, go Google for them and check them out.  What I am going to do is describe what in my ideal world versioning would do for me.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Versioning: James Ervin's Happy Place&lt;/span&gt;&lt;br /&gt;I am not a big Adam Sandler fan, but I am a guy, so I will say that in the movie "Happy Gillmore", I was moved by Happy's idea of his "Happy Place."  So what I am going to describe is my "Happy Place" for Software Versioning, though I will say that the "Happy Place" described in the movie is far superior to the one I will go into.&lt;br /&gt;&lt;br /&gt;First off, any versioning scheme on the component level has to take into account that all software changes fall into one of the two orthogonal categories that I defined above, they are either external API or, for lack of a better word, internal "bookkeeping" changes.  Any tooling support should be able to distinguish.&lt;br /&gt;&lt;br /&gt;Secondly, I would like the notion of backward compatibility to go away.  You change the external API, you create incompatibilities period.  Incompatibilities between versions are a two way street.  I mean if you make so called "backward compatible changes", then you shouldn't break existing clients, well that's great right?  The problem with this view is that it assumes that your new stuff will be automagically available everywhere, which really does not take a full lifecycle view of your component into account.  What you do is allow for a set of clients to be written that will be unable to use your pre-existing components.  I don't have a great answer for this, but I would like people to take a greater view into account, all external API changes could force incompatibilities, not just ones that break backward compatibility.  Once external API is defined, you need to treat it like set cement.  How to potentially better deal with set cement?  I try and deal with it in the next point.&lt;br /&gt;&lt;br /&gt;Thirdly, I would like better API tooling support.  This comes from point two, I want better tooling to help with what is in effect an intractable problem.  First I would like to mention I know about the new Eclipse API tooling push and I want to investigate it thoroughly later on.  I think it is worth mentioning that I view tooling support here in two categories again, what I would call "static support" and "client feedback support".  &lt;br /&gt;&lt;br /&gt;Static Support analysis in my view is what the Eclipse API tooling effort is focused on.  Give me warnings if I add things to the external API to change the "external API" component of the version and then provide an automatic way to update it.  Give me an error/warning to update the "external API" component of the version if I change an existing method or other backward compatible breaking change.  Tell me to update the "bookkeeping" component of the version when I make any significant changes to the component that does not impact the external API.  In other words, give me some help to make it more automatic.  I, as a human being, have and will continue to forget to update versions without warning/errors markers to guide my way.  &lt;br /&gt;&lt;br /&gt;Before I go into the second category, I want to emphasize again that this is my happy place, my ideal world.  "Client Feedback" tools to me are a potential answer to the problem of external API being set concrete after released in the wild.  The trouble is that most of the time a whole API is not in use, usually only a subset, but what subset?  That information would be invaluable.  It would allow a component developer to know what parts of the API could be eliminated or given better documentation so that more clients would use it.  "Client Feedback" would provide the targets for refactoring and could prevent the kind of cruft that eventually dooms any software product.  How do you best get this feedback?  Some sort of tooling support of course and beyond that I dunno.  Did I mention this was my "Happy Place"?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;So what do I want in a versioning scheme or tooling support?  Prevent me from making simple obvious mistakes that I have done again and again.  I want support to make me take into account that when a component is released, people write clients to use it and I have to keep them in mind for any changes, period.  I think what I really want is the &lt;a href="http://www.staples.com/sbd/cre/marketing/easybutton/index.html"&gt;Staples Easy Button&lt;/a&gt;, which if you know me, is a metaphor for an impossible to build tool.  Still there is alot that can be done before we need an 'Easy Button' to make this problem less problematic.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18663041-5051705391009130623?l=iacobus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/5051705391009130623/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18663041&amp;postID=5051705391009130623' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/5051705391009130623'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/5051705391009130623'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/2008/06/versioning-my-happy-place.html' title='Versioning: My Happy Place'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18663041.post-7451295081976113738</id><published>2008-06-16T15:04:00.000-07:00</published><updated>2008-06-16T15:20:49.801-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Groovy Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse Monkey'/><category scheme='http://www.blogger.com/atom/ns#' term='EclipseMonkey'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='GroovyMonkey'/><category scheme='http://www.blogger.com/atom/ns#' term='GroovyEclipse'/><title type='text'>Notes from Eclipse Democamp in Dallas, Texas</title><content type='html'>I am late writing this blog since the democamp actually occurred last monday and it is now a week later.  I know my memory is a bit faulty, but I wanted to jot a few notes on things that stood out to me.&lt;br /&gt;&lt;br /&gt;* &lt;a href="http://www.poweredbypulse.com/"&gt;Pulse&lt;/a&gt; is a cool tool that I really need to take the chance to learn and leverage.  I think its ability to generate profiles is a killer app for a Eclipse developer like myself, since I need to switch between versions of Eclipse often.  The stuff about being able to provision a workspace should be of great use on my next project.  I mean talking to Mr.Williams about the feature convinces me that it is what you want Eclipse Teamsets and exported settings to be.&lt;br /&gt;&lt;br /&gt;* You know you should really hold a democamp in a place that has an internet connection.  I mean BJ's Brewhouse is a fine enough choice, but no wireless?  I wonder how long it will be that any restaurant that has a meeting room will put in wireless internet, it is really starting to become necessary.  Todd Williams from Genuitec had a devil of a time demoing what appears to be a really cool product, Pulse.  The trouble is that Pulse is based on the Eclipse P2 provisioning platform, which is meant to attend to the Update Manager's legion of flaws.  So without an internet connection, there aint alot to demo is there?  I think Chris Aniszczyk must have thought of this since the Austin Democamp will be held at Nokia's offices near Stubb's BBQ.  Btw, nice choice Chris, Stubb's is an Austin landmark.  I would have chosen to do Chuy's or the Hula Hut somehow, but hey, Stubb's is pretty damn cool too.&lt;br /&gt;&lt;br /&gt;* I need to come up with a set of cool example scripts so that people get why a monkey scripting tool is so cool.  This is a problem of my own making, I see the advantage, particularly coming from the Eclipse plugin development side of the fence, but there aren't that many Eclipse plugin developers.  Any help in this arena would be most appreciated.  I don't want to see the blank stares again when I goto Eclipse Day at the Googleplex or do the Austin Democamp later on this month.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18663041-7451295081976113738?l=iacobus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.poweredbypulse.com/' title='Notes from Eclipse Democamp in Dallas, Texas'/><link rel='replies' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/7451295081976113738/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18663041&amp;postID=7451295081976113738' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/7451295081976113738'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/7451295081976113738'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/2008/06/notes-from-eclipse-democamp-in-dallas.html' title='Notes from Eclipse Democamp in Dallas, Texas'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18663041.post-531093276517734952</id><published>2008-06-11T18:44:00.000-07:00</published><updated>2008-07-16T16:29:23.310-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Groovy Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='GroovyEclipse'/><title type='text'>Beware GStrings and their IDE support!</title><content type='html'>Despite the lascivious implications of the title, this blog entry has a G rating, as in Groovy!!  You know, before I continue, I would like to apologize to y'all out there.  I realize that punnery is considered, in the eyes of many, to be the lowest form of humor.  But you know, why oh why was the name GString chosen and permitted to persist?  Even though I am a strong Groovy proponent (some accuse me of being a fanboy), I can't stop the little 12 year old pubescent child in me from snickering every time I read about Groovy 'GString(s)'.&lt;br /&gt;&lt;br /&gt;I want to preface my comments by saying that I love Groovy Strings (aka. GString(s)).  I love the multiline strings, I love the ability to create regular expressions without slashing yourself all up, I really love the templating or string interpolation that allows arbitrary groovy expressions to be embedded in a string expression and I even love the fact that the GString is lazily evaluated.  So why the title?  I will get to that next.  Before I continue, for you nit-pickers out there, I know that a GString is strictly only a string expression that is double quoted and contains an unescaped dollar sign, so I suppose I should have titled the blog entry as 'Beware Groovy String Support from within IDE(s)!', but really what fun is that?&lt;br /&gt;&lt;br /&gt;As I started using Groovy and learned about its support for strings, I grew to love single quoted strings.  Single quoted strings are the closest thing to Java string literals, they are immutable and are never evaluated to GString(s).  They appeal to my need for simplicity.  The problem comes later, as I write code, especially Unit Testing code, when all of a sudden I want to use a GString.  &lt;br /&gt;&lt;br /&gt;What is the problem?  Why don't I just switch the single quotes to a double quote and voila!  You ever try it?  I don't know if IntelliJ's allegedly miraculous Groovy support does the same thing, but my baby, the Groovy Eclipse plugin sure does annoy me on this one.  I suppose I could do a find and replace, but often my first instinct is to use the cursor keys and use that backspace button baby!  And when I do that I run smack dab into a little feature that wants to autocomplete the double quotes, you know take " and change it to "".  That is fine, but my first instinct is to hit backspace to remove the second and unnecessary double quote, which causes both of the double quotes to vanish, not what I want!  So usually I stop, mutter an obscenity under my breath to myself, move my cursor in-between the two double quotes and hit the delete button, which I almost never use except in this one case.&lt;br /&gt;&lt;br /&gt;Maybe this is more of a commentary on my coding style and how I interact with the IDE, but it has forced me to reconsider how I use strings in Groovy.  From now on, I will try and avoid single quotes like the plague and use them only in cases where they are explicitly called for.  In other words, I will no longer use the '' (single quoted) strings in groovy by default and instead use "" (double quoted) strings.  &lt;br /&gt;&lt;br /&gt;You know there is one other reason for this switch.  I have had on occasion the need to convert my Groovy code to Java code and, other than the missing semicolons, fixing single quoted strings to be double quoted is second most laborious/annoying/mind-numbing step I have had to take.&lt;br /&gt;&lt;br /&gt;So it is double quoted strings from now on for this boy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18663041-531093276517734952?l=iacobus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/531093276517734952/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18663041&amp;postID=531093276517734952' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/531093276517734952'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/531093276517734952'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/2008/06/beware-gstrings-and-their-ide-support.html' title='Beware GStrings and their IDE support!'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18663041.post-4758283112981345013</id><published>2008-06-08T11:52:00.000-07:00</published><updated>2008-06-08T13:55:15.260-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Groovy Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse Monkey'/><category scheme='http://www.blogger.com/atom/ns#' term='EclipseMonkey'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='Monkey'/><category scheme='http://www.blogger.com/atom/ns#' term='JUnit'/><category scheme='http://www.blogger.com/atom/ns#' term='GroovyEclipse'/><title type='text'>Using Groovy for Unit Tests inside Eclipse</title><content type='html'>I have blogged before in the past about using &lt;a href="http://iacobus.blogspot.com/2007/03/add-groovy-to-your-eclipse-plugin.html"&gt;Groovy to write Eclipse Plugins&lt;/a&gt;.  In fact, I think I am the only person in the world to ever write about the subject ever.  This lack of interest in the subject is unfortunate for many reasons, but one reason in particular is the fact that writing in Groovy as opposed to Java can make many plugin related tasks simpler, particularly a lot of the tasks that make writing plugins no fun.  For this specific reason, I am considering giving giving &lt;a href="http://groovy.codehaus.org/Using+the+Eclipse+Modeling+Framework+%28EMF%29"&gt;Groovy EMF&lt;/a&gt; a hard look as part of my ongoing efforts to make sense out of the &lt;a href="http://www.eclipse.org/modeling/emf/"&gt;Eclipse EMF Project.&lt;/a&gt;  In my opinion, EMF could be like &lt;a href="http://grails.org/"&gt;Grails&lt;/a&gt; if the generated code were in &lt;a href="http://groovy.codehaus.org/"&gt;Groovy&lt;/a&gt; instead of Java. &lt;br /&gt;&lt;br /&gt;Still I wanted to focus the blog entry on the use of Groovy for Unit Tests inside of Eclipse.  This is because, in my opinion, that writing Unit Tests in Groovy is one of the main entry points for a Java developer to get their feet wet with Groovy and to see its benefits (the other two cases, in my opinion once again, are XML document parsing/generation and scripting).  So here goes.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Framing the problem&lt;/span&gt;&lt;br /&gt;The trouble with using Groovy in your projects is the same for using it for Unit Tests as when using it in production code from within Eclipse.  The problem is that you usually have a build process that is run from the command line, often referred to as headless mode that you use for continuous integration or releases, and then you have the incremental build process that runs from within Eclipse.  For headless (or batch/command line) builds, there is support from Groovy to assist with this, first there is the groovyc command that is equivalent to javac and second there is the &lt;a href="http://groovy.codehaus.org/The+groovyc+Ant+Task"&gt;Groovyc Ant Task.&lt;/a&gt;  To take advantage of Eclipse incremental builds you really need to have an Eclipse plugin supporting that for you.  This is where &lt;a href="http://groovy.codehaus.org/Eclipse+Plugin"&gt;Groovy Eclipse&lt;/a&gt; can really be helpful, it provides the needed plugin support for incremental builds for Groovy from within Eclipse.  For the next sections we will focus on solutions for utilizing Groovy for Unit tests.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Solution 1: GroovyTestSuite&lt;/span&gt;&lt;br /&gt;There is a short snippet on using &lt;a href="http://groovy.codehaus.org/Unit+Testing"&gt;GroovyTestSuite&lt;/a&gt; from within Eclipse.  There is one strong advantage to this method, since the groovy code is compiled when the AllTests are run, ostensibly this method could be used in both the headless batch build and from within Eclipse without any changes.  So why not just use this method?  Well there are downsides:&lt;br /&gt;&lt;br /&gt;1. You can't use Eclipse's nice 'Recreate Test Suite' operation to keep the AllTests suite in sync.  Over time, this is one of those problems that will bite more than once and usually when you least expect it.&lt;br /&gt;2. If you don't have unit test classes compiled to classfiles, it makes running individual test cases difficult.  This is something you feel more when you are trying to get a particularly challenging testcase to pass, in addition to the added compilation time, you will have to run the suite again.  Of course you could create a new JUnit Testsuite just for the testcase you are trying to run, but then don't forget to delete it when done and don't check it into your source repository.&lt;br /&gt;3. You have to make an assumption as to the current working directory.  If you notice in the example code for &lt;a href="http://groovy.codehaus.org/Unit+Testing"&gt;GroovyTestSuite&lt;/a&gt; you have to assume that the unit test runner is being run from the project source directory.  This is fine for Eclipse, just remember to check if that assumption holds for your batch/headless build as well.&lt;br /&gt;4. You have to make assumptions as to the testcase's package.  Once again refer to the code example for &lt;a href="http://groovy.codehaus.org/Unit+Testing"&gt;GroovyTestSuite&lt;/a&gt;.  In the example see that the source directory, the package path is hardcoded, and the groovy file name is hardcoded.  This is fine as long as you never change the source directory or refactor your test code into other groovy files or java packages, (*sarcasm alert*) which will never happen right?  Now admittedly if you run your unit tests early and often, you will see this and then you will go and fix them immediately.  Still better to not have to make those assumptions right?&lt;br /&gt;5. Be careful about making Groovy code dependent on Java code or vice versa from within the same Eclipse Java project.  This is a problem shared with the second approach as well.  It is something you must consider (I know that groovyc will now compile Java code as well and it should be evaluated for use from within Groovy Eclipse or from your external build processes).  There are a couple of ways to deal with the issue as I currently understand it.  First, if you write only Groovy or Java code in a test project, there is no problem.  This is usually an ok solution for greenfield test writing, but will not hold long term.  Secondly, since there are no generated classfiles from groovy code in your project, you cannot allow your Java code to rely on any groovy code in the same test project period.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Solution 2: Groovy Eclipse Plugin&lt;/span&gt;&lt;br /&gt;There is another option from within Eclipse, install the &lt;a href="http://groovy.codehaus.org/Eclipse+Plugin"&gt;Groovy Eclipse Plugin&lt;/a&gt; and then add the Groovy builder and nature to your JUnit test project.  Why do this?  Well Groovy Eclipse will compile your Groovy code to classfiles and place them in a class folder for Eclipse so that Eclipse sees the compiled code as just another set of compiled Java code.  This means that GroovyTestSuite is unnecessary and that running tests will not incur the full costs of compilation at start time, a significant advantage for developers.  Another advantage is that the unit tests are compiled, so it is possible to easily run one testcase at a time.  If setup correctly, using the Groovy Eclipse plugin makes developing/using Unit Tests in Groovy as seamless and invisible as possible.  "So", you may ask, "ok Groovy Eclipse fan boy, what are the tradeoffs?"  First off, even though I am a Groovy Eclipse committer and supporter, I am very well aware of its shortcomings, so I am not a fan boy.  Secondly, well here are the tradeoffs/issues with this approach.&lt;br /&gt;&lt;br /&gt;1. You must include Groovy as part of your batch/headless build process to compile the Groovy Unit Tests first, before the Unit tests are run.  This is the same trouble you have if you are using Groovy in your production code.  I will refer you to the section above titled 'Framing the Problem', for approaches on dealing with this.  Using GroovyTestSuite only requires access to the groovy libraries at runtime.&lt;br /&gt;2. Be careful about making Groovy code dependent on Java code or vice versa from within the same Eclipse Java project.  This is not a problem unique to Groovy Eclipse or to writing Unit Tests with Groovy, but it is something you must consider (I know that groovyc will now compile Java code as well and it should be evaluated for use from within Groovy Eclipse).  There are a couple of ways to deal with the issue as I currently understand it.  First, if you write only Groovy or Java code in a test project, there is no problem.  This is usually an ok solution for greenfield test writing, but will not hold long term.  Secondly, be careful and avoid the following circumstances, A.groovy depends on B.java which depends on C.groovy or A.java depends on B.groovy which depends on C.java.  This is an issue that needs to be addressed in Groovy Eclipse generally, either by leveraging groovyc to compile Java code or do an analysis to provide an Error/Warning marker to the user about the above circumstances.  A useful heuristic traditionally is to allow groovy code to depend on java code or java code to depend on groovy code but not vice versa in the same project.  If you hold to that heuristic, just consider the issue raised by number 3.&lt;br /&gt;3. The order of the builders in the .project file.  First off if you have groovy code depending on java code or vice versa in the same project, make sure that the groovy builder is before or after the java builder in the .project file.  This can be easily checked by right clicking the project and then bringing up the properties dialog.  Just look for the Builders section, you can easily remove, add, or reorder the builders in your .project file.  Secondly, there are other occasions to be careful about the build order.  In particular, this one bit me yesterday when I was trying to write a couple of unit tests for Eclipse monkey in groovy.  I was pulling my hair out and about to give up on groovy unit tests for monkey (I mentioned I am not a Groovy Eclipse fanboy didn't I?), when I remembered to check the builder order.  Sure enough, the groovy builder came after the plugin and manifest builders.  Reordering the groovy builder to come before the PDE builders then allowed the PDE JUnit to actually run (Note to self: add better PDE support for Groovy Eclipse).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;There are advantages and disadvantages to both approaches to writing Unit Tests for your projects from within Eclipse.  The first approach, at first, seems more straightforward and simple, in particular no integration with external builds, compilation of groovy code is reduced to a classpath resolution problem.  The second approach, using Groovy Eclipse, leaves the developer with the need to integrate Groovy into their external build processes, but in the longer term provides a more seamless and productive experience.  So if you are wanting to write Unit Tests in groovy, give Groovy Eclipse a try!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18663041-4758283112981345013?l=iacobus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/4758283112981345013/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18663041&amp;postID=4758283112981345013' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/4758283112981345013'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/4758283112981345013'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/2008/06/using-groovy-for-unit-tests-inside.html' title='Using Groovy for Unit Tests inside Eclipse'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18663041.post-8478671805663718690</id><published>2008-05-28T17:55:00.000-07:00</published><updated>2008-06-08T14:01:03.880-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse Monkey'/><category scheme='http://www.blogger.com/atom/ns#' term='EclipseMonkey'/><category scheme='http://www.blogger.com/atom/ns#' term='GroovyMonkey'/><category scheme='http://www.blogger.com/atom/ns#' term='Monkey'/><title type='text'>Eclipse Monkey - Extension Points it is</title><content type='html'>For the new Eclipse Monkey I was considering use of Declarative Services in OSGi since I was intending to allow at least the core set of plugins to be able to used within the context of just a OSGi container.  I have decided to use extension points based on my research of the past couple of days.&lt;br /&gt;&lt;br /&gt;Neil Bartlett has an excellent writeup of &lt;a href="http://neilbartlett.name/downloads/extensions_vs_services.pdf"&gt;extension points versus OSGi services&lt;/a&gt;: http://neilbartlett.name/downloads/extensions_vs_services.pdf&lt;br /&gt;&lt;br /&gt;My number one concern was allowing people using Equinox, Knopflerfish(really what a name right?), Apache Felix, or other OSGi container could leverage the basic ability to write scripts.  This concern addressed by the fact that bundles working in the context of a pure OSGi container only has to add the following two Eclipse Equinox bundles: org.eclipse.equinox.registry and org.eclipse.equinox.common.  I don't think this is a bad trade-off because of the following considerations: dynamic bundles and tooling.&lt;br /&gt;&lt;br /&gt;The first consideration is dynamism of bundles, whether they can be hot swapped in or out.  This is the number one reason to use OSGi Declarative Services, it is made to work with the fact that bundles could come up or down.  I don't think this will be a major concern for monkey, extensions will be things like definitions of script metadata elements, DOM objects, etc...  These are things where dynamic hot swapping of bundles is not really beneficial.  Besides I always prefer to ask the Extension Registry for the list of available extensions and not cache them.  Without caching references from extensions, the code will already allow for dynamic hot swapping.  If performance becomes a major issue, well that is what the ExtensionTracker is for. &lt;br /&gt;&lt;br /&gt;The second consideration is a major one for me.  There is some tooling in Eclipse within the PDE for extensions.  Actually there is a lot of tooling.  Tooling support for OSGi services, much less Declarative Services, is pretty much non-existent.&lt;br /&gt;&lt;br /&gt;So given the thought process outlined here, I think Eclipse Monkey is safe sticking with extension points.  As long as there is an Eclipse, it will have to support Extension Points and Extensions.  If there is no Eclipse, well there is no Monkey either right?&lt;br /&gt;&lt;br /&gt;P.S.:  During my research on this I have to say I was impressed with the &lt;a href="http://www.knopflerfish.org/"&gt;Knopflerfish &lt;/a&gt;site and its Eclipse plugin.  I was also almost impressed with the &lt;a href="http://wiki.ops4j.org/confluence/display/ops4j/Pax+Cursor"&gt;Ops4J Pax Cursor&lt;/a&gt;.  Honestly, is it so hard to integrate with the PDE Knopflerfish developers?  I mean do you need to create your own builder and nature?  You guys are almost there, just hook into the PDE and provide an Eclipse recognizable Target Platform.  That is it, a few days work maybe, and then voila your stuff will work and all the PDE tooling will work for you.  Same complaint with the Pax Cursor people, y'all are further along than the Knopflerfish people in that you not only support multiple OSGi containers and integrate better with the Eclipse PDE, but could I just get an Eclipse recognizable Target Platform?  I mean y'all are just one little step away.  Get &lt;a href="http://wiki.ops4j.org/confluence/display/ops4j/Pax+Cursor"&gt;Chris Aniszczyk&lt;/a&gt;(I take back what I said about Knopflerfish's name earlier) or someone else on the PDE team to point you to how to address the last hurdle.  I mean guys, what better way to get some Java developers(in particular Eclipse Plugin developers) to try out your stuff.  Also I should not just beat up on the Knopflerfish and Pax Cursor guys, I mean are you listening Eclipse PDE people?  Its great you can run your bundles on a launch configuration that says OSGi container, but is it really that cool given that the only container that works out of the box is the Equinox one??  I have worked with some of those containers in the past and I know this aint rocket science.  Why don't I do it?  As my grandmother used to say, "If wishes were horses, beggars would ride."  My interests right now lie elsewhere.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18663041-8478671805663718690?l=iacobus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://neilbartlett.name/downloads/extensions_vs_services.pdf' title='Eclipse Monkey - Extension Points it is'/><link rel='replies' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/8478671805663718690/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18663041&amp;postID=8478671805663718690' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/8478671805663718690'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/8478671805663718690'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/2008/05/eclipse-monkey-extension-points-it-is.html' title='Eclipse Monkey - Extension Points it is'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18663041.post-910661042936358913</id><published>2008-05-26T11:45:00.000-07:00</published><updated>2008-06-08T14:01:32.298-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse Monkey'/><category scheme='http://www.blogger.com/atom/ns#' term='EclipseMonkey'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Monkey'/><title type='text'>Eclipse Monkey - Core design notes</title><content type='html'>I am currently working on the new Eclipse monkey, starting this week.  You know it is amazing how much time unemployment can free up for you or, er, contract sabbatical.   I will make available a temporary public repository when I have something to show for this.  I am always open to comments.   I am writing this blog entry in order to state what are the design goals for this version of monkey, in particular the core plugin.&lt;br /&gt;&lt;br /&gt;In many ways it is very very tempting to just take Groovy Monkey, rename a few packages and classes and then voila, here is the new Eclipse Monkey.  There would be nothing wrong with that, I am after all proud of Groovy Monkey, its simple and it works.  Still I would be remiss if I did not take advantage of this natural break to consider some refactoring and or redesign. &lt;br /&gt;&lt;br /&gt;The main consideration I wish to take into account for the new version of Eclipse Monkey is to make it more modular.  What I mean by that, is that I wish it to be possible to use monkey across the full spectrum of the Eclipse platform.  Now what does that mean?  I think I would be best able to explain it in terms of goals.  It is a goal to allow people developing using just an OSGi container to be able to leverage some useful subset of Eclipse Monkey functionality in their applications.  Allowing a bundle developer to be able to run scripts embedded in a bundle, specified via a URI/URL or specified directly in a string.  Another goal would be to allow that core functionality plus some additional support to be used by a developer of Eclipse RCP applications.  At the RCP level, there is now the notion of a workspace, SWT/JFace UI API and Eclipse jobs, so the monkey functionality to support that should be available.  The same idea would apply to Eclipse Platform, JDT and finally the PDE (which would constitute the full Eclipse SDK).&lt;br /&gt;&lt;br /&gt;There are some consequences of these decisions.  There will be more bundles/fragments than would be otherwise, but at least those components should be simpler and smaller in size.  I will focus on those that deal with the new org.eclipse.monkey.core component, which will run in the base OSGi container only.&lt;br /&gt;&lt;br /&gt;We will have to consider OSGi services (perhaps declarative services), since we are missing Eclipse extension points for one.  This will be decidedly different from Groovy Monkey where language extensions and DOM(s) are specified via extension points.  Hopefully this will be possible without too much difficulty, also consideration will be made to allow parallel extension points, since the PDE support for extension points is much further along than with OSGi services.  Of course allowing for parallel definitions, we will hopefully not have too many headaches with monkey bundle developers trying to define their extensions as both OSGi services and Eclipse defined extension points.&lt;br /&gt;&lt;br /&gt;Another consequence of the OSGI only approach is that there will be no IResources API, so there will need to be support for allowing scripts to be embedded in a bundle, located via URI/URL or even to allow script text to be taken in verbatim.  This will be a significant difference from Groovy Monkey where everything is assumed to be a resource in the workspace.&lt;br /&gt;&lt;br /&gt;Finally, another major impact of this choice, will be the fact that support for threading through the Eclipse Jobs API will not be available.  This in and of itself also makes me want to abandon the OSGi only approach.  This means that use of IWorkspaceRunnable and Eclipse Jobs will commence only when the org.eclipse.core.runtime bundle is available.&lt;br /&gt;&lt;br /&gt;There are two other things that this line of thinking has led me to consider.  One, the metadata keywords and definitions should be pluggable themselves.  As of right now in Groovy Monkey the script metadata is pretty statically defined in the code for the core plugin.  If the layering support is to work, they have to be plugged by different plugins/fragments depending on the framework that monkey is being run in.  Second, probably need a way to define which bundles are required or which platform the script is meant to run against.  For instance, putting in a Job definition for a script running in an OSGi container is nonsense, however once in the RCP level, it is required.  I think that there should be probably hardcoded values: OSGi, RSP, RCP, Platform, JDT and PDE.  RSP would be the OSGi container plus the org.eclipse.core.runtime and org.eclipse.core.resources plugins, but no UI support.&lt;br /&gt;&lt;br /&gt;Finally, all this work has to be done with the idea of backwards compatibility in mind.  Hey I have written lots of monkey scripts I don't wanna throw away either.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18663041-910661042936358913?l=iacobus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/910661042936358913/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18663041&amp;postID=910661042936358913' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/910661042936358913'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/910661042936358913'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/2008/05/eclipse-monkey-core-design-notes.html' title='Eclipse Monkey - Core design notes'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18663041.post-2541337111714645376</id><published>2008-05-15T15:38:00.000-07:00</published><updated>2008-05-15T15:41:19.625-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><title type='text'>Groovy Presentation at eBay available</title><content type='html'>I got the opportunity to present an introduction to groovy at eBay this past May 9th.  It is now available from the Groovy Codehaus site at: http://groovy.codehaus.org/presentations/Groovy_eBay_2008May09/GroovyJamesErvin.html&lt;br /&gt;&lt;br /&gt;Thanks to Dave Marsland and others at eBay for giving the the chance.&lt;br /&gt;&lt;br /&gt;Note to Microsoft, getting WebDAV to work on Vista should not be *that* difficult.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18663041-2541337111714645376?l=iacobus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://groovy.codehaus.org/presentations/Groovy_eBay_2008May09/GroovyJamesErvin.html' title='Groovy Presentation at eBay available'/><link rel='replies' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/2541337111714645376/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18663041&amp;postID=2541337111714645376' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/2541337111714645376'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/2541337111714645376'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/2008/05/groovy-presentation-at-ebay-available.html' title='Groovy Presentation at eBay available'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18663041.post-6842364448549472799</id><published>2008-05-06T16:30:00.001-07:00</published><updated>2008-06-08T13:57:24.911-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='EclipseMonkey'/><category scheme='http://www.blogger.com/atom/ns#' term='GroovyMonkey'/><category scheme='http://www.blogger.com/atom/ns#' term='Monkey'/><title type='text'>New Eclipse Monkey</title><content type='html'>As you may or may not know, I have been working on Groovy Monkey for some time now.  I think it is a useful tool and has a number of benefits over its predecessor Eclipse Monkey.  Right now I am hoping that I will have the opportunity to take over Eclipse Monkey and take all of Groovy Monkey's improvements and make them more available to everyone.&lt;br /&gt;&lt;br /&gt;I am writing a proposal for this (its a work in progress), you can view it at &lt;a href="http://docs.google.com/Doc?id=dhqk7f2t_32f3wd95g6"&gt;Eclipse Monkey Proposal&lt;/a&gt;.  I would love your comments and feedback.  I really hope this will happen, I wrote Groovy Monkey because I wanted a tool like that and I think others will too.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18663041-6842364448549472799?l=iacobus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://docs.google.com/Doc?id=dhqk7f2t_32f3wd95g6' title='New Eclipse Monkey'/><link rel='replies' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/6842364448549472799/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18663041&amp;postID=6842364448549472799' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/6842364448549472799'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/6842364448549472799'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/2008/05/new-eclipse-monkey.html' title='New Eclipse Monkey'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18663041.post-6197112359869031484</id><published>2008-05-06T10:31:00.000-07:00</published><updated>2008-06-08T14:02:00.654-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Groovy Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='GroovyEclipse'/><title type='text'>Remarks from the Groovy Meetup before JavaOne</title><content type='html'>I went to the Groovy meetup yesterday in San Fransisco and I can tell you that the primary effect on me was to get me all geeked up again for Groovy.  Now I don't want to leave the wrong impression, I wasn't upset with Groovy at all or anything.  What I will say is that I thought that the excitement in the room was palpable and I definitely feel that Groovy is finally coming out of its 2004 pre-JSR malaise and really about to achieve its potential.  Now I know being in a hotel conference room with a bunch of people who are obviously Groovy partisans does not a trend or good prediction make but I defend the statement on two grounds.  One, my gut feel is not solely based on what I sensed yesterday, but rather based on what I have seen on the net and experienced as a Java developer working with Groovy.  If you are a Java developer and well aware of its pain points, how can groovy not appeal to you, I mean really?  Second, its my opinion, which I am entitled to have and be wrong about (which I don't believe I am wrong in this case).&lt;br /&gt;&lt;br /&gt;One of the points that Guillaume, the Groovy project manager, brought up in his presentation, was the improvement of the performance of the 1.5+ Groovy runtime.  I can say, without equivocation, that the improvement in performance is indeed extraordinary.  In fact, he left out of his presentation the area that I think that Groovy 1.5+ has improved most on, was compiler performance.  I would put compiler performance improvement to be on the order of magnitude better.  Now I do not have any micro-benchmarks or pseudo statistics to back me up, but I will say that this is my gut feel based on my experience with Groovy Monkey.  On the machine I currently use for my work (Windows Server 2003/Quad Core/8 GB RAM/IBM JVM 5.0/Eclipse 3.4M5), I would say that before Groovy 1.5, the scripts I would write that would invoke other monkey scripts, could be very very slow, on the order of a couple of minutes or more.  Now those same scripts are running like well under 30 seconds and this result is not based on any changes to Groovy Monkey or any of the underlying platform.  All I can say is wow!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Groovy Eclipse&lt;/span&gt;&lt;br /&gt;I do have a comment on a slightly bitter note.  I am a committer to the Groovy Eclipse project and it pained me to hear how it was mentioned that the plugin was more of a impediment than an asset to Groovy's adoption.  I will admit that I myself began to get frustrated with it (and there are still some frustrations) a couple of months back.  Still with the newer Groovy runtime and the latest submissions to at least the development version of the plugin, it is a far far better product.  &lt;br /&gt;&lt;br /&gt;Still there is the point that even with the latest improvements that the Groovy Eclipse plugin is still lagging significantly IDE support from IntelliJ.  First off I want to mention, congrats to IntelliJ.  Even though I am primarily an Eclipse developer, I am probably going to try it out just to see the Groovy support and this is a point to which I want to get back to.  Still both IntelliJ and NetBeans have people working full time on the Groovy IDE support, which is great for people using those platforms, not so great for the vast numbers of developers using Eclipse.  The point I want to drive home is that, as I have learned from personal experience, IDE integration is both vital to the success of a language or framework and &lt;span style="font-weight:bold;"&gt;hard&lt;/span&gt; to do.  Now I may fiddle around with IntelliJ (or even, *&lt;span style="font-weight:bold;"&gt;gasp&lt;/span&gt;* NetBeans) to try out their Groovy support, but do you really think that the vast legion of Java developers using Eclipse are really going to take a hard look at Groovy without first class IDE support?  I don't believe so and I would think that just about everyone would agree with me on this point.&lt;br /&gt;&lt;br /&gt;So how do you address this?  Simple, there needs to be a small group of well motivated and competent Groovy and Eclipse plugin developers that can be dedicated full time to Groovy Eclipse.  In my experience, only people working full time focused on IDE support could give Groovy Eclipse that first class spit and polish which can impress developers trying Groovy for this first time.  I mean, Project Zero and Scott Hickey's work with Mutual of Omaha has contributed much to the plugin and there are some nice contributions being made currently by people in their free time, but this is not their primary focus.  Even though the plugin continues to evolve under current circumstances, this would not compare with the strides that could be made by people working full time.  Are you listening Guillaume, Mr. Guan, others, anybody??  I mean there has some buzz about Groovy being the &lt;span style="font-weight:bold;"&gt;next&lt;/span&gt; version of Java and I know that Guillaume and others have stated that there is no intention of Groovy replacing Java, but can you imaging Groovy reaching its potential without great Eclipse IDE support?  I know that I just repeated that point from earlier, but it bears repeating.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Back to the meetup&lt;/span&gt;&lt;br /&gt;Now back to the Groovy meetup.  I would also like to point out that I was much impressed with the presentation from the folks at Linked In.  I am already a user of their product and I am even more impressed to the degree to which they appear to be driven from the Engineering perspective.  Besides, they are really starting to use Groovy and Grails in anger!  How cool is that man?  I love the fact that they and, I believe it was, Sky television are showing that Grails is like RoR, but with stability and scalability added at no extra charge.  That is so cool and can demonstrate how getting better IDE support for both Groovy and Grails could make such a difference.&lt;br /&gt;&lt;br /&gt;I am looking forward to the future of Groovy and crossing my fingers that there wont be too much backward compatibility breaking between now and Groovy 2.0.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18663041-6197112359869031484?l=iacobus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://g2one.com/meetup/' title='Remarks from the Groovy Meetup before JavaOne'/><link rel='replies' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/6197112359869031484/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18663041&amp;postID=6197112359869031484' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/6197112359869031484'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/6197112359869031484'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/2008/05/remarks-from-groovy-meetup-before.html' title='Remarks from the Groovy Meetup before JavaOne'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18663041.post-8543891079888784037</id><published>2008-04-03T09:33:00.000-07:00</published><updated>2008-04-03T14:10:55.809-07:00</updated><title type='text'>New stuff coming for Groovy Monkey</title><content type='html'>I know I have been negligent over the past few months about keeping up with new features to groovy monkey.  I also know and appreciate the fact that there are those of you out there who use the tool *in anger* so to speak. First off all you should know that the project is not *dead* in any real sense.  Secondly, I make use of the tool daily and have been making some commits to enhance groovy monkey.  Third, I saw some cool stuff out of EclipseCon that I would like to integrate into Groovy Monkey.&lt;br /&gt;&lt;br /&gt;On the first point, after going to EclipseCon and seeing that there was very little activity with Eclipse Monkey along with the fact that it still has the same weaknesses that led me to write Groovy Monkey in the first place, has rekindled my interest in writing new features for the plugin.  I mean, Eclipse Monkey still runs everything in the UI thread, what is up with that?&lt;br /&gt;&lt;br /&gt;On the second point, I have written a tool to allow me to automatically publish a new version to the update site, so you should be seeing more regular changes to the plugin.  Now if I only had a nice script to automate publishing new releases as well.&lt;br /&gt;&lt;br /&gt;On the third and final point, at EclipseCon I saw a couple of things that I would love to integrate with Groovy Monkey.  First something called glimmer and second something called Plugin spy.&lt;br /&gt;&lt;br /&gt;First off I was introduced to something called Glimmer by Andy Maleh.  The reason that this project is of note is that I do not want to forget those people who want to use that language Ruby.  Glimmer is a cool utility that is in effect a SWT/JFace builder.  In fact, it is a far cooler builder than the one we have available from Groovy.  I look forward to trying this and to updating the jruby libraries in Groovy Monkey.&lt;br /&gt;&lt;br /&gt;Second is Chris Aniszczyk's new tool called Plugin spy.  It is due to come out with Eclipse 3.4 (you can try it out now in version 3.4M5) and it is soooo cool.  Actually I saw the tool earlier when he demonstrated it at the Eclipse Demo camp in Austin last December, but the epiphany came at EclipseCon.  There is a killer feature, where you select a ui element in the workbench, hit ALT-shift-F1 and it will show a dialog with the class that represents that element, plus any additional information like extension points, etc...  It is killer if you have ever tried to write a plugin extending the workbench you know that oftentimes over half the battle is just finding something.  This tool can point you straight at what you want to see.  So you say, where does Groovy Monkey come in and what about this life-changing epiphany?  (Its so cool now that I know how to spell epiphany now.)  The idea is if we could get an extension point into the Plugin spy so that Groovy Monkey could add a link and then be invoked with the information in that dialog it could be used to create a script.  Why would that be cool?  Imagine for a second that you are looking around the workbench and then want to see what is implementing a given feature, you use the plugin spy to see what is doing it.  Well that is great, but how about trying it out?  You would need to create groovy script, remembering all the details like the bundle, class name, etc...  What if you could click the link in the plugin spy dialog and then use that information to create a template script?  It would save alot of clicks and hassle, now that would be cool.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18663041-8543891079888784037?l=iacobus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/8543891079888784037/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18663041&amp;postID=8543891079888784037' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/8543891079888784037'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/8543891079888784037'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/2008/04/new-features-for-groovy-monkey.html' title='New stuff coming for Groovy Monkey'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18663041.post-4643580705017380326</id><published>2007-03-08T08:43:00.000-08:00</published><updated>2007-03-08T11:09:56.058-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='Grails'/><title type='text'>Add Groovy to your Eclipse Plugin Projects</title><content type='html'>I have begun some basic work on the Grails Eclipse plugin that I outlined in a proposal in a previous &lt;a href="http://iacobus.blogspot.com/2007/03/grails-eclipse-ide-support.html"&gt;post&lt;/a&gt;. One of the features I want to highlight will be the fact that I want the plugin to be almost exclusively written in Groovy instead of Java.&lt;br /&gt;&lt;br /&gt;As I start work on the plugin, I want to highlight a feature that I will hopefully add to the Groovy Eclipse Plugin in the real near future, Groovy PDE Build support. If you install the Groovy Eclipse Plugin ( I think the version currently in Head/Trunk is better than the one on the update site ), you will find that your development for the most part goes smoothly, except for when you start using Groovy to write your Eclipse Plugins. The issue is that the PDE Builder doesn't know, and probably doesn't want to know, about the Groovy code and its need to be compiled with the Groovy compiler. So how do you deal with this?&lt;br /&gt;&lt;br /&gt;One way is to parallel the work of the Eclipse PDE Build team and write your own scripts that can interpret the build.properties file to export your plugin yourself. This can make you proud and think you are a real programmer, except that why in the heck do you want to repeat something that has already been done?&lt;br /&gt;&lt;br /&gt;Another way is to generate the build.xml file, click the custom build option on the plugin and maintain the ant build file manually. Do I need to go into the obvious problems and pain with this option? If you like pain, reading ant XML scripts, pain, deciphering the incredibly ( but probably necessary ) complex PDE build process, pain, keeping your Ant XML file synchronized to changes in your project manually, and yet more pain, go ahead. I wont stop you, for the rest of us I am going to cover the next, and I believe, better option.&lt;br /&gt;&lt;br /&gt;One side note, I am very familiar with the pain that I described above, I wrote a series of Groovy scripts to build our products, as per the first option. Pretty cool and better than the second option, but it really was a source of pain and, as I will now show you, unnecessary work.&lt;br /&gt;&lt;br /&gt;The final option I give you, with an example, is what I think to be the best option. In fact, I wish I knew of it before on previous Eclipse based projects. As of Eclipse 3.2, you have the ability to specify a custom callbacks XML file.&lt;br /&gt;&lt;br /&gt;To add Groovy PDE Build support to your plugin project, first you must install the Groovy Eclipse plugin and enable the groovy nature for your project. Deployment of the groovy libraries into your plugin for installation is another topic for another time.&lt;br /&gt;&lt;br /&gt;Afterwards goto your Eclipse installation directory and open up the plugins directory. Goto the org.eclipse.pde.build plugin installation directory and look in the templates/plugins subdirectory. You will see there a template called customBuildCallbacks.xml, import this into your project.&lt;br /&gt;&lt;br /&gt;Now open up your build.properties file and add a property called customBuildCallbacks like the following example:&lt;br /&gt;&lt;br /&gt;customBuildCallbacks = customBuildCallbacks.xml&lt;br /&gt;&lt;br /&gt;This means that the build will now reference a callback Ant Build script in my project called customBuildCallbacks.xml in the root of my project. You could prepend a project relative path to the file name to place the file somewhere else if you choose.&lt;br /&gt;&lt;br /&gt;The next step I like to do is to right click the manifest.mf(plugin.xml) file and ask the PDE to generate a build.xml file. Now I am not going to keep the build.xml file around very long nor its javaCompiler args file. I am going to use it to extract the targets that will be called in the callback ant script and to find out the name of the classpath reference that will be used.&lt;br /&gt;&lt;br /&gt;Below is an example file from the plugin I am currently working on.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;subant antfile="${customBuildCallbacks}" target="pre.@dot" failonerror="false" buildpath="."&amp;gt;&lt;br /&gt; &amp;lt;property name="source.folder1" value="src/"/&amp;gt;&lt;br /&gt; &amp;lt;property name="target.folder" value="${temp.folder}/@dot.bin"/&amp;gt;&lt;br /&gt; &amp;lt;reference refid="@dot.classpath"/&amp;gt;&lt;br /&gt;&amp;lt;/subant&amp;gt;&lt;br /&gt;&amp;lt;!-- compile the source code --&amp;gt;&lt;br /&gt;&amp;lt;javac destdir="${temp.folder}/@dot.bin" failonerror="${javacFailOnError}" verbose="${javacVerbose}" debug="${javacDebugInfo}" includeAntRuntime="no" bootclasspath="${bundleBootClasspath}" source="${bundleJavacSource}" target="${bundleJavacTarget}"  &amp;gt;&lt;br /&gt; &amp;lt;compilerarg line="${compilerArg}" compiler="${build.compiler}"/&amp;gt;&lt;br /&gt; &amp;lt;classpath refid="@dot.classpath" /&amp;gt;&lt;br /&gt; &amp;lt;src path="src/"   /&amp;gt;&lt;br /&gt; &amp;lt;compilerarg value="@${basedir}/javaCompiler...args" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/&amp;gt;&lt;br /&gt; &amp;lt;compilerarg line="-log '${temp.folder}/@dot.bin${logExtension}'" compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/&amp;gt;&lt;br /&gt;&amp;lt;/javac&amp;gt;&lt;br /&gt;&amp;lt;!-- Copy necessary resources --&amp;gt;&lt;br /&gt;&amp;lt;copy todir="${temp.folder}/@dot.bin" failonerror="true" overwrite="false"&amp;gt;&lt;br /&gt; &amp;lt;fileset dir="src/" excludes="**/*.java, **/package.htm*"   /&amp;gt;&lt;br /&gt;&amp;lt;/copy&amp;gt;&lt;br /&gt;&amp;lt;subant antfile="${customBuildCallbacks}" target="post.compile.@dot" failonerror="false" buildpath="."&amp;gt;&lt;br /&gt; &amp;lt;property name="source.folder1" value="src/"/&amp;gt;&lt;br /&gt; &amp;lt;property name="target.folder" value="${temp.folder}/@dot.bin"/&amp;gt;&lt;br /&gt; &amp;lt;reference refid="@dot.classpath"/&amp;gt;&lt;br /&gt;&amp;lt;/subant&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;There are two subant tasks that are of interest one before the javac task and one after. You can overload one or both in your callbacks ant script to allow the groovy builder to run before, after or before and after the java compiler. The important thing here is that the target name and classpath reference in your callbacks script must match.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Here below is an example from my current plugin project.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;target name="pre.@dot"&amp;gt;&lt;br /&gt;&amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;!-- ===================================================================== --&amp;gt;&lt;br /&gt;&amp;lt;!-- Steps to do during the compilation target &amp;lt;name&amp;gt;, after the compile   --&amp;gt;&lt;br /&gt;&amp;lt;!-- but before jaring.  Substitute "name" with the name of the compilation--&amp;gt;&lt;br /&gt;&amp;lt;!-- target, eg @dot                                                       --&amp;gt;&lt;br /&gt;&amp;lt;!-- Available parameters :                                                --&amp;gt;&lt;br /&gt;&amp;lt;!--   source.foldern : n = 1 ... N, the source folders                    --&amp;gt;&lt;br /&gt;&amp;lt;!--   target.folder  : where the results of the compilation go            --&amp;gt;&lt;br /&gt;&amp;lt;!--   &amp;lt;name&amp;gt;.classpath : name = name of the compilation target. A         --&amp;gt;&lt;br /&gt;&amp;lt;!--                      reference to the classpath structure.            --&amp;gt;&lt;br /&gt;&amp;lt;!-- ===================================================================== --&amp;gt;&lt;br /&gt;&amp;lt;target name="post.compile.@dot"&amp;gt;&lt;br /&gt; &amp;lt;path id="org.codehaus.groovy.eclipse.libs"&amp;gt;&lt;br /&gt;  &amp;lt;fileset dir="../org.codehaus.grails.eclipse/grails-home/lib"&amp;gt;&lt;br /&gt;   &amp;lt;include name="**/*.jar"/&amp;gt;&lt;br /&gt;  &amp;lt;/fileset&amp;gt;&lt;br /&gt; &amp;lt;/path&amp;gt;&lt;br /&gt; &amp;lt;taskdef name="groovy"&lt;br /&gt;          classname="org.codehaus.groovy.ant.Groovy"&lt;br /&gt;          classpathref="org.codehaus.groovy.eclipse.libs"/&amp;gt;&lt;br /&gt; &amp;lt;taskdef name="groovyc"&lt;br /&gt;             classname="org.codehaus.groovy.ant.Groovyc"&lt;br /&gt;    classpathref="org.codehaus.groovy.eclipse.libs"/&amp;gt;&lt;br /&gt; &amp;lt;delete&amp;gt;&lt;br /&gt;  &amp;lt;fileset dir="${target.folder}" includes="**/*.groovy"/&amp;gt;&lt;br /&gt; &amp;lt;/delete&amp;gt;&lt;br /&gt; &amp;lt;groovy classpathref="@dot.classpath"&amp;gt;&lt;br /&gt;  def classpathString = task.classpath.list().toList().findAll{ new File( "$it" ).exists() }.join( File.pathSeparator )&lt;br /&gt;  ant.groovyc( srcdir: properties.'source.folder1', &lt;br /&gt;      destdir: properties.'target.folder', &lt;br /&gt;      stacktrace:'true',&lt;br /&gt;      classpath: classpathString )&lt;br /&gt; &amp;lt;/groovy&amp;gt;&lt;br /&gt;&amp;lt;/target&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;The important things to notice are that the targets are called pre.@dot and post.compile.@dot which were derived from the generated ant build script and could be derived from your build.properties file.  The next thing to notice is the classpath called 'org.codehaus.groovy.eclipse.libs' that points to a directory and slurps in all available jar files.  This is done to locate the groovy library and therefore the groovy and groovyc ant tasks.  You must set the path, either relative to the workspace or hardcoded from your file system.  The last thing to notice is the use of the sourceN.folder properties, if you have more than one source folder that is being compiled into your plugin, then you must make allowance for it.  If you are not sure, go back to the generated build.xml, it will tell you since it will set those properties before making the subant call to your customBuildCallbacks.xml script.  &lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;What is the point of all this?  Well simply put, once you have made these modifications, you can write groovy code in your plugin and have the Eclipse PDE Builder/Exporter compile your groovy code along with your bundle with no muss or fuss.  This functionality works if you are exporting a plugin, or as part of a feature or as part of an update site.  Cool eh?&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;One last point, since most of this is rather rote cut and paste, I am looking to enhance the Groovy Eclipse Plugin to handle this for you.  Hopefully it should be part of the next official release on the update site.&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18663041-4643580705017380326?l=iacobus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/4643580705017380326/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18663041&amp;postID=4643580705017380326' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/4643580705017380326'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/4643580705017380326'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/2007/03/add-groovy-to-your-eclipse-plugin.html' title='Add Groovy to your Eclipse Plugin Projects'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18663041.post-6358668567228451796</id><published>2007-03-06T12:33:00.000-08:00</published><updated>2007-03-07T06:58:40.848-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='J2EE'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='Grails'/><title type='text'>Grails Eclipse IDE Support</title><content type='html'>&lt;p&gt;I knew that the idea of an IDE plugin to support Grails could not be new. So I am going to post the contents a nice little "IDE Integration Wish List" from the grails wiki site. I am then going to make a proposal for what I see the path of a Grails Eclipse plugin would take. Comments are more than welcome.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;IDE Wish List (from grails.org)&lt;/strong&gt;&lt;br /&gt;Below are the features that would be great to have from a Grails IDE: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Wizards to create Grails artifacts like controllers/domain objects and so on. Unlike Rails, Grails doesn't do any background configuration with its command line tools so these can merely be simple wizards &lt;/li&gt;&lt;li&gt;Running a Grails server embedded in the IDE and being able to step debug the application. Groovy provides all the information in the classes necessary to enable step debugging of Groovy code &lt;/li&gt;&lt;li&gt;Code navigation with keyboard shotcuts and CTRL+click between Grails artifacts like controllers domain classes etc. &lt;/li&gt;&lt;li&gt;Code completion for things like dynamic finders and persistent methods like save/delete/findAll/findBy* on domain classes &lt;/li&gt;&lt;li&gt;Auto-completion of Grails tags in GSPs &lt;/li&gt;&lt;li&gt;Integration of an embedded Grails console to be able to execute arbitrary scripts against a running application &lt;/li&gt;&lt;li&gt;Being able to right-click execute Grails unit tests and get green/red bars etc. &lt;/li&gt;&lt;li&gt;Being able to right-click on a Grails project and execute all unit tests &lt;/li&gt;&lt;li&gt;Being able to right-click on a domain class and click generate to generate a controller and views for CRUD &lt;/li&gt;&lt;li&gt;Better editor support for groovy files. This means autocompletion and so on. &lt;/li&gt;&lt;li&gt;Special outline views for Domain-Classes, Controllers and Views&lt;br /&gt;Graphical editor for Domain Classes, with a UML-like or ER-like view &lt;/li&gt;&lt;li&gt;The IDE should hook into Grails' upcoming plug-in architecture to be able to do things like auto-find new executable scripts, download and install new plug-ins etc. &lt;/li&gt;&lt;li&gt;Integration of every Servlet-Container to test the Grails-App. The best solution were intergration into webtools &lt;/li&gt;&lt;li&gt;XP Refactor support (e.g. rename methods/groovy file names and cascade changes to all dependencies) &lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;Proposal &lt;/strong&gt;&lt;br /&gt;I would like to start by taking the Grails application and embedding it within a set of Eclipse plugins and then have Eclipse plugins to be able to run directly from the workbench ( via right click options ) the command line commands directly. This would mean that you would not have to install Grails seperately, kinda like Eclipse handles ant. &lt;/p&gt;&lt;p&gt;After that I would like to begin integrating the Groovy Eclipse plugin into the mix. I think that the Groovy Eclipse plugin should be included seperately from the Grails plugin to avoid issues of differing Groovy versions ( that Grails could require different versions from the main Groovy distribution ) and to avoid the overhead of installing all the Grails libraries along with the Groovy Eclipse plugin. Of course, there would be lots and lots of overlap and we should be able to leverage any new improvements in the Groovy plugin quickly. The Groovy Eclipse plugin with its editor and outline view would be the basis for adding more support for Grails.&lt;/p&gt;&lt;p&gt;After the Groovy Eclipse plugin functionality is added, the fun can really begin. As I mentioned in a previous post, convention over configuration would allow us to inject suggestions to method completion. A first target would be the Data Source configuration files, a second would be the Domain classes, and so forth.&lt;/p&gt;&lt;p&gt;A related issue would be to find an open source JSP Editor project that would be willing to partner with us to help develop the GSP Editor. If an acceptable one is not found, then one will have to be fabricated, probably based on a previously existing XML editor.&lt;/p&gt;&lt;p&gt;I think this could be very useful ( i.e. cool ) and since we could leverage already existing tools, we could have something to show rather quickly and have a nice evolutionary path to add new features and functions a little bit at a time.&lt;/p&gt;&lt;p&gt;I would love comments on this proposal.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18663041-6358668567228451796?l=iacobus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://docs.codehaus.org/display/GRAILS/IDE+Integration+Proposal' title='Grails Eclipse IDE Support'/><link rel='replies' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/6358668567228451796/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18663041&amp;postID=6358668567228451796' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/6358668567228451796'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/6358668567228451796'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/2007/03/grails-eclipse-ide-support.html' title='Grails Eclipse IDE Support'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18663041.post-6861190172470920176</id><published>2007-03-06T12:15:00.000-08:00</published><updated>2007-03-06T12:25:54.367-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='J2EE'/><category scheme='http://www.blogger.com/atom/ns#' term='WebApps'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='Grails'/><title type='text'>Convention over Configuration == Eclipse IDE completion support for Grails?</title><content type='html'>As I am going through the "Definitive Guide to Grails", I can definitely say that for the most part things are going well.  I wish that the dynamic update feature would work, but other than that things are going well.&lt;br /&gt;&lt;br /&gt;One thing that has been hitting me like a pile of bricks, is Grails' use of injection to put properties and methods onto an object without it needing to extend a base class.  This is all fine and dandy, but who can remember all those extensions easily for like a domain class?  I know the IDE can.&lt;br /&gt;&lt;br /&gt;As work has been progressing on method completion on the Groovy Eclipse plugin ( great work Ed ), it occured to me that adding additional completion options based on the fact that the project is a grails project should not be very hard, not hard at all.  In fact, I did something similar in Groovy Monkey to add autocompletion and elements in the outline view based on what the script's binding was.  How cool would that be, to not have to remember the domain's class' get, what actions are injected automatically into a controller, to perhaps provide some assistance to using the findBy* methods?&lt;br /&gt;&lt;br /&gt;In fact, the way I think about it, using conventions is a bit like having static type information around.  And if you have some equivalent of static type information, don't autocompletion and other IDE goodies follow?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18663041-6861190172470920176?l=iacobus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/6861190172470920176/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18663041&amp;postID=6861190172470920176' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/6861190172470920176'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/6861190172470920176'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/2007/03/convention-over-configuration-eclipse.html' title='Convention over Configuration == Eclipse IDE completion support for Grails?'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18663041.post-6602138239550955026</id><published>2007-03-06T08:25:00.000-08:00</published><updated>2007-03-06T08:28:40.264-08:00</updated><title type='text'>I are not Stoopid</title><content type='html'>&lt;a href="http://www.stupidtester.com/index.php?im"&gt;&lt;br /&gt;&lt;img alt="StupidTester.com says I'm 4% Stupid! How stupid are you? Click Here!" src="http://www.stupidtester.com/images/stupid.php?val=1e912191018542f7" /&gt;&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;I just wasted a few minutes of my life to fill out the stoopid test, I wonder if that means that their test is a bit faulty??&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18663041-6602138239550955026?l=iacobus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/6602138239550955026/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18663041&amp;postID=6602138239550955026' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/6602138239550955026'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/6602138239550955026'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/2007/03/i-are-not-stoopid.html' title='I are not Stoopid'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18663041.post-2975513204668137046</id><published>2007-02-27T11:53:00.000-08:00</published><updated>2007-03-01T08:38:57.849-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='J2EE'/><category scheme='http://www.blogger.com/atom/ns#' term='WebApps'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='Grails'/><title type='text'>Why dig into Grails?</title><content type='html'>During my time as a C/C++ then Java developer, somehow I have avoided the need to write J2EE web applications. Not web enabled or web services applications, no I have somehow avoided the beast that is J2EE ( not to mention *gasp* EJB ). However the current Web 2.0 ( I read AJAX ) wave has forced me from my comfort zone ( replace 'comfort zone' with Happy Gillmore's 'Happy Place' if you like ).&lt;br /&gt;&lt;br /&gt;*Note: when I read AJAX I read, browser based client side UI programming and not alot of buzzword happy nonsense.&lt;br /&gt;&lt;br /&gt;I have to admit that the current wave of browser based web applications are pretty cool. I love GMail, blogger.com's interface, Google Reader, Google Calendar etc... I don't think of myself as a google fan boy, but that is another topic ( hmm... maybe I should try out 37 signals stuff like backpack ). Another reason that has forced me from my comfort zone is that fact that I have recently been evaluating technologies for my current job and taking a cursory look at the Job market again and I have come to a conclusions of sorts. People out there like these browser based applications. Something about avoid the problems of upgrades, deployment, configuration, licensing, etc... Personally I don't see their point ;) I actually like to ram my head into walls, tables, floors, etc... So I have begun a journey to acquire some of these skills and acquaint myself with those technologies that can enable them.&lt;br /&gt;&lt;br /&gt;A brief aside, I have not been doing monolithic applications for some time now, but it is just that my container of choice is the OSGi Java container that the Eclipse platform is based on. After learning a bit more about the Spring framework and the new Spring OSGi project, I am even more impressed with OSGi as a container and enterprisey platform architecture, but this is a digression from the current topic.&lt;br /&gt;&lt;br /&gt;Before digging into topics like AJAX, I figured I better get more acquainted with the Java Web application world in general. I know that even though frameworks exist to make development easier, but in the end you wind up needing to at least be familiar with what is going on underneath the hood. So I began to get more familiar and see what was out there.&lt;br /&gt;&lt;br /&gt;One more point, before I tried to begin this journey, I have been acquainted with Ruby on Rails (RoR) and its convention over configuration paradigm. "Convention over configuration" is something that I had begun to use in my own work and I immediately saw its advantages over doing everything in an XML configuration file. I was suitably impressed with the ability of RoR to generate scaffolding and allow you to have an up and running web application in minutes. I am a "lazy" ( as in the good way ) kind of person and I don't like to have to perform lots of scaffolding to get get something up. Needless to say, this was something I wanted in a web application platform that I wanted to use.&lt;br /&gt;&lt;br /&gt;So the next obvious question is, "why not use RoR?" Good question. The answer is I am a Java developer that has been working with Java for sometime now and I don't want to have to give up all my experience just to bet it on something new, if there is a viable alternative. Second part of the answer is something I don't like about Java, lack of native integration support with legacy code (JNI (Java Native Interface) is not on my christmas card list). People out there have alot written for J2EE in Java for the web, as far as I know there is no direct way to be able to leverage this legacy stuff directly in RoR. I know that the JRuby folks are getting closer to being able to run RoR through the JVM, but they are not there yet. Even when they do, the code to interact with other Java code can be awkward. This is normal, since Ruby was developed independently and has its own ideas of what a collection, array, type is and it differs at times significantly from Java. So is there a viable alternative? I think so, the Groovy language with Grails.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Groovy&lt;/strong&gt;&lt;br /&gt;Groovy (&lt;a href="http://groovy.codehaus.org/"&gt;http://groovy.codehaus.org/&lt;/a&gt;) is a dynamic scripting language written to be friendly to those of us coming from the statically typed Java world. Just remember that Groovy is Java, just not the Java language. Java is the title of a platform that includes the JVM, libraries and the Java language. Groovy natively sits on top of the JVM and directly uses the Java libraries, so it is a Java platform language. Visit the web site to learn more and I highly recommend the "Groovy In Action" book for you to acquaint yourself with Groovy. Groovy has the great feature of being native to the Java platform and being optionally static. Now what does Grails have to do with Groovy? Simple, Groovy is the language that a Grails application is written in. So you have a choice of learning a new language that has a completely separate syntax than you are used to ( being a Java/C++ developer ) or learn a language that is more of an extension of Java and that has most ( if not all ) the advantages of the other language? Is it really an issue? To me it wasn't, if I could find a web framework like RoR to go with it.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Grails&lt;/strong&gt;&lt;br /&gt;Groovy is all fine and dandy, but it can only do so much to help with writing Web Applications. Ruby without Rails has much the same problem, that is why the Rails framework was created. Grails is the Groovy ( and indeed Java ) world's equivalent to RoR. I have been reading the "Definitive Guide to Grails" and I find the framework very interesting. You have alot of the same advantages of RoR, namely the quick development of a simple web application, standard project structure, support for writing test suites, delineation of environments ( development, production, testing ), support for switching between databases, support for the Model-View-Controller (MVC) pattern, etc... The nice thing about it all is that in the end you have a Java based web application that can be injected directly into a servlet container like Tomcat and will seamlessly interoperate with the other web applications you have already developed.&lt;br /&gt;&lt;br /&gt;For example to create an application in Grails you type, "grails create-app". You enter in the project name and voila, the project and its scaffolding is created for you automatically. Being an Eclipse fanboy (hey if the shoe fits... yup it does...), I like the fact that the grails application scaffolding includes a .project and .classpath file that allows me to directly import the generated grails application directly into Eclipse. The cool thing is that you can type, "grails run-app" from the project directory and you have a Jetty web server up and running your web application. You can open up a web browser and see the results immediately. This is just the sort of thing that got people all excited about RoR. Another great feature is that of dynamic loading. While running your web application in Grails with "grails create-app" you can modify the code of the application and have the results displayed in your browser by just refreshing the page. This is the sort of thing that dynamically typed languages have held over Java all this time. Now Java can have this advantage, enabling quick iterative development. This is the sort of thing that in another context, that of eclipse plugin writing, led me to write the Groovy Monkey tool.&lt;br /&gt;&lt;br /&gt;So I have been sold, hook, line and sinker. I am going to try and write some quick blog entries over the next few days as I continue to learn Grails and highlight my progress and issues.&lt;br /&gt;&lt;br /&gt;*Btw I have no financial interests in Grails or any of the two publications I recommended ( 'Groovy in Action' and 'The Definitive Guide to Grails' ). So take my recommendations with as much salt as you like, but at least know it is not tied to any 'check in the mail' coming to me. *Sigh*&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18663041-2975513204668137046?l=iacobus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/2975513204668137046/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18663041&amp;postID=2975513204668137046' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/2975513204668137046'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/2975513204668137046'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/2007/02/why-dig-into-grails.html' title='Why dig into Grails?'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18663041.post-116863336680553161</id><published>2007-01-12T12:12:00.000-08:00</published><updated>2008-06-08T14:02:30.786-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='GroovyMonkey'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='Monkey'/><title type='text'>Install Eclipse Update Sites through a Firewall</title><content type='html'>&lt;pre&gt;&lt;span style="font-family:Georgia;"&gt;&lt;/span&gt;&lt;br /&gt;--- Came wiffling through the eclipsey wood ---&lt;br /&gt;/*&lt;br /&gt; * Menu: Download &gt; Update Site&lt;br /&gt; * Script-Path: /GroovyWebUtil/monkey/UpdateSiteDownload.em&lt;br /&gt; * Kudos: ERVIN&lt;br /&gt; * License: EPL 1.0&lt;br /&gt; * Include: /GroovyWebUtil/commons-codec-1.3.jar&lt;br /&gt; * Include: /GroovyWebUtil/commons-httpclient-3.0.1.jar&lt;br /&gt; * Include: /GroovyWebUtil/commons-logging-1.0.3.jar&lt;br /&gt; * Include-Bundle: org.apache.ant&lt;br /&gt; */&lt;br /&gt;&lt;br /&gt;import java.io.*&lt;br /&gt;import java.net.*&lt;br /&gt;import org.apache.commons.httpclient.*&lt;br /&gt;import org.apache.commons.httpclient.auth.*&lt;br /&gt;import org.apache.commons.httpclient.methods.*&lt;br /&gt;import org.apache.commons.io.*&lt;br /&gt;import org.apache.commons.lang.*&lt;br /&gt;import org.eclipse.core.resources.*&lt;br /&gt;import org.eclipse.core.runtime.*&lt;br /&gt;&lt;br /&gt;// Set these following 8 parameters&lt;br /&gt;def featureName = 'GroovyEclipsePlugin'&lt;br /&gt;def baseURL = 'http://dist.codehaus.org/groovy/distributions/update/'&lt;br /&gt;def siteURL = baseURL + 'site.xml'&lt;br /&gt;def baseDir = 'c:/plugins/' + featureName + '/eclipse/'&lt;br /&gt;&lt;br /&gt;def proxyHost = 'xxxx'&lt;br /&gt;def proxyPort = xx&lt;br /&gt;def proxyUser = 'xxxx'&lt;br /&gt;def proxyPassword = 'xxxx'&lt;br /&gt;&lt;br /&gt;def client = new HttpClient()&lt;br /&gt;client.params.setParameter( CredentialsProvider.PROVIDER, this )&lt;br /&gt;client.hostConfiguration.setProxy( proxyHost, proxyPort )&lt;br /&gt;&lt;br /&gt;FileUtils.forceMkdir( new File( baseDir ) )&lt;br /&gt;FileUtils.touch( new File( baseDir + '.eclipseextension' ) )&lt;br /&gt;&lt;br /&gt;def method = new GetMethod( siteURL )&lt;br /&gt;client.executeMethod( method )&lt;br /&gt;&lt;br /&gt;out.println 'status: ' + method.statusText + ' -&gt; ' + siteURL&lt;br /&gt;&lt;br /&gt;def input = method.responseBodyAsStream&lt;br /&gt;def siteXML = new XmlSlurper().parse( input )&lt;br /&gt;def features = siteXML.feature&lt;br /&gt;def featureURLs = [ : ]&lt;br /&gt;def versionMap = [ : ]&lt;br /&gt;features.each&lt;br /&gt;{ feature -&gt;&lt;br /&gt; if( !versionMap.containsKey( feature.@id.text() ) )&lt;br /&gt;  versionMap[ feature.@id.text() ] = feature.@version.text()&lt;br /&gt; if( versionMap[ feature.@id.text() ].compareTo( feature.@version.text() ) &gt; 0 )&lt;br /&gt;  return&lt;br /&gt; featureURLs[ feature.@id.text() ] = feature.@url&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;def ant = new AntBuilder()&lt;br /&gt;&lt;br /&gt;def plugins = []&lt;br /&gt;featureURLs.values().each&lt;br /&gt;{ featureURL -&gt;&lt;br /&gt; if( monitor.isCanceled() )&lt;br /&gt;  return&lt;br /&gt; def newURL = new URL( baseURL + featureURL )&lt;br /&gt; def featureFile = baseDir + featureURL&lt;br /&gt; def destDir = StringUtils.substringBeforeLast( featureFile, '.' )&lt;br /&gt; FileUtils.forceMkdir( new File( destDir ) )&lt;br /&gt; FileUtils.copyURLToFile( newURL, new File( featureFile ) )&lt;br /&gt; ant.unzip( src: featureFile, dest: destDir )&lt;br /&gt; ant.delete( file: featureFile )&lt;br /&gt; def featureXMLText = new File( destDir + '/feature.xml' ).text&lt;br /&gt; def featureXML = new XmlSlurper().parseText( featureXMLText )&lt;br /&gt; featureXML.plugin.depthFirst().collect{ plugins.add( it ) }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;monitor.beginTask( 'Starting downloads', plugins.size() + 1 )&lt;br /&gt;plugins.each&lt;br /&gt;{ plugin -&gt;&lt;br /&gt; if( monitor.isCanceled() )&lt;br /&gt;  return&lt;br /&gt; def pluginJar = "${plugin.@id}_${plugin.@version}.jar"&lt;br /&gt; def newURL = new URL( baseURL + 'plugins/' + pluginJar )&lt;br /&gt; def pluginFile = baseDir + 'plugins/' + pluginJar&lt;br /&gt; def destDir = StringUtils.substringBeforeLast( pluginFile, '.' )&lt;br /&gt; FileUtils.forceMkdir( new File( destDir ) )&lt;br /&gt; if( new File( pluginFile ).exists() )&lt;br /&gt;  return&lt;br /&gt; FileUtils.copyURLToFile( newURL, new File( pluginFile ) )&lt;br /&gt; if( plugin.@unpack.text().trim().toLowerCase() != 'false' )&lt;br /&gt; {&lt;br /&gt;  ant.unzip( src: pluginFile, dest: destDir )&lt;br /&gt;  ant.delete( file: pluginFile )&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;--- And burbled as it ran! ---&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  --- Came wiffling through the eclipsey wood ---&lt;br /&gt;  /*&lt;br /&gt;   * Menu: Download &gt; Update Site&lt;br /&gt;   * Script-Path: /GroovyMonkeyScripts/monkey/UpdateSiteDownload.gm&lt;br /&gt;   * Kudos: ERVIN&lt;br /&gt;   * License: EPL 1.0&lt;br /&gt;   * DOM: http://groovy-monkey.sourceforge.net/update/plugins/net.sf.groovyMonkey.dom&lt;br /&gt;   * Include: /GroovyMonkeyScripts/commons-codec-1.3.jar&lt;br /&gt;   * Include: /GroovyMonkeyScripts/commons-httpclient-3.0.1.jar&lt;br /&gt;   * Include: /GroovyMonkeyScripts/commons-logging-1.1.jar&lt;br /&gt;   * Include-Bundle: org.apache.ant&lt;br /&gt;   */&lt;br /&gt;  &lt;br /&gt;  import java.io.*&lt;br /&gt;  import java.net.*&lt;br /&gt;  import org.apache.commons.httpclient.*&lt;br /&gt;  import org.apache.commons.httpclient.auth.*&lt;br /&gt;  import org.apache.commons.httpclient.methods.*&lt;br /&gt;  import org.apache.commons.io.*&lt;br /&gt;  import org.apache.commons.lang.*&lt;br /&gt;  import org.eclipse.core.resources.*&lt;br /&gt;  import org.eclipse.core.runtime.*&lt;br /&gt;  &lt;br /&gt;  // Set these following 8 parameters&lt;br /&gt;  def featureName = 'GroovyEclipsePlugin'&lt;br /&gt;  def baseURL = 'http://dist.codehaus.org/groovy/distributions/update/'&lt;br /&gt;  def siteURL = baseURL + 'site.xml'&lt;br /&gt;  def baseDir = 'c:/plugins/' + featureName + '/eclipse/'&lt;br /&gt;  &lt;br /&gt;  def proxyHost = 'xxxx'&lt;br /&gt;  def proxyPort = xx&lt;br /&gt;  def proxyUser = 'xxxx'&lt;br /&gt;  def proxyPassword = 'xxxx'&lt;br /&gt;&lt;br /&gt;  def client = new HttpClient()&lt;br /&gt;  client.params.setParameter( CredentialsProvider.PROVIDER, this )&lt;br /&gt;  client.hostConfiguration.setProxy( proxyHost, proxyPort )&lt;br /&gt;&lt;br /&gt;  FileUtils.forceMkdir( new File( baseDir ) )&lt;br /&gt;  FileUtils.touch( new File( baseDir + '.eclipseextension' ) )&lt;br /&gt;  def method = new GetMethod( siteURL )&lt;br /&gt;  client.executeMethod( method )&lt;br /&gt;  out.println 'status: ' + method.statusText + ' -&gt; ' + siteURL&lt;br /&gt;  &lt;br /&gt;  def input = method.responseBodyAsStream&lt;br /&gt;  def siteXML = new XmlSlurper().parse( input )&lt;br /&gt;  def features = siteXML.feature&lt;br /&gt;  def featureURLs = [ : ]&lt;br /&gt;  def versionMap = [ : ]&lt;br /&gt;  features.each&lt;br /&gt;  { feature -&gt;&lt;br /&gt;    if( !versionMap.containsKey( feature.@id.text() ) )&lt;br /&gt;      versionMap[ feature.@id.text() ] = feature.@version.text()&lt;br /&gt;    if( versionMap[ feature.@id.text() ].compareTo( feature.@version.text() ) &gt; 0 )&lt;br /&gt;      return&lt;br /&gt;    featureURLs[ feature.@id.text() ] = feature.@url&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  def ant = new AntBuilder()&lt;br /&gt;  def plugins = []&lt;br /&gt;  featureURLs.values().each&lt;br /&gt;  { featureURL -&gt;&lt;br /&gt;    if( monitor.isCanceled() )&lt;br /&gt;      return&lt;br /&gt;    def newURL = new URL( baseURL + featureURL )&lt;br /&gt;    def featureFile = baseDir + featureURL&lt;br /&gt;    def destDir = StringUtils.substringBeforeLast( featureFile, '.' )&lt;br /&gt;    FileUtils.forceMkdir( new File( destDir ) )&lt;br /&gt;    FileUtils.copyURLToFile( newURL, new File( featureFile ) )&lt;br /&gt;    ant.unzip( src: featureFile, dest: destDir )&lt;br /&gt;    ant.delete( file: featureFile )&lt;br /&gt;    def featureXMLText = new File( destDir + '/feature.xml' ).text&lt;br /&gt;    def featureXML = new XmlSlurper().parseText( featureXMLText )&lt;br /&gt;    featureXML.plugin.depthFirst().collect{ plugins.add( it ) }&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  monitor.beginTask( 'Starting downloads', plugins.size() + 1 )&lt;br /&gt;  plugins.each&lt;br /&gt;  { plugin -&gt;&lt;br /&gt;    if( monitor.isCanceled() )&lt;br /&gt;      return&lt;br /&gt;    def pluginJar = "${plugin.@id}_${plugin.@version}.jar"&lt;br /&gt;    def newURL = new URL( baseURL + 'plugins/' + pluginJar )&lt;br /&gt;    def pluginFile = baseDir + 'plugins/' + pluginJar&lt;br /&gt;    def destDir = StringUtils.substringBeforeLast( pluginFile, '.' )&lt;br /&gt;    if( new File( pluginFile ).exists() )&lt;br /&gt;      return&lt;br /&gt;    FileUtils.copyURLToFile( newURL, new File( pluginFile ) )&lt;br /&gt;    out.println "${plugin.@id}: unpack=${plugin.@unpack.text()}"&lt;br /&gt;    if( plugin.@unpack.text().trim().toLowerCase() == 'false' )&lt;br /&gt;     return&lt;br /&gt;    FileUtils.forceMkdir( new File( destDir ) )&lt;br /&gt;   ant.unzip( src: pluginFile, dest: destDir )&lt;br /&gt;   ant.delete( file: pluginFile )&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  --- And burbled as it ran! ---&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Want to be able to download eclipse plugins, but the firewall wont let you?&lt;br /&gt;&lt;br /&gt;Having trouble getting the eclipse update mechanism to tunnel through the firewall, but port 80 is open through http?&lt;br /&gt;&lt;br /&gt;If you have Groovy Monkey installed and include the commons-codec-1.3.jar, commons-httpclient-3.0.1.jar and commons-logging-1.0.3.jar libraries in your workspace, use the script above. Define the 8 parameters and the script should download the update package from the url that the update manager should connect to. The script then packages it as the appropriate set of plugins ( zipped or unzipped ) based on the feature.xml and then deploys it to a directory that you can define and creates an extension location that Eclipse can directly import.&lt;br /&gt;&lt;br /&gt;In the script above I downloaded the Groovy Eclipse plugin from the update site and had it packaged into the /plugins/GroovyEclipse/eclipse directory as an extension location. I like to separate my plugins like this. The last step is after the script runs successfully goto "Help -&gt; Software Updates -&gt; Manage Configuration" and open the manage configuration dialog. Right click on the root node "Eclipse SDK" and select "Add -&gt; Extension Location". Navigate to the location where the plugin was installed, in the above case /plugins/GroovyEclipse/eclipse, and then click ok. Eclipse will install the plugin and probably ask to restart. You are done...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18663041-116863336680553161?l=iacobus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/116863336680553161/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18663041&amp;postID=116863336680553161' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/116863336680553161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/116863336680553161'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/2007/01/install-eclipse-update-sites-through.html' title='Install Eclipse Update Sites through a Firewall'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18663041.post-116716688621333393</id><published>2006-12-26T12:59:00.000-08:00</published><updated>2007-03-01T08:40:22.768-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='GroovyMonkey'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><title type='text'>Version 0.4.0 is released</title><content type='html'>I have released the latest version of Groovy Monkey with the following new features:&lt;br /&gt;&lt;h3&gt;Version 0.4.0 - December 24, 2006&lt;/h3&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Added autocomplete for binding variables.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Added method autocompletion for bound variables.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Now can publish to clipboard directly from the editor.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Added a "Save Script To" dialog to allow the user to select where in their workspace they want the script written.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;I am also in the process of merging Groovy Monkey with the original Eclipse Monkey, so future work maybe accomplished over there.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18663041-116716688621333393?l=iacobus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/116716688621333393/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18663041&amp;postID=116716688621333393' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/116716688621333393'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/116716688621333393'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/2006/12/version-040-is-released.html' title='Version 0.4.0 is released'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18663041.post-116654701086390326</id><published>2006-12-19T08:40:00.000-08:00</published><updated>2007-03-01T08:40:48.428-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='GroovyMonkey'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><title type='text'>Quickly remove unwanted markers in your workspace.</title><content type='html'>I have been asked, "Groovy Monkey why?"  Now there are the default answers of API exploration, Eclipse Automation and rapid prototyping, however, now I have a new one: "You think someone will bother to write a plugin to do that?"  The following example highlights this feature.&lt;br /&gt;&lt;br /&gt;Here is a quick script written whilest I was debugging the Groovy Eclipse Plugin.  The problem I had was that the plugin left some markers lying around that I don't want to see anymore.  &lt;br /&gt;&lt;br /&gt;So you can use this script to parse through your Eclipse workspace and find all the problem markers and then choose to delete those that don't apply anymore.  I think it is pretty useful when you are working on plugins or if you downloaded a particularly buggy plugin.  Sure does beat shutting down Eclipse, then opening up the $workspace/.metadata/org.eclipse.core.resources/.projects/$projectname/ and then manually deleting any .markers files you find.&lt;br /&gt;&lt;br /&gt;To import the script into Eclipse follow the following steps.  &lt;br /&gt;First you must have installed Groovy Monkey. &lt;br /&gt;&lt;br /&gt;Secondly, then you must select all the text below ( starting with '--- Came wiffling...' and copy it into your clipboard on your browser (Ctrl-C usually works).  &lt;br /&gt;&lt;br /&gt;Now goto eclipse and under the Groovy Monkey menu select 'Paste New Script'.&lt;br /&gt;&lt;br /&gt;Voila it will be incorporated into your workspace and can be run as 'Groovy Monkey &gt; Remove Markers'.  Enjoy.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;--- Came wiffling through the eclipsey wood ---&lt;br /&gt;/*&lt;br /&gt; * Menu: Remove Markers&lt;br /&gt; * Script-Path: /GroovyMonkeyScripts/monkey/removeMarkers.gm&lt;br /&gt; * Kudos: ERVIN&lt;br /&gt; * License: EPL 1.0&lt;br /&gt; * DOM: http://groovy-monkey.sourceforge.net/update/plugins/net.sf.groovyMonkey.dom&lt;br /&gt; */&lt;br /&gt;import org.eclipse.core.resources.*&lt;br /&gt;&lt;br /&gt;out.clear()&lt;br /&gt;workspace.root.projects.each&lt;br /&gt;{ project -&gt;&lt;br /&gt; out.println "${project.name}"&lt;br /&gt; project.findMarkers( null, true, IResource.DEPTH_INFINITE ).each&lt;br /&gt; { marker -&gt;&lt;br /&gt;  out.println "  ** ${marker.type} ${marker.id} ${marker.attributes}"&lt;br /&gt;  if( marker.type == 'org.codehaus.groovy.eclipse.groovyFailure' )&lt;br /&gt;   marker.delete()&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;--- And burbled as it ran! ---&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18663041-116654701086390326?l=iacobus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/116654701086390326/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18663041&amp;postID=116654701086390326' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/116654701086390326'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/116654701086390326'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/2006/12/quickly-remove-unwanted-markers-in.html' title='Quickly remove unwanted markers in your workspace.'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18663041.post-115800120143316170</id><published>2006-09-11T11:56:00.000-07:00</published><updated>2007-03-01T08:41:15.469-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='GroovyMonkey'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><title type='text'>Version 0.3.0 of Groovy Monkey released</title><content type='html'>I am just putting all the packaging in place for the latest version of Groovy Monkey, version 0.3.0.  By the way, I am not putting a whole lot of meaning behind the version numbers, 0.2.0 was chosen before since it was originally a port of Eclipse Monkey and it was at version 0.1.5 or something.  The following is noteworthy:&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Version 0.3.0 - September 11, 2006&lt;/h3&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Changed the Groovy Monkey default project name to GroovyMonkeyScripts as per issue: [ 1536760 ] Change GroovyMonkeyExamples to GroovyMonkeyScripts&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Added an Include-Bundle dialog to the editor context menu, to the Package Explorer view and Navigator.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Added Include and Include-Bundle dialogs to Groovy Editor context menu command set.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Added a Java search, modeled on the PDE search, to the outline view to look for all the classes exposed from an included bundle in the set of exported packages.  So if your 'External Plug-in Libraries' project is setup, you should see the classes.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Added a Script-Path: metadata tag that is automatically maintained by Groovy Monkey, it is set to the workspace path of the script.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The Script Outline view now has menu commands to switch between Flat/Hierarchical views of the binding.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;There are now error markers signifying some command errors with script metadata and some quick fixes to assist.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;There is now some content assist on the Script Metadata tags.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;A new submenu of the top level 'Groovy Monkey' has been added called 'Edit Script'.  The Edit Script submenu reflects the top menu, but instead of launching the scripts, it opens the editor for you.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Added Hippie completion to the editor.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Added ability to map dom vars to different names for the local script, enables solution for variable name conflicts between DOM plugins.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18663041-115800120143316170?l=iacobus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/115800120143316170/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18663041&amp;postID=115800120143316170' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/115800120143316170'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/115800120143316170'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/2006/09/version-030-of-groovy-monkey-released.html' title='Version 0.3.0 of Groovy Monkey released'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18663041.post-115505593730979418</id><published>2006-08-08T09:32:00.000-07:00</published><updated>2007-03-01T08:30:37.780-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='GroovyMonkey'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><title type='text'>Groovy Monkey: Eclipse Icons Script Pt 4/4: Rapid Prototyping with DOM Plugins</title><content type='html'>In the first and second postings of this series I showed how to implement a script that checks out the icons folders from all of the Eclipse Projects from the CVS server at dev.eclipse.org. The third installment had to do with breaking up and using library scripts through the Runner DOM to create code reuse and refactoring. This installment will now attempt to do what the third did, but with a prototype DOM plugin developed right in the workspace of your current Eclipse instance. The part I think that is exciting is that we will write a plugin and then use some simple Groovy Monkey scripts to dynamically update the DOM from within the current running Eclipse instance without restarting the workbench. Before I continue, one note of caution, this is still a bit of a work in progress. The plugins that will be dynamically swapped out are the simple type that you would use as a DOM and shouldn't contain much in the way of state, unless you are going through the trouble to make sure that you can hotswap out your plugins. The subject of how to make your plugins hotswappable is a whole subject onto itself, so we are going to sidestep it by keeping the DOM plugins simple.&lt;br /&gt;&lt;br /&gt;This article is going to take you step by step through an example using the getEclipseIcons.gm script that was developed in previous articles in this series and the IncludeLocalBundle PDE JUnit test case that I wrote in net.sf.groovyMonkey.tests.&lt;br /&gt;&lt;br /&gt;So to begin lets start with the example script that was created before we modified it to use library scripts in the last posting.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;--- Came wiffling through the eclipsey wood ---&lt;br /&gt;/*&lt;br /&gt;* Menu: Get Eclipse Icons&lt;br /&gt;* Kudos: ervinja&lt;br /&gt;* License: EPL 1.0&lt;br /&gt;* DOM: http://groovy-monkey.sourceforge.net/update/plugins/net.sf.groovyMonkey.dom&lt;br /&gt;* Include-Bundle: org.eclipse.team.cvs.core&lt;br /&gt;* Include-Bundle: org.eclipse.team.cvs.ui&lt;br /&gt;*/&lt;br /&gt;import org.eclipse.core.resources.IProject&lt;br /&gt;import org.eclipse.core.resources.IResource&lt;br /&gt;import org.eclipse.core.runtime.SubProgressMonitor&lt;br /&gt;import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin&lt;br /&gt;import org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder&lt;br /&gt;import org.eclipse.team.internal.ccvs.ui.operations.CheckoutIntoOperation&lt;br /&gt;import org.eclipse.team.internal.ccvs.ui.operations.DisconnectOperation&lt;br /&gt;&lt;br /&gt;// Here we find the desired repository location that has already been configured&lt;br /&gt;//  in the CVS Respository Explorer.&lt;br /&gt;def plugin = CVSProviderPlugin.getPlugin()&lt;br /&gt;def repositoryLoc&lt;br /&gt;for( location in plugin.getKnownRepositories() )&lt;br /&gt;{&lt;br /&gt;     if( monitor.isCanceled() )&lt;br /&gt;                return&lt;br /&gt;        if( location.getRootDirectory() == '/home/eclipse' )&lt;br /&gt;                repositoryLoc = location&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Here we query all the remote repository top level projects for sub-folders&lt;br /&gt;//  called icons and then store them into a list for later use.&lt;br /&gt;def members = repositoryLoc.members( null, false, null )&lt;br /&gt;monitor.beginTask( '', 2 * members.size() )&lt;br /&gt;def iconFolders = []&lt;br /&gt;for( member in members )&lt;br /&gt;{&lt;br /&gt;    member.fetchChildren()&lt;br /&gt;    if( monitor.isCanceled() )&lt;br /&gt;               return&lt;br /&gt;    if( !member.childExists( 'icons' ) )&lt;br /&gt;    {&lt;br /&gt;        monitor.worked( 1 )&lt;br /&gt;               continue&lt;br /&gt;    }&lt;br /&gt;       def icons = member.getFolder( 'icons' )&lt;br /&gt;    iconFolders.add( icons )&lt;br /&gt;    monitor.worked( 1 )&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Check out those icon folders under a sub-folder of the target project called&lt;br /&gt;//  icons and place each remote icon folder in a sub-folder of icons that corresponds&lt;br /&gt;//  to its project name.&lt;br /&gt;def targetProject = workspace.getRoot().getProject( 'GroovyMonkeyExamples' )&lt;br /&gt;iconFolders.each&lt;br /&gt;{ folder -&gt;&lt;br /&gt;    if( monitor.isCanceled() )&lt;br /&gt;        return&lt;br /&gt;        def targetFolder = targetProject.getFolder( 'icons' ).getFolder( folder.getRemoteParent().getRepositoryRelativePath() )&lt;br /&gt;    new CheckoutIntoOperation( null, folder, targetFolder, true ).execute( new SubProgressMonitor( monitor, 1 ) )&lt;br /&gt;    monitor.worked( 1 )&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Clear off the CVS cruft.&lt;br /&gt;jface.syncExec&lt;br /&gt;{&lt;br /&gt;        new DisconnectOperation( null, [ targetProject ].toArray( new IProject[0] ), true ).run()&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Build the eclipse-icons.zip file using AntBuilder&lt;br /&gt;def baseDir = targetProject.getFolder( 'icons' )&lt;br /&gt;def destFile = targetProject.getFile( 'eclipse-icons.zip' )&lt;br /&gt;if( destFile.exists() )&lt;br /&gt;        destFile.delete( true, null )&lt;br /&gt;&lt;br /&gt;def ant = new AntBuilder()&lt;br /&gt;ant.zip( basedir:"${baseDir.getRawLocation()}", destfile:"${destFile.getRawLocation()}" )&lt;br /&gt;&lt;br /&gt;// Refresh the targetProject so that eclipse-icons.zip shows up in the Navigator and Package Explorer.&lt;br /&gt;targetProject.refreshLocal( IResource.DEPTH_INFINITE, null )&lt;br /&gt;&lt;br /&gt;monitor.done()&lt;br /&gt;--- And burbled as it ran! ---&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;We want to create a DOM that can wrap calls to Eclipse's CVS API and provide a simplified interface for our scripts. One definite advantage to doing this is that we can develop the DOM plugin using the PDE and all of the wonderous advantages of the JDT Editor like autocompletion and the like. Another is that while the Runner DOM is useful, there is nothing like being able to make a direct method call on an object for clarity.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Setup DOM Plugin Project: net.sf.groovyMonkey.dom.cvs&lt;/h4&gt;&lt;br /&gt;The first step is that we need an Eclipse Project in our workspace in which to begin work on this new DOM. Of course this is a plugin project, so we use the 'New Plug-in Project' wizard. I name this project net.sf.groovyMonkey.dom.cvs since I am working on Groovy Monkey projects, however, you can name it whatever you like. I use all the default settings and avoid using the templates since Groovy Monkey does not have a wizard for creating a DOM Plugin Project. Of course, there is nothing that says that your DOM cannot have UI elements and therefore you might choose to use a template for your project, but at this time I am electing for simplicity.&lt;br /&gt;&lt;br /&gt;After we have our project in the workspace, we must do some configuration work.&lt;br /&gt;&lt;br /&gt;First make your plugin depend upon the net.sf.groovyMonkey plugin project by opening the Manifest editor and adding it to the list of required plugins.&lt;br /&gt;&lt;br /&gt;Second add an extension of the extension point net.sf.groovyMonkey.dom using the Extensions page of the Manifest editor. Right click the net.sf.groovyMonkey.dom extension in the view and select 'New &gt; updateSite'. This is what is used to display your DOM in the Outline view of the Groovy Monkey editor and the InstalledDOMs view. If you don't know exactly what it should be yet, this is fine, just select something that is likely to make sense. In my case I put in 'http://groovy-monkey.sourceforge.net/update/net.sf.groovyMonkey.dom.cvsdom'. To be honest I have yet to really use update sites to update my DOM plugins, so don't be surprised if it does not quite work. I tend to use the DOM plugins in my workspace and also have a default set of doms that come with Groovy Monkey included. If you try and it does/doesn't work, drop me a line ( jervin@completecomputing.com ) and let me know the results. As you will see from what follows, it may not be completely necessary.&lt;br /&gt;&lt;br /&gt;Next right click the net.sf.groovyMonkey.dom node again and this time select 'New &gt; dom'. Under this new node you see a few fields to fill in and we will go through them one by one.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The first field is variableName and it is required. The variableName field is the name under which your dom will be put in the scripts binding, so it is important to select something easy to type and more importantly a name that is relatively unique. I know that the uniqueness part is a bit tricky and perhaps this is something that could use a tool to enhance or help. At the very least a warning in the Error Log that Eclipse has a DOM Plugins that define variables of the same name. Of course conflicting names may not be a problem if your scripts do not reference the DOMs with the same variable name. In this case I use cvsDOM. I am using the DOM postfix convention, so as to hopefully leave the binding and the script namespace relatively clean. Even if you should override the variable name inside your script's scope, you can use the bsf ( never override ) variable to access the BSFFunctions class which can allow you to look up the bound object by name.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The next field specifies the class that will implement the IMonkeyDOMFactory interface to create instances of the DOM objects that the script will use. I click the class link and use the wizard to create a class called DOMFactory in the net.sf.groovymonkey.dom.cvsdom package that implements IMonkeyDOMFactory. I am not using a name like CVSDOMFactory since I think that the package that it exists in is obvious enough and I am not going to put another DOM object in that package, for now at least.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The next field called 'id' is an optional field where you can put a human friendly name on this DOM, I think 'CVS DOM' is friendly enough.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Finally there is the optional field called 'resource' and it is used to have you enter in the full class name of the object that the DOM Factory is supposed to return in the method getDOMRoot(). This field is preferred by the Groovy Monkey Outline page to assist the user in knowing what types and methods they have available. So it is highly recommended that you set it, since otherwise the Outline page content provider will call getDOMRoot() and perform reflection on it to determine what is being returned. It is kind of hard to know what to put in there before we create it, so we leave it blank for now.&lt;/li&gt;&lt;/ol&gt;Now we have the class DOMFactory that has a constructor and a method called getDOMRoot(). It is probably best practice to not do too much in the constructor and indeed in this class in general, since it could be instanciated numberous times and getDOMRoot() could be invoked a number of times from outside the context of the script. One thing though, do not return null from the getDOMRoot() method. So to make life easier on me, I create the class net.sf.groovymonkey.dom.cvs.CVSDOM and have the getDOMRoot() method just return a new instance of this class. Now that we have the type, go back to the manifest editor and put in that value into the resource field. Believe it or not we are now done with both the manifest editor and the DOM Factory class. This is all the scaffolding that is needed to put a DOM from a plugin into Groovy Monkey. Groovy Monkey searches for all net.sf.groovyMonkey.dom extensions and then grabs all the information we provided. You could in fact already use this as a plugin for your Eclipse workbench, of course the DOM object doesn't do anything yet, but that is beside the point, right? ;) You could use self hosting and make sure that the Groovy Monkey plugins are used in the runtime instance and check it out for yourself, but that is alot of trouble no and I said I will show you how to do it without headaches.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Setup Project to be loaded at will in current Eclipse Workspace&lt;/h4&gt;&lt;br /&gt;I just made a strong claim, that you can already install this DOM in your workbench and use it. It is an even stronger claim given that I made the promise that I will show you how to do it dynamically and without restarting your workbench and without having to spawn a self hosted runtime workbench instance. To make this promise come true, we are going to have to do a few things.&lt;br /&gt;&lt;br /&gt;1. Create a monkey folder, for a script I am going to provide, under the project, in my case net.sf.groovyMonkey.dom.cvs.&lt;br /&gt;2. Create a lib folder for the library scripts I am going to provide.&lt;br /&gt;3. Copy the following script into your clipboard and use the 'Groovy Monkey &gt; Paste New Script' menu command to put it into your workspace. You are going to have to move it to your project under the monkey folder manually, perhaps there is an opportunity for an enhancement here. I put in under my net.sf.groovyMonkey.dom.cvs project under the monkey folder and called it installDOM.gm.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;--- Came wiffling through the eclipsey wood ---&lt;br /&gt;/*&lt;br /&gt; * Menu: Install/Update &gt; CVS DOM&lt;br /&gt; * Kudos: James E. Ervin&lt;br /&gt; * License: EPL 1.0&lt;br /&gt; * DOM: http://groovy-monkey.sourceforge.net/update/net.sf.groovyMonkey.dom&lt;br /&gt; */&lt;br /&gt;import java.io.File&lt;br /&gt;import org.apache.commons.io.FileUtils&lt;br /&gt;&lt;br /&gt;def plugin = 'net.sf.groovyMonkey.dom.cvs'&lt;br /&gt;&lt;br /&gt;// If this bundle is already installed, remove it&lt;br /&gt;runnerDOM.runScript( "${plugin}/lib/uninstall.gm", [ pluginToUninstall:plugin ] )&lt;br /&gt;&lt;br /&gt;// Build and export the bundle jar&lt;br /&gt;bundlerDOM.createDeployDir()&lt;br /&gt;jface.syncExec&lt;br /&gt;{&lt;br /&gt;    bundlerDOM.buildPluginJar( workspace.getRoot().getProject( plugin ) )&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Grab the current version of the plugin to be able to identify the jar file.&lt;br /&gt;def bundleVersion = runnerDOM.runScript( "${plugin}/lib/getBundleVersion.gm", [ 'plugin':plugin ] )&lt;br /&gt;&lt;br /&gt;// Install and start the new bundle.&lt;br /&gt;def context = bundleDOM.context()&lt;br /&gt;def installedBundle = context.installBundle( "file:" + bundlerDOM.getDeployDir() + "/plugins/" + plugin + "_" + bundleVersion + ".jar" )&lt;br /&gt;installedBundle.start()&lt;br /&gt;&lt;br /&gt;--- And burbled as it ran! ---&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;* Note: If you are not calling your project 'net.sf.groovyMonkey.dom.cvs' remember to change the plugin variable above to the correct project name.&lt;br /&gt;** Note: Be real careful with bunderDOM. By default it wants to deploy plugins to '/tmp/deployedBundles/plugins' and will want to delete and recreate the directory each time you call createDeployDir() on it. I forgot about this and set the deploy dir to my eclipse install plugins directory and *really* regretted it.&lt;br /&gt;*** Note: When you restart eclipse, since the path '/tmp/deployedBundles' is not an Eclipse Extension Location, it be loaded when eclipse is restarted. I think while you are developing a DOM plugin this could be a feature, however, if you want it to persist just copy it from the deploy directory ( default: '/tmp/deployedBundles/plugins' ) to an Eclipse Extension Location or easier yet, into your Eclipse Install plugins directory.&lt;br /&gt;&lt;br /&gt;4. Copy the following script into the clipboard and use the 'Groovy Monkey &gt; Paste New Script' menu command to place it into your workspace. Once again move it manually into the project under the lib folder. There is a difference here, since the script above makes a call on it by directly referencing it as uninstall.gm, it is important you name it as such or you go back and change the installDOM.gm script to refer to the correct library script. I put it into my net.sf.groovyMonkey.dom.cvs project under lib and with the name uninstall.gm.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;--- Came wiffling through the eclipsey wood ---&lt;br /&gt;/*&lt;br /&gt; * Kudos: James E. Ervin&lt;br /&gt; * License: EPL 1.0&lt;br /&gt; * DOM: http://groovy-monkey.sourceforge.net/update/net.sf.groovyMonkey.dom&lt;br /&gt; */&lt;br /&gt;import org.apache.commons.lang.Validate&lt;br /&gt;&lt;br /&gt;Validate.notNull( bsf.lookupBean( 'pluginToUninstall' ), 'pluginToUninstall must be set' )&lt;br /&gt;&lt;br /&gt;for( plugin in bundleDOM.context().getBundles() )&lt;br /&gt;{&lt;br /&gt;    if( plugin.getSymbolicName().equals( pluginToUninstall ) )&lt;br /&gt;        plugin.uninstall()&lt;br /&gt;}&lt;br /&gt;--- And burbled as it ran! ---&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;5. Once again copy the following script into the clipboard and use the 'Groovy Monkey &gt; Paste New Script' menu command to place it into your workspace. Move it manually into the project under the lib folder. Since the main script makes a call on it by directly referencing it as getBundleVersion.gm, it is important you name it as such or you go back and change the installDOM.gm script to refer to the correct library script. I put it into my net.sf.groovyMonkey.dom.cvs project under lib and with the name getBundleVersion.gm.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;--- Came wiffling through the eclipsey wood ---&lt;br /&gt;/*&lt;br /&gt; * Kudos: James E. Ervin&lt;br /&gt; * License: EPL 1.0&lt;br /&gt; * DOM: http://groovy-monkey.sourceforge.net/update/net.sf.groovyMonkey.dom&lt;br /&gt; */&lt;br /&gt;import java.util.jar.Manifest&lt;br /&gt;import org.apache.commons.lang.Validate&lt;br /&gt;&lt;br /&gt;Validate.notNull( bsf.lookupBean( 'plugin' ), 'plugin must be set' )&lt;br /&gt;&lt;br /&gt;def file = workspace.getRoot().getProject( plugin ).getFile( 'META-INF/MANIFEST.MF' )&lt;br /&gt;def input = file.getContents()&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;    def manifest = new Manifest( input )&lt;br /&gt;    def attributes = manifest.getMainAttributes()&lt;br /&gt;    return attributes.getValue( 'Bundle-Version' )&lt;br /&gt;}&lt;br /&gt;finally&lt;br /&gt;{&lt;br /&gt;    input.close()&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;--- And burbled as it ran! ---&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;6. Just to be able to show that it works as expected, bring up the 'Installed DOMs' view by 'Window &gt; Show View &gt; Other &gt; Groovy Monkey &gt; Installed DOMs'. Look at the list, unless you have done some other work before following this script, it should not include an entry for your project, in my case no net.sf.groovyMonkey.dom.cvs DOM plugin installed.&lt;br /&gt;&lt;br /&gt;Run the script installDOM.gm either by right click menu command 'Run Script' from the Groovy Monkey Editor or by 'Groovy Monkey &gt; Install &gt; CVS DOM'. Now go back to the 'Installed DOMs' view and it should be there. Go ahead and write a quick script to check it out if you like, of course we haven't added anything to it yet.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Start work on CVS DOM object&lt;/h4&gt;&lt;br /&gt;Well the initial idea is to replace sections of the original getEclipseIcons.gm script with method calls on this new CVS DOM object. So lets add a method called getKnownRepository that takes the arguments of the script that we used to refactor the script in the last article. To accomplish this we will have to add org.eclipse.team.cvs.core bundle as a Required Plug-in in the manifest editor. The code is as follows:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package net.sf.groovymonkey.dom.cvsdom;&lt;br /&gt;import static org.eclipse.team.internal.ccvs.core.CVSProviderPlugin.getPlugin;&lt;br /&gt;import org.eclipse.team.internal.ccvs.core.ICVSRepositoryLocation;&lt;br /&gt;&lt;br /&gt;public class CVSDOM&lt;br /&gt;{&lt;br /&gt;    public ICVSRepositoryLocation getKnownRepository( final String locationString )&lt;br /&gt;    {&lt;br /&gt;        for( ICVSRepositoryLocation location : getPlugin().getKnownRepositories() )&lt;br /&gt;        {&lt;br /&gt;            if( location.getLocation( true ).equals( locationString ) )&lt;br /&gt;                return location;&lt;br /&gt;        }&lt;br /&gt;        return null;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;* Note: I am using Java 5.0 for this example and if you are running Groovy Monkey, your Eclipse instance needs to be run in Java 5.0 too. This should not be a large problem since Eclipse can be run with one JRE install, but your code that you are developing can be run with another. There are also all sorts of nice settings in the JDT to allow you to use Java 5.0, but force the code to be valid for 1.4, 1.3, etc...&lt;br /&gt;** Note: Of course you can rewrite this to be 1.4 compliant if you wish.&lt;br /&gt;*** Note: Lastly remember that since your DOM will not be invoked in a seperate thread ( i.e. Eclipse Job ), if you suspect that the operation will take too long, by all means pass in a progress monitor to the method and make use of it.&lt;br /&gt;&lt;br /&gt;Now that is kind of neat, so lets use this. What we can't? The other version of the DOM was installed first? Well try running the 'Groovy Monkey &gt; Install &gt; CVS DOM' feature again. Now go back to the 'Installed DOMs' view, does it look the same? Open up the cvsDOM node, open up the CVSDOM class node and now check the listed methods. Your new getKnownRepository() method now shows up.&lt;br /&gt;&lt;br /&gt;For people who have been working with Eclipse and developing plugins, this should pique your interest. We are using the OSGi runtime as it was intended, we hotswapped out our net.sf.groovyMonkey.dom.cvs plugin at runtime. If you keep the DOM plugin simple, this should work again and again, with no need to restart the workbench or having to mess with version numbers. To learn more about this goto &lt;a href="http://osgi.org"&gt;OSGi&lt;/a&gt; and get a copy of the specification.&lt;br /&gt;&lt;br /&gt;So now to use it in our script, we open up the getEclipseIcons.gm script in our Groovy Monkey Editor and then right click to bring up the menu option 'Add DOM to Script'. Select the new DOM to be added, in my case here it is net.sf.groovyMonkey.dom.cvs, and click ok. Now rewrite the following section of the script:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;// Here we find the desired repository location that has already been configured&lt;br /&gt;//  in the CVS Respository Explorer.&lt;br /&gt;def plugin = CVSProviderPlugin.getPlugin()&lt;br /&gt;def repositoryLoc&lt;br /&gt;for( location in plugin.getKnownRepositories() )&lt;br /&gt;{&lt;br /&gt;    if( monitor.isCanceled() )&lt;br /&gt;        return&lt;br /&gt;    if( location.getRootDirectory() == '/home/eclipse' )&lt;br /&gt;        repositoryLoc = location&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;as:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;// Here we find the desired repository location that has already been configured&lt;br /&gt;//  in the CVS Respository Explorer.&lt;br /&gt;def cvsRepository = ':pserver:anonymous@dev.eclipse.org:/home/eclipse'&lt;br /&gt;def repositoryLoc = cvsDOM.getKnownRepository( cvsRepository )&lt;br /&gt;Validate.notNull( repositoryLoc, "Error could not find the repository ${cvsRepository}, has it been added to the CVS Repository Explorer?" )&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The last part just makes sure that the value is not null as a check.&lt;br /&gt;&lt;br /&gt;You can continue on to replace the other sections of code with the DOM. Down below is the final version of the class:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package net.sf.groovymonkey.dom.cvsdom;&lt;br /&gt;import static org.eclipse.core.runtime.SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK;&lt;br /&gt;import static org.eclipse.swt.widgets.Display.getCurrent;&lt;br /&gt;import static org.eclipse.swt.widgets.Display.getDefault;&lt;br /&gt;import static org.eclipse.team.internal.ccvs.core.CVSProviderPlugin.getPlugin;&lt;br /&gt;import java.lang.reflect.InvocationTargetException;&lt;br /&gt;import java.util.ArrayList;&lt;br /&gt;import java.util.List;&lt;br /&gt;import org.apache.commons.lang.StringUtils;&lt;br /&gt;import org.eclipse.core.resources.IFolder;&lt;br /&gt;import org.eclipse.core.resources.IProject;&lt;br /&gt;import org.eclipse.core.runtime.IProgressMonitor;&lt;br /&gt;import org.eclipse.core.runtime.NullProgressMonitor;&lt;br /&gt;import org.eclipse.core.runtime.SubProgressMonitor;&lt;br /&gt;import org.eclipse.team.internal.ccvs.core.CVSException;&lt;br /&gt;import org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder;&lt;br /&gt;import org.eclipse.team.internal.ccvs.core.ICVSRemoteResource;&lt;br /&gt;import org.eclipse.team.internal.ccvs.core.ICVSRepositoryLocation;&lt;br /&gt;import org.eclipse.team.internal.ccvs.core.resources.RemoteFolder;&lt;br /&gt;import org.eclipse.team.internal.ccvs.ui.operations.CheckoutIntoOperation;&lt;br /&gt;import org.eclipse.team.internal.ccvs.ui.operations.DisconnectOperation;&lt;br /&gt;&lt;br /&gt;public class CVSDOM&lt;br /&gt;{&lt;br /&gt;    public ICVSRepositoryLocation getKnownRepository( final String locationString )&lt;br /&gt;    {&lt;br /&gt;        for( ICVSRepositoryLocation location : getPlugin().getKnownRepositories() )&lt;br /&gt;        {&lt;br /&gt;            if( location.getLocation( true ).equals( locationString ) )&lt;br /&gt;                return location;&lt;br /&gt;        }&lt;br /&gt;        return null;&lt;br /&gt;    }&lt;br /&gt;    public List&lt;&gt; getRepositoryResources( final IProgressMonitor progressMonitor,&lt;br /&gt;                                                              final ICVSRepositoryLocation location,&lt;br /&gt;                                                              final String subfolder )&lt;br /&gt;    throws CVSException&lt;br /&gt;    {&lt;br /&gt;        final IProgressMonitor monitor = progressMonitor == null ? new NullProgressMonitor() : progressMonitor;&lt;br /&gt;        final List&lt;&gt; folders = new ArrayList&lt;&gt;();&lt;br /&gt;        final ICVSRemoteResource[] members = location.members( null, false, null );&lt;br /&gt;        monitor.beginTask( "Getting Remote CVS Resources", members.length );&lt;br /&gt;        for( final ICVSRemoteResource member : members )&lt;br /&gt;        {&lt;br /&gt;            if( monitor.isCanceled() )&lt;br /&gt;                return null;&lt;br /&gt;            monitor.subTask( member.getName() );&lt;br /&gt;            final RemoteFolder folder = ( RemoteFolder )member;&lt;br /&gt;            folder.fetchChildren( new SubProgressMonitor( monitor, PREPEND_MAIN_LABEL_TO_SUBTASK ) );&lt;br /&gt;            if( StringUtils.isBlank( subfolder ) )&lt;br /&gt;            {&lt;br /&gt;                folders.add( member );&lt;br /&gt;                monitor.worked( 1 );&lt;br /&gt;                continue;&lt;br /&gt;            }&lt;br /&gt;            if( !folder.childExists( subfolder ) )&lt;br /&gt;            {&lt;br /&gt;                monitor.worked( 1 );&lt;br /&gt;                continue;&lt;br /&gt;            }&lt;br /&gt;            folders.add( ( ICVSRemoteResource )folder.getFolder( subfolder ) );&lt;br /&gt;            monitor.worked( 1 );&lt;br /&gt;        }&lt;br /&gt;        monitor.done();&lt;br /&gt;        return folders;&lt;br /&gt;    }&lt;br /&gt;    public CVSDOM checkOut( final IProgressMonitor progressMonitor,&lt;br /&gt;                            final List&lt;&gt; remoteResources,&lt;br /&gt;                            final IFolder target,&lt;br /&gt;                            final boolean disconnect )&lt;br /&gt;    throws CVSException, InterruptedException, InvocationTargetException&lt;br /&gt;    {&lt;br /&gt;        final IProgressMonitor monitor = progressMonitor == null ? new NullProgressMonitor() : progressMonitor;&lt;br /&gt;        monitor.beginTask( "Checking out into target: " + target.getFullPath(), remoteResources.size() );&lt;br /&gt;        for( final ICVSRemoteResource folder : remoteResources )&lt;br /&gt;        {&lt;br /&gt;            if( monitor.isCanceled() )&lt;br /&gt;                return this;&lt;br /&gt;            if( !( folder instanceof ICVSRemoteFolder ) )&lt;br /&gt;                continue;&lt;br /&gt;            final IFolder targetFolder = target.getFolder( folder.getRemoteParent().getRepositoryRelativePath() );&lt;br /&gt;            new CheckoutIntoOperation( null, ( ICVSRemoteFolder )folder, targetFolder, true ).execute( new SubProgressMonitor( monitor, 1 ) );&lt;br /&gt;            monitor.worked( 1 );&lt;br /&gt;        }&lt;br /&gt;        if( !disconnect )&lt;br /&gt;            return this;&lt;br /&gt;        disconnect( target.getProject() );&lt;br /&gt;        monitor.done();&lt;br /&gt;        return this;&lt;br /&gt;    }&lt;br /&gt;    public CVSDOM disconnect( final IProject project )&lt;br /&gt;    {&lt;br /&gt;        if( getCurrent() == null )&lt;br /&gt;        {&lt;br /&gt;            final Runnable runnable = new Runnable()&lt;br /&gt;            {&lt;br /&gt;                public void run()&lt;br /&gt;                {&lt;br /&gt;                    disconnect( project );&lt;br /&gt;                }&lt;br /&gt;               &lt;br /&gt;            };&lt;br /&gt;            getDefault().syncExec( runnable );&lt;br /&gt;            return this;&lt;br /&gt;        }&lt;br /&gt;        try&lt;br /&gt;        {&lt;br /&gt;            new DisconnectOperation( null, new IProject[] { project }, true ).run();&lt;br /&gt;        }&lt;br /&gt;        catch( final InvocationTargetException e )&lt;br /&gt;        {&lt;br /&gt;            throw new RuntimeException( e );&lt;br /&gt;        }&lt;br /&gt;        catch( final InterruptedException e )&lt;br /&gt;        {&lt;br /&gt;            throw new RuntimeException( e );&lt;br /&gt;        }&lt;br /&gt;        return this;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now here is the final version of the script to the new DOM:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;--- Came wiffling through the eclipsey wood ---&lt;br /&gt;/*&lt;br /&gt; * Menu: Get Eclipse Icons &gt; Refactored DOM&lt;br /&gt; * Kudos: ervinja&lt;br /&gt; * License: EPL 1.0&lt;br /&gt; * DOM: http://groovy-monkey.sourceforge.net/update/plugins/net.sf.groovyMonkey.dom&lt;br /&gt; * Include-Bundle: org.eclipse.team.cvs.core&lt;br /&gt; * Include-Bundle: org.eclipse.team.cvs.ui&lt;br /&gt; * DOM: http://groovy-monkey.sourceforge.net/update/net.sf.groovyMonkey.dom.cvs&lt;br /&gt; */&lt;br /&gt;import org.apache.commons.lang.Validate&lt;br /&gt;import org.eclipse.core.resources.IResource&lt;br /&gt;import org.eclipse.core.runtime.SubProgressMonitor&lt;br /&gt;&lt;br /&gt;// Here we find the desired repository location that has already been configured&lt;br /&gt;//  in the CVS Respository Explorer.&lt;br /&gt;def cvsRepository = ':pserver:anonymous@dev.eclipse.org:/home/eclipse'&lt;br /&gt;def repositoryLoc = cvsDOM.getKnownRepository( cvsRepository )&lt;br /&gt;Validate.notNull( repositoryLoc, "Error could not find the repository ${cvsRepository}, has it been added to the CVS Repository Explorer?" )&lt;br /&gt;&lt;br /&gt;// Here we query all the remote repository top level projects for sub-folders&lt;br /&gt;//  called icons and then store them into a list for later use.&lt;br /&gt;def iconFolders = cvsDOM.getRepositoryResources( new SubProgressMonitor( monitor, 1 ), repositoryLoc, 'icons' )&lt;br /&gt;if( iconFolders == null )&lt;br /&gt;    return&lt;br /&gt;&lt;br /&gt;// Check out those icon folders under a sub-folder of the target project called&lt;br /&gt;//  icons and place each remote icon folder in a sub-folder of icons that corresponds&lt;br /&gt;//  to its project name.&lt;br /&gt;def targetProject = workspace.getRoot().getProject( 'GroovyMonkeyExamples' )&lt;br /&gt;cvsDOM.checkOut( new SubProgressMonitor( monitor, 1 ), iconFolders, targetProject.getFolder( 'icons' ), true )&lt;br /&gt;&lt;br /&gt;// Build the eclipse-icons.zip file using AntBuilder&lt;br /&gt;def baseDir = targetProject.getFolder( 'icons' )&lt;br /&gt;def destFile = targetProject.getFile( 'eclipse-icons.zip' )&lt;br /&gt;if( destFile.exists() )&lt;br /&gt;    destFile.delete( true, null )&lt;br /&gt;def ant = new AntBuilder()&lt;br /&gt;ant.zip( basedir:"${baseDir.getRawLocation()}", destfile:"${destFile.getRawLocation()}" )&lt;br /&gt;// Refresh the targetProject so that eclipse-icons.zip shows up in the Navigator and Package Explorer.&lt;br /&gt;targetProject.refreshLocal( IResource.DEPTH_INFINITE, null )&lt;br /&gt;monitor.done()&lt;br /&gt;--- And burbled as it ran! ---&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If we like the results, we can then deploy the DOM plugin for real to an update site for others to use. Once I figure out a little bit more of this blog API and figure out how to upload files, I will include the source files for the scripts and the net.sf.groovyMonkey.dom.cvs DOM plugin.&lt;br /&gt;&lt;br /&gt;I hope once again this has proven helpful and will encourage you to experiment more with Eclipse using Groovy Monkey.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18663041-115505593730979418?l=iacobus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/115505593730979418/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18663041&amp;postID=115505593730979418' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/115505593730979418'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/115505593730979418'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/2006/08/groovy-monkey-eclipse-icons-script-pt_08.html' title='Groovy Monkey: Eclipse Icons Script Pt 4/4: Rapid Prototyping with DOM Plugins'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18663041.post-115496717620183275</id><published>2006-08-07T08:58:00.000-07:00</published><updated>2007-03-01T08:27:40.303-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='GroovyMonkey'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><title type='text'>Groovy Monkey: Eclipse Icons Script Pt 3/4: Using library scripts</title><content type='html'>In my previous posts on the Eclipse Icons Script ( &lt;a href="http://iacobus.blogspot.com/2006/08/eclipse-icons-script-in-groovy-monkey.html"&gt;here&lt;/a&gt; and &lt;a href="http://iacobus.blogspot.com/2006/08/eclipse-icons-script-in-groovy-monkey_07.html"&gt;here&lt;/a&gt; ) I wrote a functional Groovy Monkey script that would query the remote Eclipse projects in CVS to get the contents of all their 'icons' folders. The script would then clean up the CVS team cruft and then package it all as a zip file called 'eclipse-icons.zip'. The next question to ask is, how can I reuse some of this work? I mean there are more than one occasion where I would like to check projects out of CVS and the like. You could cut and paste those sections in to new scripts. While cut and paste is a programmer's best friend, avoiding duplication should be a mantra followed under penalty of death. So why don't we investigate some reuse?&lt;br /&gt;&lt;br /&gt;To faciliate reuse Groovy Monkey has two mechanisms. One is the Runner DOM which allows you to invoke other Groovy Monkey scripts in your workspace and the second is developing a DOM plugin that can be invoked from your Groovy Monkey script using the script binding. This blog entry will describe how to use the Runner DOM.&lt;br /&gt;&lt;br /&gt;One of the big advantages of using monkey scripts to reuse code is that it can be shared far more easily than with plugins. A library script can be posted to the web directly in a blog or web page and just as easily shared. In fact if you compensate for the workspace paths and the script names, you can cut and paste these scripts and run them immediately within your Eclipse workbench. All this without having to run the Update Manager and probably having to restart Eclipse.&lt;br /&gt;&lt;br /&gt;I am going to paste the original script with some comments delimiting the various steps the script does to accomplish its task. These delimited sections would seem to be good candidates for separate library scripts.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;--- Came wiffling through the eclipsey wood ---&lt;br /&gt;/*&lt;br /&gt; * Menu: Get Eclipse Icons&lt;br /&gt; * Kudos: ervinja&lt;br /&gt; * License: EPL 1.0&lt;br /&gt; * DOM: http://groovy-monkey.sourceforge.net/update/plugins/net.sf.groovyMonkey.dom&lt;br /&gt; * Include-Bundle: org.eclipse.team.cvs.core&lt;br /&gt; * Include-Bundle: org.eclipse.team.cvs.ui&lt;br /&gt; */&lt;br /&gt;import org.eclipse.core.resources.IProject&lt;br /&gt;import org.eclipse.core.resources.IResource&lt;br /&gt;import org.eclipse.core.runtime.SubProgressMonitor&lt;br /&gt;import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin&lt;br /&gt;import org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder&lt;br /&gt;import org.eclipse.team.internal.ccvs.ui.operations.CheckoutIntoOperation&lt;br /&gt;import org.eclipse.team.internal.ccvs.ui.operations.DisconnectOperation&lt;br /&gt;&lt;br /&gt;// Here we find the desired repository location that has already been configured&lt;br /&gt;//  in the CVS Respository Explorer.&lt;br /&gt;def plugin = CVSProviderPlugin.getPlugin()&lt;br /&gt;def repositoryLoc&lt;br /&gt;for( location in plugin.getKnownRepositories() )&lt;br /&gt;{&lt;br /&gt;    if( monitor.isCanceled() )&lt;br /&gt;        return&lt;br /&gt;    if( location.getRootDirectory() == '/home/eclipse' )&lt;br /&gt;        repositoryLoc = location&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Here we query all the remote repository top level projects for sub-folders&lt;br /&gt;//  called icons and then store them into a list for later use.&lt;br /&gt;def members = repositoryLoc.members( null, false, null )&lt;br /&gt;monitor.beginTask( '', 2 * members.size() )&lt;br /&gt;def iconFolders = []&lt;br /&gt;for( member in members )&lt;br /&gt;{&lt;br /&gt;    member.fetchChildren()&lt;br /&gt;    if( monitor.isCanceled() )&lt;br /&gt;        return&lt;br /&gt;    if( !member.childExists( 'icons' ) )&lt;br /&gt;    {&lt;br /&gt;        monitor.worked( 1 )&lt;br /&gt;        continue&lt;br /&gt;    }&lt;br /&gt;    def icons = member.getFolder( 'icons' )&lt;br /&gt;    iconFolders.add( icons )&lt;br /&gt;    monitor.worked( 1 )&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Check out those icon folders under a sub-folder of the target project called&lt;br /&gt;//  icons and place each remote icon folder in a sub-folder of icons that corresponds&lt;br /&gt;//  to its project name.&lt;br /&gt;def targetProject = workspace.getRoot().getProject( 'GroovyMonkeyExamples' )&lt;br /&gt;iconFolders.each&lt;br /&gt;{ folder -&gt;&lt;br /&gt;    if( monitor.isCanceled() )&lt;br /&gt;        return&lt;br /&gt;    def targetFolder = targetProject.getFolder( 'icons' ).getFolder( folder.getRemoteParent().getRepositoryRelativePath() )&lt;br /&gt;    new CheckoutIntoOperation( null, folder, targetFolder, true ).execute( new SubProgressMonitor( monitor, 1 ) )&lt;br /&gt;    monitor.worked( 1 )&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Clear off the CVS cruft.&lt;br /&gt;jface.syncExec&lt;br /&gt;{&lt;br /&gt;    new DisconnectOperation( null, [ targetProject ].toArray( new IProject[0] ), true ).run()&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Build the eclipse-icons.zip file using AntBuilder&lt;br /&gt;def baseDir = targetProject.getFolder( 'icons' )&lt;br /&gt;def destFile = targetProject.getFile( 'eclipse-icons.zip' )&lt;br /&gt;if( destFile.exists() )&lt;br /&gt; destFile.delete( true, null )&lt;br /&gt;&lt;br /&gt;def ant = new AntBuilder()&lt;br /&gt;ant.zip( basedir:"${baseDir.getRawLocation()}", destfile:"${destFile.getRawLocation()}" )&lt;br /&gt;&lt;br /&gt;// Refresh the targetProject so that eclipse-icons.zip shows up in the Navigator and Package Explorer.&lt;br /&gt;targetProject.refreshLocal( IResource.DEPTH_INFINITE, null )&lt;br /&gt;&lt;br /&gt;monitor.done()&lt;br /&gt;--- And burbled as it ran! ---&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;One note before we start breaking the script up into component library scripts, is the issue of where to store the scripts. In Groovy Monkey when a script is loaded under the monkey folder of a project and contains a 'Menu:' metadata tag that is not blank, only then will it show up in the 'Groovy Monkey' menu. This is important because library scripts often need parameters passed into them for them to work and there is no mechanism for setting parameters using an action kicked off by a menu item. So as long as the library script does not have a 'Menu:' metadata tag set, this requirement is satisfied. Since library scripts are not meant to be invoked from the menu, you are free to place them where you like in the workspace. I like to put them under a lib folder under my 'GroovyMonkeyExamples' project, but you are not held to this.&lt;br /&gt;&lt;br /&gt;As I look at the first part of the script that gets the ICVSRepositoryLocation instance associated with dev.eclipse.org, I realize I really don't like how I did it. So I go ahead and pop off a script to test the getLocation() method output and see if it is in a form I like.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;--- Came wiffling through the eclipsey wood ---&lt;br /&gt;/*&lt;br /&gt; * Menu: List Repositories&lt;br /&gt; * Kudos: ervinja&lt;br /&gt; * License: EPL 1.0&lt;br /&gt; * DOM: http://groovy-monkey.sourceforge.net/update/plugins/net.sf.groovyMonkey.dom&lt;br /&gt; * Include-Bundle: org.eclipse.team.cvs.core&lt;br /&gt; */&lt;br /&gt;import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin&lt;br /&gt;&lt;br /&gt;def plugin = CVSProviderPlugin.getPlugin()&lt;br /&gt;for( location in plugin.getKnownRepositories() )&lt;br /&gt;{&lt;br /&gt;    if( monitor.isCanceled() )&lt;br /&gt;        return&lt;br /&gt;    out.println 'location.getLocation( true  ): ' + location.getLocation( true )&lt;br /&gt;    out.println 'location.getLocation( false ): ' + location.getLocation( false )&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;--- And burbled as it ran! ---&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;When running that script I found no real difference with the output format, but since the boolean parameter is named display, I will set it to true hoping that means it matches the string shown in the CVS Repository Explorer. I am going to use the above script as the model for the library script. I copy it into the 'GroovyMonkeyExamples/lib' folder and rename it getKnownRepository.gm. The first modification I make is to remove the 'Menu:' metadata tag.&lt;br /&gt;&lt;br /&gt;With a library script usually you have to pass in some parameters and Groovy Monkey does this via the script binding when invoked. You can use the BSFFunctions class that is put in the binding under the variable name bsf to check if something has been put into the binding. In fact the following is probably a good practice just for documentation. I named the following script getKnownRepository.gm&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;--- Came wiffling through the eclipsey wood ---&lt;br /&gt;/*&lt;br /&gt; * Kudos: ervinja&lt;br /&gt; * License: EPL 1.0&lt;br /&gt; * DOM: http://groovy-monkey.sourceforge.net/update/plugins/net.sf.groovyMonkey.dom&lt;br /&gt; * Include-Bundle: org.eclipse.team.cvs.core&lt;br /&gt; */&lt;br /&gt;import org.apache.commons.lang.Validate&lt;br /&gt;import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin&lt;br /&gt;&lt;br /&gt;Validate.notNull( bsf.lookupBean( 'cvsLocation' ), 'cvsLocation string describing the CVS location must be set' )&lt;br /&gt;&lt;br /&gt;def plugin = CVSProviderPlugin.getPlugin()&lt;br /&gt;for( location in plugin.getKnownRepositories() )&lt;br /&gt;{&lt;br /&gt;    if( monitor.isCanceled() )&lt;br /&gt;        return&lt;br /&gt;    if( location.getLocation( true ) == "$cvsLocation" )&lt;br /&gt;     return location&lt;br /&gt;}&lt;br /&gt;return null&lt;br /&gt;&lt;br /&gt;--- And burbled as it ran! ---&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So now we modify the original script to invoke it. We have made it clear that we must put in a value in the binding for cvsLocation. Here is how it is done.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;def map = [ cvsLocation : ':pserver:anonymous@dev.eclipse.org:/home/eclipse' ]&lt;br /&gt;def repositoryLoc = runnerDOM.runScript( '/GroovyMonkeyExamples/lib/getKnownRepository.gm', map )&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Notice that we specify the path in the workspace to the script as a string and that we pass in a java.util.Map instance that specifies those values we wish to set/override in the targetted script's binding. The script is started within its own Eclipse Job and this script is stopped while the other waits to complete and give us a return value. This is all there is to it. Remember that you must specify the full workspace relative path to the target script, this could cause some trouble when you are renaming or moving scripts around in your workspace. It would be nice to include the sort of refactoring support that exists in Eclipse, but since Groovy Monkey is designed to support multiple scripting languages, this presents a bit of a challenge to implement.&lt;br /&gt;&lt;br /&gt;Now we rewrite the next section to a script that takes an ICVSRepositoryLocation and a string called subfolder that can be set blank. It does the work of the original section of the script with the addition that if the subfolder parameter is set blank, the top level project is returned instead. This is so you can use the script to just check out all the remote projects. I called this script getRepositoryResources.gm.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;--- Came wiffling through the eclipsey wood ---&lt;br /&gt;/*&lt;br /&gt; * Kudos: ervinja&lt;br /&gt; * License: EPL 1.0&lt;br /&gt; * DOM: http://groovy-monkey.sourceforge.net/update/plugins/net.sf.groovyMonkey.dom&lt;br /&gt; * Include-Bundle: org.eclipse.team.cvs.core&lt;br /&gt; * Include-Bundle: org.eclipse.team.cvs.ui&lt;br /&gt; */&lt;br /&gt;import org.apache.commons.lang.Validate&lt;br /&gt;import org.apache.commons.lang.StringUtils&lt;br /&gt;&lt;br /&gt;Validate.notNull( bsf.lookupBean( 'repositoryLoc' ), 'repositoryLoc must be set' )&lt;br /&gt;Validate.notNull( bsf.lookupBean( 'subfolder' ), 'subfolder must be set' )&lt;br /&gt;&lt;br /&gt;def members = repositoryLoc.members( null, false, null )&lt;br /&gt;monitor.beginTask( 'Getting Remote CVS Resources', members.size() )&lt;br /&gt;def folders = []&lt;br /&gt;for( member in members )&lt;br /&gt;{&lt;br /&gt; if( monitor.isCanceled() )&lt;br /&gt;        return null&lt;br /&gt;    monitor.subTask( "${member.getName()}" )&lt;br /&gt;    member.fetchChildren()&lt;br /&gt;    if( StringUtils.isBlank( "$subfolder" ) )&lt;br /&gt;    {&lt;br /&gt;        folders.add( member )&lt;br /&gt;        monitor.worked( 1 )&lt;br /&gt;        continue&lt;br /&gt;    }&lt;br /&gt;    if( !member.childExists( "$subfolder" ) )&lt;br /&gt;    {&lt;br /&gt;        monitor.worked( 1 )&lt;br /&gt;        continue&lt;br /&gt;    }&lt;br /&gt;    def icons = member.getFolder( "$subfolder" )&lt;br /&gt;    folders.add( icons )&lt;br /&gt;    monitor.worked( 1 )&lt;br /&gt;}&lt;br /&gt;monitor.done()&lt;br /&gt;return folders&lt;br /&gt;&lt;br /&gt;--- And burbled as it ran! ---&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now here is the check out script, which I called checkOut.gm.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;--- Came wiffling through the eclipsey wood ---&lt;br /&gt;/*&lt;br /&gt; * Kudos: ervinja&lt;br /&gt; * License: EPL 1.0&lt;br /&gt; * DOM: http://groovy-monkey.sourceforge.net/update/plugins/net.sf.groovyMonkey.dom&lt;br /&gt; * Include-Bundle: org.eclipse.team.cvs.core&lt;br /&gt; * Include-Bundle: org.eclipse.team.cvs.ui&lt;br /&gt; */&lt;br /&gt;import org.apache.commons.lang.Validate&lt;br /&gt;import org.apache.commons.lang.StringUtils&lt;br /&gt;import org.eclipse.core.resources.IProject&lt;br /&gt;import org.eclipse.core.resources.IResource&lt;br /&gt;import org.eclipse.core.runtime.SubProgressMonitor&lt;br /&gt;import org.eclipse.team.internal.ccvs.ui.operations.CheckoutIntoOperation&lt;br /&gt;import org.eclipse.team.internal.ccvs.ui.operations.DisconnectOperation&lt;br /&gt;&lt;br /&gt;Validate.notNull( bsf.lookupBean( 'remoteResources' ), 'remoteResources must be set' )&lt;br /&gt;Validate.notNull( bsf.lookupBean( 'target' ), 'target must be set' )&lt;br /&gt;Validate.notNull( bsf.lookupBean( 'disconnect' ), 'disconnect must be set' )&lt;br /&gt;&lt;br /&gt;monitor.beginTask( 'Check out from CVS', remoteResources.size() )&lt;br /&gt;remoteResources.each&lt;br /&gt;{ folder -&gt;&lt;br /&gt;    if( monitor.isCanceled() )&lt;br /&gt;        return&lt;br /&gt;    def targetFolder = target.getFolder( folder.getRemoteParent().getRepositoryRelativePath() )&lt;br /&gt;    new CheckoutIntoOperation( null, folder, targetFolder, true ).execute( new SubProgressMonitor( monitor, 1 ) )&lt;br /&gt;    monitor.worked( 1 )&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if( disconnect )&lt;br /&gt;{&lt;br /&gt;    // Clear off the CVS cruft.&lt;br /&gt;    jface.syncExec&lt;br /&gt;    {&lt;br /&gt;        new DisconnectOperation( null, [ target.getProject() ].toArray( new IProject[0] ), true ).run()&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;monitor.done()&lt;br /&gt;&lt;br /&gt;--- And burbled as it ran! ---&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now here is the script to build the zip file, which I called buildZip.gm.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;--- Came wiffling through the eclipsey wood ---&lt;br /&gt;/*&lt;br /&gt; * Kudos: ervinja&lt;br /&gt; * License: EPL 1.0&lt;br /&gt; * DOM: http://groovy-monkey.sourceforge.net/update/plugins/net.sf.groovyMonkey.dom&lt;br /&gt; * Include-Bundle: org.eclipse.team.cvs.core&lt;br /&gt; */&lt;br /&gt;import org.apache.commons.lang.Validate&lt;br /&gt;import org.apache.commons.lang.StringUtils&lt;br /&gt;import org.eclipse.core.resources.IProject&lt;br /&gt;import org.eclipse.core.resources.IResource&lt;br /&gt;import org.eclipse.core.runtime.SubProgressMonitor&lt;br /&gt;&lt;br /&gt;Validate.notNull( bsf.lookupBean( 'srcFolder' ), 'srcFolder must be set' )&lt;br /&gt;Validate.notNull( bsf.lookupBean( 'destFolder' ), 'destFolder must be set' )&lt;br /&gt;Validate.notNull( bsf.lookupBean( 'zipName' ), 'zipName must be set' )&lt;br /&gt;Validate.notNull( bsf.lookupBean( 'replace' ), 'replace must be set' )&lt;br /&gt;&lt;br /&gt;monitor.beginTask( 'Building Zip', -1 )&lt;br /&gt;def destFile = destFolder.getFile( "$zipName" )&lt;br /&gt;if( destFile.exists() )&lt;br /&gt;{&lt;br /&gt;    if( replace == false )&lt;br /&gt;    {&lt;br /&gt;        monitor.done()&lt;br /&gt;        return&lt;br /&gt;    }&lt;br /&gt;    destFile.delete( true, null )&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;def ant = new AntBuilder()&lt;br /&gt;ant.zip( basedir:"${srcFolder.getRawLocation()}",destfile:"${destFile.getRawLocation()}" )&lt;br /&gt;&lt;br /&gt;// Refresh the targetProject so that eclipse-icons.zip shows up in the Navigator and Package Explorer.&lt;br /&gt;destFolder.getProject().refreshLocal( IResource.DEPTH_INFINITE, null )&lt;br /&gt;monitor.done()&lt;br /&gt;&lt;br /&gt;--- And burbled as it ran! ---&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here is the original script, rewritten to use the library scripts. Note that your paths and script names could be different from these, adjust accordingly.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;--- Came wiffling through the eclipsey wood ---&lt;br /&gt;/*&lt;br /&gt; * Menu: Get Eclipse Icons&lt;br /&gt; * Kudos: ervinja&lt;br /&gt; * License: EPL 1.0&lt;br /&gt; * DOM: http://groovy-monkey.sourceforge.net/update/plugins/net.sf.groovyMonkey.dom&lt;br /&gt; * Include-Bundle: org.eclipse.team.cvs.core&lt;br /&gt; * Include-Bundle: org.eclipse.team.cvs.ui&lt;br /&gt; */&lt;br /&gt;import org.eclipse.core.resources.IResource&lt;br /&gt;import org.eclipse.core.runtime.SubProgressMonitor&lt;br /&gt;&lt;br /&gt;def libDir = '/GroovyMonkeyExamples/lib/'&lt;br /&gt;monitor.beginTask( 'Get Eclipse Icons', -1 )&lt;br /&gt;// Here we find the desired repository location that has already been configured&lt;br /&gt;//  in the CVS Respository Explorer.&lt;br /&gt;def map = [ cvsLocation : ':pserver:anonymous@dev.eclipse.org:/home/eclipse' ]&lt;br /&gt;def repositoryLoc = runnerDOM.runScript( libDir + 'getKnownRepository.gm', map )&lt;br /&gt;if( repositoryLoc == null )&lt;br /&gt;    throw new RuntimeException( 'Error repositoryLoc has not been configured correctly: ' + map )&lt;br /&gt;&lt;br /&gt;// Here we query all the remote repository top level projects for sub-folders&lt;br /&gt;//  called icons and then store them into a list for later use.&lt;br /&gt;map = [ 'repositoryLoc':repositoryLoc, subfolder:'icons' ]&lt;br /&gt;def iconFolders = runnerDOM.runScript( libDir + 'getRepositoryResources.gm', map )&lt;br /&gt;if( iconFolders == null  monitor.isCanceled() )&lt;br /&gt;    return&lt;br /&gt;&lt;br /&gt;// Check out those icon folders under a sub-folder of the target project called&lt;br /&gt;//  icons and place each remote icon folder in a sub-folder of icons that corresponds&lt;br /&gt;//  to its project name.&lt;br /&gt;def targetProject = workspace.getRoot().getProject( 'GroovyMonkeyExamples' )&lt;br /&gt;map = [ remoteResources:iconFolders, target:targetProject.getFolder( 'icons' ), disconnect:true ]&lt;br /&gt;runnerDOM.runScript( libDir + 'checkOut.gm', map )&lt;br /&gt;if( monitor.isCanceled() )&lt;br /&gt;    return&lt;br /&gt;&lt;br /&gt;// Build the eclipse-icons.zip file using AntBuilder&lt;br /&gt;map = [ srcFolder:targetProject.getFolder( 'icons' ), destFolder:targetProject, zipName: 'eclipse-icons.zip', replace:true ]&lt;br /&gt;runnerDOM.runScript( libDir + 'buildZip.gm', map )&lt;br /&gt;&lt;br /&gt;monitor.done()&lt;br /&gt;--- And burbled as it ran! ---&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I hope you found this little exercise useful, because I have. For one I think there is some more work to do to remove some scaffolding, like maybe a convience validate DOM or method to reduce the need to keep calling Validate.notNull() for instance. I would also like to reduce some of the overhead in calling the Runner DOM, but I am not sure how yet to accomplish it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18663041-115496717620183275?l=iacobus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://iacobus.blogspot.com/2006/08/eclipse-icons-script-pt-3-using.html' title='Groovy Monkey: Eclipse Icons Script Pt 3/4: Using library scripts'/><link rel='replies' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/115496717620183275/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18663041&amp;postID=115496717620183275' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/115496717620183275'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/115496717620183275'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/2006/08/groovy-monkey-eclipse-icons-script-pt.html' title='Groovy Monkey: Eclipse Icons Script Pt 3/4: Using library scripts'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18663041.post-115496134645788221</id><published>2006-08-07T07:05:00.000-07:00</published><updated>2007-03-01T08:28:33.169-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='GroovyMonkey'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><title type='text'>Groovy Monkey: Eclipse Icons Script in Groovy Monkey Pt 2/4</title><content type='html'>In my previous &lt;a href="http://iacobus.blogspot.com/2006/08/eclipse-icons-script-in-groovy-monkey.html"&gt;post&lt;/a&gt; I began work on writing a script to checkout all the available icon files from the Eclipse Platform project as a test and demonstration of Groovy Monkey. I would like to continue on and begin demonstrating how you can rewrite some of that code to be reused as a Groovy Monkey library script or as a DOM plugin prototype. I would like to but after reading the original &lt;a href="http://blogs.codehaus.org/people/bwalding/archives/000779_icons_borrowed_from_eclipse.html"&gt;article&lt;/a&gt; that inspired me again, I realized I have a little more work to do. I need to remove all the CVS cruft from the workspace and then package the whole thing up as a zip file that could be published to a website.&lt;br /&gt;&lt;br /&gt;Now before I dive into the subject, I would like to take a moment to point out a feature of Groovy Monkey that was inherited from Eclipse Monkey. In my previous posting I have a number of versions of the "Get Eclipse Icons" script and I have been working on this script from more than one location. It is easy in Groovy Monkey to grab scripts and to dump them into your workspace. Select the text of the script beginning with:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;--- Came wiffling through the eclipsey wood ---&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And ending with:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;--- And burbled as it ran! ---&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Copy into the clipboard and then go over to your Eclipse workbench and select "Groovy Monkey &gt; Paste New Script". The script should be dumped into your workspace into the GroovyMonkeyExamples or Groovy Monkey Scripts project under the monkey folder. You can directly invoke it from the Groovy Monkey menu or can proceed to edit it.&lt;br /&gt;&lt;br /&gt;Now back to the job at hand. We could just delete the CVS folders and files and then have Eclipse update the workspace, but there is a command in Eclipse that will disconnect a project from CVS and so why not try and use it?&lt;br /&gt;&lt;br /&gt;I know there is a Disconnect popup menu command from the Package Explorer view and so I know to begin looking through the plugin.xml files of Eclipse plugins I suspect. From the previous work on this script I suspect the org.eclipse.team.cvs plugins, so lets start there. Since the command I would like to automate has a graphical component, I start with the org.eclipse.team.cvs.ui plugin. Since I know that Eclipse likes to use plugin/bundle.properties to put the names of UI commands in, I start there. Sure enough "UnmanageFolder.label=&amp;amp;Disconnect..." seems to be what I am looking for. In the plugin.xml this maps to the class org.eclipse.team.internal.ccvs.ui.actions.UnmanageAction. Lets start there.&lt;br /&gt;&lt;br /&gt;In the UnmanageAction class, it seems as though all it does is do some configuration , then query the user to see if they are sure they wish to disconnect the project and then use the DisconnectOperation class to actually do the work. So it looks as though all we must do is to instanciate the DisconnectOperation and then invoke run, lets go for it.&lt;br /&gt;&lt;br /&gt;One note, if you have already run the script and checked out the icons, it would probably be better to split this off into another script so as to avoid having to recheckout everything.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;--- Came wiffling through the eclipsey wood ---&lt;br /&gt;/*&lt;br /&gt; * Menu: Get Eclipse Icons&lt;br /&gt; * Kudos: ervinja&lt;br /&gt; * License: EPL 1.0&lt;br /&gt; * DOM: http://groovy-monkey.sourceforge.net/update/plugins/net.sf.groovyMonkey.dom&lt;br /&gt; * Include-Bundle: org.eclipse.team.cvs.core&lt;br /&gt; * Include-Bundle: org.eclipse.team.cvs.ui&lt;br /&gt; */&lt;br /&gt;import org.eclipse.core.resources.IProject&lt;br /&gt;import org.eclipse.core.runtime.SubProgressMonitor&lt;br /&gt;import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin&lt;br /&gt;import org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder&lt;br /&gt;import org.eclipse.team.internal.ccvs.ui.operations.CheckoutIntoOperation&lt;br /&gt;import org.eclipse.team.internal.ccvs.ui.operations.DisconnectOperation&lt;br /&gt;&lt;br /&gt;def plugin = CVSProviderPlugin.getPlugin()&lt;br /&gt;def repositoryLoc&lt;br /&gt;for( location in plugin.getKnownRepositories() )&lt;br /&gt;{&lt;br /&gt;    if( monitor.isCanceled() )&lt;br /&gt;        return&lt;br /&gt;    if( location.getRootDirectory() == '/home/eclipse' )&lt;br /&gt;        repositoryLoc = location&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;def targetProject = workspace.getRoot().getProject( 'GroovyMonkeyExamples' )&lt;br /&gt;def members = repositoryLoc.members( null, false, null )&lt;br /&gt;monitor.beginTask( '', 2 * members.size() )&lt;br /&gt;def iconFolders = []&lt;br /&gt;for( member in members )&lt;br /&gt;{&lt;br /&gt;    member.fetchChildren()&lt;br /&gt;    if( monitor.isCanceled() )&lt;br /&gt;        return&lt;br /&gt;    if( !member.childExists( 'icons' ) )&lt;br /&gt;    {&lt;br /&gt;        monitor.worked( 1 )&lt;br /&gt;        continue&lt;br /&gt;    }&lt;br /&gt;    def icons = member.getFolder( 'icons' )&lt;br /&gt;    iconFolders.add( icons )&lt;br /&gt;    monitor.worked( 1 )&lt;br /&gt;}&lt;br /&gt;iconFolders.each&lt;br /&gt;{ folder -&gt;&lt;br /&gt;    if( monitor.isCanceled() )&lt;br /&gt;        return&lt;br /&gt;    def targetFolder = targetProject.getFolder( 'icons' ).getFolder( folder.getRemoteParent().getRepositoryRelativePath() )&lt;br /&gt;    new CheckoutIntoOperation( null, folder, targetFolder, true ).execute( new SubProgressMonitor( monitor, 1 ) )&lt;br /&gt;    monitor.worked( 1 )&lt;br /&gt;}&lt;br /&gt;jface.syncExec&lt;br /&gt;{&lt;br /&gt;    new DisconnectOperation( null, [ targetProject ].toArray( new IProject[0] ), true ).run()&lt;br /&gt;}&lt;br /&gt;monitor.done()&lt;br /&gt;--- And burbled as it ran! ---&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now we have a script that checks out icons and then removes CVS cruft. So that just leaves us with the need to package it up as a zip. I don't know of any Eclipse code in particular to support this so I am going to use the Groovy Ant scripting support to do this quickly. Afterwords I am going to have the script tell the workspace to refresh itself.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;--- Came wiffling through the eclipsey wood ---&lt;br /&gt;/*&lt;br /&gt; * Menu: Get Eclipse Icons&lt;br /&gt; * Kudos: ervinja&lt;br /&gt; * License: EPL 1.0&lt;br /&gt; * DOM: http://groovy-monkey.sourceforge.net/update/plugins/net.sf.groovyMonkey.dom&lt;br /&gt; * Include-Bundle: org.eclipse.team.cvs.core&lt;br /&gt; * Include-Bundle: org.eclipse.team.cvs.ui&lt;br /&gt; */&lt;br /&gt;import org.eclipse.core.resources.IProject&lt;br /&gt;import org.eclipse.core.resources.IResource&lt;br /&gt;import org.eclipse.core.runtime.SubProgressMonitor&lt;br /&gt;import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin&lt;br /&gt;import org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder&lt;br /&gt;import org.eclipse.team.internal.ccvs.ui.operations.CheckoutIntoOperation&lt;br /&gt;import org.eclipse.team.internal.ccvs.ui.operations.DisconnectOperation&lt;br /&gt;&lt;br /&gt;def plugin = CVSProviderPlugin.getPlugin()&lt;br /&gt;def repositoryLoc&lt;br /&gt;for( location in plugin.getKnownRepositories() )&lt;br /&gt;{&lt;br /&gt;    if( monitor.isCanceled() )&lt;br /&gt;        return&lt;br /&gt;    if( location.getRootDirectory() == '/home/eclipse' )&lt;br /&gt;        repositoryLoc = location&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;def targetProject = workspace.getRoot().getProject( 'GroovyMonkeyExamples' )&lt;br /&gt;def members = repositoryLoc.members( null, false, null )&lt;br /&gt;monitor.beginTask( '', 2 * members.size() )&lt;br /&gt;def iconFolders = []&lt;br /&gt;for( member in members )&lt;br /&gt;{&lt;br /&gt;    member.fetchChildren()&lt;br /&gt;    if( monitor.isCanceled() )&lt;br /&gt;        return&lt;br /&gt;    if( !member.childExists( 'icons' ) )&lt;br /&gt;    {&lt;br /&gt;        monitor.worked( 1 )&lt;br /&gt;        continue&lt;br /&gt;    }&lt;br /&gt;    def icons = member.getFolder( 'icons' )&lt;br /&gt;    iconFolders.add( icons )&lt;br /&gt;    monitor.worked( 1 )&lt;br /&gt;}&lt;br /&gt;iconFolders.each&lt;br /&gt;{ folder -&gt;&lt;br /&gt;    if( monitor.isCanceled() )&lt;br /&gt;        return&lt;br /&gt;    def targetFolder = targetProject.getFolder( 'icons' ).getFolder( folder.getRemoteParent().getRepositoryRelativePath() )&lt;br /&gt;    new CheckoutIntoOperation( null, folder, targetFolder, true ).execute( new SubProgressMonitor( monitor, 1 ) )&lt;br /&gt;    monitor.worked( 1 )&lt;br /&gt;}&lt;br /&gt;jface.syncExec&lt;br /&gt;{&lt;br /&gt; new DisconnectOperation( null, [ targetProject ].toArray( new IProject[0] ), true ).run()&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;def baseDir = targetProject.getFolder( 'icons' )&lt;br /&gt;def destFile = targetProject.getFile( 'eclipse-icons.zip' )&lt;br /&gt;if( destFile.exists() )&lt;br /&gt; destFile.delete( true, null )&lt;br /&gt;&lt;br /&gt;def ant = new AntBuilder()&lt;br /&gt;ant.zip( basedir:"${baseDir.getRawLocation()}", destfile:"${destFile.getRawLocation()}" )&lt;br /&gt;&lt;br /&gt;targetProject.refreshLocal( IResource.DEPTH_INFINITE, null )&lt;br /&gt;&lt;br /&gt;monitor.done()&lt;br /&gt;--- And burbled as it ran! ---&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now we have a script that accomplishes the entirety of the original &lt;a href="http://blogs.codehaus.org/people/bwalding/archives/000779_icons_borrowed_from_eclipse.html"&gt;script&lt;/a&gt;. Now to some of you this script is probably pretty good and you would use it as written. Now me, with my ADD and lazy mind, does not like it. I would like to be able to reuse some of this code in other scripts and quite frankly it is too complex and ugly. So my next couple of blog entries are going to deal with this issue. First we are going to rewrite the script so that it can invoke other Groovy Monkey scripts and create reuse that way and second we are going to start work on doing a DOM plugin prototype that I think you will find more dynamic and fun that doing straight Eclipse plugin work. So hopefully you will stick around for them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18663041-115496134645788221?l=iacobus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://iacobus.blogspot.com/2006/08/eclipse-icons-script-in-groovy-monkey_07.html' title='Groovy Monkey: Eclipse Icons Script in Groovy Monkey Pt 2/4'/><link rel='replies' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/115496134645788221/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18663041&amp;postID=115496134645788221' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/115496134645788221'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/115496134645788221'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/2006/08/groovy-monkey-eclipse-icons-script-in.html' title='Groovy Monkey: Eclipse Icons Script in Groovy Monkey Pt 2/4'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18663041.post-115470917979576330</id><published>2006-08-04T09:23:00.000-07:00</published><updated>2007-03-01T08:29:10.209-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='GroovyMonkey'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><title type='text'>Groovy Monkey: Eclipse Icons script in Groovy Monkey Pt 1/4</title><content type='html'>Since I have been working on Groovy Monkey, I have been trying to reuse the icons that are provided by the Eclipse Platform. Why? Well Eclipse does have its look and feel and where concepts in Groovy Monkey are similar to those in Eclipse, why not make it look similar? Besides I am lazy and the thought of creating a bunch of icons does not float my boat.&lt;br /&gt;&lt;br /&gt;So I took particular interest in what Mr. Ben Walding &lt;a href="http://blogs.codehaus.org/people/bwalding/archives/000779_icons_borrowed_from_eclipse.html"&gt;posted&lt;/a&gt;. He wrote a script that would goto cvs and check out the icon folders from the Eclipse projects themselves and place them on your local system. This is something I have considered myself, though I thought more about using your local install of the Eclipse SDK and extracting them.&lt;br /&gt;&lt;br /&gt;Still what he wrote was a Shell script and if it can work for you, use it. It did get me to thinking, why not try and rewrite it as a Groovy Monkey script so that you can run it in Eclipse and dump it into your workspace? This could be a really nice testcase for Groovy Monkey.&lt;br /&gt;&lt;br /&gt;So I am going to be updating this post based on my results in attempting to write it in Groovy Monkey. I mean I am writing this as I am trying to write the script and so do not be surprised if there are a few dead ends and the like.&lt;br /&gt;&lt;br /&gt;The first step is to setup Eclipse for this. We need to add the repository location :pserver:anonymous@dev.eclipse.org:/home/eclipse to the CVS Repository Explorer. Validate the connection by opening the HEAD branch under the explorer and browse around a bit just to make sure it is working. So now we should have access to the repositories to do a checkout.&lt;br /&gt;&lt;br /&gt;The next step is a bit tricky since the Eclipse Team people have yet to publish a public API for CVS, so now we have to fumble around and find what we want. I start by looking at the Eclipse Help under the "Platform Plugin Developer Guide" and check out what is there under "Team Support." On that page I see the following blurb of text:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;extension&lt;br /&gt;    point="org.eclipse.team.core.repository"&gt;&lt;br /&gt;      &amp;lt;repository&lt;br /&gt;            class="org.eclipse.team.internal.ccvs.core.CVSTeamProvider"&lt;br /&gt;            id="org.eclipse.team.cvs.core.cvsprovider"&gt;&lt;br /&gt;      &amp;lt;/repository&gt;&lt;br /&gt;&amp;lt;/extension&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The specifics are not as important as the fact that I have found my first clue, use Ctrl-Shift-T to open the class CVSTeamProvider and check it out. As I scan the API and the documentation on Repository Providers, I realize that they are mapped directly to projects and I am not sure that is what I want to do. Still one thing did catch my eye as a first target of a Groovy Monkey script. The RepositoryProvider class has static methods to allow you to find out what Repository Providers exist currently in your workspace. So I create my new Groovy Monkey Script using the "File &gt; New &gt; Other &gt; Groovy Monkey &gt; New Groovy Monkey Script" menu item to start the wizard. I name it getEclipseIcons.gm and here it is.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;--- Came wiffling through the eclipsey wood ---&lt;br /&gt;/*&lt;br /&gt; * Menu: Get Eclipse Icons&lt;br /&gt; * Kudos: ervinja&lt;br /&gt; * License: EPL 1.0&lt;br /&gt; * DOM: http://groovy-monkey.sourceforge.net/update/plugins/net.sf.groovyMonkey.dom&lt;br /&gt; * Include-Bundle: org.eclipse.team.core&lt;br /&gt; */&lt;br /&gt;import org.eclipse.team.core.RepositoryProvider&lt;br /&gt;for( providerID in RepositoryProvider.getAllProviderTypeIds() )&lt;br /&gt;{&lt;br /&gt;    out.println "providerID: ${providerID}"&lt;br /&gt;}&lt;br /&gt;--- And burbled as it ran! ---&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In the Monkey output console I get the following:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;providerID: org.eclipse.team.cvs.core.cvsnature&lt;br /&gt;providerID: org.eclipse.pde.core.BinaryRepositoryProvider&lt;br /&gt;providerID: org.polarion.team.svn.core.svnnature&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So now I know that I have three providers, one for cvs, another one that the PDE is providing and my subversion provider.&lt;br /&gt;&lt;br /&gt;Well the above script is interesting and does highlight in a simple way some of the power of Groovy Script, it does not get me closer to what I want. So I go open up the CVSRepositoryProvider in the Editor and use the "Show In &gt; Package Explorer" pop-up menu command to show me where the code is located. I see it is in the org.eclipse.team.cvs.core plugin and I notice the CVSProviderPlugin class.&lt;br /&gt;&lt;br /&gt;The CVSProviderPlugin class seems more interesting and I begin to explore by rewriting the script to the following:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;--- Came wiffling through the eclipsey wood ---&lt;br /&gt;/*&lt;br /&gt; * Menu: Get Eclipse Icons&lt;br /&gt; * Kudos: ervinja&lt;br /&gt; * License: EPL 1.0&lt;br /&gt; * DOM: http://groovy-monkey.sourceforge.net/update/plugins/net.sf.groovyMonkey.dom&lt;br /&gt; * Include-Bundle: org.eclipse.team.cvs.core&lt;br /&gt; */&lt;br /&gt;import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin&lt;br /&gt;&lt;br /&gt;def plugin = CVSProviderPlugin.getPlugin()&lt;br /&gt;for( location in plugin.getKnownRepositories() )&lt;br /&gt;{&lt;br /&gt;    out.println "Repository Location: ${location.dump()}"&lt;br /&gt;}&lt;br /&gt;--- And burbled as it ran! ---&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The output in the console is:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Repository Location: &amp;lt;org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation@63adab5c method=org.eclipse.team.internal.ccvs.core.connection.PServerConnectionMethod@262e12 user=anonymous password=null host=dev.eclipse.org port=0 root=/home/eclipse userFixed=true passwordFixed=false allowCaching=false serverPlatform=1 previousAuthenticationFailed=false&gt;&lt;br /&gt;Repository Location: &amp;lt;org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation@553087e method=org.eclipse.team.internal.ccvs.core.connection.PServerConnectionMethod@262e12 user=anonymous password=null host=dev.eclipse.org port=0 root=/cvsroot/technology userFixed=true passwordFixed=false allowCaching=false serverPlatform=0 previousAuthenticationFailed=false&gt;&lt;br /&gt;Repository Location: &amp;lt;org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation@6142ea28 method=org.eclipse.team.internal.ccvs.core.connection.ExtConnectionMethod@7b51d2 user=xxxxx password=null host=groovy-monkey.cvs.sourceforge.net port=0 root=/cvsroot/groovy-monkey userFixed=true passwordFixed=false allowCaching=false serverPlatform=0 previousAuthenticationFailed=false&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now this is looking like it can be useful.&lt;br /&gt;&lt;br /&gt;On second thought, maybe not, as I scan the Eclipse Platform code a bit more, it really looks like what I want is in the org.eclipse.team.cvs.ui plugin and that I want to try out is the CheckoutIntoOperation. CheckoutIntoOperation requires that I&lt;br /&gt;get some IRemoteFolder(s) and well the above script is useful after all. So I rewrite the script as follows:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;--- Came wiffling through the eclipsey wood ---&lt;br /&gt;/*&lt;br /&gt; * Menu: Get Eclipse Icons&lt;br /&gt; * Kudos: ervinja&lt;br /&gt; * License: EPL 1.0&lt;br /&gt; * DOM: http://groovy-monkey.sourceforge.net/update/plugins/net.sf.groovyMonkey.dom&lt;br /&gt; * Include-Bundle: org.eclipse.team.cvs.core&lt;br /&gt; * Include-Bundle: org.eclipse.team.cvs.ui&lt;br /&gt; */&lt;br /&gt;import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin&lt;br /&gt;import org.eclipse.team.internal.ccvs.ui.operations.CheckoutIntoOperation&lt;br /&gt;&lt;br /&gt;def plugin = CVSProviderPlugin.getPlugin()&lt;br /&gt;def repositoryLoc&lt;br /&gt;for( location in plugin.getKnownRepositories() )&lt;br /&gt;{&lt;br /&gt;    out.println "Repository Location: ${location.getRootDirectory()}"&lt;br /&gt;    if( location.getRootDirectory() == '/home/eclipse' )&lt;br /&gt;        repositoryLoc = location&lt;br /&gt;}&lt;br /&gt;for( member in repositoryLoc.members( null, false, null ) )&lt;br /&gt;{&lt;br /&gt;    out.println "Repository Path: ${member.getRepositoryRelativePath()}"&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;--- And burbled as it ran! ---&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I get the following output from running this modified script:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Repository Location: /home/eclipse&lt;br /&gt;Repository Location: /cvsroot/technology&lt;br /&gt;Repository Location: /cvsroot/groovy-monkey&lt;br /&gt;Repository Path: CVSROOT&lt;br /&gt;Repository Path: cdt-contrib&lt;br /&gt;Repository Path: eclipse-project-home&lt;br /&gt;Repository Path: eclipse-project-website&lt;br /&gt;Repository Path: equinox-incubator&lt;br /&gt;Repository Path: jdt-core-home&lt;br /&gt;Repository Path: jdt-debug-home&lt;br /&gt;Repository Path: jdt-doc-home&lt;br /&gt;Repository Path: jdt-ui-home&lt;br /&gt;Repository Path: org.apache.ant&lt;br /&gt;Repository Path: org.apache.lucene&lt;br /&gt;Repository Path: org.apache.xerces&lt;br /&gt;Repository Path: org.eclipse.ant.core&lt;br /&gt;Repository Path: org.eclipse.ant.optional.junit&lt;br /&gt;Repository Path: org.eclipse.ant.tests.core&lt;br /&gt;Repository Path: org.eclipse.ant.tests.ui&lt;br /&gt;Repository Path: org.eclipse.ant.ui&lt;br /&gt;Repository Path: org.eclipse.compare&lt;br /&gt;Repository Path: org.eclipse.compare.examples&lt;br /&gt;Repository Path: org.eclipse.compare.examples.xml&lt;br /&gt;Repository Path: org.eclipse.compare.tests&lt;br /&gt;Repository Path: org.eclipse.core.applicationrunner&lt;br /&gt;Repository Path: org.eclipse.core.boot&lt;br /&gt;Repository Path: org.eclipse.core.commands&lt;br /&gt;Repository Path: org.eclipse.core.components&lt;br /&gt;Repository Path: org.eclipse.core.contenttype&lt;br /&gt;Repository Path: org.eclipse.core.expressions&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now this is starting to look like the script described in Mr Walding's blog &lt;a href="http://blogs.codehaus.org/people/bwalding/archives/000779_icons_borrowed_from_eclipse.html"&gt;posting&lt;/a&gt;. We have a hint that we want to use the CheckoutIntoOperation and we now have access to the remote folders.&lt;br /&gt;&lt;br /&gt;Since each of these CVS operations can take some time to complete, I need to have a way to allow the user to monitor progress and cancel the script if they desire. Therefore next step I realize I should do is start using the monitor variable. I also want to begin to check the individual eclipse projects for icons. I know, I think, that Eclipse CVS projects like to put all their icon files into a top level directory called icons, so I am going to check for them.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;--- Came wiffling through the eclipsey wood ---&lt;br /&gt;/*&lt;br /&gt; * Menu: Get Eclipse Icons&lt;br /&gt; * Kudos: ervinja&lt;br /&gt; * License: EPL 1.0&lt;br /&gt; * DOM: http://groovy-monkey.sourceforge.net/update/plugins/net.sf.groovyMonkey.dom&lt;br /&gt; * Include-Bundle: org.eclipse.team.cvs.core&lt;br /&gt; * Include-Bundle: org.eclipse.team.cvs.ui&lt;br /&gt; */&lt;br /&gt;import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin&lt;br /&gt;import org.eclipse.team.internal.ccvs.ui.operations.CheckoutIntoOperation&lt;br /&gt;&lt;br /&gt;def plugin = CVSProviderPlugin.getPlugin()&lt;br /&gt;def repositoryLoc&lt;br /&gt;for( location in plugin.getKnownRepositories() )&lt;br /&gt;{&lt;br /&gt;    out.println "Repository Location: ${location.getRootDirectory()}"&lt;br /&gt;    if( location.getRootDirectory() == '/home/eclipse' )&lt;br /&gt;        repositoryLoc = location&lt;br /&gt;}&lt;br /&gt;monitor.beginTask( '', members.size() )&lt;br /&gt;for( member in repositoryLoc.members( null, false, null ) )&lt;br /&gt;{&lt;br /&gt;    if( monitor.isCanceled() )&lt;br /&gt;        return&lt;br /&gt;    if( !member.childExists( 'icons' ) )&lt;br /&gt;    {&lt;br /&gt;        monitor.worked( 1 )&lt;br /&gt;        continue&lt;br /&gt;    }&lt;br /&gt;    out.println "Repository Path: ${member.getRepositoryRelativePath()}"&lt;br /&gt;}&lt;br /&gt;monitor.done()&lt;br /&gt;--- And burbled as it ran! ---&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I get a surprising result from the script above, it doesn't work. I fumble about the API and notice an interesting method called fetchChildren(). I am guessing that information is cached in these classes only on request, so I add the call.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;--- Came wiffling through the eclipsey wood ---&lt;br /&gt;/*&lt;br /&gt; * Menu: Get Eclipse Icons&lt;br /&gt; * Kudos: ervinja&lt;br /&gt; * License: EPL 1.0&lt;br /&gt; * DOM: http://groovy-monkey.sourceforge.net/update/plugins/net.sf.groovyMonkey.dom&lt;br /&gt; * Include-Bundle: org.eclipse.team.cvs.core&lt;br /&gt; * Include-Bundle: org.eclipse.team.cvs.ui&lt;br /&gt; */&lt;br /&gt;import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin&lt;br /&gt;import org.eclipse.team.internal.ccvs.ui.operations.CheckoutIntoOperation&lt;br /&gt;&lt;br /&gt;def plugin = CVSProviderPlugin.getPlugin()&lt;br /&gt;def repositoryLoc&lt;br /&gt;for( location in plugin.getKnownRepositories() )&lt;br /&gt;{&lt;br /&gt;    out.println "Repository Location: ${location.getRootDirectory()}"&lt;br /&gt;    if( location.getRootDirectory() == '/home/eclipse' )&lt;br /&gt;        repositoryLoc = location&lt;br /&gt;}&lt;br /&gt;monitor.beginTask( '', members.size() )&lt;br /&gt;for( member in repositoryLoc.members( null, false, null ) )&lt;br /&gt;{&lt;br /&gt;    member.fetchChildren()&lt;br /&gt;    if( monitor.isCanceled() )&lt;br /&gt;        return&lt;br /&gt;    if( !member.childExists( 'icons' ) )&lt;br /&gt;    {&lt;br /&gt;        monitor.worked( 1 )&lt;br /&gt;        continue&lt;br /&gt;    }&lt;br /&gt;    out.println "Repository Path: ${member.getRepositoryRelativePath()}"&lt;br /&gt;}&lt;br /&gt;monitor.done()&lt;br /&gt;--- And burbled as it ran! ---&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Well the script now does what I expected to. So to complete this exercise I collect those repository resources that correspond to icon folders and place them into a list called iconFolders and prepare to make the call to CheckoutIntoOperation. I did have one more intermediate step here, I tried to check out all the icons into the same set of folders, but the CheckoutIntoOperation would wipe the directory for each project. So we check them out into a project that already exists in my workspace called GroovyMonkeyExamples and into a folder called icons. We place the icon folders into subdirectories under icons that correspond to their remote repository path. To complete we instanciate the CheckoutIntoOperation and invoke its execute() method.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;--- Came wiffling through the eclipsey wood ---&lt;br /&gt;/*&lt;br /&gt; * Menu: Get Eclipse Icons&lt;br /&gt; * Kudos: ervinja&lt;br /&gt; * License: EPL 1.0&lt;br /&gt; * DOM: http://groovy-monkey.sourceforge.net/update/plugins/net.sf.groovyMonkey.dom&lt;br /&gt; * Include-Bundle: org.eclipse.team.cvs.core&lt;br /&gt; * Include-Bundle: org.eclipse.team.cvs.ui&lt;br /&gt; */&lt;br /&gt;import org.eclipse.core.runtime.SubProgressMonitor&lt;br /&gt;import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin&lt;br /&gt;import org.eclipse.team.internal.ccvs.core.ICVSRemoteFolder&lt;br /&gt;import org.eclipse.team.internal.ccvs.ui.operations.CheckoutIntoOperation&lt;br /&gt;&lt;br /&gt;def plugin = CVSProviderPlugin.getPlugin()&lt;br /&gt;def repositoryLoc&lt;br /&gt;for( location in plugin.getKnownRepositories() )&lt;br /&gt;{&lt;br /&gt;    if( monitor.isCanceled() )&lt;br /&gt;        return&lt;br /&gt;    if( location.getRootDirectory() == '/home/eclipse' )&lt;br /&gt;        repositoryLoc = location&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;def targetProject = workspace.getRoot().getProject( 'GroovyMonkeyExamples' )&lt;br /&gt;def members = repositoryLoc.members( null, false, null )&lt;br /&gt;monitor.beginTask( '', 2 * members.size() )&lt;br /&gt;def iconFolders = []&lt;br /&gt;for( member in members )&lt;br /&gt;{&lt;br /&gt;    member.fetchChildren()&lt;br /&gt;    if( monitor.isCanceled() )&lt;br /&gt;        return&lt;br /&gt;    if( !member.childExists( 'icons' ) )&lt;br /&gt;    {&lt;br /&gt;        monitor.worked( 1 )&lt;br /&gt;        continue&lt;br /&gt;    }&lt;br /&gt;    def icons = member.getFolder( 'icons' )&lt;br /&gt;    iconFolders.add( icons )&lt;br /&gt;    monitor.worked( 1 )&lt;br /&gt;}&lt;br /&gt;iconFolders.each&lt;br /&gt;{ folder -&gt;&lt;br /&gt;    if( monitor.isCanceled() )&lt;br /&gt;        return&lt;br /&gt;    def targetFolder = targetProject.getFolder( 'icons' ).getFolder( folder.getRemoteParent().getRepositoryRelativePath() )&lt;br /&gt;    new CheckoutIntoOperation( null, folder, targetFolder, true ).execute( new SubProgressMonitor( monitor, 1 ) )&lt;br /&gt;    monitor.worked( 1 )&lt;br /&gt;}&lt;br /&gt;monitor.done()&lt;br /&gt;&lt;br /&gt;--- And burbled as it ran! ---&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This now gets what we want. We check all the Eclipse projects for icons and get them all. It can be left for homework to try and automate the task to disconnect the project from CVS and to package it up into a zip archive.&lt;br /&gt;&lt;br /&gt;There are a few notes to make here. First, this is a quick prototype and there may very well be far more efficient ways to accomplish this. In fact, you could write a seperate script to grab all the icon folders and print them out so that you can paste them into this script and check only those remote projects that have icons. A second note to make is, well this prototype only took a couple of hours to accomplish and that was with my less than ideal setup ( and I do mean less than ideal ). Imagine the time it would have taken using self hosting or deploying plugins. The last note is that of course it would be been easier to install cvs on my system and script commands to call it directly, but that would have been cheating since the whole point was to demonstrate how you could use Groovy Monkey to navigate the Eclipse Platform API world directly and easily.&lt;br /&gt;&lt;br /&gt;So we do have a functional script, but it is not very asthetically pleasing ( at least to me ) and the ability to check out remote resources from CVS into my workspace is probably something I want to do again. So in future blog entries I want to demonstrate how we can split off some functions into seperate libraries scripts that can be reused or how you can begin to prototype some plugins by starting to write the function as DOM in your workspace and be able to runtime deploy it into your current Eclipse instance.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blogs.codehaus.org/people/bwalding/archives/000779_icons_borrowed_from_eclipse.html"&gt;External Link&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18663041-115470917979576330?l=iacobus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://iacobus.blogspot.com/2006/08/groovy-monkey-eclipse-icons-script-in_04.html' title='Groovy Monkey: Eclipse Icons script in Groovy Monkey Pt 1/4'/><link rel='replies' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/115470917979576330/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18663041&amp;postID=115470917979576330' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/115470917979576330'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/115470917979576330'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/2006/08/groovy-monkey-eclipse-icons-script-in_04.html' title='Groovy Monkey: Eclipse Icons script in Groovy Monkey Pt 1/4'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18663041.post-115470505909766159</id><published>2006-08-04T08:20:00.000-07:00</published><updated>2006-08-04T09:21:46.923-07:00</updated><title type='text'>Hello there</title><content type='html'>This is my first post to my blog Iacobus.&lt;br /&gt;&lt;br /&gt;I am James Ervin and I think I will be blogging mostly on issues relating to Software Engineering in particular with regards to Eclipse, Java and dynamic languages like Groovy.  I am also the author of the &lt;a href="http://docs.codehaus.org/display/GROOVY/Groovy+Monkey"&gt;Groovy Monkey&lt;/a&gt; scripting tool for Eclipse, I encourage you to check it out at &lt;a href="http://docs.codehaus.org/display/GROOVY/Groovy+Monkey"&gt;http://docs.codehaus.org/display/GROOVY/Groovy+Monkey&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And while you are there by all means check out the &lt;a href="http://groovy.codehaus.org"&gt;Groovy&lt;/a&gt; scripting language.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18663041-115470505909766159?l=iacobus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://iacobus.blogspot.com/feeds/115470505909766159/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18663041&amp;postID=115470505909766159' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/115470505909766159'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18663041/posts/default/115470505909766159'/><link rel='alternate' type='text/html' href='http://iacobus.blogspot.com/2006/08/hello-there.html' title='Hello there'/><author><name>James E. Ervin, IV</name><uri>http://www.blogger.com/profile/08449037734048661986</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_-xK16NyT8Ko/SFay3PAbaCI/AAAAAAAAABs/efRHGuIdOAA/S220/me.jpg'/></author><thr:total>0</thr:total></entry></feed>
