diff --git a/applications/cafe-scripted/.gitignore b/applications/cafe-scripted/.gitignore
new file mode 100644
index 00000000..c2f82a3b
--- /dev/null
+++ b/applications/cafe-scripted/.gitignore
@@ -0,0 +1,5 @@
+/target
+.classpath
+.project
+.springBeans
+.settings
diff --git a/applications/cafe-scripted/README.md b/applications/cafe-scripted/README.md
new file mode 100644
index 00000000..53119680
--- /dev/null
+++ b/applications/cafe-scripted/README.md
@@ -0,0 +1,27 @@
+Cafe Demo - Scripted Implementation
+===================================
+
+This is the scripted implementation of the classic **cafe** sample application. You can choose among **javascript**,
+**groovy**, **ruby**, and **python** scripting languages. The functionality is basically identical in all cases to the
+original cafe demo.
+
+# Instructions for running the CafeDemo sample
+
+The script language is passed as a command line argument. This may be run directly from maven:
+>mvn clean compile
+
+>mvn exec:exec -Dlang=[language]
+
+## Groovy Control Bus
+This sample also demonstrates the use of Spring Integration's **groovy control bus** which accepts
+Groovy scripts as control messages. These scripts may invoke lifecycle operations on adapters or
+operations on managed beans.
+
+To demonstrate the control bus, while the CafeDemoApp is running, execute in a separate window:
+
+>mvn exec:exec -Pcontrol-bus
+
+This will use groovy scripts to
+ * Query the waiter for the total number of orders delivered
+ * If the total orders > 3, stop the inbound adaptor on the cafe (the order flow). The Cafe application
+ will continue to run, but eventually the output will stop when all pending orders have completed.
diff --git a/applications/cafe-scripted/pom.xml b/applications/cafe-scripted/pom.xml
new file mode 100644
index 00000000..011dcee9
--- /dev/null
+++ b/applications/cafe-scripted/pom.xml
@@ -0,0 +1,212 @@
+
+
+ 4.0.0
+ org.springframework.integration.samples
+ cafe-scripted
+ 2.1.0
+ Spring Integration Cafe Sample
+
+ 2.1.0.RC1
+ 3.1.0.RC1
+ 1.2.16
+ 4.7
+
+
+
+
+ org.springframework
+ spring-core
+ ${spring.version}
+
+
+
+ org.springframework
+ spring-test
+ ${spring.version}
+ test
+
+
+
+ org.springframework
+ spring-context
+ ${spring.version}
+
+
+
+ org.springframework
+ spring-context-support
+ ${spring.version}
+
+
+
+ org.springframework.integration
+ spring-integration-core
+ ${spring.integration.version}
+
+
+
+ org.springframework.integration
+ spring-integration-stream
+ ${spring.integration.version}
+
+
+
+ org.springframework.integration
+ spring-integration-groovy
+ ${spring.integration.version}
+
+
+ org.springframework.integration
+ spring-integration-rmi
+ ${spring.integration.version}
+
+
+ org.springframework.integration
+ spring-integration-jmx
+ ${spring.integration.version}
+
+
+
+ org.springframework.integration
+ spring-integration-scripting
+ ${spring.integration.version}
+
+
+
+ log4j
+ log4j
+ ${log4j.version}
+
+
+
+ junit
+ junit
+ ${junit.version}
+
+
+
+
+
+ org.jruby
+ jruby
+ 1.5.6
+
+
+
+ org.python
+ jython-standalone
+ 2.5.2
+
+
+
+ org.codehaus.groovy
+ groovy-all
+ 1.7.5
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 2.2
+
+ 1.5
+ 1.6
+ -Xlint:all
+ true
+ false
+
+
+
+
+
+
+
+
+ true
+
+ demo
+
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ 1.2.1
+
+
+
+ exec
+
+
+
+
+ java
+
+ -classpath
+
+ org.springframework.integration.samples.cafe.demo.CafeDemoApp
+ ${lang}
+
+
+ 0
+
+
+
+
+
+
+
+ control-bus
+
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ 1.2.1
+
+
+
+ exec
+
+
+
+
+ java
+
+ -classpath
+
+ org.springframework.integration.samples.cafe.demo.ControlBusMain
+
+
+
+ 0
+
+
+
+
+
+
+
+
+
+ repository.springframework.maven.release
+ Spring Framework Maven Release Repository
+ http://maven.springframework.org/release
+
+
+ repository.springframework.maven.milestone
+ Spring Framework Maven Milestone Repository
+ http://maven.springframework.org/milestone
+
+
+ repository.springframework.maven.snapshot
+ Spring Framework Maven Snapshot Repository
+ http://maven.springframework.org/snapshot
+
+
+
diff --git a/applications/cafe-scripted/scripts/groovy/barista.groovy b/applications/cafe-scripted/scripts/groovy/barista.groovy
new file mode 100644
index 00000000..cf5da34f
--- /dev/null
+++ b/applications/cafe-scripted/scripts/groovy/barista.groovy
@@ -0,0 +1,19 @@
+package groovy
+import org.springframework.integration.samples.cafe.Drink
+
+def prepareDrink(orderItem){
+ println "groovy: preparing $orderItem for order ${orderItem.order.number}"
+ try {
+ Thread.sleep(timeToPrepare as long)
+ } catch (e) {
+ println "sleep interrupted"
+ }
+ new Drink(orderItem.getOrder().getNumber(), orderItem.getDrinkType(), orderItem.isIced(),
+ orderItem.getShots())
+}
+
+prepareDrink(payload)
+
+
+
+
\ No newline at end of file
diff --git a/applications/cafe-scripted/scripts/javascript/barista.js b/applications/cafe-scripted/scripts/javascript/barista.js
new file mode 100644
index 00000000..3f1effe7
--- /dev/null
+++ b/applications/cafe-scripted/scripts/javascript/barista.js
@@ -0,0 +1,13 @@
+importClass(org.springframework.integration.samples.cafe.Drink);
+importClass(java.lang.Thread);
+importClass(java.lang.System);
+
+function prepareDrink(orderItem){
+ Thread.sleep(timeToPrepare);
+ System.out.println("javascript: preparing "+ orderItem + " for order "+ orderItem.getOrder().getNumber())
+ return new Drink(orderItem.getOrder().getNumber(), orderItem.getDrinkType(), orderItem.isIced(),
+ orderItem.getShots())
+}
+
+prepareDrink(payload);
+
diff --git a/applications/cafe-scripted/scripts/python/barista.py b/applications/cafe-scripted/scripts/python/barista.py
new file mode 100644
index 00000000..fef0b2f3
--- /dev/null
+++ b/applications/cafe-scripted/scripts/python/barista.py
@@ -0,0 +1,11 @@
+from org.springframework.integration.samples.cafe import Drink
+import time
+
+def prepareDrink(orderItem):
+ print("python: preparing %s for order %s" % (orderItem,orderItem.order.number))
+ time.sleep(eval(timeToPrepare))
+ return Drink(orderItem.getOrder().getNumber(), orderItem.getDrinkType(), orderItem.isIced(),
+ orderItem.getShots())
+
+drink = prepareDrink(payload)
+
\ No newline at end of file
diff --git a/applications/cafe-scripted/scripts/ruby/barista.rb b/applications/cafe-scripted/scripts/ruby/barista.rb
new file mode 100644
index 00000000..6e235b9f
--- /dev/null
+++ b/applications/cafe-scripted/scripts/ruby/barista.rb
@@ -0,0 +1,15 @@
+ require 'java'
+
+ import org.springframework.integration.samples.cafe.Drink
+
+ orderItem = payload
+
+ puts "ruby: preparing #{orderItem} for order #{orderItem.order.number}"
+
+ sleep(timeToPrepare.to_f)
+
+ Drink.new(orderItem.getOrder().getNumber(), orderItem.getDrinkType(), orderItem.isIced(),
+ orderItem.getShots())
+
+
+
\ No newline at end of file
diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Customer.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Customer.java
new file mode 100644
index 00000000..fa48aa75
--- /dev/null
+++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Customer.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2002-2011 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.samples.cafe;
+
+/**
+ * @author David Turanski
+ *
+ */
+public class Customer {
+ int orderNumber = 1;
+ public Order getOrder(){
+ Order order = new Order(orderNumber++);
+ order.addItem(DrinkType.LATTE, 2, false);
+ order.addItem(DrinkType.MOCHA, 3, true);
+ return order;
+ }
+}
diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Delivery.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Delivery.java
new file mode 100644
index 00000000..a59fbd43
--- /dev/null
+++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Delivery.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2002-2010 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.samples.cafe;
+
+import java.util.List;
+
+/**
+ * @author Marius Bogoevici
+ */
+public class Delivery {
+
+ private static final String SEPARATOR = "-----------------------";
+
+
+ private List deliveredDrinks;
+
+ private int orderNumber;
+
+
+ public Delivery(List deliveredDrinks) {
+ assert(deliveredDrinks.size() > 0);
+ this.deliveredDrinks = deliveredDrinks;
+ this.orderNumber = deliveredDrinks.get(0).getOrderNumber();
+ }
+
+
+ public int getOrderNumber() {
+ return orderNumber;
+ }
+
+ public List getDeliveredDrinks() {
+ return deliveredDrinks;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer buffer = new StringBuffer(SEPARATOR + "\n");
+ buffer.append("Order #" + getOrderNumber() + "\n");
+ for (Drink drink : getDeliveredDrinks()) {
+ buffer.append(drink);
+ buffer.append("\n");
+ }
+ buffer.append(SEPARATOR + "\n");
+ return buffer.toString();
+ }
+
+}
diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Drink.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Drink.java
new file mode 100644
index 00000000..a8e445ee
--- /dev/null
+++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Drink.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2002-2011 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.samples.cafe;
+
+/**
+ * @author Marius Bogoevici
+ */
+public class Drink {
+
+ private boolean iced;
+
+ private int shots;
+
+ private DrinkType drinkType;
+
+ private int orderNumber;
+
+
+ public Drink(int orderNumber, DrinkType drinkType, boolean hot, int shots) {
+ this.orderNumber = orderNumber;
+ this.drinkType = drinkType;
+ this.iced = hot;
+ this.shots = shots;
+ }
+
+
+ public int getOrderNumber() {
+ return orderNumber;
+ }
+
+ @Override
+ public String toString() {
+ return (iced?"Iced":"Hot") + " " + drinkType.toString() + ", " + shots + " shots.";
+ }
+
+}
diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/DrinkType.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/DrinkType.java
new file mode 100644
index 00000000..4944ca4c
--- /dev/null
+++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/DrinkType.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2002-2011 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.samples.cafe;
+
+/**
+ * @author Mark Fisher
+ */
+public enum DrinkType {
+
+ ESPRESSO,
+ LATTE,
+ CAPPUCCINO,
+ MOCHA
+
+}
diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Order.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Order.java
new file mode 100644
index 00000000..eb2d7e75
--- /dev/null
+++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Order.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2002-2011 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.samples.cafe;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Mark Fisher
+ * @author Marius Bogoevici
+ */
+public class Order {
+
+ private List orderItems = new ArrayList();
+
+ private int number;
+
+ public Order(int number) {
+ this.number = number;
+ }
+
+ public void addItem(DrinkType drinkType, int shots, boolean iced) {
+ this.orderItems.add(new OrderItem(this, drinkType, shots, iced));
+ }
+
+ public int getNumber() {
+ return number;
+ }
+
+ public List getItems() {
+ return this.orderItems;
+ }
+
+ public String toString() {
+ return "Order number " + number;
+ }
+
+}
diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/OrderItem.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/OrderItem.java
new file mode 100644
index 00000000..07c5e9a4
--- /dev/null
+++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/OrderItem.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2002-2011 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.samples.cafe;
+
+/**
+ * @author Mark Fisher
+ * @author Marius Bogoevici
+ */
+public class OrderItem {
+
+ private DrinkType type;
+
+ private int shots = 1;
+
+ private boolean iced = false;
+
+ private final Order order;
+
+
+ public OrderItem(Order order, DrinkType type, int shots, boolean iced) {
+ this.order = order;
+ this.type = type;
+ this.shots = shots;
+ this.iced = iced;
+ }
+
+
+ public Order getOrder() {
+ return this.order;
+ }
+
+ public boolean isIced() {
+ return this.iced;
+ }
+
+ public int getShots() {
+ return shots;
+ }
+
+ public DrinkType getDrinkType() {
+ return this.type;
+ }
+
+ public String toString() {
+ return ((this.iced) ? "iced " : "hot ") + " order:" + this.order.getNumber() + " " +this.shots + " shot " + this.type;
+ }
+
+}
diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Waiter.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Waiter.java
new file mode 100644
index 00000000..fac1e6ae
--- /dev/null
+++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Waiter.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2002-2010 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.samples.cafe;
+
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.springframework.jmx.export.annotation.ManagedOperation;
+import org.springframework.jmx.export.annotation.ManagedResource;
+
+/**
+ * A managed resource implementation to expose the total deliveries via the Control Bus
+ *
+ * @author Marius Bogoevici
+ * @author David Turanski
+ */
+@ManagedResource
+public class Waiter {
+
+ private AtomicInteger totalDeliveries = new AtomicInteger();
+
+ public Delivery prepareDelivery(List drinks) {
+ totalDeliveries.getAndIncrement();
+ return new Delivery(drinks);
+ }
+
+ @ManagedOperation
+ public int getTotalDeliveries() {
+ return this.totalDeliveries.get();
+ }
+
+}
diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/WaiterMonitor.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/WaiterMonitor.java
new file mode 100644
index 00000000..c71dfaad
--- /dev/null
+++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/WaiterMonitor.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2002-2011 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.samples.cafe;
+
+/**
+ * Send a groovy script to the control bus and return the result
+ * @author David Turanski
+ *
+ */
+public interface WaiterMonitor {
+ Object sendControlScript(String script);
+}
diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/demo/CafeDemoApp.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/demo/CafeDemoApp.java
new file mode 100644
index 00000000..adcab88b
--- /dev/null
+++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/demo/CafeDemoApp.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2002-2011 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.samples.cafe.demo;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.springframework.core.env.ConfigurableEnvironment;
+import org.springframework.util.StringUtils;
+
+/**
+ * An implementation of the Cafe Demo application to demonstrate Spring Integration's
+ * scripting capability. This process expects a command line argument corresponding to the scripting language
+ * to use.
+ *
+ * Provides the 'main' method for running the Cafe Demo application. When an
+ * order is placed, the Cafe will send that order to the "orders" channel.
+ * The relevant components are defined within the configuration file
+ * ("cafeDemo.xml").
+ *
+ * @author Mark Fisher
+ * @author Marius Bogoevici
+ * @author Oleg Zhurakousky
+ * @author David Turanski
+ */
+public class CafeDemoApp {
+
+
+ public static void main(String[] args) {
+
+ List languages = Arrays.asList(new String[]{"groovy","ruby","javascript","python"});
+ if (args.length != 1) {
+ usage();
+ }
+ String lang = args[0];
+
+ if (!StringUtils.hasText(lang)){
+ usage();
+ }
+
+ lang = lang.toLowerCase();
+ if (!languages.contains(lang)){
+ usage();
+ }
+
+ /*
+ * Create an application context and set the active profile to configure the
+ * corresponding scripting implementation
+ */
+
+ ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext();
+ ((ConfigurableEnvironment)ctx.getEnvironment()).setActiveProfiles(lang);
+ ctx.setConfigLocation("/META-INF/spring/integration/cafeDemo.xml");
+ ctx.refresh();
+ }
+
+
+ private static void usage() {
+ System.out.println("missing or invalid commannd line argument [groovy,ruby,javascript,python]");
+ System.exit(1);
+ }
+}
diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/demo/ControlBusMain.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/demo/ControlBusMain.java
new file mode 100644
index 00000000..95c7cec0
--- /dev/null
+++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/demo/ControlBusMain.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2002-2011 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.samples.cafe.demo;
+
+
+import org.apache.log4j.Logger;
+import org.springframework.context.support.AbstractApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+import org.springframework.integration.samples.cafe.WaiterMonitor;
+
+/**
+ * Sets up a remote connection to the CafeDemoApp to manage it using the Groovy Control Bus.
+ * The WaiterMonitor queries the total delivered orders every second.
+ * If totalDeliveries >= 3, stop the cafe inbound adapter.
+ *
+ * @author David Turanski
+ *
+ */
+public class ControlBusMain {
+ private static Logger logger = Logger.getLogger(ControlBusMain.class);
+
+ public static void main(String[] args) {
+
+ AbstractApplicationContext context =
+ new ClassPathXmlApplicationContext("/META-INF/spring/integration/cafeDemo-control-bus.xml");
+
+ WaiterMonitor waiterMonitor = (WaiterMonitor) context.getBean("waiterMonitor");
+
+ int totalDeliveries = 0;
+ while (totalDeliveries <= 3) {
+ try {
+ Thread.sleep(1000);
+ }
+ catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ totalDeliveries = (Integer)waiterMonitor.sendControlScript("waiter.totalDeliveries");
+
+ logger.info("Total cafe deliveries: " + totalDeliveries);
+
+ if (totalDeliveries > 3) {
+ logger.info("stopping orders...");
+ waiterMonitor.sendControlScript("cafe.stop()");
+ logger.info("orders stopped");
+ }
+ }
+ context.close();
+ System.exit(0);
+ }
+
+}
diff --git a/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-control-bus.xml b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-control-bus.xml
new file mode 100644
index 00000000..67764eb7
--- /dev/null
+++ b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-control-bus.xml
@@ -0,0 +1,30 @@
+
+
+
+
+ This is the application context for ControlBusMain. It configures a Gateway tied to an RMI outbound gateway to communicate
+ remotely with the CafeDemoApp.
+
+
+
+
+
+
+
+
+
+
diff --git a/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-groovy.xml b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-groovy.xml
new file mode 100644
index 00000000..84f26e1c
--- /dev/null
+++ b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-groovy.xml
@@ -0,0 +1,33 @@
+
+
+
+
+ payload.items
+
+
+
+ payload.iced ? "coldDrinks" : "hotDrinks"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-javascript.xml b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-javascript.xml
new file mode 100644
index 00000000..3c8245f4
--- /dev/null
+++ b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-javascript.xml
@@ -0,0 +1,32 @@
+
+
+
+
+ payload.items;
+
+
+
+ payload.iced ? "coldDrinks" : "hotDrinks";
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-python.xml b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-python.xml
new file mode 100644
index 00000000..dfaa92e4
--- /dev/null
+++ b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-python.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+ items=payload.items
+
+
+
+ 'coldDrinks' if payload.iced else 'hotDrinks'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-ruby.xml b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-ruby.xml
new file mode 100644
index 00000000..4c1922a7
--- /dev/null
+++ b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-ruby.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+ payload.items
+
+
+
+
+ payload.iced ? "coldDrinks": "hotDrinks"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo.xml b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo.xml
new file mode 100644
index 00000000..78ba9e2c
--- /dev/null
+++ b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo.xml
@@ -0,0 +1,83 @@
+
+
+
+
+ This is the application context for the scripted implementation of CafeDemoApp. The functionality is basically
+ identical to the original CafeDemoApp.
+
+ In order to demonstrate the Groovy control bus, the original cafe Gateway is replaced with an
+ inbound-channel-adapter (which supports the SmartLifeCycle interface).
+
+ The inbound-channel-adapter is backed by a Customer bean which provides the orders.
+
+ This configuration also uses Spring 3.1 environment profiles to inject a configuration specific to the
+ selected scripting language.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/applications/cafe-scripted/src/main/resources/log4j.xml b/applications/cafe-scripted/src/main/resources/log4j.xml
new file mode 100644
index 00000000..fd99f56c
--- /dev/null
+++ b/applications/cafe-scripted/src/main/resources/log4j.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/applications/cafe-scripted/src/test/java/org/springframework/integration/samples/cafe/ScriptTests.java b/applications/cafe-scripted/src/test/java/org/springframework/integration/samples/cafe/ScriptTests.java
new file mode 100644
index 00000000..e616d3b9
--- /dev/null
+++ b/applications/cafe-scripted/src/test/java/org/springframework/integration/samples/cafe/ScriptTests.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2002-2011 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.samples.cafe;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Test;
+import org.springframework.core.io.FileSystemResource;
+import org.springframework.integration.scripting.ScriptExecutor;
+import org.springframework.integration.scripting.jsr223.ScriptExecutorFactory;
+import org.springframework.scripting.support.ResourceScriptSource;
+/**
+ * @author David Turanski
+ *
+ */
+public class ScriptTests {
+ @Test
+ public void testRuby() {
+ ScriptExecutor executor = ScriptExecutorFactory.getScriptExecutor("ruby");
+
+ Order order = new Order(0);
+ order.addItem(DrinkType.LATTE, 2, false);
+ Map variables = new HashMap();
+ variables.put("payload", order.getItems().get(0));
+ variables.put("timeToPrepare", 1L);
+
+ Object obj = executor.executeScript(
+ new ResourceScriptSource(new FileSystemResource("scripts/ruby/barista.rb")), variables);
+ assertNotNull(obj);
+ assertTrue(obj instanceof Drink);
+
+ }
+
+ @Test
+ public void testPython() {
+ ScriptExecutor executor = ScriptExecutorFactory.getScriptExecutor("python");
+ Order order = new Order(0);
+ order.addItem(DrinkType.LATTE, 2, false);
+ Map variables = new HashMap();
+ variables.put("payload", order.getItems().get(0));
+ variables.put("timeToPrepare", "1");
+
+ Object obj = executor.executeScript(new ResourceScriptSource(
+ new FileSystemResource("scripts/python/barista.py")), variables);
+ assertNotNull(obj);
+ assertTrue(obj instanceof Drink);
+
+ }
+}