<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.dzone.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
<channel>
  <title>JRoller</title>
  <link>http://www.jroller.com</link>
  
  <description>Javalobby Community Weblog Service</description>
  <language>en-us</language>
  <copyright>Copyright 2007</copyright>
  <lastBuildDate>Tue, 17 Jul 2007 11:08:23 -0400</lastBuildDate>
  <generator>Apache Roller (incubating) 3.1 (20070421020349:dave)</generator>
        <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://jroller.com/rss" type="application/rss+xml" /><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Fjroller.com%2Frss" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Fjroller.com%2Frss" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Fjroller.com%2Frss" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://jroller.com/rss" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Fjroller.com%2Frss" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Fjroller.com%2Frss" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Fjroller.com%2Frss" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
    <guid isPermaLink="false">http://www.jroller.com/robwilliams/entry/it_s_official_ca_declares</guid>
    <title>CA's Open Source Farce</title>
    <dc:creator>Rob Williams</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/NAyZz92MmGI/it_s_official_ca_declares</link>
        <pubDate>Tue, 24 Nov 2009 14:38:22 -0500</pubDate>
    <category>Technology</category>
            <description>&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/The_Eighteenth_Brumaire_of_Louis_Napoleon"&gt;&lt;img src="http://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Karl_Marx.jpg/100px-Karl_Marx.jpg" class="rightWrap"/&gt;&lt;/a&gt;So there has been a lot of talk lately about how Open Source is really turning into 'Yeah, so let's do this: you do all the work, then if it's worth a damn, a couple sharks will take it to the marketplace and make a fortune and you'll get bubkiss..' I would love to see some interviews with the original &lt;strong&gt;MySQL&lt;/strong&gt; team, see how they feel about the fact that one of Satan&amp;#8216;s minions is about to take ownership of their love child.&lt;/p&gt;

	&lt;p&gt;So this morning, &lt;strong&gt;SDTimes&lt;/strong&gt; had an article about how &lt;strong&gt;Computer Associates&lt;/strong&gt; has created an Agile management tool and their plan is to create a community around it, get a bunch of developer feedback and help, then go and commercialize it. Am I missing something? Or is this the sign that we are in the second capitulation where tragedy turns to farce? (Of course, it reminded me of the Eighteenth Brumaire article where Marx says history repeats itself, first as tragedy, then as farce.. (for any other Randian or otherwise nutballs lurking, it is possible to read Marx without believing that we all ought live in a commune&amp;#8230;)).&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/NAyZz92MmGI" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/robwilliams/entry/it_s_official_ca_declares</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/DhavalDalal/entry/downloading_files_to_desktop_in</guid>
    <title>Downloading CSV, Excel files in GWT</title>
    <dc:creator>Dhaval Dalal</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/3elEEzsKqJ8/downloading_files_to_desktop_in</link>
        <pubDate>Tue, 24 Nov 2009 11:28:25 -0500</pubDate>
    <category>Java</category>
    <category>csv</category>
    <category>download</category>
    <category>excel</category>
    <category>files</category>
    <category>gwt</category>
            <description>Alright, this one needs some plumbing, I would have expected GWT to provide some out-of-box solution for this one (just like the File-Upload widget), as its a very common feature needed by almost all web applications.  Anyways, quite a bit of server-side and client-side plumbing needs to be done in order to achieve this functionality.
&lt;p&gt;
First of all, when a user clicks a download link or button, this has to be a Synchronous request and cannot work with the Aynchronous callback handler that GWT provides.  So, I have broken this post in two parts:&lt;br/&gt;
A. The Client-Side Plumbing.&lt;br/&gt;
B. The Server-Side Plumbing.
&lt;/p&gt;
&lt;p&gt;
Also, I have BDDed the design and won't show the Scenarios and Specs, instead will focus on the key design components in this post.
&lt;/p&gt;
&lt;b&gt;&lt;u&gt;A. The Client-Side Plumbing:&lt;/u&gt;&lt;/b&gt;&lt;br/&gt; 
&lt;ol&gt;
&lt;li&gt;Starting from the UI, I have created a SyncAction representing the concept of Synchronous Action with a single method execute() on it. 
&lt;pre name="code" class="brush:java"&gt;
public interface SyncAction {
	public abstract void execute();
}
&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;&lt;code&gt;DownloadCsvAction&lt;/code&gt; is a implementation of &lt;code&gt;SyncAction&lt;/code&gt;.  So, basically, populate this action with a Url and fire execute()...thats all! Inside the execute() method, I had to make a GET synchronous request to Server Resource on &lt;code&gt;HiddenIFrame&lt;/code&gt;.  This will ensure that we do not refresh the page that we are already in.  Once execute(), is called, the server-side starts processing the incoming request. 
&lt;pre name="code" class="brush:java"&gt;
public class DownloadCsvAction implements SyncAction {
	
	private String encodedUrl;
	
	public void setEncodedUrl(String encodedUrl) {
		this.encodedUrl = encodedUrl;
	}

	public void execute() {
		HiddenIFrame frame = new HiddenIFrame(encodedUrl);
	}
}
&lt;/pre&gt;

Here is the HiddenIFrame class (I obtained this from one of the blogs and have renamed to HiddenIFrame a more meaningful name, thanks to the author, but don't recollect the blog-url, sorry!).
&lt;pre name="code" class="brush:java"&gt;
public class HiddenIFrame extends Frame {
   
   public HiddenIFrame(String url) {
      super();
      setSize("0px", "0px");
      setVisible(false);
      sinkEvents(Event.ONLOAD);
      // TODO: Add Form here so that it will POST instead of GET
      RootPanel.get().add(this);
      // Do a GET currently
      setUrl(url);
   }

   public void onBrowserEvent(Event event) {
      if (DOM.eventGetType(event) == Event.ONLOAD) {
         unsinkEvents(Event.ONLOAD);
         DOM.eventCancelBubble(event, true);
         RootPanel.get().remove(this);
      } else {
         super.onBrowserEvent(event);
      }
   }
}
&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt;In order to populate the action with URL, &lt;b&gt;GetRequestBuilder&lt;/b&gt; generates a GET URL request based on the base Url, target Url, and request params.  Here is the breakdown of the GET parameters:&lt;br/&gt;
&lt;ul&gt;
&lt;li&gt;Base Url will be fixed and it will almost always be GWT.getModuleBaseURL().&lt;/li&gt;
&lt;li&gt;Target Url is also fixed and will always be exporter.&lt;/li&gt;
&lt;li&gt;There are few reserved parameters that are required to be passed.  They are:&lt;br/&gt;
    &lt;ol&gt;
      &lt;li&gt;&lt;b&gt;serviceName&lt;/b&gt; (This is used by server side plumbing code)&lt;/li&gt;
      &lt;li&gt;&lt;b&gt;exportAs&lt;/b&gt; (This is used by server side plumbing code)&lt;/li&gt;
    &lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Add remaining parameters as per your business case (Remember its GET request, so it does have length limitation).&lt;/li&gt;
&lt;/ul&gt;
&lt;pre name="code" class="brush:java"&gt;
public class GetRequestBuilder {
	private static final String QUESTIONMARK = "?";
	private static final String EQUAL_TO = "=";
	private static final String PARAMETER_DELIMITER = "&amp;";
	
	private Map&amp;lt;String, String&amp;gt; params = new LinkedHashMap&amp;lt;String, String&amp;gt;();
	private String baseUrl;
	private String targetUrl;
	
	public GetRequestBuilder withBaseUrl(String baseUrl) {
		this.baseUrl = baseUrl;
		return this;
	}

	public GetRequestBuilder withTargetUrl(String targetUrl) {
		this.targetUrl = targetUrl;
		return this;
	}
	
	public GetRequestBuilder havingParameterWithValue(String name, String value) {
		if(value != null){
			params.put(name, value);
		}
		return this;
	}

	public String toEncodedUrl() {
		StringBuilder url = new StringBuilder();
		if(baseUrl != null) {
			url.append(baseUrl);
		}
		if(targetUrl != null) {
			url.append(targetUrl);
		}
		if(!params.entrySet().isEmpty()) {
			url.append(QUESTIONMARK);
		}
		int size = params.size();
		int count = 0;
		for (Map.Entry&amp;lt;String, String&amp;gt; requestParameter : params.entrySet()) {
			url.append(requestParameter.getKey());
			url.append(EQUAL_TO);
			url.append(requestParameter.getValue());
			if (count &amp;lt; size - 1) {
				url.append(PARAMETER_DELIMITER);
				count++;
			}
		}
		
		return URL.encode(url.toString());
	}
}


&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;

Finally, here is the client code in action using the above abstractions:
&lt;pre name="code" class="brush:java"&gt;
Button csvExport = new Button();
AbstractImagePrototype csvIcon = IconHelper.createStyle("csv");
csvExport.setIcon(csvIcon);
csvExport.setToolTip("Download CSV");
final DownloadCsvAction downloadCsvAction = new DownloadCsvAction();
String encodedUrl = 
	new GetRequestBuilder()
		.withBaseUrl(GWT.getModuleBaseURL())
		.withTargetUrl("exporter")
		.havingParameterWithValue("exportAs", "csv")
		.havingParameterWithValue("serviceName", "searchResultsExporterService")
		.havingParameterWithValue("paramOne", "someValue")
		.havingParameterWithValue("paramTwo", "someOtherValue")
		.toEncodedUrl();

downloadCsvAction.setEncodedUrl(encodedUrl));
csvExport.addSelectionListener(new SelectionListener&amp;lt;ButtonEvent&amp;gt;() {
	public void componentSelected(ButtonEvent ce) {
		downloadCsvAction.execute();
	}
});
&lt;/pre&gt;

&lt;b&gt;&lt;u&gt;B. The Server-Side Plumbing:&lt;/b&gt;&lt;/u&gt;&lt;br/&gt; 
&lt;ol&gt;
&lt;li&gt;&lt;b&gt;ExporterServlet&lt;/b&gt; is the front-ending servlet for all export requests from Web.  Look at web.xml for the settings/wiring of this servlet.  
&lt;pre name="code" class="brush:xml"&gt;
	&amp;lt;servlet&amp;gt;
		&amp;lt;servlet-name&amp;gt;exporter&amp;lt;/servlet-name&amp;gt;
		&amp;lt;servlet-class&amp;gt;com.company.product.web.servlets.ExporterServlet&amp;lt;/servlet-class&amp;gt;
		&amp;lt;load-on-startup&amp;gt;2&amp;lt;/load-on-startup&amp;gt;
	&amp;lt;/servlet&amp;gt;
	
	&amp;lt;servlet-mapping&amp;gt;
		&amp;lt;servlet-name&amp;gt;exporter&amp;lt;/servlet-name&amp;gt;
		&amp;lt;url-pattern&amp;gt;/application/exporter&amp;lt;/url-pattern&amp;gt;
	&amp;lt;/servlet-mapping&amp;gt;
&lt;/pre&gt;
&lt;p&gt;
&lt;code&gt;ExporterServlet&lt;/code&gt; converts the reserved parameters for you already.  In the service() method, you will want to add in section of code to forward the request to a particular exporter service that is represented by the serviceName parameter in the request.  
&lt;/p&gt;
&lt;pre name="code" class="brush:java"&gt;
public class ExporterServlet extends HttpServlet {

	private ApplicationContext spring;
	private SearchResultsExporterService searchResultsExporterService;

	public void init(ServletConfig servletConfig) throws ServletException {
		spring = WebApplicationContextUtils.getWebApplicationContext(servletConfig.getServletContext());
		searchResultsExporterService = (SearchResultsExporterService) spring.getBean("searchResultsExporterService");
	}

	protected void service(HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws ServletException, IOException {
		String serviceName = httpRequest.getParameter("serviceName");
		String exportAs = httpRequest.getParameter("exportAs").toUpperCase();
		ExportAs format = ExportAs.valueOf(exportAs);

		if("searchResultsExporterService".equals(serviceName)) {
			exportSearchResults(httpRequest, httpResponse, format);
			return;
		}
		httpResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
	}

	private void exportSearchResults(HttpServletRequest httpRequest, HttpServletResponse httpResponse, ExportAs format) throws IOException {
		SearchCriteria criteria = new SearchCriteria();
		criteria.setParamOne(httpRequest.getParameter("paramOne"));
		criteria.setParamTwo(httpRequest.getParameter("paramTwo"));
		searchResultsExporterService.export(httpResponse, format, criteria);
	}
}
&lt;/pre&gt;

Here is the ExportAs enumeration.
&lt;pre name="code" class="brush:java"&gt;
public enum ExportAs {
	CSV, EXCEL
}
&lt;/pre&gt;

&lt;li&gt;ExporterServlet already has Spring application context, all you have to do is spring.getBean(serviceName) to get handle to your spring configured service. For example, look at &lt;b&gt;SearchResultsExporterService&lt;/b&gt; and &lt;b&gt;DefaultSearchResultsExporterService&lt;/b&gt; as reference implementation.  Here, SearchResultsExporterService is a facade over SearchResultsService with additional responsibility of exporting search results.  In short, the exporter service will use delegation to appropriate type of Exporter (CsvExporter, ExcelExporter) as the case may be.  For additional parameters that your service method needs, you will have to reconstruct the objects on the server-side by hand if your service requires it (as this is case based, you do this by hand)...take a look at the SearchCriteria construction.
&lt;pre name="code" class="brush:java"&gt;
public interface SearchResultsExporterService {

	void export(HttpServletResponse httpResponse, ExportAs format, SearchCriteria criteria) throws IOException;

}


public class DefaultSearchResultsExporterService implements SearchResultsExporterService {

	private static final String CONTENT_DISPOSITION = "Content-Disposition";
	private static final String ATTACHMENT_FILENAME = "attachment; filename=";
	private static final String filename = "SearchResults";
	private final SearchResultsService searchResultsService;
	
	public DefaultSearchResultsExporterService(SearchResultsService searchResultsService) {
		this.searchResultsService = searchResultsService;
	}

	public void export(HttpServletResponse httpResponse, ExportAs format, SearchCriteria criteria) throws IOException {
		setContentType(httpResponse, exporter);
		setContentDisposition(httpResponse, exporter, filename);
		exporter = getExporter(format);

		OutputStream outputStream = httpResponse.getOutputStream();
		exporter.exportHeader(outputStream, getHeader());
		try {
			//Invoke the actual service and loop through the results
			for (Result result : searchResultsservice.getResults()) {
				exporter.exportRow(outputStream, resultAsRow(result));
			}
		} finally {
			exporter.flush(outputStream);
		}
	}

	private Exporter getExporter(ExportAs exportAs) {
		switch (exportAs){
			case CSV: 
				exporter = new CsvExporter();
				break;
			case EXCEL:
				exporter = new ExcelExporter();
				break;
			default:
				exporter = new CsvExporter();
		}
	}

	private void setContentType(HttpServletResponse httpResponse, Exporter exporter) {
		httpResponse.setContentType(exporter.contentType());
	}

	private void setContentDisposition(HttpServletResponse httpResponse, Exporter exporter, String filename) {
		httpResponse.setHeader(CONTENT_DISPOSITION, ATTACHMENT_FILENAME + filename + exporter.fileExtension());
	}
	
	private void setCharacterSet(HttpServletResponse httpResponse) {
		httpResponse.setCharacterEncoding("UTF-16");		
	}
	
}
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
Finally here is the exporter interface and a reference CSVExporter Reference implementation.
&lt;pre name="code" class="brush:java"&gt;
public interface Exporter {
	
	String contentType();

	String fileExtension();

	void exportHeader(OutputStream outputStream, List&lt;String&gt; header) throws IOException;
	
	void exportRow(OutputStream outputStream, List&lt;String&gt; row) throws IOException;
	
	void flush(OutputStream outputStream) throws IOException;
	
}

public class CsvExporter implements Exporter {

	private static final String COMMA = ",";
	private static final String NEWLINE = System.getProperty("line.separator");
	private static final String QUOTE = "\"";
	private String charset = "utf-8";

	public CsvExporter() {
	}
	
	public void setCharset(String charset) {
		this.charset = charset;
	}

	public String fileExtension() {
		return ".csv";
	}
	
	public String contentType() {
		return "text/csv";
	}

	public void exportHeader(OutputStream outputStream, List&amp;lt;String&amp;gt; header) throws IOException {
		writeRow(outputStream, header);
	}

	public void exportRow(OutputStream outputStream, List&amp;lt;String&amp;gt; row) throws IOException {
		writeRow(outputStream, row);
	}
	
	private void writeRow(OutputStream outputStream, List&amp;lt;String&amp;gt; row) throws IOException {
		int columns = row.size();
		for(int index = 0; index &amp;lt; columns; index++) {
			String data = row.get(index);
			if(data.contains(COMMA)) {
				write(outputStream, escape(data));
			} else {
				write(outputStream, data);
			}
			if (index &lt; columns - 1) {
				write(outputStream, COMMA);
			} else {
				write(outputStream, NEWLINE);
			}
		}
	}

	private void write(OutputStream outputStream, String data) throws IOException {
		outputStream.write(data.getBytes(Charset.forName(charset)));
	}

	private String escape(String data) {
		return QUOTE + data + QUOTE;
	}

	public void flush(OutputStream outputStream) throws IOException {
	}
}
&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
So that completes the entire design description.  Now, what can impact this design? 
&lt;ol&gt;
&lt;li&gt;Large number of parameters that GET cannot handle, at that point in time, we need to change the HiddenIFrame implementation to do a POST via a form...right now, my project does not need it and I am following YAGNI approach (You Ain't Gonna Need It)  taking a minimalist approach.&lt;/li&gt;
&lt;li&gt;Need to take care of Session Timeout.&lt;/li&gt;
&lt;li&gt;Right now as it stands, the its fixed url (and open - no authentication required), unauthorized users will be able to download.&lt;/li&gt;
&lt;/ol&gt;
First point is a scalability thing, whereas the last two points would be applicable in general to any servlet.
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/3elEEzsKqJ8" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/DhavalDalal/entry/downloading_files_to_desktop_in</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/dmdevito/entry/dual_licensing_has_a_bad</guid>
    <title>Dual licensing has a bad influence on MySQL future (more generally, on open source too)</title>
    <dc:creator>Dominique De Vito</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/kNr2Y2lDapA/dual_licensing_has_a_bad</link>
        <pubDate>Tue, 24 Nov 2009 05:55:45 -0500</pubDate>
    <category>Developer</category>
            <description>&lt;p&gt;
I have read recently
two French articles
&lt;a href="http://pro.01net.com/editorial/508665/monty-le-developpement-de-mysql-est-dans-une-situation-lamentable/"&gt;here&lt;/a&gt;
and
&lt;a href="http://www.lemondeinformatique.fr/actualites/lire-michael-widenius-%C2%A0oracle-devrait-passer-mysql-sous-license-bsd%C2%A0-29435.html"&gt;here&lt;/a&gt;
about MySQL, 
that are, Michael Widenius (Monty) interviews
made during Forum PHP (November 2009).
Reading these interviews about MySQL 
was both quite hilarious and
disappointing, too.
&lt;/p&gt;

&lt;p&gt;
In the 
&lt;a href="http://pro.01net.com/editorial/508665/monty-le-developpement-de-mysql-est-dans-une-situation-lamentable/"&gt;first interview&lt;/a&gt;,
Monty
said
he has created MariaDB, a MySQL clone (?),
and he has hired
all core MySQL developers,
and, as he said,
it proves that
Oracle has only bought MySQL trademark (an empty box ?).
Monty said too
the current MySQL development is 
a shame,
with no manager, 
no leader anymore.
He added that, yes, the GPL license enables to create a fork, 
but making a good successful fork
is not easy at all and relies on a healthy ecosystem.
If it were so easy, Oracle would have forked MySQL and 
not bought it. That's the GPL 3 problem, he concluded.
So, if Oracle purchases definitively MySQL,
it would be easy to destroy it,
and that's why EC (European Commission) decision is important.
&lt;/p&gt;

&lt;p&gt;
In the 
&lt;a href="http://www.lemondeinformatique.fr/actualites/lire-michael-widenius-%C2%A0oracle-devrait-passer-mysql-sous-license-bsd%C2%A0-29435.html"&gt;second interview&lt;/a&gt;,
MariaDB is presented as a MySQL branch (?),
and not a fork.
He said he is fighting to push EC (European Commission)
for restrictions on this purchase.
He gives 2 main propositions as follows: 
either Oracle could sell MySQL,
or Oracle could open much more MySQL uses while adopting
a more permissive license than GPL,
that is, "a BSD or Apache license: it would show
Oracle has sincere intentions".
&lt;/p&gt;

&lt;p&gt;
&lt;u&gt;Monty wants to have the cake and eat it too!&lt;/u&gt;
&lt;/p&gt;

&lt;p&gt;
Well, SUN has bought MySQL
and MySQL has received cash (and Monty too, I imagine)
for this purchase.
I imagine
he was quite happy at that time to accept
business rules, 
and a loss of control of its baby.
Now,
as things don't turn as he wished,
he complains
and asks Oracle to relicense MySQL under BSD.
What a joke!
Monty is somewhat hilarious when talking about MySQL...
&lt;/p&gt;

&lt;p&gt;
(1) Monty
complains about Oracle action,
but he could have done license change himself,
to release previously MySQL under BSD!
So,
at least,
he has not been a visionary!
&lt;/p&gt;

&lt;p&gt;
(2) It's too easy 
to want to have the cake 
(to keep the control of MySQL code through a fork with the addition of 
all rights)
and eat it too
(the dollars he got after SUN's purchase) !
&lt;/p&gt;

&lt;p&gt;
(3) There is something
he didn't say during interviews: 
while he could do a fork,
he has not anymore the copyrights
of the historic main branch
and then, 
he is not able anymore to do &lt;a href="http://linux.sys-con.com/node/49061"&gt;dual licensing&lt;/a&gt;.
Well,
he could not sell anymore to enterprises (that is,
without GPL contamination), 
he is not able to do (full) business;
and then, he complains,
while he is the main person to blame.
&lt;/p&gt;

&lt;p&gt;
&lt;u&gt;Conclusion !?&lt;/u&gt;
&lt;/p&gt;

&lt;p&gt;
Well, 
IMHO 
this MySQL
episode  suggests
that
one can't rely on dual licensing
(and should rely with more comfort 
on a RDBMS like 
&lt;a href="http://www.postgresql.org"&gt;PostgreSQL&lt;/a&gt;). 
&lt;/p&gt;

&lt;p&gt;
Indeed, dual licensed projects
are not 
true open source projects (I am against 
dual licensing for years!).
Well, 
it's all about
the
&lt;a href="http://en.wikipedia.org/wiki/Letter_and_spirit_of_the_law"&gt;letter and spirit of the law&lt;/a&gt;.
These are open source projects, they respect the letter,
but IMHO
they don't respect the spirit,
they have not all pros/features
one naturally
associates
with true open source projects;
and they can easily turn against users. 
&lt;/p&gt;

&lt;p&gt;
Beyond dual licensing,
this MySQL episode
points the GPL flaws.
&lt;a href="http://en.wikipedia.org/wiki/Richard_Stallman"&gt;RMS&lt;/a&gt;
has
sent a letter to EC to stop MySQL
purchase as he wrote
that Oracle purchase would stop MySQL evolution,
and will cause prejudice to MySQL users.
Then, he confesses (without saying it)
that GPL is not 
able to protect
open source project evolution
and to make live his
motto
&lt;a href="http://en.wikipedia.org/wiki/Libert%C3%A9,_%C3%A9galit%C3%A9,_fraternit%C3%A9"&gt;Liberty, equality, fraternity&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
I have written
in my post
&lt;a href="http://www.jroller.com/dmdevito/entry/rich_hunter_and_a_darwinian"&gt;Rich Hunter 
	and a darwinian point of view for open source license debate&lt;/a&gt;
that 
"the GPL looks like 
often the license of those who are mavericks, pioneers who invest a new land and don't want 
to end up naked after having done a lot of effort, with courage. I think (but one would have to verify) 
it reflects somewhat a "commando spirit" of those who enter first 
a land where only fighting proprietary software owners are, since, maybe years."
While open source developers
need multiple licenses, that live and play together
in an ecosystem, as written in my 
&lt;a href="http://www.jroller.com/dmdevito/entry/rich_hunter_and_a_darwinian"&gt;post&lt;/a&gt;,
I strongly doubt
dual licensing (and beyond that, GPL) 
is adapted 
to open source in a professional way/context,
because dual licensing is all about lock-in, and not exactly true
open source.
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/kNr2Y2lDapA" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/dmdevito/entry/dual_licensing_has_a_bad</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/kaiulrich/entry/spring_json_view_1_23</guid>
    <title>spring-json view 1.2.1 added to maven 2 repository</title>
    <dc:creator>Kai Ulrich</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/6YqiQYxDY_o/spring_json_view_1_23</link>
        <pubDate>Tue, 24 Nov 2009 03:23:00 -0500</pubDate>
    <category>Java</category>
    <category>java</category>
    <category>json</category>
    <category>mvc</category>
    <category>spring</category>
            <description>&lt;p&gt;&lt;p&gt;&lt;a href="http://spring-json.sourceforge.net/" title="http://spring-json.sourceforge.net/"&gt;http://spring-json.sourceforge.net/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Spring Json-View adds JavaScript Object Notation (JSON) support to&lt;br/&gt;
Spring-MVC. Now spring-json 1.2 is added to the maven 2 central repository :&lt;/p&gt;&lt;p&gt;&lt;a class="externalLink" href="http://repo1.maven.org/maven2" title="http://repo1.maven.org/maven2"&gt;http://repo1.maven.org/maven2&lt;/a&gt;&lt;/p&gt;&lt;p&gt;usage: &lt;br /&gt;&lt;/p&gt;&amp;lt;dependency&amp;gt;&lt;br /&gt;&lt;br/&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;groupId&amp;gt;net.sf.spring-json&amp;lt;/groupId&amp;gt;&lt;br /&gt;&lt;br/&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;artifactId&amp;gt;spring-json&amp;lt;/artifactId&amp;gt;&lt;br /&gt;&lt;br/&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;version&amp;gt;1.2.1&amp;lt;/version&amp;gt;&lt;br /&gt;&lt;br/&gt;
    &amp;lt;/dependency&amp;gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/6YqiQYxDY_o" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/kaiulrich/entry/spring_json_view_1_23</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/perryn/entry/given_when_then_and_how</guid>
    <title>Given, When, Then and how not to do it</title>
    <dc:creator>Perryn Fowler</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/BDSRThbETTU/given_when_then_and_how</link>
        <pubDate>Tue, 24 Nov 2009 01:04:18 -0500</pubDate>
    <category>Ruby</category>
    <category>cucumber</category>
    <category>gherkin</category>
    <category>given</category>
    <category>then</category>
    <category>when</category>
    <atom:summary type="html">A few mistakes I have seen people make when writing cucumber scenarios using given/when/then format</atom:summary>        <description>&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://wiki.github.com/aslakhellesoy/cucumber/given-when-then"&gt;Given, When, Then&lt;/a&gt; format is often used when
writing scenarios for automated acceptance tests. &lt;a href="http://cukes.info"&gt;Cucumber&lt;/a&gt; enforces this format.
&lt;br /&gt;&lt;br /&gt;
This format is popular because
&lt;ul&gt;
&lt;li&gt;it enables us to express our requirements in plain english&lt;/li&gt;
&lt;li&gt;it forces us to express each scenario clearly in terms of interactions with the system &lt;/li&gt;
&lt;/ul&gt;

For example:&lt;br /&gt;&lt;br /&gt;
&lt;code&gt;
GIVEN a registered user 'bob'&lt;br /&gt;
WHEN a user navigates to the Sign In page&lt;br /&gt;
AND the user signs in as 'bob'&lt;br /&gt;
THEN the profile page for 'bob' will be displayed&lt;br /&gt;
&lt;/code&gt;
&lt;br /&gt;
There are quite a few resources &lt;a href="http://www.google.com.au/search?q=%22given+when+then%22"&gt;about&lt;/a&gt; that explain Given-When-Then, but I thought I would list down a few mistakes and misunderstandings I often see when people first start trying to use it. Or at least, things that differ from the way &lt;b&gt;I&lt;/b&gt; like to do things ;)
&lt;br /&gt;

&lt;h3&gt;The GIVEN clause&lt;/h3&gt;

The &lt;b&gt;given&lt;/b&gt; clause sets up the initial state for the scenario we are testing.
&lt;br /&gt;&lt;br /&gt;
As such, it
&lt;ul&gt;&lt;li&gt;may interact with the system&lt;/li&gt;&lt;/ul&gt;
But should not
&lt;ul&gt;&lt;li&gt;perform interactions relevant to the scenario itself&lt;/li&gt;&lt;/ul&gt;
&lt;br /&gt;
 For example, I think the following would &lt;b&gt;not&lt;/b&gt; be an appropriate way to
express the example above because the GIVEN step is performing an
interaction that is part of the  thing we are trying to test, instead
of just set up for it.
&lt;br /&gt;&lt;br /&gt;
&lt;code&gt;
GIVEN a registered user 'bob' has signed in &lt;br /&gt;
THEN the profile page for 'bob' will be displayed
&lt;/code&gt;
&lt;br /&gt;&lt;br /&gt;
Also it
&lt;ul&gt;&lt;li&gt;should be expressed as a pre-existing condition&lt;/li&gt;&lt;/ul&gt;
But should not
&lt;ul&gt;&lt;li&gt;be expressed like an action&lt;/li&gt;&lt;/ul&gt;
&lt;br /&gt;
For example, I think the following would &lt;b&gt;not&lt;/b&gt; be an appropriate way to express
the example above because the GIVEN step sounds like it is an action
rather than an existing condition
&lt;br /&gt;&lt;br /&gt;
&lt;code&gt;
GIVEN a user registers as 'bob'&lt;br/&gt;
WHEN a user navigates to the Sign In page&lt;br/&gt;
AND the user signs in as 'bob'&lt;br/&gt;
THEN the profile page for 'bob' will be displayed
&lt;/code&gt;
&lt;br /&gt;&lt;br /&gt;

&lt;h3&gt;The WHEN clause&lt;/h3&gt;

The &lt;b&gt;when&lt;/b&gt; clause describes the things that the user (or some other actor) does to the
system. 

&lt;br /&gt;&lt;br /&gt;
As such, it
&lt;ul&gt;&lt;li&gt;should describe what the user does&lt;/li&gt;&lt;/ul&gt;
But should not
&lt;ul&gt;&lt;li&gt;describe things that the system does&lt;/li&gt;&lt;/ul&gt;
&lt;br /&gt;
For example, I think the second WHEN clause below is an inappropriate use of
WHEN since it describes something the system does.
&lt;br /&gt;&lt;br /&gt;
&lt;code&gt;
GIVEN a registered user 'bob'&lt;br/&gt;
WHEN a user navigates to the Sign In page&lt;br/&gt;
AND the user signs in as 'bob'&lt;br/&gt;
WHEN the profile page for 'bob' is displayed&lt;br/&gt;
THEN the username 'bob' will be displayed
&lt;/code&gt;
&lt;br /&gt;&lt;br /&gt;


&lt;h3&gt;The THEN clause&lt;/h3&gt;

The &lt;b&gt;then&lt;/b&gt; clause describes the things that the system is expected to
do. ( in response to something done in a &lt;b&gt;when&lt;/b&gt; clause)


&lt;br /&gt;&lt;br /&gt;
As such, it
&lt;ul&gt;&lt;li&gt;should describe what the system should do&lt;/li&gt;&lt;/ul&gt;
But should not
&lt;ul&gt;&lt;li&gt;describe things that the user does&lt;/li&gt;&lt;/ul&gt;
&lt;br /&gt;
For example, I think the following contains  innapropriate use of THEN since it
is being used to describe things that the user does. Although this
still presents a coherent narrative, it blurs the distinction between
what the user does and what we expect the system to do in response.
&lt;br /&gt;&lt;br /&gt;
&lt;code&gt;
GIVEN a registered user 'bob'&lt;br/&gt;
THEN a user navigates to the Sign In page&lt;br/&gt;
THEN the user signs in as 'bob'&lt;br/&gt;
THEN the profile page for 'bob' is displayed
&lt;/code&gt;
&lt;br /&gt;&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/BDSRThbETTU" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/perryn/entry/given_when_then_and_how</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/agoubard/entry/online_text_to_speech_application</guid>
    <title>Online text to speech application Japplis Speech 1.2 has been released</title>
    <dc:creator>Anthony Goubard</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/y9DlhNHu94o/online_text_to_speech_application</link>
        <pubDate>Tue, 24 Nov 2009 01:00:00 -0500</pubDate>
    <category>Java</category>
    <category>online</category>
    <category>speech</category>
    <category>t2s</category>
    <category>text</category>
    <category>text2speech</category>
            <description>&lt;p&gt;I've just released &lt;a href="http://speech.japplis.com/"&gt;Japplis Speech&lt;/a&gt; 1.2.&lt;/p&gt;


&lt;p&gt;Japplis Speech is a text to speech application, that includes the possibility to read the text while you're typing it.&lt;/p&gt;


&lt;p&gt;In this release the start-up has been greatly improved.&lt;br/&gt;
This release also includes &lt;a href="http://speech.japplis.com/plus.html"&gt;Japplis Speech +&lt;/a&gt; which is the similar to Japplis Speech. Japplis Speech + has a better voice quaility but a slower start-up time.&lt;/p&gt;


&lt;p&gt;&lt;a href="http://speech.japplis.com/"&gt;&lt;img src="http://speech.japplis.com/images/ie-screen.jpg"&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/y9DlhNHu94o" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/agoubard/entry/online_text_to_speech_application</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/peter_pilgrim/entry/xenondatagrid_m4_0_nelson_framework</guid>
    <title>XenonDataGrid M4.0, Nelson Framework *WIP*</title>
    <dc:creator>Peter Pilgrim</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/STwyGvQ5wG4/xenondatagrid_m4_0_nelson_framework</link>
        <pubDate>Mon, 23 Nov 2009 18:04:54 -0500</pubDate>
    <category>Java</category>
    <category>control</category>
    <category>datagrid</category>
    <category>framework</category>
    <category>javafx</category>
    <category>m4</category>
    <category>nelson</category>
    <category>release</category>
    <category>ria</category>
    <category>ui</category>
    <category>xenondatagrid</category>
            <description>&lt;h1&gt;XenonDataGrid M4.0, Nelson Framework *WIP*&lt;/h1&gt;

&lt;br&gt;

&lt;p&gt;
Hi All &lt;br&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
I am very happy make the release &lt;b&gt;Milestone 4.0&lt;/b&gt; release of the &lt;a title="Nelson Framework JavaFX Data Grid Component" href="http://kenai.com/projects/nelson/pages/Home" id="y3wr"&gt;Nelson Core JavaFX Framework and the Xenon Data Grid Component&lt;/a&gt;. You can find the &lt;a title="download nelson-core-1.0-M4.jar on Xenonique" href="http://kenai.com/projects/nelson/downloads" id="j6ii"&gt;download nelson-core-1.0-M4.jar on Xenonique&lt;/a&gt;. I have already uploaded the &lt;a title="PDF slides to my talk on XenonDataGrid" href="http://www.jroller.com/peter_pilgrim/entry/devoxx_2009_xenon_data_grid" id="nsfk"&gt;PDF slides to my talk on XenonDataGrid&lt;/a&gt; at Devoxx 2009. &lt;br&gt;
&lt;br&gt;
&lt;div id="broh" style="text-align: left;"&gt;
&lt;div id="rtuh" style="text-align: left;"&gt;&lt;a title="  Devoxx Master 2009 Launcher " href="http://www.xenonsoft.com/jws/DevoxxMaster-2009-1.0-M4.jnlp"&gt; &lt;img src="http://docs.google.com/File?id=df5jk3g7_332g7n7h5dr_b" height="334" width="501"&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;
The &lt;a title="Devoxx Master Launcher (JNLP)" href="http://www.xenonsoft.com/jws/DevoxxMaster-2009-1.0-M4.jnlp" id="wpcz"&gt;Devoxx Master Launcher (JNLP)&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;h3&gt;Release Notes&lt;/h3&gt;
&lt;br&gt;
These are release notes for Nelson Core JavaFX framework.&lt;br&gt;
&lt;a title="http://www.jroller.com/peter_pilgrim/entry/the_nelson_framework" href="http://www.jroller.com/peter_pilgrim/entry/the_nelson_framework" id="jr1o"&gt;http://www.jroller.com/peter_pilgrim/entry/the_nelson_framework&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
Milestone 4&lt;br&gt;
=============&lt;br&gt;
&lt;br&gt;
The ``XenonDataGrid'' data grid UI component is the fundamental and paramount change in this release.&lt;br&gt;
&lt;br&gt;
The Key Changes&lt;br&gt;
&lt;br&gt;
Support for more FX Types instead of Strin now includes Boolean, Character, Byte, Short, Integer, Long, Float and Double.&lt;br&gt;
&lt;br&gt;
``DynamicGridCellRenderer'' is a new renderer with a ``Painter'' architecture to support different FXType.&lt;br&gt;
&lt;br&gt;
``BooleanGridCellPainter'' is a painter for rendering Boolean cells.&lt;br&gt;
&lt;br&gt;
``BooleanEditorCellPainter'' is a editor component to changing Boolean cells.&lt;br&gt;
&lt;br&gt;
``DecimalGridCellPainter'' is a painter for rendering decimal types, namely Floats and Doubles.&lt;br&gt;
&lt;br&gt;
``IntegralGridCellPainter'' is a painter dedicated for rendering integer types, namely Byte, Short, Integer and Long&lt;br&gt;
&lt;br&gt;
``TextGridCellPainter'' is a renderer for rendering String as before.&lt;br&gt;
&lt;br&gt;
``RegisterEditorTableModelVariant'' - a mixin for table model to support editor renderor associated an FXType.&lt;br&gt;
&lt;br&gt;
``LifecycleManager'' is a store for managing dynamic painters, associated with DynamicGridCellRenderer&lt;br&gt;
&lt;br&gt;
A new plug-in keyboard selection strategy. The default one is called ``DefaultNavigationStrategy''&lt;br&gt;
&lt;br&gt;
A new package ``com.xenonsoft.nelson.scene.layout.grid.conversion'&lt;br&gt;
&lt;br&gt;
A new plug-in type conversion strategy. The default one is called ``StringConverter''&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
JIRA ISSUES&lt;br&gt;
============&lt;br&gt;
&lt;br&gt;
&lt;a title="http://kenai.com/jira/browse/NELSON-18" href="http://kenai.com/jira/browse/NELSON-18" id="swtz"&gt;http://kenai.com/jira/browse/NELSON-18&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; XDG has scroll wheel support&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; XDG has plug-in keyboard navigation *FIXED*&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a title="http://kenai.com/jira/browse/NELSON-14" href="http://kenai.com/jira/browse/NELSON-14" id="jkvu"&gt;http://kenai.com/jira/browse/NELSON-14&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Users need to be able to display application data in many types in JavaFX.&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Consequently, the XDG needs data adaptors, and renderers for types other java.lang.String. *INCOMPLETE*&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; So this M4 release features an BooleanGridCellPainter, IntegralGridCellPainter, DecimalGridCellPainter etc&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a title="http://kenai.com/jira/browse/NELSON-20" href="http://kenai.com/jira/browse/NELSON-20" id="tbm4"&gt;http://kenai.com/jira/browse/NELSON-20&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Introduce Keyboard Navigation Strategy in XDG *FIXED*&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a title="http://kenai.com/jira/browse/NELSON-12" href="http://kenai.com/jira/browse/NELSON-12" id="y3l1"&gt;http://kenai.com/jira/browse/NELSON-12&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Redesign and refactor reordering layer API *FIXED*&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a title="http://kenai.com/jira/browse/NELSON-10" href="http://kenai.com/jira/browse/NELSON-10" id="sc9:"&gt;http://kenai.com/jira/browse/NELSON-10&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Improve JavaFXDoc to a higher level *FIXED*&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a title="http://kenai.com/jira/browse/NELSON-19" href="http://kenai.com/jira/browse/NELSON-19" id="yckw"&gt;http://kenai.com/jira/browse/NELSON-19&lt;/a&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Graphic Niggles *INCOMPLETE*&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a title="http://kenai.com/jira/browse/NELSON-11" href="http://kenai.com/jira/browse/NELSON-11" id="nfsz"&gt;http://kenai.com/jira/browse/NELSON-11&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Reordering of Rows and Columns is broken *FIXED*&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a title="http://kenai.com/jira/browse/NELSON-13" href="http://kenai.com/jira/browse/NELSON-13" id="v904"&gt;http://kenai.com/jira/browse/NELSON-13&lt;/a&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Refactor by name XDG scroll properties *FIXED*&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a title="http://kenai.com/jira/browse/NELSON-7" href="http://kenai.com/jira/browse/NELSON-7" id="vrbu"&gt;http://kenai.com/jira/browse/NELSON-7&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; DataGrid should allow the application developer to listen to important events *INCOMPLETE*&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; M4 includes a ``ScrollEvent'' type.&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a title="http://kenai.com/jira/browse/NELSON-17" href="http://kenai.com/jira/browse/NELSON-17" id="x9lu"&gt;http://kenai.com/jira/browse/NELSON-17&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; XDG needs skinnable subcomponents *OPEN*&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a title="http://kenai.com/jira/browse/NELSON-16" href="http://kenai.com/jira/browse/NELSON-16" id="llft"&gt;http://kenai.com/jira/browse/NELSON-16&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Dynamic creation of rendering. *FIXED*&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; See ``DynamicGridCellRenderer'' and the new painter infrastructure&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a title="http://kenai.com/jira/browse/NELSON-15" href="http://kenai.com/jira/browse/NELSON-15" id="t6aq"&gt;http://kenai.com/jira/browse/NELSON-15&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Unify render layer and table model data structures? *CLOSED*&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Based on discussions at Devoxx 2009, where an audience participant asked about filtering of&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; the data model, I feel this is the wrong approach. This issue is closed&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
Peter Pilgrim&lt;br&gt;
Monday, 23 November 2009&lt;br&gt;
&lt;br clear="all"&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/STwyGvQ5wG4" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/peter_pilgrim/entry/xenondatagrid_m4_0_nelson_framework</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/HazemBlog/entry/my_interview_with_developerworks</guid>
    <title>My interview with developerWorks</title>
    <dc:creator>Hazem Ahmed Saleh</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/sViQLaXC8EY/my_interview_with_developerworks</link>
        <pubDate>Mon, 23 Nov 2009 16:56:41 -0500</pubDate>
    <category>Java</category>
    <category>developerworks</category>
    <category>jsf</category>
    <category>myfaces</category>
    <category>opensource</category>
            <description>&lt;br&gt;
(Valerie Skinner - a developerWorks team member) invited me for an interview about my open source experience.&lt;br&gt;
&lt;br&gt;
Here is the interview script:&lt;br&gt;
&lt;a href="https://www.ibm.com/developerworks/mydeveloperworks/blogs/yinmeetsyang/entry/interview_with_hazem_saleh12?lang=en_us"&gt;https://www.ibm.com/developerworks/mydeveloperworks/blogs/yinmeetsyang/entry/interview_with_hazem_saleh12?lang=en_us&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
I wish it can be useful.&lt;br&gt;
&lt;br&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/sViQLaXC8EY" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/HazemBlog/entry/my_interview_with_developerworks</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/trickymar/entry/desperate_binding_module_in_swing</guid>
    <title>Desperate Binding Module in Swing</title>
    <dc:creator>Mario García</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/YY6C1FGKfls/desperate_binding_module_in_swing</link>
        <pubDate>Mon, 23 Nov 2009 12:14:51 -0500</pubDate>
    <category>Swing</category>
            <description>&lt;p&gt;&lt;p&gt;Buff, If I knew how much I was going to suffer doing a binding module... aaarrggg!!&lt;/p&gt;&lt;p&gt;It's really difficult to establish a basement for building something scalable or even maintainable. I've spent a whole week and I think it's enough for me, tomorrow I'm going to see if I come to an end or I leave it.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;I took a look at beansbindings and jgoodies binding as a start, but at the beginning was like reading chinese for me. Swing is a nightmare for doing that sort of things.&lt;/p&gt;&lt;p&gt;The only conclusion I could come to was that I had to do a part for binding properties between beans and ui components, and another part for binding lists with UI components.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;jgoodies binding: &lt;a href="https://binding.dev.java.net/"&gt;&lt;span id="main" style="visibility: visible;"&gt;&lt;span id="search" style="visibility: visible;"&gt;&lt;cite&gt;https://binding.dev.java.net/&lt;/cite&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;beansbinding: &lt;a href="https://beansbinding.dev.java.net"&gt;&lt;span id="main" style="visibility: visible;"&gt;&lt;span id="search" style="visibility: visible;"&gt;&lt;cite&gt;https://beansbinding.dev.java.net&lt;/cite&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/YY6C1FGKfls" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/trickymar/entry/desperate_binding_module_in_swing</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/DhavalDalal/entry/session_handling_in_gwt</guid>
    <title>Session Handling in GWT</title>
    <dc:creator>Dhaval Dalal</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/OU_eiub2tU0/session_handling_in_gwt</link>
        <pubDate>Mon, 23 Nov 2009 07:40:31 -0500</pubDate>
    <category>Java</category>
    <category>gilead</category>
    <category>gwt</category>
    <category>session</category>
            <description>On my current GWT project, I needed to re-direct the user to the Login Dialog box upon session timeout on the server.  In traditional web applications, it can be done either by taking a Filter-based approach or a inheriting from a common Controller Servlet; with GWT, it gets a little different...especially on the client-side...and depending on the frameworks that you use, you may need to do some additional work other than the server-side.    On my project, I chose the Spring, Hibernate, Gilead and GWT-SL as a stack of technologies that will allow me to use the DDD approach so that I do not have to code a DTO layer, refer to my &lt;a href="http://www.jroller.com/DhavalDalal/entry/a_note_on_technology_frameworks"&gt;earlier post&lt;/a&gt; for tech frameworks stack.

&lt;p&gt;
First of all, some context on GWT method exceptions. In GWT, call to an asynchronous method throws an exception or it returns the Object that you want to do something with on the client-side.  So, the strategy that I adopted for session handling is to throw an Exception upon Session-Timeout and let each response handler in the application deal with that exception.  But this means that each response handler has to deal with Session-Timeout related exception....this calls for creating a generic mechanism for handling session timeout for all reponse handlers within the application.  Hence, I came up with &lt;code&gt;ApplicationResponseHandler&lt;/code&gt;, from which all the other response handlers will derive from.  ApplicationResponse handler will take care of client-side handling of session timeout and/or other generic stuff.  In the code below, when I receive message keys pertaining to session timeout, or not-logged-in or logout error, I dispatch a Logout event using the GWT's event Dispatcher.  But, if the message keys are not the ones that &lt;code&gt;ApplicationResponseHandler&lt;/code&gt; is not interested in handling, it calls the uponFailure(), and so with uponSuccess().

&lt;pre name="code" class="brush:java"&gt;
public abstract class ApplicationResponseHandler&amp;lt;T&amp;gt; implements AsyncCallback&amp;lt;T&amp;gt; {

	public ApplicationResponseHandler() {
	}
	
	public final void onFailure(Throwable caught) {
		String messageKey = caught.getMessage();
		if (
			(GatewayMessageKeys.SESSION_TIMEOUT.equals(messageKey)) ||
			(GatewayMessageKeys.NOT_LOGGED_IN.equals(messageKey)) ||
			(GatewayMessageKeys.LOGOUT_ERROR.equals(messageKey))) {
			dispatchLogoutEvent();
			return;
		}
		uponFailure(caught);
	}

	protected void dispatchLogoutEvent() {
		Dispatcher.get().dispatch(GatewayEvents.Logout);
	}
	
	public final void onSuccess(T result) {
		uponSuccess(result);
	};
	
	public abstract void uponSuccess(T result);
	public abstract void uponFailure(Throwable problem);
}
&lt;/pre&gt;
&lt;p&gt;
Here are the GatewayMessage keys, packed in &lt;code&gt;GatewayMessageKeys&lt;/code&gt; interface
&lt;/p&gt;
&lt;pre name="code" class="brush:java"&gt;
public final class GatewayMessageKeys {
	private GatewayMessageKeys() {
	}
	public static final String INCORRECT_CREDENTIALS = "incorrectCredentials"; 
	public static final String ACCOUNT_DOES_NOT_EXIST = "accountDoesNotExist";
	public static final String SERVICE_UNAVAILABLE = "serviceUnavailable";
	
	public static final String NOT_LOGGED_IN = "notLoggedIn";
	public static final String LOGOUT_SUCCESSFUL = "logoutSuccessful";
	public static final String LOGOUT_ERROR = "logoutError";
	public static final String SESSION_TIMEOUT = "sessionTimeout";
}
&lt;/pre&gt;

&lt;p&gt;
Having taken care of the client-side plumbing, lets move on to the server-side.  Further, the GWT's RPC encoding and processing logic examines interfaces for declared exceptions and if your method encounters an exception that is &lt;b&gt;NOT&lt;/b&gt; declared in the throws clause of the RPC interface, then GWT throws an &lt;code&gt;UnexpectedException&lt;/code&gt; instead to the client and you will see...&lt;b&gt;"Call failed on server...See server log for details"&lt;/b&gt;.  This implies that GWT demands that server-side RPC method needs to throw a Checked Exception.  So, I came up with this class called &lt;b&gt;&lt;code&gt;ApplicationException&lt;/code&gt;&lt;/b&gt;, from which all our other Exception subclasses will inherit from.
&lt;/p&gt;
&lt;pre name="code" class="brush:java"&gt;
/**
 * Please do not add Throwable cause constructors, because we do 
 * not want to reveal the stack trace to the client...obvious security 
 * risk! In your exception class, if you still need to provide a 
 * throwable cause constructor (due to some third party library 
 * dependency or due to any other reason), then make a call to 
 * super(message) constructor of this class.
 */
public class ApplicationException extends Exception {

	public ApplicationException() {
		super();
	}

	public ApplicationException(String message) {
		super(message);
	}
}
&lt;/pre&gt;
&lt;p&gt;
Below is the &lt;code&gt;GatewayService&lt;/code&gt; that is called when the user logs-in to and logs-out of the application.
&lt;/p&gt;
&lt;pre name="code" class="brush:java"&gt;
@RemoteServiceRelativePath("services/gatewayService")
public interface GatewayService extends RemoteService {
	User login(String userName, String password) throws LoginFailure;
	public String logout(String uid) throws LogoutFailure;
}
&lt;/pre&gt;

In the &lt;code&gt;DefaultGatewayService&lt;/code&gt; implementation, as I am using the GWT-SL, it helps me export regular Spring-configured services as GWT-RPC services, the only problem is that these services are not HttpServletRequest/Response aware.  Hence, I make them HttpServletRequest/Response aware by injecting &lt;code&gt;HttpContext&lt;/code&gt; when the service is created by Spring.  Apart from that, I inject the authenticator used by the login() method to authenticate the user.

&lt;pre name="code" class="brush:java"&gt;
public class DefaultGatewayService implements GatewayService {
	
	public static final String TICKET = "__APPLICATION_TICKET__";
	private final Authenticator authenticator;
	private final HttpContext httpContext;

	public DefaultGatewayService(Authenticator authenticator, HttpContext httpContext) {
		this.authenticator = authenticator;
		this.httpContext = httpContext;
	}
	
	@Transactional(readOnly = true)
	public User login(String uid, String password) throws LoginFailure {
		HttpSession session = getHttpServletRequest().getSession(false);
		if(exists(session)) {
			session.invalidate();
		}
		User user = authenticator.authenticate(uid, password);
		createNewSession(user);
		return user;
	}

	private void createNewSession(User user) {
		HttpSession session = getHttpServletRequest().getSession();
		session.setAttribute(USER, user.getUid());
	}
	
	public String logout(String uid) throws LogoutFailure {
		if (doesNotExists(uid)) {
			throw new LogoutFailure(GatewayMessageKeys.NOT_LOGGED_IN);
		}
		
		HttpServletRequest httpServletRequest = getHttpServletRequest();
		HttpSession session = httpServletRequest.getSession(false);
		String userIdInSession = (String) session.getAttribute(USER);
		if(uid.equals(userIdInSession)) {
			session.setAttribute(USER, null);
			logger.info(GatewayMessageKeys.LOGOUT_SUCCESSFUL + " For User: " + uid);
		} else {
			logger.error("User " + uid + "Not in HttpSession");
		}
		session.invalidate();
		return GatewayMessageKeys.LOGOUT_SUCCESSFUL;
	}

	private String getApplicationTicketFromCookie() {
		HttpServletRequest httpRequest = getHttpServletRequest();
		Cookie[] cookies = httpRequest.getCookies();
		for (Cookie cookie : cookies) {
			if(TICKET.equals(cookie.getName())) {
				return cookie.getValue();
			}
		}
		return null;
	}
	
	private boolean doesNotExists(String uid) {
		return uid == null || uid == "";
	}

	protected HttpServletRequest getHttpServletRequest() {
		return httpContext.getHttpServletRequest();
	}
}
&lt;/pre&gt;
&lt;p&gt;
Here is the &lt;code&gt;HttpContext&lt;/code&gt;, that uses a simple ThreadLocal based implementation.
&lt;/p&gt;
&lt;pre name="code" class="brush:java"&gt;
public interface HttpContext {
	
	public void setHttpServletRequest(HttpServletRequest request);
	
	public HttpServletRequest getHttpServletRequest();
	
	public void setHttpServletResponse(HttpServletResponse response);
	
	public HttpServletResponse getHttpServletResponse();

}

// Implementation
public class ApplicationHttpContext implements HttpContext {
	
	private static ThreadLocal&amp;lt;HttpServletRequest&amp;gt; requestThreadLocal = new ThreadLocal&amp;lt;HttpServletRequest&amp;gt;();
	
	private static ThreadLocal&amp;lt;HttpServletResponse&amp;gt; responseThreadLocal = new ThreadLocal&amp;lt;HttpServletResponse&amp;gt;();

	@Override
	public HttpServletRequest getHttpServletRequest() {
		return requestThreadLocal.get();
	}

	@Override
	public HttpServletResponse getHttpServletResponse() {
		return responseThreadLocal.get();
	}

	@Override
	public void setHttpServletRequest(HttpServletRequest request) {
		requestThreadLocal.set(request);
	}

	@Override
	public void setHttpServletResponse(HttpServletResponse response) {
		responseThreadLocal.set(response);
	}
}
&lt;/pre&gt;
&lt;p&gt;
The next most interesting thing, is the &lt;code&gt;ApplicationGWTRPCServiceExporter&lt;/code&gt; which would be used by all the Spring managed services to wrap themselves in.  It is in this interceptor where session timeout validation is performed for all calls made to any of the services within the system. Here are the steps that happen in the &lt;b&gt;invokeMethodOnService()&lt;/b&gt; method:
&lt;ul&gt;
&lt;li&gt;Inject HttpContext&lt;/li&gt;
&lt;li&gt;Check whether a session exists or not:
&lt;ul&gt;
&lt;li&gt; If the session does not exist:
    &lt;ul&gt;
    &lt;li&gt;If the incoming service all is that of login() method, then allow the user to login and return.&lt;/li&gt;
    &lt;li&gt;Else use reflection to examine the interface method called and use the declared exception of that method to 
throw it to the caller with message GatewayMessageKeys.SESSION_TIMEOUT.&lt;/li&gt;
    &lt;/ul&gt;
&lt;/li&gt;    
&lt;li&gt; If session exists: Determine whether user is present in the session:
   &lt;ul&gt;
    &lt;li&gt;If user is in session, allow the service call&lt;/li&gt;
    &lt;li&gt;If user is not in session, wrap in target method exception and throw it and thus don't allow the service call&lt;/li&gt;
   &lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;  
&lt;pre name="code" class="brush:java"&gt;
public class ApplicationGWTRPCServiceExporter extends HB4GWTRPCServiceExporter {
	
	private final HttpContext httpContext;
	private static final String LOGIN_METHOD = "login";
	
	public ApplicationGWTRPCServiceExporter(HttpContext httpContext, UserRepository userRepository) {
		this.httpContext = httpContext;
	}

	@Override
	public String invokeMethodOnService(Object service, Method targetMethod, Object[] targetParameters, RPCRequest rpcRequest) throws Exception {
		HttpServletRequest request = getHttpRequest();
		HttpServletResponse response = getHttpResponse();
		
		injectHttpContext(request, response);
		HttpSession session = request.getSession(false);
		if (doesNotExist(session)) {
			if (targetMethod.getName().equals(LOGIN_METHOD)) {
				return super.invokeMethodOnService(service, targetMethod, targetParameters, rpcRequest);
			}
			logger.info("HttpSession Timedout");
			InvocationTargetException invocationException = wrapInTargetMethodException(targetMethod, GatewayMessageKeys.SESSION_TIMEOUT);
			return handleInvocationTargetException(invocationException, service, targetMethod, rpcRequest);
		}
		if (userNotInSession(session)) {
			logger.info("User not in existing HttpSession..invalidating session");
			session.invalidate();
			InvocationTargetException invocationException = wrapInTargetMethodException(targetMethod, GatewayMessageKeys.NOT_LOGGED_IN);
			return handleInvocationTargetException(invocationException, service, targetMethod, rpcRequest);
		}
		logger.debug("User in existing HttpSession...allowing service call");
		return super.invokeMethodOnService(service, targetMethod, targetParameters, rpcRequest);
	}

	private void injectHttpContext(HttpServletRequest request, HttpServletResponse response) {
		httpContext.setHttpServletRequest(request);
		httpContext.setHttpServletResponse(response);
	}

	private InvocationTargetException wrapInTargetMethodException(Method targetMethod, String messageKey) throws Exception {
		Class&lt;?&gt;[] exceptionTypes = targetMethod.getExceptionTypes();
		if(exceptionTypes.length &gt; 0) {
			Constructor&lt;?&gt; constructor = exceptionTypes[0].getConstructor(String.class);
			Exception newExceptionInstance = (Exception) constructor.newInstance(messageKey);
			return new InvocationTargetException(newExceptionInstance);
		}
		return new InvocationTargetException(new ApplicationException("Make sure your Service Method throws subclass of ApplicationException!!"));
	}

	protected HttpServletRequest getHttpRequest() {
		return getThreadLocalRequest();
	}
	
	protected HttpServletResponse getHttpResponse() {
		return getThreadLocalResponse();
	}
}
&lt;/pre&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/OU_eiub2tU0" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/DhavalDalal/entry/session_handling_in_gwt</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/cagataycivici/entry/primefaces_1_0_0_rc1</guid>
    <title>PrimeFaces 1.0.0.RC Released</title>
    <dc:creator>Cagatay Civici</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/XrPWLrDUVYg/primefaces_1_0_0_rc1</link>
        <pubDate>Mon, 23 Nov 2009 04:57:12 -0500</pubDate>
    <category>Java</category>
            <description>&lt;p&gt;&lt;a href="http://cagataycivici.wordpress.com/2009/11/23/primefaces-1-0-0-rc-is-released/"&gt;http://cagataycivici.wordpress.com/2009/11/23/primefaces-1-0-0-rc-is-released/&lt;/a&gt; &lt;br /&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/XrPWLrDUVYg" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/cagataycivici/entry/primefaces_1_0_0_rc1</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/rickard/entry/thinking_of_systems</guid>
    <title>Thinking of systems</title>
    <dc:creator>Rickard Öberg</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/dIL0aCY01nU/thinking_of_systems</link>
        <pubDate>Mon, 23 Nov 2009 00:10:55 -0500</pubDate>
    <category>Java</category>
    <atom:summary type="html">
&lt;p&gt;Software development today suffers from not taking a holistic view of the systems it produces. This post outlines the underlying issues, and how these relate to other forms of human activity, and what we should do to deal with it.&lt;/p&gt;

</atom:summary>        <description>&lt;p&gt;&lt;p&gt;A couple of weeks ago I, Trygve Reenskaug (inventor of the MVC pattern) and Jim Coplien did a track at the Oredev conference about DCI (Data, Context, Interaction), which is a new way of thinking about object-oriented software development. Trygve's presentation did a good job at analyzing the progression from the procedural programming, where code could be read and understood, to todays object-oriented paradigm in which descriptions of interactions and algorithms are spread out in a multitude of so-called &amp;quot;objects&amp;quot;, thereby making it impossible to get an understanding of how the overall system works, and what the interactions between objects are. DCI is an attempt to reconnect with the procedural programming success, where it was possible to read a procedure and figure out what the software does. By bringing this concept, that of systems and a sense holistic views, back into software development we might be able to avert the quality crisis that our industry is currently in.&lt;/p&gt;&lt;p&gt;After having done this presentation, I also realized that software development is not the only field of human activity which suffers from this general issue. Apart from studying software development I am also looking into management theory, healthcare, and psychopathological influences on societal levels (aka political ponerology). What I can see now, with software development as an example of the general pattern, is that all these fields, in their popular western form, suffer from the same issue: the inability to look at the problem from a systems point of view, and instead focusing on the individual parts, thereby introducing suboptimizations and harming flow that decrease quality and increases cost.&lt;/p&gt;&lt;p&gt;In management theory we have the notion of &amp;quot;economies of scale&amp;quot;, where service is seen as a form of production where workers are given standards and highly detailed processes to be adhered to (and which were not created by the workers themselves). The idea is that by having these standards, and targets to measure success with, we can reach new levels of productivity and efficiency, which are impossible to reach otherwise. These notions are sometimes implicit in the management of a company, and sometimes they are explicitly expounded through implementation of things like ISO 9000. This idea has now been shown to be false, even fatally so, and is slowly being replaced with a more holistic view, that of systems thinking, which talks of &amp;quot;economies of flow&amp;quot; instead, and where knowledge and understanding replaces guessing and predicting. Here is one &lt;a href="http://www.thesystemsthinkingreview.co.uk/index.php?pg=18&amp;amp;backto=18&amp;amp;utwkstoryid=181&amp;amp;title=Economy+of+scale+-+It%27s+a+myth!&amp;amp;ind=1"&gt;example&lt;/a&gt; outlining this.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;In the healthcare sector we are currently seeing a failure on a monumental scale, as the western methods of understanding, diagnosing and treating disease based on the &amp;quot;fix the parts&amp;quot;-idea are not working. We are spending monumental amounts of money on healthcare and medicine, and which don't solve the problem, introduce new problems through sideeffects, and which ultimately only works to create an even sicker population, which benefit the &amp;quot;big pharma&amp;quot; that is supposed to help us deal with it in the first place. The healthcare issues are then further compounded by the use of flawed management theory, as outlined above, which makes it even more inefficient and useless. Those who work in hospitals are often trying to desperately workaround the system to help patients, but ultimately they are only the 5% of the puzzle, with 95% of the outcome being ruled by the system itself, flawed as it is. &lt;/p&gt;&lt;p&gt;In contrast, holistic medicinal practices such as TCM (Traditional Chinese Medicine) provides a way of looking at the human body as a system, understanding the parts as being related to each other, and has uninvasive methods of treatment, largely without side-effects, and at a cost that is only a fraction of what the western &amp;quot;modern&amp;quot; method would be. TCM is slowly being adapted by western institutions, but it has to be done cautiosly as it is still officially considered &amp;quot;alternative&amp;quot; and unproven. Whether TCM works or not isn't really the issue. The issue is that its very underlying idea, that of the human body being a system whose parts interact symbiotically, threatens the ideology that western medicine is based on, and as any weakly founded religion would do, such threats must be dealt with without remorse. Questioning dogma is simply not an option.&lt;/p&gt;&lt;p&gt;Finally, when it comes to understanding pathology of the mind, and the effect that it has on our society, the western research so far has focused on the diagnosis and treatment of individuals, without looking at the bigger picture. Thus the popular idea of psychopaths, and other pathological disorders, is still in most peoples mind limited to the extreme examples provided by Hollywood and flashing headlines, where extreme psychopaths go on killing sprees and whatnot. This, however, we now know is not an accurate reflection of the impact that people with pathological mental disorders have on society. Through the study of &lt;a href="http://www.ponerology.com/"&gt;political ponerology&lt;/a&gt; one can get a glimpse of the fact that not only are these mental disorders more common than one would think, they also interact in such a way as to boost each other. A psychopath with a devious plan might manipulate a paranoid schizophrenic to further it, which in turn causes people with narcissistic wounding to become devotees and followers, thereby creating a chain of delusion which ultimately infects entire social groups, societies, and eventually nations. We have many examples of this in our contemporary history, and there is no reason to believe that this will not happen again, as the only vaccine is knowledge, and knowledge is sparse. By studying pathology and ponerology it also becomes possible to understand the impact that it has had on the previous two systems, that of management and healthcare, and as noted, healthcare in itself is afflicted by the delusions of current management thinking as well.&lt;/p&gt;&lt;p&gt;In short, not only do we have to start thinking in terms of systems with regard to individual aspects of life, such as healthcare, we must also consider how these systems interact, pathologically, on an even larger scale. Only then does it become possible to understand the monumental amount of waste and failure that we have created, and which is made possible by remaining in the dark as to the underlying causes.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Doom and gloom? Yes, indeed, the picture is pretty much pitch black as it is. But as John Seddon points out, there is no way to create change without first studying the system as it is, in its current incarnation. The good news is that the interconnectedness works both ways. If we collectively deal with the root cause of all these issues, which is the pathological influence of various mental disorders, then the other affected systems will benefit from it, and when you have systems interacting with systems in a positive way you get exponential improvement as a result: if management theory accepts and corrects itself based on an understanding of pathological thinking, it will help the healthcare system, which in turn will give them a way to get a more holistic way of looking at their work, which can improve the results of treatment, which will improve everyones lives, which... and so on, you get the idea. This should be the main concern of people wanting to make a real difference in todays world, as most of anything else will be to be cutting the leaves of a tree, rather than its roots. You are, as western medicine is focused on, treating a symptom rather than the true cause. Treating the true problem will clear out the symptoms that it caused, and in a way that is much more effective as you can be sure that the symptoms will not be coming back anytime soon.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Coming back to software development, which was the initial cause of this realization of mine, it is now clear to me that if we do not accept the conclusions that Trygve put forward, and which are reflected in so many other forms of human activity, there is no chance of creating software in a way that the code becomes readable, understandable and maintainable. We cannot continue to focus on the parts, the objects, without also taking into consideration the contexts and interactions that these objects have. We need a holistic way of thinking about systems. &lt;/p&gt;&lt;p&gt;The question is: can we afford not to do this? Can we allow ourselves to continue using bad practices, which lead to more low-quality code and unmaintainable software?&lt;br /&gt;&lt;/p&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/dIL0aCY01nU" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/rickard/entry/thinking_of_systems</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/scolebourne/entry/more_detail_on_closures_in</guid>
    <title>More detail on Closures in JDK 7</title>
    <dc:creator>Stephen Colebourne</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/SXcP070x0Ys/more_detail_on_closures_in</link>
        <pubDate>Sun, 22 Nov 2009 21:57:06 -0500</pubDate>
    <category>Java</category>
    <category>bgga</category>
    <category>cfj</category>
    <category>closures</category>
    <category>fcm</category>
    <category>jdk7</category>
            <description>&lt;p&gt;
This blog goes into a little more detail about the closures announcement at Devoxx and subsequent
information that has become apparent.
&lt;/p&gt;


&lt;h4&gt;Closures in JDK 7&lt;/h4&gt;
&lt;p&gt;
At &lt;a href="http://www.devoxx.com/display/DV09/Home"&gt;Devoxx 2009&lt;/a&gt;, Mark Reinhold from Sun announced that it was time for closures in Java.
This was a big surprise to everyone, and there was a bit of a vacuum as to what was announced.
&lt;/p&gt;
&lt;p&gt;
Firstly, Sun, via Mark, have chosen to accept the basic case for including closures in Java.
By doing so, the debate now changes from &lt;b&gt;whether&lt;/b&gt; to go ahead, to &lt;b&gt;how&lt;/b&gt; to proceed.
This is an important step.
&lt;/p&gt;
&lt;p&gt;
Secondly, what did Mark consider to be in and what out?
Well, he indicated that non-local returns and the control-invocation statement were out of scope.
There was also some indication that access to non-final variables may be out of scope (this is
mainly because it raises nasty multi-threading Java Memory Model issues with local variables).
&lt;/p&gt;
&lt;p&gt;
In terms of what was included, Mark indicated that extension methods would be considered.
This would be necessary to provide meaningful closure style APIs since the existing Java collection
APIs cannot be altered. The result of what was in was being called "simple closures".
&lt;/p&gt;
&lt;p&gt;
Finally, Mark offered up a possible syntax.
The syntax he showed was very close to &lt;a href="http://docs.google.com/Doc?id=ddhp95vd_0f7mcns"&gt;FCM&lt;/a&gt;:
&lt;/p&gt;
&lt;pre&gt;
  // function expressions
  #(int i, String s) {
    System.println.out(s);
    return i + str.length();
  }

  // function expressions
  #(int i, String s) (i + str.length())
  
  // function types
  #int(int, String)
&lt;/pre&gt;
&lt;p&gt;
As such, its easy to say that Sun has "chosen the FCM proposal".
However, with all language changes, we have to look at the semantics, not the syntax!
&lt;/p&gt;
&lt;p&gt;
The other session at Devoxx was the late night BOF session.
I didn't attend, however &lt;a href="http://mail.openjdk.java.net/pipermail/coin-dev/2009-November/002463.html"&gt;according to Reinier Zwitserloot&lt;/a&gt;,
Mark indicated that Exception transparancy might not be essential to the final proposal.
&lt;/p&gt;
&lt;p&gt;
According to Reinier, Mark also said "It is not an endorsement of FCM. He was very specific about that."
I'd like to consider that in a little more detail (below).
&lt;/p&gt;
&lt;p&gt;
The final twist was when a &lt;a href="http://www.javac.info/closures-v06a.html"&gt;new proposal&lt;/a&gt;
by Neal Gafter was launched which I'm referring to as the CFJ proposal.
After some initial confusion, it became clear that this was written 2 weeks before Devoxx,
and that Neal had discussed it primarily with James Gosling on the basis of it being a
&lt;a href="http://groups.google.com/group/javaposse/msg/6fe32856d9ed0e74"&gt;"compromise proposal"&lt;/a&gt;.
Neal has also stated that he didn't speak to Mark directly before Devoxx (and nor did I).
&lt;/p&gt;
&lt;p&gt;
There are a number of elements that have come together in the various proposals:
&lt;/p&gt;
&lt;table cellspacing="0" cellpadding="0" style="border:2px solid black"&gt;
&lt;tr&gt;
&lt;th&gt;&amp;nbsp;&lt;/td&gt;
&lt;th style="text-align:center;width=150px;"&gt;&lt;a href="http://docs.google.com/View?docid=k73_1ggr36h"&gt;CICE&lt;/a&gt;&lt;/th&gt;
&lt;th style="text-align:center;width=150px;"&gt;&lt;a href="http://www.javac.info/closures-v05.html"&gt;BGGA 0.5&lt;/a&gt;&lt;/th&gt;
&lt;th style="text-align:center;width=150px;"&gt;&lt;a href="http://docs.google.com/Doc?id=ddhp95vd_6hg3qhc"&gt;FCM 0.5&lt;/a&gt;&lt;/th&gt;
&lt;th style="text-align:center;width=150px;"&gt;&lt;a href="http://www.javac.info/closures-v06a.html"&gt;CFJ 0.6a&lt;/a&gt;&lt;/th&gt;
&lt;th style="text-align:center;width=150px;"&gt;Devoxx announcement&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th style="border-top:1px solid black"&gt;Literals for reflection&lt;/th&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;-&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;-&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;-&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;No info&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;th style="border-top:1px solid black"&gt;Method references&lt;/th&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;-&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;-&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;No info&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;th style="border-top:1px solid black"&gt;Closures assignable to single method interface&lt;/th&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;No info&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;th style="border-top:1px solid black"&gt;Closures independent of single method interface&lt;/th&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;-&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;th style="border-top:1px solid black"&gt;Access non-final local variables&lt;/th&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Maybe not&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;th style="border-top:1px solid black"&gt;Keyword 'this' binds to enclosing class&lt;/th&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;-&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Probably yes&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;th style="border-top:1px solid black"&gt;Local 'return'&lt;br /&gt;(binds to closure)&lt;/th&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;-&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;th style="border-top:1px solid black"&gt;Non-local 'return'&lt;br /&gt;(binds to enclosing method)&lt;/th&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;-&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;-&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;-&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;No&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;th style="border-top:1px solid black"&gt;Alternative 'return' binding&lt;br /&gt;(Last-line-no-semicolon)&lt;/th&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;-&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;-&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;-&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;No&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;th style="border-top:1px solid black"&gt;Exception transparancy&lt;/th&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;-&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Maybe not&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;th style="border-top:1px solid black"&gt;Function types&lt;/th&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;-&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;th style="border-top:1px solid black"&gt;Library based Control Structure&lt;/th&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;-&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Yes&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;-&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;-&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;No&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;th style="border-top:1px solid black"&gt;Proposed closure syntax&lt;/th&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;Name(args) {block}&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;{args =&gt; block;expr}&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;#(args) {block}&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;#(args) {block}&lt;br /&gt;#(args) expr&lt;/td&gt;
&lt;td style="border-top:1px solid black;text-align:center;width=150px;"&gt;#(args) {block}&lt;br /&gt;#(args) (expr)&lt;/td&gt;
&lt;/tr&gt;

&lt;/table&gt;

&lt;p&gt;
A table never captures the full detail of any proposal.
However, I hope that I've demonstrated some key points.
&lt;/p&gt;
&lt;p&gt;
Firstly, the table shows how the CFJ is worthy of a new name (from BGGA) as it treats the problem space differently
by avoiding non-local returns and control invocation.
Neal Gafter is also the only author of the CFJ proposal, unlike BGGA.
&lt;/p&gt;
&lt;p&gt;
Secondly, it should be clear that at the high level, the CFJ and FCM proposals are similar.
But in many respects, this is also a result of what would naturally occur when the non-local returns
and control invocation is removed from BGGA.
&lt;/p&gt;
&lt;p&gt;
Finally, it should be clear that it is not certain that the CFJ proposal meets the aims that
Mark announced at Devoxx ("simple closures"). There simply isn't enough hard information to make that judgement.
&lt;/p&gt;
&lt;p&gt;
One question I've seen on a few tweets and blog posts is whether Mark and Sun picked the BGGA or FCM proposal.
Well, given what Mark said in the BOF (via Reinier), the answer is that neither was "picked" and that he'd
like to see a new form of "simple closures" created.
However, it should also be clear that the choices announced at Devoxx were certainly closer to the FCM proposal than
any other proposal widely circulated at the time of the announcement.
&lt;/p&gt;
&lt;p&gt;
At this point, it is critical to note that Neal Gafter adds a huge amount of technical detail to each
proposal he is involved with - both BGGA and CFJ.
The FCM proposal, while considerably more detailed than CICE, was never at the level necessary for full
usage in the JDK.
As such, I welcome the CFJ proposal as taking key points from FCM and applying the rigour from BGGA.
&lt;/p&gt;
&lt;p&gt;
As of now, there has been relatively little debate on extension methods.
&lt;/p&gt;

&lt;h4&gt;Summary&lt;/h4&gt;
&lt;p&gt;
The key point now is to focus on how to implement closures within the overall scope laid out.
This should allow the discussion to move forward considerably, and hopefully with less acrimony.
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/SXcP070x0Ys" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/scolebourne/entry/more_detail_on_closures_in</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/fthamura/entry/s1_java_di_universitas_gunadarma</guid>
    <title>S1 Java di Universitas Gunadarma, program jTechnopreneuer dan Program jTechnopreneur 1 tahun (Cakra)</title>
    <dc:creator>Frans Thamura</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/fdEQcDfuYuQ/s1_java_di_universitas_gunadarma</link>
        <pubDate>Sun, 22 Nov 2009 20:45:25 -0500</pubDate>
    <category>Java - The Peace Tech</category>
            <description>Program jTechnopreneur dimulai dengan roadshow tahun 2008 lalu di 8 kota, untuk mempromosikan gimana berwirausaha dengan Java, dan selain itu sejak 2006 saya membantu IBC (Incubator Business Center) Gunadarma, menshare pengalaman dan susah sedihnya berwirausaha di Indonesia.&lt;br /&gt;&lt;br /&gt;&lt;div align="center"&gt;&lt;img style="max-width: 800px;" src="http://farm4.static.flickr.com/3194/2545821496_e93321f1ff.jpg" /&gt;&lt;br /&gt;jTechnopreneur 2008 Unpar Bandung&lt;br /&gt;&lt;br /&gt;&lt;img style="max-width: 800px;" src="http://farm3.static.flickr.com/2134/2381200055_e7f873b13c.jpg" /&gt;&lt;br /&gt;jTechnopreneur 2008 IPB Bandung&lt;br /&gt;&lt;br /&gt;&lt;img style="max-width: 800px;" src="http://farm3.static.flickr.com/2373/2381310781_fbe099fb75.jpg" /&gt;&lt;br /&gt;Kecapean sampe ketiduran di jTechnopreneur IPB Bogor&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Sekarang telah lahir sebuah program undergraduate atau Strata 1 di Universitas Gunadarma dengan sebutan jTechnopreneur Program, ini sebenarnya extension kecil dikurikulum S1 dari Universitas Gunadarma, tetapi kalau digabung-gabung total semuanya, banyak juga yang berubah, lihat diagram dipresentasi dibawah ini, terutama yang warna biru, itu adalah program intensive Java di Gunadarma, sedangkan yang pink, masih dalam proses, terutama sistem operasi, kita inginnya mengadopsi teknologi Java on Hypervisor, jadi cloud infrastructure langsung menjalankan Java tanpa sistem operasi, sebuah teknologi virtual edition terbaru dari Java, sebagai tambahan boot sistem operasi yang umum didunia virtualization.&lt;br /&gt;&lt;br /&gt;Selain itu kita juga memiliki program 1 tahun, kode name Cakra, untuk membuat perusahaan kecil berbasis teknologi, khususnya Java tentu saja. Walaupun dalam perjalanannya tidak 100% Java, tetapi ada Javascript sebagai default skillset untuk AJAX, dan untuk intensif aplikasi frontnya kita menciptakan project MIDAS. Apa itu Midas, tunggu blog saya berikutnya...&lt;br /&gt;&lt;br /&gt;Nah ini dia slide apa itu jTechnopreneur C/S (Computer Science) S1 dan Meruvian Cakra.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="width: 425px; text-align: left;" id="__ss_2503618"&gt;&lt;a style="margin: 12px 0pt 3px; font-family: Helvetica,Arial,Sans-serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 14px; line-height: normal; font-size-adjust: none; font-stretch: normal; display: block; text-decoration: underline;" href="http://www.slideshare.net/flatburger/jtechnopreneur-cs-r1-1" title="jTechnopreneur C/S r1.1"&gt;jTechnopreneur C/S r1.1&lt;/a&gt;&lt;div class="youtube-video"&gt;&lt;object style="margin: 0px;" height="355" width="425"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=jtechnopreneur-cs-r1-1-4646&amp;amp;stripped_title=jtechnopreneur-cs-r1-1"&gt; &lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt; &lt;/param&gt;&lt;param name="allowScriptAccess" value="always"&gt; &lt;/param&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=jtechnopreneur-cs-r1-1-4646&amp;amp;stripped_title=jtechnopreneur-cs-r1-1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="355" width="425"&gt; &lt;/embed&gt;    &lt;/object&gt;&lt;/div&gt;&lt;div style="font-size: 11px; font-family: tahoma,arial; height: 26px; padding-top: 2px;"&gt;View more &lt;a style="text-decoration: underline;" href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a style="text-decoration: underline;" href="http://www.slideshare.net/flatburger"&gt;Frans Thamura&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="zemanta-pixie"&gt;&lt;img class="zemanta-pixie-img" alt="" src="http://img.zemanta.com/pixy.gif?x-id=308ba2fd-3916-87c2-9e97-1af1b6f5a714" /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/fdEQcDfuYuQ" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/fthamura/entry/s1_java_di_universitas_gunadarma</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/peter_pilgrim/entry/devoxx_2009_xenon_data_grid</guid>
    <title>Devoxx 2009 Xenon Data Grid Presentation Slides</title>
    <dc:creator>Peter Pilgrim</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/Stv5XsqDrxQ/devoxx_2009_xenon_data_grid</link>
        <pubDate>Sun, 22 Nov 2009 13:50:45 -0500</pubDate>
    <category>Java</category>
    <category>devoxx</category>
    <category>java</category>
    <category>javafx</category>
    <category>nelson</category>
    <category>presentation</category>
    <category>slides</category>
    <category>xenondatagrid</category>
            <description>&lt;h1&gt;Devoxx 2009 Xenon Data Grid Presentation Slides&lt;font size="4"&gt;&lt;br style="color: rgb(255, 255, 255);"&gt;
&lt;/font&gt;
&lt;/h1&gt;
&lt;table style="float: right; text-align: left;" class="zeroBorder" cellpadding="16" cellspacing="1" width="350"&gt;
 
&lt;tbody&gt;
 
&lt;tr&gt;
 
&lt;td align="center" bgcolor="#6666ff"&gt;
&lt;font size="4"&gt;
&lt;span style="color: rgb(255, 255, 255);"&gt;&lt;br&gt;
&lt;div id="x.li" style="text-align: center;"&gt;
&lt;div id="y8gj" style="text-align: center;"&gt;&lt;a href="http://www.javafx.com" alt=" JavaFX.com"&gt;&lt;img style="width: 193px; height: 88px;" src="http://docs.google.com/File?id=df5jk3g7_196dgnwqtdg_b" alt="JavaFX.com"&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div id="hn1e" style="text-align: center;"&gt;&lt;a href="http://www.devoxx.com/display/JV08/JavaFX+-+Animations%2C+Timelines+and+Collision+Analysis+for+Games" alt=" Peter Pilgrim's JavaFX Presentation "&gt;&lt;img style="width: 240px; height: 160px;" src="http://docs.google.com/File?id=df5jk3g7_202d8r7w3gh_b"&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;/span&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;
Above all, I strongly recommend the Devoxx conference to any Java
beginner in Europe who wants to expand their mind, to get ahead and to stay ahead of the pack.&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;br&gt;
Dear Reader&lt;br&gt;
&lt;br&gt;
Well Hello &lt;a title="Devoxx 2009" href="http://devoxx.com/display/DV09/" id="sfxa"&gt;Devoxx 2009&lt;/a&gt; POST conference.&lt;br&gt;
&lt;br&gt;
Here are my presentation slides for my short talk at &lt;a title="Devoxx 2009 on Wednesday 18th November 2009" href="http://devoxx.com/display/DV09/XenonDataGrid+Open+Source+JavaFX+Table+Component" id="dlz5"&gt;Devoxx 2009 on Wednesday 18th November 2009&lt;/a&gt;.&lt;br&gt;
&lt;br&gt;
&lt;font size="4"&gt;
Here is the &lt;a title="slide deck (PDF file)" href="http://www.xenonsoft.com/resources/docs/Devoxx_2009_XenonDataGrid_20091118.pdf" id="mpkb"&gt;slide deck (PDF file)&lt;/a&gt;.&lt;br&gt;
&lt;/font&gt;
&lt;h1&gt;XenonDataGrid Open Source JavaFX Table Component&lt;/h1&gt;

&lt;h2&gt;&lt;a name="XenonDataGridOpenSourceJavaFXTableComponent-Abstract"&gt;&lt;/a&gt;Abstract&lt;/h2&gt;

&lt;p&gt;In this brief presentation, I will talk about the XenonDataGrid
JavaFX component that I have been building over the Summer of 2009. The XenonDataGrid is a table component, displays data in rows and columns. It is comparable to Swing's JTable component except that XDG is purely developed in JavaFX, and therefore uses the
scenegraph for rendering rather than calling directly Java 2D immediate
mode API. XenonDataGrid is part of the &lt;a href="http://kenai.com/projects/nelson" rel="nofollow"&gt;Nelson FX project&lt;/a&gt;, which I open sourced on &lt;a href="http://kenai.com/" rel="nofollow"&gt;Project Kenai &lt;/a&gt; shortly after JavaOne 2009.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;br clear="all"&gt;
&lt;br&gt;
&lt;div id="sdb2" style="text-align: left;"&gt;&lt;img src="http://docs.google.com/File?id=df5jk3g7_328dm474cjx_b" height="333" width="500"&gt;&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
&lt;div id="pkad" style="text-align: left;"&gt;&lt;img src="http://docs.google.com/File?id=df5jk3g7_329d36d6nc7_b" height="334" width="501"&gt;&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
See you all next year at Devoxx 2010!&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;br&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/Stv5XsqDrxQ" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/peter_pilgrim/entry/devoxx_2009_xenon_data_grid</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/wesleyhales/entry/creating_another_firefox_theme</guid>
    <title>Creating (another) Firefox Theme</title>
    <dc:creator>Wesley Hales</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/cKJI2prE6J0/creating_another_firefox_theme</link>
        <pubDate>Sun, 22 Nov 2009 10:50:58 -0500</pubDate>
    <category>Java</category>
    <category>firefox</category>
            <description>&lt;a href="http://www.jroller.com/wesleyhales/resource/recovery/ff3-theme-new-h-small.jpg"&gt;&lt;img src="http://www.jroller.com/wesleyhales/resource/recovery/ff3-theme-new-h-small.jpg" style="margin:5px;" align="right"/&gt;&lt;/a&gt;
&lt;p&gt;I started laying down ideas for a new Firefox theme a few months ago and this is what emerged. I'm not sure why I can't stay away from the darker themes. Maybe it's the richness that black (and darker colors) allows on a monitor, but I tried to stay as far away from mainstream design on this as I could. I have already coded this into a downloadable theme, but I am still working out some glitches. Then I have to let it sit in the Mozilla incubator, as I did with ANTHEM.&lt;/p&gt;
&lt;p&gt;Speaking of ANTHEM, I'm quite surprised that it has done so well. 780k downloads and counting in 1 year. But it is all in vain if I can't "supply more blood" to this living organ (As &lt;a href="http://www.jroller.com/robwilliams/"&gt;Rob W.&lt;/a&gt; likes to put it.) With that said, I'm thinking about starting an open source project for these themes, because quite honestly, I don't have time to &lt;a href="http://www.jroller.com/wesleyhales/entry/creating_a_firefox_3_theme"&gt;fix the bugs&lt;/a&gt;. Anybody wanna help? Comment with your email...&lt;/p&gt;
&lt;br/&gt;
&lt;a href="http://www.jroller.com/wesleyhales/resource/recovery/ff3-theme-new-h-bg.jpg"&gt;&lt;img src="http://www.jroller.com/wesleyhales/resource/recovery/ff3-theme-new-h-bg-icon.jpg" style="" border="0"/&gt;&lt;/a&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;a href="http://www.jroller.com/wesleyhales/resource/recovery/ff3-theme-new-f.jpg"&gt;&lt;img src="http://www.jroller.com/wesleyhales/resource/recovery/ff3-theme-new-f.jpg" style="margin:5px;" align="right"/&gt;&lt;/a&gt;
&lt;p&gt;I have been a bit indecisive about the the background on the toolbar on this one. What do you think? The first one at the top, or this one... &lt;/p&gt;

&lt;br/&gt;
&lt;br/&gt;
&lt;br/&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/cKJI2prE6J0" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/wesleyhales/entry/creating_another_firefox_theme</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/peter_pilgrim/entry/devoxx_2009_digital_media_report</guid>
    <title>Devoxx 2009 Digital Media Report </title>
    <dc:creator>Peter Pilgrim</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/VDbLS7lahKM/devoxx_2009_digital_media_report</link>
        <pubDate>Fri, 20 Nov 2009 09:54:13 -0500</pubDate>
    <category>Java</category>
    <category>audioboo</category>
    <category>conference</category>
    <category>devoxx</category>
    <category>java</category>
    <category>javaee</category>
    <category>javafx</category>
    <category>jdk7</category>
    <category>media</category>
    <category>news</category>
    <category>scala</category>
    <category>update</category>
    <category>ustream</category>
            <description>&amp;nbsp;&amp;nbsp;

 
 
 
&lt;h1&gt;Devoxx 2009 Digital Media Report&lt;font size="4"&gt;&lt;br style="color: rgb(255, 255, 255);"&gt;
&lt;/font&gt;
&lt;/h1&gt;
&lt;table style="float: right; text-align: left;" class="zeroBorder" cellpadding="16" cellspacing="1" width="350"&gt;
 
&lt;tbody&gt;
 
&lt;tr&gt;
 
&lt;td align="center" bgcolor="#6666ff"&gt;
&lt;font size="4"&gt;
&lt;span style="color: rgb(255, 255, 255);"&gt;&lt;br&gt;
&lt;div id="x.li" style="text-align: center;"&gt;
&lt;div id="y8gj" style="text-align: center;"&gt;&lt;a href="http://www.javafx.com" alt=" JavaFX.com"&gt;&lt;img style="width: 193px; height: 88px;" src="http://docs.google.com/File?id=df5jk3g7_196dgnwqtdg_b" alt="JavaFX.com"&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div id="hn1e" style="text-align: center;"&gt;&lt;a href="http://www.devoxx.com/display/JV08/JavaFX+-+Animations%2C+Timelines+and+Collision+Analysis+for+Games" alt=" Peter Pilgrim's JavaFX Presentation "&gt;&lt;img style="width: 240px; height: 160px;" src="http://docs.google.com/File?id=df5jk3g7_202d8r7w3gh_b"&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;/span&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;
Above all, I strongly recommend the Devoxx conference to any Java
beginner in Europe who wants to expand their mind, to get ahead and to stay ahead of the pack.&lt;/span&gt;&lt;/font&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;br&gt;
Dear Reader&lt;br&gt;
&lt;br&gt;
Well Hello &lt;a title="Devoxx 2009" href="http://devoxx.com/display/DV09/" id="sfxa"&gt;Devoxx 2009&lt;/a&gt; conference and it is Wednesday&lt;br&gt;
&lt;br&gt;

First, a few words, on the conference itself. I think Devoxx is the
best conference this side of the Atlantic Ocean for Java news and
speakers. The technical quality of the speakers is excellent. Sun
Microsystems also feels this is a great community so they will sent
their top representatives like &lt;b&gt;Brian Goetz&lt;/b&gt;, &lt;b&gt;Mark Reinhold, Alex Buckley&lt;/b&gt;, &lt;b&gt;Joe Darcy&lt;/b&gt;, &lt;b&gt;Richard Bair&lt;/b&gt;, &lt;b&gt;Bruno Souza&lt;/b&gt; and &lt;b&gt;Aaron Houston&lt;/b&gt;.
So okay even if this conference was 500 participants down from last
year and the economic markets is suffering severe dislocation in many
countries of the world, this Devoxx conference is undoubtedly the
European standard, against which conferences have to be compare with. &lt;br&gt;

&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;br&gt;
&lt;span style="color: rgb(255, 0, 0);"&gt;[European JUG Leaders BOF 2009 with James Gosling Meeting Vimeo Player *Coming Soon*]&lt;/span&gt;&lt;br style="color: rgb(255, 0, 0);"&gt;
&lt;br&gt;
&lt;br&gt;
&lt;div id="au9j" style="text-align: left;"&gt;&lt;img src="http://docs.google.com/File?id=df5jk3g7_321dn29s3c5_b" height="343" width="516"&gt;&lt;/div&gt;
&lt;br&gt;
&lt;div id="kkn6" style="text-align: left;"&gt;
&lt;div id="f10g" style="text-align: left;"&gt;&lt;br&gt;
&lt;/div&gt;
&lt;font size="1"&gt;Photo courtesy of &lt;a title="Stephan Janssen" href="http://picasaweb.google.com/JavaPolis.com" id="f5fg"&gt;Stephan Janssen&lt;/a&gt; &lt;a title="Aaron Houston (sunahouston2)" href="http://picasaweb.google.com/sunahouston2" id="ijy3"&gt;&lt;/a&gt; uploaded onto &lt;a title="Picasa" href="http://picasaweb.google.com/sunahouston2/DeVoxx2008#" id="cpnd"&gt;Picasa&lt;/a&gt;.&lt;/font&gt;&lt;br&gt;
&lt;/div&gt;

&lt;br&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;This year yours truly has decided not write any more daily blog
reports. I think you, dearest reader, you have been getting thatmessage from myself with my AudioBoo and video drops over the past six to eight months or so. &lt;br&gt;
&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a href="http://audioboo.fm/boos/77431-devoxx-2009-interview-with-adaptivist-dudes-senior-board"&gt;
&lt;img src="http://www.jroller.com/peter_pilgrim/resource/audioboo-button-128x128.png" border="0"&gt; 
&lt;/a&gt;
&lt;a href="http://audioboo.fm/boos/77431-devoxx-2009-interview-with-adaptivist-dudes-senior-board"&gt;
Devoxx 2009 Interview with the Adaptavist guys&lt;/a&gt;
&lt;br&gt;
&lt;br&gt;
&lt;p&gt;

&lt;a href="http://audioboo.fm/boos/77166-devoxx-interview-with-stephen-colebourne-opinions-on-jdk-7-closures-etc"&gt;
&lt;img src="http://www.jroller.com/peter_pilgrim/resource/audioboo-button-128x128.png" border="0"&gt; 
&lt;/a&gt;
&lt;a href="http://audioboo.fm/boos/77166-devoxx-interview-with-stephen-colebourne-opinions-on-jdk-7-closures-etc"&gt;
Devoxx 2009 Interview with Stephen Colebourne Opinions on JDK 7 Closures etc&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;

&lt;a href="http://audioboo.fm/boos/77022-my-interview-with-aaron-houston-pd-tech-outreach-sun-also-w-sven-florien"&gt;
&lt;img src="http://www.jroller.com/peter_pilgrim/resource/audioboo-button-128x128.png" border="0"&gt; 
&lt;/a&gt;
&lt;a href="http://audioboo.fm/boos/77022-my-interview-with-aaron-houston-pd-tech-outreach-sun-also-w-sven-florien"&gt;
Devoxx 2009 My Interview for Aaron Houston, Program Director, Outreach, Sun Microsystems&amp;nbsp;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;

&lt;a href="http://audioboo.fm/boos/76929-devoxx-interview-with-antonio-gonclaves-paris-jug-leader-on-java-ee-6"&gt;
&lt;img src="http://www.jroller.com/peter_pilgrim/resource/audioboo-button-128x128.png" border="0"&gt; 
&lt;/a&gt;
&lt;a href="http://audioboo.fm/boos/76929-devoxx-interview-with-antonio-gonclaves-paris-jug-leader-on-java-ee-6"&gt;
Devoxx 2009 Interview with Antonia Gonclaves, Paris JUG Leader, Java EE 6 Advocate&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;

&lt;a href="http://audioboo.fm/boos/76702-devoxx-2009-interview-with-oliver-gierke-aus-mannheim-easing-jpa-with-hades"&gt;
&lt;img src="http://www.jroller.com/peter_pilgrim/resource/audioboo-button-128x128.png" border="0"&gt; 
&lt;/a&gt;
&lt;a href="http://audioboo.fm/boos/76702-devoxx-2009-interview-with-oliver-gierke-aus-mannheim-easing-jpa-with-hades"&gt;
Devoxx 2009 Interview with Oliver Gierke, Easing JPA with Hades&lt;/a&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;

&lt;a href="http://audioboo.fm/boos/76700-devoxx-2009-interview-with-federick-simon-of-jfrog-talking-about-artifactory"&gt;
&lt;img src="http://www.jroller.com/peter_pilgrim/resource/audioboo-button-128x128.png" border="0"&gt; 
&lt;/a&gt;
&lt;a href="http://audioboo.fm/boos/76700-devoxx-2009-interview-with-federick-simon-of-jfrog-talking-about-artifactory"&gt;
Devoxx 2009 Interview with Frederick Simon, JFrog, Talking About Artifactory&lt;/a&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;

&lt;br&gt;
&lt;/p&gt;
&lt;h3&gt;UStream TV Devoxx JAVAWUG Link-Up Show&lt;/h3&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;In other words, I think a daily blog is a complete waste of (my) time. Why? Because, people can get the best of external news from Twitter and professional journal blogs. However, I do think that the new digital media taking advantage of these technologies is the correct way to go. I attempted to do this on Tuesday night with a live link up with the &lt;b&gt;JAVAWUG&lt;/b&gt; in London. &lt;b&gt;Richard Gomes&lt;/b&gt; was hosting our very first Professional Jam #1. Antwerp's timezone is one hour ahead of time of London, and still I found out later in the day that the Internet link at &lt;b&gt;Skills Matter&lt;/b&gt; was unavailable. It was sod's law, but I continue with my &lt;a title="Ustream TV feed" href="http://www.ustream.tv/channel/test-from-peter-pilgrim-devoxx-linkup-1" id="z.p5"&gt;Ustream TV feed&lt;/a&gt; and recorded it. You can judge the results yourself of whether this helps user group members who unluckily unable to visit a conference such as Devoxx. &lt;br&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;p style="color: rgb(255, 0, 0);"&gt;[UStream liveshow]&lt;/p&gt;
&lt;object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="400" height="320" id="utv429128"&gt;&lt;param name="flashvars" value="autoplay=false&amp;amp;brand=embed&amp;amp;cid=1943256"/&gt;&lt;param name="allowfullscreen" value="true"/&gt;&lt;param name="allowscriptaccess" value="always"/&gt;&lt;param name="movie" value="http://www.ustream.tv/flash/live/1/1943256"/&gt;&lt;embed flashvars="autoplay=false&amp;amp;brand=embed&amp;amp;cid=1943256" width="400" height="320" allowfullscreen="true" allowscriptaccess="always" id="utv429128" name="utv_n_33219" src="http://www.ustream.tv/flash/live/1/1943256" type="application/x-shockwave-flash" /&gt;&lt;/object&gt;&lt;a href="http://www.ustream.tv/" style="padding: 2px 0px 4px; width: 400px; background: #ffffff; display: block; color: #000000; font-weight: normal; font-size: 10px; text-decoration: underline; text-align: center;" target="_blank"&gt;Live Streaming by Ustream.TV&lt;/a&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;It was rough and ready and the quality of the video low, but I believe this is valuable in the next decade when we will be economically and airplane challenged. In English, travel may become more restrictive and socially frown upon unless it is necessary. I can certain JUG Leaders, like &lt;b&gt;Marcelo Magno &lt;/b&gt;from the &lt;b&gt;Milan JUG&lt;/b&gt;, using &lt;a title="Peter Pilgrim's Devoxx Link Up UStream.TV" href="http://www.ustream.tv/channel/test-from-peter-pilgrim-devoxx-linkup-1" id="mt6i"&gt;Ustream TV&lt;/a&gt; to broadcast live or recorded to native speakers of his user group who do not speak English very well. Tech has it's uses and I am digressing here ...&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;a href="http://www.flickr.com/photos/8268882@N06/4125022178/" title="Devoxx 2009 by peter_java_pilgrim, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2547/4125022178_6fba6f4e49.jpg" alt="Devoxx 2009" height="375" width="500"&gt;&lt;/a&gt;&lt;br&gt;
&lt;font size="1"&gt;Chet Haase and I in a photograph. This is a real proud moment. What a graphics hero Chet Haase is?&lt;br&gt;
&lt;/font&gt;&lt;br&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;h3&gt;Incredible Announcements and The Vector of Progress Continues Unabated&lt;br&gt;
&lt;/h3&gt;
&lt;p&gt;

The top items of interest were &lt;b&gt;JavaFX &lt;/b&gt;(of course), &lt;b&gt;Java EE 6&lt;/b&gt;, &lt;b&gt;Scala &lt;/b&gt;and &lt;b&gt;JDK 7&lt;/b&gt; Changes. Additionally, I was most impressed with the high standard of operation and integration of the Adobe &lt;b&gt;Flex &lt;/b&gt;tools. In particular, the Adobe &lt;b&gt;Catalyst &lt;/b&gt;demonstration was outstanding. 
As a developer you can easily take the composition layers of a designer's Photoshop, Illustrator or Flash file, and simply select a region, and automatically convert that graphic into an ActionScript button.This was for me watching it live physically unheard of usability and productivity between developers and designers. 


&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;a href="http://www.flickr.com/photos/8268882@N06/4124243411/" title="Devoxx 2009 by peter_java_pilgrim, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2636/4124243411_c138eeebcd.jpg" alt="Devoxx 2009" height="375" width="500"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;&lt;font size="1"&gt;Tor Norbye and Stephen Chin&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;


&lt;p&gt;JavaFX started with &lt;b&gt;Stephen Chin&lt;/b&gt;'s University talk, which I thought was a light gentre introduction into JavaFX areas and capabilities. However, in the middle of this talk was a real clincher, &lt;b&gt;Tor Norbye&lt;/b&gt;, the technical leader of authorisation tool, who demonstrated the &lt;b&gt;Netbean JavaFX Rapid Application Development&lt;/b&gt; tool. 





The NetBeans 6.8 team have been very busy. The &lt;b&gt;Matisse &lt;/b&gt;qualities of the forthcoming RAD tools for JavaFX look very impressive indeed. The ability to drag components from the palette into a design canvas, the ability edit properties of those component is simply paramount programmability. The next trick that Tor showed off was the binding, timeline and animation capabilites. Yes that is quite right, the design canvas was not a static breadboard, it actually came to life with transformation, effects and opacities changes. Best of all this produce readable JavaFX code I think. I forgot to ask Tor whether this was reversible. Can you tweak the RAD tools JavaFX code and would it still work? Hmmm.... Anyway nice, I cannot wait for&lt;b&gt; NetBeans 6.8&lt;/b&gt; to be released.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;a href="http://www.flickr.com/photos/8268882@N06/4125019014/" title="Devoxx 2009 by peter_java_pilgrim, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2589/4125019014_77cb75113a.jpg" alt="Devoxx 2009" height="375" width="500"&gt;&lt;/a&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;&lt;font size="1"&gt;Juggy, the Brazilian Java User Group mascot and myself at Access, Bar Salsa.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;There was a demonstration of the &lt;b&gt;PRISM &lt;/b&gt;runtime exclusively in the last JavaFX session on Friday with &lt;b&gt;Richard Bair&lt;/b&gt; and &lt;b&gt;Jasper Potts&lt;/b&gt;. It was fast, fantastically fast. JavaFX 1.3 will be out on January/February 2010, I think they [Sun] are targetting the &lt;b&gt;Mobile World Congress&lt;/b&gt; in &lt;b&gt;Barcelona &lt;/b&gt;for this. Good luck boys, I hope you make it. PRISM is slated for next years JavaOne 2010 (or whatever they are going to call it).&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;a href="http://www.flickr.com/photos/8268882@N06/4124244421/" title="Devoxx 2009 by peter_java_pilgrim, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2616/4124244421_25972cf827.jpg" alt="Devoxx 2009" height="375" width="500"&gt;&lt;/a&gt;
&lt;p&gt;&lt;font size="1"&gt;Howard Lewis-Ship presenting Clojure the JVM language&lt;/font&gt;&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;

&lt;p&gt;I was most impressed with &lt;b&gt;ScalaTest &lt;/b&gt;and the ability to remove boilerplate code from EasyMock and the behaviour driven tests. &lt;b&gt;Bill Venners&lt;/b&gt; was excellent and I want to take up the suggestion that a good way way to get involved in Scala is to start writing ScalaTest. He suggested that we use our own existing Java libraries and codebase to do this. Great idea.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;Java EE 6 specification and the reference implementation looks good. We are finally getting an EJB container API that we can test outside the application server. &lt;b&gt;Antonio Gonclaves&lt;/b&gt; and &lt;b&gt;Alexis &lt;a href="http://devoxx.com/display/DV09/Alexis+Moussine-Pouchkine" title="Alexis Moussine-Pouchkine"&gt;Moussine-Pouchkine&lt;/a&gt;&lt;/b&gt; had a great talk. The Servlet 3 API, however, from &lt;b&gt;Kevin Nielson&lt;/b&gt;'s eyes, at least when he discussed this topic with myself, looked weakened from what was originally expected, althought it is still a step forward in progress. Java EE 6 and the JDK 7, I believe, will make an awesome combination. No longer do we need monolithic application server that were truly heavy. Instead we might looking at web server monitors based on EJB Lite containers. The EJB might be facade on a data persistence that do need no damn SQL database server.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;Of course there is now new direction, not quite a change of heart, in Closures for Java. Go to &lt;a title="Stephen Colebourne's blog for more information on the JDK 7 Closures" href="http://www.jroller.com/scolebourne/entry/closures_in_jdk_7" id="rsp2"&gt;&lt;b&gt;Stephen Colebourne&lt;/b&gt;'s blog for more information on the JDK 7 Closures&lt;/a&gt; as they now stand up.&lt;br&gt;
&lt;/p&gt;

&lt;a href="http://www.flickr.com/photos/8268882@N06/4125017056/" title="Devoxx 2009 by peter_java_pilgrim, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2590/4125017056_7e06d0c22d.jpg" alt="Devoxx 2009" height="375" width="500"&gt;&lt;/a&gt;
&lt;br&gt;
&lt;font size="1"&gt;
To left is Mark Reinhold of Sun Microsystem's JDK 7 project and the Joe Darcy the technical lead of Project Coin "Small Changes" also for JDK 7. Both are participating with Brian Goetz and Alex Buckley (out of the picture) in a JDK 7 BOF at Devoxx on 18 November 2009
&lt;/font&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;The best keynote of the entire conference was by &lt;b&gt;Robert C. Martin&lt;/b&gt;. And so it was software professionalism that won the fight, hands-down. Martin was definitely the greatest show on earth. He was animated, he was enthused and he inspired all of us to do better in our testing. Why do not we as developer, designers and architect treat ourselves like blue-collar workers, clocking in by the hour. We are just as professionalism as accounts, bankers , lawyers and other executvies. Great stuff!&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;a href="http://www.flickr.com/photos/8268882@N06/4124242945/" title="Devoxx 2009 by peter_java_pilgrim, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2597/4124242945_861d7bcdf8.jpg" alt="Devoxx 2009" height="375" width="500"&gt;&lt;/a&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;&lt;font size="1"&gt;Sven (centre) of the NetBeans Dream Team and also Java Duke Award winner 2009 talking to Aaron Houston (out of the picture).&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;I bought only one book at the conference, a little something on &lt;b&gt;Grails&lt;/b&gt; and a companion tome to &lt;b&gt;Scott Davis'&lt;/b&gt;s &lt;b&gt;Groovy Recipes&lt;/b&gt;. By the way, whatever&amp;nbsp; happened to Vaclav Pech's GParalleliser quickie talk. Did I missed it? &lt;br&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;h3&gt;Conclusions&lt;/h3&gt;

&lt;p&gt;What a ride?! Devoxx 2009 was just great. Obviously, I finished this article on the last day of the conference on Friday, 20&lt;sup&gt;th&lt;/sup&gt; November 2009. &lt;br&gt;

&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.publicenemy.com/"&gt;&lt;img id="lp0-" style="width: 320px; height: 254.653px; float: right; margin-left: 1em; margin-right: 0pt;" src="http://docs.google.com/File?id=df5jk3g7_323gz2k28f8_b"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;There many items, which I noticed, from previous years, which were
missing. The conference ended a couple of hours earlier this year, at
lunch time. There was no Friday lunch voucher. There was no daily
newspaper and the number of exhibitions were clearly down. Sun
Microsystems Belgium were not there this year, for example, which I
personally do not care about. However, the let us consider the
positives here for a minute. The Java Champions and most of the
European JUG leaders / co-JUG leaders were in attendance. You got
entrepreneur and really good technical/business people like David Booth
coming here, then most of the people in your niché of technology
whether it be Groovy, Scala, Fan(tom), SOA, FX or just plain Java
around. For me even members of the &lt;b&gt;JAVAWUG&lt;/b&gt; , &lt;b&gt;Markus K&lt;/b&gt; and &lt;b&gt;Phil Haigh&lt;/b&gt;, made it over at the last
minute, the conference was not sold out a week before. I think it says
something about developers, designers and architects and that they are
still hungry of innovation, inspiration and good old community
socialisation. Above all, I strongly recommend the Devoxx conference to any Java
beginner in Europe who wants to expand their mind, to get ahead and to stay ahead of the pack. Just like "Public Enemy Number One! One, one, one. One, two, three, huue haarggh"&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;Finally, &lt;b&gt;Parleys.com &lt;/b&gt;are offering, now, a subscription to &lt;b&gt;&lt;a title="Devoxx Online" href="http://devoxx.parleys.com/" id="xj.-"&gt;Devoxx Online&lt;/a&gt;&lt;/b&gt;. For pnly 49.00EU for six months, you can get streamed videos of the conference show as they are transcoded, uploaded and produced on demand. This is great for those of you who could not attend Devoxx and also feel that you need some further education. &lt;br&gt;
&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;This is Peter Pilgrim at Devoxx 2009. Out!&lt;br&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;h2&gt;&lt;b&gt;The Shout Outs!&lt;/b&gt;&lt;/h2&gt;
&lt;br&gt;
In no special order:&lt;br&gt;
&lt;br&gt;
&lt;b&gt;Dave Booth&lt;/b&gt;, CEO of Zero Turnaround,&lt;br&gt;
&lt;b&gt;Stephen Janssen&lt;/b&gt;, "Mr. Devoxx", himself &lt;br&gt;
&lt;b&gt;Jo Voreendecker&lt;/b&gt;, JavaFX and Flex, Devoxx Committee member&lt;br&gt;
&lt;b&gt;Dan Hardiker&lt;/b&gt;, Adaptavist, Devoxx Committee member&lt;br&gt;
&lt;b&gt;Stephen Colebourne&lt;/b&gt;, Fan(tom) Language Adovocate, Author of First Class Methods Closure Proposal 2008&lt;br&gt;
&lt;b&gt;Aaron Houston&lt;/b&gt;, Program Manager, Outreach, Sun Microsystems,&lt;br&gt;
&lt;b&gt;Mike Van Riper&lt;/b&gt;, Silicon Valley Web User Group, JUG Leader&lt;br&gt;
&lt;b&gt;Kevin Nilson&lt;/b&gt;,&amp;nbsp; Silicon Valley Web User Group, JUG Leader&lt;br&gt;
&lt;b&gt;Valerié Hillaweare&lt;/b&gt;, Devoxx Committee member and Congratulations. ( All the best for February 2010 ;-)&lt;br&gt;
&lt;b&gt;Stephen Chin&lt;/b&gt;, JFXtras Project&lt;br&gt;
&lt;b&gt;Markus Kobler&lt;/b&gt;, JAVAWUG Member, London&lt;br&gt;
&lt;b&gt;Oliver Gierke&lt;/b&gt;, JPR09 Housemate&lt;br&gt;
&lt;b&gt;Alex Buckley&lt;/b&gt;, JDK 7 Jigsaw, Sun&lt;br&gt;
&lt;b&gt;Brian Goetz&lt;/b&gt;, Universal VM and JavaFX Compiler and Runtime&lt;br&gt;
&lt;b&gt;Richard Bair&lt;/b&gt;, JavaFX Team, Sun&lt;br&gt;
&lt;b&gt;Jasper Potts&lt;/b&gt;, JavaFX Team, Sun &lt;br&gt;
&lt;b&gt;Holly Cummins&lt;/b&gt;, IBM Performance (Come on down and present to the LondonJAVAWUG anytime)&lt;br&gt;
&lt;b&gt;Kirk Pepperdine&lt;/b&gt;, Kodework (You too),t&lt;br&gt;
&lt;b&gt;Alain Moran&lt;/b&gt;, Adaptavist&lt;br&gt;
&lt;b&gt;Keith Brophy&lt;/b&gt;, Adaptavist&lt;br&gt;
&lt;b&gt;Frederick Simon&lt;/b&gt;, JFrog&lt;br&gt;
&lt;b&gt;Shlomi Ben Haim&lt;/b&gt;, Co Founder CEO JFrog&lt;br&gt;
&lt;b&gt;Daniel Wroblewski&lt;/b&gt;, Flygpoolen&lt;br&gt;
&lt;b&gt;Marcelo&lt;/b&gt; &lt;b&gt;Milano&lt;/b&gt;, JUG Milano,&lt;br&gt;
&lt;b&gt;Joe Darcy&lt;/b&gt;, Project Jigsaw, Sun Microsystems,&lt;br&gt;
&lt;b&gt;Reggie Hutcherson&lt;/b&gt;, Program Director, Outreach, Sun Microsystems &lt;br&gt;
&lt;b&gt;Frenk Greco&lt;/b&gt;, New York Java Users Group, KaaZing,&lt;br&gt;
&lt;b&gt;Romain Guy&lt;/b&gt;, Curious Creature, Android SDK Google&lt;br&gt;
&lt;b&gt;Dick Wall&lt;/b&gt;, Java Posse,&lt;br&gt;
&lt;b&gt;Joe Nuxoll&lt;/b&gt;, Java Posse,&lt;br&gt;
&lt;b&gt;Tor Norbye&lt;/b&gt;, Java Posse,&lt;br&gt;
&lt;b&gt;Karl Quinn&lt;/b&gt;, Java Posse&lt;br&gt;
&lt;b&gt;Antonio Gonclaves&lt;/b&gt;, Java EE 6 Export Group member, Paris JUG Leader&lt;br&gt;
&lt;b&gt;Peter Lubbers&lt;/b&gt;, CEO, KaaZing&lt;br&gt;
&lt;b&gt;Jevgeni Kabanov&lt;/b&gt;, Founder, Chief Technical Officer, ZeroTurnaround&lt;br&gt;
&lt;b&gt;Bill Venners&lt;/b&gt;, Scala Test presenter at Devoxx, Artima&lt;br&gt;
&lt;b&gt;Jason van Zyl&lt;/b&gt;, Maven 3, Sonatype&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;br&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/VDbLS7lahKM" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/peter_pilgrim/entry/devoxx_2009_digital_media_report</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/serkanguler/entry/jdk7_notes_from_devoxx09</guid>
    <title>JDK7 notes from Devoxx09</title>
    <dc:creator>Serkan Guler</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/BNka-u_iUuk/jdk7_notes_from_devoxx09</link>
        <pubDate>Fri, 20 Nov 2009 06:20:20 -0500</pubDate>
    <category>Java</category>
    <category>devoxx09</category>
    <category>java</category>
    <category>jdk7</category>
            <description>&lt;p&gt;&lt;a href="http://serkanguler.info/2009/11/20/jdk7-notes-from-devoxx09/"&gt;http://serkanguler.info/2009/11/20/jdk7-notes-from-devoxx09/&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/BNka-u_iUuk" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/serkanguler/entry/jdk7_notes_from_devoxx09</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/neugens/entry/fedora_12</guid>
    <title>Fedora 12</title>
    <dc:creator>Mario Torre</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/0oqCFq3k7Ko/fedora_12</link>
        <pubDate>Fri, 20 Nov 2009 05:22:12 -0500</pubDate>
    <category>Linux</category>
            <description>&lt;p&gt;It&amp;#8216;s out and it&amp;#8216;s nice. And &lt;a href='http://www.theregister.co.uk/2009/11/19/fedora_12_root_imbroglio/'&gt;looks like&lt;/a&gt; even Microsoft &lt;a href='https://bugzilla.redhat.com/show_bug.cgi?id=534047'&gt;is contributing to it too&lt;/a&gt;.&lt;/p&gt;

	&lt;p&gt;I guess I&amp;#8216;m going to wait a little before &amp;#8220;upgrading&amp;#8221; this time&amp;#8230;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/0oqCFq3k7Ko" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/neugens/entry/fedora_12</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/scolebourne/entry/why_jsr_310_isn_t</guid>
    <title>Why JSR-310 isn't Joda-Time</title>
    <dc:creator>Stephen Colebourne</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/BVNLMOI96zk/why_jsr_310_isn_t</link>
        <pubDate>Fri, 20 Nov 2009 03:44:38 -0500</pubDate>
    <category>Java</category>
    <category>jodatime</category>
    <category>jsr310</category>
            <description>&lt;p&gt;
One question that has been repeatedly asked is why 
&lt;a href="https://jsr-310.dev.java.net/"&gt;JSR-310&lt;/a&gt; wasn't simply the same as
&lt;a href="http://joda-time.sourceforge.net"&gt;Joda-Time&lt;/a&gt;.
I hope to expain some reasons here.
&lt;/p&gt;

&lt;h4&gt;Joda-Time as JSR-310?&lt;/h4&gt;
&lt;p&gt;
At its heart, JSR-310 is an effort to add a quality date and time library to the JDK.
So, since most people consider Joda-Time to be a quality library, why not include it directly in the JDK?
&lt;/p&gt;
&lt;p&gt;
Well, there is one key reason - Joda-Time has design flaws.
&lt;/p&gt;
&lt;p&gt;
Now before everyone panics and abuses that line as a tweet, I need to say that Joda-Time
is by far the best option curently available, and that most users won't appreciate the design flaws.
But, I do want to document them, so the basis for the changes in JSR-310 is clear.
&lt;/p&gt;
&lt;p&gt;
&lt;u&gt;1) Human/Machine timelines&lt;/u&gt;
&lt;/p&gt;
&lt;p&gt;
One element of clarity is a better understanding of the distinction between the two
principle views of the timeline - Human and Machine.
&lt;/p&gt;
&lt;p&gt;
Machines have one view - a single, ever increasing number.
In Java we set zero as 1970-01-01T00:00Z and count in milliseconds from there.
&lt;/p&gt;
&lt;p&gt;
Humans have a totally different view of time.
We have multiple calendar systems (one primary, many others), which divide the timeline into
years, months, days, hours, minutes and seconds.
In addition, humans have time zones which cause the values to vary around the globe, and for there
to be gaps and overlaps in the human timeline as DST starts and ends.
&lt;/p&gt;
&lt;p&gt;
Much of the time, a conversion between the two timeline views is possible with a time zone,
however in a DST gap or overlap, things are much less clear.
&lt;/p&gt;
&lt;p&gt;
Joda-Time defines two key interfaces - ReadableInstant and ReadablePartial.
Both the Instant class (simple instant in time) and the DateTime class (human view of an
instant in time) are implementations of ReadableInstant. This is wrong.
&lt;/p&gt;
&lt;p&gt;
DateTime is a human-timeline view of the world, not a machine-timeline view.
As such, DateTime is much better thought of, and designed as, a LocalDateTime and a timezone
rather than the projection of the machine timeline onto the human timeline.
Thus, DateTime should not implement ReadableInstant.
&lt;/p&gt;
&lt;p&gt;
&lt;u&gt;2) Pluggable chronology&lt;/u&gt;
&lt;/p&gt;
&lt;p&gt;
What is the range of values returned by this method in Joda-Time?:&lt;br /&gt;
&lt;code&gt; int month = dateTime.getMonthOfDay(); &lt;/code&gt;&lt;br /&gt;
The answer is not 1 to 12, but could be 1 to 13! (yet January is still  1 and December is 12)
&lt;/p&gt;
&lt;p&gt;
The answer to this puzzler is down to pluggable chronologies.
Each date/time class in Joda-Time has a pluggable chronology.
This defines the calendar system that is in use.
But most users of the API never check to see if the chronology is the standard ISO/ chronology
before calling getMonthOfDay().
Yet, the Coptic chronology has 13 months in a year, and thus can return a range of 1 to 13.
&lt;/p&gt;
&lt;p&gt;
A better solution would be to keep the date/time classes restricted to a single calendar system.
That way, the result from each method call is clear, and not dependent on any other state
in the class, like the chronology.
&lt;/p&gt;
&lt;p&gt;
&lt;u&gt;3) Nulls&lt;/u&gt;
&lt;/p&gt;
&lt;p&gt;
Joda-Time accepts null as a valid value in most of its methods.
For date/times it means 1970-01-01T00:00Z. For durations it means zero.
For peiods it means zero.
&lt;/p&gt;
&lt;p&gt;
This approach causes random bugs if your code happens to provide a null to Joda-Time that
you hadn't originally planned for. Instead of throwing an error, Joda-Time continues,
and the resulting date/time is going to be different from what you want.
&lt;/p&gt;
&lt;p&gt;
&lt;u&gt;4) Internal implementation&lt;/u&gt;
&lt;/p&gt;
&lt;p&gt;
Certain aspects of the internal implementation are complex, and the result of having pluggable
chronologies and a misunderstanding of the machine/human divide in the timeline.
Changing this is a big change to the code.
&lt;/p&gt;
&lt;p&gt;
One particular area of trouble is managing DST overlaps.
The behaviour in Joda-Time of these isn't that well defined.
&lt;/p&gt;
&lt;h4&gt;Summary&lt;/h4&gt;
&lt;p&gt;
&lt;b&gt;Joda-Time isn't broken!&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
It does the job it was designed for, and does it much better than the JDK.
And it is widely used and without too many major issues.
However, after a few years, it is now clear where it could be designed better.
&lt;/p&gt;
&lt;p&gt;
I took the decision that I didn't want to add an API to the JDK that had known design flaws.
And the changes required weren't just minor.
As a result, JSR-310 started from scratch, but with an API 'inspired by Joda-Time'.
&lt;/p&gt;
&lt;p&gt;
I hope that explains the thought process behind the creation of a new API in JSR-310.
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/BVNLMOI96zk" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/scolebourne/entry/why_jsr_310_isn_t</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/rickard/entry/systems_thinking_and_maxis</guid>
    <title>Systems Thinking and Maxis</title>
    <dc:creator>Rickard Öberg</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/4PYa0Gg20Fc/systems_thinking_and_maxis</link>
        <pubDate>Fri, 20 Nov 2009 01:09:09 -0500</pubDate>
    <category>Java</category>
            <description>&lt;p&gt;&lt;p&gt;In our StreamFlow project, where we build a workflow system for humans based on GTD, Human Interaction Theory and Systems Thinking, it has been interesting to do research on these topics, and in particular ST. ST states, according to John Seddon, that a worker in a system have roughly 5% impact and the system itself has 95% impact. These are bold numbers, and I've been wondering how accurate they are.&lt;/p&gt;&lt;p&gt;Then today I got an interesting example of this. I'm using the new iPhone 3GS in Malaysia, and the default telco for it is Maxis. Since I mostly wanted to use the data services I signed up for a Value-package which includes 3GB each month, and then I pay extra for calls to other operators. Since my wife is on Celcom there's a non-zero cost to that every month. So far so good.&lt;/p&gt;&lt;p&gt;Then yesterday my phone stopped working! Calling the Maxis hotline number stated that we had not paid our bill! But, we had only received one bill, which we HAD paid. What was going on!?&lt;/p&gt;&lt;p&gt;When we called the Maxis callcenter, using another phone since my own Maxis-connected phone was unusable, we got the explanation. The Value-package I have cost 99RM per month, but the credit limit is 100RM. As I had made a phonecall using the iPhone, the total for the next bill was over 99RM, and so Maxis instantly shut down the phone. So where was the bill? As far as we knew we had paid it! Apparently the new bill was sent a couple of days ago, but had not yet arrived in our mailbox, so there was no way that I could have paid it! In essence, there is no way that I can use the iPhone to make calls without having it be closed down each month between the time they send out the bill and me paying it a couple of days later. The stupidity of this system completely boggles my mind, but there ya go.&lt;/p&gt;&lt;p&gt;The people at the Maxis callcenter did everything correct, answering our questions about how this situation could come about. And there was nothing they could do about it. They were an example of that the system really does represent 95% of what the customer experience is. No matter how nice they were, and they were, my experience of Maxis, as a customer, is absolutely horrible.&lt;/p&gt;&lt;p&gt;Then, a couple of hours later I get an SMS from Maxis:&lt;br /&gt;&lt;b&gt;&amp;quot;Please rate our Maxis staff from 1 to 5. 1=lowest &amp;amp; 5=highest for the customer experience you received recently. Kindly reply to 20002 at no cost to you. TQ&amp;quot;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;I understand what they want, they want me to rate the staff taking the call, but as ST shows, and which this example confirms, the staff that took my call has almost nothing to do with my customer experience. Their stupid system is entirely responsible for my lousy customer experience. I responded &amp;quot;1&amp;quot;, of course, knowing that this will tell them nothing. They are asking the wrong question, as they have the wrong assumption (that the callcenter staff can influence my customer experience in any significant way). What that &amp;quot;1&amp;quot; really means is that whoever came up with the policy that caused this situation should be instantly fired (first, for causing waste and failure demand in the Maxis system, and second, for giving me a reason to switch operator). Even worse, the higher-up execs at Maxis are also in trouble, as they are not ensuring that there is a system in place whereby Maxis can get relevant feedback (feedback on the system) from customers which would give them actual data to use to improve their business. In the end, this can only cause Maxis to lose revenue and business.&lt;/p&gt;&lt;p&gt;The more I delve into understanding Systems Thinking, and seeing the lack of it in businesses that I deal with on a daily basis, the more I understand just how much potential there is for improvement out there. I hope that we can build some of this understanding into our own products, and can avoid these kinds of problems ourselves. Having a solid method for improving our business and understanding of our customers' needs is essential, and it seems Systems Thinking can help us do that.&lt;/p&gt;&lt;p&gt;&lt;b&gt;UPDATE 2009-11-23:&lt;/b&gt; I was called up by Maxis customer support to discuss my concerns. The lady I talked to was most graceful, and did everything correct from the point of view of what she had instructed, even though it was clear that the instructions were, as they say, bollocks. The first attempt at fixing the above issue was to increase the credit limit, which would give me more &amp;quot;space&amp;quot; to make phonecalls without having the phone shutdown. While this would work there are two problems with it: one, I would probably have to pay for a &amp;quot;top up&amp;quot;, and second, sometimes I make overseas calls which are quite expensive, and so it could happen that even an increased credit limit that would solve my local calls problems wouldn't be enough. &lt;/p&gt;&lt;p&gt;Seeing this is a generally bad solution I asked for the reason behind this credit limit in the first place. The reasoning was that they wanted to &amp;quot;protect&amp;quot; customers from getting too high bills that they couldn't pay, and so they turn off the phone after the credit limit has been reached. She did say that they send out warning SMS's first, but when I looked I couldn't find any. And even if they did, there's a big chance I would delete it without looking at it, as Maxis sends quite a lot of spam SMS's that I delete without even opening. Another bad business practice that gets in the way of achieving real value for me as a customer, and in the end, for Maxis. All in all, my guess is that they do this just to get people to &amp;quot;top up&amp;quot; the credit limit, which in effect is free money for them even though it is just an inconvenience for the customer.&lt;/p&gt;&lt;p&gt;The second suggestion was that I should call the customer support callcenter if I received a warning SMS, to tell them not to close down my phone and that I would pay it shortly. Since this would happen every month if I don't increase my credit limit I would have to repeat this dance every month. This would obviously create failure demand in the support callcenter (=phone calls that don't bring value to Maxis or me as a customer), and is just pure waste. Still, this is what was suggested. Seriously! Again, I want to emphasize that I don't blame the person calling me, who had no way to help me other than tell me all these stupid suggestions that she had in her scripts, all of which were bad both for Maxis and myself.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The last suggestion was that I should change to have my bills sent by email. Then I would get them quicker and could pay them before they shut off my phone. At this point my mind is boggled quite a bit. She was asking me to change my behaviour (get bill by email instead of snailmail) to compensate for their bad processes. I refused, and said that even if I &amp;quot;fixed&amp;quot; my problem this way, it wouldn't help Maxis or the other customers who did not have this option. It was just a way to &amp;quot;cover up&amp;quot; the bad process, not fix it at its root.&lt;/p&gt;&lt;p&gt;In the end I agreed to let her check if my credit limit could be upped somewhat, with the condition that I should not have to pay extra just to be able to use the phone as a normal user. She would check it out. So that's the status for now.&lt;/p&gt;&lt;p&gt;This again shows that the worker, in this case the lovely callcenter support agent, could not impact my customer experience in the least, as the main problem has to do with the system at Maxis. No performance targets, KPI's, ISO 9000 certifications, or any similar bullshit, would ever be able to fix this. Only a change to the system would.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Update 2009-11-24&lt;/b&gt;: The Maxis bill arrived today, and it is even worse than I thought. Initially I thought the issue was that I had made some phone calls with my phone, and that was what crossed me over the credit limit. From the bill, however, it is clear that it would have been shut off even if I hadn't used it at all. Why is that? Because I have the base &amp;quot;Value 50&amp;quot; package (i.e. 50RM monthly), and then I added a monthly data service for 99RM, which together brings the bill to 149RM per month - 49RM above my credit limit. Which causes the phone to be shut off without notice. Why this wasn't pointed out by the Maxis sales when I got the phone is one question to consider, but the main solutions to this problem seems to be: either I have to give Maxis more money up front to increase my credit limit (and I would have had to figure that out on my own, since the sales didn't mention it), or I have to call Maxis every month to say &amp;quot;please don't shut off my phone, I'll pay the bill&amp;quot;, and yes, this I would also have to figure out on my own. It's like Maxis don't want customers, or at least not in a way that is beneficial for the customers. It will be really interesting to see just how much stupidity will be exposed once I get to the bottom of this pit of bad business practices.&lt;br /&gt;&lt;/p&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/4PYa0Gg20Fc" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/rickard/entry/systems_thinking_and_maxis</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/javawug/entry/javawug_bof_52_what_is</guid>
    <title>JAVAWUG BOF 52 What is Oracle Doing With Java?</title>
    <dc:creator>Peter Pilgrim</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/JtHkuJLS78E/javawug_bof_52_what_is</link>
        <pubDate>Thu, 19 Nov 2009 20:51:10 -0500</pubDate>
    <category>Java</category>
    <category>business</category>
    <category>consumers</category>
    <category>enterprise</category>
    <category>groovy</category>
    <category>hardware</category>
    <category>java</category>
    <category>javafx</category>
    <category>javawug</category>
    <category>microsystems</category>
    <category>oracle</category>
    <category>scala</category>
    <category>software</category>
    <category>sun</category>
            <description>&lt;br id="b5hq"&gt;
 
&lt;h1 id="b5hq0"&gt; JAVAWUG BOF 52 What is Oracle Doing With Java?&lt;br&gt;
&lt;/h1&gt;
 



&lt;table class="zeroBorder" id="b5hq1" align="right" border="0" cellpadding="3" cellspacing="0" hspace="25" vspace="25" width="275"&gt; 
 
&lt;tbody id="b5hq2"&gt; 
 
&lt;tr id="b5hq3"&gt; 
 
&lt;td id="b5hq4" align="center" bgcolor="#f0f0ff"&gt;
 
&lt;div id="b5hq5" style="background: white none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;
 &lt;a id="b5hq6" href="http://www.javawug.com"&gt;
 &lt;img id="b5hq7" src="http://www.jroller.com/javawug/resource/JAVAWUG07-256w266h.png" border="0" height="266" hspace="10" vspace="10" width="266"&gt;&lt;/a&gt;
 &lt;/div&gt;
 &lt;/td&gt;
 &lt;/tr&gt;
 
 
&lt;tr id="b5hq8"&gt;
 
&lt;td id="b5hq9" align="center" bgcolor="#f0f0ff"&gt;
 &lt;font id="b5hq10" color="#000000" size="+1"&gt; &lt;b id="b5hq11"&gt;Birds-of-a-Feather 52&lt;br id="b5hq12"&gt;
 Thursday, &lt;br&gt;
3&lt;sup id="b5hq13"&gt;rd&lt;/sup&gt; December 2009&lt;br id="b5hq14"&gt;
&lt;/b&gt;
 Oracle City of London Office, &lt;br&gt;
London, UK&lt;/font&gt;&lt;span id="b5hq15" style="color: rgb(255, 0, 0);"&gt;&lt;b id="b5hq16"&gt;&lt;br&gt;
&lt;/b&gt;&lt;/span&gt;
 &lt;/td&gt;
 &lt;/tr&gt;
 
 &lt;/tbody&gt;
 
&lt;/table&gt;
 




&lt;p id="b5hq17"&gt; Dear All &lt;/p&gt;
 &lt;br id="b5hq18"&gt;
 &lt;br id="b5hq19"&gt;
 
&lt;p id="b5hq20"&gt; &lt;br id="b5hq21"&gt;
 &lt;/p&gt;
 &lt;br id="b5hq22"&gt;
&lt;br id="b5hq25"&gt;
 
&lt;p id="b5hq26"&gt; I would like to formally announce that &lt;b id="b5hq27"&gt;JAVAWUG&lt;/b&gt; (Java Web User Group) is holding the Fifty Second Birds-of-Feather (Meet-up 52) at &lt;b id="b5hq28"&gt;Oracle City of London Office&lt;/b&gt; on Thursday, 3&lt;sup id="b5hq29"&gt;rd&lt;/sup&gt; December 2009 from 18:30 until 20:30 .&lt;/p&gt;
&lt;br&gt;
&lt;br&gt;
&lt;div id="ckw1" style="text-align: left;"&gt;&lt;img src="http://docs.google.com/File?id=df5jk3g7_319gtz6xpj7_b" height="79" width="178"&gt;&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
&lt;br clear="all"&gt;
&lt;div style="text-align: center;"&gt;&lt;font size="7"&gt;What is&lt;/font&gt;&lt;br id="b5hq32"&gt;
&lt;/div&gt;
&lt;p id="socl"&gt;&lt;/p&gt;
&lt;div id="cps." style="text-align: center;"&gt;&lt;img style="width: 640px; height: 90.8327px;" src="http://docs.google.com/File?id=df5jk3g7_3186d8pcgds_b"&gt;&lt;/div&gt;
&lt;br&gt;
&lt;div style="text-align: center;"&gt;&lt;font size="7"&gt;Doing with Java™?&lt;/font&gt;&lt;br id="etz8"&gt;
&lt;/div&gt;


&lt;p style="color: rgb(255, 0, 0);" id="iodi"&gt;&lt;br&gt;
&lt;/p&gt;
&lt;p id="npnw"&gt;&lt;br id="b5hq34"&gt;
&lt;/p&gt;
&lt;h2 id="b5hq35"&gt;Headline Talk&lt;/h2&gt;
&lt;b&gt;Title: Oracle and Java&lt;br&gt;
&lt;/b&gt;
&lt;p id="ihts"&gt;&lt;b&gt;Speaker: Duncan Mills, Sr. Director, Oracle Development Tools&lt;/b&gt;&lt;/p&gt;
&lt;p id="wkyl"&gt;&lt;br&gt;
&lt;/p&gt;
&lt;br&gt;
&lt;p id="equ2"&gt;&lt;br id="b5hq24"&gt;
Whilst the future of the Oracle/ Sun deal is in the hands of the European Union we can't talk in detail about Oracle's plans for Java or any other Sun product. However, in this talk I'll explain exactly how Oracle, as a major consumer of Java in it's own right, uses the Java platform for it's own application development. This will concentrate on the key technologies and frameworks that we use, and why we use them, for building both web user interfaces and other parts of the solution stack.&lt;br&gt;
&lt;/p&gt;
&lt;p id="jlv&lt;img src="http://www.jroller.com/images/smileys/blush.gif" class="smiley" alt=":&amp;quot;&amp;gt;" title=":&amp;quot;&amp;gt;" /&gt;&lt;br&gt;

&lt;/p&gt;
&lt;h2 id="b5hq39"&gt;Biography&lt;br id="b5hq40"&gt;
 &lt;/h2&gt;
Duncan Mills is Senior Director of Product Management for Oracle's development tools and frameworks including both the Oracle JDeveloper IDE, the Oracle Application Development Framework and the Oracle Enterprise Pack for Eclipse. Duncan has been working in the IT industry for 20 years or so both in the UK and the USA. He was one of the earlier members of JavaWUG before callously abandoning the group for the sunny land of California.&amp;nbsp; &lt;br&gt;
&lt;br&gt;
Duncan Mill's Blog &lt;a title="http://groundside.com/blog/" href="http://groundside.com/blog/" id="ssh9"&gt;http://groundside.com/blog/&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
&lt;a title="Google Video Introduction to JavaServer Faces" href="http://video.google.com/videoplay?docid=-4159610325036424729" id="bqhj"&gt;Google Video: Introduction to JavaServer Faces&lt;/a&gt;&lt;br&gt;
&lt;a title="Google Video: Quick Introduction to ADF JSF" href="http://video.google.com/videoplay?docid=-4007935838724254948" id="aa-."&gt;Google Video: Quick Introduction to ADF JSF&lt;/a&gt;&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;h2&gt;Support Talk&lt;/h2&gt;
&lt;b&gt;Title: 15 Java libraries every Java developer should know about&lt;br&gt;
Speaker: Joe Walnes&lt;/b&gt;&lt;br&gt;
&lt;br&gt;
&lt;span id="rg9o" style="color: rgb(255, 0, 0);"&gt;&lt;br&gt;
&lt;/span&gt;
&lt;div&gt;A quick tour of some high quality libraries that can improve productivity and functionality. Some new, some old. Some well known, some unsung heroes.&lt;/div&gt;
&lt;div&gt;&lt;br&gt;
&lt;/div&gt;
&lt;div&gt;I'll give an overview and some examples of things you can do with them. Even if you can't use them immediately, it's always useful to know about the possibilities out there. All of the libraries are open source, and easy to embed in any existing JVM based system.&lt;/div&gt;
&lt;div&gt;&lt;br&gt;
&lt;/div&gt;
&lt;div&gt;This will include libraries for: data processing, common utilities, concurrency, performance, scalability, testing, and web apps.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;h2&gt;Biography&lt;/h2&gt;
Joe Walnes leads the software team for DRW London, a proprietary trading organization. In a previous life, Joe has also worked for Google and ThoughtWorks. He founded some Java open source projects, including &lt;a title="XStream" href="http://xstream.codehaus.org/" id="j3h_"&gt;XStream&lt;/a&gt;, &lt;a title="SiteMesh" href="http://www.opensymphony.com/sitemesh/" id="a9tk"&gt;SiteMesh&lt;/a&gt;, Hamcrest, QDox and Objenesis. But he won't be talking about those. He also co-founded the &lt;a title="OpenSymphony" href="http://opensymphony.org/" id="k5f&lt;img src="http://www.jroller.com/images/smileys/blush.gif" class="smiley" alt=":&amp;quot;&amp;gt;" title=":&amp;quot;&amp;gt;" /&gt;OpenSymphony&lt;/a&gt; project and has contributed to projects such as &lt;a title="WebWork" href="http://www.opensymphony.com/webwork;jsessionid=DGBJMDHNHAOE" id="z5g."&gt;WebWork&lt;/a&gt;, &lt;a title="jMock" href="http://www.jmock.org/" id="cq3f"&gt;jMock&lt;/a&gt;, ActiveMQ, XDoclet and &lt;a title="Groovy" href="http://groovy.codehaus.org/" id="pdf2"&gt;Groovy&lt;/a&gt;. Joe's main interests are performance, scalability, concurrency, rich web applications, usability and lean development.&lt;br&gt;
&lt;br&gt;
&lt;div&gt;&lt;a title="http://joewalnes.com/" href="http://joewalnes.com/" id="kpmj"&gt;http://joewalnes.com/&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;&lt;a title="http://drw.com/" href="http://drw.com/" id="h880"&gt;http://drw.com/&lt;/a&gt;&lt;br id="b5hq41"&gt;
 
&lt;h2 id="rnb-"&gt;&lt;br&gt;
 &lt;/h2&gt;
&lt;h2 id="rh0y"&gt;Registration &lt;/h2&gt;
 
&lt;p id="b5hq43"&gt; Afterwards members can retire to the nearby All Bar One pub/restaurant for more in depth discussion dinner, food and drink ... &lt;/p&gt;
 
&lt;p id="b5hq46"&gt; &lt;br id="b5hq47"&gt;
 &lt;/p&gt;
 
&lt;p id="b5hq48"&gt; The address is: &lt;/p&gt;
 
&lt;p id="xpn." style="background-color: rgb(255, 102, 0); color: rgb(255, 255, 255);"&gt; &lt;b&gt;Oracle City of London&lt;/b&gt;&lt;br&gt;
Oracle Corporation UK Ltd., &lt;br&gt;
One South Place, &lt;br&gt;
London. &lt;br&gt;
&lt;/p&gt;
&lt;p id="xty8" style="background-color: rgb(255, 102, 0); color: rgb(255, 255, 255);"&gt;EC2M 2RB&lt;br&gt;
Tel: 0207 816 7500&lt;br&gt;
Fax: 0207 816 7555
 &lt;/p&gt;
 
&lt;p id="v-ip"&gt;&lt;br id="i70t"&gt;
 &lt;/p&gt;
&lt;p id="rixb58"&gt; If you would like to attend: &lt;/p&gt;
 
&lt;ol id="rixb59"&gt;
&lt;li id="rixb60"&gt; &lt;b id="rixb61"&gt;Please REGISTER&lt;/b&gt; so that you can be added to the &lt;a title="SECURITY DETAIL with Oracle (EventBrite)" id="rixb62" href="http://javawugbof52.eventbrite.com/"&gt;&lt;b id="rixb63"&gt;SECURITY DETAIL with Oracle (EventBrite)&lt;/b&gt;&lt;/a&gt;. &lt;/li&gt;
&lt;li id="rixb64"&gt; If you aren't a &lt;b id="pxk4"&gt;JAVAWUG member&lt;/b&gt; why not join the &lt;a id="rixb65" href="http://groups.google.com/group/javawug"&gt;&lt;b id="rixb66"&gt;JAVAWUG at Google Groups&lt;/b&gt;&lt;/a&gt;? &lt;br id="meba"&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;br id="pxk40"&gt;
For problems, send an email to &lt;b id="rixb67"&gt;peter (dot) pilgrim (at) gmail (dot) com&lt;/b&gt;. 
 
&lt;p id="pd0_"&gt; &lt;/p&gt;
&lt;br id="i70t0"&gt;
&lt;p id="b5hq69"&gt; Here is some relevant travel information: &lt;/p&gt;
 
&lt;ul id="b5hq70"&gt; 
&lt;li id="b5hq71"&gt; By Underground: -&lt;br id="b5hq72"&gt;
 &lt;a title="Moorgate" id="b5hq73" href="http://www.tfl.gov.uk/tfl/livetravelnews/realtime/tube/default.html"&gt;&lt;b id="b5hq74"&gt;Moorgate&lt;/b&gt;&lt;/a&gt;: 200 yards from Moorgate Station pass the HMV and Hotel Chocolat. &lt;b&gt;&lt;a title="Liverpool Street" href="http://www.tfl.gov.uk/tfl/livetravelnews/realtime/tube/default.html" id="uaxa"&gt;Liverpool Street&lt;/a&gt;&lt;/b&gt;: 400 yards walk north pass Broadgate exit along Eldon Street&lt;br&gt;
&lt;/li&gt;
 
&lt;li id="b5hq75"&gt; Map: &lt;a title="Google Maps Link to 1 South Place" id="b5hq76" href="http://maps.google.co.uk/maps?f=q&amp;amp;source=s_q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=oracle,+1south+place,+EC2M+2RB&amp;amp;sll=51.519385,-0.087225&amp;amp;sspn=0.007157,0.013626&amp;amp;ie=UTF8&amp;amp;hq=oracle,+1south+place,&amp;amp;hnear=London+EC2M+2RB,+UK&amp;amp;ll=51.519321,-0.087772&amp;amp;spn=0,359.986374&amp;amp;z=16&amp;amp;layer=c&amp;amp;cbll=51.519296,-0.087662&amp;amp;panoid=yeE0GzqbyJYGxrUS5ds_MA&amp;amp;cbp=12,62.42,,0,5"&gt;&lt;b id="b5hq77"&gt;Google Maps Link to 1 South Place&lt;/b&gt;&lt;/a&gt; &lt;/li&gt;
 &lt;/ul&gt;
 
&lt;p id="b5hq78"&gt; &lt;br id="b5hq79"&gt;
 &lt;/p&gt;
 
&lt;p id="b5hq80"&gt; The venue has graciously been organised by &lt;b id="b5hq81"&gt;Oracle UK&lt;/b&gt; team. We all appreciate this generous gift. &lt;/p&gt;
 
&lt;p id="b5hq82"&gt; &lt;a id="b5hq83" href="http://www.javawug.com/"&gt;JAVAWUG.com&lt;/a&gt; &lt;/p&gt;
 
&lt;p id="m1jj"&gt;&lt;br id="zeq."&gt;
 &lt;/p&gt;

&lt;table class="zeroBorder" align="right" border="0" cellpadding="3" cellspacing="0" hspace="25" vspace="25" width="275"&gt;   
&lt;tbody&gt;
&lt;tr&gt;
&lt;td bgcolor="#e0e0ff"&gt;
&lt;a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.0/uk/"&gt;&lt;img alt="Creative Commons License" style="border-width: 0pt;" src="http://i.creativecommons.org/l/by-nc-sa/2.0/uk/88x31.png"&gt;&lt;/a&gt;&lt;br&gt;
&lt;b&gt;&lt;span href="http://purl.org/dc/dcmitype/MovingImage" rel="dc:type"&gt;JAVAWUG BOF Videos&lt;/span&gt;&lt;/b&gt; by &lt;a href="http://jroller.com/javawug" rel="cc:attributionURL"&gt;Peter Pilgrim&lt;/a&gt; is licensed under a &lt;a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.0/uk/"&gt;Creative Commons Attribution-Non-Commercial-Share Alike 2.0 UK: England &amp;amp; Wales License&lt;/a&gt;.&lt;br&gt;
&lt;br&gt;
Based on a work at &lt;a href="http://jroller.com/javawug" rel="dc:source"&gt;http://jroller.com/javawug&lt;/a&gt;.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="b1i0"&gt;Media Copyright Notice&lt;br id="zeq.0"&gt;
&lt;/h2&gt;


&lt;i id="itqp"&gt;JAVAWUG BOF Events&lt;/i&gt; are video recorded, edited and published freely. We normally record the speaker and administrators. You can find examples on &lt;a title="JAVAWUG BOF Videos on Vimeo.com" href="http://www.vimeo.com/videos/search:JAVAWUG" id="ack4"&gt;Vimeo&lt;/a&gt; and &lt;a title="JAVAWUG Videos on Google Video" href="http://video.google.com/videosearch?q=javawug&amp;amp;sitesearch=#" id="u:fs"&gt;Google Video&lt;/a&gt;. On the rare occasion we do record some audience members. Please let us know if you &lt;i id="qw4j"&gt;personally &lt;/i&gt;would rather not been filmed. We reserved &lt;i&gt;Some of the Copyright 2009/2010 &lt;/i&gt;©© JAVAWUG Video Productions, &lt;a title="Creative Commons License" target="_blank" href="http://www.creativecommons.org/" id="lrjb"&gt;Creative Commons License&lt;/a&gt; (Attributions: &lt;b id="h_-_"&gt;Attribution&lt;/b&gt; (by): Licensees may copy, distribute, display and
perform the work and make derivative works based on it only if they
give the author or licensor the credits in the manner specified by
these conditions.). &lt;br id="zeq.1"&gt;
&lt;br id="zeq.2"&gt;
 
&lt;p id="b5hq86"&gt; This is &lt;a id="b5hq87" href="http://jroller.com/page/peter_pilgrim"&gt;Peter Pilgrim&lt;/a&gt;, Out. &lt;/p&gt;
&lt;br clear="all"&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/JtHkuJLS78E" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/javawug/entry/javawug_bof_52_what_is</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/RickHigh/entry/graphing_django_pyjamas_random_thoughts</guid>
    <title>Graphing, Django, pyjamas... random thoughts</title>
    <dc:creator>Rick Hightower</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/whrQYBJfdtE/graphing_django_pyjamas_random_thoughts</link>
        <pubDate>Thu, 19 Nov 2009 14:47:05 -0500</pubDate>
    <category>technology</category>
            <description>&lt;p&gt;Created the graph daemon 0.1, to pre-generates all the graphs before viewing, I did not use a graph lib, just PIL. I read the data with DOM. I read the data with lxml (python lib DOM with XPath). The graph data comes in huge XML files. I need to rewrite to use SAX for speed. But not right now. I will stick with the lxml version until I get some more time (it is a background daemon, speed it as important this phase... if I get time I will rewrite quickly).&amp;nbsp;&lt;/p&gt;&lt;p&gt;The marketing guys loved the new graphs! I created a high-res version (to zoom into detail) and a low-res version (for speed load time). I will also have to create windows of the graphs for reporting.&lt;/p&gt;&lt;p&gt;Got to work and we had another scheduling system. Django is out of scope for this release. We are going to stick with Spring MVC. We have a quick release cycle and there is no time to retrain the team. I don't have a problem with this. This takes a lot of&amp;nbsp;pressure&amp;nbsp;off of me.&lt;/p&gt;&lt;p&gt;There are some back-end (low visibility) admin mgmt apps that need written. We will use these to introduce Django into the mix for these in Jan. Then once we get a few of these under our belt we will start to use Django for some higher priority stuff. &lt;/p&gt;&lt;p&gt;For RIA pieces, I am still considering GWT or Pyjamas. If I use Pjs, I can resuse some of the graph logic that I have already written (maybe even share modules). If Pjs works out well, the new &amp;quot;desktop&amp;quot; app could go the Pjs route. Then there was one code base to rule them all. One day, there wont be web apps and desktop apps... just apps. That is the Pjs vision... not sure it is a reality.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/whrQYBJfdtE" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/RickHigh/entry/graphing_django_pyjamas_random_thoughts</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/ethdsy/entry/reentrantlock_bug</guid>
    <title>ReentrantLock Bug?</title>
    <dc:creator>David Shay</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/hnD_KPwSt-w/reentrantlock_bug</link>
        <pubDate>Thu, 19 Nov 2009 08:05:41 -0500</pubDate>
    <category>Java</category>
            <description>This is the kind of bug that never happens, except when it does. I've been sent the following stack trace:
&lt;pre&gt;
java.lang.IllegalMonitorStateException
	at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:127)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1175)
	at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:431)
        ...
