1. pk11
  2. pico-servlet

Commits

pk11  committed 687ebab

initial version

  • Participants
  • Branches default

Comments (0)

Files changed (8)

File pico_servlet.iml

View file
+<?xml version="1.0" encoding="UTF-8"?>
+<module relativePaths="true" MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="web" name="Web">
+      <configuration>
+        <descriptors>
+          <deploymentDescriptor name="web.xml" url="file://$MODULE_DIR$/src/main/webapp/WEB-INF/web.xml" optional="false" version="2.5" />
+        </descriptors>
+        <webroots>
+          <root url="file://$MODULE_DIR$/src/main/webapp" relative="/" />
+        </webroots>
+        <sourceRoots>
+          <root url="file://$MODULE_DIR$/src/main/resources" />
+        </sourceRoots>
+        <building>
+          <setting name="EXPLODED_URL" value="file://" />
+          <setting name="EXPLODED_ENABLED" value="false" />
+          <setting name="JAR_URL" value="file://$MODULE_DIR$/target/pico_servlet.war" />
+          <setting name="JAR_ENABLED" value="true" />
+          <setting name="EXCLUDE_EXPLODED_DIRECTORY" value="true" />
+        </building>
+        <packaging>
+          <containerElement type="module" name="pico_servlet">
+            <attribute name="method" value="1" />
+            <attribute name="URI" value="/WEB-INF/classes" />
+          </containerElement>
+        </packaging>
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_5" inherit-compiler-output="false">
+    <output url="file://$MODULE_DIR$/target/classes" />
+    <output-test url="file://$MODULE_DIR$/target/test-classes" />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" name="Maven: junit:junit:3.8.1" level="project" />
+    <orderEntry type="library" name="Maven: org.mockito:mockito-core:1.6" level="project" />
+    <orderEntry type="library" name="Maven: org.hamcrest:hamcrest-core:1.1" level="project" />
+    <orderEntry type="library" name="Maven: org.objenesis:objenesis:1.0" level="project" />
+    <orderEntry type="library" exported="" name="Maven: org.picocontainer.web:picocontainer-web-core:2.2" level="project" />
+    <orderEntry type="library" exported="" name="Maven: org.picocontainer:picocontainer:2.7" level="project" />
+    <orderEntry type="library" exported="" name="Maven: org.picocontainer.script:picocontainer-script-core:2.0" level="project" />
+    <orderEntry type="library" name="Maven: javax.servlet:servlet-api:2.4" level="project" />
+  </component>
+</module>
+

File pom.xml

View file
+<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>
+    <groupId>pico_servlet</groupId>
+    <artifactId>pico_servlet</artifactId>
+    <packaging>jar</packaging>
+    <version>1.0</version>
+    <name>pico_servlet Maven Webapp</name>
+    <url>http://maven.apache.org</url>
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>3.8.1</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <version>1.6</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.picocontainer.web</groupId>
+            <artifactId>picocontainer-web-core</artifactId>
+            <version>2.2</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+            <version>2.4</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+    <build>
+        <finalName>pico_servlet</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <useFile>false</useFile>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.5</source>
+                    <target>1.5</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

File src/main/java/org/picocontainer/web/extension/PicoBaseServlet.java

