You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@abdera.apache.org by jm...@apache.org on 2006/09/08 18:24:39 UTC

svn commit: r441551 - in /incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server: ./ exceptions/ servlet/ util/

Author: jmsnell
Date: Fri Sep  8 09:24:37 2006
New Revision: 441551

URL: http://svn.apache.org/viewvc?view=rev&rev=441551
Log:
Continuing a number of general implementation improvements.

* Improve thread safety by using immutable fields
* Move X-HTTP-Method-Override support out of the RequestContext and into a servlet filter.
  This simplifies the servlet filter code and separates concerns. It also makes it 
  easier to administratively enable/disable POST tunneling.

Added:
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/MethodOverrideFilter.java
Modified:
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/AbderaServer.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/exceptions/AbderaServerException.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/AbderaServlet.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/ServletRequestContext.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/AbstractRequestHandler.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/BaseResponseContext.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/RegexTargetResolver.java
    incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/ResourceType.java

Modified: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/AbderaServer.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/AbderaServer.java?view=diff&rev=441551&r1=441550&r2=441551
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/AbderaServer.java (original)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/AbderaServer.java Fri Sep  8 09:24:37 2006
@@ -24,41 +24,64 @@
 
 public class AbderaServer implements ServerConstants {
   
-  private Abdera abdera = null;
-  private RequestHandlerFactory handlerFactory = null;
-  private TargetResolver targetResolver = null;
+  private final Abdera abdera;
+  private final RequestHandlerFactory handlerFactory;
+  private final TargetResolver targetResolver;
+  private final String defaultHandlerFactory;
+  private final String defaultTargetResolver;
   
   public AbderaServer() {
-    abdera = new Abdera();
+    this(new Abdera(),"","");
+  }
+  
+  public AbderaServer(
+    String defaultTargetResolver, 
+    String defaultHandlerFactory) {
+      this(new Abdera(), defaultTargetResolver, defaultHandlerFactory);
   }
   
   public AbderaServer(Abdera abdera) {
-    this.abdera = abdera;
+    this(abdera,"","");
+  }
+  
+  public AbderaServer(
+    Abdera abdera, 
+    String defaultTargetResolver, 
+    String defaultHandlerFactory) {
+      this.abdera = abdera;
+      this.handlerFactory = newRequestHandlerFactory(defaultHandlerFactory);
+      this.targetResolver = newTargetResolver(defaultTargetResolver);
+      this.defaultHandlerFactory = defaultHandlerFactory;
+      this.defaultTargetResolver = defaultTargetResolver;
   }
   
   public Abdera getAbdera() {
     return abdera;
   }
   
+  public RequestHandlerFactory newRequestHandlerFactory() {
+    return newRequestHandlerFactory(defaultHandlerFactory);
+  }
+  
   public RequestHandlerFactory newRequestHandlerFactory(String _default) {
     return (RequestHandlerFactory) ServiceUtil.newInstance(
       HANDLER_FACTORY, (_default != null) ? _default : "", abdera);
   }
   
   public RequestHandlerFactory getRequestHandlerFactory(String _default) {
-    if (handlerFactory == null)
-      handlerFactory = newRequestHandlerFactory(_default);
     return handlerFactory;
   }
   
+  public TargetResolver newTargetResolver() {
+    return newTargetResolver(defaultTargetResolver);
+  }
+  
   public TargetResolver newTargetResolver(String _default) {
     return (TargetResolver) ServiceUtil.newInstance(
       TARGET_RESOLVER, (_default != null) ? _default : "", abdera);
   }
   
   public TargetResolver getTargetResolver(String _default) {
-    if (targetResolver == null)
-      targetResolver = newTargetResolver(_default);
     return targetResolver;
   }
 }