&lt;/pre&gt;
&lt;p&gt;
This exception can occur in an unlock() method only if the thread that performs the unlock is not the one that performed the lock. Which was not really the case for me. Here is more or less what my code is doing:
&lt;pre&gt;
&lt;font color="#ffffff"&gt;   &lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;private &lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;Lock theLock = &lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;new &lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;ReentrantLock();&lt;/font&gt;
&lt;font color="#ffffff"&gt;   &lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;private &lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;Condition theCondition = theLock.newCondition();&lt;/font&gt;
&lt;font color="#ffffff"&gt;   &lt;/font&gt;
&lt;font color="#ffffff"&gt;   &lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;private &lt;/b&gt;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;void &lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;await()&lt;/font&gt;
&lt;font color="#ffffff"&gt;   &lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;
&lt;font color="#ffffff"&gt;      &lt;/font&gt;&lt;font color="#000000"&gt;theLock.lock();&lt;/font&gt;
&lt;font color="#ffffff"&gt;      &lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;try&lt;/b&gt;&lt;/font&gt;
&lt;font color="#ffffff"&gt;      &lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;
&lt;font color="#ffffff"&gt;         &lt;/font&gt;&lt;font color="#000000"&gt;...&lt;/font&gt;
&lt;font color="#ffffff"&gt;         &lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;boolean &lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;bHasTimedOut = !theCondition.await( &lt;/font&gt;&lt;font color="#990000"&gt;1&lt;/font&gt;&lt;font color="#000000"&gt;, TimeUnit.SECONDS );&lt;/font&gt;
&lt;font color="#ffffff"&gt;         &lt;/font&gt;&lt;font color="#000000"&gt;...&lt;/font&gt;
&lt;font color="#ffffff"&gt;      &lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;
&lt;font color="#ffffff"&gt;      &lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;catch &lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;(InterruptedException e)&lt;/font&gt;
&lt;font color="#ffffff"&gt;      &lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;
&lt;font color="#ffffff"&gt;         &lt;/font&gt;&lt;font color="#000000"&gt;e.printStackTrace();&lt;/font&gt;
&lt;font color="#ffffff"&gt;      &lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;
&lt;font color="#ffffff"&gt;      &lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;finally&lt;/b&gt;&lt;/font&gt;
&lt;font color="#ffffff"&gt;      &lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;
&lt;font color="#ffffff"&gt;         &lt;/font&gt;&lt;font color="#000000"&gt;theLock.unlock();&lt;/font&gt;
&lt;font color="#ffffff"&gt;      &lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;
&lt;font color="#ffffff"&gt;   &lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;
&lt;font color="#ffffff"&gt;   &lt;/font&gt;
&lt;font color="#ffffff"&gt;   &lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;private &lt;/b&gt;&lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;void &lt;/b&gt;&lt;/font&gt;&lt;font color="#000000"&gt;wake()&lt;/font&gt;
&lt;font color="#ffffff"&gt;   &lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;
&lt;font color="#ffffff"&gt;      &lt;/font&gt;&lt;font color="#000000"&gt;theLock.lock();&lt;/font&gt;
&lt;font color="#ffffff"&gt;      &lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;try&lt;/b&gt;&lt;/font&gt;
&lt;font color="#ffffff"&gt;      &lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;
&lt;font color="#ffffff"&gt;         &lt;/font&gt;&lt;font color="#000000"&gt;...&lt;/font&gt;
&lt;font color="#ffffff"&gt;         &lt;/font&gt;&lt;font color="#000000"&gt;theCondition.signal();&lt;/font&gt;
&lt;font color="#ffffff"&gt;         &lt;/font&gt;&lt;font color="#000000"&gt;...&lt;/font&gt;
&lt;font color="#ffffff"&gt;      &lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;
&lt;font color="#ffffff"&gt;      &lt;/font&gt;&lt;font color="#7f0055"&gt;&lt;b&gt;finally&lt;/b&gt;&lt;/font&gt;
&lt;font color="#ffffff"&gt;      &lt;/font&gt;&lt;font color="#000000"&gt;{&lt;/font&gt;
&lt;font color="#ffffff"&gt;         &lt;/font&gt;&lt;font color="#000000"&gt;theLock.unlock();&lt;/font&gt;
&lt;font color="#ffffff"&gt;      &lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;
&lt;font color="#ffffff"&gt;   &lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt;&lt;/pre&gt;
&lt;p&gt;
One thread is waiting for a condition with a timeout, while another will wake it up at some point. They are both working on the same lock, the lock is never modified, neither is it accessed by any other method. And clearly, the thread that holds the lock is the one that will unlock it.
&lt;p&gt;This code ran for million times already without any glitch. Until today. Can it be a JVM bug? (by the way, we run Java 6 build 16).&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/hnD_KPwSt-w" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/ethdsy/entry/reentrantlock_bug</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/wasp/entry/ibm_websphere_extreme_scale_6</guid>
    <title>IBM WebSphere eXtreme Scale 6</title>
    <dc:creator>Ricardo Sueiras</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/4_gwuL0FC-M/ibm_websphere_extreme_scale_6</link>
        <pubDate>Thu, 19 Nov 2009 06:51:06 -0500</pubDate>
    <category>WebSphere</category>
    <category>book</category>
    <category>extreme</category>
    <category>ibm</category>
    <category>review</category>
    <category>websphere</category>
            <description>&lt;p&gt;Those nice people at Packt (thanks Ryan) have sent me a copy of Anthony Chaves&amp;#8216; book called &lt;span class="caps"&gt;IBM &lt;/span&gt;WebSphere eXtreme Scale 6. I&amp;#8216;ll be reading this over the next couple of weeks and report back my thoughts.&lt;/p&gt;

	&lt;p&gt;There is a free chapter available on the publishers website &lt;a href="http://www.packtpub.com/ibm-websphere-extreme-scale-6?utm_source=jroller.com&amp;#38;utm_medium=bookrev&amp;#38;utm_content=blog&amp;#38;utm_campaign=mdb_001420" title=""&gt;here&lt;/a&gt;(and actually, looks like they got a WebSphere 7 book I might have to purchse&amp;#8230;.)&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/4_gwuL0FC-M" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/wasp/entry/ibm_websphere_extreme_scale_6</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/serkanguler/entry/selecting_web_technologies_from_devoxx09</guid>
    <title>Selecting Web Technologies from Devoxx09</title>
    <dc:creator>Serkan Guler</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/zcFfZE6G2xM/selecting_web_technologies_from_devoxx09</link>
        <pubDate>Thu, 19 Nov 2009 06:38:02 -0500</pubDate>
    <category>Technology</category>
    <category>development</category>
    <category>devoxx09</category>
    <category>web</category>
            <description>&lt;p&gt;&lt;a href="http://serkanguler.info/2009/11/19/selecting-web-technologies-from-devoxx09/"&gt;http://serkanguler.info/2009/11/19/selecting-web-technologies-from-devoxx09/&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/zcFfZE6G2xM" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/serkanguler/entry/selecting_web_technologies_from_devoxx09</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/scolebourne/entry/closures_in_jdk_7</guid>
    <title>Closures in JDK 7</title>
    <dc:creator>Stephen Colebourne</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/UPA6mx-8T7o/closures_in_jdk_7</link>
        <pubDate>Thu, 19 Nov 2009 02:53:16 -0500</pubDate>
    <category>Java</category>
    <category>bgga</category>
    <category>closures</category>
    <category>fcm</category>
    <category>jdk7</category>
            <description>&lt;p&gt;
So, on Wednesday, Mark Reinhold from Sun announced that it was time for closures in Java.
This came as a surprise to everyone, but what was announced?
&lt;/p&gt;


&lt;h4&gt;Closures in JDK 7&lt;/h4&gt;
&lt;p&gt;
Mark took the audience through the new features of JDK 7 in his presentation at
&lt;a href="http://devoxx.com"&gt;Devoxx&lt;/a&gt;.
As part of this he showed the &lt;a href="http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166ydocs/"&gt;Fork Join framework&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Part of this framework features a set of interfaces to support functional style predicates and transforms.
But, in order to implement this in Java required 80 interfaces, all generified, and that only
covered 4 of the primitive types! Basically, Mark, and others, had clearly come to the conclusion
that this code was important to Java, but that the implementation with single-method interfaces,
generics and inner classes was too horrible to stomach for the JDK.
&lt;/p&gt;
&lt;p&gt;
Thus, 'its time to add closures to Java'.
&lt;/p&gt;
&lt;p&gt;
Mark announced that Sun would investigate, and intended to commit, closures to OpenJDK for JDK 7.
While there will be no JSR yet, it isn't unreasonable to expect that there will be an open aspect to discussions.
&lt;/p&gt;
&lt;p&gt;
Mark noted that the work in the closures discussion, and particularly the detail in the BGGA proposal,
had allowed the options to be properly explored. He emphasised how this had resulted in the decision
to reject key aspects of BGGA.
&lt;/p&gt;
&lt;p&gt;
JDK 7 closures will not have control-invocation statements as a goal, nor will it have
non-local returns. He also indicated that access to non-final variables was unlikely.
Beyond this, there wasn't much detail on semantics, nor do I believe that there has been much
consideration of semantics yet.
&lt;/p&gt;
&lt;p&gt;
On syntax, Mark wrote up some strawman syntaxes. These follow the FCM syntax style:
&lt;/p&gt;
&lt;pre&gt;
  // function expressions
  #(int i, String s) {
    System.println.out(s);
    return i + s.length();
  }

  // function expressions
  #(int i, String s) (i + s.length())
  
  // function types
  #int(int, String)
&lt;/pre&gt;
&lt;p&gt;
Mark also argued that a form of extension methods would be added to allow closures to
be used with existing libraries like the collections API.
&lt;/p&gt;
&lt;p&gt;
Although I must emphasise that everything announced was a proposal and NOT based on any specific
proposal (BGGA, FCM or CICE). However, the syntax and semantics do follow the
&lt;a href="http://docs.google.com/Doc?id=ddhp95vd_0f7mcns"&gt;FCM&lt;/a&gt; proposal quite closely.
&lt;/p&gt;
&lt;p&gt;
In addition, Neal Gafter has produced an initial &lt;a href="http://www.javac.info/closures-v06a.html"&gt;formal writeup&lt;/a&gt; of what was announced
derived from BGGA.
Based on my initial reading, I believe that Neal's document represents a good place to start from.
&lt;b&gt;I also hereby propose that we refer to Neal's document as the CFJ proposal (Closures for Java), as BGGA rather implies control invocation.&lt;/b&gt;
&lt;/p&gt;
&lt;p&gt;
So, lets hope the process for closures provides for feedback, and we get the best closures
in the style most suitable for Java in JDK 7.
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/UPA6mx-8T7o" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/scolebourne/entry/closures_in_jdk_7</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/aalmiray/entry/grails_griffon_stats_trick</guid>
    <title>Grails/Griffon stats trick</title>
    <dc:creator>Andres Almiray</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/LaeayDHr5sQ/grails_griffon_stats_trick</link>
        <pubDate>Wed, 18 Nov 2009 18:17:22 -0500</pubDate>
    <category>Groovy</category>
    <category>grails</category>
    <category>griffon</category>
    <category>groovy</category>
            <description>&lt;a href="http://grails.org"&gt;Grails&lt;/a&gt; has had a &lt;tt&gt;stats&lt;/tt&gt; script for quite a while (thanks to awesome &lt;a href="http://blogs.bytecode.com.au/glen/"&gt;Glen Smith&lt;/a&gt;), it's job is to display how many lines of code you've written on your app. Not to be left behind, &lt;a href="http://griffon.codehaus.org"&gt;Griffon&lt;/a&gt; provides the same script. As useful as the script is there is a catch: you can't compute LOCs of additional artifacts that are not defined in the source paths found in the stats script.&lt;br/&gt;&lt;br/&gt;Well, you couldn't until recently. Starting with Grails 1.2M4 and Griffon 0.2 you'll be able to plug into the stats script and provide additional paths to be counted. Hows does this work you ask? let me introduce you to &lt;a href="http://grails.org/doc/latest/guide/4.%20The%20Command%20Line.html#4.3%20Hooking%20into%20Events"&gt;build events&lt;/a&gt;, as explained at the official Grails guide (Griffon events work exactly the same, cool huh?). The stats plugin will publish a &lt;tt&gt;&lt;b&gt;StatsStart&lt;/b&gt;&lt;/tt&gt; event, passing a list of maps as parameter. Each entry on that list defines a path to be searched, files found on that path will be counted if they match a certain criteria, mainly their filetype (actually a file suffix). To give you an example these are the default paths of the Grails stats script&lt;br/&gt;&lt;textarea name="srccode" class="groovy:nocontrols:nogutter" cols="80" rows="12"&gt;def pathToInfo = [
  [name: "Controllers",       path: "controllers",      filetype: [".groovy"]],
  [name: "Domain Classes",    path: "domain",           filetype: [".groovy"]],
  [name: "Jobs",              path: "job",              filetype: [".groovy"]],
  [name: "Services",          path: "services",         filetype: [".groovy"]],
  [name: "Tag Libraries",     path: "taglib",           filetype: [".groovy"]],
  [name: "Groovy Helpers",    path: "src.groovy",       filetype: [".groovy"]],
  [name: "Java Helpers",      path: "src.java",         filetype: [".java"]],
  [name: "Unit Tests",        path: "test.unit",        filetype: [".groovy"]],
  [name: "Integration Tests", path: "test.integration", filetype: [".groovy"]],
  [name: "Scripts",           path: "scripts",          filetype: [".groovy"]],
]&lt;/textarea&gt;You'll notice that filetype is a list (it used to be a single String). This is useful when joint-compilation is taken into account, a fact that the Griffon stats plugin relies on, as the path &lt;tt&gt;src/main&lt;/tt&gt; main contains both Groovy and Java sources&lt;br/&gt;&lt;textarea name="srccode" class="groovy:nocontrols:nogutter" cols="80" rows="10"&gt;def pathToInfo = [
  [name: "Models",              path: "models",           filetype: [".groovy"]],
  [name: "Views",               path: "views",            filetype: [".groovy"]],
  [name: "Controllers",         path: "controllers",      filetype: [".groovy"]],
  [name: "Lifecycle",           path: "lifecycle",        filetype: [".groovy"]],
  [name: "Groovy/Java Sources", path: "src.main",         filetype: [".groovy",".java"]],
  [name: "Unit Tests",          path: "test.unit",        filetype: [".groovy"]],
  [name: "Integration Tests",   path: "test.integration", filetype: [".groovy"]],
  [name: "Scripts",             path: "scripts",          filetype: [".groovy"]],
]&lt;/textarea&gt;Alright, so how do you plug into this feature? all you to do is add an event handler in scripts/_Events.groovy, like this one (used by Griffon's Scala plugin)&lt;br/&gt;&lt;textarea name="srccode" class="groovy:nocontrols:nogutter" cols="80" rows="8"&gt;eventStatsStart = { pathToInfo -&gt;
    if(!pathToInfo.find{ it.path == "src.commons"} ) {
        pathToInfo &lt;&lt; [name: "Common Sources", path: "src.commons", filetype: [".groovy",".java"]]
    }
    if(!pathToInfo.find{ it.path == "src.scala"} ) {
        pathToInfo &lt;&lt; [name: "Scala Sources", path: "src.scala", filetype: [".scala"]]
    }
}&lt;/textarea&gt;There is an additional feature, you may redefine how comments and empty lines are matched for a particular path. Provide a value for a &lt;tt&gt;locmatcher&lt;/tt&gt; property. This is how the Griffon Clojure plugin does it:&lt;br/&gt;&lt;textarea name="srccode" class="groovy:nocontrols:nogutter" cols="80" rows="17"&gt;eventStatsStart = { pathToInfo -&gt;
    if(!pathToInfo.find{ it.path == "src.commons"} ) {
        pathToInfo &lt;&lt; [name: "Common Sources", path: "src.commons", filetype: [".groovy",".java"]]
    }
    // TODO -- match multiline comments -&gt; (comment ...)
    if(!pathToInfo.find{ it.path == "src.clojure"} ) {
        def EMPTY = /^\s*$/
        pathToInfo &lt;&lt; [name: "Clojure Sources", path: "src.clojure", filetype: [".clj"], locmatcher: {file -&gt;
            def loc = 0
            file.eachLine { line -&gt;
                if(line ==~ EMPTY || line ==~ /^\s*\;.*/) return
                loc++
            }
            loc
        }]
    }
}&lt;/textarea&gt;Finally, the default LOC matcher should give better results when a multiline (/* */) comment is found on the source code.&lt;br/&gt;&lt;br/&gt;Keep on Groovying!&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/LaeayDHr5sQ" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/aalmiray/entry/grails_griffon_stats_trick</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/RickHigh/entry/ripped_out_aggdraw_went_back</guid>
    <title>Ripped out aggdraw... went back to plain PIL</title>
    <dc:creator>Rick Hightower</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/4DLfb1vndK4/ripped_out_aggdraw_went_back</link>
        <pubDate>Wed, 18 Nov 2009 16:01:29 -0500</pubDate>
    <category>technology</category>
            <description>&lt;span class="Apple-style-span" style="font-family: sans-serif; font-size: 13px; line-height: 19px; "&gt;&lt;p style="margin-top: 0.4em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; line-height: 1.5em; "&gt;Added the ability to add text annotations to the graphs... I had to rip out aggdraw as there was no decent documentation on how to load a font and no mailing list, and everything I tried failed. I went back to just using PIL. That was a real pisser.&lt;/p&gt;&lt;p style="margin-top: 0.4em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; line-height: 1.5em; "&gt;&lt;br /&gt;&lt;/p&gt;&lt;div dir="ltr" style="text-align: left; "&gt;&lt;pre class="source-python" style="padding-top: 1em; padding-right: 1em; padding-bottom: 1em; padding-left: 1em; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dashed; border-right-style: dashed; border-bottom-style: dashed; border-left-style: dashed; border-top-color: rgb(47, 111, 171); border-right-color: rgb(47, 111, 171); border-bottom-color: rgb(47, 111, 171); border-left-color: rgb(47, 111, 171); color: black; background-color: rgb(249, 249, 249); line-height: normal; overflow-x: auto; overflow-y: auto; "&gt;&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;class&lt;/span&gt; Canvas:
	&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;pass&lt;/span&gt;
