{"id":47,"date":"2004-10-20T21:52:29","date_gmt":"2004-10-20T11:52:29","guid":{"rendered":"http:\/\/thekua.com\/rant\/?p=47"},"modified":"2004-10-20T21:58:58","modified_gmt":"2004-10-20T11:58:58","slug":"the-value-in-checking-your-style","status":"publish","type":"post","link":"https:\/\/thekua.com\/rant\/2004\/10\/the-value-in-checking-your-style\/","title":{"rendered":"The Value in Checking Your Style"},"content":{"rendered":"<p>Increasing code quality is something that is currently being driven hard in our project. I am a big fan of weeding out code to make way for better smelling things like patterns and easily unit testable code. Many people have attempted to quantify code quality using metrics and a variety of tools to enforce these metrics. Checkstyle is one of these tools that we employ to encourage code quality (I qualify this because using these tools do not automatically equate to high quality code). <\/p>\n<p><!--more-->If you haven&#8217;t heard of it before, it&#8217;s a tool that helps to enforce coding standards in your project (and you should read more <a href=\"http:\/\/checkstyle.sourceforge.net\/\">here<\/a>). It can be used (and abused by project nazis) to enforce all types of coding standards from the most mediocre of coding formatting standards (have these people not heard of <a href=\"http:\/\/jalopy.sourceforge.net\">Jalopy<\/a>?) to preventing code that is known to be poor design or quality from being added. <\/p>\n<p>Take the following block of code which can be picked up by the <a href=\"http:\/\/checkstyle.sourceforge.net\/config_coding.html#IllegalInstantiation\">IllegalInstantiation<\/a> check:<\/p>\n<blockquote><p><code>\/\/ code that creates a new and unnecessary boolean object<br \/>\nBoolean isRedundant = new Boolean(true); <\/code><\/p><\/blockquote>\n<p>Although the JDK allows you do this, it is preferred that the following is used instead:<\/p>\n<blockquote><p><code>\/\/ code that reuses the same reference as Boolean.TRUE<br \/>\nBoolean isRendant = Boolean.valueOf(true); <\/code><\/p><\/blockquote>\n<p>Code formatting standards aside (still a very useful item for consistency and a whole another blog entry together), I believe the biggest value that checkstyle can bring are the custom checks that can be (easily written and) added for a specific project. The value behind custom checks (at least to me) is an obvious one. As a project ages over time, certain standard design patterns are used to approach a particular type of problem. Part of the induction cost of new programmers to a team is the knowledge transfer that happens over time as they are gradually exposed to all of the code base and learn these implict patterns that are littered throughtout the code. Quantifying these standards as custom checks is a less costly, and more reliable way ensuring new programmers do not violate these implicit standards, and more importantly can instantly gain the knowledge from the lessons learned by the current team. <\/p>\n<p>On the project I am currently on, I contributed a custom check as a sanity check to ensure that whenever a session (think of a database connection) was opened, a corresponding close was called within the same method scope (with the intention of minimising the chances of leaving any sessions open).<\/p>\n<p><!--nextpage-->See the following code:<\/p>\n<blockquote><p><code>package com.example.of.custom.checks;<\/code><\/p>\n<p><code>import com.puppycrawl.tools.checkstyle.api.Check;<\/code><br \/>\n<code>import com.puppycrawl.tools.checkstyle.api.TokenTypes;<\/code><br \/>\n<code>import com.puppycrawl.tools.checkstyle.api.DetailAST;<\/code><\/p>\n<p><code>\/**<\/code><br \/>\n<code> * Each method that calls a createSession() method should have a corresponding<\/code><br \/>\n<code> * close call to ensure that the database connection is closed. It is good practice<\/code><br \/>\n<code> * to have the same method that calls the createSession() to call the close() <\/code><br \/>\n<code> * method as well as it makes it easier to see that we do not leak open connections.<\/code><br \/>\n<code> * <\/code><br \/>\n<code> * NOTE: The algorithm for ensuring all opened sessions are closed can probably be improved.<\/code><br \/>\n<code> *\/<\/code><br \/>\n<code>public class SessionClosingCheck extends Check {<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;\/**<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* Name of the call to the create session method.<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*\/<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public static final String SESSION_CREATE = \"createSession\";<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;\/**<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* Name of the method that closes the session.<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*\/<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public static final String SESSION_CLOSE = \"close\";<\/code><\/p>\n<p><code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;\/**<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* Context for a method storing the details about calls to createSession and close.<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*\/<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private SessionClosingContext sessionClosingContext;<\/code><\/p>\n<p><code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;\/**<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* For each createSession() we increase the call to the numberOfSessions. For each<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* call to close (as long as it is a session object), we can decrement it.<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* If we reach the end of the file, and we have more than 0 then we have a problem.<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* @return List of tokens that trigger a call to the visitToken method.<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*\/<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public int[] getDefaultTokens() {<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return new int[] {<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TokenTypes.METHOD_DEF,  \/\/ Check based on each method declared.<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TokenTypes.IDENT,       \/\/ for calls to session.close() and createSession()<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}<\/code><\/p>\n<p><code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;\/**<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* Handle visiting a method and visiting an IDENT token.<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*\/<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public void visitToken(DetailAST detailAST) {<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;switch (detailAST.getType()) {<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case TokenTypes.METHOD_DEF:<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sessionClosingContext = new SessionClosingContext();<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sessionClosingContext.visitMethodDef(detailAST);<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case TokenTypes.IDENT:<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;\/\/ Only check method calls in a method declaration<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (sessionClosingContext != null) {<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sessionClosingContext.visitIdent(detailAST);<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break;<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}<\/code><\/p>\n<p><code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;\/**<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* When we leave the method declaration, check the context and then log failure of<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* a check if conditions have not been met.<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*\/<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public void leaveToken(DetailAST detailAST) {<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (TokenTypes.METHOD_DEF == detailAST.getType()) {<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (sessionClosingContext != null &amp;&amp; !sessionClosingContext.haveAllSessionsBeenClosed()) {<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;log(detailAST.getLineNo(), \"The count to close() is not more than that of createSession()\");<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;\/\/ Reset the context<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sessionClosingContext = null;<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}<\/code><\/p>\n<p><code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;\/**<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* Return the method name given a AST that was found for a MethodDef.<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*\/<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private String getMethodName(DetailAST methodAST) {<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return methodAST.findFirstToken(TokenTypes.IDENT).getText();<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}<\/code><\/p>\n<p><code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;\/**<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* Context class for each method. Within a method definition, we want to keep<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* track of the number of calls to createSession() and then the number of calls<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* to close(). We then compare these at the end of a method call to tell whether<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* or not we have closed all connections we may have opened.<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*\/<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private class SessionClosingContext {<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;\/\/ Number of calls found for createSession<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private int sessionCreateCalls = 0;<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;\/\/ Number of calls found for close<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private int sessionCloseCalls = 0;<\/code><\/p>\n<p><code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;\/**<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* Visit the IDENT tokens. In this case we are interested in only the calls<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* to createSession and close.<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*\/<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public void visitIdent(DetailAST identAST) {<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (SESSION_CLOSE.equals(identAST.getText())) {<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sessionCloseCalls++;<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} else if (SESSION_CREATE.equals(identAST.getText())) {<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sessionCreateCalls++;<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}<\/code><\/p>\n<p><code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;\/**<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* If the createSession is actually a method declaration, we are going to count<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* an additional call to createSession without ignoring it. This method <\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* ensures that we don't count these.<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*\/<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public void visitMethodDef(DetailAST detailAST) {<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (SESSION_CREATE.equals(getMethodName(detailAST))) {<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sessionCreateCalls--;<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}<\/code><\/p>\n<p><code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;\/**<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* Check whether or not all sessions have been closed. Ensure that the count to<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* close() is greater than or equal to the number of session creates.<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*\/<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public boolean haveAllSessionsBeenClosed() {<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return sessionCloseCalls &gt;= sessionCreateCalls;<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}<\/code><br \/>\n<code>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}<\/code><br \/>\n<code>}<\/code>\n<\/p><\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>Increasing code quality is something that is currently being driven hard in our project. I am a big fan of weeding out code to make way for better smelling things like patterns and easily unit testable code. Many people have attempted to quantify code quality using metrics and a variety of tools to enforce these [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[39],"class_list":["post-47","post","type-post","status-publish","format-standard","hentry","category-technical","tag-work-related"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>The Value in Checking Your Style - thekua.com@rest<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/thekua.com\/rant\/2004\/10\/the-value-in-checking-your-style\/\" \/>\n<link rel=\"next\" href=\"https:\/\/thekua.com\/rant\/2004\/10\/the-value-in-checking-your-style\/2\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"The Value in Checking Your Style - thekua.com@rest\" \/>\n<meta property=\"og:description\" content=\"Increasing code quality is something that is currently being driven hard in our project. I am a big fan of weeding out code to make way for better smelling things like patterns and easily unit testable code. Many people have attempted to quantify code quality using metrics and a variety of tools to enforce these [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/thekua.com\/rant\/2004\/10\/the-value-in-checking-your-style\/\" \/>\n<meta property=\"og:site_name\" content=\"thekua.com@rest\" \/>\n<meta property=\"article:published_time\" content=\"2004-10-20T11:52:29+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2004-10-20T11:58:58+00:00\" \/>\n<meta name=\"author\" content=\"Patrick\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Patrick\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/thekua.com\\\/rant\\\/2004\\\/10\\\/the-value-in-checking-your-style\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/thekua.com\\\/rant\\\/2004\\\/10\\\/the-value-in-checking-your-style\\\/\"},\"author\":{\"name\":\"Patrick\",\"@id\":\"https:\\\/\\\/thekua.com\\\/rant\\\/#\\\/schema\\\/person\\\/6de103b28f96be3f1f4dc25db357c6ae\"},\"headline\":\"The Value in Checking Your Style\",\"datePublished\":\"2004-10-20T11:52:29+00:00\",\"dateModified\":\"2004-10-20T11:58:58+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/thekua.com\\\/rant\\\/2004\\\/10\\\/the-value-in-checking-your-style\\\/\"},\"wordCount\":403,\"commentCount\":4,\"publisher\":{\"@id\":\"https:\\\/\\\/thekua.com\\\/rant\\\/#\\\/schema\\\/person\\\/6de103b28f96be3f1f4dc25db357c6ae\"},\"keywords\":[\"Work-Related\"],\"articleSection\":[\"Work Related\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/thekua.com\\\/rant\\\/2004\\\/10\\\/the-value-in-checking-your-style\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/thekua.com\\\/rant\\\/2004\\\/10\\\/the-value-in-checking-your-style\\\/\",\"url\":\"https:\\\/\\\/thekua.com\\\/rant\\\/2004\\\/10\\\/the-value-in-checking-your-style\\\/\",\"name\":\"The Value in Checking Your Style - thekua.com@rest\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/thekua.com\\\/rant\\\/#website\"},\"datePublished\":\"2004-10-20T11:52:29+00:00\",\"dateModified\":\"2004-10-20T11:58:58+00:00\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/thekua.com\\\/rant\\\/2004\\\/10\\\/the-value-in-checking-your-style\\\/\"]}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/thekua.com\\\/rant\\\/#website\",\"url\":\"https:\\\/\\\/thekua.com\\\/rant\\\/\",\"name\":\"thekua.com@rest\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/thekua.com\\\/rant\\\/#\\\/schema\\\/person\\\/6de103b28f96be3f1f4dc25db357c6ae\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/thekua.com\\\/rant\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/thekua.com\\\/rant\\\/#\\\/schema\\\/person\\\/6de103b28f96be3f1f4dc25db357c6ae\",\"name\":\"Patrick\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/thekua.com\\\/rant\\\/wp-content\\\/uploads\\\/2025\\\/12\\\/pat-kua-head.png\",\"url\":\"https:\\\/\\\/thekua.com\\\/rant\\\/wp-content\\\/uploads\\\/2025\\\/12\\\/pat-kua-head.png\",\"contentUrl\":\"https:\\\/\\\/thekua.com\\\/rant\\\/wp-content\\\/uploads\\\/2025\\\/12\\\/pat-kua-head.png\",\"width\":400,\"height\":400,\"caption\":\"Patrick\"},\"logo\":{\"@id\":\"https:\\\/\\\/thekua.com\\\/rant\\\/wp-content\\\/uploads\\\/2025\\\/12\\\/pat-kua-head.png\"},\"sameAs\":[\"http:\\\/\\\/www.thekua.com\"],\"url\":\"https:\\\/\\\/thekua.com\\\/rant\\\/author\\\/patrick\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"The Value in Checking Your Style - thekua.com@rest","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/thekua.com\/rant\/2004\/10\/the-value-in-checking-your-style\/","next":"https:\/\/thekua.com\/rant\/2004\/10\/the-value-in-checking-your-style\/2\/","og_locale":"en_US","og_type":"article","og_title":"The Value in Checking Your Style - thekua.com@rest","og_description":"Increasing code quality is something that is currently being driven hard in our project. I am a big fan of weeding out code to make way for better smelling things like patterns and easily unit testable code. Many people have attempted to quantify code quality using metrics and a variety of tools to enforce these [&hellip;]","og_url":"https:\/\/thekua.com\/rant\/2004\/10\/the-value-in-checking-your-style\/","og_site_name":"thekua.com@rest","article_published_time":"2004-10-20T11:52:29+00:00","article_modified_time":"2004-10-20T11:58:58+00:00","author":"Patrick","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Patrick","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/thekua.com\/rant\/2004\/10\/the-value-in-checking-your-style\/#article","isPartOf":{"@id":"https:\/\/thekua.com\/rant\/2004\/10\/the-value-in-checking-your-style\/"},"author":{"name":"Patrick","@id":"https:\/\/thekua.com\/rant\/#\/schema\/person\/6de103b28f96be3f1f4dc25db357c6ae"},"headline":"The Value in Checking Your Style","datePublished":"2004-10-20T11:52:29+00:00","dateModified":"2004-10-20T11:58:58+00:00","mainEntityOfPage":{"@id":"https:\/\/thekua.com\/rant\/2004\/10\/the-value-in-checking-your-style\/"},"wordCount":403,"commentCount":4,"publisher":{"@id":"https:\/\/thekua.com\/rant\/#\/schema\/person\/6de103b28f96be3f1f4dc25db357c6ae"},"keywords":["Work-Related"],"articleSection":["Work Related"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/thekua.com\/rant\/2004\/10\/the-value-in-checking-your-style\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/thekua.com\/rant\/2004\/10\/the-value-in-checking-your-style\/","url":"https:\/\/thekua.com\/rant\/2004\/10\/the-value-in-checking-your-style\/","name":"The Value in Checking Your Style - thekua.com@rest","isPartOf":{"@id":"https:\/\/thekua.com\/rant\/#website"},"datePublished":"2004-10-20T11:52:29+00:00","dateModified":"2004-10-20T11:58:58+00:00","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/thekua.com\/rant\/2004\/10\/the-value-in-checking-your-style\/"]}]},{"@type":"WebSite","@id":"https:\/\/thekua.com\/rant\/#website","url":"https:\/\/thekua.com\/rant\/","name":"thekua.com@rest","description":"","publisher":{"@id":"https:\/\/thekua.com\/rant\/#\/schema\/person\/6de103b28f96be3f1f4dc25db357c6ae"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/thekua.com\/rant\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/thekua.com\/rant\/#\/schema\/person\/6de103b28f96be3f1f4dc25db357c6ae","name":"Patrick","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/thekua.com\/rant\/wp-content\/uploads\/2025\/12\/pat-kua-head.png","url":"https:\/\/thekua.com\/rant\/wp-content\/uploads\/2025\/12\/pat-kua-head.png","contentUrl":"https:\/\/thekua.com\/rant\/wp-content\/uploads\/2025\/12\/pat-kua-head.png","width":400,"height":400,"caption":"Patrick"},"logo":{"@id":"https:\/\/thekua.com\/rant\/wp-content\/uploads\/2025\/12\/pat-kua-head.png"},"sameAs":["http:\/\/www.thekua.com"],"url":"https:\/\/thekua.com\/rant\/author\/patrick\/"}]}},"_links":{"self":[{"href":"https:\/\/thekua.com\/rant\/wp-json\/wp\/v2\/posts\/47","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/thekua.com\/rant\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/thekua.com\/rant\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/thekua.com\/rant\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/thekua.com\/rant\/wp-json\/wp\/v2\/comments?post=47"}],"version-history":[{"count":0,"href":"https:\/\/thekua.com\/rant\/wp-json\/wp\/v2\/posts\/47\/revisions"}],"wp:attachment":[{"href":"https:\/\/thekua.com\/rant\/wp-json\/wp\/v2\/media?parent=47"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/thekua.com\/rant\/wp-json\/wp\/v2\/categories?post=47"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/thekua.com\/rant\/wp-json\/wp\/v2\/tags?post=47"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}