Modified: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/exceptions/AbderaServerException.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/exceptions/AbderaServerException.java?view=diff&rev=441551&r1=441550&r2=441551
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/exceptions/AbderaServerException.java (original)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/exceptions/AbderaServerException.java Fri Sep  8 09:24:37 2006
@@ -47,7 +47,7 @@
   implements ResponseContext {
 
   private static final long serialVersionUID = -4477406225965489951L;
-  protected ExceptionResponseContext context = null;
+  protected final ExceptionResponseContext context;
   protected DataSource ds = null;
   
   public static enum Code {

Modified: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/AbderaServlet.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/AbderaServlet.java?view=diff&rev=441551&r1=441550&r2=441551
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/AbderaServlet.java (original)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/AbderaServlet.java Fri Sep  8 09:24:37 2006
@@ -44,16 +44,16 @@
 
   private static final long serialVersionUID = -4273782501412352619L;
 
-  private Abdera abdera = null;
-  private AbderaServer abderaServer = null;
+  private final Abdera abdera;
+  private final AbderaServer abderaServer;
   
-  @Override
-  public void init() throws ServletException {
-    synchronized(this) {
-      abdera = new Abdera();
-      abderaServer = new AbderaServer(abdera);
-    }
+  public AbderaServlet() {
+    this.abdera = new Abdera();
+    this.abderaServer = new AbderaServer(abdera);
   }
+  
+  @Override
+  public void init() throws ServletException {}
 
   /**
    * The RequestContext will either be set on the HttpServletRequest by 
@@ -138,7 +138,7 @@
       long cl = context.getContentLength();
       String cc = context.getCacheControl();
       if (cl > -1) response.setHeader("Content-Length", Long.toString(cl));
-      if (cc != null) response.setHeader("Cache-Control",cc);      
+      if (cc != null) response.setHeader("Cache-Control",cc);
       Map<String, List<Object>> headers = context.getHeaders();
       if (headers != null) {
         for (Map.Entry<String, List<Object>> entry : headers.entrySet()) {

Added: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/MethodOverrideFilter.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/MethodOverrideFilter.java?view=auto&rev=441551
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/MethodOverrideFilter.java (added)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/MethodOverrideFilter.java Fri Sep  8 09:24:37 2006
@@ -0,0 +1,93 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  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.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.protocol.server.servlet;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+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.HttpServletRequestWrapper;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * HTTP Servlet Filter that implements support for Google's X-HTTP-Method-Override
+ * header to perform "POST Tunneling" of various HTTP operations 
+ */
+public class MethodOverrideFilter 
+  implements Filter {
+
+  public static final String METHODS = "org.apache.abdera.protocol.server.servlet.Overrides";
+  
+  private final List<String> METHODS_TO_OVERRIDE = new ArrayList<String>();
+  
+  public void doFilter(
+    ServletRequest request, 
+    ServletResponse response,
+    FilterChain chain) 
+      throws IOException, 
+             ServletException {
+    chain.doFilter(
+      new MethodOverrideRequestWrapper(
+        (HttpServletRequest) request), 
+        response);
+    
+    HttpServletResponse hresponse = (HttpServletResponse) response;
+    hresponse.addHeader("Vary", "X-HTTP-Method-Override");
+  }
+
+  public void init(FilterConfig config) throws ServletException {
+    String param = config.getInitParameter(METHODS);
+    if (param != null) {
+      String[] methods = param.split(",");
+      for (String method : methods) {
+        method = method.trim();
+        METHODS_TO_OVERRIDE.add(method);
+      }
+    }
+  }
+
+  public void destroy() {}
+
+  private class MethodOverrideRequestWrapper 
+    extends HttpServletRequestWrapper {
+
+    public MethodOverrideRequestWrapper(HttpServletRequest request) {
+      super(request);
+    }
+
+    @Override
+    public String getMethod() {
+      String method = super.getMethod();
+      String xheader = getHeader("X-HTTP-Method-Override");
+      if (method.equals("POST") && 
+          xheader != null && 
+          METHODS_TO_OVERRIDE.contains(xheader)) {
+        method = xheader.trim();
+      }
+      return method;
+    }
+    
+  }
+}

Modified: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/ServletRequestContext.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/ServletRequestContext.java?view=diff&rev=441551&r1=441550&r2=441551
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/ServletRequestContext.java (original)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/ServletRequestContext.java Fri Sep  8 09:24:37 2006
@@ -40,10 +40,13 @@
   extends AbstractRequest
   implements RequestContext, ServerConstants {
   
-  private Target target = null;
-  private Abdera abdera = null;
-  private HttpServletRequest servletRequest = null;
-  private String method = null;
+  private final Target target;
+  private final Abdera abdera;
+  private final HttpServletRequest servletRequest;
+  private final String method;
+  private final URI uri;
+  private final URI baseUri;
+  private final URI pathInfo;
     
   public ServletRequestContext(
     Abdera abdera,
@@ -52,7 +55,11 @@
       this.abdera = abdera;
       this.servletRequest = request;
       CacheControlUtil.parseCacheControl(getCacheControl(), this);
+      uri = initUri();
+      baseUri = initBaseUri();
+      pathInfo = initPathInfo();
       target = resolver.resolve(getUri().toString());
+      method = request.getMethod();
   }
   
   public Target getTarget() {
@@ -60,14 +67,14 @@
   }
   
   public String getMethod() {
-    if (method == null) {
-      String o = getHeader(X_OVERRIDE_HEADER);
-      method = (o == null) ? servletRequest.getMethod() : o;
-    }
     return method;
   }
   
   public URI getUri() {
+    return uri;
+  }
+  
+  private URI initUri() {
     URI uri = null;
     try {
       StringBuffer buf = 
@@ -98,6 +105,10 @@
   }
   
   public URI getBaseUri() {
+    return baseUri;
+  }
+  
+  private URI initBaseUri() {
     StringBuffer buffer = 
       new StringBuffer(
         (servletRequest.isSecure())?
@@ -135,6 +146,10 @@
   }
     
   public URI getPathInfo() {
+    return pathInfo;
+  }
+  
+  private URI initPathInfo() {
     try {
       String pathInfo = servletRequest.getPathInfo();
       if (pathInfo == null)  {

Modified: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/AbstractRequestHandler.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/AbstractRequestHandler.java?view=diff&rev=441551&r1=441550&r2=441551
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/AbstractRequestHandler.java (original)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/AbstractRequestHandler.java Fri Sep  8 09:24:37 2006
@@ -24,8 +24,6 @@
 
 public abstract class AbstractRequestHandler 
   implements RequestHandler, ServerConstants {
-
-  protected ResourceType resourceType = ResourceType.UNKNOWN;
   
   public AbstractRequestHandler() {}
   

Modified: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/BaseResponseContext.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/BaseResponseContext.java?view=diff&rev=441551&r1=441550&r2=441551
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/BaseResponseContext.java (original)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/BaseResponseContext.java Fri Sep  8 09:24:37 2006
@@ -25,23 +25,22 @@
 import javax.activation.MimeTypeParseException;
 
 import org.apache.abdera.model.Base;
-import org.apache.abdera.model.Document;
-import org.apache.abdera.model.Element;
+import org.apache.abdera.util.MimeTypeHelper;
 
 public class BaseResponseContext<T extends Base>
   extends AbstractResponseContext {
 
-  private T base = null;
-  private boolean chunked = true;
+  private final T base;
+  private final boolean chunked;
   
   public BaseResponseContext(T base) {
-    this.base = base;
-    setStatus(200);
-    setStatusText("OK");
+    this(base, true);
   }
   
   public BaseResponseContext(T base, boolean chunked) {
-    this(base);
+    this.base = base;
+    setStatus(200);
+    setStatusText("OK");
     this.chunked = chunked;
   }
   
@@ -62,14 +61,8 @@
     throws MimeTypeParseException {
       MimeType t = super.getContentType();
       if (t == null) {
-        Document doc = null;
-        if (base instanceof Document) {
-          doc = (Document) base;
-        } else if (base instanceof Element) {
-          Element el = (Element) base;
-          doc = el.getDocument();
-        }
-        t = (doc != null) ? doc.getContentType() : null;
+        String type = MimeTypeHelper.getMimeType(base);
+        if (type != null) t = new MimeType(type);
       }
       return t;
   }

Modified: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/RegexTargetResolver.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/RegexTargetResolver.java?view=diff&rev=441551&r1=441550&r2=441551
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/RegexTargetResolver.java (original)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/RegexTargetResolver.java Fri Sep  8 09:24:37 2006
@@ -51,7 +51,7 @@
  */
 public class RegexTargetResolver implements TargetResolver {
 
-  private Map<ResourceType,Pattern> patterns = null;
+  private final Map<ResourceType,Pattern> patterns;
   
   public RegexTargetResolver() {
     this.patterns = new HashMap<ResourceType,Pattern>();
@@ -66,13 +66,12 @@
     }
   }
   
-  public void addPattern(ResourceType type, String pattern) {
+  public synchronized void setPattern(ResourceType type, String pattern) {
     Pattern p = Pattern.compile(pattern);
     this.patterns.put(type, p);
   }
   
   public Target resolve(String path_info) {
-    if (patterns == null) return null;
     for (ResourceType type : patterns.keySet()) {
       Pattern pattern = patterns.get(type);
       Matcher matcher = pattern.matcher(path_info);
@@ -83,8 +82,8 @@
   
   public static class RegexTarget implements Target {
     
-    Matcher matcher = null;
-    ResourceType type = ResourceType.UNKNOWN;
+    final Matcher matcher;
+    final ResourceType type;
     
     RegexTarget(ResourceType type, Matcher matcher) {
       this.type = type;

Modified: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/ResourceType.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/ResourceType.java?view=diff&rev=441551&r1=441550&r2=441551
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/ResourceType.java (original)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/ResourceType.java Fri Sep  8 09:24:37 2006
@@ -27,20 +27,20 @@
              Serializable {
 
   private static final long serialVersionUID = -4325229702865059923L;
-  public static final int UNKNOWN_ORDINAL = 0;
-  public static final int SERVICE_ORDINAL = 1;
+  public static final int UNKNOWN_ORDINAL    = 0;
+  public static final int SERVICE_ORDINAL    = 1;
   public static final int COLLECTION_ORDINAL = 2;
-  public static final int ENTRY_ORDINAL = 3;
+  public static final int ENTRY_ORDINAL      = 3;
   public static final int ENTRY_EDIT_ORDINAL = 4;
-  public static final int MEDIA_ORDINAL = 5;
+  public static final int MEDIA_ORDINAL      = 5;
   public static final int MEDIA_EDIT_ORDINAL = 6;
   
-  public static final ResourceType UNKNOWN = new ResourceType("UNKNOWN", UNKNOWN_ORDINAL); 
-  public static final ResourceType SERVICE = new ResourceType("SERVICE", SERVICE_ORDINAL);
+  public static final ResourceType UNKNOWN    = new ResourceType("UNKNOWN", UNKNOWN_ORDINAL); 
+  public static final ResourceType SERVICE    = new ResourceType("SERVICE", SERVICE_ORDINAL);
   public static final ResourceType COLLECTION = new ResourceType("COLLECTION", COLLECTION_ORDINAL); 
-  public static final ResourceType ENTRY = new ResourceType("ENTRY", ENTRY_ORDINAL);
+  public static final ResourceType ENTRY      = new ResourceType("ENTRY", ENTRY_ORDINAL);
   public static final ResourceType ENTRY_EDIT = new ResourceType("ENTRY_EDIT", ENTRY_EDIT_ORDINAL);
-  public static final ResourceType MEDIA = new ResourceType("MEDIA", MEDIA_ORDINAL);
+  public static final ResourceType MEDIA      = new ResourceType("MEDIA", MEDIA_ORDINAL);
   public static final ResourceType MEDIA_EDIT = new ResourceType("MEDIA_EDIT", MEDIA_EDIT_ORDINAL);
   
   private static List<ResourceType> values;
@@ -58,7 +58,7 @@
     values.add(type);
   }
   
-  public static synchronized ResourceType[] values() {
+  public static ResourceType[] values() {
     List<ResourceType> values = get_values();
     return values.toArray(new ResourceType[values.size()]);
   }
@@ -70,8 +70,8 @@
     return null;
   }
   
-  private int i;
-  private String name;
+  private final int i;
+  private final String name;
   
   public ResourceType(String name, int ordinal) {
     this.i = ordinal;