&amp;nbsp;
&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;class&lt;/span&gt; ImageCanvas &lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;Canvas&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
	&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;
	Since the drawing logic will be the same for Pyjamas, PyGTK and images, I want
	to abstract the canvas.
	&amp;quot;&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;&amp;quot;&lt;/span&gt;
	&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;def&lt;/span&gt; &lt;span class="kw4" style="color: rgb(0, 0, 205); "&gt;__init__&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;, size, file_name=&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;image.png&amp;quot;&lt;/span&gt;, file_type=&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;PNG&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
		&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;import&lt;/span&gt; Image
		&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;import&lt;/span&gt; ImageDraw
		&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;import&lt;/span&gt; ImageFont
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;img&lt;/span&gt; = Image.&lt;span class="kw3" style="color: rgb(220, 20, 60); "&gt;new&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;RGB&amp;quot;&lt;/span&gt;, size, &lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;#FFFFFF&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt; 
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;canvas&lt;/span&gt; = ImageDraw.&lt;span class="me1" style="color: black; "&gt;Draw&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;img&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;width&lt;/span&gt; = size&lt;span class="br0" style="color: black; "&gt;[&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;]&lt;/span&gt;
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;height&lt;/span&gt; = size&lt;span class="br0" style="color: black; "&gt;[&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;1&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;]&lt;/span&gt;
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;file_name&lt;/span&gt; = file_name
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;file_type&lt;/span&gt; = file_type&lt;br /&gt;                #Nothing says I hate all that is good in the world by adding a absolute path... fix me
                &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;font&lt;/span&gt;=ImageFont.&lt;span class="me1" style="color: black; "&gt;truetype&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;/usr/share/fonts/truetype/freefont/FreeSerif.ttf&amp;quot;&lt;/span&gt;, &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;15&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
	&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;def&lt;/span&gt; draw_line&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;, x, y, x2, y2, color=&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;black&amp;quot;&lt;/span&gt;, width=&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;1&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;canvas&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;x, y, x2, y2&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;, fill=color, width=width&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
	&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;def&lt;/span&gt; draw_string&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;, x, y, text, color=&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;black&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;canvas&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;text&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;x,y&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;, text, font=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;font&lt;/span&gt;, fill=color&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
	&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;def&lt;/span&gt; render&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;img&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;save&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;file_name&lt;/span&gt;, &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;file_type&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;class&lt;/span&gt; SomeGraph:
	&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;The drawing logic for this graph is going to grow. 
	It would be good to encapsulate the drawing logic in one place&amp;quot;&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;&amp;quot;&lt;/span&gt;
	DURATION_SECONDS = &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;40&lt;/span&gt;
	LARGE_STEP_PER_SECOND = &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;5&lt;/span&gt;
	LARGE_TO_SMALL_FACTOR = &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;5&lt;/span&gt;
