<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;CEQDSXs9eyp7ImA9WxJUF08.&quot;"><id>tag:blogger.com,1999:blog-1083890928935553699</id><updated>2009-07-16T01:32:58.563-04:00</updated><title>Rob's Musings</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://robbyoconnor.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://robbyoconnor.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Robert O'Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>44</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><link rel="self" href="http://feeds.feedburner.com/robbyoconnor" type="application/atom+xml" /><entry gd:etag="W/&quot;CEQDSXs8fCp7ImA9WxJUF08.&quot;"><id>tag:blogger.com,1999:blog-1083890928935553699.post-8627342073928215552</id><published>2009-07-16T01:31:00.001-04:00</published><updated>2009-07-16T01:32:58.574-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-16T01:32:58.574-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="gsoc" /><category scheme="http://www.blogger.com/atom/ns#" term="facility data module" /><category scheme="http://www.blogger.com/atom/ns#" term="hfoss" /><category scheme="http://www.blogger.com/atom/ns#" term="openmrs" /><title>Midterm Progress Update</title><content type="html">Progress has been slow and steady. I'm on track to finish however! What's done:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Reports can be entered, saved, and the values entered will be reloaded into the proper form fields. If edited and if the values have changed -- the old values are voided and new values are saved (retaining the old values in the database for auditing purposes).&lt;/li&gt;&lt;/ul&gt;What's left:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Management pages See &lt;a href="http://is.gd/1AAmo"&gt;this&lt;/a&gt; and &lt;a href="http://is.gd/1AAox"&gt;this&lt;/a&gt; for what it will ultimately look like.&lt;/li&gt;&lt;li&gt;Still need to get the "View Only" pages working; in theory it should work. The "View Only" will be the answers but no form fields present.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The UI to create the report, questions, sections, etc.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Ultimately, I think this shouldn't be too bad.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1083890928935553699-8627342073928215552?l=robbyoconnor.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/robbyoconnor/~4/eJKTRlMXIdA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://robbyoconnor.blogspot.com/feeds/8627342073928215552/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1083890928935553699&amp;postID=8627342073928215552" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/8627342073928215552?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/8627342073928215552?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/robbyoconnor/~3/eJKTRlMXIdA/midterm-progress-update.html" title="Midterm Progress Update" /><author><name>Robert O'Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10413037710454370678" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://robbyoconnor.blogspot.com/2009/07/midterm-progress-update.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkMAQXw-fCp7ImA9WxJWFUo.&quot;"><id>tag:blogger.com,1999:blog-1083890928935553699.post-5683637485562081848</id><published>2009-06-21T00:00:00.008-04:00</published><updated>2009-06-21T06:00:40.254-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-21T06:00:40.254-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="foss" /><category scheme="http://www.blogger.com/atom/ns#" term="soc" /><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="gsoc" /><category scheme="http://www.blogger.com/atom/ns#" term="facility data module" /><category scheme="http://www.blogger.com/atom/ns#" term="hfoss" /><category scheme="http://www.blogger.com/atom/ns#" term="openmrs" /><title>The overdue progress report</title><content type="html">Apologies for not blogging as much as I should. I've focused on getting what needed to be done, done.&lt;br /&gt;&lt;br /&gt;Tasks that have been completed thus far with a target milestone of &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="background-color: rgb(255, 255, 255);"&gt;using a mock Form, enable persistence of Questions and Values to the database:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;       Mock out a report form using the domain classes     &lt;/li&gt;&lt;li&gt;       Using the mocked up schema, generate a simple report form      &lt;/li&gt;&lt;li&gt;       Design the SQL Schema (for just FacilityDataValue and FacilityDataQuestion)&lt;br /&gt;    &lt;/li&gt;&lt;li&gt;       Write Hibernate Mapping files (for just FacilityDataValue and FacilityDataQuestion)&lt;br /&gt;    &lt;/li&gt;&lt;li&gt;       Write Data Access layer (for FacilityDataValue and FacilityDataQuestion)&lt;br /&gt;    &lt;/li&gt;&lt;li&gt;       Write Service layer (for FacilityDataValue and FacilityDataQuestion)     &lt;/li&gt;&lt;li&gt;       Refactor the rendering logic to use the JSP and write EL function(s) to check types using &lt;b&gt;instanceof&lt;/b&gt;.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;       Allow a simple the mocked form from Week 1 to save the question answers.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Tasks that are are in progress, soon to be finished with a target milestone of removing the code used to mock up everything from the first few weeks; ability to use the saved schemas for rendering the report form:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;       Design SQL Schema for the rest of the domain classes&lt;br /&gt;&lt;/li&gt;&lt;li&gt;       Write mappings for the rest of the domain classes     &lt;/li&gt;&lt;li&gt;       Support loading the previously saved values for a form/startdate/enddate/location into a page for viewing or editing&lt;br /&gt;&lt;/li&gt;&lt;li&gt;       Write methods to save the rest of the domain classes in the data access layer&lt;br /&gt;&lt;/li&gt;&lt;li&gt;       Write methods to save the rest of the domain in the service layer&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Now that I have summarized work completed and in progress, let's explain the overall design:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;b&gt;FacilityDataFormSchema &lt;/b&gt;serves as the overall representation of the report form in the system. &lt;/li&gt;&lt;li&gt;&lt;b&gt;FacilityDataFormSection &lt;/b&gt;is simply that, sections on the form, e.g., monitoring equipment status, stock status of vaccinations, number of people vaccinated, etc. &lt;/li&gt;&lt;li&gt;&lt;b&gt;FacilityDataFormQuestion&lt;/b&gt; holds metadata regarding a question. &lt;/li&gt;&lt;li&gt;&lt;b&gt;FacilityDataQuestion &lt;/b&gt;is the question itself; it specifies the datatype; it is subclassed for each question datatype; if not subclassed, then the question is considered to be "freetext" -- in other words: just simply a text-based question.&lt;br /&gt;&lt;/li&gt;&lt;ol&gt;&lt;li&gt;&lt;b&gt;CodedQuestion&lt;/b&gt; is a question that has a coded answer. This too is subclassed for each coded question datatype.&lt;br /&gt;&lt;/li&gt;&lt;ol&gt;&lt;li&gt;&lt;b&gt;StockQuestion &lt;/b&gt;is exactly as the name says, to track stock of items such as vaccinations. The coded answers are: "not_stocked_out","stocked_out","expired","not_applicable"&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;BooleanCodedQuestion  &lt;/b&gt;is a simple "yes","no","not applicable" type of thing; e.g., "Was there mobile clinic today?"&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;&lt;b&gt;NumericQuestion&lt;/b&gt; is a question which has a numeric answer, e.g., "Number of Adults Vaccinated."&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;&lt;b&gt;FacilityDataValue &lt;/b&gt;is what holds the values entered in the report forms for each question.&lt;/li&gt;&lt;li&gt;&lt;b&gt;FacilityDataReportFormData&lt;/b&gt; is a non-persisted class used for retrieving the answers for a specific report. &lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Hopefully this makes up for my lack of updates.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1083890928935553699-5683637485562081848?l=robbyoconnor.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/robbyoconnor/~4/GaCa6s7K8Qo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://robbyoconnor.blogspot.com/feeds/5683637485562081848/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1083890928935553699&amp;postID=5683637485562081848" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/5683637485562081848?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/5683637485562081848?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/robbyoconnor/~3/GaCa6s7K8Qo/overdue-progress-report.html" title="The overdue progress report" /><author><name>Robert O'Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10413037710454370678" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://robbyoconnor.blogspot.com/2009/06/overdue-progress-report.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEQHQXk7cSp7ImA9WxJXGE4.&quot;"><id>tag:blogger.com,1999:blog-1083890928935553699.post-2638054448112847234</id><published>2009-06-12T14:39:00.006-04:00</published><updated>2009-06-12T14:45:30.709-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-12T14:45:30.709-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="soc" /><category scheme="http://www.blogger.com/atom/ns#" term="facility data module" /><category scheme="http://www.blogger.com/atom/ns#" term="hfoss" /><category scheme="http://www.blogger.com/atom/ns#" term="openmrs" /><title>The long overdue progress report</title><content type="html">This is gonna be short, sweet and to the point:&lt;br /&gt;&lt;br /&gt;Week 1:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;I wrote a mock report form with 10 questions (screenshots in a later post)&lt;/li&gt;&lt;li&gt;I then wrote up some code to render it approriately for each question type.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Week 2 (still ongoing):&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Designed the SQL schema, and wrote the service/database layer classes for 2 of the classes.&lt;/li&gt;&lt;li&gt;Wrote in the functionality to save the report data to the database.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Will explain the design at a later date.&lt;br /&gt;&lt;br /&gt;Ciao!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1083890928935553699-2638054448112847234?l=robbyoconnor.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/robbyoconnor/~4/wtZGhe64C6A" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://robbyoconnor.blogspot.com/feeds/2638054448112847234/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1083890928935553699&amp;postID=2638054448112847234" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/2638054448112847234?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/2638054448112847234?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/robbyoconnor/~3/wtZGhe64C6A/long-overdue-progress-report.html" title="The long overdue progress report" /><author><name>Robert O'Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10413037710454370678" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://robbyoconnor.blogspot.com/2009/06/long-overdue-progress-report.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0QNRn05eSp7ImA9WxJTF08.&quot;"><id>tag:blogger.com,1999:blog-1083890928935553699.post-8690191771014302701</id><published>2009-04-21T00:11:00.010-04:00</published><updated>2009-04-26T01:56:37.321-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-26T01:56:37.321-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="foss" /><category scheme="http://www.blogger.com/atom/ns#" term="soc" /><category scheme="http://www.blogger.com/atom/ns#" term="openeverything" /><category scheme="http://www.blogger.com/atom/ns#" term="hfoss" /><category scheme="http://www.blogger.com/atom/ns#" term="openmrs" /><title>Open Everything NYC Recap</title><content type="html">I attended &lt;a href="http://nyc.openeverything.us"&gt;Open Everything NYC&lt;/a&gt; on Saturday. For those who do not know, Open Everything is an "un-conference" which is a conference where the participants run the show. There are several open sessions, and a few keynotes. &lt;br /&gt;&lt;br /&gt;Some of the open session topics were on education, Open Source Software licensing, and even relationships! The Open Relationships talk was really interesting. I find it amusing how many people wind up creating alter egos to prevent employers from finding out things about them.&lt;br /&gt;&lt;br /&gt;(Some of) the keynote speakers were amazing: &lt;br /&gt;&lt;br /&gt;Schuyler Erle, a guy who wrote some code for UNICEF, utilized text messaging as a means to track distribution of Bed Nets to prevent malaria via a web application, among other things. If you want to research this it's all on the &lt;a href="http://openeverything.wik.is/New_York/New_York_City"&gt;wiki&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Robert Steele, a former spy (yes a spy!) whose talk in my opinion was pretty much utterly useless! I saw diagrams which were well.. horrid. His talk had ZERO flow planning, it seemed to be a bunch of conspiracies, one after the other. Let alone the fact the guy is abrasive. After his talk, I went up to him to let him know that his site (which he linked in his talk), was down; his response was condescending and &lt;b&gt;RUDE&lt;/b&gt;. I turned to some people behind me as I was leaving, and said that there was no way I could have summarized anything that guy said (I was writing notes for the &lt;a href="http://openeverything.wik.is/New_York/New_York_City"&gt;wiki&lt;/a&gt;); they agreed. The consensus on Robert Steele was pretty universal: Conspiracy nutjob.&lt;br /&gt;&lt;br /&gt;The final speaker, Leslie Hawthorne, a woman I have a lot of respect for gave a talk that was short, sweet, and to the point. She disussed how open source software development can be used in a common sense way to solve complex problems we face. OpenMRS, solving the problem of the HIV/AIDS crisis in the developing world; Sahana for the disaster relief management in areas devastated by floods and such. Amazing talk! Best part, she did not use any slides! &lt;br /&gt;&lt;br /&gt;John Britton, the conference organizer gave the closing talk, and he took notes as to what should change next time. Longer open sessions etc came up. Additionally, we found out: it's possible to do this ongoing, I'd REALLY enjoy that. I met some freaking awesome people.&lt;br /&gt;&lt;br /&gt;We were to screen RIP: "A REMIX MANIFESTO" at McFaddens Bar and Pub by the UN, but the owner didn't allow us to do it; which was stupid. We wound up sitting around half price drinks/appetizers and had some good conversations and fun. &lt;br /&gt;&lt;br /&gt;Overall, I had fun and would do it again. I went into this not knowing what to expect.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1083890928935553699-8690191771014302701?l=robbyoconnor.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/robbyoconnor/~4/UJNSErV-lQE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://robbyoconnor.blogspot.com/feeds/8690191771014302701/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1083890928935553699&amp;postID=8690191771014302701" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/8690191771014302701?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/8690191771014302701?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/robbyoconnor/~3/UJNSErV-lQE/open-everything-nyc-recap.html" title="Open Everything NYC Recap" /><author><name>Robert O'Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10413037710454370678" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://robbyoconnor.blogspot.com/2009/04/open-everything-nyc-recap.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUMBRHw7fyp7ImA9WxJSEU4.&quot;"><id>tag:blogger.com,1999:blog-1083890928935553699.post-6947909951232620345</id><published>2009-04-20T17:05:00.012-04:00</published><updated>2009-04-30T19:17:35.207-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-30T19:17:35.207-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="open source" /><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="gsoc" /><category scheme="http://www.blogger.com/atom/ns#" term="facility data module" /><category scheme="http://www.blogger.com/atom/ns#" term="hfoss" /><category scheme="http://www.blogger.com/atom/ns#" term="openmrs" /><title>Accepted into Google Summer of Code 2009</title><content type="html">For the second year in a row, I was &lt;a href="http://twitter.com/robbyoconnor/status/1568071039"&gt;accepted&lt;/a&gt; into &lt;a href="http://socghop.appspot.com"&gt;Google Summer of Code&lt;/a&gt;!!! I will be working with &lt;a href="http://www.openmrs.org"&gt;OpenMRS&lt;/a&gt; on the &lt;a href="http://socghop.appspot.com/student_project/show/google/gsoc2009/openmrs/t124023038249"&gt;Facility Data Module&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;My project will focus on developing tools for collecting and ultimately generating reports for aggregate data from external sources.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1083890928935553699-6947909951232620345?l=robbyoconnor.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/robbyoconnor/~4/DA4nHYUNO_0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://robbyoconnor.blogspot.com/feeds/6947909951232620345/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1083890928935553699&amp;postID=6947909951232620345" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/6947909951232620345?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/6947909951232620345?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/robbyoconnor/~3/DA4nHYUNO_0/accepted-into-google-summer-of-code.html" title="Accepted into Google Summer of Code 2009" /><author><name>Robert O'Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10413037710454370678" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://robbyoconnor.blogspot.com/2009/04/accepted-into-google-summer-of-code.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0QHQ3Y_cCp7ImA9WxVXEU4.&quot;"><id>tag:blogger.com,1999:blog-1083890928935553699.post-1278017806932116731</id><published>2009-02-08T17:09:00.004-05:00</published><updated>2009-02-08T17:15:32.848-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-08T17:15:32.848-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="soc" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy forms module" /><category scheme="http://www.blogger.com/atom/ns#" term="google summer of code" /><category scheme="http://www.blogger.com/atom/ns#" term="openmrs" /><title>Groovy Forms Module is NOT dead</title><content type="html">Hey folks! &lt;br /&gt;&lt;br /&gt;I'm still alive and not dead. The Groovy Forms Module is not a dead project, and &lt;b&gt;WILL&lt;/b&gt; be finished. I plan on getting work started back up on it soonish. School is back in session for me. I'm sorry for the long delay.&lt;br /&gt;&lt;br /&gt;That is all.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1083890928935553699-1278017806932116731?l=robbyoconnor.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/robbyoconnor/~4/2s5t-ePPrCE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://robbyoconnor.blogspot.com/feeds/1278017806932116731/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1083890928935553699&amp;postID=1278017806932116731" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/1278017806932116731?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/1278017806932116731?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/robbyoconnor/~3/2s5t-ePPrCE/groovy-forms-module.html" title="Groovy Forms Module is NOT dead" /><author><name>Robert O'Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10413037710454370678" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://robbyoconnor.blogspot.com/2009/02/groovy-forms-module.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUYFSH8zfCp7ImA9WxRSEEg.&quot;"><id>tag:blogger.com,1999:blog-1083890928935553699.post-2335388825686052165</id><published>2008-09-10T10:02:00.004-04:00</published><updated>2008-09-10T10:31:59.184-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-09-10T10:31:59.184-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="groovy forms module" /><category scheme="http://www.blogger.com/atom/ns#" term="gsoc" /><category scheme="http://www.blogger.com/atom/ns#" term="google summer of code" /><category scheme="http://www.blogger.com/atom/ns#" term="openmrs" /><title>GSoC wrap-up</title><content type="html">The program officially ended on August 18&lt;sup&gt;th&lt;/sup&gt;. I'm awaiting the arrival of my t-shirt!! &lt;br /&gt;&lt;br /&gt;Now, I didn't quite have time to finish my project prior to that date since my uncle suddenly passed away on August 10&lt;sup&gt;th&lt;/sup&gt;.&lt;br /&gt;&lt;br /&gt;The project itself is about 80 percent completed. All that is left is to get the rendering working and finish up the management page to edit the form metadata as it appears in the system.&lt;br /&gt;&lt;br /&gt;My time is now limited since school started up again for me, so as much time as I can I'm going to devote to finishing up this project.&lt;br /&gt;&lt;br /&gt;I'd like to thank the following:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://blog.burkeware.com/"&gt;Burke Mamlin&lt;/a&gt; for helping me and answering all the questions I had and guiding me when I was lost.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://blog.eflow.org/"&gt;Ben Wolfe&lt;/a&gt; for putting up with me and helping me when &lt;a href="http://blog.burkeware.com/"&gt;Burke&lt;/a&gt; was MIA.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.openmrs.org/"&gt;OpenMRS&lt;/a&gt; and its wonderful worldwide network of developers for making this project into what it has become.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://docpaul.wordpress.com"&gt;Paul Biondich&lt;/a&gt; for encouraging me (along with &lt;a href="http://blog.burkeware.com"&gt;Burke&lt;/a&gt;) to apply for summer of code.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Last, but certainly not least, &lt;a href="http://www.hawthornlandings.org/"&gt;Leslie Hawthorn&lt;/a&gt; for managing this program and every problem that popped up. She must have super human powers or something.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;The list can only be so long, I feel like I'm accepting an academy award here. It was a great experience, and I will definately continue to maintain my project in whatever free time I can find.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1083890928935553699-2335388825686052165?l=robbyoconnor.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/robbyoconnor/~4/8HQ6DhHL_hc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://robbyoconnor.blogspot.com/feeds/2335388825686052165/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1083890928935553699&amp;postID=2335388825686052165" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/2335388825686052165?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/2335388825686052165?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/robbyoconnor/~3/8HQ6DhHL_hc/gsoc-wrap-up.html" title="GSoC wrap-up" /><author><name>Robert O'Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10413037710454370678" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://robbyoconnor.blogspot.com/2008/09/gsoc-wrap-up.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkMESHc5cCp7ImA9WxdbFEw.&quot;"><id>tag:blogger.com,1999:blog-1083890928935553699.post-6494743798965084334</id><published>2008-08-10T21:20:00.003-04:00</published><updated>2008-08-10T21:33:29.928-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-08-10T21:33:29.928-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="open source" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy forms module" /><category scheme="http://www.blogger.com/atom/ns#" term="gsoc" /><category scheme="http://www.blogger.com/atom/ns#" term="google summer of code" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy" /><category scheme="http://www.blogger.com/atom/ns#" term="openmrs" /><title>GSoC 2008: We're in the home stretch</title><content type="html">Well folks, I can't believe it's almost over. What a journey. I never imagined I'd be able to do this. I have an (almost) working project. I have a few more things that need to be done.&lt;br /&gt;&lt;br /&gt;Let's highlight what &lt;span style="font-weight: bold;"&gt;IS&lt;/span&gt; done:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;GroovyForm and its related metadata is stored&lt;/li&gt;&lt;li&gt;Model class is interrogated for its properties and those are stored in a container class.&lt;/li&gt;&lt;li&gt;From the data collected in the container class, I generate markup checking for a predefined set of data types.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The view and its related controller is generated -- sneaking in some groovy magic of course! &lt;/li&gt;&lt;li&gt;GroovyForms are successfully saved into the system, along with their respective, model, view and controller.&lt;/li&gt;&lt;li&gt;Forms are persisted when the module is shutdown and reloaded when it is restarted&lt;/li&gt;&lt;/ol&gt;What's left:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Editing metadata related to the forms currently in the system&lt;/li&gt;&lt;li&gt;Writing the servlet which handles submissions&lt;/li&gt;&lt;li&gt;Create some sample forms&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Documentation &lt;/li&gt;&lt;/ol&gt;I did plan to add a lot of other stuff such as the ability to create custom form widgets, however there were a few problems which caused me to redirect my focus. These will come in after I finish with Summer of Code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1083890928935553699-6494743798965084334?l=robbyoconnor.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/robbyoconnor/~4/lYYbZcZkIPA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://robbyoconnor.blogspot.com/feeds/6494743798965084334/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1083890928935553699&amp;postID=6494743798965084334" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/6494743798965084334?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/6494743798965084334?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/robbyoconnor/~3/lYYbZcZkIPA/gsoc-2008-were-in-home-stretch.html" title="GSoC 2008: We're in the home stretch" /><author><name>Robert O'Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10413037710454370678" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://robbyoconnor.blogspot.com/2008/08/gsoc-2008-were-in-home-stretch.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEMMQXs-eip7ImA9WxdUEU0.&quot;"><id>tag:blogger.com,1999:blog-1083890928935553699.post-4038809746169386198</id><published>2008-07-26T15:49:00.003-04:00</published><updated>2008-07-26T16:01:20.552-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-07-26T16:01:20.552-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="the last lecture" /><category scheme="http://www.blogger.com/atom/ns#" term="computer science. pausch" /><title>Randy Pausch dies</title><content type="html">I learned via the &lt;a href="http://googleresearch.blogspot.com"&gt;Official Google Research Blog&lt;/a&gt; that &lt;a href="http://download.srv.cs.cmu.edu/~pausch/"&gt;Randy Pausch&lt;/a&gt; died yesterday. Randy Pausch is famous for delivering a lecture entitled informally "&lt;a href="http://www.youtube.com/watch?v=ji5_MqicxSo"&gt;The Last Lecture: Really Achieving your Childhood dreams&lt;/a&gt;". Pausch was also a Computer Science professor at Carnegie Mellon University (CMU).&lt;br /&gt;&lt;br /&gt;He will be missed greatly. &lt;br /&gt;&lt;br /&gt;RIP Randy Pausch&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1083890928935553699-4038809746169386198?l=robbyoconnor.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/robbyoconnor/~4/Y7kljIAiW3Y" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://robbyoconnor.blogspot.com/feeds/4038809746169386198/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1083890928935553699&amp;postID=4038809746169386198" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/4038809746169386198?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/4038809746169386198?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/robbyoconnor/~3/Y7kljIAiW3Y/randy-pausch-dies.html" title="Randy Pausch dies" /><author><name>Robert O'Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10413037710454370678" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://robbyoconnor.blogspot.com/2008/07/randy-pausch-dies.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkQBRnw9eyp7ImA9WxdWEE8.&quot;"><id>tag:blogger.com,1999:blog-1083890928935553699.post-4086146737965789331</id><published>2008-07-02T02:47:00.015-04:00</published><updated>2008-07-02T13:39:17.263-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-07-02T13:39:17.263-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="open source" /><category scheme="http://www.blogger.com/atom/ns#" term="js" /><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="soc" /><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy forms module" /><category scheme="http://www.blogger.com/atom/ns#" term="gsoc" /><category scheme="http://www.blogger.com/atom/ns#" term="ajax" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy" /><category scheme="http://www.blogger.com/atom/ns#" term="openmrs" /><title>GSOC 2008: Week 5</title><content type="html">So, it's time for an update. This week got off to a sketchy start, but it's gained momentum. Let me enumerate what I have done thus far with the project. First, I've added AJAX using &lt;a href="http://www.jquery.com"&gt;jquery&lt;/a&gt;. I figured I would use jquery mainly because it provided painless AJAX goodness. Prior to even thinking of using jquery, I wrote my own AJAX code using &lt;a href="http://java.sun.com/developer/technicalArticles/J2EE/AJAX/RealtimeValidation/index.html"&gt;a tutorial&lt;/a&gt; that I found while googling. I had to tweak it a bit, but for the most part, it seemed very standard. However, after I wrote the AJAX equivalent code, it didn't feel too elegant. So, first I'm going to show the AJAX code I wrote; then I'll show you the jquery version; finally, I'm going to show you the servlet which handles the AJAX on the server-side. &lt;br /&gt;&lt;br /&gt;First, the AJAX I wrote: &lt;br /&gt;&lt;pre name="code" class="js"&gt;&lt;br /&gt; function AjaxValidation(url,callback) {&lt;br /&gt;        var req = init()&lt;br /&gt;        req.onreadystatechange = processRequest&lt;br /&gt;&lt;br /&gt;        function init() {&lt;br /&gt;            if(window.XMLHttpRequest) {&lt;br /&gt;                return new XMLHttpRequest()&lt;br /&gt;            } else if(window.ActiveXObject) {&lt;br /&gt;                return new ActiveXObject("Mircosoft.XMLHTTP")&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        function processRequest() {&lt;br /&gt;            if(req.readyState == 4) {&lt;br /&gt;                if(req.status == 200) {&lt;br /&gt;                    if(callback) {&lt;br /&gt;                        chkSyntaxCallBack(req.responseXML)&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        this.doGet = function() {&lt;br /&gt;            req.open("GET",url,true)&lt;br /&gt;            req.send(null)&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    function chkSyntaxCallBack(responseXML) {&lt;br /&gt;        var res = responseXML.getElementsByTagName("result")[0].firstChild.nodeValue&lt;br /&gt;        document.getElementById("out").innerHTML = res&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    function checkSyntax() {&lt;br /&gt;        var target = document.getElementById("groovyModel")&lt;br /&gt;        var url = "${pageContext.request.contextPath}/moduleServlet/groovyforms/createGroovyForm?groovyModel="+escape(target.value)&lt;br /&gt;        var ajax = new AjaxValidation(url, chkSyntaxCallBack)&lt;br /&gt;        ajax.doGet()&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I warned you that it wasn't too elegant. Understanding this isn't too hard. Here is the call sequence: &lt;code&gt;init() -&gt; doGet() -&gt; processRequest() -&gt; chkSyntaxCallBack()&lt;/code&gt;. Not that bad. Now let's see the jquery version.&lt;br /&gt;&lt;pre name="code" class="js"&gt;&lt;br /&gt;$(window).ready(function() {&lt;br /&gt;        $("#groovyModel").bind("blur",function() {&lt;br /&gt;            $.ajax({&lt;br /&gt;                type:'POST',&lt;br /&gt;                data: { groovyModel:$("#groovyModel").val() },&lt;br /&gt;                url:  "${pageContext.request.contextPath}/moduleServlet/groovyforms/createGroovyForm",&lt;br /&gt;                cache: false,&lt;br /&gt;                success: function(data) {&lt;br /&gt;                   var res = $(data).find("result").text()&lt;br /&gt;                   $("#out").html(res)&lt;br /&gt;&lt;br /&gt;                }&lt;br /&gt;            })&lt;br /&gt;      });&lt;br /&gt; })&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Okay, that's much better. A few things are still happening here. When the window is finished loading, I bind my textarea element which has the CSS id of "groovyModel" to the blur event (lost focus). Then you see the AJAX. Now this is very straight forward. We're using the &lt;strong&gt;POST&lt;/strong&gt; method, we're sending whatever value is inside of the textarea at the time the event is fired, we're posting to a servlet, not going to cache, and when we're done, it's printed to the screen. Very straight forward. &lt;br /&gt;&lt;br /&gt;Now, like I said, this is all backed on the server-side by a servlet, which is written in &lt;a href="http://groovy.codehaus.org"&gt;Groovy&lt;/a&gt;. So here we go: &lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;/**&lt;br /&gt; * The contents of this file are subject to the OpenMRS Public License&lt;br /&gt; * Version 1.0 (the "License") you may not use this file except in&lt;br /&gt; * compliance with the License. You may obtain a copy of the License at&lt;br /&gt; * http://license.openmrs.org&lt;br /&gt; *&lt;br /&gt; * Software distributed under the License is distributed on an "AS IS"&lt;br /&gt; * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the&lt;br /&gt; * License for the specific language governing rights and limitations&lt;br /&gt; * under the License.&lt;br /&gt; *&lt;br /&gt; * Copyright (C) OpenMRS, LLC.  All Rights Reserved.&lt;br /&gt; */&lt;br /&gt;package org.openmrs.module.groovyforms.web&lt;br /&gt;&lt;br /&gt;import javax.servlet.ServletException&lt;br /&gt;import javax.servlet.http.HttpServlet&lt;br /&gt;import javax.servlet.http.HttpServletRequest&lt;br /&gt;import javax.servlet.http.HttpServletResponse&lt;br /&gt;import org.apache.commons.logging.LogFactory&lt;br /&gt;import org.codehaus.groovy.control.CompilationFailedException&lt;br /&gt;&lt;br /&gt;class CreateGroovyFormServlet extends HttpServlet {&lt;br /&gt;    def classLoader&lt;br /&gt;    static final def log = LogFactory.getLog(CreateGroovyFormServlet.class)&lt;br /&gt;    private static final long serialVersionUID = 066373513262051L&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {&lt;br /&gt;        def generateTemplate = request.getParameter("template")&lt;br /&gt;        def generateController = request.getParameter("controller")&lt;br /&gt;        def finalMarkup = request.getParameter("markup")&lt;br /&gt;        def clazz = URLDecoder.decode(request.getParameter("groovyModel"))&lt;br /&gt;        def name = request.getParameter("formName")&lt;br /&gt;        def version = request.getParameter("version")&lt;br /&gt;        def res = this.checkSyntax(clazz)&lt;br /&gt;        if (clazz) {&lt;br /&gt;            if (checkSyntax(clazz)) {&lt;br /&gt;                response.contentType = "text/xml"&lt;br /&gt;                response.setHeader "Cache-Conrol", "no-cache"&lt;br /&gt;                response.writer.write "&lt;result&gt;\n\t$res\n&lt;/result&gt;"              &lt;br /&gt;            } else {&lt;br /&gt;                response.contentType = "text/xml"&lt;br /&gt;                response.setHeader "Cache-Control", "no-cache"&lt;br /&gt;                response.writer.write "&lt;result&gt;true&lt;/result&gt;"&lt;br /&gt;            }&lt;br /&gt;        } else {&lt;br /&gt;            response.contentType = "text/xml"&lt;br /&gt;            response.setHeader "Cache-Control", "no-cache"&lt;br /&gt;            response.writer.write "&lt;result&gt;\n\tPlease fill in the Form Model\n&lt;/result&gt;"&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {&lt;br /&gt;        doGet(request,response)&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    void init() throws ServletException {&lt;br /&gt;        if (log.infoEnabled)&lt;br /&gt;            log.info("Initializing...")&lt;br /&gt;        classLoader = getClassLoader()&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    def getClassLoader() {        &lt;br /&gt;        def gcl = new GroovyClassLoader(this.getClass().getClassLoader())&lt;br /&gt;        gcl&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * This method is used to relay errors to the user&lt;br /&gt;     * @param clazz  the class&lt;br /&gt;     * @return the exception message or null if it was successful&lt;br /&gt;     */&lt;br /&gt;    def checkSyntax(clazz) {&lt;br /&gt;        def sb = new StringBuilder()&lt;br /&gt;        sb &lt;&lt; "import org.openmrs.*\n\n\n"&lt;br /&gt;        sb &lt;&lt; clazz&lt;br /&gt;        def res = null&lt;br /&gt;        try {&lt;br /&gt;            getClassLoader().parseClass(sb.toString())&lt;br /&gt;&lt;br /&gt;        } catch (CompilationFailedException e) {&lt;br /&gt;            res = "Exception: ${e.message}"&lt;br /&gt;        }&lt;br /&gt;        res&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Check if it is result groovy code.&lt;br /&gt;     * @param clazz the class&lt;br /&gt;     * @return whether or not it is result groovy code&lt;br /&gt;     */&lt;br /&gt;    def isValidGroovy(clazz) {&lt;br /&gt;        def sb = new StringBuilder()&lt;br /&gt;        sb &lt;&lt; "import org.openmrs.*\n\n\n"&lt;br /&gt;        sb &lt;&lt; clazz&lt;br /&gt;        try {&lt;br /&gt;            getClassLoader().parseClass(sb.toString())&lt;br /&gt;        } catch (CompilationFailedException e) {&lt;br /&gt;            return false&lt;br /&gt;        }&lt;br /&gt;        return true&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This servlet contains a lot of utility methods. One compiles, one initializes/returns the &lt;a href="http://groovy.codehaus.org/gapi/groovy/lang/GroovyClassLoader.html"&gt;GroovyClassLoader&lt;/a&gt;, and of course doGet(), doPost() and init(). &lt;code&gt;doGet()&lt;/code&gt; and &lt;code&gt;doPost()&lt;/code&gt; both do the same thing, with doPost() simply delegating to doGet(). The code should be reasonably easy to understand. &lt;code&gt;checkSyntax()&lt;/code&gt; returns null if it was parsed cleanly, otherwise it returns the exception message, the stack track wouldn't be useful in my case. It returns an XML tag &amp;lt;result&amp;gt; with "true" if it was successful, the exception message if it was not, and a message stating that the field must be filled in if it's empty or just not passed in. I implicitly import &lt;code&gt;org.openmrs.*&lt;/code&gt; to allow for easier access to the OpenMRS domain model classes. The parent classloader for the GroovyClassLoader is set the servlet container's classloader. This gives me access to the classpath when loading Groovy classes. &lt;br /&gt;&lt;br /&gt;I still have a bit to do, templating needs to be written in, for the most part it's done. Just have a few problems I'm facing, but I'll get through it. Too many people are relying on me succeeding. I feel that this project could help a lot of people, so i feel pressure to succeed. I still need to write in the "Edit" functionality of the "Manage Groovy Forms" page.&lt;br /&gt;&lt;br /&gt;I'm definately making progress. More updates to come, that's for sure.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1083890928935553699-4086146737965789331?l=robbyoconnor.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/robbyoconnor/~4/hqbY2Dl2P3Q" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://robbyoconnor.blogspot.com/feeds/4086146737965789331/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1083890928935553699&amp;postID=4086146737965789331" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/4086146737965789331?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/4086146737965789331?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/robbyoconnor/~3/hqbY2Dl2P3Q/gsoc-2008-week-5.html" title="GSOC 2008: Week 5" /><author><name>Robert O'Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10413037710454370678" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://robbyoconnor.blogspot.com/2008/07/gsoc-2008-week-5.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUQDSHo6fyp7ImA9WxdXEEQ.&quot;"><id>tag:blogger.com,1999:blog-1083890928935553699.post-6882837065981235794</id><published>2008-06-21T18:48:00.010-04:00</published><updated>2008-06-21T20:09:39.417-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-06-21T20:09:39.417-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="soc" /><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="dwr" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy forms module" /><category scheme="http://www.blogger.com/atom/ns#" term="gsoc" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy" /><category scheme="http://www.blogger.com/atom/ns#" term="openmrs" /><title>GSoC 2008: Groovy Forms getting some AJAX!</title><content type="html">No, not the cleaning product! The "Web 2.0" kind of AJAX! Now where will this goodness be placed? The pages for creating the forms and managing the forms.&lt;br /&gt;&lt;br /&gt;First off, I used &lt;a href="http://www.directwebremoting.org/dwr"&gt;Direct Web Remoting (DWR)&lt;/a&gt; to provide a link between my backend java codebase and the front-end javascript! It's quite amazing. You can choose to publish/unpublish the forms with the tick of a checkbox and DWR will magically set the published attribute on the form to the proper state. I then decided to go one step furthur, and provide a mechanism to backup the forms via &lt;a href="http://xstream.codehaus.org/"&gt;xstream&lt;/a&gt; to XML. Now, with the XML files, two files are maintained, one individual XML file for each form, and one global one, which makes up the model for the entire system. The rationale for having the XML file for each form is that you can just zip up the form folder, and unzip it into another &lt;a href="http://www.openmrs.org/"&gt;OpenMRS&lt;/a&gt; install and you're good to go. Adding the ability to re-generate the XML files via the management interface is especially handle so that if you make a quick change on one system, then want to install it onto another you can.&lt;br /&gt;&lt;br /&gt;Now, &lt;a href="http://www.directwebremoting.org/dwr"&gt;DWR&lt;/a&gt; will be used for creating the forms as well. This will be done mostly to easily relay errors, such as syntax errors in the Controller and the Model of the &lt;a href="http://openmrs.org/wiki/GroovyForms_Module"&gt;groovy form&lt;/a&gt;. Don't fear, I'm going to go overboard with AJAX! It'll only be used up until the point of where templates are generated. After that point, a Servlet will take over the bulk of the work (I am undecided on the Servlet bit.).&lt;br /&gt;&lt;br /&gt;Now what's next? Several things need to happen.&lt;br /&gt;&lt;br /&gt;First, creating the form:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;We need to validate that form fields are not empty; also the input must be checked for validity.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The model's syntax needs to be compiled and syntax errors need to be relayed to the user.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;We need to get the fields of the class and store them.&lt;/li&gt;&lt;li&gt;We need to generate templates like: &lt;%= textArea(...); %&gt; -- They will not be run it through the template engine immediately until the user has confirmed what they want,&lt;/li&gt;&lt;li&gt;After the view has been tweaked -- it is run through the template engine; at this point we will also run the controller through and generate that and present it at the same time the final view is presented.&lt;/li&gt;&lt;li&gt;The user will be presented with the HTML of the view and &lt;a href="http://groovy.codehaus.org/"&gt;Groovy&lt;/a&gt; controller and given a final opportunity to tweak it before it is saved to the system.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The form is added to the system -- by default the form is not published.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Finally, to publish the form so that it can be used to enter data, they go to the management screen and tick the checkbox.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The form is now ready to be used for data entry.&lt;/li&gt;&lt;/ol&gt;Pictures are worth a thousand words so here we go: &lt;a href="http://img522.imageshack.us/img522/897/manageforms2mp5.png"&gt;One&lt;/a&gt; and &lt;a href="http://img103.imageshack.us/img103/4825/manageformsuc2.png"&gt;Two&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;First one contains one form which is published, the rest are not. The second, no forms are published.  &lt;br /&gt;&lt;br /&gt;The user interface is intuitive and easy to use. It's a great design, of course I'm biased since It was was me who designed it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1083890928935553699-6882837065981235794?l=robbyoconnor.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/robbyoconnor/~4/rabmfCgxqAA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://robbyoconnor.blogspot.com/feeds/6882837065981235794/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1083890928935553699&amp;postID=6882837065981235794" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/6882837065981235794?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/6882837065981235794?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/robbyoconnor/~3/rabmfCgxqAA/gsoc-2008-groovy-forms-getting-some.html" title="GSoC 2008: Groovy Forms getting some AJAX!" /><author><name>Robert O'Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10413037710454370678" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://robbyoconnor.blogspot.com/2008/06/gsoc-2008-groovy-forms-getting-some.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0UFSXw_fyp7ImA9WxdQFUw.&quot;"><id>tag:blogger.com,1999:blog-1083890928935553699.post-899389761943681110</id><published>2008-06-14T23:55:00.007-04:00</published><updated>2008-06-15T02:26:58.247-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-06-15T02:26:58.247-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="gsoc" /><category scheme="http://www.blogger.com/atom/ns#" term="openmrs" /><category scheme="http://www.blogger.com/atom/ns#" term="hypopara" /><title>GSoC 2008: Updates and such</title><content type="html">Okay, let's see what was accomplished in the past few weeks:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;I tweaked the domain class interrogation code a bit. Basically, now there is a 1:1 relationship between a field and the domain model metadata storage container class instance.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;I've started the templating work -- most of it right now is just methods which will be called like: &lt;%= textField(...) %&gt; -- that will generate a text field html form widget.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;I know I haven't accomplished much, but there's a reason, I swear!&lt;br /&gt;&lt;br /&gt;June 11th I went to Rockville, MD to the &lt;a href="http://hpth.org/"&gt;Hypoparathyroidism Association&lt;/a&gt;'s 3rd Annual Hypoparathyroidism Conference. I just got home tonight.&lt;br /&gt;&lt;br /&gt;Let me stray off a bit to explain what hypoparathyroidism is. Basically, the parathyroid is a gland in your neck, underneath the thyroid. Most people get it via surgical error, where the surgeon cuts out, or damages the parathyroid. When this occurs, the PTH (Parathyroid Hormone) is no longer produced. Now, this is responsible for regulating among other things, Calcium. Without this present, the calcium levels in the blood drop, and patients start to experience Tetnay, where their muscles involuntarily contract. It's not fun. If the levels drop low enough, you can go into convulsions, and ultimately seizures. Death is also a possibility, which is why it's important for patients with hypoparathyroidism to take their meds (Calcium Supplements, sometimes Magnesium, Vitamin D (usually D2 or D3), and a medication which is the active form of Vitamin D called Calcitriol.) Some patients also take other meds as well. These must be continued for the rest of their lives. I got Hypoparathyroidism idiopathically -- which means the origin nor the cause is known.&lt;br /&gt;&lt;br /&gt;Back to the point: I was at this conference, and it's such a rare disease that I don't know many people. So I wound up talking with the people there. As a result, not much work was done. Monday, I plan to get the templating working, then probably do some Front end UI work.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1083890928935553699-899389761943681110?l=robbyoconnor.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/robbyoconnor/~4/Nu0De0GHyJA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://robbyoconnor.blogspot.com/feeds/899389761943681110/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1083890928935553699&amp;postID=899389761943681110" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/899389761943681110?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/899389761943681110?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/robbyoconnor/~3/Nu0De0GHyJA/gsoc-2008-updates-and-such.html" title="GSoC 2008: Updates and such" /><author><name>Robert O'Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10413037710454370678" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://robbyoconnor.blogspot.com/2008/06/gsoc-2008-updates-and-such.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU8CRng6fCp7ImA9WxdQEUg.&quot;"><id>tag:blogger.com,1999:blog-1083890928935553699.post-1326549730017982636</id><published>2008-06-11T00:04:00.005-04:00</published><updated>2008-06-11T00:17:47.614-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-06-11T00:17:47.614-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="soc" /><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="ant" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy" /><category scheme="http://www.blogger.com/atom/ns#" term="openmrs" /><title>Well, that's so NOT groovy</title><content type="html">So, I was working on my &lt;a href="http://openmrs.org/wiki/GroovyForms_Module"&gt;summer of code project&lt;/a&gt;, and I have groovy code along side my java code. I needed to add the &lt;a href="http://groovy.codehaus.org/The+groovyc+Ant+Task"&gt;groovyc&lt;/a&gt; ant task. While i assumed that groovy-&lt;b&gt;all&lt;/b&gt;-1.5.6.jar, (note the &lt;b&gt;all&lt;/b&gt;) contained everything that was needed, guess what folks, it doesn't! I spent the greater part of the evening tracking down this problem, and then i added the &lt;b&gt;ant-1.7.0.jar&lt;/b&gt; and &lt;b&gt;ant-launcher.jar&lt;/b&gt; jars, after that suddenly everything worked. That begs the question though, why isn't everything included in the groovy jar?&lt;br /&gt;&lt;br /&gt;The problem: NoClassDefFoundError on &lt;a href="http://dpml.net/api/ant/1.7.0/org/apache/tools/ant/taskdefs/MatchingTask.html"&gt;MatchingTask&lt;/a&gt; class. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I figured I would put this out there for others in case they too experience what I did.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1083890928935553699-1326549730017982636?l=robbyoconnor.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/robbyoconnor/~4/La9YFl-ISbk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://robbyoconnor.blogspot.com/feeds/1326549730017982636/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1083890928935553699&amp;postID=1326549730017982636" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/1326549730017982636?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/1326549730017982636?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/robbyoconnor/~3/La9YFl-ISbk/wellthats-so-not-groovy.html" title="Well, that's so NOT groovy" /><author><name>Robert O'Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10413037710454370678" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://robbyoconnor.blogspot.com/2008/06/wellthats-so-not-groovy.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE4NQ3k8fip7ImA9WxdREkw.&quot;"><id>tag:blogger.com,1999:blog-1083890928935553699.post-1922241087289487880</id><published>2008-05-31T00:48:00.007-04:00</published><updated>2008-05-31T02:56:32.776-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-31T02:56:32.776-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="open source" /><category scheme="http://www.blogger.com/atom/ns#" term="soc" /><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="closures" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy forms module" /><category scheme="http://www.blogger.com/atom/ns#" term="gsoc" /><category scheme="http://www.blogger.com/atom/ns#" term="google summer of code" /><category scheme="http://www.blogger.com/atom/ns#" term="google" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy" /><category scheme="http://www.blogger.com/atom/ns#" term="openmrs" /><title>GSoC 2008: Week 1</title><content type="html">Okay, week 1 is nearing an end.I accomplished alot of things. &lt;br /&gt;&lt;br /&gt;First, I &lt;a href="http://robbyoconnor.blogspot.com/2008/05/gsoc-2008-progress-report.html"&gt;completed the meta-data storage code&lt;/a&gt;. I wrote some tests, which revealed some bugs that needed fixing, and they were. I am happy to say, that the metadata storage works! &lt;br /&gt;&lt;br /&gt;Writing the test was difficult due to the fact I store the forms in the system using a static List in my &lt;a href="http://dev.openmrs.org/browser/openmrs-modules/groovyforms/src/org/openmrs/module/groovyforms/metadata/model/GroovyFormsContainer.java"&gt;container class&lt;/a&gt;. I wound up updating to &lt;a href="http://www.junit.org"&gt;JUnit 4&lt;/a&gt; to get at the &lt;a href="http://junit.sourceforge.net/javadoc_40/org/junit/BeforeClass.html"&gt;@BeforeClass&lt;/a&gt; annotation so that the only one set of forms gets loaded into the container class. This helped me greatly. Additionally, the &lt;a href"http://junit.sourceforge.net/javadoc_40/org/junit/AfterClass.html"&gt;@AfterClass&lt;/a&gt; annotation was handy for cleaning up from the tests.&lt;br /&gt;&lt;br /&gt;Secondly, Writing the code for interrogating the model was a piece of cake, thanks to &lt;a href="http://groovy.codehaus.org"&gt;groovy&lt;/a&gt;. All code for interrogating the model has 50 lines! That includes a model class I wrote to hold the field types and field names. I'll show you, but before I do, I should note that return statements are optional, and the final statement will be returned.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;package org.openmrs.module.groovyforms.util&lt;br /&gt;&lt;br /&gt;import java.lang.reflect.Field&lt;br /&gt;import org.openmrs.module.groovyforms.metadata.model.GroovyFormsDomainModel&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * Utility class containing methods for class interrogation.&lt;br /&gt; */&lt;br /&gt;class GroovyFormsClassUtil {&lt;br /&gt;    /**&lt;br /&gt;     * Interrogates the class for all declared fields and&lt;br /&gt;     * stores the type and name in a container class&lt;br /&gt;     * @param the {@link Class#getCanonicalName() canonical name of the class}&lt;br /&gt;     * @see Class#getCanonicalName()&lt;br /&gt;     * @return a reference to a container class containing the type&lt;br /&gt;     */&lt;br /&gt;    static def getModel(fields) {&lt;br /&gt;        def domainModel = new GroovyFormsDomainModel()&lt;br /&gt;        def names = domainModel.fieldNames.&amp;add&lt;br /&gt;        def types = domainModel.fieldTypes.&amp;add&lt;br /&gt;        def f = fields.each {Field field -&gt;&lt;br /&gt;            names field.name&lt;br /&gt;            types field.type.canonicalName&lt;br /&gt;        }&lt;br /&gt;        domainModel&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;With groovy, it's so easy and concise (as you can see). Let's explain what's going on. First, I pass in the Field array I get from &lt;a href="http://java.sun.com/javase/6/docs/api/java/lang/Class.html#getDeclaredFields()"&gt;Field.getDeclaredFields()&lt;/a&gt;. Now, groovy adds methods onto the standard JDK classes, one of those methods is a method named each() which takes a &lt;a href="http://groovy.codehaus.org/Closures"&gt;closure&lt;/a&gt;. Now, back to the point, I pass a &lt;a href="http://java.sun.com/javase/6/docs/api/java/lang/reflect/Field.html"&gt;Field&lt;/a&gt; into the closure. That closure is executed for each element (in this case, a Field). Then I add the name, and the type to a List stored in a container class, now that container class is also written in groovy! &lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;package org.openmrs.module.groovyforms.metadata.model&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * Ths class holds information about the properties of the model. &lt;br /&gt; */&lt;br /&gt;class GroovyFormsDomainModel {&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * The field names&lt;br /&gt;     */&lt;br /&gt;    def fieldNames = []&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * The field types&lt;br /&gt;     */&lt;br /&gt;    def fieldTypes = []&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now, the fields are Lists, not arrays. Anyways, I've gotten off on a tangent here, so let me get back on track. &lt;br /&gt;&lt;br /&gt;What I accomplished:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;u&gt;&lt;b&gt;Week 1&lt;/b&gt;:&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;Code to generate the directory structure, serialization of metadata back/forth between XML and POJOs (Plain Old Java Objects), Wrote tests to ensure everything works in that regard. Additionally, I wrote the code to interrogate the domain model which I will generate the forms from. &lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;u&gt;&lt;b&gt;Next Week&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;Write up the templates for the view/controller and write code to do the generation of the view/controller. Write some tests to ensure everything generates correctly. &lt;br /&gt;&lt;br /&gt;Unrelated to that, my stored-value card from google came today. It feels nice to be $500 richer! This is going to be the best summer, I'm already having fun doing this. It's amazing seeing the whole project evolve into something amazing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1083890928935553699-1922241087289487880?l=robbyoconnor.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/robbyoconnor/~4/T-Y2kDPwxAk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://robbyoconnor.blogspot.com/feeds/1922241087289487880/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1083890928935553699&amp;postID=1922241087289487880" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/1922241087289487880?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/1922241087289487880?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/robbyoconnor/~3/T-Y2kDPwxAk/gsoc-2008-week-1.html" title="GSoC 2008: Week 1" /><author><name>Robert O'Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10413037710454370678" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://robbyoconnor.blogspot.com/2008/05/gsoc-2008-week-1.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEUNRno-eSp7ImA9WxdREEk.&quot;"><id>tag:blogger.com,1999:blog-1083890928935553699.post-1908500793546013344</id><published>2008-05-29T00:58:00.008-04:00</published><updated>2008-05-29T03:31:37.451-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-29T03:31:37.451-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="regexp" /><category scheme="http://www.blogger.com/atom/ns#" term="gsoc" /><category scheme="http://www.blogger.com/atom/ns#" term="google summer of code" /><category scheme="http://www.blogger.com/atom/ns#" term="regex" /><category scheme="http://www.blogger.com/atom/ns#" term="regular expressions" /><category scheme="http://www.blogger.com/atom/ns#" term="openmrs" /><title>GSoC 2008: Progress report</title><content type="html">I have made a lot of &lt;a href="http://openmrs.org/wiki/GroovyForms_Module#Completed_Goals"&gt;progress&lt;/a&gt; on my &lt;a href="http://code.google.com/soc/2008"&gt;Google Summer of Code&lt;/a&gt; &lt;a href="http://openmrs.org/wiki/GroovyForms_Module"&gt;Project&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;First, I've completed the code for the generation of the directory structure for the forms. This is done using the form id, which is the name with all illegal characters removed. The only valid characters left are alpha-numeric and periods. Let me tell you, the regular expression to replace all of those characters was hell to write. But, thanks to the help of &lt;a href="http://openactive.org"&gt;Jason Davis&lt;/a&gt;, I was able to make it much more readable and easier digest. You've gotta see it to get an idea of how bad it was, so here goes: &lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;   /**&lt;br /&gt;     * Removes all illegal characters, then removes all spaces and makes it all lower-case.&lt;br /&gt;     *&lt;br /&gt;     * @param str the form name&lt;br /&gt;     * @return a viable form id.&lt;br /&gt;     */&lt;br /&gt;    public static String formNameToFormId(String str) {&lt;br /&gt;        return str.replaceAll("[\\$\\(\\)%`~!@#&amp;;:\\^=\\+\\?&lt;&gt;\"\\*\\\\////\\\\{\\}'\\]\\[\\|\\s+]", "").toLowerCase();&lt;br /&gt;   &lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;That is pretty much hell on earth to read, and it was hell on earth to type. Here's the *MUCH* simpler version:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="Java"&gt;&lt;br /&gt;   /**&lt;br /&gt;     * Removes all illegal characters, then removes all spaces and makes it all lower-case.&lt;br /&gt;     *&lt;br /&gt;     * @param str the form name&lt;br /&gt;     * @return a viable form id.&lt;br /&gt;     */&lt;br /&gt;    public static String formNameToFormId(String str) {&lt;br /&gt;        return str.replaceAll("[^a-zA-Z0-9.]", "").toLowerCase();&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Note, you can clearly see that i'm negating that entire sequence. It does the &lt;b&gt;SAME&lt;/b&gt; thing, but is MUCH more readable. That reads: "replace everything that isn't a letter from A to Z *OR* a to z(lower case letters) *OR* from 0 through 9 *OR* a period. Whereas the above just excluded the invalid characters explicitly but was a MONSTER of a regular expression.&lt;br /&gt;&lt;br /&gt;Secondly, metadata persistence is written in, I'm using &lt;a href="http://xstream.codehaus.org"&gt;xstream&lt;/a&gt;. It's a great tool for XML serialization. &lt;br /&gt;&lt;br /&gt;That's it. Oh, by the way, these are the things I earmarked TWO WEEKS FOR! Now, I push domain class model processing up, will work on that tomorrow.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1083890928935553699-1908500793546013344?l=robbyoconnor.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/robbyoconnor/~4/RiYfNHBz4Fk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://robbyoconnor.blogspot.com/feeds/1908500793546013344/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1083890928935553699&amp;postID=1908500793546013344" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/1908500793546013344?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/1908500793546013344?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/robbyoconnor/~3/RiYfNHBz4Fk/gsoc-2008-progress-report.html" title="GSoC 2008: Progress report" /><author><name>Robert O'Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10413037710454370678" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://robbyoconnor.blogspot.com/2008/05/gsoc-2008-progress-report.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkACRHs-fyp7ImA9WxdSGEs.&quot;"><id>tag:blogger.com,1999:blog-1083890928935553699.post-5526046742590167002</id><published>2008-05-27T00:43:00.012-04:00</published><updated>2008-05-27T02:12:45.557-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-27T02:12:45.557-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="soc" /><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy forms module" /><category scheme="http://www.blogger.com/atom/ns#" term="gsoc" /><category scheme="http://www.blogger.com/atom/ns#" term="google summer of code" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy" /><category scheme="http://www.blogger.com/atom/ns#" term="openmrs" /><title>Ready...Set...Code: Google Summer of Code has started!</title><content type="html">Today was the official start of &lt;a href="http://code.google.com/soc/2008"&gt;Google Summer of Code 2008 &lt;/a&gt;  Hopefully everybody is finding it a pleasant experience. I have yet to start coding as today was a US Holiday (Memorial Day). &lt;br /&gt;&lt;br /&gt;The project plan for the summer has been finalized. I decided to set two-week blocks, rather than do a weekly thing. I chose this, as it's extremely flexible and can scale items either back or forward.&lt;br /&gt;&lt;br /&gt;The project plan can be found &lt;a href="http://openmrs.org/wiki/GroovyForms_Module#Project_Plan"&gt;here&lt;/a&gt;. A Google Doc which &lt;a href="http://burkeware.com"&gt;my mentor&lt;/a&gt; and I used to plan the project can be found &lt;a href="http://docs.google.com/Doc?docid=df8w66j7_7c5n48z58&amp;hl=en"&gt;here&lt;/a&gt;. Finally, See &lt;a href="http://robbyoconnor.blogspot.com/2008/05/google-summer-of-code-status-report.html"&gt;my general plan&lt;/a&gt; written as a previous blog post. &lt;br /&gt;&lt;br /&gt;Best of luck to all the summer of code students!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1083890928935553699-5526046742590167002?l=robbyoconnor.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/robbyoconnor/~4/txajGHD5P3U" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://robbyoconnor.blogspot.com/feeds/5526046742590167002/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1083890928935553699&amp;postID=5526046742590167002" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/5526046742590167002?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/5526046742590167002?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/robbyoconnor/~3/txajGHD5P3U/readysetcode-google-summer-of-code-has.html" title="Ready...Set...Code: Google Summer of Code has started!" /><author><name>Robert O'Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10413037710454370678" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://robbyoconnor.blogspot.com/2008/05/readysetcode-google-summer-of-code-has.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0AEQXg7cCp7ImA9WxdSGEw.&quot;"><id>tag:blogger.com,1999:blog-1083890928935553699.post-2574777941824550177</id><published>2008-05-20T12:22:00.004-04:00</published><updated>2008-05-26T12:35:00.608-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-26T12:35:00.608-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="gsoc" /><category scheme="http://www.blogger.com/atom/ns#" term="openmrs" /><title>Thank you so much Google!!</title><content type="html">Today I got the coveted "Google Book" that all &lt;a href="http://code.google.com/soc/2008/"&gt;Google Summer of Code&lt;/a&gt; students have been talking about constantly! I've flipped through it, it's an amazing book! Want to know the name? Everybody knows it already, it's "Beautiful Code" by O'Reilly. &lt;br /&gt;&lt;br /&gt;Thank you so much!!!!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1083890928935553699-2574777941824550177?l=robbyoconnor.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/robbyoconnor/~4/oPYaTBH5haw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://robbyoconnor.blogspot.com/feeds/2574777941824550177/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1083890928935553699&amp;postID=2574777941824550177" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/2574777941824550177?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/2574777941824550177?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/robbyoconnor/~3/oPYaTBH5haw/thank-you-so-much-google.html" title="Thank you so much Google!!" /><author><name>Robert O'Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10413037710454370678" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://robbyoconnor.blogspot.com/2008/05/thank-you-so-much-google.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUINQHs5fyp7ImA9WxdSEkw.&quot;"><id>tag:blogger.com,1999:blog-1083890928935553699.post-6006389286474639624</id><published>2008-05-19T01:23:00.012-04:00</published><updated>2008-05-19T12:13:11.527-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-19T12:13:11.527-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="open source" /><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="dwr" /><category scheme="http://www.blogger.com/atom/ns#" term="gsoc" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy" /><category scheme="http://www.blogger.com/atom/ns#" term="openmrs" /><title>Google Summer of Code Status Report</title><content type="html">I haven't really blogged since I last &lt;a href="http://robbyoconnor.blogspot.com/2008/04/accepted-to-google-summer-of-code.html"&gt;announced&lt;/a&gt; that I was accepted into &lt;a href="http://code.google.com/soc/2008"&gt;Google Summer of Code&lt;/a&gt;. I have a phone meeting with &lt;a href="http://burkeware.com/blog"&gt;my mentor&lt;/a&gt; to bang out a project plan, I more or less have a general idea of how I want things to go, and he does too. Overall, it should be a very successful summer.&lt;br /&gt;&lt;br /&gt;I've been enjoying the &lt;a href="http://googlesummerofcode.blogspot.com/2007/04/so-what-is-this-community-bonding-all.html"&gt;Community Bonding&lt;/a&gt; period. I have made a lot of friends. My fellow summer of coders are amazing. I planned a potential meet-up for google soc'ers from NY, NJ and CT (to be announced formally when it is more concrete).&lt;br /&gt;&lt;br /&gt;Now, onto the fun part, telling you all about my project and how I plan on doing it. I'm gonna break this down. There's a lot of things that need to happen. A lot of data needs to be passed between the front and back ends. &lt;br /&gt;&lt;br /&gt;Firstly, &lt;a href="http://getahead.org/dwr/"&gt;Direct Web Remoting (DWR)&lt;/a&gt; will be used to grab all the information the users enter into the &lt;a href="http://img412.imageshack.us/img412/6167/openmrsjr4.png"&gt;form&lt;/a&gt; and forwards it to the backend whose job it is to generate the form, and then relay it back to the user showing them the result, then saving it to the system. DWR will also be used to provide some AJAX magic.  &lt;br /&gt;&lt;br /&gt;Then, after I have the data, I need to use &lt;a href="http://java.sun.com/docs/books/tutorial/reflect/"&gt;reflection&lt;/a&gt; on the Form Model and based on the data type, using a templating engine, such as &lt;a href="http://velocity.apache.org"&gt;Velocity&lt;/a&gt; generate HTML form components.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;String, etc&lt;/b&gt;: text field or text area; Using some Groovy &lt;a href="http://groovy.codehaus.org/ExpandoMetaClass"&gt;ExpandoMetaClass&lt;/a&gt; magic will aid in deciding if we use a text field or text area.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;List&lt;/b&gt;: drop-select select box&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Boolean&lt;/b&gt;: radio or checkbox with some Groovy &lt;a href="http://groovy.codehaus.org/ExpandoMetaClass"&gt;ExpandoMetaClass&lt;/a&gt; magic, i'll add a property which will help aid in deciding which one to use. &lt;br /&gt;&lt;br /&gt;After the form is generated, a controller will be generated with default checks that the fields are not empty. This will also be done using &lt;a href="http://velocity.apache.org"&gt;Velocity&lt;/a&gt; for templating.&lt;br /&gt;&lt;br /&gt;Once I have everything generated, it will be saved on the file system someplace with an associated XML file containing all metadata(title,version, description,etc) which will be read in by the system when showing which forms are in the system.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1083890928935553699-6006389286474639624?l=robbyoconnor.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/robbyoconnor/~4/iPglTfmmm2I" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://robbyoconnor.blogspot.com/feeds/6006389286474639624/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1083890928935553699&amp;postID=6006389286474639624" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/6006389286474639624?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/6006389286474639624?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/robbyoconnor/~3/iPglTfmmm2I/google-summer-of-code-status-report.html" title="Google Summer of Code Status Report" /><author><name>Robert O'Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10413037710454370678" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://robbyoconnor.blogspot.com/2008/05/google-summer-of-code-status-report.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkMFQHg8fSp7ImA9WxdTF0Q.&quot;"><id>tag:blogger.com,1999:blog-1083890928935553699.post-2814660682843050375</id><published>2008-05-14T16:17:00.004-04:00</published><updated>2008-05-14T16:53:31.675-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-14T16:53:31.675-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="open source" /><category scheme="http://www.blogger.com/atom/ns#" term="foss" /><category scheme="http://www.blogger.com/atom/ns#" term="bus factor" /><category scheme="http://www.blogger.com/atom/ns#" term="gsoc" /><category scheme="http://www.blogger.com/atom/ns#" term="openmrs" /><title>Bus Factor in Open Source Software Development</title><content type="html">&lt;a href="http://www.hawthornlandings.org"&gt;Leslie Hawthorne&lt;/a&gt; posted an interested thread to the &lt;a href="http://code.google.com/soc/2008"&gt;Google Summer of Code&lt;/a&gt; Student's List regarding the &lt;a href="http://en.wikipedia.com/wiki/Bus_Factor"&gt;Bus Factor&lt;/a&gt; and the related &lt;a href="http://en.wikipedia.org/wiki/Single_point_of_failure"&gt;Single point of failure&lt;/a&gt;.It presents a large problem in FOSS development. &lt;br /&gt;&lt;br /&gt;She posed the following questions: &lt;br /&gt;&lt;br /&gt;1) Do you see the bus factor as a problem in Open Source in general?&lt;br /&gt;How about for your project?&lt;br /&gt;&lt;br /&gt;2) Do you think that the bottlenecks result from having too few people&lt;br /&gt;involved in a project?  How do those bottlenecks get resolved if it is&lt;br /&gt;hard to bring on newcomers due to bottlenecks?&lt;br /&gt;&lt;br /&gt;3) What parallels can you draw between the concept of the bus factor,&lt;br /&gt;socially speaking, and reliability engineering?&lt;br /&gt;&lt;br /&gt;The best example of how it is a problem in open source can be explained by the saga of &lt;a href="http://en.wikipedia.org/Hans_Reiser"&gt;Hans Reiser&lt;/a&gt;, whom everybody knows killed his wife. He is the lead developer on &lt;a href="http://en.wikipedia.org/ReiserFS"&gt;ReiserFS&lt;/a&gt;. Now with him in prison, there is a good chance that ReiserFS will now slowly die due to his incarceration.  &lt;br /&gt;&lt;br /&gt;Imagine for a moment if you will, that &lt;a href="http://en.wikipedia.org/Linus_Torvalds"&gt;Linus Torvalds&lt;/a&gt; got hit by a bus or something related to that. What would happen to the &lt;a href="http://en.wikipedia.org/wiki/Linux"&gt;Linux&lt;/a&gt; Kernel? Well, it would probably not die, but it would be a HUGE hit since he is the one who leads the development. Would it die? Probably not. The Bus Factor for linux is pretty low. &lt;br /&gt;&lt;br /&gt;As for my &lt;a href="http://www.openmrs.org/wiki/GroovyForms_Module"&gt;Summer of Code project&lt;/a&gt;, the Bus Factor would be high. Since I am the primary developer.&lt;br /&gt;&lt;br /&gt;Applying this socially, every organization is ultimately led by the vision of one person, and usually there are safeties in place to prevent the Bus Factor from even becoming an issue. So this really can't be applied socially in my opinion. &lt;b&gt;BUT&lt;/b&gt; if Google were eliminated, Summer of Code would cease to exist. So I suppose it could be applied.&lt;br /&gt;&lt;br /&gt;The success and potential failure is usually dependent on one person (or a select few in some cases). Again, referencing Hans Reiser, his project will now most likely fail, may not; but the probability is high. This is the same across all industries. &lt;br /&gt;&lt;br /&gt;Now, does anybody else have answers regarding this topic?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1083890928935553699-2814660682843050375?l=robbyoconnor.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/robbyoconnor/~4/ykh2URUJej4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://robbyoconnor.blogspot.com/feeds/2814660682843050375/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1083890928935553699&amp;postID=2814660682843050375" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/2814660682843050375?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/2814660682843050375?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/robbyoconnor/~3/ykh2URUJej4/bus-factor-in-open-source-software.html" title="Bus Factor in Open Source Software Development" /><author><name>Robert O'Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10413037710454370678" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://robbyoconnor.blogspot.com/2008/05/bus-factor-in-open-source-software.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEEHR305eSp7ImA9WxdTEU0.&quot;"><id>tag:blogger.com,1999:blog-1083890928935553699.post-3638032177119491713</id><published>2008-05-06T15:17:00.015-04:00</published><updated>2008-05-06T15:37:16.321-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-06T15:37:16.321-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="gsoc" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy" /><category scheme="http://www.blogger.com/atom/ns#" term="openmrs" /><title>Posting code made easier (for everybody else reading your blog!)</title><content type="html">I've noticed something while reading my daily blogs, a lot of code is just unreadable because most blog systems (blogger looking at you), screw up indentation, unless you wrap it in a pre tag (opening and closing are both required. This makes it readable for your readers! I've left comments on the blogs that didn't know this, and now they do. &lt;br /&gt;&lt;br /&gt;This message is primarily for the &lt;a href="http://code.google.com/soc/2008"&gt;Google Summer of Code&lt;/a&gt; students, but is useful to the programming community as a whole. When you post code, wrap it in a pre tag and be sure to close them when your code example is complete.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1083890928935553699-3638032177119491713?l=robbyoconnor.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/robbyoconnor/~4/hyyBJr-EODg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://robbyoconnor.blogspot.com/feeds/3638032177119491713/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1083890928935553699&amp;postID=3638032177119491713" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/3638032177119491713?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/3638032177119491713?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/robbyoconnor/~3/hyyBJr-EODg/posting-code-made-easier-for-everybody.html" title="Posting code made easier (for everybody else reading your blog!)" /><author><name>Robert O'Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10413037710454370678" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://robbyoconnor.blogspot.com/2008/05/posting-code-made-easier-for-everybody.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkUGQXg7eSp7ImA9WxZaF0Q.&quot;"><id>tag:blogger.com,1999:blog-1083890928935553699.post-1647865295629859372</id><published>2008-05-03T00:45:00.003-04:00</published><updated>2008-05-03T00:50:20.601-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-03T00:50:20.601-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="groovy" /><title>Groovy 1.6-beta-1 released!</title><content type="html">So, i read that &lt;a href="http://groovy.codehaus.org"&gt;groovy&lt;/a&gt; &lt;a href="http://glaforge.free.fr/weblog/index.php?itemid=241"&gt;released&lt;/a&gt; 1.6-beta-1. They kept the &lt;a href="http://robbyoconnor.blogspot.com/2008/04/new-groovy-mixins-syntax.html"&gt;mixins syntax&lt;/a&gt; that was added. I love the new syntax, it's easy to use, and concise as well. &lt;br /&gt;&lt;br /&gt;Congrats to the Groovy team! Great Job!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1083890928935553699-1647865295629859372?l=robbyoconnor.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/robbyoconnor/~4/Chl_6YuLt0Q" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://robbyoconnor.blogspot.com/feeds/1647865295629859372/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1083890928935553699&amp;postID=1647865295629859372" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/1647865295629859372?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/1647865295629859372?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/robbyoconnor/~3/Chl_6YuLt0Q/groovy-16-beta-1-released.html" title="Groovy 1.6-beta-1 released!" /><author><name>Robert O'Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10413037710454370678" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://robbyoconnor.blogspot.com/2008/05/groovy-16-beta-1-released.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkUFSHo7cCp7ImA9WxZbGU8.&quot;"><id>tag:blogger.com,1999:blog-1083890928935553699.post-6816667694990176960</id><published>2008-04-21T16:09:00.004-04:00</published><updated>2008-04-23T00:16:59.408-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-04-23T00:16:59.408-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="soc" /><category scheme="http://www.blogger.com/atom/ns#" term="gsoc" /><category scheme="http://www.blogger.com/atom/ns#" term="google" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy" /><category scheme="http://www.blogger.com/atom/ns#" term="openmrs" /><title>Accepted to google summer of code!</title><content type="html">I was accepted to participate in &lt;a href="http://code.google.com/soc/2008"&gt;Google Summer of Code&lt;/a&gt;. I will be blogging regularly about my progress. The project I will be working is a &lt;a href="http://groovy.codehaus.org"&gt;Groovy&lt;/a&gt; Forms Module, which will enable administrators of &lt;a href="http://www.openmrs.org"&gt;OpenMRS&lt;/a&gt; to quickly create forms along with HTML and controllers. I think it will be a fun experience.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1083890928935553699-6816667694990176960?l=robbyoconnor.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/robbyoconnor/~4/pyFjG43KdOk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://robbyoconnor.blogspot.com/feeds/6816667694990176960/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1083890928935553699&amp;postID=6816667694990176960" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/6816667694990176960?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/6816667694990176960?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/robbyoconnor/~3/pyFjG43KdOk/accepted-to-google-summer-of-code.html" title="Accepted to google summer of code!" /><author><name>Robert O'Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10413037710454370678" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://robbyoconnor.blogspot.com/2008/04/accepted-to-google-summer-of-code.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0cASHo8eyp7ImA9WxZbFE8.&quot;"><id>tag:blogger.com,1999:blog-1083890928935553699.post-9170781011449436424</id><published>2008-04-09T01:29:00.007-04:00</published><updated>2008-04-17T04:30:49.473-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-04-17T04:30:49.473-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="catagories" /><category scheme="http://www.blogger.com/atom/ns#" term="mixins" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy" /><title>The new groovy mixins syntax</title><content type="html">Today, I read &lt;a href="http://archive.groovy.codehaus.org/dev/4cf0f24c0804081656l5aed67b5hf34fc73cbea375b0%40mail.gmail.com"&gt;this&lt;/a&gt; post to the groovy dev list and felt the strong urge to play with it. Now to use this, you'll need to compile the groovy code from the trunk in their subversion repository. Read &lt;a href="http://groovy.codehaus.org/Building+Groovy+from+Source"&gt;the tutorial&lt;/a&gt; about how to build from source. To avoid the dreaded OutOfMemoryException, be sure to increase the amount of heap available to the JVM by doing: &lt;code&gt;ANT_OPTS=-Xmx512m&lt;/code&gt;. Now the code. &lt;br /&gt;&lt;pre name="code" class="java"&gt; &lt;br /&gt;class DeceptiveIntegerExt {&lt;br /&gt;    static def minus(int self, int other) {&lt;br /&gt;        self + other; &lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Integer.mixin DeceptiveIntegerExt &lt;br /&gt;&lt;br /&gt;assert 5 - 5 == 10&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Let's explain this code: First, I create my mixin class which I named DeceptiveIntegerExt for the sheer reason that the only purpose was to overload the subtraction operator and make it add the numbers. Then I add the mixin class to the Integer class; finally I assert that my mixin works as it should, and indeed it does. Albeit that this is a &lt;b&gt;VERY&lt;/b&gt; simple example, but I wanted to play with it.&lt;br /&gt;&lt;br /&gt;That's all for now.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1083890928935553699-9170781011449436424?l=robbyoconnor.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/robbyoconnor/~4/jNZyjqjItaw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://robbyoconnor.blogspot.com/feeds/9170781011449436424/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1083890928935553699&amp;postID=9170781011449436424" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/9170781011449436424?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/9170781011449436424?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/robbyoconnor/~3/jNZyjqjItaw/new-groovy-mixins-syntax.html" title="The new groovy mixins syntax" /><author><name>Robert O'Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10413037710454370678" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://robbyoconnor.blogspot.com/2008/04/new-groovy-mixins-syntax.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ck8BSHw-eip7ImA9WxZbFE8.&quot;"><id>tag:blogger.com,1999:blog-1083890928935553699.post-570469881375780895</id><published>2008-04-06T23:02:00.007-04:00</published><updated>2008-04-17T04:27:39.252-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-04-17T04:27:39.252-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="jerklib" /><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="irc bots" /><category scheme="http://www.blogger.com/atom/ns#" term="closures" /><category scheme="http://www.blogger.com/atom/ns#" term="concise instance creation expressions" /><category scheme="http://www.blogger.com/atom/ns#" term="cice" /><title>a CICE Bot</title><content type="html">After writing a bot using both &lt;a href="http://robbyoconnor.blogspot.com/2008/04/irc-bot-written-using-bgga.html"&gt;BGGA&lt;/a&gt; and &lt;a href="http://robbyoconnor.blogspot.com/2008/04/first-class-bot-w-fcm.html"&gt;First-Class Methods (FCM)&lt;/a&gt;, I wanted to do &lt;a href="http://docs.google.com/View?docid=k73_1ggr36h&amp;"&gt;Concise Instance Creation Expressions (CICE)&lt;/a&gt; as well. To compile you will need &lt;a href="http://slm888.com/javac/"&gt;the cice prototype compiler&lt;/a&gt; and &lt;a href="http://www.ank.com.ar/r0bby/jerklib.jar"&gt;the jerklib jar&lt;/a&gt;. Now here we go: &lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;import jerklib.ConnectionManager;&lt;br /&gt;import jerklib.ProfileImpl;&lt;br /&gt;import jerklib.Session;&lt;br /&gt;import jerklib.events.listeners.IRCEventListener;&lt;br /&gt;import jerklib.events.IRCEvent;&lt;br /&gt;import jerklib.events.JoinCompleteEvent;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * Created: Apr 6, 2008 10:55:08 PM&lt;br /&gt; *&lt;br /&gt; * @author &lt;a href="mailto:robby.oconnor@gmail.com"&gt;Robert O'Connor&lt;/a&gt;&lt;br /&gt; */&lt;br /&gt;public class CICEBot {&lt;br /&gt;    ConnectionManager manager = new ConnectionManager(new ProfileImpl("cicebot", "cicebot", "cicebot2", "cicebot3"));&lt;br /&gt;    Session s = manager.requestConnection("irc.freenode.org");&lt;br /&gt;&lt;br /&gt;    public CICEBot() {&lt;br /&gt;        s.addIRCEventListener(IRCEventListener(IRCEvent e) {&lt;br /&gt;              if(e.getType() == IRCEvent.Type.CONNECT_COMPLETE) {&lt;br /&gt;                e.getSession().join("#jerklib");&lt;br /&gt;              } else if(e.getType() == IRCEvent.Type.JOIN_COMPLETE) {&lt;br /&gt;                JoinCompleteEvent jce = (JoinCompleteEvent)e;&lt;br /&gt;                jce.getChannel().say("Hello from CICE!!!");&lt;br /&gt;            }&lt;br /&gt;        });&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public static void main(String[] args) {&lt;br /&gt;        new CICEBot(); &lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The regular java version looks like this: &lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;import jerklib.ConnectionManager;&lt;br /&gt;import jerklib.ProfileImpl;&lt;br /&gt;import jerklib.Session;&lt;br /&gt;import jerklib.events.IRCEvent;&lt;br /&gt;import jerklib.events.JoinCompleteEvent;&lt;br /&gt;import jerklib.events.listeners.IRCEventListener;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * Created: Apr 6, 2008 10:05:09 PM&lt;br /&gt; *&lt;br /&gt; * @author &lt;a href="mailto:robby.oconnor@gmail.com"&gt;Robert O'Connor&lt;/a&gt;&lt;br /&gt; */&lt;br /&gt;public class JavaBot {&lt;br /&gt;        ConnectionManager manager = new ConnectionManager(new ProfileImpl("javabot", "javabot", "javabot2", "javabot3"));&lt;br /&gt;        Session s = manager.requestConnection("irc.freenode.org");&lt;br /&gt;&lt;br /&gt;        public JavaBot() {&lt;br /&gt;            s.addIRCEventListener(new IRCEventListener() {&lt;br /&gt;                public void receiveEvent(IRCEvent e) {&lt;br /&gt;                    if (e.getType() == IRCEvent.Type.CONNECT_COMPLETE) {&lt;br /&gt;                        e.getSession().join("#jerklib");&lt;br /&gt;                    } else if (e.getType() == IRCEvent.Type.JOIN_COMPLETE) {&lt;br /&gt;                        JoinCompleteEvent jce = (JoinCompleteEvent) e;&lt;br /&gt;                        jce.getSession().sayChannel(jce.getChannel(), "Hi from Java!!!");&lt;br /&gt;                    }&lt;br /&gt;&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;            });&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public static void main(String[] args) {&lt;br /&gt;            new JavaBot();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1083890928935553699-570469881375780895?l=robbyoconnor.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/robbyoconnor/~4/zitd_xLaDYA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://robbyoconnor.blogspot.com/feeds/570469881375780895/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1083890928935553699&amp;postID=570469881375780895" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/570469881375780895?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/570469881375780895?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/robbyoconnor/~3/zitd_xLaDYA/cice-bot.html" title="a CICE Bot" /><author><name>Robert O'Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10413037710454370678" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://robbyoconnor.blogspot.com/2008/04/cice-bot.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0YEQXY7fyp7ImA9WxZbFE8.&quot;"><id>tag:blogger.com,1999:blog-1083890928935553699.post-476107821510251291</id><published>2008-04-06T22:45:00.005-04:00</published><updated>2008-04-17T04:31:40.807-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-04-17T04:31:40.807-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="jerklib" /><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="irc bots" /><category scheme="http://www.blogger.com/atom/ns#" term="fcm" /><category scheme="http://www.blogger.com/atom/ns#" term="closures" /><category scheme="http://www.blogger.com/atom/ns#" term="first class methods" /><title>a first class bot (w/ FCM)</title><content type="html">After writing a bot using &lt;a href="http://robbyoconnor.blogspot.com/2008/04/irc-bot-written-using-bgga.html"&gt;BGGA&lt;/a&gt;, I decided to write one using &lt;a href="http://docs.google.com/View?docid=ddhp95vd_0f7mcns"&gt;First-Class Methods&lt;/a&gt;. Now to compile this, again you will need the &lt;a href="https://kijaro.dev.java.net/files/documents/7974/87470/FCM-2008-02-25.zip"&gt;FCM prototype compiler&lt;/a&gt; and &lt;a href="http://www.ank.com.ar/r0bby/jerklib.jar"&gt;the jerklib jar&lt;/a&gt;. &lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;import jerklib.ConnectionManager;&lt;br /&gt;import jerklib.ProfileImpl;&lt;br /&gt;import jerklib.Session;&lt;br /&gt;import jerklib.events.IRCEvent;&lt;br /&gt;import jerklib.events.JoinCompleteEvent;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * Created: Apr 6, 2008 10:23:06 PM&lt;br /&gt; *&lt;br /&gt; * @author &lt;a href="mailto:robby.oconnor@gmail.com"&gt;Robert O'Connor&lt;/a&gt;&lt;br /&gt; */&lt;br /&gt;public class FCMBot {&lt;br /&gt;    ConnectionManager manager = new ConnectionManager(new ProfileImpl("fcmbot","fcmbot","fcmbot2","fcmbot3"));&lt;br /&gt;    Session s = manager.requestConnection("irc.freenode.org");&lt;br /&gt;&lt;br /&gt;    public FCMBot() {&lt;br /&gt;        s.addIRCEventListener(#(IRCEvent e) {&lt;br /&gt;            if(e.getType() == IRCEvent.Type.CONNECT_COMPLETE) {&lt;br /&gt;                e.getSession().join("#jerklib");&lt;br /&gt;            } else if(e.getType() == IRCEvent.Type.JOIN_COMPLETE) {&lt;br /&gt;                JoinCompleteEvent jce = (JoinCompleteEvent)e;&lt;br /&gt;                jce.getChannel().say("Hello from FCM!!!");&lt;br /&gt;            }&lt;br /&gt;        });&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public static void main(String[] args) {&lt;br /&gt;        new FCMBot();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;It is much like the BGGA bot; in fact i changed nothing and followed the same design:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;import jerklib.ConnectionManager;&lt;br /&gt;import jerklib.ProfileImpl;&lt;br /&gt;import jerklib.Session;&lt;br /&gt;import jerklib.events.IRCEvent;&lt;br /&gt;import jerklib.events.JoinCompleteEvent;&lt;br /&gt;import jerklib.events.listeners.IRCEventListener;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * Created: Apr 6, 2008 10:05:09 PM&lt;br /&gt; *&lt;br /&gt; * @author &lt;a href="mailto:robby.oconnor@gmail.com"&gt;Robert O'Connor&lt;/a&gt;&lt;br /&gt; */&lt;br /&gt;public class JavaBot {&lt;br /&gt;        ConnectionManager manager = new ConnectionManager(new ProfileImpl("javabot", "javabot", "javabot2", "javabot3"));&lt;br /&gt;        Session s = manager.requestConnection("irc.freenode.org");&lt;br /&gt;&lt;br /&gt;        public JavaBot() {&lt;br /&gt;            s.addIRCEventListener(new IRCEventListener() {&lt;br /&gt;                public void receiveEvent(IRCEvent e) {&lt;br /&gt;                    if (e.getType() == IRCEvent.Type.CONNECT_COMPLETE) {&lt;br /&gt;                        e.getSession().join("#jerklib");&lt;br /&gt;                    } else if (e.getType() == IRCEvent.Type.JOIN_COMPLETE) {&lt;br /&gt;                        JoinCompleteEvent jce = (JoinCompleteEvent) e;&lt;br /&gt;                        jce.getSession().sayChannel(jce.getChannel(), "Hi from Java!!!");&lt;br /&gt;                    }&lt;br /&gt;&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;            });&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public static void main(String[] args) {&lt;br /&gt;            new JavaBot();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1083890928935553699-476107821510251291?l=robbyoconnor.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/robbyoconnor/~4/RCwDuCvAWNM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://robbyoconnor.blogspot.com/feeds/476107821510251291/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1083890928935553699&amp;postID=476107821510251291" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/476107821510251291?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1083890928935553699/posts/default/476107821510251291?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/robbyoconnor/~3/RCwDuCvAWNM/first-class-bot-w-fcm.html" title="a first class bot (w/ FCM)" /><author><name>Robert O'Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10413037710454370678" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://robbyoconnor.blogspot.com/2008/04/first-class-bot-w-fcm.html</feedburner:origLink></entry></feed>
