diff --git a/bundles/demo/pom.xml b/bundles/demo/pom.xml
new file mode 100644
index 000000000..1afa730a8
--- /dev/null
+++ b/bundles/demo/pom.xml
@@ -0,0 +1,84 @@
+
+
+ 4.0.0
+ org.apache.struts.osgi
+ struts2-demo-bundle
+ 1.0.0-SNAPSHOT
+ bundle
+ Struts 2 OSGi Demo Bundle
+
+
+
+ org.apache.struts
+ struts2-core
+ 2.1.7-SNAPSHOT
+
+
+
+ velocity
+ velocity
+ 1.5
+
+
+
+ velocity-tools
+ velocity-tools
+ 1.3
+
+
+
+ commons-digester
+ commons-digester
+ 1.8
+
+
+
+ org.apache.struts
+ struts2-convention-plugin
+ 2.1.7-SNAPSHOT
+
+
+
+ org.apache.struts
+ struts2-osgi-plugin
+ 1.0.0-SNAPSHOT
+
+
+
+ org.apache.struts
+ struts2-spring-plugin
+ 2.1.7-SNAPSHOT
+
+
+
+
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+ 2.0.0
+
+
+ META-INF
+ *,com.opensymphony.xwork2
+ *;create-asynchronously:=false
+ true
+
+
+
+
+
+
+
+ maven-compiler-plugin
+
+ 1.5
+ 1.5
+
+
+
+
+
+
diff --git a/bundles/demo/src/main/java/actions/osgi/BundlesAction.java b/bundles/demo/src/main/java/actions/osgi/BundlesAction.java
new file mode 100644
index 000000000..74feff244
--- /dev/null
+++ b/bundles/demo/src/main/java/actions/osgi/BundlesAction.java
@@ -0,0 +1,57 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 actions.osgi;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Bundle;
+import org.apache.struts2.osgi.interceptor.BundleContextAware;
+import org.apache.struts2.osgi.interceptor.ServiceAware;
+import org.apache.struts2.convention.annotation.ResultPath;
+import org.springframework.context.ApplicationContext;
+
+import java.util.List;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+/**
+ * This action shows how to interact with the OSGi container, using the OSGi interceptor
+ */
+@ResultPath("/content")
+public class BundlesAction extends ActionSupport implements BundleContextAware, ServiceAware {
+ private BundleContext bundleContext;
+ private List services;
+
+ public void setServices(List services) {
+ this.services = services;
+ }
+
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+ public int getApplicationContextsCount() {
+ return services.size();
+ }
+
+ public Bundle[] getBundles() {
+ return bundleContext.getBundles();
+ }
+}
diff --git a/bundles/demo/src/main/java/actions/osgi/HelloWorldAction.java b/bundles/demo/src/main/java/actions/osgi/HelloWorldAction.java
new file mode 100644
index 000000000..b27ab0f9a
--- /dev/null
+++ b/bundles/demo/src/main/java/actions/osgi/HelloWorldAction.java
@@ -0,0 +1,40 @@
+package actions.osgi;
+
+import com.opensymphony.xwork2.ActionSupport;
+import org.apache.struts2.convention.annotation.Action;
+import org.apache.struts2.convention.annotation.ResultPath;
+import org.apache.struts2.osgi.interceptor.BundleContextAware;
+import org.apache.struts2.osgi.interceptor.ServiceAware;
+import org.osgi.framework.BundleContext;
+import org.springframework.context.ApplicationContext;
+
+import java.util.List;
+
+@ResultPath("/content")
+public class HelloWorldAction extends ActionSupport {
+ private Message message;
+
+ @Action("hello-convention")
+ public String execute() {
+ return SUCCESS;
+ }
+
+ public Message getMessage() {
+ return message;
+ }
+
+ public void setMessage(Message message) {
+ this.message = message;
+ }
+
+ public String getSimpleMessage() {
+ return "Hello!!!";
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder("{message:");
+ sb.append(message != null ? message.getText() : "null");
+ sb.append("}");
+ return sb.toString();
+ }
+}
\ No newline at end of file
diff --git a/bundles/demo/src/main/java/actions/osgi/Message.java b/bundles/demo/src/main/java/actions/osgi/Message.java
new file mode 100644
index 000000000..eb31f2948
--- /dev/null
+++ b/bundles/demo/src/main/java/actions/osgi/Message.java
@@ -0,0 +1,37 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 actions.osgi;
+
+public class Message {
+ private String text;
+
+ public Message(String text) {
+ this.text = text;
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ public void setText(String text) {
+ this.text = text;
+ }
+}
diff --git a/bundles/demo/src/main/resources/META-INF/spring/applicationContext.xml b/bundles/demo/src/main/resources/META-INF/spring/applicationContext.xml
new file mode 100644
index 000000000..bc3cc3145
--- /dev/null
+++ b/bundles/demo/src/main/resources/META-INF/spring/applicationContext.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bundles/demo/src/main/resources/content/osgi/bundles.ftl b/bundles/demo/src/main/resources/content/osgi/bundles.ftl
new file mode 100644
index 000000000..e9decadf0
--- /dev/null
+++ b/bundles/demo/src/main/resources/content/osgi/bundles.ftl
@@ -0,0 +1,18 @@
+
+
+ OSGi integration
+
+
+ This action was mapped by Convention, and shows how to get access to the BundleContext
+ and registered services
+
+ Spring Application Contexts: ${applicationContextsCount!}
+
+ Bundles List:
+
+ <#list bundles as bundle>
+
${bundle.symbolicName!}
+ #list>
+
+
+
\ No newline at end of file
diff --git a/bundles/demo/src/main/resources/content/osgi/hello-convention.ftl b/bundles/demo/src/main/resources/content/osgi/hello-convention.ftl
new file mode 100644
index 000000000..e47d160ce
--- /dev/null
+++ b/bundles/demo/src/main/resources/content/osgi/hello-convention.ftl
@@ -0,0 +1,10 @@
+
+
+ Action mapped by the Convention plugin
+
+
+ This is an action mapped by the Convention plugin, using a FreeMarker result.
+
+ Message from Action: ${simpleMessage}
+
+
\ No newline at end of file
diff --git a/bundles/demo/src/main/resources/content/osgi/hello.ftl b/bundles/demo/src/main/resources/content/osgi/hello.ftl
new file mode 100644
index 000000000..fec234335
--- /dev/null
+++ b/bundles/demo/src/main/resources/content/osgi/hello.ftl
@@ -0,0 +1,10 @@
+
+
+ Action mapped by the XML configurationn
+
+
+ This is an action mapped by XML configuration, using a FreeMarker result.
+
+ Message from Action: ${message.text}
+
+
\ No newline at end of file
diff --git a/bundles/demo/src/main/resources/content/osgi/hello.vm b/bundles/demo/src/main/resources/content/osgi/hello.vm
new file mode 100644
index 000000000..40c1ff029
--- /dev/null
+++ b/bundles/demo/src/main/resources/content/osgi/hello.vm
@@ -0,0 +1,10 @@
+
+
+ Action mapped by the XML configurationn
+
+
+ This is an action mapped by XML configuration, using a Velocity result.
+
+ Message from Action: $message.text
+
+
\ No newline at end of file
diff --git a/bundles/demo/src/main/resources/content/osgi/home.ftl b/bundles/demo/src/main/resources/content/osgi/home.ftl
new file mode 100644
index 000000000..089c89e85
--- /dev/null
+++ b/bundles/demo/src/main/resources/content/osgi/home.ftl
@@ -0,0 +1,14 @@
+
+
+ OSGi Demo Bundle
+
+
+ This demo contains actions that will be packaged into an OSGi bundle and loaded by the Struts 2 OSGi plugin.
+
+
+
<@s.a namespace="/osgi" action="hello-convention">Action mapped by the Convention plugin, with FreeMarker result@s.a>
+
<@s.a namespace="/osgi" action="hello-freemarker">Action mapped by XML, with FreeMarker result@s.a>
+
<@s.a namespace="/osgi" action="hello-velocity">Action mapped by XML, with Velocity result@s.a>
+
+
+
\ No newline at end of file
diff --git a/bundles/demo/src/main/resources/struts.xml b/bundles/demo/src/main/resources/struts.xml
new file mode 100644
index 000000000..3f72ce861
--- /dev/null
+++ b/bundles/demo/src/main/resources/struts.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+ /content/osgi/hello.vm
+
+
+ /content/osgi/hello.ftl
+
+
+
+ /content/osgi/home.ftl
+
+
+
\ No newline at end of file