&amp;nbsp;
	&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;def&lt;/span&gt; &lt;span class="kw4" style="color: rgb(0, 0, 205); "&gt;__init__&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;, step_size=&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;3&lt;/span&gt;, y_offset=&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, x_offset=&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;step_size&lt;/span&gt; = step_size
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;large_step_size&lt;/span&gt; = &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;step_size&lt;/span&gt; &lt;span class="sy0" style="color: rgb(102, 204, 102); "&gt;*&lt;/span&gt; &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;LARGE_TO_SMALL_FACTOR&lt;/span&gt;
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;height&lt;/span&gt; = &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;large_step_size&lt;/span&gt; &lt;span class="sy0" style="color: rgb(102, 204, 102); "&gt;*&lt;/span&gt; &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;4&lt;/span&gt;
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;width&lt;/span&gt; = &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;LARGE_STEP_PER_SECOND&lt;/span&gt; &lt;span class="sy0" style="color: rgb(102, 204, 102); "&gt;*&lt;/span&gt; &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;DURATION_SECONDS&lt;/span&gt; &lt;span class="sy0" style="color: rgb(102, 204, 102); "&gt;*&lt;/span&gt; &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;large_step_size&lt;/span&gt;
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;y_offset&lt;/span&gt;=y_offset
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;x_offset&lt;/span&gt;=x_offset
&amp;nbsp;
	&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;def&lt;/span&gt; draw_grid_lines&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;, canvas&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
		&lt;span class="co1" style="color: rgb(128, 128, 128); font-style: italic; "&gt;#Draw vertical red lines (inner lines)&lt;/span&gt;
		&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;for&lt;/span&gt; x &lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;in&lt;/span&gt; &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;range&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;x_offset&lt;/span&gt;, &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;width&lt;/span&gt;+&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;x_offset&lt;/span&gt;, &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;step_size&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
			canvas.&lt;span class="me1" style="color: black; "&gt;draw_line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;x=x, x2=x, y=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;y_offset&lt;/span&gt;, y2=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;height&lt;/span&gt;+&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;y_offset&lt;/span&gt;, color=&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;red&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
		&lt;span class="co1" style="color: rgb(128, 128, 128); font-style: italic; "&gt;#Draw vertical black lines (outer grid)&lt;/span&gt;
		&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;for&lt;/span&gt; x &lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;in&lt;/span&gt; &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;range&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;x_offset&lt;/span&gt;, &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;width&lt;/span&gt;+&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;x_offset&lt;/span&gt;, &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;large_step_size&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;: 
			canvas.&lt;span class="me1" style="color: black; "&gt;draw_line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;x=x, x2=x, y=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;y_offset&lt;/span&gt;, y2=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;height&lt;/span&gt;+&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;y_offset&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
		canvas.&lt;span class="me1" style="color: black; "&gt;draw_line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;x=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;width&lt;/span&gt;+&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;x_offset&lt;/span&gt;, x2=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;width&lt;/span&gt; + &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;x_offset&lt;/span&gt;, 
                                 y=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;y_offset&lt;/span&gt;, y2=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;height&lt;/span&gt;+&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;y_offset&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
		&lt;span class="co1" style="color: rgb(128, 128, 128); font-style: italic; "&gt;#Draw horizontal lines&lt;/span&gt;
		&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;for&lt;/span&gt; y &lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;in&lt;/span&gt; &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;range&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;y_offset&lt;/span&gt;, &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;height&lt;/span&gt; + &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;y_offset&lt;/span&gt;, &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;step_size&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
				canvas.&lt;span class="me1" style="color: black; "&gt;draw_line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;y=y, y2=y, x=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;x_offset&lt;/span&gt;, x2=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;width&lt;/span&gt; + &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;x_offset&lt;/span&gt;, color=&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;red&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
				flag=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;False&lt;/span&gt;
		&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;for&lt;/span&gt; y &lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;in&lt;/span&gt; &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;range&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;y_offset&lt;/span&gt;, &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;height&lt;/span&gt;  + &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;y_offset&lt;/span&gt;, &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;large_step_size&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;: 
			canvas.&lt;span class="me1" style="color: black; "&gt;draw_line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;y=y, y2=y, x=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;x_offset&lt;/span&gt;, x2=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;width&lt;/span&gt;  + &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;x_offset&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
		canvas.&lt;span class="me1" style="color: black; "&gt;draw_line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;y=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;height&lt;/span&gt;+&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;y_offset&lt;/span&gt;, y2=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;height&lt;/span&gt;+&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;y_offset&lt;/span&gt;, 
				 x=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;x_offset&lt;/span&gt;, x2=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;width&lt;/span&gt;  + &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;x_offset&lt;/span&gt;, width=&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;2&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
