[Osgi-messages] SF.net SVN: osgi:[255] papoose-cmpn/trunk
Status: Beta
Brought to you by:
maguro
|
From: <osg...@li...> - 2010-02-24 23:41:54
|
Revision: 255
http://osgi.svn.sourceforge.net/osgi/?rev=255&view=rev
Author: maguro
Date: 2010-02-24 23:41:47 +0000 (Wed, 24 Feb 2010)
Log Message:
-----------
More HTTP service work
Modified Paths:
--------------
papoose-cmpn/trunk/http/pom.xml
papoose-cmpn/trunk/http/src/main/java/org/papoose/http/HttpServiceImpl.java
papoose-cmpn/trunk/http/src/main/java/org/papoose/http/ServletDispatcher.java
papoose-cmpn/trunk/http/src/main/java/org/papoose/http/ServletRegistration.java
papoose-cmpn/trunk/pom.xml
Added Paths:
-----------
papoose-cmpn/trunk/http/src/test/java/org/
papoose-cmpn/trunk/http/src/test/java/org/papoose/
papoose-cmpn/trunk/http/src/test/java/org/papoose/http/
papoose-cmpn/trunk/http/src/test/java/org/papoose/http/ServletDispatcherTest.java
Modified: papoose-cmpn/trunk/http/pom.xml
===================================================================
--- papoose-cmpn/trunk/http/pom.xml 2010-02-24 23:38:32 UTC (rev 254)
+++ papoose-cmpn/trunk/http/pom.xml 2010-02-24 23:41:47 UTC (rev 255)
@@ -41,6 +41,12 @@
</dependency>
<dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.compendium</artifactId>
</dependency>
Modified: papoose-cmpn/trunk/http/src/main/java/org/papoose/http/HttpServiceImpl.java
===================================================================
--- papoose-cmpn/trunk/http/src/main/java/org/papoose/http/HttpServiceImpl.java 2010-02-24 23:38:32 UTC (rev 254)
+++ papoose-cmpn/trunk/http/src/main/java/org/papoose/http/HttpServiceImpl.java 2010-02-24 23:41:47 UTC (rev 255)
@@ -63,6 +63,8 @@
*/
public void registerServlet(String alias, Servlet servlet, Dictionary initParams, HttpContext httpContext) throws ServletException, NamespaceException
{
+ LOGGER.entering(CLASS_NAME, "registerServlet", new Object[]{ alias, servlet, initParams, httpContext });
+
ServletRegistration registration;
ServletContextImpl servletContext;
synchronized (lock)
@@ -97,9 +99,13 @@
if (servletContext.getReferenceCount() == 0) contexts.remove(registration.getContext());
}
+ LOGGER.throwing(CLASS_NAME, "registerServlet", t);
+
if (t instanceof ServletException) throw (ServletException) t;
throw (RuntimeException) t;
}
+
+ LOGGER.exiting(CLASS_NAME, "registerServlet");
}
@@ -108,6 +114,8 @@
*/
public void registerResources(String alias, String name, HttpContext httpContext) throws NamespaceException
{
+ LOGGER.entering(CLASS_NAME, "registerResources", new Object[]{ alias, name, httpContext });
+
try
{
registerServlet(alias, new ServletWrapper(alias, name, httpContext), EMPTY_PARAMS, httpContext);
@@ -116,6 +124,8 @@
{
LOGGER.log(Level.SEVERE, "Error registering resource wrapper servlet", se);
}
+
+ LOGGER.exiting(CLASS_NAME, "registerResources");
}
/**
@@ -123,6 +133,8 @@
*/
public void unregister(String alias)
{
+ LOGGER.entering(CLASS_NAME, "unregister", alias);
+
ServletRegistration registration;
synchronized (lock)
{
@@ -146,6 +158,8 @@
{
LOGGER.log(Level.WARNING, "Error destroying servlet", t);
}
+
+ LOGGER.exiting(CLASS_NAME, "unregister");
}
/**
@@ -153,7 +167,9 @@
*/
public HttpContext createDefaultHttpContext()
{
- return new HttpContext()
+ LOGGER.entering(CLASS_NAME, "createDefaultHttpContext");
+
+ HttpContext defaultContext = new HttpContext()
{
public boolean handleSecurity(HttpServletRequest request, HttpServletResponse response) throws IOException
{
@@ -172,5 +188,9 @@
return null;
}
};
+
+ LOGGER.exiting(CLASS_NAME, "createDefaultHttpContext", defaultContext);
+
+ return defaultContext;
}
}
Modified: papoose-cmpn/trunk/http/src/main/java/org/papoose/http/ServletDispatcher.java
===================================================================
--- papoose-cmpn/trunk/http/src/main/java/org/papoose/http/ServletDispatcher.java 2010-02-24 23:38:32 UTC (rev 254)
+++ papoose-cmpn/trunk/http/src/main/java/org/papoose/http/ServletDispatcher.java 2010-02-24 23:41:47 UTC (rev 255)
@@ -21,7 +21,9 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -41,40 +43,76 @@
{
String path = req.getPathInfo();
- for (ServletRegistration registration : registrations)
+ ServletRegistration r = null;
+
+ done:
+ while (true)
{
- if (path.startsWith(registration.getAlias()))
+ for (ServletRegistration registration : registrations)
{
- if (registration.getContext().handleSecurity(req, resp))
+ if (path.equals(registration.getAlias()))
{
- try
+ if (registration.getContext().handleSecurity(req, resp))
{
- registration.getServlet().service(req, resp);
+ r = registration;
+ break done;
}
- catch (ServletException e)
+ }
+ }
+
+ int index = path.lastIndexOf('/');
+ if (index == 0) break;
+ path = path.substring(0, index);
+ }
+
+ if (r == null)
+ {
+ for (ServletRegistration registration : registrations)
+ {
+ if ("/".equals(registration.getAlias()))
+ {
+ if (registration.getContext().handleSecurity(req, resp))
{
- throw e;
+ r = registration;
+ break;
}
- catch (IOException e)
- {
- throw e;
- }
- catch(Throwable t)
- {
- LOGGER.log(Level.WARNING, "Problems calling ", t);
- }
}
}
}
+
+ if (r != null)
+ {
+ try
+ {
+ r.getServlet().service(req, resp);
+ }
+ catch (ServletException e)
+ {
+ throw e;
+ }
+ catch (IOException e)
+ {
+ throw e;
+ }
+ catch (Throwable t)
+ {
+ LOGGER.log(Level.WARNING, "Problems calling ", t);
+ resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ }
+ }
+ else
+ {
+ resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
+ }
}
void register(ServletRegistration registration)
{
-
+ registrations.add(registration);
}
void unregister(ServletRegistration registration)
{
-
+ registrations.remove(registration);
}
}
Modified: papoose-cmpn/trunk/http/src/main/java/org/papoose/http/ServletRegistration.java
===================================================================
--- papoose-cmpn/trunk/http/src/main/java/org/papoose/http/ServletRegistration.java 2010-02-24 23:38:32 UTC (rev 254)
+++ papoose-cmpn/trunk/http/src/main/java/org/papoose/http/ServletRegistration.java 2010-02-24 23:41:47 UTC (rev 255)
@@ -17,8 +17,6 @@
package org.papoose.http;
import javax.servlet.Servlet;
-import java.util.Dictionary;
-import java.util.logging.Logger;
import org.osgi.service.http.HttpContext;
@@ -28,8 +26,6 @@
*/
class ServletRegistration
{
- private final static String CLASS_NAME = ServletRegistration.class.getName();
- private final static Logger LOGGER = Logger.getLogger(CLASS_NAME);
private final String alias;
private final Servlet servlet;
private final HttpContext context;
@@ -55,4 +51,21 @@
{
return servlet;
}
+
+ @Override
+ public boolean equals(Object o)
+ {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ServletRegistration that = (ServletRegistration) o;
+
+ return alias.equals(that.alias);
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return alias.hashCode();
+ }
}
Added: papoose-cmpn/trunk/http/src/test/java/org/papoose/http/ServletDispatcherTest.java
===================================================================
--- papoose-cmpn/trunk/http/src/test/java/org/papoose/http/ServletDispatcherTest.java (rev 0)
+++ papoose-cmpn/trunk/http/src/test/java/org/papoose/http/ServletDispatcherTest.java 2010-02-24 23:41:47 UTC (rev 255)
@@ -0,0 +1,222 @@
+/**
+ *
+ * Copyright 2010 (C) 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.papoose.http;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import static junit.framework.Assert.fail;
+import org.junit.Test;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.only;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.osgi.service.http.HttpContext;
+
+
+/**
+ * @version $Revision: $ $Date: $
+ */
+public class ServletDispatcherTest
+{
+ @Test
+ public void testNoRegistrants() throws Exception
+ {
+ HttpServletRequest request = mock(HttpServletRequest.class);
+ HttpServletResponse response = mock(HttpServletResponse.class);
+ ServletDispatcher dispatcher = new ServletDispatcher();
+
+ when(request.getPathInfo()).thenReturn("/a/b/c");
+
+ dispatcher.service(request, response);
+
+ verify(response, only()).setStatus(HttpServletResponse.SC_NOT_FOUND);
+ }
+
+ @Test
+ public void testOneRegistrant() throws Exception
+ {
+ HttpServletRequest request = mock(HttpServletRequest.class);
+ HttpServletResponse response = mock(HttpServletResponse.class);
+ ServletDispatcher dispatcher = new ServletDispatcher();
+ Servlet servlet = mock(Servlet.class);
+ HttpContext context = mock(HttpContext.class);
+ ServletRegistration registration = new ServletRegistration("/a/b", servlet, context);
+
+ doAnswer(new Answer()
+ {
+ public Object answer(InvocationOnMock invocation)
+ {
+ HttpServletResponse resp = (HttpServletResponse) invocation.getArguments()[1];
+ resp.setStatus(HttpServletResponse.SC_OK);
+ return null;
+ }
+ }).when(servlet).service(request, response);
+ when(context.handleSecurity(request, response)).thenReturn(true);
+ when(request.getPathInfo()).thenReturn("/a/b/c");
+
+ dispatcher.register(registration);
+ dispatcher.service(request, response);
+
+ verify(context, only()).handleSecurity(request, response);
+ verify(response, only()).setStatus(HttpServletResponse.SC_OK);
+ }
+
+ @Test
+ public void testSimplePathRegistrant() throws Exception
+ {
+ HttpServletRequest request = mock(HttpServletRequest.class);
+ HttpServletResponse response = mock(HttpServletResponse.class);
+ ServletDispatcher dispatcher = new ServletDispatcher();
+ Servlet servlet = mock(Servlet.class);
+ HttpContext context = mock(HttpContext.class);
+ ServletRegistration registration = new ServletRegistration("/", servlet, context);
+
+ doAnswer(new Answer()
+ {
+ public Object answer(InvocationOnMock invocation)
+ {
+ HttpServletResponse resp = (HttpServletResponse) invocation.getArguments()[1];
+ resp.setStatus(HttpServletResponse.SC_OK);
+ return null;
+ }
+ }).when(servlet).service(request, response);
+ when(context.handleSecurity(request, response)).thenReturn(true);
+ when(request.getPathInfo()).thenReturn("/a/b/c");
+
+ dispatcher.register(registration);
+ dispatcher.service(request, response);
+
+ verify(context, only()).handleSecurity(request, response);
+ verify(response, only()).setStatus(HttpServletResponse.SC_OK);
+ }
+
+ @Test
+ public void testNaughtyRegistrant() throws Exception
+ {
+ HttpServletRequest request = mock(HttpServletRequest.class);
+ HttpServletResponse response = mock(HttpServletResponse.class);
+ ServletDispatcher dispatcher = new ServletDispatcher();
+ Servlet servlet = mock(Servlet.class);
+ HttpContext context = mock(HttpContext.class);
+ ServletRegistration registration = new ServletRegistration("/a/b", servlet, context);
+
+ doThrow(new NullPointerException()).when(servlet).service(request, response);
+ when(context.handleSecurity(request, response)).thenReturn(true);
+ when(request.getPathInfo()).thenReturn("/a/b/c");
+
+ dispatcher.register(registration);
+ dispatcher.service(request, response);
+
+ verify(context, only()).handleSecurity(request, response);
+ verify(response, only()).setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ }
+
+ @Test
+ public void testStumblingRegistrant() throws Exception
+ {
+ HttpServletRequest request = mock(HttpServletRequest.class);
+ HttpServletResponse response = mock(HttpServletResponse.class);
+ ServletDispatcher dispatcher = new ServletDispatcher();
+ Servlet servlet = mock(Servlet.class);
+ HttpContext context = mock(HttpContext.class);
+ ServletRegistration registration = new ServletRegistration("/a/b", servlet, context);
+
+ doThrow(new ServletException()).when(servlet).service(request, response);
+ when(context.handleSecurity(request, response)).thenReturn(true);
+ when(request.getPathInfo()).thenReturn("/a/b/c");
+
+ dispatcher.register(registration);
+ try
+ {
+ dispatcher.service(request, response);
+ fail("Should have passed on the exception");
+ }
+ catch (ServletException ignore)
+ {
+ }
+
+ verify(context, only()).handleSecurity(request, response);
+ verify(response, never()).setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ }
+
+ @Test
+ public void testWrongPathRegistrant() throws Exception
+ {
+ HttpServletRequest request = mock(HttpServletRequest.class);
+ HttpServletResponse response = mock(HttpServletResponse.class);
+ ServletDispatcher dispatcher = new ServletDispatcher();
+ Servlet servlet = mock(Servlet.class);
+ HttpContext context = mock(HttpContext.class);
+ ServletRegistration registration = new ServletRegistration("/cad", servlet, context);
+
+ doAnswer(new Answer()
+ {
+ public Object answer(InvocationOnMock invocation)
+ {
+ HttpServletResponse resp = (HttpServletResponse) invocation.getArguments()[1];
+ resp.setStatus(HttpServletResponse.SC_OK);
+ return null;
+ }
+ }).when(servlet).service(request, response);
+ when(context.handleSecurity(request, response)).thenReturn(true);
+ when(request.getPathInfo()).thenReturn("/a/b/c");
+
+ dispatcher.register(registration);
+ dispatcher.service(request, response);
+
+ verify(context, never()).handleSecurity(request, response);
+ verify(response, only()).setStatus(HttpServletResponse.SC_NOT_FOUND);
+ }
+
+ @Test
+ public void testMatchingRegistrant() throws Exception
+ {
+ HttpServletRequest request = mock(HttpServletRequest.class);
+ HttpServletResponse response = mock(HttpServletResponse.class);
+ ServletDispatcher dispatcher = new ServletDispatcher();
+ Servlet servlet = mock(Servlet.class);
+ HttpContext context = mock(HttpContext.class);
+ ServletRegistration registration = new ServletRegistration("/a/b", servlet, context);
+
+ doAnswer(new Answer()
+ {
+ public Object answer(InvocationOnMock invocation)
+ {
+ HttpServletResponse resp = (HttpServletResponse) invocation.getArguments()[1];
+ resp.setStatus(HttpServletResponse.SC_OK);
+ return null;
+ }
+ }).when(servlet).service(request, response);
+ when(context.handleSecurity(request, response)).thenReturn(true);
+ when(request.getPathInfo()).thenReturn("/a/bar");
+
+ dispatcher.register(registration);
+ dispatcher.service(request, response);
+
+ verify(context, never()).handleSecurity(request, response);
+ verify(response, only()).setStatus(HttpServletResponse.SC_NOT_FOUND);
+ }
+}
Property changes on: papoose-cmpn/trunk/http/src/test/java/org/papoose/http/ServletDispatcherTest.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:eol-style
+ native
Modified: papoose-cmpn/trunk/pom.xml
===================================================================
--- papoose-cmpn/trunk/pom.xml 2010-02-24 23:38:32 UTC (rev 254)
+++ papoose-cmpn/trunk/pom.xml 2010-02-24 23:41:47 UTC (rev 255)
@@ -82,6 +82,13 @@
</dependency>
<dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <version>1.8.2</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
<groupId>org.ops4j.pax.exam</groupId>
<artifactId>pax-exam</artifactId>
<version>${paxExamVersion}</version>
@@ -122,12 +129,6 @@
<version>1.0.0.SNAPSHOT</version>
</dependency>
- <dependency>
- <groupId>org.papoose.test</groupId>
- <artifactId>papoose-test-bundle</artifactId>
- <version>${papooseTestVersion}</version>
- </dependency>
-
</dependencies>
</dependencyManagement>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|