<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1083890928935553699</id><updated>2025-01-16T15:56:04.177-05:00</updated><category term="openmrs"/><category term="java"/><category term="gsoc"/><category term="groovy"/><category term="google summer of code"/><category term="soc"/><category term="hfoss"/><category term="closures"/><category term="facility data module"/><category term="groovy forms module"/><category term="open source"/><category term="bgga"/><category term="google"/><category term="jerklib"/><category term="foss"/><category term="google summer of code 2010"/><category term="irc bots"/><category term="sahana eden survey tool"/><category term="swing"/><category term="web2py"/><category term="cice"/><category term="dwr"/><category term="fcm"/><category term="gsoc2010"/><category term="programming"/><category term="properties"/><category term="python"/><category term="sahana"/><category term="sahana eden"/><category term="ajax"/><category term="ant"/><category term="april fools"/><category term="arm"/><category term="bytecode"/><category term="catagories"/><category term="concise instance creation expressions"/><category term="exceptions"/><category term="first class methods"/><category term="floss"/><category term="free text messaging"/><category term="gci2014"/><category term="git"/><category term="git tips and tricks"/><category term="google code in"/><category term="google code in 2014"/><category term="google nyc office visit"/><category term="google summer of code 2013"/><category term="google summer of code meetup"/><category term="google voice"/><category term="google voice tips and tricks"/><category term="gsoc meetup"/><category term="gsoc2009"/><category term="hoaxes"/><category term="hunter college"/><category term="hypopara"/><category term="java7"/><category term="javascript"/><category term="js"/><category term="mixins"/><category term="omrs15"/><category term="openeverything"/><category term="random"/><category term="regex"/><category term="regexp"/><category term="regular expressions"/><category term="security"/><category term="singapore"/><category term="survey tool"/><title type='text'>Rob&#39;s Musings</title><subtitle type='html'>[insert witty tag line here]</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://robby.oconnor.ninja/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/-/openmrs'/><link rel='alternate' type='text/html' href='http://robby.oconnor.ninja/search/label/openmrs'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/-/openmrs/-/openmrs?start-index=26&amp;max-results=25'/><author><name>Robby O&#39;Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>28</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1083890928935553699.post-6950154681127100189</id><published>2015-12-28T18:41:00.002-05:00</published><updated>2018-12-02T04:21:51.900-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="google code in"/><category scheme="http://www.blogger.com/atom/ns#" term="google summer of code"/><category scheme="http://www.blogger.com/atom/ns#" term="gsoc"/><category scheme="http://www.blogger.com/atom/ns#" term="omrs15"/><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><category scheme="http://www.blogger.com/atom/ns#" term="singapore"/><title type='text'>OpenMRS Worldwide Summit 2015 Wrapup </title><content type='html'>&amp;nbsp; &amp;nbsp; I have been around the &lt;a href=&quot;http://www.openmrs.org/&quot; target=&quot;_blank&quot;&gt;OpenMRS&lt;/a&gt; Community in one form or another since 2008 when &lt;a href=&quot;https://twitter.com/ekrub&quot; target=&quot;_blank&quot;&gt;Burke Mamlin&lt;/a&gt; and &lt;a href=&quot;https://twitter.com/pbiondich&quot; target=&quot;_blank&quot;&gt;Paul Biondich&lt;/a&gt; came by the Java IRC channel on freenode to recruit for &lt;a href=&quot;https://wiki.openmrs.org/display/RES/Google+Summer+of+Code&quot; target=&quot;_blank&quot;&gt;Google Summer of Code&lt;/a&gt; and I was drawn by the fact that I could write code that saved lives. I went on to do the first two of my three Google Summer of Code stints with OpenMRS. My first Google Summer of Code was under Burke Mamlin and Ben Wolfe; my second was under Mike Seaton and Darius Jazayeri. Recently, I am currently Manager of &lt;a href=&quot;http://id.openmrs.org/&quot; target=&quot;_blank&quot;&gt;Identity Systems&lt;/a&gt;, and also am a member of the OpenMRS Infrastructure Team and am having a blast.&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp;Three weeks ago (8-14 Dec) I got to meet all of my Google Summer of Code mentors but Ben Wolfe in person for the first time at the first annual &lt;a href=&quot;http://lanyrd.com/2015/omrs15/&quot; target=&quot;_blank&quot;&gt;OpenMRS Worldwide Summit&lt;/a&gt; in Singapore. This wasn&#39;t even the highlight. OpenMRS is a special community, one which I have yet to encounter anything similar. I was lucky enough and eternally grateful for the &lt;a href=&quot;https://wiki.openmrs.org/display/RES/OpenMRS+Inc.+Travel+Grant+Program&quot; target=&quot;_blank&quot;&gt;OpenMRS Inc. Travel Grant Program&lt;/a&gt;, which covered my hotel costs partially so that I could attend this amazing event.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp;I arrived in Singapore, quite tired a little bit after 10:00 PM SGT on 6 December, and after getting through immigration and customs and grabbed my checked bags; I grabbed the shuttle for $9 SGD, which is reasonably cheap.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; I spent most of the day following sleeping off jet lag, and then ran to the mall to troubleshoot what wound up being a case of PEBKAC with my simcard; and then met up with&amp;nbsp;&lt;a href=&quot;https://twitter.com/downey&quot; target=&quot;_blank&quot;&gt;Michael Downey&lt;/a&gt;&amp;nbsp;and Kaweesi &amp;nbsp;and grabbed some food and then headed for a preview of &lt;a href=&quot;http://www.marinabaysands.com/entertainment/wonderfull.html&quot; target=&quot;_blank&quot;&gt;Wonder Full&lt;/a&gt;, an amazing water and light show which is amazing to see, the group of us from the summit as a whole went to see it on Friday, 11 December. One of the things that made me chuckle was the crosswalks telling me to wait for the green man...I saw that and snapped a photo as I was headed back to meet up with Michael Downey:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNjEQX_mDAydvTJsKDYnIpo53kkJXS3l6CVQ1DOuncArvDGcjzbwdsWauedad_4UDIP330Y9InlgwKX1TnT1WTTMSVLpyvRk2Wy2e2te_JZm-2A0V8eUMcFg-UqECgGiRYCvagdnBep2Q/s1600/photo_2016-07-04_04-07-43.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNjEQX_mDAydvTJsKDYnIpo53kkJXS3l6CVQ1DOuncArvDGcjzbwdsWauedad_4UDIP330Y9InlgwKX1TnT1WTTMSVLpyvRk2Wy2e2te_JZm-2A0V8eUMcFg-UqECgGiRYCvagdnBep2Q/s400/photo_2016-07-04_04-07-43.jpg&quot; width=&quot;225&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; I volunteered and helped out with registration and general event logistics such as set-up and breakdown each day, as well as helping out with registration. On Tuesday morning, I helped bring things to the event venue (Singapore Management University). Tuesday-Wednesday (8 Dec to 9 Dec) was tutorials, either day-long or half-day. Thursday-Saturday ( 8-12 Dec) was main Conference, with both formal talks and unconference sessions(more round-table discussion), my favorite of which was a cause which I feel strongly about is the &lt;a href=&quot;https://talk.openmrs.org/t/women-in-technology-session/3950&quot; target=&quot;_blank&quot;&gt;Women in Technology&lt;/a&gt;&amp;nbsp;session, which was an amazing session. Notes from the talk can be found in the link above. Hearing about the strategic goals of OpenMRS, as well as the the talks about the OpenMRS Governance, which was amazing.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;img height=&quot;300&quot; src=&quot;https://talk.openmrs.org/uploads/default/original/2X/5/594c47f17cbe8ec288d6f58b083d79b480bc499f.JPG&quot; style=&quot;margin-left: auto; margin-right: auto;&quot; width=&quot;400&quot; /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Photo by James Arbaugh, via &lt;a href=&quot;https://talk.openmrs.org/t/women-in-technology-session/3950&quot; target=&quot;_blank&quot;&gt;OpenMRS Talk&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp;The lightning talks were amazing. I originally was not going to give a talk since I did not prepare slides, but last second I typed up some notes and gave a talk trying to recruit more people to mentor for&amp;nbsp;&lt;a href=&quot;http://codein.withgoogle.com/&quot; target=&quot;_blank&quot;&gt;Google Code-In&lt;/a&gt;, and I feel extremely passionate about this program. This year and last were by far my favorite years! It&#39;s exhilarating to look at the work of these students and just be amazed. We are fostering young open source developers, some as young as 13! I got so many compliments from people saying they loved my lightning talk. I just wish more people gave talks. The ones who did, hit it out of the park.&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;img alt=&quot;CV6R1e3WcAIsxGd.jpg (600×800)&quot; height=&quot;640&quot; src=&quot;https://pbs.twimg.com/media/CV6R1e3WcAIsxGd.jpg&quot; style=&quot;margin-left: auto; margin-right: auto;&quot; width=&quot;480&quot; /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;&amp;nbsp;Photo Credit: Jan Flowers, via Twitter&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp;The after-hours activities were a chance to bond with the awesome community. There was an Informal Group Dinner at Maxwell Food Centre, The Pre-Summit BBQ at the Labrador Nature Reserve, Powerpoint Karaoke at Thoughtworks(I went with the &quot;this is going to go bad&quot; theme and it worked...), Chinatown Food Crawl. We also took a trip to the Marina Bay Sands for&amp;nbsp;&lt;a href=&quot;http://www.marinabaysands.com/entertainment/wonderfull.html&quot; target=&quot;_blank&quot;&gt;Wonder Full&lt;/a&gt;&amp;nbsp;and a light show by Gardens By The Bay, which you can&#39;t get enough of. I had a way better seat for it this time! The after-hours activities were closed out by a fun trip to Little India, followed by a group dinner for those who went. Afterward, some of us headed to the&amp;nbsp;Mustafa Centre and then met up with a group that were enjoying the beautiful Clark Quay night-life; we wound up closing out the night at Life of Liquor (LoL). The after-hours events gave the community a chance to bond.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkk179pWh6P4uQ5tdpCvYmIzpkhCY9XVtBSws_oxZQ15pxYRDeXeaUV8ZFn8KQqwo00jKV2lpGn8YhUsPnguI4jixXzV_G-ZLXrA0iAD0znVRcX5UKIbyKktwaP5plZ-8qkqZ3p6OLuRE/s1600/IMG_20151212_184842.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkk179pWh6P4uQ5tdpCvYmIzpkhCY9XVtBSws_oxZQ15pxYRDeXeaUV8ZFn8KQqwo00jKV2lpGn8YhUsPnguI4jixXzV_G-ZLXrA0iAD0znVRcX5UKIbyKktwaP5plZ-8qkqZ3p6OLuRE/s400/IMG_20151212_184842.jpg&quot; width=&quot;225&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Little India group shot (Photo from Mayank Sharma)&lt;br /&gt;
&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDCZeLhiVgwv13dc3yGNnGrioUw9hD0XDrLw7r6WuOR5EEfG9c8xoNnnK8AF0wglTvS9IUwW3DTSHuMRjHCLYOo_ssSunxckL-cDOEo1bWEEzNijrnUzdQqPObmigtGIUW95htDPHyf9s/s1600/IMG_20151212_183316.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDCZeLhiVgwv13dc3yGNnGrioUw9hD0XDrLw7r6WuOR5EEfG9c8xoNnnK8AF0wglTvS9IUwW3DTSHuMRjHCLYOo_ssSunxckL-cDOEo1bWEEzNijrnUzdQqPObmigtGIUW95htDPHyf9s/s320/IMG_20151212_183316.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Photo Credit Hong Phuc Dang&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8Frc_CYpP2Vnp_1ONXbqqyg0fz1BzilIeuvjoNlwHUgOkdkLtvTj8qfMufOufvXOzIT8f5bP7oH5CBnM0_NAtCr8XDd5gklZyNwMWfsbDPAVQKlgfIHzhh2gh4iuwZuN87xpmXJbXbAs/s1600/IMG_20151212_183355.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8Frc_CYpP2Vnp_1ONXbqqyg0fz1BzilIeuvjoNlwHUgOkdkLtvTj8qfMufOufvXOzIT8f5bP7oH5CBnM0_NAtCr8XDd5gklZyNwMWfsbDPAVQKlgfIHzhh2gh4iuwZuN87xpmXJbXbAs/s320/IMG_20151212_183355.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-size: 12.8px;&quot;&gt;Photo Credit Hong Phuc Dang&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtKe6OswMgD5PHQFnAXxUdYvKacStxtlapG5z6nmk0dzyoPIRPR6Gf_SCsODqwOM3j3oKbz6IwQjxsuhr_q8-egJsep9ZZKFVI1_o6ibckbpRTdOhxypWHoq6hfqnv36vGGLPQ7HL8Ng0/s1600/IMG_20151212_183556.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtKe6OswMgD5PHQFnAXxUdYvKacStxtlapG5z6nmk0dzyoPIRPR6Gf_SCsODqwOM3j3oKbz6IwQjxsuhr_q8-egJsep9ZZKFVI1_o6ibckbpRTdOhxypWHoq6hfqnv36vGGLPQ7HL8Ng0/s400/IMG_20151212_183556.jpg&quot; width=&quot;300&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-size: 12.8px;&quot;&gt;Photo Credit Hong Phuc Dang&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-Jbs-iB9fsz3972zhZPpIgYnmkPvnQugAuPyylAMgD8X0igpFYrXeNUiRbqQz2imEWhKmmXwnrjHuVPgsSrPACVIOBY0b5khfJwKwSQdMyxD4ygB_wu_ReBQdwMfnJerfVgRvw1spiSU/s1600/IMG_20151212_183559.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-Jbs-iB9fsz3972zhZPpIgYnmkPvnQugAuPyylAMgD8X0igpFYrXeNUiRbqQz2imEWhKmmXwnrjHuVPgsSrPACVIOBY0b5khfJwKwSQdMyxD4ygB_wu_ReBQdwMfnJerfVgRvw1spiSU/s320/IMG_20151212_183559.jpg&quot; width=&quot;240&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-size: 12.8px;&quot;&gt;Photo Credit Hong Phuc Dang&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&amp;nbsp; &amp;nbsp; On Wednesday, 9 December, Burke, Paul, Mayank and I took a walk to the Funan Tech Mall to get the prize for the scavenger hunt and grabbed lunch there. It was amazing to spend time with such amazing people.&amp;nbsp;&lt;/div&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifeYfKTwjOk_6ymiGBSht917BbnU9nNU3_JsBlin9WLfokOlgbRv6rvNyMAmWm6p8w3LQe0K-3wwuzqWmB1TmwCtGxoqVshZQCAM2gcYv0p9OVVxxKOscIzqZ4Yo_j8UsXglWof5F-pa8/s1600/IMG_20151209_145855.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;180&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifeYfKTwjOk_6ymiGBSht917BbnU9nNU3_JsBlin9WLfokOlgbRv6rvNyMAmWm6p8w3LQe0K-3wwuzqWmB1TmwCtGxoqVshZQCAM2gcYv0p9OVVxxKOscIzqZ4Yo_j8UsXglWof5F-pa8/s320/IMG_20151209_145855.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Mayank, Paul, Burke, and myself (from left to right) (from Mayank Sharma)&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&amp;nbsp; &amp;nbsp;One of my favorite moments was when we waiting for the light show at Gardens By the Bay, Burke spotted a kid with a Rubik&#39;s cube, pulled his out and well this was the end result, it was about as awkward and funny as it looks. Photo Credit to Mayank Sharma though, this picture needs to be included somewhere official, it&#39;s an epic battle, the kid forfeited, so I guess Burke wins by default? It&#39;s one of those you had to be there to appreciate it, but hopefully this still works somewhat.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-PNyPT-uYHRjKcMZyr5Rv_QdEDaqCOFN7upYuXrF6UGP_cbpQR_3r6puL-ltIndi6PCaYNXE2Zt2wt4pT1Q9cumZyfnHkf2e3ClLFuaDeyM_3SgTcBej7FrXdE2M6u9CFDkqL7BYJ69M/s1600/photo_2015-12-28_17-19-43.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-PNyPT-uYHRjKcMZyr5Rv_QdEDaqCOFN7upYuXrF6UGP_cbpQR_3r6puL-ltIndi6PCaYNXE2Zt2wt4pT1Q9cumZyfnHkf2e3ClLFuaDeyM_3SgTcBej7FrXdE2M6u9CFDkqL7BYJ69M/s320/photo_2015-12-28_17-19-43.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Photo Credit to Mayank Sharma&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;div&gt;
&amp;nbsp; It is also amazing that &lt;a href=&quot;https://twitter.com/maany_shr&quot; target=&quot;_blank&quot;&gt;Mayank Sharma&lt;/a&gt;, &lt;a href=&quot;http://twitter.com/downey&quot; target=&quot;_blank&quot;&gt;Michael Downey&lt;/a&gt;, and myself (whom form 3/4 of the OpenMRS Infrastructure Team) were able to be together. &lt;a href=&quot;https://twitter.com/ryatesm&quot; target=&quot;_blank&quot;&gt;Ryan Yates&lt;/a&gt; was missing sadly. Would have been pretty awesome to have all four of us.&lt;br /&gt;
&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLGCzp_zkFPEEdSv-YufByJlC8YBQ2gLQkb1Psf4wlX5wwiQ4PyTFgv6EpRpUyO1H2tTC6VD5ccXDRkA0GM9Jkf-96IKlCJ4lprstkW-BeVei2HdWvEqlGVvYT70cUaNdO7lTIuOLJ3jc/s1600/img_20151214_172545.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;179&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLGCzp_zkFPEEdSv-YufByJlC8YBQ2gLQkb1Psf4wlX5wwiQ4PyTFgv6EpRpUyO1H2tTC6VD5ccXDRkA0GM9Jkf-96IKlCJ4lprstkW-BeVei2HdWvEqlGVvYT70cUaNdO7lTIuOLJ3jc/s320/img_20151214_172545.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Photo from Mayank Sharma&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; I would like to thank OpenMRS, Inc for the Travel Grant to attend. I would also like to thank Michael Downey for the Korean BBQ on Sunday (12 Dec). Though one thing I&#39;m sad about: I never got to try the infamous Durian, the only thing which doesn&#39;t seem to a carry a fine, nobody seems to know what actually happens...This sign was found in the MRT station.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmFj81EUiKzWuCLp1Fz6c6AYcKQqr_wMsmjzH6Cquzwx0dWbp_ihSPUWd6JXPm-xOHBv5hsYD6cVQDauawBUVSR8UkavOgpql6qCWOnsRqGtTTHgznj-IuEmEMwYzMvP_Dwh-Vxn3Ypsg/s1600/photo_2015-12-28_17-56-17.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;224&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmFj81EUiKzWuCLp1Fz6c6AYcKQqr_wMsmjzH6Cquzwx0dWbp_ihSPUWd6JXPm-xOHBv5hsYD6cVQDauawBUVSR8UkavOgpql6qCWOnsRqGtTTHgznj-IuEmEMwYzMvP_Dwh-Vxn3Ypsg/s400/photo_2015-12-28_17-56-17.jpg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhd4OjXo7iQQMdULX2OnjXo48dAZxJR07KlhtsncFAF5QiS7YeB_k6CJhc1aXAtoCSPdDRRhoX2X-ss7BovzeuqhUDYxpXJjXbBeDy7nAkD5pi12mWMqxkVxZ7txPxNLpK2XhDstgI7KMc/s1600/photo_2015-12-28_17-56-25.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;225&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhd4OjXo7iQQMdULX2OnjXo48dAZxJR07KlhtsncFAF5QiS7YeB_k6CJhc1aXAtoCSPdDRRhoX2X-ss7BovzeuqhUDYxpXJjXbBeDy7nAkD5pi12mWMqxkVxZ7txPxNLpK2XhDstgI7KMc/s400/photo_2015-12-28_17-56-25.jpg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div style=&quot;text-align: right;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://robby.oconnor.ninja/feeds/6950154681127100189/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1083890928935553699/6950154681127100189' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/6950154681127100189'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/6950154681127100189'/><link rel='alternate' type='text/html' href='http://robby.oconnor.ninja/2015/12/openmrs-worldwide-summit-2015-wrapup.html' title='OpenMRS Worldwide Summit 2015 Wrapup '/><author><name>Robby O&#39;Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNjEQX_mDAydvTJsKDYnIpo53kkJXS3l6CVQ1DOuncArvDGcjzbwdsWauedad_4UDIP330Y9InlgwKX1TnT1WTTMSVLpyvRk2Wy2e2te_JZm-2A0V8eUMcFg-UqECgGiRYCvagdnBep2Q/s72-c/photo_2016-07-04_04-07-43.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1083890928935553699.post-1896821745074508378</id><published>2015-03-23T19:06:00.003-04:00</published><updated>2015-07-31T06:11:07.509-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="gci2014"/><category scheme="http://www.blogger.com/atom/ns#" term="git"/><category scheme="http://www.blogger.com/atom/ns#" term="git tips and tricks"/><category scheme="http://www.blogger.com/atom/ns#" term="google code in 2014"/><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><title type='text'>How to checkout Github Pull Requests locally</title><content type='html'>Today&#39;s post centers around a need I had not too long ago. While checking student&#39;s work during &lt;a href=&quot;https://www.google-melange.com/gci/homepage/google/gci2014&quot;&gt;Google Code-In (GCI)&lt;/a&gt;&amp;nbsp;I needed to check their branches out locally to run it. Turns out to be easier than you think:&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/robbyoconnor/a4121b77545b09761b8f.js&quot;&gt;&lt;/script&gt;