&amp;nbsp;
&amp;nbsp;
&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;def&lt;/span&gt; draw_graph&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;step_size=&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;3&lt;/span&gt;, file_name=&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;foo.png&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
	SIDE_GUTTER = &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;50&lt;/span&gt;
	TOP_GUTTER = &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;25&lt;/span&gt;
	graph = SomeGraph&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;step_size=step_size, x_offset=SIDE_GUTTER, y_offset=TOP_GUTTER&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
	canvas = ImageCanvas&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;graph.&lt;span class="me1" style="color: black; "&gt;width&lt;/span&gt;+SIDE_GUTTER,graph.&lt;span class="me1" style="color: black; "&gt;height&lt;/span&gt;+TOP_GUTTER&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;, file_name=file_name&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
	graph.&lt;span class="me1" style="color: black; "&gt;draw_grid_lines&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;canvas&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
	canvas.&lt;span class="me1" style="color: black; "&gt;draw_string&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;50&lt;/span&gt;, &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, &lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;Avg 50,      CVP 20,                 ASDF, alskjdflaksjdflkajsdflkjasdflkjasdfljkasdlkjf&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
	canvas.&lt;span class="me1" style="color: black; "&gt;draw_string&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;5&lt;/span&gt;, &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;5&lt;/span&gt;, &lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;Blah&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
	canvas.&lt;span class="me1" style="color: black; "&gt;draw_string&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;5&lt;/span&gt;, &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;20&lt;/span&gt;, &lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;Rick&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
	canvas.&lt;span class="me1" style="color: black; "&gt;draw_string&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;5&lt;/span&gt;, &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;35&lt;/span&gt;, &lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;Was&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
	canvas.&lt;span class="me1" style="color: black; "&gt;draw_string&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;5&lt;/span&gt;, &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;50&lt;/span&gt;, &lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;Here&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
	canvas.&lt;span class="me1" style="color: black; "&gt;render&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
draw_graph&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
draw_graph&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;6&lt;/span&gt;,&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;zoom.png&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/span&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/4DLfb1vndK4" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/RickHigh/entry/ripped_out_aggdraw_went_back</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/robwilliams/entry/california_bans_energy_hogging_tvs</guid>
    <title>California Bans Energy Hogging TVs</title>
    <dc:creator>Rob Williams</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/jGMqHh52Kz0/california_bans_energy_hogging_tvs</link>
        <pubDate>Wed, 18 Nov 2009 15:49:29 -0500</pubDate>
    <category>Technology</category>
            <description>&lt;p&gt;So rare that the california state government does something good! This is a total no brainer. Another exercise in how one person saying &amp;#8216;my plasma doesn&amp;#8216;t make much difference&amp;#8216; turns into a catastrophe. Enough savings to power almost a million homes. Insane..&lt;/p&gt;

	&lt;p&gt;People who argue against this kind of stuff are complete whackjobs. Usually, it just boils down to &amp;#8216;how dare the nanny state tell ME what to do!!&amp;#8216; The answer is simple: we all have to pay for the new power plants to run said stupid plasma because the &lt;span class="caps"&gt;LCD&lt;/span&gt; just wasn&amp;#8216;t good enough.&lt;/p&gt;

	&lt;p&gt;Personally, I favor systems where we actually assess real costs and then we just tax things appropriately. Have to have that huge TV? No problem, you just pay more tax on it.&lt;/p&gt;

	&lt;p&gt;Read about it &lt;a href="http://online.wsj.com/article/BT-CO-20091118-711554.html" title=""&gt;here&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/jGMqHh52Kz0" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/robwilliams/entry/california_bans_energy_hogging_tvs</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/RickHigh/entry/abstracting_the_canvas_from_the</guid>
    <title>Abstracting the canvas from the drawing logic (continuation of last blog)</title>
    <dc:creator>Rick Hightower</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/KpFRcOlvDwY/abstracting_the_canvas_from_the</link>
        <pubDate>Wed, 18 Nov 2009 13:10:16 -0500</pubDate>
    <category>technology</category>
            <description>&lt;span class="Apple-style-span" style="font-family: sans-serif; font-size: 18px; line-height: 27px; "&gt;&lt;p style="margin-top: 0.4em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; line-height: 1.5em; "&gt;Since the drawing logic will be the same for Pyjamas, PyGTK, PDF's and images, I want to abstract the canvas from the graph drawing logic so we can reuse it. Also just a good SOC (separation of concern).&lt;/p&gt;&lt;p style="margin-top: 0.4em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; line-height: 1.5em; "&gt;&lt;br /&gt;&lt;/p&gt;&lt;div dir="ltr" style="text-align: left; "&gt;&lt;pre class="source-python" style="padding-top: 1em; padding-right: 1em; padding-bottom: 1em; padding-left: 1em; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dashed; border-right-style: dashed; border-bottom-style: dashed; border-left-style: dashed; border-top-color: rgb(47, 111, 171); border-right-color: rgb(47, 111, 171); border-bottom-color: rgb(47, 111, 171); border-left-color: rgb(47, 111, 171); color: black; background-color: rgb(249, 249, 249); line-height: normal; overflow-x: auto; overflow-y: auto; "&gt;&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;class&lt;/span&gt; Canvas:
	&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;pass&lt;/span&gt;
