<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Devon Hillard&#039;s Digital Sanctuary &#187; Java</title>
	<atom:link href="http://www.digitalsanctuary.com/tech-blog/tag/java/feed" rel="self" type="application/rss+xml" />
	<link>http://www.digitalsanctuary.com/tech-blog</link>
	<description>Java, ATG, Seam, and related Technologies</description>
	<lastBuildDate>Mon, 30 Jan 2012 23:04:32 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Terrible Code</title>
		<link>http://www.digitalsanctuary.com/tech-blog/java/atg/terrible-code.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/java/atg/terrible-code.html#comments</comments>
		<pubDate>Tue, 03 Nov 2009 02:57:34 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[ATG]]></category>
		<category><![CDATA[development practices]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/?p=526</guid>
		<description><![CDATA[&#8220;qualifySkus&#8221; is confusing. Is it an array/list/collection of &#8220;qualifiedSKUs&#8221; or a flag that&#8217;s a result of &#8220;qualifyingSkus&#8221; or&#8230;. &#8220;qualifySKus&#8221; should be a constant with a nice comment, not an in-line String. The method getSkusRespository seems like it would return a &#8230; <a href="http://www.digitalsanctuary.com/tech-blog/java/atg/terrible-code.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<pre class="brush: java; title: ; notranslate">
request.setParameter(&quot;qualifySkus&quot;, getSkusRepository(d, cItem));
</pre>
<ol>
<li>&#8220;qualifySkus&#8221; is confusing.  Is it an array/list/collection of &#8220;qualifiedSKUs&#8221; or a flag that&#8217;s a result of &#8220;qualifyingSkus&#8221; or&#8230;.  </li>
<li>&#8220;qualifySKus&#8221; should be a constant with a nice comment, not an in-line String.</li>
<li>The method getSkusRespository seems like it would return a catalog repository, doesn&#8217;t it?  Instead it takes in a List of String SkuIds, loads up the corresponding SKU RepositoryItems, removes any that have the property &#8220;isLive&#8221; set to false, and removes any that have a current inventory stock level of zero.  It then returns an ArrayList of those filtered SKU RepositoryItems.  Perhaps a better name might be &#8220;getLiveInStockSKUs&#8221;?</li>
<li>What on earth is &#8220;d&#8221;?  Even looking at the full code of this class, it&#8217;s very difficult to tell what d is meant to contain.  It&#8217;s actually a List of Strings of SkuIds that are qualifying skus for a given promo.  &#8220;qualifiedSkus&#8221; would be a better name.</li>
<li>cItem is a commerce item.  However it&#8217;s not actually used by the getSkusRepository method at all.  There&#8217;s no reason to pass it in.</li>
<li>This line is in an ATG droplet and shoves the result of the getSkusRepository method into a request param before servicing an oparam.  However, as you can see, it doesn&#8217;t inspect the output of the method.  As I explained above, the method actually filters a list of SKUs based on isLive and current inventory state.  It&#8217;s very possible that there will be no live and in-stock SKUs, and the param&#8217;s value will be null or an empty list.  In that case, we&#8217;d actually want to render a different oparam, which is defined and called elsewhere, but not here.  Validate your output!</li>
</ol>
<p>That&#8217;s six issues in one line.  Please don&#8217;t write code like this.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/java/atg/terrible-code.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Eclipse Auto Complete Templates for ATG</title>
		<link>http://www.digitalsanctuary.com/tech-blog/java/eclipse-auto-complete-templates-for-atg.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/java/eclipse-auto-complete-templates-for-atg.html#comments</comments>
		<pubDate>Wed, 02 Sep 2009 16:40:47 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[eclipse]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/?p=480</guid>
		<description><![CDATA[Eclipse has an often under-utilized feature called Templates. You&#8217;ve probably used the built in templates when Eclipse auto-completes for loops or try-catch blocks, etc&#8230; However, you can create your own templates for commonly used chunks of code. This can save &#8230; <a href="http://www.digitalsanctuary.com/tech-blog/java/eclipse-auto-complete-templates-for-atg.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Eclipse has an often under-utilized feature called Templates.  You&#8217;ve probably used the built in templates when Eclipse auto-completes for loops or try-catch blocks, etc&#8230;  However, you can create your own templates for commonly used chunks of code.  This can save you a lot of time, and more importantly can facilitate you writing better quality code.</p>
<div id="attachment_483" class="wp-caption alignleft" style="width: 560px"><a href="http://www.digitalsanctuary.com/tech-blog/wp-content/uploads/2009/09/Picture-5.png"><img src="http://www.digitalsanctuary.com/tech-blog/wp-content/uploads/2009/09/Picture-5-550x274.png" alt="ATG Eclipse Templates" title="ATG Eclipse Templates" width="550" height="274" class="size-medium wp-image-483" /></a><p class="wp-caption-text">ATG Eclipse Templates</p></div>
<p>By making commonly used code blocks available with a couple of keystrokes it is much easier to write best practices code, that otherwise you might shortcut around.</p>
<p>You can view, import, and create new templates by going to Eclipse&#8217;s Preferences, then opening Java->Editor->Templates.  Each Template has a Name, this is what triggers it for auto-complete so making this simple and unique is good, a Description, a Context, a checkbox to Automatically insert, and then the Pattern which is the code that will get inserted for you.  Within the Pattern you have access to a substantial number of variables, such as the current class or method name, variables, method arguments, dates, etc&#8230; which allow you do some very useful things.</p>
<p>For ATG coding I&#8217;ve created nine Templates for common code blocks.</p>
<p>My templates isBlank and isNotBlank create if blocks based on ATG&#8217;s StringUtils.isBlank method, which checks for null, empty, or blank Strings.  Checking Strings is something that I do all the time (validating user input, query params, etc&#8230;) so being able to do it in a few keystrokes is very useful.</p>
<pre class="brush: java; title: ; notranslate">
ls.isBlank(${cursor})) {

}
</pre>
<p>I have three templates for ATG Performance Monitor operations.  Adding in ATG Performance Monitor hooks when you&#8217;re coding can make diagnosing performance problems later much easier.  Using templates means you don&#8217;t have to remember the syntax or even type in the class and method names:</p>
<pre class="brush: java; title: ; notranslate">
PerformanceMonitor.startOperation(&quot;${enclosing_type}&quot;, &quot;${enclosing_method}&quot;);
</pre>
<p>I also have four templates for the primary ATG logging methods with the respective if blocks needed to prevent unnecessary String concatenations.</p>
<pre class="brush: java; title: ; notranslate">
if(isLoggingDebug()) {
	logDebug(&quot;${enclosing_type}.${enclosing_method}:&quot; + &quot;${cursor}&quot;);
}
</pre>
<p>I&#8217;ve exported these nine ATG templates so you can easily import and start to use them.<br />
<a href='http://www.digitalsanctuary.com/tech-blog/wp-content/uploads/2009/09/ATG-Templates.xml'>Eclipse ATG Coding Templates</a>.</p>
<p>What templates have you created?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/java/eclipse-auto-complete-templates-for-atg.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>JForum SSO (single sign-on) and Atlassian Crowd</title>
		<link>http://www.digitalsanctuary.com/tech-blog/java/jforum-sso-single-sign-on-and-atlassian-crowd.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/java/jforum-sso-single-sign-on-and-atlassian-crowd.html#comments</comments>
		<pubDate>Sun, 08 Jun 2008 08:24:06 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[atlassian]]></category>
		<category><![CDATA[crowd]]></category>
		<category><![CDATA[forum]]></category>
		<category><![CDATA[jforum]]></category>
		<category><![CDATA[sso]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/?p=123</guid>
		<description><![CDATA[Over at our new ATG Developer Community site, we&#8217;re using Atlassian Crowd to manage our user accounts, groups, and single sign-on (SSO) between Jira, Confluence, to manage Subversion authentication, and to handle the forums (JForum) user accounts. There was an &#8230; <a href="http://www.digitalsanctuary.com/tech-blog/java/jforum-sso-single-sign-on-and-atlassian-crowd.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Over at our new <a href="http://developer.sparkred.com/" target="_new">ATG Developer Community</a> site, we&#8217;re using <a href="http://www.atlassian.com/software/crowd/" target="_new">Atlassian Crowd</a> to manage our user accounts, groups, and single sign-on (SSO) between Jira, Confluence, to manage Subversion authentication, and to handle the forums (JForum) user accounts.</p>
<p>There was an example on how to integrate JForum and Crowd, which works pretty well.  When you login to the forum, it checks Crowd and creates a local account if needed and logs you in.</p>
<p>However, we want single sign-on (SSO) so that our users don&#8217;t need to login to the forums separately.  We also want group membership in Crowd to be reflected in JForum to allow us to manage permissions based on Crowd managed groups.</p>
<p>I&#8217;ve written a JForum SSO implementation that ties into Crowd that I&#8217;m going to share here.  It&#8217;s version 1.1 (just added group sync), but it seems to work nicely.</p>
<p>Download the zip file here:<br />
<a href='http://www.digitalsanctuary.com/tech-blog/wp-content/uploads/2008/06/jforum-crowd-sso-11.zip'>jforum-crowd-sso</a></p>
<p>unzip it into your jforum/WEB-INF/classes/ directory.</p>
<p>You have to install the crowd client jar, and the crowd.properties file.</p>
<p>You may also need to install the xfire jars if you get errors.  I did.</p>
<p>Then you need to setup the sso configuration in the jforum/WEB-INF/config/SystemGlobals.properties</p>
<p>like this:</p>
<pre>
authentication.type=sso
sso.implementation = com.digitalsanctuary.jforum.CrowdSSO
sso.redirect = your crowd managed app login page
sso.crowd.syncGroups=false
</pre>
<p>That last flag should be set to true if you would like the user&#8217;s groups synced from Crowd to JForum at auth time.  This takes a second, so I made it optional.  It does not push JForum group membership info to Crowd, it just syncs Crowd data down, as Crowd should be your master directory for that type of data.</p>
<p>The source code is available here for now:</p>
<p><a href='http://www.digitalsanctuary.com/tech-blog/wp-content/uploads/2008/06/crowdsso.java'>CrowdSSO.java</a></p>
<p>-EDIT-</p>
<p>Added a full downloadable module and installation instructions here:</p>
<p><a href="http://confluence.atlassian.com/display/CROWDEXT/JForum+Single+Sign-On+Crowd+Connector">http://confluence.atlassian.com/display/CROWDEXT/JForum+Single+Sign-On+Crowd+Connector</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/java/jforum-sso-single-sign-on-and-atlassian-crowd.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How To Resize Uploaded Images Using Java &#8211; Better Way</title>
		<link>http://www.digitalsanctuary.com/tech-blog/java/how-to-resize-uploaded-images-using-java-better-way.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/java/how-to-resize-uploaded-images-using-java-better-way.html#comments</comments>
		<pubDate>Fri, 14 Mar 2008 01:23:39 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Seam]]></category>
		<category><![CDATA[BufferedImage]]></category>
		<category><![CDATA[Byte Array]]></category>
		<category><![CDATA[byte[]]]></category>
		<category><![CDATA[Image]]></category>
		<category><![CDATA[ImageIcon]]></category>
		<category><![CDATA[JAI]]></category>
		<category><![CDATA[JPG]]></category>
		<category><![CDATA[Resize]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/java/how-to-resize-uploaded-images-using-java-better-way.html</guid>
		<description><![CDATA[Based on helpful comments from Matt on this previous post: How To Resize Uploaded Images Using Java I have upgraded the image resizing code. The results are noticeably better in quality, even at thumbnail sizes. I wanted to share the &#8230; <a href="http://www.digitalsanctuary.com/tech-blog/java/how-to-resize-uploaded-images-using-java-better-way.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Based on helpful comments from Matt on this previous post:</p>
<p><a href="http://www.digitalsanctuary.com/tech-blog/java/how-to-resize-uploaded-images-using-java.html">How To Resize Uploaded Images Using Java</a></p>
<p>I have upgraded the image resizing code.  The results are noticeably better in quality, even at thumbnail sizes.  I wanted to share the completed new code, in case anyone needs it.</p>
<p>Again, thanks to Matt S. for his pointers.</p>
<pre class="brush: java; title: ; notranslate">
    /**
     * The JAI.create action name for handling a stream.
     */
    private static final String JAI_STREAM_ACTION = &quot;stream&quot;;

    /**
     * The JAI.create action name for handling a resizing using a subsample averaging technique.
     */
    private static final String JAI_SUBSAMPLE_AVERAGE_ACTION = &quot;SubsampleAverage&quot;;

    /**
     * The JAI.create encoding format name for JPEG.
     */
    private static final String JAI_ENCODE_FORMAT_JPEG = &quot;JPEG&quot;;

    /**
     * The JAI.create action name for encoding image data.
     */
    private static final String JAI_ENCODE_ACTION = &quot;encode&quot;;

    /**
     * The http content type/mime-type for JPEG images.
     */
    private static final String JPEG_CONTENT_TYPE = &quot;image/jpeg&quot;;

    private int mMaxWidth = 800;

    private int mMaxWidthThumbnail = 150;

.....

    /**
     * This method takes in an image as a byte array (currently supports GIF, JPG, PNG and
     * possibly other formats) and
     * resizes it to have a width no greater than the pMaxWidth parameter in pixels.
     * It converts the image to a standard
     * quality JPG and returns the byte array of that JPG image.
     *
     * @param pImageData
     *                the image data.
     * @param pMaxWidth
     *                the max width in pixels, 0 means do not scale.
     * @return the resized JPG image.
     * @throws IOException
     *                 if the image could not be manipulated correctly.
     */
    public byte[] resizeImageAsJPG(byte[] pImageData, int pMaxWidth) throws IOException {
	InputStream imageInputStream = new ByteArrayInputStream(pImageData);
	// read in the original image from an input stream
	SeekableStream seekableImageStream = SeekableStream.wrapInputStream(imageInputStream, true);
	RenderedOp originalImage = JAI.create(JAI_STREAM_ACTION, seekableImageStream);
	((OpImage) originalImage.getRendering()).setTileCache(null);
	int origImageWidth = originalImage.getWidth();
	// now resize the image
	double scale = 1.0;
	if (pMaxWidth &gt; 0 &amp;&amp; origImageWidth &gt; pMaxWidth) {
	    scale = (double) pMaxWidth / originalImage.getWidth();
	}
	ParameterBlock paramBlock = new ParameterBlock();
	paramBlock.addSource(originalImage); // The source image
	paramBlock.add(scale); // The xScale
	paramBlock.add(scale); // The yScale
	paramBlock.add(0.0); // The x translation
	paramBlock.add(0.0); // The y translation

	RenderingHints qualityHints = new RenderingHints(RenderingHints.KEY_RENDERING,
		RenderingHints.VALUE_RENDER_QUALITY);

	RenderedOp resizedImage = JAI.create(JAI_SUBSAMPLE_AVERAGE_ACTION, paramBlock, qualityHints);

	// lastly, write the newly-resized image to an output stream, in a specific encoding
	ByteArrayOutputStream encoderOutputStream = new ByteArrayOutputStream();
	JAI.create(JAI_ENCODE_ACTION, resizedImage, encoderOutputStream, JAI_ENCODE_FORMAT_JPEG, null);
	// Export to Byte Array
	byte[] resizedImageByteArray = encoderOutputStream.toByteArray();
	return resizedImageByteArray;
    }
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/java/how-to-resize-uploaded-images-using-java-better-way.html/feed</wfw:commentRss>
		<slash:comments>54</slash:comments>
		</item>
		<item>
		<title>How To Resize Uploaded Images Using Java</title>
		<link>http://www.digitalsanctuary.com/tech-blog/java/how-to-resize-uploaded-images-using-java.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/java/how-to-resize-uploaded-images-using-java.html#comments</comments>
		<pubDate>Thu, 06 Mar 2008 18:03:48 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Seam]]></category>
		<category><![CDATA[gallery]]></category>
		<category><![CDATA[Image]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/java/how-to-resize-uploaded-images-using-java.html</guid>
		<description><![CDATA[Edit: please read the better way here: Better way to Resize Images Using Java! &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; I am building a Seam application which need to support users uploading images, and then the site displaying them. I wanted to resize big images &#8230; <a href="http://www.digitalsanctuary.com/tech-blog/java/how-to-resize-uploaded-images-using-java.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Edit:  please read the better way here: <a href="http://www.digitalsanctuary.com/tech-blog/java/how-to-resize-uploaded-images-using-java-better-way.html">Better way to Resize Images Using Java</a>!</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
I am building a Seam application which need to support users uploading images, and then the site displaying them.  I wanted to resize big images into something reasonable (say 1024 or 800 px wide) and generate a thumbnail, and I also wanted to standardize on a single image format just to make things easy and consistent.</p>
<p>So I needed method that would take an uploaded image as a byte array (byte[]) and would resize the image (if needed) and convert it to a fixed quality JPG, and give me back a byte array to store in the database.  I am using Seam, so I get a handy byte array, but this method should work fine for non-Seam applications as well.</p>
<pre lang="java">
    /**
     * This method takes in an image as a byte array (currently supports GIF, JPG, PNG and possibly other formats) and
     * resizes it to have a width no greater than the pMaxWidth parameter in pixels. It converts the image to a standard
     * quality JPG and returns the byte array of that JPG image.
     *
     * @param pImageData
     *                the image data.
     * @param pMaxWidth
     *                the max width in pixels, 0 means do not scale.
     * @return the resized JPG image.
     * @throws IOException
     *                 if the iamge could not be manipulated correctly.
     */
    public byte[] resizeImageAsJPG(byte[] pImageData, int pMaxWidth) throws IOException {
	// Create an ImageIcon from the image data
	ImageIcon imageIcon = new ImageIcon(pImageData);
	int width = imageIcon.getIconWidth();
	int height = imageIcon.getIconHeight();
	mLog.info("imageIcon width: #0  height: #1", width, height);
	// If the image is larger than the max width, we need to resize it
	if (pMaxWidth > 0 &#038;&#038; width > pMaxWidth) {
	    // Determine the shrink ratio
	    double ratio = (double) pMaxWidth / imageIcon.getIconWidth();
	    mLog.info("resize ratio: #0", ratio);
	    height = (int) (imageIcon.getIconHeight() * ratio);
	    width = pMaxWidth;
	    mLog.info("imageIcon post scale width: #0  height: #1", width, height);
	}
	// Create a new empty image buffer to "draw" the resized image into
	BufferedImage bufferedResizedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
	// Create a Graphics object to do the "drawing"
	Graphics2D g2d = bufferedResizedImage.createGraphics();
	g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
	// Draw the resized image
	g2d.drawImage(imageIcon.getImage(), 0, 0, width, height, null);
	g2d.dispose();
	// Now our buffered image is ready
	// Encode it as a JPEG
	ByteArrayOutputStream encoderOutputStream = new ByteArrayOutputStream();
	JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(encoderOutputStream);
	encoder.encode(bufferedResizedImage);
	byte[] resizedImageByteArray = encoderOutputStream.toByteArray();
	return resizedImageByteArray;
    }
</pre>
<p>In my application I call this method twice, once to convert the uploaded image into a limited size JPG, and then once again to generate a much smaller thumbnail.  I store both of these in the database and will use caching at the Apache layer to ensure performance.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/java/how-to-resize-uploaded-images-using-java.html/feed</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
		<item>
		<title>Constants</title>
		<link>http://www.digitalsanctuary.com/tech-blog/java/constants.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/java/constants.html#comments</comments>
		<pubDate>Wed, 15 Aug 2007 02:38:07 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[ATG]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/archives/27</guid>
		<description><![CDATA[What &#8211; constants in Java While Java does not have a built-in Constant type, functionally constants are supported through the use of two modifiers: final and static, like this: public static final int NUM_CARDS_IN_DECK=52; First, we define the variable as &#8230; <a href="http://www.digitalsanctuary.com/tech-blog/java/constants.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><strong>What &#8211; constants in Java</strong><br />
While Java does not have a built-in Constant type, functionally constants are supported through the use of two modifiers: final and static, like this:</p>
<p><code>public static final int NUM_CARDS_IN_DECK=52;</code></p>
<p>First, we define the variable as public, this is not necessary for using the constant within the same class, but is needed in order to access the same constant from multiple classes.  I will go into this distinction in more detail later.</p>
<p>Secondly we mark it as static.  This provides two related features.  The variable can be referenced without instantiating a copy of it’s enclosing object.  The variable will only exist ONCE in memory.  This is very efficient.  Also, during compilation the access will be in-lined into the class and therefore much faster.</p>
<p>Thirdly we mark it as final.  This prevents the value from being changed or overridden, ensuring that that the value is consistent throughout your entire application, and letting the compiler know it does not have to worry about the value changing.</p>
<p>From there it looks like a normal variable except for the name.  The convention is to name constants in all capitals with underscore characters separating logical words.<br />
<span id="more-27"></span><br />
<strong>Where &#8211; local or global</strong><br />
Constants can be defined within one of your functional classes as private (or another restrictive modifier), and used only within that class, or they can be defined in a single purpose location holding all of your shared constants as public.  For the nature of this container, see the next section.</p>
<p>The defining line governing where a given constant should live is based on it’s usage.  Is it something that is specific to the one class, or is it something that multiple classes within your application should be utilizing?  You can always refactor it later as well, so don’t get too hung up on this question.</p>
<p><strong>How &#8211; interface versus class</strong><br />
For constants that need to accessed from multiple classes, there are two options on exposing the constants.  First, by creating an Interface which will hold all of the constants for your application.  Then, in any class you need access to a constant, you simply implement the interface.  The advantage to this is that you do not need to prefix the constant name with a class or anything else.  This has been a popular approach, and many of the initial examples of constants used this method.  However, thankfully, it has finally been recognized as an anti-pattern.  Using an interface for this purpose is really abusing the concept of an interface.  An interface is meant to hold a type definition, not to piggie-back your constants around your application.</p>
<p>The second approach, creating a constants class which houses your constants and referring to them via the Class.CONSTANT notation in your code (or you can import the individual static constants if you like) is the best approach.  It is easy to tell where the constants are defined, and you aren’t cluttering up your class definition.</p>
<p><strong>Why &#8211; context through constants</strong><br />
People usually think to use a constant when a value may be used across many classes within their application.  For instance an application limit such as the maximum number of threads to use, or the number of cards in a deck of playing cards, etc&#8230;<br />
These are great places to use constants (assuming they shouldn’t be runtime configurable properties).  In this case one of the main reasons constants are used are to provide a single point of definition.  Allowing you to have consistency across the application and a single point to make changes.</p>
<p>What is often overlooked is the use of constants to provide context.  The above usage does this as well, but is rarely a motivating factor for developers.  I advocate using local constants in classes frequently in order to convey context to your code.  Consider this code:</p>
<p><code>int tally = 0;<br />
for(int i = 0; i &amp;lt; 60; i++) {<br />
Random rand = new Random();<br />
if(rand.nextInt(100) &amp;gt; 60) {<br />
tally = tally + 5;<br />
}<br />
}</code></p>
<p>There are many numbers but no context.  This can easily happen with Strings as well, see the section on ATG for an example.  If you were new and had been asked to adjust the game logic to make the game this code is part of, easier or harder it would not be easy.  Now, let’s add some context to the functionality by using local constants:</p>
<p><code>private static final int SECONDS_PER_TURN = 60;<br />
private static final int PERCENT_CHANCE_OF_SLIPPING_PER_SECOND = 60;<br />
private static final int FEET_SLIPPED = 5;<br />
.....<br />
int tally = 0;<br />
for(int i = 0; i &amp;lt; SECONDS_PER_TURN; i++) {<br />
Random rand = new Random();<br />
if(rand.nextInt(100) &amp;gt; PERCENT_CHANCE_OF_SLIPPING_PER_SECOND) {<br />
tally = tally + FEET_SLIPPED;<br />
}<br />
}</code></p>
<p>and it becomes clear that this piece of code calculates the number of feet slipped in a turn.  It also makes it easy to adjust the percent chance of slipping, without getting confused by the multiple uses of “60” in the area.  If you use constants to give your code more context you will thank yourself later, as will anyone else who deals with your code.</p>
<p><strong>ATG &#8211; repositories</strong><br />
Repositories are ATG’s data access and object-relational mapping technology.  In many ways the technology is similar to Hibernate with a few key differences.  One of those differences is that instead of mapping to typed objects like Hibernate does, ATG Repositories use RepositoryItem to represent every data object.  The values are accessed through a value dictionary.  In the repository definition file you map out all the objects, their properties (and the tables and columns backing them), and the relationships between objects.  Each object is given an item descriptor name which is used to identify that type of object.  The properties of an object are also named.  These names are used to query objects from the database and access, or update, the properties of the object.</p>
<p>Take a shoe management application (not that you need one):  You have a Shoes object, representing a pair of shoes, which happens to have a few properties, including flags for shoes, boots, or sandals (not the best way to model it, but perhaps it is a legacy database).  You also have a Wearer object, for the person currently wearing the shoes.  This object has a shoe property.  You have a Manufacturer who has a shoes Collection property.  You also have an Owner who also has a shoes Collection property.  You can see where this is going.</p>
<p><code>RepositoryItem shoes = Repository.getItem(myShoesId, “shoes”);<br />
if((Boolean)shoes.getPropertyValue(“shoes”).booleanValue()) {<br />
List manShoes = (List)manufacturerer.getPropertyValue(“shoes”);<br />
manShoes.add(shoes);<br />
manufacturer.setPropertyValue(“shoes”, shoes);<br />
.........<br />
}</code><br />
And so on.  You can see that it can get ugly very quickly.  And of course you may want to change the names of properties as time goes on, and trying to work through all of your code to update it each time is bound to cause problems.<br />
When using ATG Repositories, I highly recommend using a constants file to hold all of the item descriptor and property names.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/java/constants.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Database Caching 1/29 queries in 0.006 seconds using disk: basic
Object Caching 555/622 objects using disk: basic

Served from: www.digitalsanctuary.com @ 2012-02-06 23:49:49 -->
