WINK-351 - Applying patch from Reto Bachmann-Gmur to provide Felix OSGi integration/extension

git-svn-id: https://svn.apache.org/repos/asf/incubator/wink/trunk@1328770 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/pom.xml b/pom.xml
index dc182fb..e9a4811 100644
--- a/pom.xml
+++ b/pom.xml
@@ -53,6 +53,7 @@
         <module>wink-guice-server</module>
         <module>wink-examples</module>
         <module>wink-assembly</module>
+        <module>wink-osgi</module>
     </modules>
     <scm>
         <connection>scm:svn:http://svn.apache.org/repos/asf/incubator/wink/trunk</connection>
diff --git a/wink-examples/ext/OSGi/pom.xml b/wink-examples/ext/OSGi/pom.xml
new file mode 100644
index 0000000..b8633d9
--- /dev/null
+++ b/wink-examples/ext/OSGi/pom.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+	<modelVersion>4.0.0</modelVersion>
+	<artifactId>Osgi</artifactId>
+	<packaging>bundle</packaging>
+	<name>Apache Wink Examples Ext :: OSGi</name>
+	<parent>
+		<groupId>org.apache.wink.example</groupId>
+		<artifactId>ext</artifactId>
+		<version>1.2.0-incubating-SNAPSHOT</version>
+	</parent>
+
+	<description>
+		Provides an OSGi bundle demonstrating the use of wink :: osgi
+	</description>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.felix</groupId>
+				<artifactId>maven-scr-plugin</artifactId>
+				<version>1.7.2</version>
+				<executions>
+					<execution>
+						<id>generate-scr-scrdescriptor</id>
+						<goals>
+							<goal>scr</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.felix</groupId>
+				<artifactId>maven-bundle-plugin</artifactId>
+				<extensions>true</extensions>
+				<configuration>
+				</configuration>
+			</plugin>
+			<plugin>
+		        <groupId>org.ops4j</groupId>
+		        <artifactId>maven-pax-plugin</artifactId>
+		        <version>1.5</version>
+		        <configuration>
+
+		          <provision>
+		            <param>--platform=felix</param>
+		            <param>--profiles=ds,log</param>
+		          </provision>
+		          <noDependencies>true</noDependencies>
+		          <!-- webconsole not needed, but handy -->
+                          <deployURLs>mvn:org.apache.felix/org.apache.felix.webconsole/3.1.8,mvn:org.apache.felix/org.apache.felix.http.jetty/2.2.0,mvn:org.apache.felix/org.apache.felix.http.whiteboard/2.2.0,mvn:org.apache.wink/wink-osgi/1.2.0-incubating-SNAPSHOT,mvn:commons-lang/commons-lang/2.5</deployURLs>
+		        </configuration>
+		      </plugin>
+		</plugins>
+	</build>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.apache.felix</groupId>
+			<artifactId>org.apache.felix.scr.annotations</artifactId>
+			<version>1.6.0</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.slf4j</groupId>
+			<artifactId>slf4j-api</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>javax.ws.rs</groupId>
+			<artifactId>jsr311-api</artifactId>
+		</dependency>
+	</dependencies>
+</project>
diff --git a/wink-examples/ext/OSGi/readme.txt b/wink-examples/ext/OSGi/readme.txt
new file mode 100644
index 0000000..95de9f9
--- /dev/null
+++ b/wink-examples/ext/OSGi/readme.txt
@@ -0,0 +1,20 @@
+OsgiHelloWorld Example
+===============================================================================
+
+Description 
+===============================================================================
+- This example demonstrate the most basic implementation of a an osgi bundle
+  providing a root resource as a service
+- It requires an OSGi container with the wink-osgi bundle installed and running
+- Running "mvn pax:run" will run the felix osgi container with the necessary dependencies
+- If the OSGi HTTP server is configured to run on port 8080 a greeting page
+  will be available at http://localhost:8080/demo/jaxrs 
+- Another one at http://localhost:8080/demo/jaxrs/greeting, this latter is 
+  rendered with a MessageBodyWriter for the returned greeting object.
+
+
+Build
+===============================================================================
+- see build instructions in examples/readme.txt file
+
+--- readme.txt EOF ---
diff --git a/wink-examples/ext/OSGi/src/main/java/org/apache/wink/example/osgi/Greeting.java b/wink-examples/ext/OSGi/src/main/java/org/apache/wink/example/osgi/Greeting.java
new file mode 100644
index 0000000..a363962
--- /dev/null
+++ b/wink-examples/ext/OSGi/src/main/java/org/apache/wink/example/osgi/Greeting.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * 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 org.apache.wink.example.osgi;
+
+
+public class Greeting {
+
+	private String verb;
+	private String name;
+
+	public Greeting(String verb, String name) {
+		this.verb = verb;
+		this.name = name;
+	}
+
+	
+	public String getVerb() {
+		return verb;
+	}
+
+	public String getName() {
+		return name;
+	}
+	
+	
+	
+}
diff --git a/wink-examples/ext/OSGi/src/main/java/org/apache/wink/example/osgi/GreetingWriter.java b/wink-examples/ext/OSGi/src/main/java/org/apache/wink/example/osgi/GreetingWriter.java
new file mode 100644
index 0000000..985aa11
--- /dev/null
+++ b/wink-examples/ext/OSGi/src/main/java/org/apache/wink/example/osgi/GreetingWriter.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * 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 org.apache.wink.example.osgi;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.ws.rs.ext.Provider;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Service;
+
+/**
+ * an example root resource, registered under different paths both as
+ * sling.ws.rs as well as javax.ws.rs component.
+ *
+ */
+@Component
+@Service(Object.class)
+@Property(name="javax.ws.rs", boolValue=true)
+@Produces("text/html")
+@Provider
+public class GreetingWriter implements MessageBodyWriter<Greeting>{
+	
+
+	public boolean isWriteable(Class<?> type, Type genericType,
+			Annotation[] annotations, MediaType mediaType) {
+		return Greeting.class.isAssignableFrom(type);
+	}
+
+	public long getSize(Greeting t, Class<?> type, Type genericType,
+			Annotation[] annotations, MediaType mediaType) {
+		return -1;
+	}
+
+	public void writeTo(Greeting t, Class<?> type, Type genericType,
+			Annotation[] annotations, MediaType mediaType,
+			MultivaluedMap<String, Object> httpHeaders,
+			OutputStream entityStream) throws IOException,
+			WebApplicationException {
+		PrintWriter out = new PrintWriter(entityStream);
+		out.println("<html>");
+		out.println("<body>");
+		out.println("<h1>");
+		out.print(t.getVerb());
+		out.print(", ");
+		out.print(t.getName() != null? t.getName() : "unknown");
+		out.print(".");
+		out.println("</h1>");
+		out.println("</body>");
+		out.println("</html>");
+		out.flush();
+	}
+
+}
diff --git a/wink-examples/ext/OSGi/src/main/java/org/apache/wink/example/osgi/SimpleRootResource.java b/wink-examples/ext/OSGi/src/main/java/org/apache/wink/example/osgi/SimpleRootResource.java
new file mode 100644
index 0000000..2b013b5
--- /dev/null
+++ b/wink-examples/ext/OSGi/src/main/java/org/apache/wink/example/osgi/SimpleRootResource.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * 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 org.apache.wink.example.osgi;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.QueryParam;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Service;
+
+/**
+ * an example jaxrs root resource.
+ *
+ */
+@Component
+@Service(Object.class)
+@Property(name="javax.ws.rs", boolValue=true)
+@Path("demo/jaxrs")
+public class SimpleRootResource {
+	
+	@GET
+	public String sayHello(@QueryParam("name") String name) {
+		return "Hello, "+name+".";
+	}
+	
+	@GET
+	@Path("greeting")
+	public Greeting getGreeting(@QueryParam("name") String name) {
+		return new Greeting("Hello", name);
+	}
+
+}
diff --git a/wink-examples/ext/pom.xml b/wink-examples/ext/pom.xml
index b79a91c..a1dc0d0 100644
--- a/wink-examples/ext/pom.xml
+++ b/wink-examples/ext/pom.xml
@@ -38,5 +38,6 @@
 		<module>Scope</module>
 		<module>Spring</module>		
 		<module>WebDAV</module>