&amp;nbsp;
&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;class&lt;/span&gt; ImageCanvas &lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;Canvas&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
	&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;
	Since the drawing logic will be the same for Pyjamas, PyGTK and images, I want
	to abstract the canvas.
	&amp;quot;&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;&amp;quot;&lt;/span&gt;
	&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;def&lt;/span&gt; &lt;span class="kw4" style="color: rgb(0, 0, 205); "&gt;__init__&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;, size, file_name=&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;image.png&amp;quot;&lt;/span&gt;, file_type=&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;PNG&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
		&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;import&lt;/span&gt; Image
		&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;import&lt;/span&gt; aggdraw as draw
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;img&lt;/span&gt; = Image.&lt;span class="kw3" style="color: rgb(220, 20, 60); "&gt;new&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;RGB&amp;quot;&lt;/span&gt;, size, &lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;#FFFFFF&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt; 
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;canvas&lt;/span&gt; = draw.&lt;span class="me1" style="color: black; "&gt;Draw&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;img&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;pens&lt;/span&gt; = &lt;span class="br0" style="color: black; "&gt;{&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;red&amp;quot;&lt;/span&gt;:draw.&lt;span class="me1" style="color: black; "&gt;Pen&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;red&amp;quot;&lt;/span&gt;, &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0.25&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;, &lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;black&amp;quot;&lt;/span&gt;:draw.&lt;span class="me1" style="color: black; "&gt;Pen&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;black&amp;quot;&lt;/span&gt;, &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0.25&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt; &lt;span class="br0" style="color: black; "&gt;}&lt;/span&gt;
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;width&lt;/span&gt; = size&lt;span class="br0" style="color: black; "&gt;[&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;]&lt;/span&gt;
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;height&lt;/span&gt; = size&lt;span class="br0" style="color: black; "&gt;[&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;1&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;]&lt;/span&gt;
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;file_name&lt;/span&gt; = file_name
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;file_type&lt;/span&gt; = file_type
&amp;nbsp;
	&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;def&lt;/span&gt; draw_line&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;, x, y, x2, y2, color=&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;black&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
		pen = &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;pens&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;[&lt;/span&gt;color&lt;span class="br0" style="color: black; "&gt;]&lt;/span&gt;
		&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;if&lt;/span&gt; pen == &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;None&lt;/span&gt;: 
			&lt;span class="co1" style="color: rgb(128, 128, 128); font-style: italic; "&gt;#Todo add logging to this class&lt;/span&gt;
			pen = &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;pens&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;[&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;black&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;]&lt;/span&gt;
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;canvas&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;x, y, x2, y2&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;, pen&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
	&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;def&lt;/span&gt; render&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;canvas&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;flush&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;save&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;file_name&lt;/span&gt;, &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;file_type&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
&amp;nbsp;
&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;def&lt;/span&gt; drawGraph&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;step_size=&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;3&lt;/span&gt;, file_name=&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;foo.png&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
	STEP_SIZE = step_size
	DURATION_SECONDS = &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;40&lt;/span&gt;
	LARGE_STEP_SIZE = STEP_SIZE &lt;span class="sy0" style="color: rgb(102, 204, 102); "&gt;*&lt;/span&gt; &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;5&lt;/span&gt;
	HEIGHT = STEP_SIZE &lt;span class="sy0" style="color: rgb(102, 204, 102); "&gt;*&lt;/span&gt; &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;5&lt;/span&gt; &lt;span class="sy0" style="color: rgb(102, 204, 102); "&gt;*&lt;/span&gt; &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;4&lt;/span&gt;
	LS_PER_SECOND = &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;5&lt;/span&gt; 
	WIDTH = LS_PER_SECOND &lt;span class="sy0" style="color: rgb(102, 204, 102); "&gt;*&lt;/span&gt; DURATION_SECONDS &lt;span class="sy0" style="color: rgb(102, 204, 102); "&gt;*&lt;/span&gt; LARGE_STEP_SIZE
	canvas = ImageCanvas&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;WIDTH, HEIGHT&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;, file_name=file_name&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
	&lt;span class="co1" style="color: rgb(128, 128, 128); font-style: italic; "&gt;#Draw vertical red lines (inner lines)&lt;/span&gt;
	&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;for&lt;/span&gt; x &lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;in&lt;/span&gt; &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;range&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, WIDTH, STEP_SIZE&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;: canvas.&lt;span class="me1" style="color: black; "&gt;draw_line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;x=x, x2=x, y=&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, y2=HEIGHT, color=&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;red&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
	&lt;span class="co1" style="color: rgb(128, 128, 128); font-style: italic; "&gt;#Draw vertical black lines (outer grid)&lt;/span&gt;
	&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;for&lt;/span&gt; x &lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;in&lt;/span&gt; &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;range&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, WIDTH, LARGE_STEP_SIZE&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;: canvas.&lt;span class="me1" style="color: black; "&gt;draw_line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;x=x, x2=x, y=&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, y2=HEIGHT&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
	&lt;span class="co1" style="color: rgb(128, 128, 128); font-style: italic; "&gt;#Draw horizontal lines&lt;/span&gt;
	&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;for&lt;/span&gt; y &lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;in&lt;/span&gt; &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;range&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, HEIGHT, STEP_SIZE&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;: canvas.&lt;span class="me1" style="color: black; "&gt;draw_line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;y=y, y2=y, x=&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, x2=WIDTH, color=&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;red&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
	&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;for&lt;/span&gt; y &lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;in&lt;/span&gt; &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;range&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, HEIGHT, LARGE_STEP_SIZE&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;: canvas.&lt;span class="me1" style="color: black; "&gt;draw_line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;y=y, y2=y, x=&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, x2=WIDTH&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
	canvas.&lt;span class="me1" style="color: black; "&gt;draw_line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;y=HEIGHT, y2=HEIGHT, x=&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, x2=WIDTH, &lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
	canvas.&lt;span class="me1" style="color: black; "&gt;render&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
&amp;nbsp;
drawGraph&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&lt;span class="co1" style="color: rgb(128, 128, 128); font-style: italic; "&gt;#drawGraph(6,&amp;quot;zoom.png&amp;quot;)&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p style="margin-top: 0.4em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; line-height: 1.5em; "&gt;Ok this is the last part I can share... I am going to get to specific to the domain in the next steps... cloaking device on...&lt;/p&gt;&lt;p style="margin-top: 0.4em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; line-height: 1.5em; "&gt;The drawing logic for the graph is going to grow. It would be good to encapsulate the drawing logic in one place. I separated the drawing logic into a class that uses the canvas.&lt;/p&gt;&lt;p style="margin-top: 0.4em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; line-height: 1.5em; "&gt;&lt;br /&gt;&lt;/p&gt;&lt;div dir="ltr" style="text-align: left; "&gt;&lt;pre class="source-python" style="padding-top: 1em; padding-right: 1em; padding-bottom: 1em; padding-left: 1em; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dashed; border-right-style: dashed; border-bottom-style: dashed; border-left-style: dashed; border-top-color: rgb(47, 111, 171); border-right-color: rgb(47, 111, 171); border-bottom-color: rgb(47, 111, 171); border-left-color: rgb(47, 111, 171); color: black; background-color: rgb(249, 249, 249); line-height: normal; overflow-x: auto; overflow-y: auto; "&gt;&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;class&lt;/span&gt; Canvas:
	&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;pass&lt;/span&gt;
&amp;nbsp;
&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;class&lt;/span&gt; ImageCanvas &lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;Canvas&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
	&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;
	Since the drawing logic will be the same for Pyjamas, PyGTK and images, I want
	to abstract the canvas.
	&amp;quot;&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;&amp;quot;&lt;/span&gt;
	&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;def&lt;/span&gt; &lt;span class="kw4" style="color: rgb(0, 0, 205); "&gt;__init__&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;, size, file_name=&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;image.png&amp;quot;&lt;/span&gt;, file_type=&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;PNG&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
		&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;import&lt;/span&gt; Image
		&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;import&lt;/span&gt; aggdraw as draw
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;img&lt;/span&gt; = Image.&lt;span class="kw3" style="color: rgb(220, 20, 60); "&gt;new&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;RGB&amp;quot;&lt;/span&gt;, size, &lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;#FFFFFF&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt; 
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;canvas&lt;/span&gt; = draw.&lt;span class="me1" style="color: black; "&gt;Draw&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;img&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;pens&lt;/span&gt; = &lt;span class="br0" style="color: black; "&gt;{&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;red&amp;quot;&lt;/span&gt;:draw.&lt;span class="me1" style="color: black; "&gt;Pen&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;red&amp;quot;&lt;/span&gt;, &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0.25&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;, &lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;black&amp;quot;&lt;/span&gt;:draw.&lt;span class="me1" style="color: black; "&gt;Pen&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;black&amp;quot;&lt;/span&gt;, &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0.25&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt; &lt;span class="br0" style="color: black; "&gt;}&lt;/span&gt;
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;width&lt;/span&gt; = size&lt;span class="br0" style="color: black; "&gt;[&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;]&lt;/span&gt;
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;height&lt;/span&gt; = size&lt;span class="br0" style="color: black; "&gt;[&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;1&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;]&lt;/span&gt;
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;file_name&lt;/span&gt; = file_name
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;file_type&lt;/span&gt; = file_type
&amp;nbsp;
	&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;def&lt;/span&gt; draw_line&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;, x, y, x2, y2, color=&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;black&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
		pen = &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;pens&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;[&lt;/span&gt;color&lt;span class="br0" style="color: black; "&gt;]&lt;/span&gt;
		&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;if&lt;/span&gt; pen == &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;None&lt;/span&gt;: 
			&lt;span class="co1" style="color: rgb(128, 128, 128); font-style: italic; "&gt;#Todo add logging to this class&lt;/span&gt;
			pen = &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;pens&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;[&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;black&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;]&lt;/span&gt;
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;canvas&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;x, y, x2, y2&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;, pen&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
	&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;def&lt;/span&gt; render&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;canvas&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;flush&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;save&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;file_name&lt;/span&gt;, &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;file_type&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;class&lt;/span&gt; EcgGraph:
	&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;The drawing logic for this graph is going to grow. 
	It would be good to encapsulate the drawing logic in one place&amp;quot;&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;&amp;quot;&lt;/span&gt;
	DURATION_SECONDS = &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;40&lt;/span&gt;
	LARGE_STEP_PER_SECOND = &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;5&lt;/span&gt;
	LARGE_TO_SMALL_FACTOR = &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;5&lt;/span&gt;
&amp;nbsp;
	&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;def&lt;/span&gt; &lt;span class="kw4" style="color: rgb(0, 0, 205); "&gt;__init__&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;, step_size=&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;3&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;step_size&lt;/span&gt; = step_size
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;large_step_size&lt;/span&gt; = &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;step_size&lt;/span&gt; &lt;span class="sy0" style="color: rgb(102, 204, 102); "&gt;*&lt;/span&gt; &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;LARGE_TO_SMALL_FACTOR&lt;/span&gt;
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;height&lt;/span&gt; = &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;large_step_size&lt;/span&gt; &lt;span class="sy0" style="color: rgb(102, 204, 102); "&gt;*&lt;/span&gt; &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;4&lt;/span&gt;
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;width&lt;/span&gt; = &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;LARGE_STEP_PER_SECOND&lt;/span&gt; &lt;span class="sy0" style="color: rgb(102, 204, 102); "&gt;*&lt;/span&gt; &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;DURATION_SECONDS&lt;/span&gt; &lt;span class="sy0" style="color: rgb(102, 204, 102); "&gt;*&lt;/span&gt; &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;large_step_size&lt;/span&gt;
&amp;nbsp;
	&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;def&lt;/span&gt; draw_grid_lines&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;, canvas&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
		&lt;span class="co1" style="color: rgb(128, 128, 128); font-style: italic; "&gt;#Draw vertical red lines (inner lines)&lt;/span&gt;
		&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;for&lt;/span&gt; x &lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;in&lt;/span&gt; &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;range&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;width&lt;/span&gt;, &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;step_size&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
			canvas.&lt;span class="me1" style="color: black; "&gt;draw_line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;x=x, x2=x, y=&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, y2=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;height&lt;/span&gt;, color=&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;red&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
		&lt;span class="co1" style="color: rgb(128, 128, 128); font-style: italic; "&gt;#Draw vertical black lines (outer grid)&lt;/span&gt;
		&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;for&lt;/span&gt; x &lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;in&lt;/span&gt; &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;range&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;width&lt;/span&gt;, &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;large_step_size&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;: 
			canvas.&lt;span class="me1" style="color: black; "&gt;draw_line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;x=x, x2=x, y=&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, y2=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;height&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
		&lt;span class="co1" style="color: rgb(128, 128, 128); font-style: italic; "&gt;#Draw horizontal lines&lt;/span&gt;
		&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;for&lt;/span&gt; y &lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;in&lt;/span&gt; &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;range&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;height&lt;/span&gt;, &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;step_size&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;: 
			canvas.&lt;span class="me1" style="color: black; "&gt;draw_line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;y=y, y2=y, x=&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, x2=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;width&lt;/span&gt;, color=&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;red&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
		&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;for&lt;/span&gt; y &lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;in&lt;/span&gt; &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;range&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;height&lt;/span&gt;, &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;large_step_size&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;: 
			canvas.&lt;span class="me1" style="color: black; "&gt;draw_line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;y=y, y2=y, x=&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, x2=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;width&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
		canvas.&lt;span class="me1" style="color: black; "&gt;draw_line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;y=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;height&lt;/span&gt;, y2=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;height&lt;/span&gt;, x=&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, x2=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;width&lt;/span&gt;, &lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
&amp;nbsp;
&amp;nbsp;
&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;def&lt;/span&gt; draw_graph&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;step_size=&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;3&lt;/span&gt;, file_name=&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;foo.png&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
	graph = EcgGraph&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;step_size=step_size&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
	canvas = ImageCanvas&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;graph.&lt;span class="me1" style="color: black; "&gt;width&lt;/span&gt;, graph.&lt;span class="me1" style="color: black; "&gt;height&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;, file_name=file_name&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
	graph.&lt;span class="me1" style="color: black; "&gt;draw_grid_lines&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;canvas&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
	canvas.&lt;span class="me1" style="color: black; "&gt;render&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
&amp;nbsp;
draw_graph&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&amp;nbsp;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;font class="Apple-style-span" face="monospace"&gt;&lt;span class="Apple-style-span" style="line-height: normal; white-space: pre; "&gt;&lt;span class="Apple-style-span" style="font-family: sans-serif; white-space: normal; line-height: 27px; "&gt;&lt;p style="margin-top: 0.4em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; line-height: 1.5em; "&gt;The drawing logic for the graph is going to grow. It would be good to encapsulate the drawing logic in one place. I separated the drawing logic into a class that uses the canvas.&lt;/p&gt;&lt;p style="margin-top: 0.4em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; line-height: 1.5em; "&gt;&lt;br /&gt;&lt;/p&gt;&lt;div dir="ltr" style="text-align: left; "&gt;&lt;pre class="source-python" style="padding-top: 1em; padding-right: 1em; padding-bottom: 1em; padding-left: 1em; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dashed; border-right-style: dashed; border-bottom-style: dashed; border-left-style: dashed; border-top-color: rgb(47, 111, 171); border-right-color: rgb(47, 111, 171); border-bottom-color: rgb(47, 111, 171); border-left-color: rgb(47, 111, 171); color: black; background-color: rgb(249, 249, 249); line-height: normal; overflow-x: auto; overflow-y: auto; "&gt;&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;class&lt;/span&gt; Canvas:
	&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;pass&lt;/span&gt;
&amp;nbsp;
&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;class&lt;/span&gt; ImageCanvas &lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;Canvas&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
	&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;
	Since the drawing logic will be the same for Pyjamas, PyGTK and images, I want
	to abstract the canvas.
	&amp;quot;&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;&amp;quot;&lt;/span&gt;
	&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;def&lt;/span&gt; &lt;span class="kw4" style="color: rgb(0, 0, 205); "&gt;__init__&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;, size, file_name=&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;image.png&amp;quot;&lt;/span&gt;, file_type=&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;PNG&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
		&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;import&lt;/span&gt; Image
		&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;import&lt;/span&gt; aggdraw as draw
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;img&lt;/span&gt; = Image.&lt;span class="kw3" style="color: rgb(220, 20, 60); "&gt;new&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;RGB&amp;quot;&lt;/span&gt;, size, &lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;#FFFFFF&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt; 
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;canvas&lt;/span&gt; = draw.&lt;span class="me1" style="color: black; "&gt;Draw&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;img&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;pens&lt;/span&gt; = &lt;span class="br0" style="color: black; "&gt;{&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;red&amp;quot;&lt;/span&gt;:draw.&lt;span class="me1" style="color: black; "&gt;Pen&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;red&amp;quot;&lt;/span&gt;, &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0.25&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;, &lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;black&amp;quot;&lt;/span&gt;:draw.&lt;span class="me1" style="color: black; "&gt;Pen&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;black&amp;quot;&lt;/span&gt;, &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0.25&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt; &lt;span class="br0" style="color: black; "&gt;}&lt;/span&gt;
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;width&lt;/span&gt; = size&lt;span class="br0" style="color: black; "&gt;[&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;]&lt;/span&gt;
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;height&lt;/span&gt; = size&lt;span class="br0" style="color: black; "&gt;[&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;1&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;]&lt;/span&gt;
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;file_name&lt;/span&gt; = file_name
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;file_type&lt;/span&gt; = file_type
&amp;nbsp;
	&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;def&lt;/span&gt; draw_line&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;, x, y, x2, y2, color=&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;black&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
		pen = &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;pens&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;[&lt;/span&gt;color&lt;span class="br0" style="color: black; "&gt;]&lt;/span&gt;
		&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;if&lt;/span&gt; pen == &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;None&lt;/span&gt;: 
			&lt;span class="co1" style="color: rgb(128, 128, 128); font-style: italic; "&gt;#Todo add logging to this class&lt;/span&gt;
			pen = &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;pens&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;[&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;black&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;]&lt;/span&gt;
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;canvas&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;x, y, x2, y2&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;, pen&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
	&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;def&lt;/span&gt; render&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;canvas&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;flush&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;save&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;file_name&lt;/span&gt;, &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;file_type&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;class&lt;/span&gt; SomeGraph:
	&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;The drawing logic for this graph is going to grow. 
	It would be good to encapsulate the drawing logic in one place&amp;quot;&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;&amp;quot;&lt;/span&gt;
	DURATION_SECONDS = &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;40&lt;/span&gt;
	LARGE_STEP_PER_SECOND = &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;5&lt;/span&gt;
	LARGE_TO_SMALL_FACTOR = &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;5&lt;/span&gt;
&amp;nbsp;
	&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;def&lt;/span&gt; &lt;span class="kw4" style="color: rgb(0, 0, 205); "&gt;__init__&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;, step_size=&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;3&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;step_size&lt;/span&gt; = step_size
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;large_step_size&lt;/span&gt; = &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;step_size&lt;/span&gt; &lt;span class="sy0" style="color: rgb(102, 204, 102); "&gt;*&lt;/span&gt; &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;LARGE_TO_SMALL_FACTOR&lt;/span&gt;
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;height&lt;/span&gt; = &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;large_step_size&lt;/span&gt; &lt;span class="sy0" style="color: rgb(102, 204, 102); "&gt;*&lt;/span&gt; &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;4&lt;/span&gt;
		&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;width&lt;/span&gt; = &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;LARGE_STEP_PER_SECOND&lt;/span&gt; &lt;span class="sy0" style="color: rgb(102, 204, 102); "&gt;*&lt;/span&gt; &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;DURATION_SECONDS&lt;/span&gt; &lt;span class="sy0" style="color: rgb(102, 204, 102); "&gt;*&lt;/span&gt; &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;large_step_size&lt;/span&gt;
&amp;nbsp;
	&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;def&lt;/span&gt; draw_grid_lines&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;, canvas&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
		&lt;span class="co1" style="color: rgb(128, 128, 128); font-style: italic; "&gt;#Draw vertical red lines (inner lines)&lt;/span&gt;
		&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;for&lt;/span&gt; x &lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;in&lt;/span&gt; &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;range&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;width&lt;/span&gt;, &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;step_size&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
			canvas.&lt;span class="me1" style="color: black; "&gt;draw_line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;x=x, x2=x, y=&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, y2=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;height&lt;/span&gt;, color=&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;red&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
		&lt;span class="co1" style="color: rgb(128, 128, 128); font-style: italic; "&gt;#Draw vertical black lines (outer grid)&lt;/span&gt;
		&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;for&lt;/span&gt; x &lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;in&lt;/span&gt; &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;range&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;width&lt;/span&gt;, &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;large_step_size&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;: 
			canvas.&lt;span class="me1" style="color: black; "&gt;draw_line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;x=x, x2=x, y=&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, y2=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;height&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
		&lt;span class="co1" style="color: rgb(128, 128, 128); font-style: italic; "&gt;#Draw horizontal lines&lt;/span&gt;
		&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;for&lt;/span&gt; y &lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;in&lt;/span&gt; &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;range&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;height&lt;/span&gt;, &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;step_size&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;: 
			canvas.&lt;span class="me1" style="color: black; "&gt;draw_line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;y=y, y2=y, x=&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, x2=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;width&lt;/span&gt;, color=&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;red&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
		&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;for&lt;/span&gt; y &lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;in&lt;/span&gt; &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;range&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;height&lt;/span&gt;, &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;large_step_size&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;: 
			canvas.&lt;span class="me1" style="color: black; "&gt;draw_line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;y=y, y2=y, x=&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, x2=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;width&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
		canvas.&lt;span class="me1" style="color: black; "&gt;draw_line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;y=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;height&lt;/span&gt;, y2=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;height&lt;/span&gt;, x=&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, x2=&lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;self&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;width&lt;/span&gt;, &lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
&amp;nbsp;
&amp;nbsp;
&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;def&lt;/span&gt; draw_graph&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;step_size=&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;3&lt;/span&gt;, file_name=&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;foo.png&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
	graph = SomeGraph&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;step_size=step_size&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
	canvas = ImageCanvas&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;graph.&lt;span class="me1" style="color: black; "&gt;width&lt;/span&gt;, graph.&lt;span class="me1" style="color: black; "&gt;height&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;, file_name=file_name&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
	graph.&lt;span class="me1" style="color: black; "&gt;draw_grid_lines&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;canvas&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
	canvas.&lt;span class="me1" style="color: black; "&gt;render&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
&amp;nbsp;
draw_graph&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
draw_graph&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;6&lt;/span&gt;,&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;zoom.png&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;/span&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/KpFRcOlvDwY" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/RickHigh/entry/abstracting_the_canvas_from_the</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/prpatel/entry/grails_was_so_electric_it</guid>
    <title>Grails was so electric, it brought down the power grid</title>
    <dc:creator>Pratik Patel</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/x3Hha88AyBA/grails_was_so_electric_it</link>
        <pubDate>Wed, 18 Nov 2009 12:50:08 -0500</pubDate>
    <category>Java</category>
    <category>ajug</category>
    <category>grails</category>
    <category>groovy</category>
            <description>&lt;p&gt;
Last nite's AJUG started off great. Burr, our venerable AJUG leader, started with a discussion on what stuff people wanted to see covered in AJUG in 2010. Next on deck was my Grails presentation. I purposely had the first half of it at a basic level, for the Grails newb's in the crowd. Based on the feedback and attention level, I was rockin' and rollin' - people were asking questions, nodding heads during the basic Grails create-a-project-create-a-domain-gen-a-controller-and-views-demo. Demo'd the RichUI plugin and also some of the features of STS and the Eclipse-Grails plugin. Was on the home stretch, 30 mins left, and was about to demo G-Func and some other cool plugins and start to dive real deep into Grails goodness, when POOF. Lights went on and off. &lt;/p&gt;&lt;p&gt;No problem, gave the projector a couple of mins to restart and starting yapping again. Then POOF, power flickered on-and-off. The torrential rain that had been hammering Atlanta had subsided a week earlier, so we were all wondering what was going on. I figured that the Amway rally that was going on next door was sucking all our electricity. So again I wait for the projector to restart, and again, BANG, power is gone. And it doesn't come back on this time. Burr runs to the hotel manager, comes back and says the power was out on the whole city block.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Funny thing is that people were so engaged in the Grails world by this time that I continued to answer questions for the next 15 mins in the near total dark - a surreal experience. Room full of 80+ people, only light is my laptop's screen. Finally, people sensed that the power wasn't coming back so the meeting came to an unceremonious end. I threw out the t-shirts I had &amp;quot;acquired&amp;quot; from SpringOne. We didn't have time (or lighting) to raffle off the Grails books that Keegan Kettering, our local SpringSource sales guy, had sent for the meeting. We'll do that at the beginning of next month's meeting. I'm hoping I get to finish off the last 20 or so mins of my Grails presentation also.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/x3Hha88AyBA" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/prpatel/entry/grails_was_so_electric_it</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/brodkin/entry/our_devoxx_2009_talk_on</guid>
    <title>Our Devoxx 2009 Talk on Google Appengine Was a Blast</title>
    <dc:creator>Sam Brodkin</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/-czXJ0FF0o4/our_devoxx_2009_talk_on</link>
        <pubDate>Wed, 18 Nov 2009 12:08:07 -0500</pubDate>
    <category>Java</category>
    <category>appengine</category>
    <category>devoxx</category>
    <category>gae</category>
            <description>&lt;p&gt;&lt;p&gt;&lt;br /&gt;
Scott and I did a &lt;a href="http://www.devoxx.com/display/DV09/Google+App+Engine+for+Java+-+a+real+live+voyage+to+The+Cloud"&gt;talk on Google App Engine for Java&lt;/a&gt; at Devoxx 2009.&amp;nbsp; For the results of our experiment, &lt;b&gt;check out our &lt;a href="http://sites.google.com/site/devoxx2009appenginetalk/"&gt;SwagSwap results and analysis site&lt;/a&gt;.&lt;/b&gt;&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;We talked about Appengine Gotchas when developing a non-trivial app.&amp;nbsp; We gave Spring 3 MVC, JSF 2.0, and GWT a spin.&amp;nbsp; The climax was undoubtedly when we gave away big beers to the attendees that used our &lt;a href="http://swagswap.org"&gt;SwagSwap app&lt;/a&gt; the most.&amp;nbsp; &lt;/p&gt;&lt;p&gt;Check out &lt;a href="http://sites.google.com/site/devoxx2009appenginetalk/"&gt;what people are saying&lt;/a&gt;.&amp;nbsp; Also look &lt;a href="http://lh3.ggpht.com/_uSgPEW_1gEA/SwQk8sHAh4I/AAAAAAAAEjg/XV98jemOEc8/s512/all-that-swag.jpg"&gt;how much swag&lt;/a&gt; I got out of the deal!&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;img vspace="0" hspace="0" border="0" align="baseline" src="http://lh3.ggpht.com/_ZrYb6GjXXeM/SwLVKykVrUI/AAAAAAAAJKk/PvAFrhOUV6o/s720/DSC_4739.jpg" /&gt; &lt;br /&gt;
&lt;/p&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/-czXJ0FF0o4" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/brodkin/entry/our_devoxx_2009_talk_on</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/robwilliams/entry/tuneup_what_is_so_hard</guid>
    <title>TuneUp: What is So Hard About Cleaning Up ID3s?</title>
    <dc:creator>Rob Williams</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/KzgFXYWQJ0A/tuneup_what_is_so_hard</link>
        <pubDate>Wed, 18 Nov 2009 10:45:23 -0500</pubDate>
    <category>Technology</category>
            <description>&lt;p&gt;After reading a bunch of reviews, I decided to buy &lt;strong&gt;TuneUp&lt;/strong&gt;. Even though laptops now have 8GBs of &lt;span class="caps"&gt;RAM&lt;/span&gt;, I have started to hawk apps that piddle away resources because it makes no sense to take all the latest technology that companies have to offer in batteries and just flush it down the toilet. That&amp;#8216;s what TuneUp does. It looks like the work of someone whose &lt;span class="caps"&gt;ADHD&lt;/span&gt; is being combatted with criminal amounts of ritalin; clearly, no one at this company got the memo that frantic, breathless huffing and puffing from any app is a bad idea, but from a sidecar is downright ludicrous. Um, I was just hoping to get all my Mahler under one folder that says simply Gustav Mahler&amp;#8230; ??&lt;/p&gt;

	&lt;p&gt;Here&amp;#8216;s TuneUp topping the &lt;span class="caps"&gt;CPU&lt;/span&gt; suckers list:&lt;/p&gt;

	&lt;p&gt;&lt;img src="http://bucket.ontometrics.com/images/tuneup-cpu.png" alt="" /&gt;&lt;/p&gt;

	&lt;p&gt;One more little treasure: it writes itself into every bloody track (credit is best when you can just go get it yourself!):&lt;/p&gt;

	&lt;p&gt;&lt;img src="http://bucket.ontometrics.com/images/tuneup-comments.png" alt="" /&gt;&lt;/p&gt;

	&lt;p&gt;In the commission of these duties, I also was fiddling with &lt;strong&gt;rsync&lt;/strong&gt; and &lt;strong&gt;ChronoSync&lt;/strong&gt; because I finally moved all my tunes to &lt;span class="caps"&gt;NAS&lt;/span&gt;. But now, I have figured out how to bring the tunes in from the &lt;span class="caps"&gt;NAS&lt;/span&gt; and I&amp;#8216;m just editing them with iTunes.&lt;/p&gt;

	&lt;p&gt;I forgot to mention I installed it on my laptop and desktop and now it says I have to call support. Apple lets me play tunes I buy on 5 devices, TuneUp goes into lockdown on #2.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/KzgFXYWQJ0A" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/robwilliams/entry/tuneup_what_is_so_hard</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/evans/entry/revisiting_pyunit_once_again</guid>
    <title>Revisiting PyUnit Once Again</title>
    <dc:creator>evans</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/1iZmGZAPX_E/revisiting_pyunit_once_again</link>
        <pubDate>Tue, 17 Nov 2009 22:08:21 -0500</pubDate>
    <category>Java</category>
            <description>&lt;p /&gt;
&lt;iframe src="http://rcm.amazon.com/e/cm?t=bolala-20&amp;o=1&amp;p=48&amp;l=ur1&amp;category=kindle&amp;banner=1A4WTMTV46B2XKSWVWG2&amp;f=ifr" width="728" height="90" scrolling="no" border="0" marginwidth="0" style="border:none;" frameborder="0"&gt;&lt;/iframe&gt;

&lt;p /&gt;I love working with Python, I learned TDD with PyUnit, but since moved to using Ruby, and have been spoilt by rspec and even cucumber. My instincts are to write
things test first, but so far I'm not finding PyUnit easy enough to get going again for some weird reason.
&lt;p /&gt;
Once I get into the groove, I find it's a wonderful way to work - and
avoids some of the drivel I've come up with in the last few days.
&lt;p /&gt;
As a discipline - I always ask my team members to work out what we want to test, write the test, watch it fail, make it pass - I find this a very productive way to think and work. This simplicity and the elegance that PyUnit provides are some of the reasons why I keep coming back to Python.&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/1iZmGZAPX_E" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/evans/entry/revisiting_pyunit_once_again</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/aalmiray/entry/griffon_scala_clojure_updates</guid>
    <title>Griffon: Scala &amp; Clojure updates</title>
    <dc:creator>Andres Almiray</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/OPaDioKoE7k/griffon_scala_clojure_updates</link>
        <pubDate>Tue, 17 Nov 2009 20:10:50 -0500</pubDate>
    <category>Groovy</category>
    <category>clojure</category>
    <category>griffon</category>
    <category>groovy</category>
    <category>plugin</category>
    <category>scala</category>
            <description>New versions of the &lt;a href="http://griffon.codehaus.org/Scala+Plugin"&gt;Scala&lt;/a&gt; and &lt;a href="http://griffon.codehaus.org/Clojure+Plugin"&gt;Clojure&lt;/a&gt; Griffon plugins have been released. These are the highlights:&lt;br/&gt;&lt;br/&gt;
&lt;b&gt;Scala&lt;/b&gt;&lt;ul&gt;
&lt;li&gt;Updated bundled libs to Scala 2.7.7 final.&lt;/li&gt;
&lt;li&gt;Added &lt;tt&gt;scala-repl&lt;/tT&gt; script. You'll now be able to launch an application interactively and prod at it using a Scala REPL.&lt;/li&gt;
&lt;li&gt;Added &lt;a href="http://scalatest.org/"&gt;Scalatest 1.0&lt;/a&gt; support via &lt;tt&gt;scala-test&lt;/tt&gt; script. There are plenty of configurable options for you to tweak and tune.&lt;/li&gt;
&lt;li&gt;Added &lt;a href="http://code.google.com/p/scalacheck/"&gt;Scalacheck 1.6&lt;/a&gt; support via &lt;tt&gt;scala-check&lt;/tt&gt; script.&lt;/li&gt;
&lt;/ul&gt;Both scala-test and scala-check produce reports that are not yet integrated with the standard reporting mechanism. This feature may be implemented in a future release.&lt;br/&gt;&lt;br/&gt;
&lt;b&gt;Clojure&lt;/b&gt;&lt;ul&gt;
&lt;li&gt;Synchronized the plugin with its Grails counterpart, as it had been updated with a few bug fixes and features, like support for Clojure macros and type conversions.&lt;/li&gt;
&lt;li&gt;Added &lt;tt&gt;create-clojure-script&lt;/tt&gt; script. Creates a new Clojure script in &lt;tt&gt;$basedir/griffon-app/resources/clj&lt;/tt&gt;.&lt;/li&gt;
&lt;li&gt;Added &lt;tt&gt;create-clojure-class&lt;/tt&gt; script. Creates a new Clojure (macro based) class in &lt;tt&gt;$basedir/src/clojure&lt;/tt&gt;.&lt;/li&gt;
&lt;li&gt;Added &lt;tt&gt;clojure-repl&lt;/tt&gt; script. Similar to its Scala counterpart, you'll be able to launch an application in interactive mode inside a Clojure REPL.&lt;/li&gt;
&lt;/ul&gt;Keep on Groovying!&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/OPaDioKoE7k" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/aalmiray/entry/griffon_scala_clojure_updates</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/RickHigh/entry/notes_on_creating_gif_png</guid>
    <title>Notes on creating GIF, PNG images in Python (first note) with PIL and aggdraw</title>
    <dc:creator>Rick Hightower</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/KMB15DotzO0/notes_on_creating_gif_png</link>
        <pubDate>Tue, 17 Nov 2009 17:46:08 -0500</pubDate>
    <category>technology</category>
            <description>&lt;span class="Apple-style-span" style="font-family: sans-serif; font-size: 13px; line-height: 19px; "&gt;&lt;p style="margin-top: 0.4em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; line-height: 1.5em; "&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin-top: 0.4em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; line-height: 1.5em; "&gt;&lt;p style="margin-top: 0.4em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; line-height: 1.5em; "&gt;Seems PIL is the way to go to create GIF, PNG and JPGs dynamiclly in python. You get a 2D API. PIL comes with a 2D API, but the PIL site seems to recommend using aggdraw on top of PIL.&lt;/p&gt;&lt;p style="margin-top: 0.4em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; line-height: 1.5em; "&gt;This site has an example of using PIL's 2D API:&lt;/p&gt;&lt;p style="margin-top: 0.4em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; line-height: 1.5em; "&gt;&lt;a href="http://lost-theory.org/python/dynamicimg.html" class="external free" title="http://lost-theory.org/python/dynamicimg.html" rel="nofollow" style="text-decoration: none; color: rgb(51, 102, 187); background-image: url(http://192.168.0.99/wiki/skins/monobook/external.png); background-repeat: no-repeat; background-attachment: initial; -webkit-background-clip: initial; -webkit-background-origin: initial; background-color: initial; padding-right: 13px; background-position: 100% 50%; "&gt;http://lost-theory.org/python/dynamicimg.html&lt;/a&gt;&lt;/p&gt;&lt;p style="margin-top: 0.4em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; line-height: 1.5em; "&gt;Here is an example (I created) of using both PIL and aggdraw:&lt;/p&gt;&lt;div dir="ltr" style="text-align: left; "&gt;&lt;pre class="source-python" style="padding-top: 1em; padding-right: 1em; padding-bottom: 1em; padding-left: 1em; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dashed; border-right-style: dashed; border-bottom-style: dashed; border-left-style: dashed; border-top-color: rgb(47, 111, 171); border-right-color: rgb(47, 111, 171); border-bottom-color: rgb(47, 111, 171); border-left-color: rgb(47, 111, 171); color: black; background-color: rgb(249, 249, 249); line-height: normal; overflow-x: auto; overflow-y: auto; "&gt;&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;import&lt;/span&gt; Image
