{"id":56,"date":"2008-09-01T19:13:34","date_gmt":"2008-09-01T17:13:34","guid":{"rendered":"http:\/\/www.steinbeck-molecular.de\/steinblog\/?p=56"},"modified":"2008-09-01T19:13:34","modified_gmt":"2008-09-01T17:13:34","slug":"creating-and-reviewing-patches-in-the-chemistry-development-kit-cdk","status":"publish","type":"post","link":"http:\/\/www.steinbeck-molecular.de\/steinblog\/index.php\/2008\/09\/01\/creating-and-reviewing-patches-in-the-chemistry-development-kit-cdk\/","title":{"rendered":"Creating and Reviewing Patches in the Chemistry Development Kit (CDK)"},"content":{"rendered":"<p>In order to prevent major turbulences in the main source code development line of the Chemistry Development Kit (CDK), we decided a while ago to have separate branches in our subversion source code management system for each developer and each of his subprojects. Once a project has been finalized by a developer in her branch, she would then publish a patch in the <a href=\"https:\/\/sourceforge.net\/tracker\/?group_id=20024&amp;atid=320024\" target=\"_blank\">CDK patch tracker system<\/a> and ask for it to be reviewed by posting to the <a href=\"https:\/\/sourceforge.net\/mailarchive\/forum.php?forum_name=cdk-devel\" target=\"_blank\">CDK developers mailing list.<\/a> A CDK senior developer would the assign the patch to himself or another senior developer.<\/p>\n<p>I have just been assigned the task to review the recent Iterator\/Iterable patch for CDK and will protocol my task for reference reasons.The patch was <a href=\"https:\/\/sourceforge.net\/tracker\/index.php?func=detail&amp;aid=2040231&amp;group_id=20024&amp;atid=320024\" target=\"_blank\">published on the CDK patch tracker.<\/a><\/p>\n<p>The executive summary of the reviewing task goes like:<\/p>\n<ol>\n<li>browse the code<\/li>\n<li>mark up code you think is buggy<\/li>\n<li>note missing unit tests<\/li>\n<li>note missing JavaDoc<\/li>\n<li>warn for subjected PMD warnings<\/li>\n<li>optionally note other problems<\/li>\n<li>optionally any other comment you have<\/li>\n<\/ol>\n<p>So, let&#8217;s see how it went:<\/p>\n<p><strong>Browse the Code<\/strong><\/p>\n<p>I got the gzipped archive with Egon&#8217;s patch and looked at the code. A large part of the changes involve<\/p>\n<p>removing\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <code>public Iterator&lt;IIsotope&gt; isotopes() {<\/code><br \/>\nand adding\u00a0\u00a0\u00a0 <code>public Iterable&lt;IIsotope&gt; isotopes() {<br \/>\n<\/code><br \/>\nto enable things like<\/p>\n<p><code>double overallCharge = 0.0<br \/>\nfor (IAtom atom : molecule.atoms()) {<br \/>\noverallCharge += atom.getCharge();<br \/>\n}<\/code><\/p>\n<p>In order to implement Iterable, one needs to have methods returning an Iterator, so a lot of code essentially implements those.<\/p>\n<p>Remove: \u00a0\u00a0\u00a0\u00a0\u00a0 <code>public java.util.Iterator atoms() {<\/code><br \/>\nand add: \u00a0\u00a0\u00a0\u00a0 <code>public Iterable&lt;IAtom&gt; atoms() {<br \/>\nlogger.debug(\"Getting atoms iterator\");<br \/>\nreturn super.atoms();<br \/>\n}<\/code><\/p>\n<p>And then there is code actually using those iterators and all of these instances had to be adapted too (I&#8217;m just giving the patch syntax):<\/p>\n<p><code>for(IReactionScheme rm : scheme.reactionSchemes()){<br \/>\n-\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 for(Iterator&lt;IAtomContainer&gt; iter = getAllMolecules(rm, molSet).atomContainers(); iter.hasNext(); ){<br \/>\n-\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 IAtomContainer ac = iter.next();<br \/>\n-\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 boolean contain = false;<br \/>\n-\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 for(Iterator&lt;IAtomContainer&gt; it2 = molSet.molecules();it2.hasNext();){<br \/>\n-\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if(it2.next().equals(ac)){<br \/>\n-\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 contain = true;<br \/>\n-\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 break;<br \/>\n-\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }<br \/>\n-\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }<br \/>\n-\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if(!contain)<br \/>\n-\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 molSet.addMolecule((IMolecule)(ac));<br \/>\n-\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }<br \/>\n+\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 for (IAtomContainer ac : getAllMolecules(rm, molSet).atomContainers()) {<br \/>\n+\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 boolean contain = false;<br \/>\n+\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 for (IAtomContainer atomContainer : molSet.molecules()) {<br \/>\n+\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (atomContainer.equals(ac)) {<br \/>\n+\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 contain = true;<br \/>\n+\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 break;<br \/>\n+\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }<br \/>\n+\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }<br \/>\n+\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (!contain)<br \/>\n+\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 molSet.addMolecule((IMolecule) (ac));<br \/>\n+\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }<br \/>\n<\/code><\/p>\n<p>Overall, the patch affected 288 classes including test classes, with almost 2000 lines of code changed.<\/p>\n<p><strong>Mark up code you think is buggy<\/strong><\/p>\n<p>Impossible to do for me for such a large bunch of changes, so one must rely here on the unit tests to work.<\/p>\n<p><strong>Note missing unit tests<\/strong><\/p>\n<p><a href=\"http:\/\/chem-bla-ics.blogspot.com\/2007\/11\/comparing-junit-test-results-between.html\" target=\"_blank\">Egon had posted some notes about comparing failing and passing between unit tests<\/a> earlier but we also need an automatic check for unit test coverage. And yes, of course, there are limits to what such an automated coverage tool can do.<\/p>\n<p>With regard for failing unit tests, the &#8220;iterable&#8221; branch did have anymore failures and errors than the head branch.<\/p>\n<p><strong>Note missing JavaDoc<\/strong><\/p>\n<p>We&#8217;ve go DocCheck results on our CDK nightly pages but nothing tells you whether a patched method is missing neccessary JavaDoc. Presumably, we could &#8220;grep&#8221; the patches class names into a DocCheck input file and get customized info about it.<\/p>\n<p><strong>Warn for subjected PMD warnings<\/strong><\/p>\n<p>PMD is a tool for checking code with respect to adherence to certain coding standards.Again, the <a href=\"http:\/\/cheminfo.informatics.indiana.edu\/~rguha\/code\/java\/nightly\/\" target=\"_blank\">CDK nightly page<\/a> contains all PMD reports on the CDK code, generated in nightly runs. The same can be achieved for each branch with a &#8220;ant -f pmd.xml&#8221;\u00a0 on your local copy of the branch.<\/p>\n<p><strong>Optionally note other problems<\/strong><\/p>\n<p>I love optional things and tend to let them be optional<\/p>\n<p><strong>Optionally any other comment you have<\/strong><\/p>\n<p>Dto.<\/p>\n<p>So, overall I would like to conclude that according to the best of my knowledge, the Iterable patch should be safe and can be applied to the HEAD branch. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>In order to prevent major turbulences in the main source code development line of the Chemistry Development Kit (CDK), we decided a while ago to have separate branches in our subversion source code management system for each developer and each of his subprojects. Once a project has been finalized by a developer in her branch, [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[23,14,27,18,29],"tags":[],"class_list":["post-56","post","type-post","status-publish","format-standard","hentry","category-chemistry-development-kit","category-life-of-chris","category-open-source","category-open-standards","category-scientific-culture"],"_links":{"self":[{"href":"http:\/\/www.steinbeck-molecular.de\/steinblog\/index.php\/wp-json\/wp\/v2\/posts\/56"}],"collection":[{"href":"http:\/\/www.steinbeck-molecular.de\/steinblog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.steinbeck-molecular.de\/steinblog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.steinbeck-molecular.de\/steinblog\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/www.steinbeck-molecular.de\/steinblog\/index.php\/wp-json\/wp\/v2\/comments?post=56"}],"version-history":[{"count":0,"href":"http:\/\/www.steinbeck-molecular.de\/steinblog\/index.php\/wp-json\/wp\/v2\/posts\/56\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.steinbeck-molecular.de\/steinblog\/index.php\/wp-json\/wp\/v2\/media?parent=56"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.steinbeck-molecular.de\/steinblog\/index.php\/wp-json\/wp\/v2\/categories?post=56"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.steinbeck-molecular.de\/steinblog\/index.php\/wp-json\/wp\/v2\/tags?post=56"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}