View file
+package org.picocontainer.web.extension;
+
+import org.picocontainer.PicoContainer;
+
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * This class delegates is the base class for Pico managed servlets
+ * User: phausel
+ * Date: Jan 30, 2009
+ * Time: 2:30:45 PM
+ */
+public abstract class PicoBaseServlet extends HttpServlet {
+
+    /**
+     * retrieve application level components
+     * @param request
+     * @param key
+     * @return a component from pico
+     */
+    protected Object getAppInstance(HttpServletRequest request, Object key) {
+        return (Object) ((PicoContainer)request.getSession().getServletContext().getAttribute("application")).getComponent(key);
+    }
+    /**
+     * retrieve session level components
+     * @param request
+     * @param key
+     * @return a component from pico
+     */
+    protected Object getSessionInstance(HttpServletRequest request, Object key) {
+        return (Object) ((PicoContainer)request.getSession().getAttribute("session")).getComponent(key);
+    }
+    /**
+     * retrieve request level components
+     * @param request
+     * @param key
+     * @return a component from pico
+     */
+    protected Object getRequestInstance(HttpServletRequest request, Object key) {
+        return (Object) ((PicoContainer)request.getAttribute("request")).getComponent(key);
+    }
+
+
+    @Override
+    public void doGet(HttpServletRequest request, HttpServletResponse response) {
+        throw new UnsupportedOperationException("doGet should be implemented for this request or URL Mapping should be changed");
+    }
+    @Override
+    public void doPut(HttpServletRequest request, HttpServletResponse response) {
+        throw new UnsupportedOperationException("doPut should be implemented for this request or URL Mapping should be changed");
+    }
+    @Override
+    public void doPost(HttpServletRequest request, HttpServletResponse response) {
+        throw new UnsupportedOperationException("doPost should be implemented for this request or URL Mapping should be changed");
+    }
+    @Override
+    public void doDelete(HttpServletRequest request, HttpServletResponse response) {
+        throw new UnsupportedOperationException("doDelete should be implemented for this request or URL Mapping should be changed");
+    }
+}

File src/main/java/org/picocontainer/web/extension/PicoDispatcherServlet.java

View file
+package org.picocontainer.web.extension;
+
+import org.picocontainer.PicoContainer;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Map;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+/**
+ * This class delegates the request to the servlet whose mapping  matches the request uri
+ * User: phausel
+ * Date: Jan 30, 2009
+ * Time: 2:30:45 PM
+ */
+public class PicoDispatcherServlet extends HttpServlet {
+
+
+    
+    public void doGet(HttpServletRequest request, HttpServletResponse response) {
+        PicoBaseServlet delegate = delegatetoServlet(request);
+        if (delegate != null)
+            delegate.doGet(request, response);
+        else
+            throw new IllegalArgumentException("either there was not an approprite pattern for " +
+                    request.getRequestURI().replaceFirst(request.getContextPath(), "") +
+                    "or component was not registered with this key");
+    }
+
+    public void doPut(HttpServletRequest request, HttpServletResponse response) {
+        PicoBaseServlet delegate = delegatetoServlet(request);
+        if (delegate != null)
+            delegate.doPut(request, response);
+        else
+            throw new IllegalArgumentException("either there was not an approprite pattern for " +
+                    request.getRequestURI().replaceFirst(request.getContextPath(), "") +
+                    "or component was not registered with this key");
+    }
+
+    public void doPost(HttpServletRequest request, HttpServletResponse response) {
+        PicoBaseServlet delegate = delegatetoServlet(request);
+        if (delegate != null)
+            delegate.doPost(request, response);
+        else
+            throw new IllegalArgumentException("either there was not an approprite pattern for " +
+                    request.getRequestURI().replaceFirst(request.getContextPath(), "") +
+                    "or component was not registered with this key");
+
+    }
+
+    public void doDelete(HttpServletRequest request, HttpServletResponse response) {
+        PicoBaseServlet delegate = delegatetoServlet(request);
+        if (delegate != null)
+            delegate.doDelete(request, response);
+        else
+            throw new IllegalArgumentException("either there was not an approprite pattern for " +
+                    request.getRequestURI().replaceFirst(request.getContextPath(), "") +
+                    "or component was not registered with this key");
+    }
+
+    /**
+    * here happens the real action. incoming url patter is checked against mapping provided by the user
+    * @return null if either the key was not registered in the application level container or the pattern was not matched
+    */
+    private PicoBaseServlet delegatetoServlet(HttpServletRequest request) {
+        Map<Pattern, Class<? extends PicoBaseServlet>> map = (Map<Pattern, Class<? extends PicoBaseServlet>>)
+                request.getSession().getServletContext().getAttribute(PicoServletContainerExtraListener.MAPPING);
+        String path = request.getRequestURI().replaceFirst(request.getContextPath(), "");
+        PicoContainer pico = (PicoContainer) request.getSession().getServletContext().getAttribute("application");
+
+        Class<? extends PicoBaseServlet> clazz = null;
+
+        for (Pattern pattern : map.keySet()) {
+            Matcher m = pattern.matcher(path);
+
+            if (m.matches()) {
+                clazz = map.get(pattern);
+                break;
+            }
+        }
+
+        if ( (clazz == null) || (pico.getComponent(clazz) == null) ) {
+            return null;
+        }
+
+        return pico.getComponent(clazz);
+
+
+    }
+}