&amp;nbsp;
img = Image.&lt;span class="kw3" style="color: rgb(220, 20, 60); "&gt;new&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;RGB&amp;quot;&lt;/span&gt;, &lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;1000&lt;/span&gt;,&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;2000&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;, &lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;#FFFFFF&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;import&lt;/span&gt; aggdraw as draw
&amp;nbsp;
canvas = draw.&lt;span class="me1" style="color: black; "&gt;Draw&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;img&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
pen = draw.&lt;span class="me1" style="color: black; "&gt;Pen&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;black&amp;quot;&lt;/span&gt;, &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0.5&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
canvas.&lt;span class="me1" style="color: black; "&gt;line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;5&lt;/span&gt;,&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;20&lt;/span&gt;,&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;200&lt;/span&gt;,&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;100&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;, pen&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
canvas.&lt;span class="me1" style="color: black; "&gt;line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;,&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;500&lt;/span&gt;,&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;500&lt;/span&gt;,&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;, draw.&lt;span class="me1" style="color: black; "&gt;Pen&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;blue&amp;quot;&lt;/span&gt;, &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0.7&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
canvas.&lt;span class="me1" style="color: black; "&gt;flush&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
img.&lt;span class="me1" style="color: black; "&gt;save&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;love.png&amp;quot;&lt;/span&gt;, &lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;PNG&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
img.&lt;span class="me1" style="color: black; "&gt;save&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;love.gif&amp;quot;&lt;/span&gt;, &lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;GIF&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p style="margin-top: 0.4em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; line-height: 1.5em; "&gt;PIL seems to come with my flavor of Ubuntu (9.0.4 rouwdy rick...), but aggdraw does not so you have to get it as follows:&lt;/p&gt;&lt;div dir="ltr" style="text-align: left; "&gt;&lt;pre class="source-python" style="padding-top: 1em; padding-right: 1em; padding-bottom: 1em; padding-left: 1em; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dashed; border-right-style: dashed; border-bottom-style: dashed; border-left-style: dashed; border-top-color: rgb(47, 111, 171); border-right-color: rgb(47, 111, 171); border-bottom-color: rgb(47, 111, 171); border-left-color: rgb(47, 111, 171); color: black; background-color: rgb(249, 249, 249); line-height: normal; overflow-x: auto; overflow-y: auto; "&gt;$ svn co http://svn.&lt;span class="me1" style="color: black; "&gt;effbot&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;org&lt;/span&gt;/public/tags/aggdraw&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;-1&lt;/span&gt;.2a3&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;-20060212&lt;/span&gt; aggdraw
$ &lt;span class="kw3" style="color: rgb(220, 20, 60); "&gt;cd&lt;/span&gt; aggdraw
$ sudo python setup.&lt;span class="me1" style="color: black; "&gt;py&lt;/span&gt; install&lt;/pre&gt;&lt;/div&gt;&lt;p style="margin-top: 0.4em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; line-height: 1.5em; "&gt;There is an executable for Windows but no installer for xNix.&lt;/p&gt;&lt;p style="margin-top: 0.4em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; line-height: 1.5em; "&gt;Here is a more involved example that draws grid paper in very long strips.&lt;/p&gt;&lt;div dir="ltr" style="text-align: left; "&gt;&lt;pre class="source-python" style="padding-top: 1em; padding-right: 1em; padding-bottom: 1em; padding-left: 1em; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dashed; border-right-style: dashed; border-bottom-style: dashed; border-left-style: dashed; border-top-color: rgb(47, 111, 171); border-right-color: rgb(47, 111, 171); border-bottom-color: rgb(47, 111, 171); border-left-color: rgb(47, 111, 171); color: black; background-color: rgb(249, 249, 249); line-height: normal; overflow-x: auto; overflow-y: auto; "&gt;&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;import&lt;/span&gt; Image
&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;import&lt;/span&gt; aggdraw as draw
&amp;nbsp;
&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;def&lt;/span&gt; drawGraph&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;step_size=&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;3&lt;/span&gt;, file_name=&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;foo.png&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;:
	STEP_SIZE = step_size
	DURATION_SECONDS = &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;40&lt;/span&gt;
	LARGE_STEP_SIZE = STEP_SIZE &lt;span class="sy0" style="color: rgb(102, 204, 102); "&gt;*&lt;/span&gt; &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;5&lt;/span&gt;
	HEIGHT = STEP_SIZE &lt;span class="sy0" style="color: rgb(102, 204, 102); "&gt;*&lt;/span&gt; &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;5&lt;/span&gt; &lt;span class="sy0" style="color: rgb(102, 204, 102); "&gt;*&lt;/span&gt; &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;4&lt;/span&gt;
	LS_PER_SECOND = &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;5&lt;/span&gt; 
	WIDTH = LS_PER_SECOND &lt;span class="sy0" style="color: rgb(102, 204, 102); "&gt;*&lt;/span&gt; DURATION_SECONDS &lt;span class="sy0" style="color: rgb(102, 204, 102); "&gt;*&lt;/span&gt; LARGE_STEP_SIZE
&amp;nbsp;
	img = Image.&lt;span class="kw3" style="color: rgb(220, 20, 60); "&gt;new&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;RGB&amp;quot;&lt;/span&gt;, &lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;WIDTH, HEIGHT&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;, &lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;#FFFFFF&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt; 
	canvas = draw.&lt;span class="me1" style="color: black; "&gt;Draw&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;img&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
	black_pen = draw.&lt;span class="me1" style="color: black; "&gt;Pen&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;black&amp;quot;&lt;/span&gt;, &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0.25&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
	blue_pen = draw.&lt;span class="me1" style="color: black; "&gt;Pen&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;red&amp;quot;&lt;/span&gt;, &lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0.25&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
	&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;for&lt;/span&gt; x &lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;in&lt;/span&gt; &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;range&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, WIDTH, STEP_SIZE&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;: canvas.&lt;span class="me1" style="color: black; "&gt;line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;x,&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;,x,HEIGHT&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;, blue_pen&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
	&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;for&lt;/span&gt; x &lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;in&lt;/span&gt; &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;range&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, WIDTH, LARGE_STEP_SIZE&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;: canvas.&lt;span class="me1" style="color: black; "&gt;line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;x,&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;,x,HEIGHT&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;, black_pen&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
	&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;for&lt;/span&gt; y &lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;in&lt;/span&gt; &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;range&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, HEIGHT, STEP_SIZE&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;: canvas.&lt;span class="me1" style="color: black; "&gt;line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;,y,WIDTH,y&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;, blue_pen&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
	&lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;for&lt;/span&gt; y &lt;span class="kw1" style="color: rgb(255, 119, 0); font-weight: bold; "&gt;in&lt;/span&gt; &lt;span class="kw2" style="color: rgb(0, 128, 0); "&gt;range&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;, HEIGHT, LARGE_STEP_SIZE&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;: canvas.&lt;span class="me1" style="color: black; "&gt;line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;,y,WIDTH,y&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;, black_pen&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
	canvas.&lt;span class="me1" style="color: black; "&gt;line&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;0&lt;/span&gt;,HEIGHT,WIDTH,HEIGHT&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;, black_pen&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
	canvas.&lt;span class="me1" style="color: black; "&gt;flush&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;.&lt;span class="me1" style="color: black; "&gt;save&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;file_name, &lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;PNG&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
&amp;nbsp;
drawGraph&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;
drawGraph&lt;span class="br0" style="color: black; "&gt;(&lt;/span&gt;&lt;span class="nu0" style="color: rgb(255, 69, 0); "&gt;6&lt;/span&gt;,&lt;span class="st0" style="color: rgb(72, 61, 139); "&gt;&amp;quot;zoom.png&amp;quot;&lt;/span&gt;&lt;span class="br0" style="color: black; "&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;/span&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/KMB15DotzO0" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/RickHigh/entry/notes_on_creating_gif_png</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/tedgoddard/entry/icefaces_tag_reference</guid>
    <title>ICEfaces Tag Reference</title>
    <dc:creator>Ted Goddard</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/dVodtLFrTZ0/icefaces_tag_reference</link>
        <pubDate>Tue, 17 Nov 2009 12:29:20 -0500</pubDate>
    <category>Java</category>
    <category>ajax</category>
    <category>dreamweaver</category>
    <category>icefaces</category>
    <category>jsf</category>
    <category>jsftoolbox</category>
            <description>&lt;br&gt;
&lt;p&gt;Here's a great &lt;a href="http://www.jsftoolbox.com/documentation/icefaces/09-TagReference/index.jsf"&gt;ICEfaces tag reference&lt;/a&gt;.  Even if you have the &lt;a href="http://www.icefaces.org/docs/v1_8_2/tld/index.html"&gt;TLD&lt;/a&gt; handy, you will find the &lt;a href="http://www.jsftoolbox.com"&gt;JSFToolbox&lt;/a&gt; reference useful because it is very concise and contains screenshots. And while you're there, be sure to check out the design-time extensions for Dreamweaver.&lt;/p&gt;
&lt;p&gt;Are you designing dynamic web applications using Dreamweaver?  JSF is an ideal technology for this, but it's something the ICEfaces community lacks experience with, because the community is almost entirely composed of Java developers.  Making Ajax Push applications easy to design is very important, so please let us know what is needed to make ICEfaces easy to use outside of a traditional Java IDE shop.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/dVodtLFrTZ0" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/tedgoddard/entry/icefaces_tag_reference</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/Solomon/entry/spring_3_0_rest_example</guid>
    <title>Spring 3.0 REST example</title>
    <dc:creator>Solomon Duskis</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/5nqejgNcDNA/spring_3_0_rest_example</link>
        <pubDate>Tue, 17 Nov 2009 11:27:02 -0500</pubDate>
    <category>Java</category>
            <description>&lt;p&gt; I've been working on getting a REST + Hibernate application using the goodies found in &lt;a href="http://www.springsource.com/download?project=Spring%20Framework&amp;__utma=1.2424796722962286600.1243170499.1258249503.1258468395.5&amp;__utmb=1.1.10.1258468395&amp;__utmc=1&amp;__utmx=-&amp;__utmz=1.1258468395.5.3.utmcsr=google|utmccn=%28organic%29|utmcmd=organic|utmctr=spring%203.0%20download&amp;__utmv=-&amp;__utmk=56484907"&gt;Spring 3.0&lt;/a&gt; for my &lt;a href="http://www.amazon.com/Spring-Persistence-Hibernate-Beginning-Fisher/dp/1430226323"&gt;upcoming book - Spring Persistence with Hibernate&lt;/a&gt;.  I'm unfortunately slightly disappointed at the current state of affairs (sorry &lt;a href="http://www.springsource.com/people/apoutsma"&gt;Arjen&lt;/a&gt; and &lt;a href="http://www.springsource.com/people/cbeams"&gt;Chris&lt;/a&gt;).  Spring 3.0 is in RC2, meaning it's had 2 Release Candidates, but the REST stuff is still not 100% right.  I was able to work around issues, but I shouldn't have had to deal with the issues I dealt with had Spring REST been a battle tested in production.  I'm going to levarage my work show you how to get a basic application up and running so that you can see exactly what I mean. My application is going to use maven, Spring 3.0, Spring MVC (REST), Spring OXM, Jetty, Hibernate and an in-memory database using H2.  You can download a ZIP file: &lt;a href="http://dl.dropbox.com/u/2654661/gallery.zip"&gt;gallery.zip&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt; Maven is the logical first place to start.  If you don't have maven installed, then &lt;a href="http://maven.apache.org/download.html#Installation"&gt;do it&lt;/a&gt;.  Choose a top level folder for your project (mine is c:\dev\springpersitence\gallery) and run &lt;strong&gt;mvn archetype:create -DgroupId=com.smartpants.artwork -DartifactId=gallery&lt;/strong&gt; to create the project. (You can switch your groupId to match com.yourcompany.project).  Update the pom.xml to import a whole bunch of dependencies from a whole bunch of repositories:  We're also going to set up an embedded Jetty instance:&lt;/p&gt;

&lt;pre class="alt2" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; height: 500px;"&gt;
&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
&amp;lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="
      http://maven.apache.org/POM/4.0.0
      http://maven.apache.org/maven-v4_0_0.xsd"&amp;gt;
  &amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;
  &amp;lt;groupId&amp;gt;com.smartpants.artwork&amp;lt;/groupId&amp;gt;
  &amp;lt;artifactId&amp;gt;gallery&amp;lt;/artifactId&amp;gt;
  &amp;lt;packaging&amp;gt;war&amp;lt;/packaging&amp;gt;
  &amp;lt;name&amp;gt;Artwork Gallery App&amp;lt;/name&amp;gt;
  &amp;lt;version&amp;gt;0.1&amp;lt;/version&amp;gt;
  &amp;lt;description /&amp;gt;

  &amp;lt;build&amp;gt;
    &amp;lt;finalName&amp;gt;gallery-web-app&amp;lt;/finalName&amp;gt;
    &amp;lt;plugins&amp;gt;
      &amp;lt;plugin&amp;gt;
        &amp;lt;artifactId&amp;gt;maven-compiler-plugin&amp;lt;/artifactId&amp;gt;
        &amp;lt;configuration&amp;gt;
          &amp;lt;source&amp;gt;1.6&amp;lt;/source&amp;gt;
          &amp;lt;target&amp;gt;1.6&amp;lt;/target&amp;gt;
        &amp;lt;/configuration&amp;gt;
      &amp;lt;/plugin&amp;gt;
      &amp;lt;plugin&amp;gt;
        &amp;lt;groupId&amp;gt;org.mortbay.jetty&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;maven-jetty-plugin&amp;lt;/artifactId&amp;gt;
        &amp;lt;version&amp;gt;6.1.15&amp;lt;/version&amp;gt;
        &amp;lt;configuration&amp;gt;
          &amp;lt;!--
            By default the artifactId is taken, override it with
            something simple
          --&amp;gt;
          &amp;lt;contextPath&amp;gt;/&amp;lt;/contextPath&amp;gt;
        &amp;lt;/configuration&amp;gt;
      &amp;lt;/plugin&amp;gt;
    &amp;lt;/plugins&amp;gt;
  &amp;lt;/build&amp;gt;

  &amp;lt;properties&amp;gt;
    &amp;lt;spring.framework.version&amp;gt;3.0.0.RC2&amp;lt;/spring.framework.version&amp;gt;
    &amp;lt;org.slf4j.version&amp;gt;1.5.2&amp;lt;/org.slf4j.version&amp;gt;
  &amp;lt;/properties&amp;gt;

  &amp;lt;dependencies&amp;gt;
    &amp;lt;!-- Spring  --&amp;gt;
    &amp;lt;dependency&amp;gt;
      &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;spring-beans&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;${spring.framework.version}&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;
    &amp;lt;dependency&amp;gt;
      &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;spring-context-support&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;${spring.framework.version}&amp;lt;/version&amp;gt;
      &amp;lt;exclusions&amp;gt;
        &amp;lt;exclusion&amp;gt;
          &amp;lt;groupId&amp;gt;quartz&amp;lt;/groupId&amp;gt;
          &amp;lt;artifactId&amp;gt;quartz&amp;lt;/artifactId&amp;gt;
        &amp;lt;/exclusion&amp;gt;
      &amp;lt;/exclusions&amp;gt;
    &amp;lt;/dependency&amp;gt;
    &amp;lt;dependency&amp;gt;
      &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;spring-core&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;${spring.framework.version}&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;
    &amp;lt;dependency&amp;gt;
      &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;spring-jdbc&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;${spring.framework.version}&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;
    &amp;lt;dependency&amp;gt;
      &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;spring-test&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;${spring.framework.version}&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;
    &amp;lt;dependency&amp;gt;
      &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;spring-orm&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;${spring.framework.version}&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;
    &amp;lt;dependency&amp;gt;
      &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;spring-oxm&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;${spring.framework.version}&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;
    &amp;lt;dependency&amp;gt;
      &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;spring-tx&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;${spring.framework.version}&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;
    &amp;lt;dependency&amp;gt;
      &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;spring-web&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;${spring.framework.version}&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;
    &amp;lt;dependency&amp;gt;
      &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;spring-webmvc&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;${spring.framework.version}&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;
    &amp;lt;dependency&amp;gt;
      &amp;lt;groupId&amp;gt;cglib&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;cglib-nodep&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;2.1_3&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;
    &amp;lt;dependency&amp;gt;
      &amp;lt;groupId&amp;gt;javax.xml.bind&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;jaxb-api&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;2.0&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;

    &amp;lt;!-- Hibernate --&amp;gt;
    &amp;lt;dependency&amp;gt;
      &amp;lt;groupId&amp;gt;org.hibernate&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;hibernate-annotations&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;3.4.0.GA&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;
    &amp;lt;dependency&amp;gt;
      &amp;lt;groupId&amp;gt;org.hibernate&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;hibernate&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;3.2.6.ga&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;
    &amp;lt;dependency&amp;gt;
      &amp;lt;groupId&amp;gt;javax.persistence&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;persistence-api&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;1.0&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;
    &amp;lt;dependency&amp;gt;
      &amp;lt;groupId&amp;gt;javassist&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;javassist&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;3.11.0.GA&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;

    &amp;lt;!-- Database --&amp;gt;
    &amp;lt;dependency&amp;gt;
      &amp;lt;groupId&amp;gt;commons-dbcp&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;commons-dbcp&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;1.2.1&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;
    &amp;lt;dependency&amp;gt;
      &amp;lt;groupId&amp;gt;commons-collections&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;commons-collections&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;3.2.1&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;
    &amp;lt;dependency&amp;gt;
      &amp;lt;groupId&amp;gt;com.h2database&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;h2&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;1.2.122&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;
    &amp;lt;dependency&amp;gt;
      &amp;lt;groupId&amp;gt;javax.transaction&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;jta&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;1.1&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;

    &amp;lt;!-- JUnit --&amp;gt;
    &amp;lt;dependency&amp;gt;
      &amp;lt;groupId&amp;gt;junit&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;junit&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;4.5&amp;lt;/version&amp;gt;
      &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
    &amp;lt;/dependency&amp;gt;

    &amp;lt;dependency&amp;gt;
      &amp;lt;groupId&amp;gt;org.slf4j&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;slf4j-api&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;${org.slf4j.version}&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;
    &amp;lt;dependency&amp;gt;
      &amp;lt;groupId&amp;gt;org.slf4j&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;slf4j-simple&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;${org.slf4j.version}&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;

    &amp;lt;dependency&amp;gt;
      &amp;lt;groupId&amp;gt;org.mortbay.jetty&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;maven-jetty-plugin&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;6.1.15&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;

  &amp;lt;/dependencies&amp;gt;

  &amp;lt;repositories&amp;gt;
    &amp;lt;repository&amp;gt;
      &amp;lt;id&amp;gt;ibiblio mirror&amp;lt;/id&amp;gt;
      &amp;lt;url&amp;gt;http://mirrors.ibiblio.org/pub/mirrors/maven2/&amp;lt;/url&amp;gt;
    &amp;lt;/repository&amp;gt;
    &amp;lt;repository&amp;gt;
      &amp;lt;id&amp;gt;Springframework milestone&amp;lt;/id&amp;gt;
      &amp;lt;url&amp;gt;http://maven.springframework.org/milestone&amp;lt;/url&amp;gt;
    &amp;lt;/repository&amp;gt;
    &amp;lt;repository&amp;gt;
      &amp;lt;id&amp;gt;jboss&amp;lt;/id&amp;gt;
      &amp;lt;url&amp;gt;http://repository.jboss.org/maven2&amp;lt;/url&amp;gt;
    &amp;lt;/repository&amp;gt;
    &amp;lt;repository&amp;gt;
      &amp;lt;id&amp;gt;java.net&amp;lt;/id&amp;gt;
      &amp;lt;url&amp;gt;https://maven-repository.dev.java.net/nonav/repository&amp;lt;/url&amp;gt;
      &amp;lt;layout&amp;gt;legacy&amp;lt;/layout&amp;gt;
    &amp;lt;/repository&amp;gt;
    &amp;lt;repository&amp;gt;
      &amp;lt;id&amp;gt;codehaus&amp;lt;/id&amp;gt;
      &amp;lt;url&amp;gt;http://repository.codehaus.org&amp;lt;/url&amp;gt;
    &amp;lt;/repository&amp;gt;
    &amp;lt;repository&amp;gt;
      &amp;lt;id&amp;gt;atlassian&amp;lt;/id&amp;gt;
      &amp;lt;url&amp;gt;http://repository.atlassian.com/maven2&amp;lt;/url&amp;gt;
    &amp;lt;/repository&amp;gt;
    &amp;lt;repository&amp;gt;
      &amp;lt;id&amp;gt;maven2-repository.dev.java.net&amp;lt;/id&amp;gt;
      &amp;lt;name&amp;gt;Java.net Repository for Maven&amp;lt;/name&amp;gt;
      &amp;lt;url&amp;gt;http://download.java.net/maven/2/&amp;lt;/url&amp;gt;
      &amp;lt;layout&amp;gt;default&amp;lt;/layout&amp;gt;
    &amp;lt;/repository&amp;gt;
  &amp;lt;/repositories&amp;gt;
  &amp;lt;pluginRepositories&amp;gt;
    &amp;lt;pluginRepository&amp;gt;
      &amp;lt;id&amp;gt;maven2-repository.dev.java.net&amp;lt;/id&amp;gt;
      &amp;lt;url&amp;gt;http://download.java.net/maven/2&amp;lt;/url&amp;gt;
    &amp;lt;/pluginRepository&amp;gt;
    &amp;lt;pluginRepository&amp;gt;
      &amp;lt;id&amp;gt;maven-repository.dev.java.net&amp;lt;/id&amp;gt;
      &amp;lt;name&amp;gt;Java.net Maven 1 Repository (legacy)&amp;lt;/name&amp;gt;
      &amp;lt;url&amp;gt;http://download.java.net/maven/1&amp;lt;/url&amp;gt;
      &amp;lt;layout&amp;gt;legacy&amp;lt;/layout&amp;gt;
    &amp;lt;/pluginRepository&amp;gt;
  &amp;lt;/pluginRepositories&amp;gt;
&amp;lt;/project&amp;gt;
&lt;/pre&gt;

&lt;br /&gt;

&lt;h2&gt;Spring XML Configuration&lt;/h2&gt;

&lt;p&gt;Next, you'll need a couple of Spring configuration files.  We'll put those files in &lt;strong&gt;src/resources&lt;/strong&gt;. The first file, &lt;strong&gt;spring-context&lt;/strong&gt; is going to be to set up hibernate (including classpath scanning for @Entity object), create the database (using the new &lt;strong&gt;jdbc&lt;/strong&gt; namespace), setup Spring classpath scanning (for Spring beans annotated with @Controller, @Repository &amp;amp etc.) and setup transaction management:

&lt;pre class="alt2" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; height: 300px;"&gt;
&amp;lt;beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
  xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
  xmlns:p="http://www.springframework.org/schema/p"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
    http://www.springframework.org/schema/jdbc
	http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd"&amp;gt;

  &amp;lt;context:component-scan base-package="com.smartpants.artwork" /&amp;gt;
  &amp;lt;jdbc:embedded-database id="dataSource" type="H2" /&amp;gt;

  &amp;lt;bean id="sessionFactory"
    class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
    p:dataSource-ref="dataSource" p:lobHandler-ref="defaultLobHandler"
    p:packagesToScan="com.smartpants.artwork.domain"&amp;gt;
    &amp;lt;property name="hibernateProperties"&amp;gt;
      &amp;lt;value&amp;gt;
        hibernate.dialect=org.hibernate.dialect.H2Dialect
        hibernate.show_sql=true
        hibernate.hbm2ddl.auto=create
      &amp;lt;/value&amp;gt;
    &amp;lt;/property&amp;gt;
  &amp;lt;/bean&amp;gt;

  &amp;lt;bean id="defaultLobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler" /&amp;gt;
  &amp;lt;bean id="transactionManager"
    class="org.springframework.orm.hibernate3.HibernateTransactionManager"
    p:sessionFactory-ref="sessionFactory" /&amp;gt;
  &amp;lt;tx:annotation-driven proxy-target-class="true" /&amp;gt;
&amp;lt;/beans&amp;gt;
&lt;/pre&gt;

&lt;p&gt; We'll also create another Spring XML file which is more geared towards the REST aspects of our projects. We're going to setup Spring @MVC annotation processing, and XML processing through JAXB.

&lt;pre class="alt2" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; height: 300px;"&gt;
&amp;lt;beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
  xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p"
  xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
 
  xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.0.xsd
           http://www.springframework.org/schema/tx
           http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
           http://www.springframework.org/schema/jdbc
		   http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd"&amp;gt;

  &amp;lt;bean
    class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" /&amp;gt;
  &amp;lt;bean
    class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"&amp;gt;
    &amp;lt;property name="messageConverters"&amp;gt;
      &amp;lt;list&amp;gt;
        &amp;lt;ref bean="marshallingHttpMessageConverter"/&amp;gt;
      &amp;lt;/list&amp;gt;
    &amp;lt;/property&amp;gt;
 &amp;lt;/bean&amp;gt;

  &amp;lt;bean id="marshallingHttpMessageConverter"
    class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter"
    p:marshaller-ref="jaxb2Marshaller" p:unmarshaller-ref="jaxb2Marshaller" /&amp;gt;

  &amp;lt;bean id="jaxb2Marshaller" class="com.smartpants.artwork.controllers.MyJaxb2Marshaller"&amp;gt;
    &amp;lt;property name="classesToBeBound"&amp;gt;
      &amp;lt;list&amp;gt;
        &amp;lt;value&amp;gt;com.smartpants.artwork.domain.Person&amp;lt;/value&amp;gt;
        &amp;lt;value&amp;gt;com.smartpants.artwork.domain.People&amp;lt;/value&amp;gt;
      &amp;lt;/list&amp;gt;
    &amp;lt;/property&amp;gt;
  &amp;lt;/bean&amp;gt;

  &amp;lt;context:component-scan base-package="com.smartpants.artwork.controllers" /&amp;gt;
  &amp;lt;tx:annotation-driven proxy-target-class="true" /&amp;gt;

&amp;lt;/beans&amp;gt;&lt;/pre&gt;

&lt;p&gt; There are two things I don't like about this:

&lt;ol&gt;
  &lt;li&gt; &lt;p&gt;Notice that I had to create &lt;strong&gt;com.smartpants.artwork.controllers.MyJaxb2Marshaller&lt;/strong&gt;.  That's to get around a problem that OXM has when working with Hibernate proxied objects, which IMHO is a fundamental test case for a Java REST system). Essentially, Spring OXM/JAXB only checks for the @XMLRootElement only on the class itself, and not on the parent classes (like the JAX-RS implementation other Spring subsystems).  The hibernate proxy process subclasses your base object (in my case Person) and doesn't add the @XMLRootElement annotation to the subclass.  My workaround:&lt;/p&gt;

&lt;pre class="alt2" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto;"&gt;package com.smartpants.artwork.controllers;

import javax.xml.bind.annotation.XmlRootElement;

import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;

public class MyJaxb2Marshaller extends Jaxb2Marshaller {

  @Override
  public boolean supports(Class&lt;?&gt; clazz) {
    return super.supports(clazz) ? true : AnnotationUtils.findAnnotation(clazz,
        XmlRootElement.class) != null;
  }
}
&lt;/pre&gt;

	&lt;p&gt; The Spring framework comes with some great annotation processing utilities that Spring OXM doesn't use... Like I said earlier, this doesn't seem battle tested to me.&lt;/p&gt;
  &lt;/li&gt;

  &lt;li&gt; Why the heck do I need to create the "classesToBeBound" list?  The JAX-RS frameworks don't need anything like that... My guess is that this is a legacy from OXM being a WS-* based system.&lt;/li&gt;

&lt;/ol&gt;

&lt;br /&gt;
&lt;h2&gt; Domain objects&lt;/h2&gt;

&lt;p&gt; My single domain object is pretty simple.  I need a Person table/entity in my system.  It represents a logical user of my system.  It plays the dual role of Hibernate object and an object for my REST interface.

&lt;pre class="alt2" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; height: 300px;"&gt;
package com.smartpants.artwork.domain;

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Version;
import javax.xml.bind.annotation.XmlRootElement;

@Entity
@XmlRootElement
public class Person implements Serializable {
  private static final long serialVersionUID = 1L;

  private Long id;
  private String firstName;
  private String lastName;
  private String username;
  private String password;
  private int roleLevel;

  private Integer version;

  public Person() {

  }

  public Person(String firstName, String lastName, String username,
      String password, int roleLevel) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.username = username;
    this.password = password;
    this.roleLevel = roleLevel;
  }

  @Id
  @GeneratedValue
  public Long getId() {
    return id;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public String getFirstName() {
    return firstName;
  }

  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }

  public String getLastName() {
    return lastName;
  }

  public void setLastName(String lastName) {
    this.lastName = lastName;
  }

  public String getUsername() {
    return username;
  }

  public void setUsername(String username) {
    this.username = username;
  }

  public String getPassword() {
    return password;
  }

  public void setPassword(String password) {
    this.password = password;
  }

  public int getRoleLevel() {
    return roleLevel;
  }

  public void setRoleLevel(int roleLevel) {
    this.roleLevel = roleLevel;
  }

  @Version
  public Integer getVersion() {
    System.out.println("getting version " + getLastName());
    return version == null ? 1 : version;
  }

  public void setVersion(Integer version) {
    this.version = version;
  }

  public enum RoleLevel {
    ADMIN(1), GUEST(2), PUBLIC(3);
    private final int level;

    RoleLevel(int value) {
      this.level = value;
    }

    public static RoleLevel getLevel(String roleName) {
      return RoleLevel.valueOf(roleName);
    }

    public int getLevel() {
      return this.level;
    }
  }

}
&lt;/pre&gt;

&lt;p&gt; Using JAXB generally requires a wrapper object, so I decided to create a People JAXB object:

&lt;pre class="alt2" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; height: 300px;"&gt;
package com.smartpants.artwork.domain;

import java.io.Serializable;
import java.util.List;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class People implements Serializable {
  private static final long serialVersionUID = 1L;

  private List&amp;lt;Person&amp;gt person;

  public People() {
    // empty constructor required for JAXB
  }

  public People(List&lt;Person&gt; person) {
    this.person = person;
  }

  public List&amp;lt;Person&amp;gt getPerson() {
    return person;
  }

  public void setPerson(List&lt;Person&gt; person) {
    this.person = person;
  }
}
&lt;/pre&gt;

&lt;br /&gt;

&lt;h2&gt;DAOs&lt;/h2&gt;

&lt;p&gt; The DAOs aren't exactly new technology, but I'll add them for completeness. Like a good boy, I created a PersonDao interface and PersonDaoHibernate implementation.  I've gotten accustomed to Grails/GORM's niceties over the last few months, and the interface kind of bothered me... but that's a post for another time.  The PersonDao:

&lt;pre class="alt2" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; height: 300px;"&gt;
package com.smartpants.artwork.dao;

import java.util.List;

import com.smartpants.artwork.domain.Person;
import com.smartpants.artwork.exception.AuthenticationException;

public interface PersonDao {

  public Person getPerson(Long personId);

  public void savePerson(Person person);

  public List&amp;lt;Person&amp;gt getPeople();

  public Person getPersonByUsername(String username);

  public Person authenticatePerson(String user, String password)
      throws AuthenticationException;
}
&lt;/pre&gt;

&lt;p&gt; The hibernate implementation (notice the super.setupSessionFactory() hack I had to do to get @Autowired to work):&lt;/p&gt;

&lt;pre class="alt2" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; height: 500px;"&gt;
package com.smartpants.artwork.dao.hibernate;

import static java.lang.String.format;

import java.util.List;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.smartpants.artwork.dao.PersonDao;
import com.smartpants.artwork.domain.Person;
import com.smartpants.artwork.exception.AuthenticationException;

@Repository
@Transactional
@SuppressWarnings("unchecked")
public class PersonDaoHibernate extends HibernateDaoSupport implements
    PersonDao {

  @Autowired
  public void setupSessionFactory(SessionFactory sessionFactory) {
    this.setSessionFactory(sessionFactory);
  }

  public Person getPerson(Long personId) throws DataAccessException {
    return this.getHibernateTemplate().load(Person.class, personId);
  }

  @Transactional(readOnly = false, propagation = Propagation.REQUIRED)
  public void savePerson(Person person) throws DataAccessException {
    this.getHibernateTemplate().saveOrUpdate(person);
  }

  public List&lt;Person&gt; getPeople() throws DataAccessException {
    return this.getHibernateTemplate().find("select people from Person people");
  }

  public Person getPersonByUsername(String username) {
    List&lt;Person&gt; people = this.getHibernateTemplate().findByNamedParam(
        "select people from Person people "
            + "where people.username = :username", "username", username);
    Person person = getFirst(people);
    if (person != null)
      getHibernateTemplate().evict(person);
    return person;
  }

  public Person authenticatePerson(String username, String password)
      throws AuthenticationException {
    List&lt;Person&gt; validUsers = this.getHibernateTemplate().findByNamedParam(
        "select people from Person people "
            + "where people.username = :username "
            + "and people.password = :password",
        new String[] { "username", "password" },
        new String[] { username, password });

    if (validUsers.isEmpty())
      throw new AuthenticationException(format("Could not authenticate %s",
          username));
    return getFirst(validUsers);
  }

  private static &amp;lt;T&amp;gt; T getFirst(List&amp;lt;T&amp;gt list) {
    return CollectionUtils.isEmpty(list) ? null : list.get(0);
  }
}
&lt;/pre&gt;

&lt;br /&gt;

&lt;h2&gt;Controller&lt;/h2&gt;

&lt;p&gt; I wanted to build a really simple PersonController that did a POST for adding a new Person at "/people", with a GET at "/people" returning all Person objects (wrapped in a People object), and a GET at "/people/{id}".  It's pretty straight forward, but is a bit more verbose that a JAX-RS equivalent:

&lt;pre class="alt2" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; height: 500px;"&gt;
package com.smartpants.artwork.controllers;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.view.RedirectView;

import com.smartpants.artwork.dao.PersonDao;
import com.smartpants.artwork.domain.People;
import com.smartpants.artwork.domain.Person;

@Controller
@RequestMapping("/people")
@Transactional()
public class PersonController {

  private PersonDao personDao;

  @Autowired
  public void setPersonDao(PersonDao personDao) {
    this.personDao = personDao;
  }

  @RequestMapping(method = RequestMethod.GET)
  public People getAll() {
    return new People(personDao.getPeople());
  }

  @RequestMapping(value = "/{id}", method = RequestMethod.GET)
  @ResponseBody
  public Person getPerson(@PathVariable("id") Long personId) {
    return personDao.getPerson(personId);
  }

  @RequestMapping(method = RequestMethod.POST)
  @Transactional(readOnly = false)
  public View savePerson(@RequestBody Person person) {
    personDao.savePerson(person);
    return new RedirectView("/people/" + person.getId());
  }
}
&lt;/pre&gt;

&lt;br /&gt;

&lt;h2&gt;web.xml&lt;/h2&gt;

&lt;p&gt; The web.xml is pretty standard fare for Spring MVC:&lt;/p&gt;

&lt;pre class="alt2" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; height: 400px;"&gt;
&amp;lt;?xml version="1.0" encoding="ISO-8859-1"?&amp;gt;

