Close Menu
    DevStackTipsDevStackTips
    • Home
    • News & Updates
      1. Tech & Work
      2. View All

      Error’d: Pickup Sticklers

      September 27, 2025

      From Prompt To Partner: Designing Your Custom AI Assistant

      September 27, 2025

      Microsoft unveils reimagined Marketplace for cloud solutions, AI apps, and more

      September 27, 2025

      Design Dialects: Breaking the Rules, Not the System

      September 27, 2025

      Building personal apps with open source and AI

      September 12, 2025

      What Can We Actually Do With corner-shape?

      September 12, 2025

      Craft, Clarity, and Care: The Story and Work of Mengchu Yao

      September 12, 2025

      Cailabs secures €57M to accelerate growth and industrial scale-up

      September 12, 2025
    • Development
      1. Algorithms & Data Structures
      2. Artificial Intelligence
      3. Back-End Development
      4. Databases
      5. Front-End Development
      6. Libraries & Frameworks
      7. Machine Learning
      8. Security
      9. Software Engineering
      10. Tools & IDEs
      11. Web Design
      12. Web Development
      13. Web Security
      14. Programming Languages
        • PHP
        • JavaScript
      Featured

      Using phpinfo() to Debug Common and Not-so-Common PHP Errors and Warnings

      September 28, 2025
      Recent

      Using phpinfo() to Debug Common and Not-so-Common PHP Errors and Warnings

      September 28, 2025

      Mastering PHP File Uploads: A Guide to php.ini Settings and Code Examples

      September 28, 2025

      The first browser with JavaScript landed 30 years ago

      September 27, 2025
    • Operating Systems
      1. Windows
      2. Linux
      3. macOS
      Featured
      Recent
    • Learning Resources
      • Books
      • Cheatsheets
      • Tutorials & Guides
    Home»News & Updates»CodeSOD: Born Single

    CodeSOD: Born Single

    July 15, 2025

    Alistair sends us a pretty big blob of code, but it’s a blob which touches upon everyone’s favorite design pattern: the singleton. It’s a lot of Java code, so we’re going to take this as chunks. Let’s start with the two methods responsible for constructing the object.

    The purpose of this code is to parse an XML file, and construct a mapping from a “name” field in the XML to a “batch descriptor”.

    	<span class="hljs-comment">/**
    	 * Instantiates a new batch manager.
    	 */</span>
    	<span class="hljs-keyword">private</span> <span class="hljs-title function_">BatchManager</span><span class="hljs-params">()</span> {
    		<span class="hljs-keyword">try</span> {
    			<span class="hljs-keyword">final</span> <span class="hljs-type">XMLReader</span> <span class="hljs-variable">xmlReader</span> <span class="hljs-operator">=</span> XMLReaderFactory.createXMLReader();
    			xmlReader.setContentHandler(<span class="hljs-built_in">this</span>);
    			xmlReader.parse(<span class="hljs-keyword">new</span> <span class="hljs-title class_">InputSource</span>(<span class="hljs-built_in">this</span>.getClass().getClassLoader().getResourceAsStream(<span class="hljs-string">"templates/"</span> + DOCUMENT)));
    		} <span class="hljs-keyword">catch</span> (<span class="hljs-keyword">final</span> Exception e) {
    			logger.error(<span class="hljs-string">"Error parsing Batch XML."</span>, e);
    		}
    	}
    
    	<span class="hljs-comment">/*
    	 * (non-Javadoc)
    	 * 
    	 * @see nz.this.is.absolute.crap.sax.XMLEntity#initChild(java.lang.String,
    	 * java.lang.String, java.lang.String, org.xml.sax.Attributes)
    	 */</span>
    	<span class="hljs-meta">@Override</span>
    	<span class="hljs-keyword">protected</span> ContentHandler <span class="hljs-title function_">initChild</span><span class="hljs-params">(String uri, String localName,
    			String qName, Attributes attributes)</span> <span class="hljs-keyword">throws</span> SAXException {
    		<span class="hljs-keyword">final</span> <span class="hljs-type">BatchDescriptor</span> <span class="hljs-variable">batchDescriptor</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">BatchDescriptor</span>();
    		<span class="hljs-comment">// put it in the map</span>
    		batchMap.put(attributes.getValue(<span class="hljs-string">"name"</span>), batchDescriptor);
    		<span class="hljs-keyword">return</span> batchDescriptor;
    	}
    

    Here we see a private constructor, which is reasonable for a singleton. It creates a SAX based reader. SAX is event driven- instead of loading the whole document into a DOM, it emits an event as it encounters each new key element in the XML document. It’s cumbersome to use, but far more memory efficient, and I’d hardly say this.is.absolute.crap, but whatever.

    This code is perfectly reasonable. But do you know what’s unreasonable? There’s a lot more code, and these are the only things not marked as static. So let’s keep going.

    	<span class="hljs-comment">// singleton instance so that static batch map can be initialised using</span>
    	<span class="hljs-comment">// xml</span>
    	<span class="hljs-comment">/** The Constant singleton. */</span>
    	<span class="hljs-meta">@SuppressWarnings("unused")</span>
    	<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-type">Object</span> <span class="hljs-variable">singleton</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">BatchManager</span>();
    

    Wait… why is the singleton object throwing warnings about being unused? And wait a second, what is that comment saying, “so the static batch map can be initalalised”? I saw a batchMap up in the initChild method above, but it can’t be…

    	<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> Map<String, BatchDescriptor> batchMap = <span class="hljs-keyword">new</span> <span class="hljs-title class_">HashMap</span><String, BatchDescriptor>();
    

    Oh. Oh no.

    	<span class="hljs-comment">/**
    	 * Gets the.
    	 * 
    	 * <span class="hljs-doctag">@param</span> batchName
    	 *            the batch name
    	 * 
    	 * <span class="hljs-doctag">@return</span> the batch descriptor
    	 */</span>
    	<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> BatchDescriptor <span class="hljs-title function_">get</span><span class="hljs-params">(String batchName)</span> {
    		<span class="hljs-keyword">return</span> batchMap.get(batchName);
    	}
    
    	<span class="hljs-comment">/**
    	 * Gets the post to selector name.
    	 * 
    	 * <span class="hljs-doctag">@param</span> batchName
    	 *            the batch name
    	 * 
    	 * <span class="hljs-doctag">@return</span> the post to selector name
    	 */</span>
    	<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> String <span class="hljs-title function_">getPostToSelectorName</span><span class="hljs-params">(String batchName)</span> {
    		<span class="hljs-keyword">final</span> <span class="hljs-type">BatchDescriptor</span> <span class="hljs-variable">batchDescriptor</span> <span class="hljs-operator">=</span> batchMap.get(batchName);
    		<span class="hljs-keyword">if</span> (batchDescriptor == <span class="hljs-literal">null</span>) {
    			<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
    		}
    		<span class="hljs-keyword">return</span> batchDescriptor.getPostTo();
    	}
    

    There are more methods, and I’ll share the whole code at the end, but this gives us a taste. Here’s what this code is actually doing.

    It creates a static Map. static, in this context, means that this instance is shared across all instances of BatchManager.They also create a static instance of BatchManager inside of itself. The constructor of that instance then executes, populating that static Map. Now, when anyone invokes BatchManager.get it will use that static Map to resolve that.

    This certainly works, and it offers a certain degree of cleanness in its implementation. A more conventional singleton would have the Map being owned by an instance, and it’s just using the singleton convention to ensure there’s only a single instance. This version’s calling convention is certainly nicer than doing something like BatchManager.getInstance().get(…), but there’s just something unholy about this that sticks into me.

    I can’t say for certain if it’s because I just hate Singletons, or if it’s this specific abuse of constructors and static members.

    This is certainly one of the cases of misusing a singleton- it does not represent something there can be only one of, it’s ensuring that an expensive computation is only allowed to be done once. There are better ways to handle that lifecycle. This approach also forces that expensive operation to happen at application startup, instead of being something flexible that can be evaluated lazily. It’s not wrong to do this eagerly, but building something that can only do it eagerly is a mistake.

    In any case, the full code submission follows:

    <span class="hljs-keyword">package</span> nz.<span class="hljs-built_in">this</span>.is.absolute.crap.server.template;
    
    <span class="hljs-keyword">import</span> java.io.IOException;
    <span class="hljs-keyword">import</span> java.util.ArrayList;
    <span class="hljs-keyword">import</span> java.util.Collection;
    <span class="hljs-keyword">import</span> java.util.HashMap;
    <span class="hljs-keyword">import</span> java.util.Iterator;
    <span class="hljs-keyword">import</span> java.util.Map;
    <span class="hljs-keyword">import</span> java.util.ResourceBundle;
    
    <span class="hljs-keyword">import</span> nz.<span class="hljs-built_in">this</span>.is.absolute.crap.KupengaException;
    <span class="hljs-keyword">import</span> nz.<span class="hljs-built_in">this</span>.is.absolute.crap.SafeComparator;
    <span class="hljs-keyword">import</span> nz.<span class="hljs-built_in">this</span>.is.absolute.crap.sax.XMLEntity;
    <span class="hljs-keyword">import</span> nz.<span class="hljs-built_in">this</span>.is.absolute.crap.selector.Selector;
    <span class="hljs-keyword">import</span> nz.<span class="hljs-built_in">this</span>.is.absolute.crap.selector.SelectorItem;
    <span class="hljs-keyword">import</span> nz.<span class="hljs-built_in">this</span>.is.absolute.crap.server.BatchValidator;
    <span class="hljs-keyword">import</span> nz.<span class="hljs-built_in">this</span>.is.absolute.crap.server.Validatable;
    <span class="hljs-keyword">import</span> nz.<span class="hljs-built_in">this</span>.is.absolute.crap.server.ValidationException;
    <span class="hljs-keyword">import</span> nz.<span class="hljs-built_in">this</span>.is.absolute.crap.server.business.BusinessObject;
    <span class="hljs-keyword">import</span> nz.<span class="hljs-built_in">this</span>.is.absolute.crap.server.database.EntityHandler;
    <span class="hljs-keyword">import</span> nz.<span class="hljs-built_in">this</span>.is.absolute.crap.server.database.SQLEntityHandler;
    
    <span class="hljs-keyword">import</span> org.apache.log4j.Logger;
    <span class="hljs-keyword">import</span> org.xml.sax.Attributes;
    <span class="hljs-keyword">import</span> org.xml.sax.ContentHandler;
    <span class="hljs-keyword">import</span> org.xml.sax.InputSource;
    <span class="hljs-keyword">import</span> org.xml.sax.SAXException;
    <span class="hljs-keyword">import</span> org.xml.sax.XMLReader;
    <span class="hljs-keyword">import</span> org.xml.sax.helpers.XMLReaderFactory;
    
    <span class="hljs-comment">/**
     * The Class BatchManager.
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">BatchManager</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">XMLEntity</span> {
    
    	<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-type">Logger</span> <span class="hljs-variable">logger</span> <span class="hljs-operator">=</span> Logger.getLogger(BatchManager.class);
    	
    	<span class="hljs-comment">/** The Constant DOCUMENT. */</span>
    	<span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">static</span> <span class="hljs-type">String</span> <span class="hljs-variable">DOCUMENT</span> <span class="hljs-operator">=</span> <span class="hljs-string">"Batches.xml"</span>;
    
    	<span class="hljs-comment">/**
    	 * The Class BatchDescriptor.
    	 */</span>
    	<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">BatchDescriptor</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">XMLEntity</span> {
    
    		<span class="hljs-comment">/** The batchSelectors. */</span>
    		<span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> Collection<String> batchSelectors = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span><String>();
    
    		<span class="hljs-comment">/** The dependentCollections. */</span>
    		<span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> Collection<String> dependentCollections = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span><String>();
    
    		<span class="hljs-comment">/** The directSelectors. */</span>
    		<span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> Collection<String> directSelectors = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span><String>();
    
    		<span class="hljs-comment">/** The postTo. */</span>
    		<span class="hljs-keyword">private</span> String postTo;
    
    		<span class="hljs-comment">/** The properties. */</span>
    		<span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> Collection<String> properties = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span><String>();
    
    		<span class="hljs-comment">/**
    		 * Gets the batch selectors iterator.
    		 * 
    		 * <span class="hljs-doctag">@return</span> the batch selectors iterator
    		 */</span>
    		<span class="hljs-keyword">public</span> Iterator<String> <span class="hljs-title function_">getBatchSelectorsIterator</span><span class="hljs-params">()</span> {
    			<span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.batchSelectors.iterator();
    		}
    
    		<span class="hljs-comment">/**
    		 * Gets the dependent collections iterator.
    		 * 
    		 * <span class="hljs-doctag">@return</span> the dependent collections iterator
    		 */</span>
    		<span class="hljs-keyword">public</span> Iterator<String> <span class="hljs-title function_">getDependentCollectionsIterator</span><span class="hljs-params">()</span> {
    			<span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.dependentCollections.iterator();
    		}
    
    		<span class="hljs-comment">/**
    		 * Gets the post to.
    		 * 
    		 * <span class="hljs-doctag">@return</span> the post to
    		 */</span>
    		<span class="hljs-keyword">public</span> String <span class="hljs-title function_">getPostTo</span><span class="hljs-params">()</span> {
    			<span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.postTo;
    		}
    
    		<span class="hljs-comment">/**
    		 * Gets the post to business object.
    		 * 
    		 * <span class="hljs-doctag">@param</span> businessObject
    		 *            the business object
    		 * <span class="hljs-doctag">@param</span> postHandler
    		 *            the post handler
    		 * 
    		 * <span class="hljs-doctag">@return</span> the post to business object
    		 * 
    		 * <span class="hljs-doctag">@throws</span> ValidationException
    		 *             the validation exception
    		 */</span>
    		<span class="hljs-keyword">private</span> BusinessObject <span class="hljs-title function_">getPostToBusinessObject</span><span class="hljs-params">(
    				BusinessObject businessObject, EntityHandler postHandler)</span>
    				<span class="hljs-keyword">throws</span> ValidationException {
    			<span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.postTo == <span class="hljs-literal">null</span>) {
    				<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
    			}
    			<span class="hljs-keyword">final</span> <span class="hljs-type">BusinessObject</span> <span class="hljs-variable">postToBusinessObject</span> <span class="hljs-operator">=</span> businessObject
    					.getBusinessObjectFromMap(<span class="hljs-built_in">this</span>.postTo, postHandler);
    			<span class="hljs-comment">// copy properties</span>
    			<span class="hljs-keyword">for</span> (<span class="hljs-keyword">final</span> String propertyName : <span class="hljs-built_in">this</span>.properties) {
    				String postToPropertyName;
    				<span class="hljs-keyword">if</span> (<span class="hljs-string">"postToStatus"</span>.equals(propertyName)) {
    					<span class="hljs-comment">// status field on batch entity refers to the batch entity</span>
    					<span class="hljs-comment">// itself</span>
    					<span class="hljs-comment">// so postToStatus is used for updating the status property</span>
    					<span class="hljs-comment">// of the postToBusinessObject itself</span>
    					postToPropertyName = <span class="hljs-string">"status"</span>;
    				} <span class="hljs-keyword">else</span> {
    					postToPropertyName = propertyName;
    				}
    				<span class="hljs-keyword">final</span> <span class="hljs-type">SelectorItem</span> <span class="hljs-variable">destinationItem</span> <span class="hljs-operator">=</span> postToBusinessObject
    						.find(postToPropertyName);
    				<span class="hljs-keyword">if</span> (destinationItem != <span class="hljs-literal">null</span>) {
    					<span class="hljs-keyword">final</span> <span class="hljs-type">Object</span> <span class="hljs-variable">oldValue</span> <span class="hljs-operator">=</span> destinationItem.getValue();
    					<span class="hljs-keyword">final</span> <span class="hljs-type">Object</span> <span class="hljs-variable">newValue</span> <span class="hljs-operator">=</span> businessObject.get(propertyName);
    					<span class="hljs-keyword">if</span> (SafeComparator.areDifferent(oldValue, newValue)) {
    						destinationItem.setValue(newValue);
    					}
    				}
    			}
    			<span class="hljs-comment">// copy direct selectors</span>
    			<span class="hljs-keyword">for</span> (<span class="hljs-keyword">final</span> String selectorName : <span class="hljs-built_in">this</span>.directSelectors) {
    				<span class="hljs-keyword">final</span> <span class="hljs-type">SelectorItem</span> <span class="hljs-variable">destinationItem</span> <span class="hljs-operator">=</span> postToBusinessObject
    						.find(selectorName);
    				<span class="hljs-keyword">if</span> (destinationItem != <span class="hljs-literal">null</span>) {
    					<span class="hljs-comment">// get the old and new values for the selectors</span>
    					<span class="hljs-type">Selector</span> <span class="hljs-variable">oldSelector</span> <span class="hljs-operator">=</span> (Selector) destinationItem
    							.getValue();
    					<span class="hljs-type">Selector</span> <span class="hljs-variable">newSelector</span> <span class="hljs-operator">=</span> (Selector) businessObject
    							.get(selectorName);
    					<span class="hljs-comment">// strip them down to bare identifiers for comparison</span>
    					<span class="hljs-keyword">if</span> (oldSelector != <span class="hljs-literal">null</span>) {
    						oldSelector = oldSelector.getAsIdentifier();
    					}
    					<span class="hljs-keyword">if</span> (newSelector != <span class="hljs-literal">null</span>) {
    						newSelector = newSelector.getAsIdentifier();
    					}
    					<span class="hljs-comment">// if they're different then update</span>
    					<span class="hljs-keyword">if</span> (SafeComparator.areDifferent(oldSelector, newSelector)) {
    						destinationItem.setValue(newSelector);
    					}
    				}
    			}
    			<span class="hljs-comment">// copy batch selectors</span>
    			<span class="hljs-keyword">for</span> (<span class="hljs-keyword">final</span> String batchSelectorName : <span class="hljs-built_in">this</span>.batchSelectors) {
    				<span class="hljs-keyword">final</span> <span class="hljs-type">Selector</span> <span class="hljs-variable">batchSelector</span> <span class="hljs-operator">=</span> (Selector) businessObject
    						.get(batchSelectorName);
    				<span class="hljs-keyword">if</span> (batchSelector == <span class="hljs-literal">null</span>) {
    					<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ValidationException</span>(
    							<span class="hljs-string">""PostTo" selector missing."</span>);
    				}
    				<span class="hljs-keyword">final</span> <span class="hljs-type">BusinessObject</span> <span class="hljs-variable">batchObject</span> <span class="hljs-operator">=</span> postHandler
    						.find(batchSelector);
    				<span class="hljs-keyword">if</span> (batchObject != <span class="hljs-literal">null</span>) {
    					<span class="hljs-comment">// get the postTo selector for the batch object we depend on</span>
    					<span class="hljs-keyword">final</span> <span class="hljs-type">BatchDescriptor</span> <span class="hljs-variable">batchDescriptor</span> <span class="hljs-operator">=</span> batchMap
    							.get(batchObject.getName());
    					<span class="hljs-keyword">if</span> (batchDescriptor.postTo != <span class="hljs-literal">null</span>
    							&& postToBusinessObject
    									.containsKey(batchDescriptor.postTo)) {
    						<span class="hljs-keyword">final</span> <span class="hljs-type">Selector</span> <span class="hljs-variable">realSelector</span> <span class="hljs-operator">=</span> batchObject
    								.getBusinessObjectFromMap(
    										batchDescriptor.postTo, postHandler);
    						postToBusinessObject.put(batchDescriptor.postTo,
    								realSelector);
    					}
    				}
    			}
    			businessObject.put(<span class="hljs-built_in">this</span>.postTo, postToBusinessObject);
    			<span class="hljs-keyword">return</span> postToBusinessObject;
    		}
    
    		<span class="hljs-comment">/*
    		 * (non-Javadoc)
    		 * 
    		 * @see
    		 * nz.this.is.absolute.crap.sax.XMLEntity#initChild(java.lang.String,
    		 * java.lang.String, java.lang.String, org.xml.sax.Attributes)
    		 */</span>
    		<span class="hljs-meta">@Override</span>
    		<span class="hljs-keyword">protected</span> ContentHandler <span class="hljs-title function_">initChild</span><span class="hljs-params">(String uri, String localName,
    				String qName, Attributes attributes)</span> <span class="hljs-keyword">throws</span> SAXException {
    			<span class="hljs-keyword">if</span> (<span class="hljs-string">"Properties"</span>.equals(qName)) {
    				<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">XMLEntity</span>() {
    					<span class="hljs-meta">@Override</span>
    					<span class="hljs-keyword">protected</span> ContentHandler <span class="hljs-title function_">initChild</span><span class="hljs-params">(String uri,
    							String localName, String qName,
    							Attributes attributes)</span> <span class="hljs-keyword">throws</span> SAXException {
    						BatchDescriptor.<span class="hljs-built_in">this</span>.properties.add(attributes
    								.getValue(<span class="hljs-string">"name"</span>));
    						<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
    					}
    				};
    			} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-string">"DirectSelectors"</span>.equals(qName)) {
    				<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">XMLEntity</span>() {
    					<span class="hljs-meta">@Override</span>
    					<span class="hljs-keyword">protected</span> ContentHandler <span class="hljs-title function_">initChild</span><span class="hljs-params">(String uri,
    							String localName, String qName,
    							Attributes attributes)</span> <span class="hljs-keyword">throws</span> SAXException {
    						BatchDescriptor.<span class="hljs-built_in">this</span>.directSelectors.add(attributes
    								.getValue(<span class="hljs-string">"name"</span>));
    						<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
    					}
    				};
    			} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-string">"BatchSelectors"</span>.equals(qName)) {
    				<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">XMLEntity</span>() {
    					<span class="hljs-meta">@Override</span>
    					<span class="hljs-keyword">protected</span> ContentHandler <span class="hljs-title function_">initChild</span><span class="hljs-params">(String uri,
    							String localName, String qName,
    							Attributes attributes)</span> <span class="hljs-keyword">throws</span> SAXException {
    						BatchDescriptor.<span class="hljs-built_in">this</span>.batchSelectors.add(attributes
    								.getValue(<span class="hljs-string">"name"</span>));
    						<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
    					}
    				};
    			} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-string">"PostTo"</span>.equals(qName)) {
    				<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">XMLEntity</span>() {
    					<span class="hljs-meta">@Override</span>
    					<span class="hljs-keyword">protected</span> ContentHandler <span class="hljs-title function_">initChild</span><span class="hljs-params">(String uri,
    							String localName, String qName,
    							Attributes attributes)</span> <span class="hljs-keyword">throws</span> SAXException {
    						BatchDescriptor.<span class="hljs-built_in">this</span>.postTo = attributes
    								.getValue(<span class="hljs-string">"name"</span>);
    						<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
    					}
    				};
    			} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-string">"DependentCollections"</span>.equals(qName)) {
    				<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">XMLEntity</span>() {
    					<span class="hljs-meta">@Override</span>
    					<span class="hljs-keyword">protected</span> ContentHandler <span class="hljs-title function_">initChild</span><span class="hljs-params">(String uri,
    							String localName, String qName,
    							Attributes attributes)</span> <span class="hljs-keyword">throws</span> SAXException {
    						BatchDescriptor.<span class="hljs-built_in">this</span>.dependentCollections
    								.add(attributes.getValue(<span class="hljs-string">"name"</span>));
    						<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
    					}
    				};
    			}
    			<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
    		}
    	}
    
    	<span class="hljs-comment">/** The batchMap. */</span>
    	<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> Map<String, BatchDescriptor> batchMap = <span class="hljs-keyword">new</span> <span class="hljs-title class_">HashMap</span><String, BatchDescriptor>();
    
    	<span class="hljs-comment">/**
    	 * Gets the.
    	 * 
    	 * <span class="hljs-doctag">@param</span> batchName
    	 *            the batch name
    	 * 
    	 * <span class="hljs-doctag">@return</span> the batch descriptor
    	 */</span>
    	<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> BatchDescriptor <span class="hljs-title function_">get</span><span class="hljs-params">(String batchName)</span> {
    		<span class="hljs-keyword">return</span> batchMap.get(batchName);
    	}
    
    	<span class="hljs-comment">/**
    	 * Gets the post to selector name.
    	 * 
    	 * <span class="hljs-doctag">@param</span> batchName
    	 *            the batch name
    	 * 
    	 * <span class="hljs-doctag">@return</span> the post to selector name
    	 */</span>
    	<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> String <span class="hljs-title function_">getPostToSelectorName</span><span class="hljs-params">(String batchName)</span> {
    		<span class="hljs-keyword">final</span> <span class="hljs-type">BatchDescriptor</span> <span class="hljs-variable">batchDescriptor</span> <span class="hljs-operator">=</span> batchMap.get(batchName);
    		<span class="hljs-keyword">if</span> (batchDescriptor == <span class="hljs-literal">null</span>) {
    			<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
    		}
    		<span class="hljs-keyword">return</span> batchDescriptor.getPostTo();
    	}
    
    	<span class="hljs-comment">// singleton instance so that static batch map can be initialised using</span>
    	<span class="hljs-comment">// xml</span>
    	<span class="hljs-comment">/** The Constant singleton. */</span>
    	<span class="hljs-meta">@SuppressWarnings("unused")</span>
    	<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-type">Object</span> <span class="hljs-variable">singleton</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">BatchManager</span>();
    
    	<span class="hljs-comment">/**
    	 * Post.
    	 * 
    	 * <span class="hljs-doctag">@param</span> businessObject
    	 *            the business object
    	 * 
    	 * <span class="hljs-doctag">@throws</span> Exception
    	 *             the exception
    	 */</span>
    	<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">post</span><span class="hljs-params">(BusinessObject businessObject)</span> <span class="hljs-keyword">throws</span> Exception {
    		<span class="hljs-comment">// validate the batch root object only - it can validate the rest if it</span>
    		<span class="hljs-comment">// needs to</span>
    		
    		<span class="hljs-keyword">if</span> (businessObject <span class="hljs-keyword">instanceof</span> Validatable) {
    			<span class="hljs-keyword">if</span> (!BatchValidator.validate(businessObject)) {
    				logger.warn(String.format(<span class="hljs-string">"Validating %s failed"</span>, businessObject.getClass().getSimpleName()));
    				<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ValidationException</span>(
    						<span class="hljs-string">"Batch did not validate - it was not posted"</span>);
    			}
    		
    			((Validatable) businessObject).validator().prepareToPost();
    		}
    		<span class="hljs-keyword">final</span> <span class="hljs-type">SQLEntityHandler</span> <span class="hljs-variable">postHandler</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">SQLEntityHandler</span>(<span class="hljs-literal">true</span>);
    		<span class="hljs-keyword">final</span> Iterator<BusinessObject> batchIterator = <span class="hljs-keyword">new</span> <span class="hljs-title class_">BatchIterator</span>(
    				businessObject, <span class="hljs-literal">null</span>, postHandler);
    		<span class="hljs-comment">// iterate through batch again posting each object</span>
    		<span class="hljs-keyword">try</span> {
    			<span class="hljs-keyword">while</span> (batchIterator.hasNext()) {
    				post(batchIterator.next(), postHandler);
    			}
    			postHandler.commit();
    		} <span class="hljs-keyword">catch</span> (<span class="hljs-keyword">final</span> Exception e) {
    			logger.error(<span class="hljs-string">"Exception occurred while posting batches"</span>, e);
    			<span class="hljs-comment">// something went wrong</span>
    			postHandler.rollback();
    			<span class="hljs-keyword">throw</span> e;
    		}
    		<span class="hljs-keyword">return</span>;
    	}
    
    	<span class="hljs-comment">/**
    	 * Post.
    	 * 
    	 * <span class="hljs-doctag">@param</span> businessObject
    	 *            the business object
    	 * <span class="hljs-doctag">@param</span> postHandler
    	 *            the post handler
    	 * 
    	 * <span class="hljs-doctag">@throws</span> KupengaException
    	 *             the kupenga exception
    	 */</span>
    	<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">post</span><span class="hljs-params">(BusinessObject businessObject,
    			EntityHandler postHandler)</span> <span class="hljs-keyword">throws</span> KupengaException {
    		<span class="hljs-keyword">if</span> (businessObject == <span class="hljs-literal">null</span>) {
    			<span class="hljs-keyword">return</span>;
    		}
    		<span class="hljs-keyword">if</span> (Boolean.TRUE.equals(businessObject.get(<span class="hljs-string">"posted"</span>))) {
    			<span class="hljs-keyword">return</span>;
    		}
    		<span class="hljs-keyword">final</span> <span class="hljs-type">BatchDescriptor</span> <span class="hljs-variable">batchDescriptor</span> <span class="hljs-operator">=</span> batchMap.get(businessObject
    				.getName());
    		<span class="hljs-keyword">final</span> <span class="hljs-type">BusinessObject</span> <span class="hljs-variable">postToBusinessObject</span> <span class="hljs-operator">=</span> batchDescriptor
    				.getPostToBusinessObject(businessObject, postHandler);
    		<span class="hljs-keyword">if</span> (postToBusinessObject != <span class="hljs-literal">null</span>) {
    			postToBusinessObject.save(postHandler);
    		}
    		businessObject.setItemValue(<span class="hljs-string">"posted"</span>, Boolean.TRUE);
    		businessObject.save(postHandler);
    	}
    
    	<span class="hljs-comment">/**
    	 * Instantiates a new batch manager.
    	 */</span>
    	<span class="hljs-keyword">private</span> <span class="hljs-title function_">BatchManager</span><span class="hljs-params">()</span> {
    		<span class="hljs-keyword">try</span> {
    			<span class="hljs-keyword">final</span> <span class="hljs-type">XMLReader</span> <span class="hljs-variable">xmlReader</span> <span class="hljs-operator">=</span> XMLReaderFactory.createXMLReader();
    			xmlReader.setContentHandler(<span class="hljs-built_in">this</span>);
    			xmlReader.parse(<span class="hljs-keyword">new</span> <span class="hljs-title class_">InputSource</span>(<span class="hljs-built_in">this</span>.getClass().getClassLoader().getResourceAsStream(<span class="hljs-string">"templates/"</span> + DOCUMENT)));
    		} <span class="hljs-keyword">catch</span> (<span class="hljs-keyword">final</span> Exception e) {
    			logger.error(<span class="hljs-string">"Error parsing Batch XML."</span>, e);
    		}
    	}
    
    	<span class="hljs-comment">/*
    	 * (non-Javadoc)
    	 * 
    	 * @see nz.this.is.absolute.crap.sax.XMLEntity#initChild(java.lang.String,
    	 * java.lang.String, java.lang.String, org.xml.sax.Attributes)
    	 */</span>
    	<span class="hljs-meta">@Override</span>
    	<span class="hljs-keyword">protected</span> ContentHandler <span class="hljs-title function_">initChild</span><span class="hljs-params">(String uri, String localName,
    			String qName, Attributes attributes)</span> <span class="hljs-keyword">throws</span> SAXException {
    		<span class="hljs-keyword">final</span> <span class="hljs-type">BatchDescriptor</span> <span class="hljs-variable">batchDescriptor</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">BatchDescriptor</span>();
    		<span class="hljs-comment">// put it in the map</span>
    		batchMap.put(attributes.getValue(<span class="hljs-string">"name"</span>), batchDescriptor);
    		<span class="hljs-keyword">return</span> batchDescriptor;
    	}
    }
    

    [Advertisement]
    Keep all your packages and Docker containers in one place, scan for vulnerabilities, and control who can access different feeds. ProGet installs in minutes and has a powerful free version with a lot of great features that you can upgrade when ready.Learn more.

    Source: Read More 

    Facebook Twitter Reddit Email Copy Link
    Previous ArticleCritical Cisco Vulnerability in Unified CM Grants Root Access via Static Credentials
    Next Article Making Animations Smarter with Data Binding: Creating a Dynamic Gold Calculator in Rive

    Related Posts

    News & Updates

    Building personal apps with open source and AI

    September 12, 2025
    News & Updates

    What Can We Actually Do With corner-shape?

    September 12, 2025
    Leave A Reply Cancel Reply

    For security, use of Google's reCAPTCHA service is required which is subject to the Google Privacy Policy and Terms of Use.

    Continue Reading

    Train and deploy AI models at trillion-parameter scale with Amazon SageMaker HyperPod support for P6e-GB200 UltraServers

    Machine Learning

    Top Data Center Service Providers in Delhi – Reliable and Scalable Solutions

    Web Development

    Amazon launches spec-driven AI IDE, Kiro

    Tech & Work

    India’s Human AI Srinidhi Ranganathan Unveils Breakthrough in Organoid Intelligence (OI) Research: The Next Step into Sun-Intelligence 5.0

    Artificial Intelligence

    Highlights

    Development

    Researchers Warn of MystRodX Backdoor Using DNS and ICMP Triggers for Stealthy Control

    September 3, 2025

    Cybersecurity researchers have disclosed a stealthy new backdoor called MystRodX that comes with a variety…

    Good UX is not enough

    August 29, 2025

    Amatera Stealer Unveiled: Rebranded ACR Stealer Now More Evasive, Targeting Your Data

    June 19, 2025

    MediaTek Vulnerabilities Let Attackers Escalate Privileges Without User Interaction

    June 2, 2025
    © DevStackTips 2025. All rights reserved.
    • Contact
    • Privacy Policy

    Type above and press Enter to search. Press Esc to cancel.