From 8c6b22f730e4483d8c4a443b2923869c030a91e1 Mon Sep 17 00:00:00 2001 From: Gunnar Hillert Date: Wed, 15 Aug 2012 00:56:45 -0400 Subject: [PATCH] INTSAMPLES-86 - Add XQuery Sample For reference see: https://jira.springsource.org/browse/INTSAMPLES-86 --- README.md | 16 ++ basic/pom.xml | 49 +++--- basic/xquery/README.md | 103 ++++++++++++ basic/xquery/pom.xml | 153 ++++++++++++++++++ .../org/springframework/integration/Main.java | 133 +++++++++++++++ .../integration/service/CustomerService.java | 36 +++++ .../spring-integration-context.xml | 42 +++++ .../src/main/resources/data/customers.xml | 18 +++ .../xquery/src/main/resources/data/xquery.xql | 4 + basic/xquery/src/main/resources/log4j.xml | 28 ++++ .../integration/CustomerServiceTest.java | 67 ++++++++ 11 files changed, 625 insertions(+), 24 deletions(-) create mode 100644 basic/xquery/README.md create mode 100644 basic/xquery/pom.xml create mode 100644 basic/xquery/src/main/java/org/springframework/integration/Main.java create mode 100644 basic/xquery/src/main/java/org/springframework/integration/service/CustomerService.java create mode 100644 basic/xquery/src/main/resources/META-INF/spring/integration/spring-integration-context.xml create mode 100644 basic/xquery/src/main/resources/data/customers.xml create mode 100644 basic/xquery/src/main/resources/data/xquery.xql create mode 100644 basic/xquery/src/main/resources/log4j.xml create mode 100644 basic/xquery/src/test/java/org/springframework/integration/CustomerServiceTest.java diff --git a/README.md b/README.md index 7252574f..b567ab72 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,15 @@ Welcome to the Spring Integration Samples. To simplify your experience, Spring I *Happy Integration!* +## Related GitHub projects + +* [Spring Integration][] +* [Spring Integration Extensions][] +* [Spring Integration Templates][] +* [Spring Integration Dsl Groovy][] +* [Spring Integration Dsl Scala][] +* [Spring Integration Pattern Catalog][] + # Categories Below is a short description of each category. @@ -43,6 +52,7 @@ This is a good place to get started. The samples here are technically motivated * **ws-outbound-gateway** - Shows outbound web services support using the **Web Service Outbound Gateway**, **Content Enricher**, Composed Message Processor (**Chain**) * **xml** - Example demonstrates various aspects of the **Xml** support using an **XPath Splitter**, **XPath Router**, **XSLT Transformer** as well as **XPath Expression** support * **xmpp** - Show the support for [**XMPP**](http://en.wikipedia.org/wiki/Extensible_Messaging_and_Presence_Protocol) (formerly known as Jabber) using e.g. GoogleTalk +* **xquery** - Shows the capabilities of the **[Spring Integration XQuery](https://github.com/SpringSource/spring-integration-extensions/tree/master/spring-integration-xquery)** module ## Intermediate @@ -82,3 +92,9 @@ This category targets developers and architects who have a good understanding of #Resources For more information, please visit the Spring Integration website at: [http://www.springsource.org/spring-integration](http://www.springsource.org/spring-integration) + +[Spring Integration Extensions]: https://github.com/SpringSource/spring-integration-extensions +[Spring Integration Templates]: https://github.com/SpringSource/spring-integration-templates/tree/master/si-sts-templates +[Spring Integration Dsl Groovy]: https://github.com/SpringSource/spring-integration-dsl-groovy +[Spring Integration Dsl Scala]: https://github.com/SpringSource/spring-integration-dsl-scala +[Spring Integration Pattern Catalog]: https://github.com/SpringSource/spring-integration-pattern-catalog diff --git a/basic/pom.xml b/basic/pom.xml index 5117037d..ebf2a342 100644 --- a/basic/pom.xml +++ b/basic/pom.xml @@ -3,36 +3,37 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 - org.springframework.integration.samples + org.springframework.integration.samples basic-samples 2.1.0.BUILD-SNAPSHOT Spring Integration Samples - Basic pom - amqp - control-bus - enricher - feed - file - ftp - helloworld - http - jdbc - jms - jmx - jpa - mail - oddeven - quote - sftp - tcp-client-server - testing-examples - twitter - ws-inbound-gateway - ws-outbound-gateway - xml - xmpp + amqp + control-bus + enricher + feed + file + ftp + helloworld + http + jdbc + jms + jmx + jpa + mail + oddeven + quote + sftp + tcp-client-server + testing-examples + twitter + ws-inbound-gateway + ws-outbound-gateway + xml + xmpp + xquery diff --git a/basic/xquery/README.md b/basic/xquery/README.md new file mode 100644 index 00000000..55929242 --- /dev/null +++ b/basic/xquery/README.md @@ -0,0 +1,103 @@ +Spring Integration - XQuery Sample +================================== + +## Overview + +This sample executes a simple [XQuery][] script. It uses the *[Spring Integration XQuery][]* module, which is part of the [Spring Integration Extensions][] project. The sample uses one of the following 3 XQuery processors: + +* [Saxon][] +* [Sedna][] +* [BaseX][] + +The example for [Saxon][] will work out of the box. [Sedna][] and [BaseX][] are in fact [XML Databases][], which run as external processes. For [Sedna][]- and [BaseX][]-specific setup instructions, please visit: + +* http://xqj.net/sedna/ +* http://xqj.net/basex/ + +## Running the Sample + +From the command line execute: + + $ mvn clean package + +followed by: + + $ mvn exec:java + +The application should start up and you will see the following screen on which you can choose which XQuery processor to use: + + ========================================================= + + Welcome to the Spring Integration XQuery Sample! + + For more information please visit: + http://www.springintegration.org/ + + ========================================================= + Which XQuery Processor would you like to use? : + 1. Use Saxon + 2. Use Sedna + 3. Use BaseX + q. Quit the application + Enter you choice: + +### Note regarding BaseX + +The [BaseX][] dependency conflicts with [Sedna][]. Therefore, this sample applies a separate Maven profile for [BaseX][]. If not triggering that special profile when you try to execute the [BaseX][] example, you may encounter the following error message: + + Detected the Sedna library to be present. This conflicts with BaseX. Please start the application from the command line using: + + mvn exec:java -Dbasex + +Consequently, execute from the command line: + + $ mvn exec:java -Dbasex + +The [BaseX][] sample will now execute successfully. + +## Details + +The used XQuery Script, located under `src/main/resources/data/xquery.xql`, is quite simple: + + + { //customers/customer/name } + + +All it does is extracting the customer names from the following XML document: + + + + Foo Industries + Chemical + Glowing City + + + Bar Refreshments + Beverage + Desert Town + + + Hello World Services + Travel + Coral Sands + + + + +The XML document is located at `src/main/resources/data/customers.xml`. + +The resulting XML document should look like: + + + Foo Industries + Bar Refreshments + Hello World Services + + +[Saxon]: http://saxon.sourceforge.net/ +[Sedna]: http://www.sedna.org/ +[BaseX]: http://basex.org/ +[Spring Integration XQuery]: https://github.com/SpringSource/spring-integration-extensions/tree/master/spring-integration-xquery +[Spring Integration Extensions]: https://github.com/SpringSource/spring-integration-extensions +[XML Databases]: http://en.wikipedia.org/wiki/XML_database +[XQuery]: http://en.wikipedia.org/wiki/XQuery \ No newline at end of file diff --git a/basic/xquery/pom.xml b/basic/xquery/pom.xml new file mode 100644 index 00000000..919682dc --- /dev/null +++ b/basic/xquery/pom.xml @@ -0,0 +1,153 @@ + + 4.0.0 + + org.springframework.integration.samples + xquery + 1.0.0.BUILD-SNAPSHOT + jar + + xquery + http://www.springsource.org/spring-integration + + + 2.2.1 + + + + UTF-8 + 2.2.0.RC2 + 1.2.17 + 4.10 + + + + + repo.springsource.org.milestone + Spring Framework Maven Snapshot Repository + https://repo.springsource.org/libs-snapshot + true + + + + + + + maven-eclipse-plugin + 2.9 + + + org.springframework.ide.eclipse.core.springnature + + + org.springframework.ide.eclipse.core.springbuilder + + true + true + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.5.1 + + 1.6 + 1.6 + -Xlint:all + true + true + + + + org.codehaus.mojo + exec-maven-plugin + 1.2.1 + + org.springframework.integration.Main + + + + + + + + + + + junit + junit + ${junit.version} + test + + + + + + org.springframework.integration + spring-integration-core + ${spring.integration.version} + + + + org.springframework.integration + spring-integration-xml + ${spring.integration.version} + + + + org.springframework.integration + spring-integration-xquery + 1.0.0.BUILD-SNAPSHOT + + + + + + log4j + log4j + ${log4j.version} + + + + + + net.sf.saxon + Saxon-HE + 9.4 + + + + + default + + !basex + + + + net.xqj.sedna + sedna-xqj + 1.0.0 + + + com.xqj2 + xqj2 + 0.1.0 + + + + + basex + + basex + + + + net.xqj + basex-xqj + 1.2.3 + + + + + + diff --git a/basic/xquery/src/main/java/org/springframework/integration/Main.java b/basic/xquery/src/main/java/org/springframework/integration/Main.java new file mode 100644 index 00000000..0db53b3e --- /dev/null +++ b/basic/xquery/src/main/java/org/springframework/integration/Main.java @@ -0,0 +1,133 @@ +/* + * Copyright 2002-2012 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.integration; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Scanner; + +import org.apache.log4j.Logger; +import org.springframework.context.support.GenericXmlApplicationContext; +import org.springframework.core.io.Resource; +import org.springframework.integration.service.CustomerService; +import org.springframework.util.ClassUtils; +import org.springframework.util.FileCopyUtils; + + +/** + * Starts the Spring Context and will initialize the Spring Integration routes. + * + * @author Gunnar Hillert + * @version 1.0 + * + */ +public final class Main { + + private static final Logger LOGGER = Logger.getLogger(Main.class); + + private static final String HORIZONTAL_LINE = "=========================================================\n"; + + private Main() { } + + /** + * Load the Spring Integration Application Context + * + * @param args - command line arguments + * @throws IOException + */ + public static void main(final String... args) throws IOException { + + final Scanner scanner = new Scanner(System.in); + + System.out.println("\n" + + HORIZONTAL_LINE + + "\n " + + "\n Welcome to the Spring Integration XQuery Sample! " + + "\n " + + "\n For more information please visit: " + + "\n http://www.springintegration.org/ " + + "\n " + + "\n" + + HORIZONTAL_LINE); + + System.out.println("Which XQuery Processor would you like to use? : "); + System.out.println("\t1. Use Saxon"); + System.out.println("\t2. Use Sedna"); + System.out.println("\t3. Use BaseX"); + + System.out.println("\tq. Quit the application"); + System.out.print("Enter your choice: "); + + final GenericXmlApplicationContext context = new GenericXmlApplicationContext(); + + while (true) { + final String input = scanner.nextLine(); + + if("1".equals(input.trim())) { + context.getEnvironment().setActiveProfiles("saxon"); + System.out.println("\nUsing Saxon..."); + break; + } else if("2".equals(input.trim())) { + context.getEnvironment().setActiveProfiles("sedna"); + System.out.println("\nUsing Sedna..."); + break; + } else if("3".equals(input.trim())) { + context.getEnvironment().setActiveProfiles("basex"); + System.out.println("\nUsing BaseX..."); + + if(ClassUtils.isPresent("net.xqj.sedna.SednaXQDataSource", ClassUtils.getDefaultClassLoader())) { + LOGGER.error("Detected the Sedna library to be present. This " + + "conflicts with BaseX. Please start the application " + + "from the command line using:\n\n" + + "mvn exec:java -Dbasex\n\nExiting..."); + System.exit(1); + } + + break; + } else if("q".equals(input.trim())) { + System.out.println("Exiting application...bye."); + System.exit(0); + } else { + System.out.println("Invalid choice\n\n"); + System.out.print("Enter you choice: "); + } + } + + context.load("classpath:META-INF/spring/integration/*-context.xml"); + context.registerShutdownHook(); + context.refresh(); + + final CustomerService service = context.getBean(CustomerService.class); + + final Resource resource = context.getResource("classpath:data/customers.xml"); + final InputStream is = resource.getInputStream(); + final String customers = new String(FileCopyUtils.copyToByteArray(is)); + + System.out.println("\n\nExtracting Customer Names from:\n" + + HORIZONTAL_LINE + + customers + "\n" + + HORIZONTAL_LINE + + "\n"); + final String customernames = service.getCustomerNames(customers); + System.out.println("Extracted Customer Names: \n" + + HORIZONTAL_LINE + + customernames + "\n" + + HORIZONTAL_LINE + + "\n"); + + } + +} \ No newline at end of file diff --git a/basic/xquery/src/main/java/org/springframework/integration/service/CustomerService.java b/basic/xquery/src/main/java/org/springframework/integration/service/CustomerService.java new file mode 100644 index 00000000..8b4de616 --- /dev/null +++ b/basic/xquery/src/main/java/org/springframework/integration/service/CustomerService.java @@ -0,0 +1,36 @@ +/* + * Copyright 2002-2012 the original author or authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.integration.service; + +/** + * XML Extraction Service. + * + * @author Gunnar Hillert + * @version 1.0 + * + */ +public interface CustomerService { + + /** + * For a given customer XML file, this method extracts all customer names and + * returns them as a new XML document. + * + * @param sourceXml The source XML file to extract the customer names from + * @return The String-based XML document containing the customer names + */ + String getCustomerNames(String sourceXml); + +} diff --git a/basic/xquery/src/main/resources/META-INF/spring/integration/spring-integration-context.xml b/basic/xquery/src/main/resources/META-INF/spring/integration/spring-integration-context.xml new file mode 100644 index 00000000..9f5347b1 --- /dev/null +++ b/basic/xquery/src/main/resources/META-INF/spring/integration/spring-integration-context.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/basic/xquery/src/main/resources/data/customers.xml b/basic/xquery/src/main/resources/data/customers.xml new file mode 100644 index 00000000..741689c6 --- /dev/null +++ b/basic/xquery/src/main/resources/data/customers.xml @@ -0,0 +1,18 @@ + + + + Foo Industries + Chemical + Glowing City + + + Bar Refreshments + Beverage + Desert Town + + + Hello World Services + Travel + Coral Sands + + \ No newline at end of file diff --git a/basic/xquery/src/main/resources/data/xquery.xql b/basic/xquery/src/main/resources/data/xquery.xql new file mode 100644 index 00000000..841a537f --- /dev/null +++ b/basic/xquery/src/main/resources/data/xquery.xql @@ -0,0 +1,4 @@ + (: The XQuery Script that will extract the customer names from the source XML file :) + + { //customers/customer/name } + \ No newline at end of file diff --git a/basic/xquery/src/main/resources/log4j.xml b/basic/xquery/src/main/resources/log4j.xml new file mode 100644 index 00000000..739aaa48 --- /dev/null +++ b/basic/xquery/src/main/resources/log4j.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/basic/xquery/src/test/java/org/springframework/integration/CustomerServiceTest.java b/basic/xquery/src/test/java/org/springframework/integration/CustomerServiceTest.java new file mode 100644 index 00000000..b3b64002 --- /dev/null +++ b/basic/xquery/src/test/java/org/springframework/integration/CustomerServiceTest.java @@ -0,0 +1,67 @@ +/* + * Copyright 2002-2012 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.integration; + +import junit.framework.Assert; + +import org.junit.Test; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.integration.service.CustomerService; + +/** + * Verify that the Spring Integration Application Context starts successfully. + * + * @author Gunnar Hillert + * @since 1.0 + * + */ +public class CustomerServiceTest { + + @Test + public void testStartupOfSpringInegrationContext() throws Exception{ + new ClassPathXmlApplicationContext("/META-INF/spring/integration/spring-integration-context.xml", + CustomerServiceTest.class); + Thread.sleep(2000); + } + + @Test + public void testExtractCustomerNames() { + final ApplicationContext context + = new ClassPathXmlApplicationContext("/META-INF/spring/integration/spring-integration-context.xml", + CustomerServiceTest.class); + + final CustomerService service = context.getBean(CustomerService.class); + + final String sourceXml = "Foo Industries" + + "ChemicalGlowing City"; + final String expectedResult = "\n" + + "\n" + + " Foo Industries\n" + + "\n"; + + final String extractedCustomerNames = service.getCustomerNames(sourceXml); + + System.out.println(">>" + expectedResult + "<<"); + System.out.println(">>" + extractedCustomerNames + "<<"); + + Assert.assertEquals("The expected list of customer names did not match.", + expectedResult, extractedCustomerNames); + + } + +}