&amp;lt;web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
  version="2.4"&amp;gt;

  &amp;lt;display-name&amp;gt;ArtworkWeb&amp;lt;/display-name&amp;gt;
  &amp;lt;description&amp;gt;ArtWork&amp;lt;/description&amp;gt;
  &amp;lt;distributable /&amp;gt;

  &amp;lt;context-param&amp;gt;
    &amp;lt;param-name&amp;gt;contextConfigLocation&amp;lt;/param-name&amp;gt;
    &amp;lt;param-value&amp;gt;classpath:spring-context.xml&amp;lt;/param-value&amp;gt;
  &amp;lt;/context-param&amp;gt;

  &amp;lt;filter&amp;gt;
    &amp;lt;filter-name&amp;gt;hibernateFilter&amp;lt;/filter-name&amp;gt;
    &amp;lt;filter-class&amp;gt;org.springframework.orm.hibernate3.support.OpenSessionInViewFilter&amp;lt;/filter-class&amp;gt;
  &amp;lt;/filter&amp;gt;

  &amp;lt;listener&amp;gt;
    &amp;lt;listener-class&amp;gt;org.springframework.web.context.ContextLoaderListener
    &amp;lt;/listener-class&amp;gt;
  &amp;lt;/listener&amp;gt;

  &amp;lt;servlet&amp;gt;
    &amp;lt;servlet-name&amp;gt;artworkWeb&amp;lt;/servlet-name&amp;gt;
    &amp;lt;servlet-class&amp;gt;org.springframework.web.servlet.DispatcherServlet&amp;lt;/servlet-class&amp;gt;
    &amp;lt;init-param&amp;gt;
      &amp;lt;param-name&amp;gt;contextConfigLocation&amp;lt;/param-name&amp;gt;
      &amp;lt;param-value&amp;gt;classpath:spring-dispatcher.xml&amp;lt;/param-value&amp;gt;
    &amp;lt;/init-param&amp;gt;
    &amp;lt;load-on-startup&amp;gt;2&amp;lt;/load-on-startup&amp;gt;
  &amp;lt;/servlet&amp;gt;

  &amp;lt;!--
    - Dispatcher servlet mapping for the web user interface, - refering
    to the "image" servlet above.
  --&amp;gt;
  &amp;lt;servlet-mapping&amp;gt;
    &amp;lt;servlet-name&amp;gt;artworkWeb&amp;lt;/servlet-name&amp;gt;
    &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;
  &amp;lt;/servlet-mapping&amp;gt;

  &amp;lt;filter-mapping&amp;gt;
    &amp;lt;filter-name&amp;gt;hibernateFilter&amp;lt;/filter-name&amp;gt;
    &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;
  &amp;lt;/filter-mapping&amp;gt;

&amp;lt;/web-app&amp;gt;
&lt;/pre&gt;

&lt;br /&gt;

&lt;h2&gt;Jetty &amp;amp; RESTClient&lt;/h2&gt;

&lt;p&gt; I use &lt;a href="http://code.google.com/p/rest-client/"&gt;RESTClient&lt;/a&gt; to test out HTTP.  To run our new application, run &lt;strong&gt;mvn jetty:run&lt;/strong&gt; in a command line in your project (I can't seem to get my Eclipse plugins to execute this for me... but theoretically that should work as well).  If you'd like to debug your application, set a system variable &lt;strong&gt;MAVEN_OPTS&lt;/strong&gt; to &lt;strong&gt;-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=4000,server=y,suspend=n&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt; You should get a long log that ends with statements that your &lt;strong&gt;/person/&lt;/strong&gt; mappings are mapped to &lt;strong&gt;PersonController&lt;/strong&gt; methods.  From there you can open up RESTClient, and open up a file with the following contents that set up a POST to /person:

&lt;pre class="alt2" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width=100%"&gt;
&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
&amp;lt;rest-client version="2.3"&amp;gt;&amp;lt;request&amp;gt;&amp;lt;http-version&amp;gt;1.1&amp;lt;/http-version&amp;gt;&amp;lt;URL&amp;gt;http://localhost:8080/people&amp;lt;/URL&amp;gt;&amp;lt;method&amp;gt;POST&amp;lt;/method&amp;gt;&amp;lt;headers&amp;gt;&amp;lt;header key="ACCEPT" value="application/xml"/&amp;gt;&amp;lt;/headers&amp;gt;&amp;lt;body content-type="application/xml" charset="UTF-8"&amp;gt;&amp;amp;lt;person&amp;amp;gt;&amp;amp;#x0D;
    &amp;amp;lt;firstName&amp;amp;gt;Solomon&amp;amp;lt;/firstName&amp;amp;gt;&amp;amp;#x0D;
    &amp;amp;lt;lastName&amp;amp;gt;Solomon&amp;amp;lt;/lastName&amp;amp;gt;&amp;amp;#x0D;
    &amp;amp;lt;username&amp;amp;gt;Solomon&amp;amp;lt;/username&amp;amp;gt;&amp;amp;#x0D;
    &amp;amp;lt;password&amp;amp;gt;foo&amp;amp;lt;/password&amp;amp;gt;&amp;amp;#x0D;
&amp;amp;lt;/person&amp;amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/request&amp;gt;&amp;lt;/rest-client&amp;gt;
&lt;/pre&gt;

&lt;br /&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt; I couldn't find much documentation, and had to ask the Spring guys and they were pretty helpful. I think that the Spring Framework's REST development approach is sound, but it doesn't seem to be battle tested yet.  Meaning, it seems to be missing features that should exist if this subsystem were broadly deployed.  It took me way too long to set up this simple test case, and I had to do a relatively ugly workaround for something that should have been there already.  I like Spring's approach, but I'd be hesitant to use it on a big scale app, since you usually end up needing a some feature late in the game... the kind of features that don't exist in less mature platforms&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/5nqejgNcDNA" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/Solomon/entry/spring_3_0_rest_example</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/serkanguler/entry/xmlhttprequest_to_server_side_by</guid>
    <title>XMLHttpRequest to server side by pure javascript</title>
    <dc:creator>Serkan Guler</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/rZoPorhdmX4/xmlhttprequest_to_server_side_by</link>
        <pubDate>Tue, 17 Nov 2009 10:28:56 -0500</pubDate>
    <category>Java</category>
    <category>javascript</category>
    <category>xhr</category>
    <category>xmlhttprequest</category>
            <description>&lt;p&gt;&lt;a href="http://serkanguler.info/2009/11/17/xmlhttprequest-to-server-side-by-pure-javascript/"&gt;http://serkanguler.info/2009/11/17/xmlhttprequest-to-server-side-by-pure-javascript/&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/rZoPorhdmX4" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/serkanguler/entry/xmlhttprequest_to_server_side_by</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/scolebourne/entry/joda_money_0_5</guid>
    <title>Joda-Money 0.5</title>
    <dc:creator>Stephen Colebourne</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/9_cYhRGo0Ns/joda_money_0_5</link>
        <pubDate>Tue, 17 Nov 2009 06:10:13 -0500</pubDate>
    <category>Java</category>
    <category>joda-money</category>
            <description>&lt;p&gt;
I've just released v0.5 of &lt;a href="http://joda-money.sourceforge.net"&gt;Joda-Money&lt;/a&gt;.
It is a simple money and currency package along the lines of &lt;a href="http://joda-time.sourceforge.net"&gt;Joda-Time&lt;/a&gt;.
&lt;/p&gt;


&lt;h4&gt;Joda-Money 0.5&lt;/h4&gt;
&lt;p&gt;
&lt;a href="http://joda-money.sourceforge.net"&gt;Joda-Money&lt;/a&gt; is a project to provide
a small, focussed monetary library for Java, similar to Joda-Time.
I released v0.5 this morning.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://joda-money.sourceforge.net/"&gt;Website&lt;/a&gt;,
&lt;a href="http://joda-money.sourceforge.net/apidocs/index.html"&gt;Javadoc&lt;/a&gt;,
&lt;a href="http://sourceforge.net/projects/joda-money/files/joda-money/0.5/"&gt;Download&lt;/a&gt;,
&lt;a href="http://oss.sonatype.org/content/repositories/joda-snapshots/"&gt;Maven 2 repo&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
The code is all tested and there are no known bugs.
But I wouldn't suggest using it in production code quite yet.
I do want lots of feedback and testing though!
So, all feedback is welcomed, here, the 
&lt;a href="http://sourceforge.net/projects/joda-money/forums/forum/996056"&gt;forum&lt;/a&gt; or the
&lt;a href="http://joda-money.sourceforge.net/mail-lists.html"&gt;list&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
The main API is as I originally intended.
There is a &lt;code&gt;Money&lt;/code&gt; and &lt;code&gt;BigMoney&lt;/code&gt; class, the former decorates the latter to
restrict the number of decimal places to the currency scale.
&lt;/p&gt;
&lt;p&gt;
There is also &lt;code&gt;CurrencyUnit&lt;/code&gt; and a provided data file of currency data.
Finally, there is printing (but not parsing yet).
&lt;/p&gt;
&lt;p&gt;
The goal of the library remains just these basic classes.
Financial calculations (for whatever domain) or classes storing specific concepts like gross/net/tax
are out of scope for the library.
&lt;/p&gt;
&lt;p&gt;
This release is part of the 'release early' approach.
Please provide as much feedback as you can!
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/9_cYhRGo0Ns" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/scolebourne/entry/joda_money_0_5</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/bobfoster/entry/first_experience_with_go</guid>
    <title>First experience with Go</title>
    <dc:creator>Bob Foster</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/tEQKlBSHdRM/first_experience_with_go</link>
        <pubDate>Tue, 17 Nov 2009 05:56:07 -0500</pubDate>
    <category>Java</category>
            <description>Since jroller doesn't work reliably with Safari, I've moved on. But &lt;a href="http://notthesmartestguyintheroom.blogspot.com/2009/11/first-program-in-googles-go.html"&gt;this post&lt;/a&gt; on Google's new Go language may be of interest to some.&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/tEQKlBSHdRM" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/bobfoster/entry/first_experience_with_go</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/desmax/entry/spring_roo_jaxitalia_slides</guid>
    <title>Spring Roo JaxItalia Slides</title>
    <dc:creator>Massimiliano Dessì</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/JkWPnd7YMhY/spring_roo_jaxitalia_slides</link>
        <pubDate>Tue, 17 Nov 2009 04:24:35 -0500</pubDate>
    <category>Java</category>
    <category>aspectj</category>
    <category>hibernate</category>
    <category>jpa</category>
    <category>jsp</category>
    <category>maven</category>
    <category>productivity</category>
    <category>roo</category>
    <category>spring</category>
    <category>springmvc</category>
    <category>sts</category>
            <description>&lt;p&gt;&lt;p&gt;&lt;div style="width:425px;text-align:left" id="__ss_2517402"&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/desmax74/spring-roo-jaxitalia09" title="Spring Roo JaxItalia09"&gt;Spring Roo JaxItalia09&lt;/a&gt;&lt;object style="margin:0px" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=spring-roojaxitalia09-091117025241-phpapp01&amp;#38;stripped_title=spring-roo-jaxitalia09" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=spring-roojaxitalia09-091117025241-phpapp01&amp;#38;stripped_title=spring-roo-jaxitalia09" 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 more &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/"&gt;documents&lt;/a&gt; from &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/desmax74"&gt;Massimiliano Dessì&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;/p&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/JkWPnd7YMhY" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/desmax/entry/spring_roo_jaxitalia_slides</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/desmax/entry/spring_best_practices_jaxitalia_slides</guid>
    <title>Spring Best Practices JaxItalia Slides</title>
    <dc:creator>Massimiliano Dessì</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/tStEbNdGv3A/spring_best_practices_jaxitalia_slides</link>
        <pubDate>Tue, 17 Nov 2009 04:20:59 -0500</pubDate>
    <category>Java</category>
    <category>aop</category>
    <category>cache</category>
    <category>jaxitalia</category>
    <category>mvccontroller</category>
    <category>mvcportlet</category>
    <category>rest</category>
    <category>springframework</category>
    <category>springmvc</category>
    <category>springsecurity</category>
    <category>transaction</category>
            <description>&lt;p&gt;&lt;p&gt;&lt;div style="width:425px;text-align:left" id="__ss_2517401"&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/desmax74/jaxitalia09-spring-best-practices" title="Jaxitalia09 Spring Best Practices"&gt;Jaxitalia09 Spring Best Practices&lt;/a&gt;&lt;object style="margin:0px" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=jaxitalia09spring-bestpractices-091117025231-phpapp01&amp;#38;stripped_title=jaxitalia09-spring-best-practices" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=jaxitalia09spring-bestpractices-091117025231-phpapp01&amp;#38;stripped_title=jaxitalia09-spring-best-practices" 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 more &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/"&gt;documents&lt;/a&gt; from &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/desmax74"&gt;Massimiliano Dessì&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;/p&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/tStEbNdGv3A" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/desmax/entry/spring_best_practices_jaxitalia_slides</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/desmax/entry/spring_3_jaxitalia_slides</guid>
    <title>Spring 3 JaxItalia Slides</title>
    <dc:creator>Massimiliano Dessì</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/yjavcP5XBYQ/spring_3_jaxitalia_slides</link>
        <pubDate>Tue, 17 Nov 2009 04:15:57 -0500</pubDate>
    <category>Java</category>
    <category>jaxitalia</category>
    <category>mvccontroller</category>
    <category>mvcportlet</category>
    <category>oxm</category>
    <category>rest</category>
    <category>roo</category>
    <category>spel</category>
    <category>spring</category>
    <category>spring3</category>
            <description>&lt;p&gt;&lt;p&gt;&lt;div style="width:425px;text-align:left" id="__ss_2517381"&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/desmax74/spring30-jaxitalia09" title="Spring3.0 JaxItalia09"&gt;Spring3.0 JaxItalia09&lt;/a&gt;&lt;object style="margin:0px" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=jaxitalia09spring3-0-091117024859-phpapp02&amp;#38;stripped_title=spring30-jaxitalia09" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=jaxitalia09spring3-0-091117024859-phpapp02&amp;#38;stripped_title=spring30-jaxitalia09" 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 more &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/"&gt;documents&lt;/a&gt; from &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/desmax74"&gt;Massimiliano Dessì&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;/p&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/yjavcP5XBYQ" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/desmax/entry/spring_3_jaxitalia_slides</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/aalmiray/entry/griffon_visualizing_an_object_graph</guid>
    <title>Griffon: visualizing an object graph</title>
    <dc:creator>Andres Almiray</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/eHSrobK5Z9o/griffon_visualizing_an_object_graph</link>
        <pubDate>Mon, 16 Nov 2009 22:23:37 -0500</pubDate>
    <category>Groovy</category>
    <category>graph</category>
    <category>griffon</category>
    <category>groovy</category>
    <category>jung</category>
    <category>swing</category>
            <description>You might have read before about &lt;a href="http://griffon.codehaus.org/Jung+Plugin"&gt;Griffon's JUNG plugin&lt;/a&gt; and wondered "how can I visualize an arbitrary object graph with it?", if so then the following steps should give you a few hints.&lt;br/&gt;&lt;br/&gt;Let's start by fleshing out the domain. I realize that at the time of writing this post Griffon does not support domain classes like Grails does (i.e, with GORM &amp;amp; scaffolding enabled), however you can create them in the same fashion, that is, place your domain classes under &lt;tt&gt;griffon-app/domain&lt;/tt&gt; and have them participate on your app. With that in mind let's create a few domain classes related to the book publishing business, mainly a Publisher, a Book and an Author classes, like this:&lt;br/&gt;&lt;textarea name="srccode" class="groovy:nocontrols:nogutter" cols="80" rows="22"&gt;// griffon-app/domain/Publisher.groovy
class Publisher {
   String name
   List books = []

   String toString() { name }
}

// griffon-app/domain/Book.groovy
class Book {
   String title
   List authors = []

   String toString() { title  }
}

// griffon-app/domain/Author.groovy
class Author {
   String name

   String toString() { name }
}&lt;/textarea&gt;If you're familiar with &lt;a href="http://groovy.codehaus.org/objectgraphbuilder"&gt;ObjectGraphBuilder&lt;/a&gt; you know you can populate an object graph with ease, as long as the domain classes follow the JavaBeans conventions. Luckily for us that is the case. Building a graph is as easy as executing the following code:&lt;br/&gt;&lt;textarea name="srccode" class="groovy:nocontrols:nogutter" cols="80" rows="19"&gt;def ogb = new ObjectGraphBuilder()
ogb.publisher(name: "Manning") {
   book(title: "Groovy in Action") {
      author(name: "Dierk König")
      author(name: "Guillaume Laforge")
      author(name: "Paul King")
      author(name: "Andy Glover")
      author(name: "Jon Skeet")
   }
   book(title: "Grails in Action") {
      author(name: "Glen Smith")
      author(name: "Peter Ledbrook")
   }
   book(title: "Griffon in Action") {
      author(name: "Andres Almiray")
      author(name: "Danno Ferrin")
      author(name: "Geertjan Wielenga")
   }
}&lt;/textarea&gt;Nothing fancy, just what you would expect from a Groovy builder, isn't it? by the way I'm using the current list of Groovy related books published by Manning as an example. Alright, now comes the "tricky" part: transforming an object graph into something capable of being visualized with JUNG. I'm glad to say this task is also a simple one. We can instruct ObjectGraphBuilder to populate a JUNG Graph at the same time it builds the domain graph, after all ObjectGraphBuilder is quite extensible. There are two things to be done in order to achieve this goal:&lt;ol&gt;
&lt;li&gt;set the root node.&lt;/li&gt;
&lt;li&gt;append child nodes to their corresponding parents.&lt;/li&gt;
&lt;/ol&gt;The following Griffon model shows how these two tasks can be done:&lt;br/&gt;&lt;textarea name="srccode" class="groovy:nocontrols:nogutter" cols="80" rows="36"&gt;import edu.uci.ics.jung.graph.Graph
import edu.uci.ics.jung.graph.DelegateTree

class BooksModel {
   Graph publishers = new DelegateTree()

   BooksModel() {
      def ogb = new ObjectGraphBuilder()

      def childPropertySetter = ogb.childPropertySetter
      ogb.childPropertySetter = { parent, child, parentName, childName -&gt;
         childPropertySetter.setChild(parent, child, parentName, childName)
         publishers.addChild("'${parent}' - '${child}'", parent, child) // TASK 2
      }

      ogb.publisher(name: "Manning") {
         publishers.addVertex(current) // TASK 1
         book(title: "Groovy in Action") {
            author(name: "Dierk König")
            author(name: "Guillaume Laforge")
            author(name: "Paul King")
            author(name: "Andy Glover")
            author(name: "Jon Skeet")
         }
         book(title: "Grails in Action") {
            author(name: "Glen Smith")
            author(name: "Peter Ledbrook")
         }
         book(title: "Griffon in Action") {
            author(name: "Andres Almiray")
            author(name: "Danno Ferrin")
            author(name: "Geertjan Wielenga")
         }
      }
   }
}&lt;/textarea&gt;Task 1 is completed by calling &lt;tt&gt;addVertex&lt;/tt&gt; on the publishers Graph using a special variable available to all &lt;a href="http://groovy.codehaus.org/factorybuildersupport"&gt;FactoryBuilderSupport&lt;/a&gt; based builders: &lt;tt&gt;current&lt;/tt&gt;. This variable points to the node that is currently being built, in our case, the publisher node. Task 2 is completed by changing the strategy used by the builder to set the parent/child relationships within nodes. Notice that it still calls the old behavior by keeping a reference to the previous strategy, then calls a Graph method on publishers that registers the child with its parent. Now both the object graph and the Graph are in sync. The following code shows how the publishers Graph can be visualized with minimal effort:&lt;br/&gt;&lt;textarea name="srccode" class="groovy:nocontrols:nogutter" cols="80" rows="17"&gt;import edu.uci.ics.jung.visualization.renderers.Renderer
import edu.uci.ics.jung.visualization.decorators.ToStringLabeller

application(title: 'Groovy Books',
  pack:true,
  locationByPlatform:true,
  iconImage: imageIcon('/griffon-icon-48x48.png').image,
  iconImages: [imageIcon('/griffon-icon-48x48.png').image,
               imageIcon('/griffon-icon-32x32.png').image,
               imageIcon('/griffon-icon-16x16.png').image]) {
  visualizationViewer(model.publishers, id: "gview", preferredSize: [550,550],
       vertexLabelTransformer: new ToStringLabeller()) {
    radialTreeLayout()
    defaultModalGraphMouse()
  }
  gview.renderer.vertexLabelRenderer.position = Renderer.VertexLabel.Position.CNTR
}&lt;/textarea&gt;Running the application should result in a screen similar to the following snapshot&lt;br/&lt;br/&gt;&lt;center&gt;&lt;img src="http://www.jroller.com/aalmiray/resource/griffon-jung-graph.1.png"&gt;&lt;/center&gt;&lt;br/&gt;&lt;br/&gt;Time to get fancier with the visualizations. JUNG allows you to tweak almost every aspect of a visualization, we will concentrate on shapes and colors for now. It can be argued that visualization metadata belongs or not to domain classes. For example we could add &lt;tt&gt;shape&lt;/tt&gt; and &lt;tt&gt;color&lt;/tt&gt; properties to our domain classes, but perhaps those properties do not make any sense should our domain classes be persisted. In the end is your call how you want to add such metadata. In this howto I'll simply wrap each domain instance with a map, have the metadata (or spillover properties) be added to the map and the corresponding bean properties to each bean. In order to do that we must tweak two other OGB strategies, as shown next on the app's model:&lt;br/&gt;&lt;textarea name="srccode" class="groovy:nocontrols:nogutter" cols="80" rows="52"&gt;import java.awt.Color
import edu.uci.ics.jung.graph.Graph
import edu.uci.ics.jung.graph.DelegateTree

class BooksModel {
   Graph publishers = new DelegateTree()

   BooksModel() {
      def ogb = new ObjectGraphBuilder()
      def newInstanceResolver = ogb.newInstanceResolver
      ogb.newInstanceResolver = { klass, attributes -&gt;
         [bean: newInstanceResolver.newInstance(klass, attributes)]
      }

      ogb.addAttributeDelegate({ builder, node, attributes -&gt;
         attributes.each { k, v -&gt;
            try {
               node.bean[(k)] = v
            } catch(MissingPropertyException mpe) {
               node[(k)] = v
            }
         }
         attributes.clear()
      })

      def childPropertySetter = ogb.childPropertySetter
      ogb.childPropertySetter = { parent, child, parentName, childName -&gt;
         childPropertySetter.setChild(parent.bean, child, parentName, childName)
         publishers.addChild("'${parent}' - '${child}'", parent, child)
      }

      ogb.publisher(name: "Manning", color: Color.GREEN) {
         publishers.addVertex(current)
         book(title: "Groovy in Action", color: Color.CYAN) {
            author(name: "Dierk König")
            author(name: "Guillaume Laforge")
            author(name: "Paul King")
            author(name: "Andy Glover")
            author(name: "Jon Skeet")
         }
         book(title: "Grails in Action", color: Color.RED) {

            author(name: "Glen Smith")
            author(name: "Peter Ledbrook")
         }
         book(title: "Griffon in Action", color: Color.BLUE) {
            author(name: "Andres Almiray")
            author(name: "Danno Ferrin")
            author(name: "Geertjan Wielenga")
         }
      }
   }
}&lt;/textarea&gt;The two strategies are&lt;ul&gt;
&lt;li&gt;newInstanceResolver - takes care of instantiating a node. This is the perfect time to wrap the bean with a map.&lt;/li&gt;
&lt;li&gt;attributeDelegate - this strategy takes care of setting properties on a node. By testing for MissingPropertyException we know the property may or may not be supported by the bean. If it is not supported we assume it is a metadata property and add it directly to the enclosing map.&lt;/li&gt;
&lt;/ul&gt;Lastly we need to update the &lt;tt&gt;childPropertySetter&lt;/tt&gt; strategy as the beans are now being wrapped. Now that the model has the desired metadata it is time to update the visualization code with a set of transformers. Given that the beans are now wrapped the &lt;tt&gt;ToStringLabeller&lt;/tt&gt; will yield weird results, we need to provide a new value for vertexLabelTransformer. Two new transformers will be added:&lt;ul&gt;
&lt;li&gt;vertexShapeTransformer - takes care of setting up the shape to be used for each node.&lt;/li&gt;
&lt;li&gt;vertexFillPaintTransformer - takes care of setting up the color to be used as the fill for each node.&lt;/li&gt;
&lt;/ul&gt;We will rely on &lt;a href="http://code.google.com/p/jsilhouette"&gt;jSilhouette's Star&lt;/a&gt; shape and a helper &lt;tt&gt;BasicVertexShapeTransfomer&lt;/tt&gt; provided by the JUNG plugin. At this point only Books will have a custom shape (the Groovy star &lt;img src="http://www.jroller.com/images/smileys/grin.gif" class="smiley" alt=":-D" title=":-D" /&gt;) while the other domain classes will use a circle.&lt;br/&gt;&lt;textarea name="srccode" class="groovy:nocontrols:nogutter" cols="80" rows="34"&gt;import edu.uci.ics.jung.visualization.renderers.Renderer
import org.apache.commons.collections15.Transformer
import org.apache.commons.collections15.functors.ConstantTransformer
import java.awt.Color
import java.awt.Shape
import java.awt.geom.Ellipse2D
import org.kordamp.jsilhouette.geom.Star
import griffon.jung.visualization.decorators.BasicVertexShapeTransformer

vertexLabeler = { v -&gt; v.bean.toString() } as Transformer
vertexPainter = { v -&gt; v.color ?: Color.WHITE } as Transformer
shaper = { Map shapes, v -&gt;
   shapes[(v.bean.class.name)] ?: new Ellipse2D.Double(0, 0, 1d, 1d)
}
bean(id: "star", new Star(), or: 40f, ir: 20f, count: 5i)
bean(new BasicVertexShapeTransformer(shaper.curry([(Book.name): star])),
     id: "vertexShaper", sizeTransformer: new ConstantTransformer(40i))

application(title: 'Groovy Books',
  pack:true,
  locationByPlatform:true,
  iconImage: imageIcon('/griffon-icon-48x48.png').image,
  iconImages: [imageIcon('/griffon-icon-48x48.png').image,
               imageIcon('/griffon-icon-32x32.png').image,
               imageIcon('/griffon-icon-16x16.png').image]) {
  visualizationViewer(model.publishers, id: "gview", preferredSize: [550,550],
       vertexShapeTransformer: vertexShaper,
       vertexFillPaintTransformer: vertexPainter,
       vertexLabelTransformer: vertexLabeler) {
    radialTreeLayout()
    defaultModalGraphMouse()
  }
  gview.renderer.vertexLabelRenderer.position = Renderer.VertexLabel.Position.CNTR
}&lt;/textarea&gt;Reviewing each transformer yields:&lt;ul&gt;
&lt;li&gt;vertexLabeler - queries the node's bean. v is of type Map.&lt;/li&gt;
&lt;li&gt;vertexPainter - queries v's color property, uses a default color (WHITE) if no property is defined. The elvis operator becomes quite handy here.&lt;/li&gt;
&lt;li&gt;shaper - another elvis enabled transformer, this one checks for the existence of a shape related to a class name.&lt;/li&gt;
&lt;li&gt;vertexShaper - relies on the previous transformer to determine which shape will be used by each node. Notice that only books define a specific shape.&lt;/li&gt; 
&lt;/ul&gt;This is all that there is to it. Running the application should result in a similar screenshot like the following one&lt;br/&lt;br/&gt;&lt;center&gt;&lt;img src="http://www.jroller.com/aalmiray/resource/griffon-jung-graph.2.png"&gt;&lt;/center&gt;&lt;br/&gt;&lt;br/&gt;There you have it, a simple yet effective way to build and visualize an object graph with ObjectGraphBuilder and Griffon/JUNG.&lt;br/&gt;&lt;br/&gt;Keep on Groovying!&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/eHSrobK5Z9o" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/aalmiray/entry/griffon_visualizing_an_object_graph</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/robwilliams/entry/some_thoughts_on_time</guid>
    <title>Some Thoughts on Time</title>
    <dc:creator>Rob Williams</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/g6QFBlmBgVI/some_thoughts_on_time</link>
        <pubDate>Mon, 16 Nov 2009 17:57:14 -0500</pubDate>
    <category>Technology</category>
            <description>&lt;p&gt;&lt;img src="http://t3.gstatic.com/images?q=tbn:x5ZvVw6QsUoWGM:http://cdn.picapp.com/ftp/Images/0299/c2b1dfb2-5b24-45a9-b468-819af1aad9f6.jpg" class="rightWrap"/&gt;Time is still something of a taboo in management. When people start talking about tracking time, most developers start getting wound around the big brother axle. Having just looked at &lt;a href="http://beust.com/weblog/" title=""&gt;Cédric's post about Agile&lt;/a&gt; this morning (rare case of cluelessness), to me, the big problem in agile is like all big tents (for instance, the Democrats), we are waking up to the painfulness of a world where there is little consensus. Mind you, even where there are areas of considerable consensus (testing), that consensus is (again, like the Dems) a. broadly prescriptive ('testing is good for you') and b. promoted through fear and guilt (Uncle Bob now refers to code that doesn't have 100% coverage as 'shit' (I literally thought about doing a whole post on just parsing out that idea, and the ugly fascistic implications of promoting a shit-free world, as the various fascisti of the 30s did, in violently rebutting positivists, but I'll keep that for later.. suffice it to say things are starting to get ugly..)). Meanwhile, last week I heard that the &lt;strong&gt;Kanban&lt;/strong&gt; rash is also taking on a fundamentalist flavor: apparently the newest kanbanists believe that estimates and time in general ought be completely banned from management. The rationale goes that estimates are a waste (raises the interesting philosophical question: does Lean, when turned on itself, decide that doing anything is waste, and therefore, the reductio ad absurdum ends up being that the process must inevitably deconstruct, then dispose of &lt;em&gt;itself&lt;/em&gt;!!). (See below for some links to read on this.) Anyway, personally our group has found &lt;strong&gt;planning poker&lt;/strong&gt; to be immensely useful. I agree with the first comment on link 1: estimates are not &lt;em&gt;just&lt;/em&gt; about getting an estimate. &lt;strong&gt;Complexity&lt;/strong&gt; is the enemy combatant and planning poker does more than anything I&amp;#8216;ve found to get people to focus on that before engaging.&lt;/p&gt;

	&lt;p&gt;Back to time: I was applauding the emergence of &lt;strong&gt;Lean&lt;/strong&gt; as one of the key spokes in the Agile wheelhouse, but now, with the new ugly kanbanists becoming dominant, I am thinking perhaps we are all going down in the middle of ocean while our hijackers chant kumbaya. People, the core of Lean is the &lt;span class="caps"&gt;VSM&lt;/span&gt;. How does one evaluate the areas that can be improved (kaizen, Baby) without time as the driving factor? Let&amp;#8216;s remember, the problem ecosystem here consists of the triangle: time, resources, features. So we just pushed a piece through, now it&amp;#8216;s done. We can&amp;#8216;t talk about time. What should we talk about? Features? People?&lt;/p&gt;

	&lt;p&gt;This brings up an issue that might be the fulcrum here: whether or not the team thinks abstractly. If the answer is no (and, unfortunately, it is most of the time), I would submit that any retrospective analysis is a waste. Why? Because it&amp;#8216;s going to end up in the 5 year old, Quincy, Cartoon Coroner, breathless realm of &amp;#8216;then Tweetie flew through and Sylvester got his tail jammed in the door.&amp;#8216; The only useful analysis would consist of things like &amp;#8216;moving to building in place on piece x slowed things down, how could we have built a test case instead?&amp;#8216; or the like.&lt;/p&gt;

	&lt;p&gt;What I like about Kanban is that it fits the &lt;span class="caps"&gt;ABC&lt;/span&gt; model well: Always Be Closing. (Read an article the other day that was hailing Mamet and another cat came on and proclaimed him one of the most overrated guys in history. It&amp;#8216;s hard to argue that his oevre can compare to others, but some people get points for ringing the bell, which &amp;#8220;Glengarry Glen Ross&amp;#8221; does pretty convincingly.) It is a good idea to focus on why things are not moving, what it will take to move them, push them off, etc. To the exclusion of all other things? Not for me. I am going to start fiddling with kanban, but as a way to see where things are and what it will take to push things.&lt;/p&gt;

	&lt;p&gt;Frankly, I want to get better tools for tracking time. Did an eval of &lt;strong&gt;Rally&lt;/strong&gt; and decided it was the best of what was out there, decided to use it, but then found, to our horror, that their product is built around putting in estimates and actuals, etc., yet it is &lt;em&gt;unable to produce the simplest time reports&lt;/em&gt; Found out they are doing a brand new time tracking module which was in beta but then was going to be release first week of Nov. Suddenly it's not coming until middle of Dec! (Guess the whole release missed the train; real Agile there, guys, there are not supposed to be empty trains.. ?) Anyway, that's not even the worst of it. The horribly lacking reports they do have are, get this, obtained by culling numbers from the &lt;em&gt;change logs on each task&lt;/em&gt; Among other reasons this is a horrible idea, if you go enter a task and while entering it, put in hours, those will never make it to your report for the month! (I kind of liked this when I discovered it, as it penalizes people who wait to report until they are done, but come on!)&lt;/p&gt;

	&lt;p&gt;If the whole idea of Lean is to track waste and figure out how to reduce it, ignoring time seams utterly insane to me. The definition of waste is that the time expended did not deliver the desired result. The question is then why. Here&amp;#8216;s the time quiz for the day: where did the convention of surgeons having implements fetched for them by a nurse come from? Early photographer did a time study of surgery and found that people were dying while surgeons were fiddling around on instrument tables looking for things. One imagines that these new time-free kanbanists might favor time tracking of this sort if they were the meat on the surgeon&amp;#8216;s slab.&lt;/p&gt;

	&lt;p&gt;&lt;a href="http://aaron.sanders.name/agile/naked-planning-explained-kanban-in-the-small"&gt;The (Weak) Case Against Estimation&lt;/a&gt;&lt;br /&gt;
&lt;br/&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/g6QFBlmBgVI" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/robwilliams/entry/some_thoughts_on_time</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/dgilbert/entry/opt_out_of_google</guid>
    <title>Opt Out of Google</title>
    <dc:creator>David Gilbert</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/PM4aSloqrTM/opt_out_of_google</link>
        <pubDate>Mon, 16 Nov 2009 17:00:31 -0500</pubDate>
    <category>Java</category>
            <description>Great new opt-out feature from Google:
&lt;br&gt;&lt;br&gt;
&lt;a href="http://www.theonion.com/content/video/google_opt_out_feature_lets_users"&gt;http://www.theonion.com/content/video/google_opt_out_feature_lets_users&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/PM4aSloqrTM" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/dgilbert/entry/opt_out_of_google</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/cagataycivici/entry/mobile_gps_navigation_app_with</guid>
    <title>Mobile GPS Navigation App with JSF</title>
    <dc:creator>Cagatay Civici</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/SCyxRPShkac/mobile_gps_navigation_app_with</link>
        <pubDate>Mon, 16 Nov 2009 04:25:30 -0500</pubDate>
    <category>Java</category>
            <description>&lt;p&gt;There's no limit in what you can do with PrimeFaces.&lt;/p&gt;&lt;p&gt;&lt;a href="http://cagataycivici.wordpress.com/2009/11/15/mobile-gps-navigation-app-with-jsf/"&gt;http://cagataycivici.wordpress.com/2009/11/15/mobile-gps-navigation-app-with-jsf/ &lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/SCyxRPShkac" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/cagataycivici/entry/mobile_gps_navigation_app_with</feedburner:origLink></item>
    <item>
    <guid isPermaLink="false">http://www.jroller.com/robertburrelldonkin/entry/qotd</guid>
    <title>QOTD</title>
    <dc:creator>robert burrell donkin</dc:creator>
    <link>http://feeds.dzone.com/~r/jroller/frontpage/~3/jOyof1TCqpA/qotd</link>
        <pubDate>Sun, 15 Nov 2009 06:53:21 -0500</pubDate>
    <category>Java</category>
    <category>humour</category>
            <description>&lt;blockquote cite='http://www.1060.org/blogxter/entry?publicid=617C5C9B37BD9470B11AEB9130938D32'&gt;
"Is it automated?"
&lt;br/&gt;
"Yes, for a loose definition of automated. There's someone who knows what to type in."
&lt;/blockquote&gt;
&lt;p&gt;
Thanks to &lt;a href='http://www.1060.org/blogxter/entry?publicid=617C5C9B37BD9470B11AEB9130938D32'&gt;Steve Loughran&lt;/a&gt; 
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/jroller/frontpage/~4/jOyof1TCqpA" height="1" width="1"/&gt;</description>          <feedburner:origLink>http://www.jroller.com/robertburrelldonkin/entry/qotd</feedburner:origLink></item>
  </channel>
</rss>