File src/main/java/org/picocontainer/web/extension/PicoServletContainerExtraListener.java

View file
+package org.picocontainer.web.extension;
+
+import org.picocontainer.web.PicoServletContainerListener;
+import org.picocontainer.web.WebappComposer;
+import org.picocontainer.PicoCompositionException;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: phausel
+ * Date: Jan 30, 2009
+ * Time: 2:25:39 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class PicoServletContainerExtraListener extends PicoServletContainerListener{
+    public static final String MAPPING="url_mapping";
+    /**
+    * The only difference between this version and the original is that we save url mapping to session variable as well
+    * @param context the
+    * @return webappcomposer
+    *
+    */
+    @Override
+    protected WebappComposer loadComposer(javax.servlet.ServletContext context) {
+           String composerClassName = context.getInitParameter(WEBAPP_COMPOSER_CLASS);
+        try {
+            WebappComposer composer = (WebappComposer) Thread.currentThread().getContextClassLoader().loadClass(composerClassName)
+                    .newInstance();
+            WebappExtraComposer mapper = (WebappExtraComposer) composer;
+            context.setAttribute(MAPPING, mapper.getUrlMapping());
+            return composer;
+        } catch (Exception e) {
+            throw new PicoCompositionException("Failed to load webapp composer class " + composerClassName
+                    + ": ensure the context-param '" + WEBAPP_COMPOSER_CLASS + "' is configured in the web.xml.", e);
+        }
+    }
+}

File src/main/java/org/picocontainer/web/extension/WebappExtraComposer.java

View file
+package org.picocontainer.web.extension;
+
+import org.picocontainer.web.WebappComposer;
+
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+/**
+ * This is an extension interface to WebappComposer
+ * User: phausel
+ * Date: Jan 30, 2009
+ * Time: 2:29:55 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public interface WebappExtraComposer extends WebappComposer{
+    /**
+     *
+     * @return returns the url mapping for pico servlets
+     */
+    public Map<Pattern, Class<? extends PicoBaseServlet>> getUrlMapping();
+}

File src/main/webapp/WEB-INF/web.xml

View file
+<!DOCTYPE web-app PUBLIC
+ "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+ "http://java.sun.com/dtd/web-app_2_3.dtd" >
+
+<web-app>
+  <display-name>Archetype Created Web Application</display-name>
+</web-app>

File src/test/java/org/picocontainer/web/extension/PicoDispatcherServletTest.java