+		<module>OSGi</module>
   </modules>
 </project>
diff --git a/wink-examples/readme.txt b/wink-examples/readme.txt
index 220701f..69a6f30 100644
--- a/wink-examples/readme.txt
+++ b/wink-examples/readme.txt
@@ -30,6 +30,7 @@
 		- Spring
 		- Scope
 		- WebDAV
+		- OSGi (maven build only)
 
 For more details regarding each example, please refer to the readme.txt file located
 in each example directory.
diff --git a/wink-osgi/pom.xml b/wink-osgi/pom.xml
new file mode 100644
index 0000000..61487e0
--- /dev/null
+++ b/wink-osgi/pom.xml
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <artifactId>wink</artifactId>
+        <groupId>org.apache.wink</groupId>
+        <version>1.2.0-incubating-SNAPSHOT</version>
+    </parent>
+    <groupId>org.apache.wink</groupId>
+    <artifactId>wink-osgi</artifactId>
+    <packaging>bundle</packaging>
+    <name>Apache Wink :: OSGi</name>
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-jar-plugin</artifactId>
+                <configuration>
+                    <archive>
+                        <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
+                    </archive>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <!-- <executions>
+                    <execution>
+                        <id>bundle-manifest</id>
+                        <phase>process-classes</phase>
+                        <goals>
+                            <goal>manifest</goal>
+                        </goals>
+                    </execution>
+                </executions> -->
+                <extensions>true</extensions>
+				<configuration>
+                    <instructions>
+                        <Export-Package>
+                          javax.ws.rs;version="1.1.1",javax.ws.rs.core;version="1.1.1",
+						  javax.ws.rs.ext;version="1.1.1", org.apache.wink.osgi
+                        </Export-Package>
+                        <Private-Package>
+                            org.apache.wink.osgi.internal
+                        </Private-Package>
+                        <Embed-Transitive>true</Embed-Transitive>
+                        <Embed-Dependency>
+                            wink-server, wink-common, activation, jsr311-api, 
+                            jaxb-api, geronimo-annotation_1.1_spec, stax-api
+                        </Embed-Dependency>
+                    </instructions>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-scr-plugin</artifactId>
+				<version>1.7.2</version>
+				<executions>
+					<execution>
+						<id>generate-scr-scrdescriptor</id>
+						<goals>
+							<goal>scr</goal>
+						</goals>
+					</execution>
+				</executions>
+            </plugin>
+        </plugins>
+    </build>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.scr.annotations</artifactId>
+            <scope>provided</scope>
+			<version>1.6.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+			<version>4.2.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+			<version>4.2.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+        	<groupId>org.apache.wink</groupId>
+    		<artifactId>wink-server</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-servlet_2.5_spec</artifactId>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/wink-osgi/src/main/java/org/apache/wink/osgi/JaxRsFilter.java b/wink-osgi/src/main/java/org/apache/wink/osgi/JaxRsFilter.java
new file mode 100644
index 0000000..c490b6d
--- /dev/null
+++ b/wink-osgi/src/main/java/org/apache/wink/osgi/JaxRsFilter.java
@@ -0,0 +1,87 @@
+/*
+ * 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 org.apache.wink.osgi;
+
+import java.io.IOException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Properties;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.wink.server.internal.DeploymentConfiguration;
+import org.apache.wink.server.internal.registry.ResourceRegistry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/** 
+ * This <code>Filter</code> handles request URIs for which
+ * there is a matching Root Resource Class registered with the  
+ * Apache Wink RequestProcessor and delegates the others to the chain.
+ */
+@Component(immediate = true, metatype = false)
+@Service(value = javax.servlet.Filter.class)
+@Properties({
+	@Property(name ="pattern", value=".*")
+})
+@SuppressWarnings("serial")
+public class JaxRsFilter implements Filter {
+
+	private final static Logger log = LoggerFactory.getLogger(JaxRsFilter.class);
+	
+	@Reference
+	private WinkRequestProcessor winkProvider;
+
+
+
+	private boolean accepts(HttpServletRequest request) {
+		DeploymentConfiguration deploymentConfiguration = winkProvider.getRequestProcessor().getConfiguration();
+		ResourceRegistry resourceRegistry = deploymentConfiguration.getResourceRegistry();
+		log.info("Checking acceptance of {}.", request.getRequestURI());
+		return resourceRegistry.getMatchingRootResources(request.getRequestURI()).size() > 0;
+	}
+
+	public void init(FilterConfig filterConfig) throws ServletException {
+		//no initialization needed
+	}
+
+	public void doFilter(ServletRequest request, ServletResponse response,
+			FilterChain chain) throws IOException, ServletException {
+		if (((request instanceof HttpServletRequest) && accepts((HttpServletRequest)request))) {
+			log.debug("processing request");
+			winkProvider.handleRequest((HttpServletRequest)request, (HttpServletResponse)response);
+		} else {
+			chain.doFilter(request, response);
+		}
+		
+	}
+
+	public void destroy() {
+		//not
+	}
+
+
+}
diff --git a/wink-osgi/src/main/java/org/apache/wink/osgi/WinkRequestProcessor.java b/wink-osgi/src/main/java/org/apache/wink/osgi/WinkRequestProcessor.java
new file mode 100644
index 0000000..700865f
--- /dev/null
+++ b/wink-osgi/src/main/java/org/apache/wink/osgi/WinkRequestProcessor.java
@@ -0,0 +1,168 @@
+/*
+ * 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 org.apache.wink.osgi;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.ext.RuntimeDelegate;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.ReferencePolicy;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.wink.common.internal.runtime.RuntimeDelegateImpl;
+import org.apache.wink.osgi.internal.DummyRuntimeDelegate;
+import org.apache.wink.osgi.internal.ThreadRootResourceDeploymentConfiguration;
+import org.apache.wink.server.internal.RequestProcessor;
+import org.apache.wink.server.utils.RegistrationUtils.InnerApplication;
+import org.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * 
+ * This component listens to registrations of services of type <code>java.lang.Object</code>
+ * with the property <code>javax.ws.rs</code> set to true and registers them with the 
+ * Wink RequestProcessor. Root resources and providers that are not exposed as such a service
+ * can be registered by invoking the bindComponent method.
+ *
+ */
+@Component
+@Reference(name="component", referenceInterface=Object.class, target="(javax.ws.rs=true)", 
+		cardinality=ReferenceCardinality.OPTIONAL_MULTIPLE, policy=ReferencePolicy.DYNAMIC)
+@Service(WinkRequestProcessor.class)
+public class WinkRequestProcessor {
+
+	private final static Logger log = LoggerFactory.getLogger(WinkRequestProcessor.class);
+	private RequestProcessor requestProcessor;
+	private Set<Object> components = new HashSet<Object>();	
+	private boolean requestProcessorOutdated = false;
+	
+	/**
+     * Dispatches the request and fills the response (even with an error
+     * message.
+     * 
+     * @param request AS or mock request
+     * @param response AS or mock response
+     */
+	public void handleRequest(HttpServletRequest request, HttpServletResponse response) 
+			throws ServletException {
+		ensureNotOutdated();
+		requestProcessor.handleRequest(request, response);
+	}
+	
+	/**
+     * Dispatches the request and fills the response (even with an error
+     * message using the spcified root resource instance. Note that any
+     * @Path annotation on the root resource class as well as methods with
+     * auch an annotation are ignored.
+     * 
+     * @param request AS or mock request
+     * @param response AS or mock response
+     * @param resource the root resource instance to be used
+     */
+	public void handleRequest(HttpServletRequest request, HttpServletResponse response, 
+			Object resource) 
+			throws ServletException {
+		ensureNotOutdated();
+		ThreadRootResourceDeploymentConfiguration.threadLocalRootResource.set(resource);
+		requestProcessor.handleRequest(request, response);
+		ThreadRootResourceDeploymentConfiguration.threadLocalRootResource.remove();
+	}
+
+	protected void activate(ComponentContext context) {
+		// hint from http://www.amdatu.org/confluence/display/Amdatu/OSGiification
+		// dummy RuntimeDelegate
+		RuntimeDelegate.setInstance(new DummyRuntimeDelegate());
+		RuntimeDelegate.setInstance(new RuntimeDelegateImpl());	
+		init();
+	}
+	
+	
+	protected void deactivate(ComponentContext context) {
+		components.clear();
+		requestProcessor = null;
+		requestProcessorOutdated = false;
+	}
+	
+	/**
+	 * @param component
+	 *            The new JAX-RS component (root resource or provider) to bind.
+	 */
+	public void bindComponent(Object component) {
+		components.add(component);
+		if (requestProcessor != null) {
+			registerComponent(component);
+		}
+	}
+	
+	/**
+	 * @param component
+	 *            The new JAX-RS component (root resource or provider) to bind.
+	 */
+	public void unbindComponent(Object component) {
+		components.remove(component);
+		//since it seems not possible to remove from RequestProcessor
+		//we need to create a new one, we defer this to prevent
+		//creation of many new RequestProcessors when unregistering many resources
+		requestProcessorOutdated = true;
+	}
+	
+	/**
+	 * Used in JaxRsFilter to check if the path can be handled by wink
+	 */
+	RequestProcessor getRequestProcessor() {
+		ensureNotOutdated();
+		return requestProcessor;
+	}
+	
+	private void ensureNotOutdated() {
+		if (requestProcessorOutdated) {
+			requestProcessorOutdated = false;
+			synchronized(this) {
+				init();
+			}
+		}
+	}
+	
+	private void init() {
+		ThreadRootResourceDeploymentConfiguration configuration = new ThreadRootResourceDeploymentConfiguration();
+		configuration.init();
+		requestProcessor = new RequestProcessor(configuration);
+		for (Object component : components) {
+			registerComponent(component);
+		}
+	}
+
+	private void registerComponent(Object component) {
+		ensureNotOutdated();
+		Application application = new InnerApplication(component);
+		requestProcessor.getConfiguration().addApplication(application, false);
+		components.add(component);
+		log.info("registered component {}", component);
+	}
+
+	
+
+}
diff --git a/wink-osgi/src/main/java/org/apache/wink/osgi/internal/DummyRuntimeDelegate.java b/wink-osgi/src/main/java/org/apache/wink/osgi/internal/DummyRuntimeDelegate.java
new file mode 100644
index 0000000..006a62a
--- /dev/null
+++ b/wink-osgi/src/main/java/org/apache/wink/osgi/internal/DummyRuntimeDelegate.java
@@ -0,0 +1,52 @@
+/*
+ * 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 org.apache.wink.osgi.internal;
+
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.Response.ResponseBuilder;
+import javax.ws.rs.core.Variant.VariantListBuilder;
+import javax.ws.rs.ext.RuntimeDelegate;
+
+/**
+ * A dummy RntimeDelegate used during initialization.
+ *
+ */
+public class DummyRuntimeDelegate extends
+		RuntimeDelegate {
+	public <T> T createEndpoint(Application arg0, Class<T> arg1)
+			throws IllegalArgumentException,
+			UnsupportedOperationException {
+		return null;
+	}
+
+	public <T> HeaderDelegate<T> createHeaderDelegate(Class<T> arg0) {
+		return null;
+	}
+
+	public ResponseBuilder createResponseBuilder() {
+		return null;
+	}
+
+	public UriBuilder createUriBuilder() {
+		return null;
+	}
+
+	public VariantListBuilder createVariantListBuilder() {
+		return null;
+	}
+}
\ No newline at end of file
diff --git a/wink-osgi/src/main/java/org/apache/wink/osgi/internal/ThreadRootResourceDeploymentConfiguration.java b/wink-osgi/src/main/java/org/apache/wink/osgi/internal/ThreadRootResourceDeploymentConfiguration.java
new file mode 100644
index 0000000..a04196d
--- /dev/null
+++ b/wink-osgi/src/main/java/org/apache/wink/osgi/internal/ThreadRootResourceDeploymentConfiguration.java
@@ -0,0 +1,194 @@
+/*
+ * 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 org.apache.wink.osgi.internal;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+import javax.ws.rs.WebApplicationException;
+
+import org.apache.wink.common.RuntimeContext;
+import org.apache.wink.common.internal.lifecycle.LifecycleManagersRegistry;
+import org.apache.wink.common.internal.lifecycle.ObjectFactory;
+import org.apache.wink.common.internal.registry.metadata.ClassMetadata;
+import org.apache.wink.common.internal.registry.metadata.ResourceMetadataCollector;
+import org.apache.wink.common.internal.uritemplate.UriTemplateMatcher;
+import org.apache.wink.common.internal.uritemplate.UriTemplateProcessor;
+import org.apache.wink.server.internal.DeploymentConfiguration;
+import org.apache.wink.server.internal.registry.MethodRecord;
+import org.apache.wink.server.internal.registry.ResourceInstance;
+import org.apache.wink.server.internal.registry.ResourceRecord;
+import org.apache.wink.server.internal.registry.ResourceRegistry;
+import org.apache.wink.server.internal.registry.SubResourceInstance;
+
+
+/**
+ * A deployment configuration that returns a thread local root resource instance if set.
+ */
+public class ThreadRootResourceDeploymentConfiguration extends DeploymentConfiguration {
+
+	public static ThreadLocal<Object> threadLocalRootResource = new ThreadLocal<Object>();
+	
+	/** 
+	 * @return the thread local root-resource as ResourceInstance or null
+	 */
+	private ResourceInstance getThreadLocalResourceInstance() {
+		final Object rootResource = threadLocalRootResource.get();
+		if (rootResource == null) {
+			return null;
+		}
+		final ObjectFactory<?> objectFactory = new ObjectFactory<Object>() {
+            public Object getInstance(RuntimeContext context) {
+                return rootResource;
+            }
+
+            public Class<Object> getInstanceClass() {
+                return Object.class;
+            }
+
+            public void releaseInstance(Object instance, RuntimeContext context) {
+                /* do nothing */
+            }
+
+            public void releaseAll(RuntimeContext context) {
+                /* do nothing */
+            }
+        };
+
+		final ClassMetadata metadata = ResourceMetadataCollector.collectMetadata(rootResource.getClass());
+		//for some reason we need a UriTemplateMatcher with a successful last match 
+		final UriTemplateProcessor processor = new UriTemplateProcessor() {
+
+			@Override
+			public void compile(String arg0) {
+				pattern = Pattern.compile(".*");
+			}
+			
+		};
+		processor.compile("{.*}");
+		final UriTemplateMatcher uriTemplateMatcher = processor.matcher();
+		uriTemplateMatcher.match("foo");
+		return new ResourceInstance(rootResource, 
+				new ResourceRecord(metadata, objectFactory, processor), uriTemplateMatcher);
+	}
+	
+
+	
+	
+	public class FixedResourceRegistry extends ResourceRegistry {
+
+		private ResourceRegistry wrapped;
+		//private LifecycleManagersRegistry lifecycleManagersRegistry = new LifecycleManagersRegistry();
+
+		public FixedResourceRegistry(ResourceRegistry wrapped) {
+			super(new LifecycleManagersRegistry(), null);
+			this.wrapped = wrapped;
+		}
+
+		@Override
+		public void addResource(Class<?> arg0, double arg1) {
+			wrapped.addResource(arg0, arg1);
+		}
+
+		@Override
+		public void addResource(Class<?> clazz) {
+			wrapped.addResource(clazz);
+		}
+
+		@Override
+		public void addResource(Object arg0, double arg1) {
+			wrapped.addResource(arg0, arg1);
+		}
+
+		@Override
+		public void addResource(Object instance) {
+			wrapped.addResource(instance);
+		}
+
+		@Override
+		public MethodRecord findMethod(ResourceInstance arg0,
+				RuntimeContext arg1) throws WebApplicationException {
+			return wrapped.findMethod(arg0, arg1);
+		}
+
+		@Override
+		public SubResourceInstance findSubResourceMethod(String pattern,
+				List<SubResourceInstance> subResourceRecords,
+				ResourceInstance resource, RuntimeContext context)
+				throws WebApplicationException {
+
+			return wrapped.findSubResourceMethod(pattern, subResourceRecords, resource,
+					context);
+		}
+
+		@Override
+		public List<ResourceInstance> getMatchingRootResources(String arg0,
+				boolean arg1) {
+			ResourceInstance threadLocaleInstance = getThreadLocalResourceInstance();
+			if (threadLocaleInstance == null) {
+				return wrapped.getMatchingRootResources(arg0, arg1);
+			} else {
+				return Collections.singletonList(threadLocaleInstance);
+			}
+		}
+
+		@Override
+		public List<ResourceInstance> getMatchingRootResources(String uri) {
+			return wrapped.getMatchingRootResources(uri);
+		}
+
+		@Override
+		public Set<String> getOptions(ResourceInstance arg0) {
+			return wrapped.getOptions(arg0);
+		}
+
+		@Override
+		public ResourceRecord getRecord(Class<?> clazz) {
+			return wrapped.getRecord(clazz);
+		}
+
+		@Override
+		public ResourceRecord getRecord(Object instance, boolean isRootResource) {
+			return wrapped.getRecord(instance, isRootResource);
+		}
+
+		@Override
+		public ResourceRecord getRecord(Object instance) {
+			return wrapped.getRecord(instance);
+		}
+
+		@Override
+		public List<ResourceRecord> getRecords() {
+			return wrapped.getRecords();
+		}
+
+		@Override
+		public void removeAllResources() {
+			wrapped.removeAllResources();
+		}
+
+	}
+
+	@Override
+	public ResourceRegistry getResourceRegistry() {
+		return new FixedResourceRegistry(super.getResourceRegistry());
+	}
+	
+
+}