The first is allows me to do: 
&lt;em&gt;gco &amp;lt;branch&amp;gt;&lt;/em&gt;
&lt;br /&gt;
&lt;br /&gt;
The second file resides in &lt;em&gt;.git/config&lt;/em&gt; -- in my case I set it up so that &lt;b&gt;origin&lt;/b&gt; is my local working branch and &lt;b&gt;upstream&lt;/b&gt; is the branch I forked from. If I do &lt;em&gt;gco pr/1&lt;/em&gt;, then it will pull from &lt;b&gt;upstream&lt;/b&gt; and checkout the working branch. 
&lt;br /&gt;
&lt;br /&gt;
Pretty nifty eh? Don&#39;t forget to switch back to &lt;b&gt;master&lt;/b&gt;, or whatever your main working branch is before merging or making changes!&lt;br /&gt;
&lt;br /&gt;
If you prefer a more linear history, you can cherrypick commits, but still switch to &lt;b&gt;master&lt;/b&gt;&amp;nbsp;first.</content><link rel='replies' type='application/atom+xml' href='http://robby.oconnor.ninja/feeds/1896821745074508378/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1083890928935553699/1896821745074508378' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/1896821745074508378'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/1896821745074508378'/><link rel='alternate' type='text/html' href='http://robby.oconnor.ninja/2015/03/how-to-checkout-github-pull-requests.html' title='How to checkout Github Pull Requests locally'/><author><name>Robby O&#39;Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1083890928935553699.post-1094044777226307734</id><published>2010-03-28T08:32:00.002-04:00</published><updated>2010-03-28T08:35:35.914-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="facility data module"/><category scheme="http://www.blogger.com/atom/ns#" term="google summer of code"/><category scheme="http://www.blogger.com/atom/ns#" term="gsoc"/><category scheme="http://www.blogger.com/atom/ns#" term="gsoc2009"/><category scheme="http://www.blogger.com/atom/ns#" term="hfoss"/><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><title type='text'>Facility Data Module v1.0 released!</title><content type='html'>It is with great pleasure that I announce the release of version 1.0 of the &lt;a href=&quot;http://openmrs.org/wiki/Facility_Data_Module_Documentation&quot;&gt;Facility Data Module&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;It is available for downloaded via the OpenMRS &lt;a href=&quot;http://modules.openmrs.org/modules/view.jsp?module=facilitydata&quot;&gt;module repository&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;Feedback is appreciated!</content><link rel='replies' type='application/atom+xml' href='http://robby.oconnor.ninja/feeds/1094044777226307734/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1083890928935553699/1094044777226307734' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/1094044777226307734'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/1094044777226307734'/><link rel='alternate' type='text/html' href='http://robby.oconnor.ninja/2010/03/facility-data-module-v10-released.html' title='Facility Data Module v1.0 released!'/><author><name>Robby O&#39;Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1083890928935553699.post-7116573361403729699</id><published>2010-01-18T22:47:00.005-05:00</published><updated>2010-01-18T23:55:48.028-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="facility data module"/><category scheme="http://www.blogger.com/atom/ns#" term="google summer of code"/><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><category scheme="http://www.blogger.com/atom/ns#" term="soc"/><title type='text'>Facility Data updates</title><content type='html'>It&#39;s been a while since I last updated on the progress of the &lt;a href=&quot;http://openmrs.org/wiki/Facility_Data_Module&quot;&gt;Facility Data Module&lt;/a&gt;. So without farther adieu here we go:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The relation between the FacilityDataFormSchema and FacilityDataFormSection is now Many to Many meaning that sections can now be re-used between several form schemas (or reports).  &lt;/li&gt;&lt;li&gt;It now runs without errors on &lt;a href=&quot;http://openmrs.org/&quot;&gt;OpenMRS&lt;/a&gt; 1.5.x&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;The first item was a big problem that was a sore spot for this project since it wasn&#39;t too intuitive, ideally a user should be able to re-use a section. The second item was a freebie since the errors were likely all due to the incorrect modeling.&lt;br /&gt;&lt;br /&gt;What&#39;s next on my list is the following:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Allow for sections to be re-ordered within the schema (this is currently not possible and is a show-stopper.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Fix up the calendar management pages -- those are horribly ugly, but this is after all a first pass, so that is to be expected right?&lt;/li&gt;&lt;li&gt;Currently, it does not validate inputs for Numeric data types -- It need to.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;There still needs to be the ability to analyze the data that exists in the system to submit to funding sources; those pages need to be implemented but that is phase two of the project.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;There are likely other sore spots that exist that I do not see at this point and time that will be fixed at a later date. &lt;/li&gt;&lt;/ol&gt;That is all for now.</content><link rel='replies' type='application/atom+xml' href='http://robby.oconnor.ninja/feeds/7116573361403729699/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1083890928935553699/7116573361403729699' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/7116573361403729699'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/7116573361403729699'/><link rel='alternate' type='text/html' href='http://robby.oconnor.ninja/2010/01/facility-data-updates.html' title='Facility Data updates'/><author><name>Robby O&#39;Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1083890928935553699.post-8028181397956518950</id><published>2009-08-19T05:56:00.006-04:00</published><updated>2009-08-26T08:40:30.539-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="facility data module"/><category scheme="http://www.blogger.com/atom/ns#" term="google summer of code"/><category scheme="http://www.blogger.com/atom/ns#" term="gsoc"/><category scheme="http://www.blogger.com/atom/ns#" term="hfoss"/><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><title type='text'>Google Summer of Code 2009  wrap-up</title><content type='html'>Google Summer of Code 2009 officially ended on August 17, 2009 at 19:00 UTC (12:00 PDT). I had an amazing time this summer. While stressful at times, it was well worth it.&lt;br /&gt;
&lt;br /&gt;
I would like to thank the following people for my success this summer:&lt;br /&gt;
&lt;br /&gt;
My mentor Mike Seaton for helping me throughout various misunderstandings surrounding the project&#39;s requirements. I probably made him work more than he had to. I attribute the success this summer to that one factor. This man is quite brilliant and knows his stuff.&lt;br /&gt;
&lt;br /&gt;
My backup mentor Darius Jazayeri, for stepping in and helping at times and providing guidance when necessary. He is truly a brilliant man.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://blog.eflow.org/&quot;&gt;Ben Wolfe&lt;/a&gt; for answering any questions I had. He didn&#39;t have to help, but he did. I am very grateful.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://docpaul.wordpress.com/&quot;&gt;Paul Biondich&lt;/a&gt; and &lt;a href=&quot;http://blog.burkeware.com/&quot;&gt;Burke Mamlin&lt;/a&gt; for believing in me and giving me a second chance this summer. Did I mention these guys are doctors? Burke, an internist and Paul a pediatrician. Sorry for clumping you guys together.&lt;br /&gt;
&lt;br /&gt;
Finally, without &lt;a href=&quot;http://www.hawthornlandings.org/&quot;&gt;Leslie Hawthorn&lt;/a&gt;, Cat Allman, and Ellen Ko from &lt;a href=&quot;http://code.google.com/soc&quot;&gt;Google&lt;/a&gt;, this program would not exist. They deserve a huge thank you. These three women are amazing. Thank you so much!!</content><link rel='replies' type='application/atom+xml' href='http://robby.oconnor.ninja/feeds/8028181397956518950/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1083890928935553699/8028181397956518950' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/8028181397956518950'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/8028181397956518950'/><link rel='alternate' type='text/html' href='http://robby.oconnor.ninja/2009/08/google-summer-of-code-wrap-up.html' title='Google Summer of Code 2009  wrap-up'/><author><name>Robby O&#39;Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1083890928935553699.post-3846840962964561413</id><published>2009-08-17T06:36:00.006-04:00</published><updated>2009-08-21T21:08:47.167-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="facility data module"/><category scheme="http://www.blogger.com/atom/ns#" term="google summer of code"/><category scheme="http://www.blogger.com/atom/ns#" term="gsoc"/><category scheme="http://www.blogger.com/atom/ns#" term="hfoss"/><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><title type='text'>Facility Data Module User Guide</title><content type='html'>&lt;div&gt;The Facility Data Module is a tool to collect non-patient centric aggregate data for reporting to external funding sources.&lt;br /&gt;&lt;br /&gt;To download it use the svn version: do a checkout:&lt;br /&gt;&lt;code&gt;svn co http://svn.openmrs.org/openmrs-modules/facilitydata&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;To create a report:&lt;br /&gt;&lt;br /&gt;1) Create all your questions&lt;br /&gt;&lt;br /&gt;2) Create all of your form sections&lt;br /&gt;&lt;br /&gt;3) Finally add all the sections to your form schema&lt;br /&gt;&lt;br /&gt;I&#39;ll go into detail how to do each:&lt;br /&gt;&lt;br /&gt;&lt;u&gt;&lt;span style=&quot;font-size:180%;&quot;&gt;&lt;b style=&quot;color: rgb(0, 0, 0);&quot;&gt;Creating/Managing questions &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/u&gt;From the admin screen: select &quot;Manage Questions.&quot;&lt;br /&gt;&lt;div id=&quot;b7.h&quot; style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div id=&quot;wzvm&quot; style=&quot;text-align: left;&quot;&gt;&lt;img src=&quot;http://docs.google.com/File?id=df8w66j7_57vvt2h2fx_b&quot; height=&quot;335&quot; width=&quot;1097&quot; /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Now, once on the question management page you will see a list of existing questions. under the &quot;Action&quot; column is a garbage can image -- this deletes the question from the database and is irreversible.&lt;br /&gt;&lt;br /&gt;Once created, a question&#39;s data type cannot be changed, this is due to the design.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;div id=&quot;uuct&quot; style=&quot;text-align: left;&quot;&gt;&lt;img src=&quot;http://docs.google.com/File?id=df8w66j7_55d9hr7vhn_b&quot; height=&quot;385&quot; width=&quot;1260&quot; /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div id=&quot;h5qn&quot; style=&quot;text-align: left;&quot;&gt;&lt;img src=&quot;http://docs.google.com/File?id=df8w66j7_58d74fhrc9_b&quot; height=&quot;330&quot; width=&quot;1554&quot; /&gt;&lt;/div&gt;Now, once on the &quot;Add New Question&quot; page there are several properties. Most of which are required.&lt;br /&gt;&lt;br /&gt;1) name &lt;b&gt;- &lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;required&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;2) question data type - &lt;b style=&quot;color: rgb(255, 0, 0);&quot;&gt;required&lt;/b&gt;&lt;br /&gt;3) aggregation method - &lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;required&lt;/span&gt;&lt;br /&gt;&lt;/b&gt;4) description - &lt;b style=&quot;color: rgb(255, 0, 0);&quot;&gt;optional&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Question Data Types are as follows:&lt;br /&gt;&lt;br /&gt;&lt;u&gt;&lt;b&gt;NumericQuestion&lt;/b&gt;&lt;/u&gt; - a question that has a numeric answer (optionally has a min/max value and whether or not to allow decimal values.) -- these fields show only if you select &quot;NumericQuestion.&quot;&lt;br /&gt;&lt;br /&gt;&lt;u&gt;&lt;b&gt;BooleanCodedQuestion  &lt;/b&gt;&lt;/u&gt;&lt;b&gt;- &lt;/b&gt;a coded question with 3 answers: &quot;t&quot;,&quot;f&quot;,&quot;not applicable&quot;&lt;br /&gt;&lt;br /&gt;&lt;u&gt;&lt;b&gt;StockQuestion&lt;/b&gt;&lt;/u&gt; - a question that tracks stock of vaccines, supplies, etc. This is a special coded question with the following answers: &quot;not_stocked_out&quot;, &quot;stocked_out&quot;, &quot;expired&quot;, &quot;not_applicable&quot; and the comments field used to track the numbers of days stocked out and reason.&lt;br /&gt;&lt;br /&gt;To add more questions after you save a question -- click &quot;Add New Question&quot; link above the form box.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size:180%;&quot;&gt;&lt;u&gt;&lt;b&gt;Creating/Managing Form Sections&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Once you have created all of your questions -- it&#39;s time to organize them into sections. You can easily navigate to the &quot;Manage Form Sections&quot; page from the &quot;Add New Question&quot; page.&lt;br /&gt;&lt;br /&gt;&lt;div id=&quot;p40x&quot; style=&quot;text-align: left;&quot;&gt;&lt;img src=&quot;http://docs.google.com/File?id=df8w66j7_59g2f7km9f_b&quot; height=&quot;278&quot; width=&quot;1309&quot; /&gt;&lt;br /&gt;Now, once on the section management page -- you&#39;ll see a list of all sections saved and the associated schema. Next, you&#39;ll want to click &quot;Add New Form Section&quot;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div id=&quot;yv.y&quot; style=&quot;text-align: left;&quot;&gt;&lt;div id=&quot;ycoj&quot; style=&quot;text-align: left;&quot;&gt;&lt;img src=&quot;http://docs.google.com/File?id=df8w66j7_61f8vpqhc7_b&quot; height=&quot;203&quot; width=&quot;1355&quot; /&gt;&lt;br /&gt;Now, once on the add questions page: you&#39;ll enter:&lt;br /&gt;&lt;br /&gt;1) Display Name - &lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;required&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;2) Description - &lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;optional&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;3) Form Schema -&lt;b style=&quot;color: rgb(255, 0, 0);&quot;&gt;optional (can be deferred) &lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Mentioned seperately is questions you&#39;re adding to the section (these are referred to as form questions by the system).&lt;br /&gt;1) Name&lt;br /&gt;2) Question Number&lt;br /&gt;3) Question&lt;br /&gt;4) Description&lt;br /&gt;To add a question: click &quot;Add New Question&quot; to remove a question, click the &quot;Remove&quot; button next to the button (see image after the one below).&lt;br /&gt;&lt;/div&gt;&lt;div id=&quot;gpqj&quot; style=&quot;text-align: left;&quot;&gt;&lt;img src=&quot;http://docs.google.com/File?id=df8w66j7_62g47935d8_b&quot; height=&quot;416&quot; width=&quot;1348&quot; /&gt;&lt;br /&gt;&lt;br /&gt;The section below is a section that was defined programmatically in a mock schema that was designed and used throughout the summer.&lt;br /&gt;As you can see, there is a &quot;Remove&quot; button next to each Form Question in the section.&lt;br /&gt;&lt;/div&gt;&lt;div id=&quot;w9ey&quot; style=&quot;text-align: left;&quot;&gt;&lt;div id=&quot;c1w7&quot; style=&quot;text-align: left;&quot;&gt;&lt;img src=&quot;http://docs.google.com/File?id=df8w66j7_64gvcmjhfm_b&quot; height=&quot;531&quot; width=&quot;1329&quot; /&gt;&lt;br /&gt;&lt;span style=&quot;font-size:180%;&quot;&gt;&lt;u&gt;Creating/Managing Form Schemas&lt;/u&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;From  the Section creation page: click &quot;Manage Form Schemas&quot;&lt;br /&gt;&lt;br /&gt;&lt;div id=&quot;n2-1&quot; style=&quot;text-align: left;&quot;&gt;&lt;img src=&quot;http://docs.google.com/File?id=df8w66j7_65px2f84hf_b&quot; height=&quot;524&quot; width=&quot;1312&quot; /&gt;&lt;/div&gt;After clicking that link you will see the page below. It allows you to delete a schema, and information relevant to te form schema.&lt;br /&gt;&lt;br /&gt;&lt;div id=&quot;oa.u&quot; style=&quot;text-align: left;&quot;&gt;&lt;img src=&quot;http://docs.google.com/File?id=df8w66j7_66d5mt5jc4_b&quot; height=&quot;166&quot; width=&quot;1315&quot; /&gt;&lt;/div&gt;&lt;br /&gt;Now, after clicking the &quot;Add New Form Schema&quot; link you will see the page below. The following information is needed:&lt;br /&gt;1) Display Name - &lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;required&lt;/span&gt;&lt;br /&gt;&lt;/b&gt;2) Data Entry Frequency -&lt;b&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;required&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;3) Validity Period &lt;b style=&quot;color: rgb(255, 0, 0);&quot;&gt;-optional&lt;br /&gt;&lt;/b&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;4) Description - &lt;b style=&quot;color: rgb(255, 0, 0);&quot;&gt;optional&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;5) Sections specified in this form schema (and the ordering) -- just drag them into the left-side of the pane.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;Now, for the shortcomings:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Ordering of questions cannot be changed once saved&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Sections cannot be associated with two schemas at once.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div id=&quot;dgw4&quot; style=&quot;text-align: left;&quot;&gt;&lt;img src=&quot;http://docs.google.com/File?id=df8w66j7_67c4jf6pgb_b&quot; height=&quot;479&quot; width=&quot;1299&quot; /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size:180%;&quot;&gt;&lt;u&gt;&lt;b&gt;Viewing and Entering Data&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Will be completed at a later date.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://robby.oconnor.ninja/feeds/3846840962964561413/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1083890928935553699/3846840962964561413' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/3846840962964561413'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/3846840962964561413'/><link rel='alternate' type='text/html' href='http://robby.oconnor.ninja/2009/08/facility-data-module-user-guide.html' title='Facility Data Module User Guide'/><author><name>Robby O&#39;Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1083890928935553699.post-8489999414382386844</id><published>2009-08-04T06:51:00.004-04:00</published><updated>2009-08-04T07:01:55.277-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="facility data module"/><category scheme="http://www.blogger.com/atom/ns#" term="foss"/><category scheme="http://www.blogger.com/atom/ns#" term="google summer of code"/><category scheme="http://www.blogger.com/atom/ns#" term="gsoc"/><category scheme="http://www.blogger.com/atom/ns#" term="hfoss"/><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><title type='text'>Project Update</title><content type='html'>So we&#39;re in the home stretch folks! 13 days to go until the &quot;Pencils Down&quot; date! Hope everybody&#39;s project is going well. Here&#39;s how mine is going:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Reports can be saved and reloaded (with all relevant data filled out (fields etc -- reports can be viewed in editable or &quot;view only&quot; mode).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Each component of the report (Questions, Form Questions(allows a question to exist on multiple reports), and Sections can be created in isolation&lt;/li&gt;&lt;li&gt;A page to view the status of a report (complete, partially complete or incomplete) is done for reports that are to be entered daily in a monthly calendar view; monthly still needs to be completed. &lt;/li&gt;&lt;/ul&gt;Overall, i feel the project is progressing well -- I expect to finish either on time, or early. (Let&#39;s hope for early!)&lt;br /&gt;&lt;br /&gt;Cheers!</content><link rel='replies' type='application/atom+xml' href='http://robby.oconnor.ninja/feeds/8489999414382386844/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1083890928935553699/8489999414382386844' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/8489999414382386844'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/8489999414382386844'/><link rel='alternate' type='text/html' href='http://robby.oconnor.ninja/2009/08/project-update.html' title='Project Update'/><author><name>Robby O&#39;Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><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><category scheme="http://www.blogger.com/atom/ns#" term="facility data module"/><category scheme="http://www.blogger.com/atom/ns#" term="gsoc"/><category scheme="http://www.blogger.com/atom/ns#" term="hfoss"/><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><title type='text'>Midterm Progress Update</title><content type='html'>Progress has been slow and steady. I&#39;m on track to finish however! What&#39;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&#39;s left:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Management pages See &lt;a href=&quot;http://is.gd/1AAmo&quot;&gt;this&lt;/a&gt; and &lt;a href=&quot;http://is.gd/1AAox&quot;&gt;this&lt;/a&gt; for what it will ultimately look like.&lt;/li&gt;&lt;li&gt;Still need to get the &quot;View Only&quot; pages working; in theory it should work. The &quot;View Only&quot; 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&#39;t be too bad.</content><link rel='replies' type='application/atom+xml' href='http://robby.oconnor.ninja/feeds/8627342073928215552/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1083890928935553699/8627342073928215552' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/8627342073928215552'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/8627342073928215552'/><link rel='alternate' type='text/html' href='http://robby.oconnor.ninja/2009/07/midterm-progress-update.html' title='Midterm Progress Update'/><author><name>Robby O&#39;Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1083890928935553699.post-5683637485562081848</id><published>2009-06-21T00:00:00.009-04:00</published><updated>2009-08-02T23:30:25.624-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="facility data module"/><category scheme="http://www.blogger.com/atom/ns#" term="foss"/><category scheme="http://www.blogger.com/atom/ns#" term="gsoc"/><category scheme="http://www.blogger.com/atom/ns#" term="hfoss"/><category scheme="http://www.blogger.com/atom/ns#" term="java"/><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><category scheme="http://www.blogger.com/atom/ns#" term="soc"/><title type='text'>The overdue progress report</title><content type='html'>Apologies for not blogging as much as I should. I&#39;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=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;span style=&quot;background-color: rgb(255, 255, 255);&quot;&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&#39;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 &quot;freetext&quot; -- 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: &quot;not_stocked_out&quot;,&quot;stocked_out&quot;,&quot;expired&quot;,&quot;not_applicable&quot;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;BooleanCodedQuestion  &lt;/b&gt;is a simple &quot;yes&quot;,&quot;no&quot;,&quot;not applicable&quot; type of thing; e.g., &quot;Was there mobile clinic today?&quot;&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., &quot;Number of Adults Vaccinated.&quot;&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 for a specified period. &lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Hopefully this makes up for my lack of updates.</content><link rel='replies' type='application/atom+xml' href='http://robby.oconnor.ninja/feeds/5683637485562081848/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1083890928935553699/5683637485562081848' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/5683637485562081848'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/5683637485562081848'/><link rel='alternate' type='text/html' href='http://robby.oconnor.ninja/2009/06/overdue-progress-report.html' title='The overdue progress report'/><author><name>Robby O&#39;Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><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><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"/><category scheme="http://www.blogger.com/atom/ns#" term="soc"/><title type='text'>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!</content><link rel='replies' type='application/atom+xml' href='http://robby.oconnor.ninja/feeds/2638054448112847234/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1083890928935553699/2638054448112847234' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/2638054448112847234'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/2638054448112847234'/><link rel='alternate' type='text/html' href='http://robby.oconnor.ninja/2009/06/long-overdue-progress-report.html' title='The long overdue progress report'/><author><name>Robby O&#39;Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><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><category scheme="http://www.blogger.com/atom/ns#" term="foss"/><category scheme="http://www.blogger.com/atom/ns#" term="hfoss"/><category scheme="http://www.blogger.com/atom/ns#" term="openeverything"/><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><category scheme="http://www.blogger.com/atom/ns#" term="soc"/><title type='text'>Open Everything NYC Recap</title><content type='html'>I attended &lt;a href=&quot;http://nyc.openeverything.us&quot;&gt;Open Everything NYC&lt;/a&gt; on Saturday. For those who do not know, Open Everything is an &quot;un-conference&quot; 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&#39;s all on the &lt;a href=&quot;http://openeverything.wik.is/New_York/New_York_City&quot;&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=&quot;http://openeverything.wik.is/New_York/New_York_City&quot;&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&#39;s possible to do this ongoing, I&#39;d REALLY enjoy that. I met some freaking awesome people.&lt;br /&gt;&lt;br /&gt;We were to screen RIP: &quot;A REMIX MANIFESTO&quot; at McFaddens Bar and Pub by the UN, but the owner didn&#39;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.</content><link rel='replies' type='application/atom+xml' href='http://robby.oconnor.ninja/feeds/8690191771014302701/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1083890928935553699/8690191771014302701' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/8690191771014302701'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/8690191771014302701'/><link rel='alternate' type='text/html' href='http://robby.oconnor.ninja/2009/04/open-everything-nyc-recap.html' title='Open Everything NYC Recap'/><author><name>Robby O&#39;Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><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><category scheme="http://www.blogger.com/atom/ns#" term="facility data module"/><category scheme="http://www.blogger.com/atom/ns#" term="gsoc"/><category scheme="http://www.blogger.com/atom/ns#" term="hfoss"/><category scheme="http://www.blogger.com/atom/ns#" term="java"/><category scheme="http://www.blogger.com/atom/ns#" term="open source"/><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><title type='text'>Accepted into Google Summer of Code 2009</title><content type='html'>For the second year in a row, I was &lt;a href=&quot;http://twitter.com/robbyoconnor/status/1568071039&quot;&gt;accepted&lt;/a&gt; into &lt;a href=&quot;http://socghop.appspot.com&quot;&gt;Google Summer of Code&lt;/a&gt;!!! I will be working with &lt;a href=&quot;http://www.openmrs.org&quot;&gt;OpenMRS&lt;/a&gt; on the &lt;a href=&quot;http://socghop.appspot.com/student_project/show/google/gsoc2009/openmrs/t124023038249&quot;&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.</content><link rel='replies' type='application/atom+xml' href='http://robby.oconnor.ninja/feeds/6947909951232620345/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1083890928935553699/6947909951232620345' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/6947909951232620345'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/6947909951232620345'/><link rel='alternate' type='text/html' href='http://robby.oconnor.ninja/2009/04/accepted-into-google-summer-of-code.html' title='Accepted into Google Summer of Code 2009'/><author><name>Robby O&#39;Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><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><category scheme="http://www.blogger.com/atom/ns#" term="google summer of code"/><category scheme="http://www.blogger.com/atom/ns#" term="groovy forms module"/><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><category scheme="http://www.blogger.com/atom/ns#" term="soc"/><title type='text'>Groovy Forms Module is NOT dead</title><content type='html'>Hey folks! &lt;br /&gt;&lt;br /&gt;I&#39;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&#39;m sorry for the long delay.&lt;br /&gt;&lt;br /&gt;That is all.</content><link rel='replies' type='application/atom+xml' href='http://robby.oconnor.ninja/feeds/1278017806932116731/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1083890928935553699/1278017806932116731' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/1278017806932116731'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/1278017806932116731'/><link rel='alternate' type='text/html' href='http://robby.oconnor.ninja/2009/02/groovy-forms-module.html' title='Groovy Forms Module is NOT dead'/><author><name>Robby O&#39;Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><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><category scheme="http://www.blogger.com/atom/ns#" term="google summer of code"/><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="openmrs"/><title type='text'>GSoC wrap-up</title><content type='html'>The program officially ended on August 18&lt;sup&gt;th&lt;/sup&gt;. I&#39;m awaiting the arrival of my t-shirt!! &lt;br /&gt;&lt;br /&gt;Now, I didn&#39;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&#39;m going to devote to finishing up this project.&lt;br /&gt;&lt;br /&gt;I&#39;d like to thank the following:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href=&quot;http://blog.burkeware.com/&quot;&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=&quot;http://blog.eflow.org/&quot;&gt;Ben Wolfe&lt;/a&gt; for putting up with me and helping me when &lt;a href=&quot;http://blog.burkeware.com/&quot;&gt;Burke&lt;/a&gt; was MIA.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;&lt;a href=&quot;http://www.openmrs.org/&quot;&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=&quot;http://docpaul.wordpress.com&quot;&gt;Paul Biondich&lt;/a&gt; for encouraging me (along with &lt;a href=&quot;http://blog.burkeware.com&quot;&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=&quot;http://www.hawthornlandings.org/&quot;&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&#39;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.</content><link rel='replies' type='application/atom+xml' href='http://robby.oconnor.ninja/feeds/2335388825686052165/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1083890928935553699/2335388825686052165' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/2335388825686052165'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/2335388825686052165'/><link rel='alternate' type='text/html' href='http://robby.oconnor.ninja/2008/09/gsoc-wrap-up.html' title='GSoC wrap-up'/><author><name>Robby O&#39;Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><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><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="groovy forms module"/><category scheme="http://www.blogger.com/atom/ns#" term="gsoc"/><category scheme="http://www.blogger.com/atom/ns#" term="open source"/><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><category scheme="http://www.blogger.com/atom/ns#" term="programming"/><title type='text'>GSoC 2008: We&#39;re in the home stretch</title><content type='html'>Well folks, I can&#39;t believe it&#39;s almost over. What a journey. I never imagined I&#39;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&#39;s highlight what &lt;span style=&quot;font-weight: bold;&quot;&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&#39;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.</content><link rel='replies' type='application/atom+xml' href='http://robby.oconnor.ninja/feeds/6494743798965084334/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1083890928935553699/6494743798965084334' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/6494743798965084334'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/6494743798965084334'/><link rel='alternate' type='text/html' href='http://robby.oconnor.ninja/2008/08/gsoc-2008-were-in-home-stretch.html' title='GSoC 2008: We&#39;re in the home stretch'/><author><name>Robby O&#39;Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1083890928935553699.post-4086146737965789331</id><published>2008-07-02T02:47:00.017-04:00</published><updated>2009-08-27T23:21:32.190-04:00</updated><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="groovy forms module"/><category scheme="http://www.blogger.com/atom/ns#" term="gsoc"/><category scheme="http://www.blogger.com/atom/ns#" term="java"/><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="js"/><category scheme="http://www.blogger.com/atom/ns#" term="open source"/><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><category scheme="http://www.blogger.com/atom/ns#" term="soc"/><title type='text'>GSOC 2008: Week 5</title><content type='html'>So, it&#39;s time for an update. This week got off to a sketchy start, but it&#39;s gained momentum. Let me enumerate what I have done thus far with the project. First, I&#39;ve added AJAX using &lt;a href=&quot;http://www.jquery.com/&quot;&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=&quot;http://java.sun.com/developer/technicalArticles/J2EE/AJAX/RealtimeValidation/index.html&quot;&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&#39;t feel too elegant. So, first I&#39;m going to show the AJAX code I wrote; then I&#39;ll show you the jquery version; finally, I&#39;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 class=&quot;brush:js&quot; name=&quot;code&quot;&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(&quot;Mircosoft.XMLHTTP&quot;)&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;&lt;br /&gt;    this.doGet = function() {&lt;br /&gt;        req.open(&quot;GET&quot;, 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(&quot;result&quot;)[0].firstChild.nodeValue&lt;br /&gt;    document.getElementById(&quot;out&quot;).innerHTML = res&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function checkSyntax() {&lt;br /&gt;    var target = document.getElementById(&quot;groovyModel&quot;)&lt;br /&gt;    var url = &quot;${pageContext.request.contextPath}/moduleServlet/groovyforms/createGroovyForm?groovyModel=&quot; + escape(target.value)&lt;br /&gt;    var ajax = new AjaxValidation(url, chkSyntaxCallBack)&lt;br /&gt;    ajax.doGet()&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I warned you that it wasn&#39;t too elegant. Understanding this isn&#39;t too hard. Here is the call sequence: &lt;code&gt;init() -&amp;gt; doGet() -&amp;gt; processRequest() -&amp;gt; chkSyntaxCallBack()&lt;/code&gt;. Not that bad. Now let&#39;s see the jquery version.&lt;br /&gt;&lt;pre class=&quot;brush:js&quot; name=&quot;code&quot;&gt;&lt;br /&gt;$(window).ready(function () {&lt;br /&gt;    $(&quot;#groovyModel&quot;).bind(&quot;blur&quot;, function () {&lt;br /&gt;        $.ajax({&lt;br /&gt;            type: &#39;POST&#39;,&lt;br /&gt;            data: { groovyModel: $(&quot;#groovyModel&quot;).val() } ,&lt;br /&gt;            url: &quot;${pageContext.request.contextPath}/moduleServlet/groovyforms/createGroovyForm&quot; ,&lt;br /&gt;            cache: false ,&lt;br /&gt;            success: function(data) {&lt;br /&gt;                var res = $(data).find(&quot;result&quot;).text()&lt;br /&gt;                $(&quot;#out&quot;).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&#39;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 &quot;groovyModel&quot; to the blur event (lost focus). Then you see the AJAX. Now this is very straight forward. We&#39;re using the &lt;b&gt;POST&lt;/b&gt; method, we&#39;re sending whatever value is inside of the textarea at the time the event is fired, we&#39;re posting to a servlet, not going to cache, and when we&#39;re done, it&#39;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=&quot;http://groovy.codehaus.org/&quot;&gt;Groovy&lt;/a&gt;. So here we go: &lt;br /&gt;&lt;pre class=&quot;brush:groovy&quot; name=&quot;code&quot;&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 &quot;License&quot;) 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 &quot;AS IS&quot;&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(&quot;template&quot;)&lt;br /&gt;    def generateController = request.getParameter(&quot;controller&quot;)&lt;br /&gt;    def finalMarkup = request.getParameter(&quot;markup&quot;)&lt;br /&gt;    def clazz = URLDecoder.decode(request.getParameter(&quot;groovyModel&quot;))&lt;br /&gt;    def name = request.getParameter(&quot;formName&quot;)&lt;br /&gt;    def version = request.getParameter(&quot;version&quot;)&lt;br /&gt;    def res = this.checkSyntax(clazz)&lt;br /&gt;    if (clazz) {&lt;br /&gt;      if (checkSyntax(clazz)) {&lt;br /&gt;        response.contentType = &quot;text/xml&quot;&lt;br /&gt;        response.setHeader &quot;Cache-Conrol&quot;, &quot;no-cache&quot;&lt;br /&gt;        response.writer.write &quot;&lt;result&gt;\n\t$res\n&lt;/result&gt;&quot;&lt;br /&gt;      } else {&lt;br /&gt;        response.contentType = &quot;text/xml&quot;&lt;br /&gt;        response.setHeader &quot;Cache-Control&quot;, &quot;no-cache&quot;&lt;br /&gt;        response.writer.write &quot;&lt;result&gt;true&lt;/result&gt;&quot;&lt;br /&gt;      }&lt;br /&gt;    } else {&lt;br /&gt;      response.contentType = &quot;text/xml&quot;&lt;br /&gt;      response.setHeader &quot;Cache-Control&quot;, &quot;no-cache&quot;&lt;br /&gt;      response.writer.write &quot;&lt;result&gt;\n\tPlease fill in the Form Model\n&lt;/result&gt;&quot;&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(&quot;Initializing...&quot;)&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; &quot;import org.openmrs.*\n\n\n&quot;&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 = &quot;Exception: ${e.message}&quot;&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; &quot;import org.openmrs.*\n\n\n&quot;&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;/pre&gt;&lt;br /&gt;&lt;br /&gt;This servlet contains a lot of utility methods. One compiles, one initializes/returns the &lt;a href=&quot;http://groovy.codehaus.org/gapi/groovy/lang/GroovyClassLoader.html&quot;&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&#39;t be useful in my case. It returns an XML tag &amp;lt;result&amp;gt; with &quot;true&quot; if it was successful, the exception message if it was not, and a message stating that the field must be filled in if it&#39;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&#39;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&#39;s done. Just have a few problems I&#39;m facing, but I&#39;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 &quot;Edit&quot; functionality of the &quot;Manage Groovy Forms&quot; page.&lt;br /&gt;&lt;br /&gt;I&#39;m definately making progress. More updates to come, that&#39;s for sure.</content><link rel='replies' type='application/atom+xml' href='http://robby.oconnor.ninja/feeds/4086146737965789331/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1083890928935553699/4086146737965789331' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/4086146737965789331'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/4086146737965789331'/><link rel='alternate' type='text/html' href='http://robby.oconnor.ninja/2008/07/gsoc-2008-week-5.html' title='GSOC 2008: Week 5'/><author><name>Robby O&#39;Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><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><category scheme="http://www.blogger.com/atom/ns#" term="dwr"/><category scheme="http://www.blogger.com/atom/ns#" term="groovy"/><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="java"/><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><category scheme="http://www.blogger.com/atom/ns#" term="soc"/><title type='text'>GSoC 2008: Groovy Forms getting some AJAX!</title><content type='html'>No, not the cleaning product! The &quot;Web 2.0&quot; 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=&quot;http://www.directwebremoting.org/dwr&quot;&gt;Direct Web Remoting (DWR)&lt;/a&gt; to provide a link between my backend java codebase and the front-end javascript! It&#39;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=&quot;http://xstream.codehaus.org/&quot;&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=&quot;http://www.openmrs.org/&quot;&gt;OpenMRS&lt;/a&gt; install and you&#39;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=&quot;http://www.directwebremoting.org/dwr&quot;&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=&quot;http://openmrs.org/wiki/GroovyForms_Module&quot;&gt;groovy form&lt;/a&gt;. Don&#39;t fear, I&#39;m going to go overboard with AJAX! It&#39;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&#39;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&#39;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=&quot;http://groovy.codehaus.org/&quot;&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=&quot;http://img522.imageshack.us/img522/897/manageforms2mp5.png&quot;&gt;One&lt;/a&gt; and &lt;a href=&quot;http://img103.imageshack.us/img103/4825/manageformsuc2.png&quot;&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&#39;s a great design, of course I&#39;m biased since It was was me who designed it.</content><link rel='replies' type='application/atom+xml' href='http://robby.oconnor.ninja/feeds/6882837065981235794/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1083890928935553699/6882837065981235794' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/6882837065981235794'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/6882837065981235794'/><link rel='alternate' type='text/html' href='http://robby.oconnor.ninja/2008/06/gsoc-2008-groovy-forms-getting-some.html' title='GSoC 2008: Groovy Forms getting some AJAX!'/><author><name>Robby O&#39;Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><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><category scheme="http://www.blogger.com/atom/ns#" term="gsoc"/><category scheme="http://www.blogger.com/atom/ns#" term="hypopara"/><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><title type='text'>GSoC 2008: Updates and such</title><content type='html'>Okay, let&#39;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&#39;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&#39;t accomplished much, but there&#39;s a reason, I swear!&lt;br /&gt;&lt;br /&gt;June 11th I went to Rockville, MD to the &lt;a href=&quot;http://hpth.org/&quot;&gt;Hypoparathyroidism Association&lt;/a&gt;&#39;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&#39;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&#39;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&#39;s such a rare disease that I don&#39;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.</content><link rel='replies' type='application/atom+xml' href='http://robby.oconnor.ninja/feeds/899389761943681110/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1083890928935553699/899389761943681110' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/899389761943681110'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/899389761943681110'/><link rel='alternate' type='text/html' href='http://robby.oconnor.ninja/2008/06/gsoc-2008-updates-and-such.html' title='GSoC 2008: Updates and such'/><author><name>Robby O&#39;Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><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><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="java"/><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><category scheme="http://www.blogger.com/atom/ns#" term="soc"/><title type='text'>Well, that&#39;s so NOT groovy</title><content type='html'>So, I was working on my &lt;a href=&quot;http://openmrs.org/wiki/GroovyForms_Module&quot;&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=&quot;http://groovy.codehaus.org/The+groovyc+Ant+Task&quot;&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&#39;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&#39;t everything included in the groovy jar?&lt;br /&gt;&lt;br /&gt;The problem: NoClassDefFoundError on &lt;a href=&quot;http://dpml.net/api/ant/1.7.0/org/apache/tools/ant/taskdefs/MatchingTask.html&quot;&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.</content><link rel='replies' type='application/atom+xml' href='http://robby.oconnor.ninja/feeds/1326549730017982636/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1083890928935553699/1326549730017982636' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/1326549730017982636'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/1326549730017982636'/><link rel='alternate' type='text/html' href='http://robby.oconnor.ninja/2008/06/wellthats-so-not-groovy.html' title='Well, that&#39;s so NOT groovy'/><author><name>Robby O&#39;Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1083890928935553699.post-1922241087289487880</id><published>2008-05-31T00:48:00.009-04:00</published><updated>2009-08-27T23:15:40.094-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="closures"/><category scheme="http://www.blogger.com/atom/ns#" term="google"/><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="groovy forms module"/><category scheme="http://www.blogger.com/atom/ns#" term="gsoc"/><category scheme="http://www.blogger.com/atom/ns#" term="java"/><category scheme="http://www.blogger.com/atom/ns#" term="open source"/><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><category scheme="http://www.blogger.com/atom/ns#" term="soc"/><title type='text'>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=&quot;http://robbyoconnor.blogspot.com/2008/05/gsoc-2008-progress-report.html&quot;&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=&quot;http://dev.openmrs.org/browser/openmrs-modules/groovyforms/src/org/openmrs/module/groovyforms/metadata/model/GroovyFormsContainer.java&quot;&gt;container class&lt;/a&gt;. I wound up updating to &lt;a href=&quot;http://www.junit.org&quot;&gt;JUnit 4&lt;/a&gt; to get at the &lt;a href=&quot;http://junit.sourceforge.net/javadoc_40/org/junit/BeforeClass.html&quot;&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&quot;http://junit.sourceforge.net/javadoc_40/org/junit/AfterClass.html&quot;&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=&quot;http://groovy.codehaus.org&quot;&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&#39;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=&quot;code&quot; class=&quot;brush:groovy&quot;&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;br /&gt;&lt;/pre&gt;&lt;br /&gt;With groovy, it&#39;s so easy and concise (as you can see). Let&#39;s explain what&#39;s going on. First, I pass in the Field array I get from &lt;a href=&quot;http://java.sun.com/javase/6/docs/api/java/lang/Class.html#getDeclaredFields()&quot;&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=&quot;http://groovy.codehaus.org/Closures&quot;&gt;closure&lt;/a&gt;. Now, back to the point, I pass a &lt;a href=&quot;http://java.sun.com/javase/6/docs/api/java/lang/reflect/Field.html&quot;&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=&quot;code&quot; class=&quot;brush:groovy&quot;&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&#39;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&#39;m already having fun doing this. It&#39;s amazing seeing the whole project evolve into something amazing.</content><link rel='replies' type='application/atom+xml' href='http://robby.oconnor.ninja/feeds/1922241087289487880/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1083890928935553699/1922241087289487880' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/1922241087289487880'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/1922241087289487880'/><link rel='alternate' type='text/html' href='http://robby.oconnor.ninja/2008/05/gsoc-2008-week-1.html' title='GSoC 2008: Week 1'/><author><name>Robby O&#39;Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1083890928935553699.post-1908500793546013344</id><published>2008-05-29T00:58:00.010-04:00</published><updated>2009-08-31T15:10:48.284-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="google summer of code"/><category scheme="http://www.blogger.com/atom/ns#" term="gsoc"/><category scheme="http://www.blogger.com/atom/ns#" term="java"/><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><category scheme="http://www.blogger.com/atom/ns#" term="regex"/><category scheme="http://www.blogger.com/atom/ns#" term="regexp"/><category scheme="http://www.blogger.com/atom/ns#" term="regular expressions"/><title type='text'>GSoC 2008: Progress report</title><content type='html'>I have made a lot of &lt;a href=&quot;http://openmrs.org/wiki/GroovyForms_Module#Completed_Goals&quot;&gt;progress&lt;/a&gt; on my &lt;a href=&quot;http://code.google.com/soc/2008&quot;&gt;Google Summer of Code&lt;/a&gt; &lt;a href=&quot;http://openmrs.org/wiki/GroovyForms_Module&quot;&gt;Project&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;First, I&#39;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=&quot;http://openactive.org&quot;&gt;Jason Davis&lt;/a&gt;, I was able to make it much more readable and easier digest. You&#39;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=&quot;code&quot; class=&quot;brush: groovy&quot;&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(&quot;[\\$\\(\\)%`~!@#&amp;;:\\^=\\+\\?&lt;&gt;\&quot;\\*\\\\////\\\\{\\}&#39;\\]\\[\\|\\s+]&quot;, &quot;&quot;).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&#39;s the *MUCH* simpler version:&lt;br /&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;brush: groovy&quot;&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(&quot;[^a-zA-Z0-9.]&quot;, &quot;&quot;).toLowerCase();&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Note, you can clearly see that i&#39;m negating that entire sequence. It does the &lt;b&gt;SAME&lt;/b&gt; thing, but is MUCH more readable. That reads: &quot;replace everything that isn&#39;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&#39;m using &lt;a href=&quot;http://xstream.codehaus.org&quot;&gt;xstream&lt;/a&gt;. It&#39;s a great tool for XML serialization. &lt;br /&gt;&lt;br /&gt;That&#39;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.</content><link rel='replies' type='application/atom+xml' href='http://robby.oconnor.ninja/feeds/1908500793546013344/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1083890928935553699/1908500793546013344' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/1908500793546013344'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/1908500793546013344'/><link rel='alternate' type='text/html' href='http://robby.oconnor.ninja/2008/05/gsoc-2008-progress-report.html' title='GSoC 2008: Progress report'/><author><name>Robby O&#39;Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><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><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="groovy forms module"/><category scheme="http://www.blogger.com/atom/ns#" term="gsoc"/><category scheme="http://www.blogger.com/atom/ns#" term="java"/><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><category scheme="http://www.blogger.com/atom/ns#" term="soc"/><title type='text'>Ready...Set...Code: Google Summer of Code has started!</title><content type='html'>Today was the official start of &lt;a href=&quot;http://code.google.com/soc/2008&quot;&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&#39;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=&quot;http://openmrs.org/wiki/GroovyForms_Module#Project_Plan&quot;&gt;here&lt;/a&gt;. A Google Doc which &lt;a href=&quot;http://burkeware.com&quot;&gt;my mentor&lt;/a&gt; and I used to plan the project can be found &lt;a href=&quot;http://docs.google.com/Doc?docid=df8w66j7_7c5n48z58&amp;hl=en&quot;&gt;here&lt;/a&gt;. Finally, See &lt;a href=&quot;http://robbyoconnor.blogspot.com/2008/05/google-summer-of-code-status-report.html&quot;&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!</content><link rel='replies' type='application/atom+xml' href='http://robby.oconnor.ninja/feeds/5526046742590167002/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1083890928935553699/5526046742590167002' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/5526046742590167002'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/5526046742590167002'/><link rel='alternate' type='text/html' href='http://robby.oconnor.ninja/2008/05/readysetcode-google-summer-of-code-has.html' title='Ready...Set...Code: Google Summer of Code has started!'/><author><name>Robby O&#39;Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><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><category scheme="http://www.blogger.com/atom/ns#" term="gsoc"/><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><title type='text'>Thank you so much Google!!</title><content type='html'>Today I got the coveted &quot;Google Book&quot; that all &lt;a href=&quot;http://code.google.com/soc/2008/&quot;&gt;Google Summer of Code&lt;/a&gt; students have been talking about constantly! I&#39;ve flipped through it, it&#39;s an amazing book! Want to know the name? Everybody knows it already, it&#39;s &quot;Beautiful Code&quot; by O&#39;Reilly. &lt;br /&gt;&lt;br /&gt;Thank you so much!!!!!</content><link rel='replies' type='application/atom+xml' href='http://robby.oconnor.ninja/feeds/2574777941824550177/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1083890928935553699/2574777941824550177' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/2574777941824550177'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/2574777941824550177'/><link rel='alternate' type='text/html' href='http://robby.oconnor.ninja/2008/05/thank-you-so-much-google.html' title='Thank you so much Google!!'/><author><name>Robby O&#39;Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><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><category scheme="http://www.blogger.com/atom/ns#" term="dwr"/><category scheme="http://www.blogger.com/atom/ns#" term="groovy"/><category scheme="http://www.blogger.com/atom/ns#" term="gsoc"/><category scheme="http://www.blogger.com/atom/ns#" term="java"/><category scheme="http://www.blogger.com/atom/ns#" term="open source"/><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><title type='text'>Google Summer of Code Status Report</title><content type='html'>I haven&#39;t really blogged since I last &lt;a href=&quot;http://robbyoconnor.blogspot.com/2008/04/accepted-to-google-summer-of-code.html&quot;&gt;announced&lt;/a&gt; that I was accepted into &lt;a href=&quot;http://code.google.com/soc/2008&quot;&gt;Google Summer of Code&lt;/a&gt;. I have a phone meeting with &lt;a href=&quot;http://burkeware.com/blog&quot;&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&#39;ve been enjoying the &lt;a href=&quot;http://googlesummerofcode.blogspot.com/2007/04/so-what-is-this-community-bonding-all.html&quot;&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&#39;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&#39;m gonna break this down. There&#39;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=&quot;http://getahead.org/dwr/&quot;&gt;Direct Web Remoting (DWR)&lt;/a&gt; will be used to grab all the information the users enter into the &lt;a href=&quot;http://img412.imageshack.us/img412/6167/openmrsjr4.png&quot;&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=&quot;http://java.sun.com/docs/books/tutorial/reflect/&quot;&gt;reflection&lt;/a&gt; on the Form Model and based on the data type, using a templating engine, such as &lt;a href=&quot;http://velocity.apache.org&quot;&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=&quot;http://groovy.codehaus.org/ExpandoMetaClass&quot;&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=&quot;http://groovy.codehaus.org/ExpandoMetaClass&quot;&gt;ExpandoMetaClass&lt;/a&gt; magic, i&#39;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=&quot;http://velocity.apache.org&quot;&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.</content><link rel='replies' type='application/atom+xml' href='http://robby.oconnor.ninja/feeds/6006389286474639624/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1083890928935553699/6006389286474639624' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/6006389286474639624'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/6006389286474639624'/><link rel='alternate' type='text/html' href='http://robby.oconnor.ninja/2008/05/google-summer-of-code-status-report.html' title='Google Summer of Code Status Report'/><author><name>Robby O&#39;Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><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><category scheme="http://www.blogger.com/atom/ns#" term="groovy"/><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="programming"/><title type='text'>Posting code made easier (for everybody else reading your blog!)</title><content type='html'>I&#39;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&#39;ve left comments on the blogs that didn&#39;t know this, and now they do. &lt;br /&gt;&lt;br /&gt;This message is primarily for the &lt;a href=&quot;http://code.google.com/soc/2008&quot;&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.</content><link rel='replies' type='application/atom+xml' href='http://robby.oconnor.ninja/feeds/3638032177119491713/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1083890928935553699/3638032177119491713' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/3638032177119491713'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1083890928935553699/posts/default/3638032177119491713'/><link rel='alternate' type='text/html' href='http://robby.oconnor.ninja/2008/05/posting-code-made-easier-for-everybody.html' title='Posting code made easier (for everybody else reading your blog!)'/><author><name>Robby O&#39;Connor</name><uri>http://www.blogger.com/profile/10437521195914796737</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry></feed>