diff --git a/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/config/xml/XQueryParserUtils.java b/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/config/xml/XQueryParserUtils.java index 202785b..d13549a 100644 --- a/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/config/xml/XQueryParserUtils.java +++ b/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/config/xml/XQueryParserUtils.java @@ -39,11 +39,18 @@ import org.w3c.dom.NodeList; * etc. * * @author Amol Nayak + * * @since 2.2 * */ public class XQueryParserUtils { + + + private XQueryParserUtils() { + //prevent instantiation + } + /** * Create the instance of the {@link XQueryExecutor} * @param element @@ -54,6 +61,69 @@ public class XQueryParserUtils { IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "converter"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "xq-datasource","xQDataSource"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "format-output"); + setXQueryInBuilder(element, builder); + //lets get the parameter nodes + setXQueryParameters(element, builder); + + return builder.getBeanDefinition(); + } + + /** + * The provided xquery may have one or more 'xquery-parameter' child elements, this private helper method sets the parameters in + * the builder for {@link XQueryExecutor} being constructed + * + * @param element + * @param builder + */ + private static void setXQueryParameters(Element element, + BeanDefinitionBuilder builder) { + NodeList parameters = element.getElementsByTagNameNS(element.getNamespaceURI(), "xquery-parameter"); + if(parameters != null && parameters.getLength() > 0) { + ManagedList params = new ManagedList(); + for(int i = 0;i < parameters.getLength();i++) { + Node node = parameters.item(i); + NamedNodeMap attrs = node.getAttributes(); + Assert.isTrue(attrs.getLength() > 1, + "One of ref, value or expression should be present with the name attribute"); + Attr nameAttr = (Attr)attrs.getNamedItem("name"); + + //TODO No check for the mutually exclusivity of these attributes, needed? + + //create a new XQueryParameter instance + BeanDefinitionBuilder paramBuilder = + BeanDefinitionBuilder.genericBeanDefinition(XQueryParameter.class); + paramBuilder.addConstructorArgValue(nameAttr.getTextContent()); + Attr attr; + //add the value if present + if(attrs.getNamedItem("value") != null) { + attr = (Attr)attrs.getNamedItem("value"); + paramBuilder.addPropertyValue("parameterValue",attr.getTextContent()); + } + else if(attrs.getNamedItem("ref") != null) { + attr = (Attr)attrs.getNamedItem("ref"); + paramBuilder.addPropertyReference("parameterValue", attr.getTextContent()); + } + else if(attrs.getNamedItem("expression") != null) { + attr = (Attr)attrs.getNamedItem("expression"); + paramBuilder.addPropertyValue("expression", attr.getTextContent()); + } + params.add(paramBuilder.getBeanDefinition()); + } + builder.addPropertyValue("xQueryParameters", params); + } + } + + /** + * Private helper method that is used to set the xquery in the builder. The XQuery can be provided + * using wither the xquery attribute, xquery sub element or the resource containing the xquery. + * These attributes/child node are mutually exclusive to each other, the method checks for this mutual + * exclusivity and sets in the builder for {@link XQueryExecutor} the appripriate attribute. + * + * @param element + * @param builder + */ + private static void setXQueryInBuilder(Element element, + BeanDefinitionBuilder builder) { NodeList list = element.getElementsByTagNameNS(element.getNamespaceURI(), "xquery"); Attr xQueryAttribute = element.getAttributeNode("xquery"); Attr xQueryResource = element.getAttributeNode("xquery-file-resource"); @@ -105,44 +175,5 @@ public class XQueryParserUtils { builder.addPropertyValue("xQuery", textContent.trim()); } } - - //lets get the parameter nodes - NodeList parameters = element.getElementsByTagNameNS(element.getNamespaceURI(), "xquery-parameter"); - if(parameters != null && parameters.getLength() > 0) { - ManagedList params = new ManagedList(); - for(int i = 0;i < parameters.getLength();i++) { - Node node = parameters.item(i); - NamedNodeMap attrs = node.getAttributes(); - Assert.isTrue(attrs.getLength() > 1, - "One of ref, value or expression should be present with the name attribute"); - Attr nameAttr = (Attr)attrs.getNamedItem("name"); - - //TODO No check for the mutually exclusivity of these attributes, needed? - - //create a new XQueryParameter instance - BeanDefinitionBuilder paramBuilder = - BeanDefinitionBuilder.genericBeanDefinition(XQueryParameter.class); - paramBuilder.addConstructorArgValue(nameAttr.getTextContent()); - Attr attr; - //add the value if present - if(attrs.getNamedItem("value") != null) { - attr = (Attr)attrs.getNamedItem("value"); - paramBuilder.addPropertyValue("parameterValue",attr.getTextContent()); - } - else if(attrs.getNamedItem("ref") != null) { - attr = (Attr)attrs.getNamedItem("ref"); - paramBuilder.addPropertyReference("parameterValue", attr.getTextContent()); - } - else if(attrs.getNamedItem("expression") != null) { - attr = (Attr)attrs.getNamedItem("expression"); - paramBuilder.addPropertyValue("expression", attr.getTextContent()); - } - params.add(paramBuilder.getBeanDefinition()); - } - builder.addPropertyValue("xQueryParameters", params); - } - - - return builder.getBeanDefinition(); } } diff --git a/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/config/xml/XQueryTransformerParser.java b/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/config/xml/XQueryTransformerParser.java index 0a67e63..f3438cb 100644 --- a/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/config/xml/XQueryTransformerParser.java +++ b/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/config/xml/XQueryTransformerParser.java @@ -74,7 +74,7 @@ public class XQueryTransformerParser extends AbstractTransformerParser { try { type = Class.forName(resultType); } catch (ClassNotFoundException e) { - new IllegalArgumentException("Class " + resultType + " specified in result-type not found, " + + throw new IllegalArgumentException("Class " + resultType + " specified in result-type not found, " + "have you provided the fully qualified name?",e); } } diff --git a/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/core/XQueryExecutor.java b/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/core/XQueryExecutor.java index 471b21e..8427364 100644 --- a/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/core/XQueryExecutor.java +++ b/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/core/XQueryExecutor.java @@ -186,19 +186,19 @@ public class XQueryExecutor implements InitializingBean,BeanClassLoaderAware { * @return the instantiated {@link XQDataSource} */ private XQDataSource discoverXQDataSource() { - Object xqDataSource = null; + Object dataSource = null; try { if(ClassUtils.isPresent(SAXON_XQ_DATASOURCE_CLASS, classLoader)) { - xqDataSource = Class.forName(SAXON_XQ_DATASOURCE_CLASS).newInstance(); + dataSource = Class.forName(SAXON_XQ_DATASOURCE_CLASS).newInstance(); } //For now its just Saxon we will discover, we can add other implementations here later } catch (Exception e) { throw new MessagingException("Unable to discover/instantiate an XQDataSource, " + "see nested exception for details", e); } - Assert.notNull(xqDataSource, "No XQDataSource provided nor any known implementation discovered in the classpath"); - logger.info("Using \"" + xqDataSource.getClass() + "\" as the XQDataSource implementation"); - return (XQDataSource)xqDataSource; + Assert.notNull(dataSource, "No XQDataSource provided nor any known implementation discovered in the classpath"); + logger.info("Using \"" + dataSource.getClass() + "\" as the XQDataSource implementation"); + return (XQDataSource)dataSource; } /** @@ -444,8 +444,9 @@ public class XQueryExecutor implements InitializingBean,BeanClassLoaderAware { */ public void setXQueryParameters(List params) { if(params != null && params.size() > 0) { - if(xQueryParameterMap == null) + if(xQueryParameterMap == null) { xQueryParameterMap = new HashMap(); + } for(XQueryParameter param:params) { xQueryParameterMap.put(param.getParameterName(), param); } diff --git a/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/support/AbstractXQueryResultMapper.java b/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/support/AbstractXQueryResultMapper.java index 8d8d9bb..463147a 100644 --- a/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/support/AbstractXQueryResultMapper.java +++ b/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/support/AbstractXQueryResultMapper.java @@ -58,7 +58,6 @@ import javax.xml.xquery.XQException; import javax.xml.xquery.XQItemType; import javax.xml.xquery.XQResultSequence; -import org.springframework.integration.xquery.support.XQueryResultMapper; import org.springframework.util.StringUtils; import org.w3c.dom.Attr; import org.w3c.dom.Node; @@ -71,7 +70,8 @@ import org.w3c.dom.Node; */ public abstract class AbstractXQueryResultMapper implements XQueryResultMapper { - protected volatile boolean formatOutput; + private volatile boolean formatOutput; + /** * The getBaseType method throws an exception if the item kind is of some specific types * This method will be used to check if the getBaseType method can be invoked or not @@ -155,7 +155,7 @@ public abstract class AbstractXQueryResultMapper implements XQueryResultMappe Number value = null; try { if(StringUtils.hasText(strValue)) { - if(strValue.indexOf(".") > 0) { + if(strValue.indexOf('.') > 0) { value = Double.valueOf(strValue); } else { @@ -263,13 +263,13 @@ public abstract class AbstractXQueryResultMapper implements XQueryResultMappe * @throws TransformerException */ protected String transformNodeToString(Node n) - throws TransformerConfigurationException, - TransformerFactoryConfigurationError, TransformerException { + throws TransformerException { String value; StringWriter writer = new StringWriter(); Transformer transformer = TransformerFactory.newInstance().newTransformer(); - if(formatOutput) + if(formatOutput) { transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + } transformer.transform( new DOMSource(n), new StreamResult(writer)); value = writer.toString(); return value; diff --git a/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/support/BooleanResultMapper.java b/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/support/BooleanResultMapper.java index f7ec562..e6be943 100644 --- a/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/support/BooleanResultMapper.java +++ b/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/support/BooleanResultMapper.java @@ -42,11 +42,9 @@ public class BooleanResultMapper extends AbstractXQueryResultMapper { while(result.next()) { XQItemType type = result.getItemType(); Boolean value = convertToBoolean(type, result); - if(value == null) { - if(isNodeType(type)) { - Node n = result.getNode(); - value = Boolean.valueOf(transformNodeToString(n)); - } + if(value == null && isNodeType(type)) { + Node n = result.getNode(); + value = Boolean.valueOf(transformNodeToString(n)); } results.add(value); } diff --git a/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/support/NumberResultMapper.java b/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/support/NumberResultMapper.java index 238185b..960c5b5 100644 --- a/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/support/NumberResultMapper.java +++ b/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/support/NumberResultMapper.java @@ -42,17 +42,15 @@ public class NumberResultMapper extends AbstractXQueryResultMapper { XQItemType type = result.getItemType(); Number value = convertToNumber(type, result); - if(value == null) { - if(isNodeType(type)) { - Node n = result.getNode(); - String strValue = transformNodeToString(n); - if(StringUtils.hasText(strValue)) { - if(strValue.indexOf(".") > 0) { - value = Double.valueOf(strValue); - } - else { - value = Long.valueOf(strValue); - } + if(value == null && isNodeType(type)) { + Node n = result.getNode(); + String strValue = transformNodeToString(n); + if(StringUtils.hasText(strValue)) { + if(strValue.indexOf('.') > 0) { + value = Double.valueOf(strValue); + } + else { + value = Long.valueOf(strValue); } } } diff --git a/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/support/XQueryParameter.java b/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/support/XQueryParameter.java index 0d5fd78..191669c 100644 --- a/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/support/XQueryParameter.java +++ b/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/support/XQueryParameter.java @@ -99,7 +99,7 @@ public class XQueryParameter { * Sets the expression that would be evaluated to get the parameter value * @param expression */ - public void setExpression(String expression) { + public final void setExpression(String expression) { Assert.isTrue(parameterValue == null, "The parameter value and expression are mutually exclusive" + ", parameter value already set"); Assert.isTrue(!StringUtils.hasText(this.expression), "Expression string is already set once, cannot reset it"); diff --git a/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/support/XQueryUtils.java b/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/support/XQueryUtils.java index 4c2ac56..56a8d4d 100644 --- a/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/support/XQueryUtils.java +++ b/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/support/XQueryUtils.java @@ -21,6 +21,8 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.springframework.core.io.Resource; import org.springframework.integration.MessagingException; import org.springframework.util.Assert; @@ -37,6 +39,16 @@ import org.springframework.util.Assert; */ public class XQueryUtils { + private static final Log logger = LogFactory.getLog(XQueryUtils.class); + + + + private XQueryUtils() { + //prevent instantiation + throw new AssertionError("Cannot instantiate a utility class"); + } + + /** * Reads the XQuery string from the resource file specified * @@ -49,10 +61,11 @@ public class XQueryUtils { Assert.notNull(resource, "null resource provided"); Assert.isTrue(resource.exists(), "Provided XQuery resource does not exist"); Assert.isTrue(resource.isReadable(), "Provided XQuery resource is not readable"); + BufferedReader reader = null; try { URL url = resource.getURL(); InputStream inStream = url.openStream(); - BufferedReader reader = new BufferedReader(new InputStreamReader(inStream)); + reader = new BufferedReader(new InputStreamReader(inStream)); String line = reader.readLine(); StringBuilder builder = new StringBuilder(); while(line != null) { @@ -64,6 +77,14 @@ public class XQueryUtils { return xQuery; } catch (IOException e) { throw new MessagingException("Error while reading the xQuery resource", e); + } finally { + if(reader != null) { + try { + reader.close(); + } catch (IOException e) { + logger.error("Exception while closing reader", e); + } + } } } } diff --git a/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/transformer/XQueryTransformer.java b/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/transformer/XQueryTransformer.java index a82c62a..f648f4a 100644 --- a/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/transformer/XQueryTransformer.java +++ b/spring-integration-xquery/src/main/java/org/springframework/integration/xquery/transformer/XQueryTransformer.java @@ -66,7 +66,7 @@ public class XQueryTransformer extends AbstractTransformer { */ @SuppressWarnings("unchecked") @Override - protected Object doTransform(Message message) throws Exception { + protected Object doTransform(Message message) { Object transformed; List queryResult; if(resultType != null) {