View file
+package org.picocontainer.web.extension;
+
+import junit.framework.TestCase;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import org.picocontainer.PicoContainer;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: phausel
+ * Date: Jan 31, 2009
+ * Time: 9:09:35 AM
+ * To change this template use File | Settings | File Templates.
+ */
+public class PicoDispatcherServletTest extends TestCase {
+
+    public class DummyServlet extends PicoBaseServlet {
+        @Override
+        public void doGet(HttpServletRequest request, HttpServletResponse response) {
+
+        }
+    }
+
+    public void testcallDispatcherWithOutMatchingPattern() {
+        try {
+            PicoContainer pico = mock(PicoContainer.class);
+            DummyServlet servlet = new DummyServlet();
+            Pattern pattern = Pattern.compile("/index11");
+            Map<Pattern, Class<? extends PicoBaseServlet>> map = new HashMap<Pattern, Class<? extends PicoBaseServlet>>();
+            map.put(pattern, DummyServlet.class);
+
+            HttpServletRequest req = mock(HttpServletRequest.class);
+            HttpServletResponse res = mock(HttpServletResponse.class);
+            HttpSession sess = mock(HttpSession.class);
+            ServletContext ctx = mock(ServletContext.class);
+
+            when(pico.getComponent(DummyServlet.class)).thenReturn(servlet);
+            when(ctx.getAttribute(PicoServletContainerExtraListener.MAPPING)).thenReturn(map);
+            when(ctx.getAttribute("application")).thenReturn(pico);
+            when(sess.getServletContext()).thenReturn(ctx);
+            when(req.getSession()).thenReturn(sess);
+            when(req.getRequestURI()).thenReturn("/project/index");
+            when(req.getContextPath()).thenReturn("/project");
+
+            PicoDispatcherServlet target = new PicoDispatcherServlet();
+            target.doGet(req, res);
+            assertTrue("it should fail by now", false);
+        } catch (java.lang.IllegalArgumentException ex) {
+            assertTrue(true);
+        }
+    }
+
+    public void testcallDispatcherWithCorrectParams() {
+        PicoContainer pico = mock(PicoContainer.class);
+        DummyServlet servlet = new DummyServlet();
+        Pattern pattern = Pattern.compile("/index");
+        Map<Pattern, Class<? extends PicoBaseServlet>> map = new HashMap<Pattern, Class<? extends PicoBaseServlet>>();
+        map.put(pattern, DummyServlet.class);
+
+        HttpServletRequest req = mock(HttpServletRequest.class);
+        HttpServletResponse res = mock(HttpServletResponse.class);
+        HttpSession sess = mock(HttpSession.class);
+        ServletContext ctx = mock(ServletContext.class);
+
+        when(pico.getComponent(DummyServlet.class)).thenReturn(servlet);
+        when(ctx.getAttribute(PicoServletContainerExtraListener.MAPPING)).thenReturn(map);
+        when(ctx.getAttribute("application")).thenReturn(pico);
+        when(sess.getServletContext()).thenReturn(ctx);
+        when(req.getSession()).thenReturn(sess);
+        when(req.getRequestURI()).thenReturn("/project/index");
+        when(req.getContextPath()).thenReturn("/project");
+
+        PicoDispatcherServlet target = new PicoDispatcherServlet();
+        target.doGet(req, res);
+    }
+
+    public void testcallDispatcherWithMissingMapper() {
+        try {
+            PicoContainer pico = mock(PicoContainer.class);
+            DummyServlet servlet = new DummyServlet();
+            Pattern pattern = Pattern.compile("/index");
+
+            HttpServletRequest req = mock(HttpServletRequest.class);
+            HttpServletResponse res = mock(HttpServletResponse.class);
+            HttpSession sess = mock(HttpSession.class);
+            ServletContext ctx = mock(ServletContext.class);
+
+            when(pico.getComponent(DummyServlet.class)).thenReturn(servlet);
+            when(ctx.getAttribute("application")).thenReturn(pico);
+            when(sess.getServletContext()).thenReturn(ctx);
+            when(req.getSession()).thenReturn(sess);
+            when(req.getRequestURI()).thenReturn("/project/index");
+            when(req.getContextPath()).thenReturn("/project");
+
+            PicoDispatcherServlet target = new PicoDispatcherServlet();
+            target.doGet(req, res);
+            assertTrue("it should fail by now", false);
+        } catch (java.lang.NullPointerException ex) {
+            assertTrue(true);
+        }
+
+    }
+}