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/13 04:00:38 UTC

svn commit: r442792 [2/2] - in /incubator/abdera/java/trunk: client/src/main/java/org/apache/abdera/protocol/client/ examples/src/main/java/org/apache/abdera/examples/appserver/ examples/src/main/resources/org/apache/abdera/examples/appserver/ protocol...

Added: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/ResponseContext.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/ResponseContext.java?view=auto&rev=442792
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/ResponseContext.java (added)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/ResponseContext.java Tue Sep 12 19:00:35 2006
@@ -0,0 +1,32 @@
+/*
+* 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.provider;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.abdera.protocol.Response;
+
+public interface ResponseContext 
+  extends Response {
+
+  public boolean hasEntity();
+  
+  public void writeTo(OutputStream out) throws IOException;
+  
+}

Added: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/Target.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/Target.java?view=auto&rev=442792
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/Target.java (added)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/Target.java Tue Sep 12 19:00:35 2006
@@ -0,0 +1,30 @@
+/*
+* 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.provider;
+
+public interface Target {
+
+  TargetType getType();
+  
+  String getIdentity();
+  
+  String getParameter(String name);
+  
+  String[] getParameterNames();
+  
+}

Added: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/TargetResolver.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/TargetResolver.java?view=auto&rev=442792
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/TargetResolver.java (added)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/TargetResolver.java Tue Sep 12 19:00:35 2006
@@ -0,0 +1,24 @@
+/*
+* 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.provider;
+
+public interface TargetResolver {
+
+  Target resolve(RequestContext context);
+  
+}

Added: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/TargetType.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/TargetType.java?view=auto&rev=442792
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/TargetType.java (added)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/provider/TargetType.java Tue Sep 12 19:00:35 2006
@@ -0,0 +1,89 @@
+/*
+* 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.provider;
+
+public final class TargetType {
+
+  public static final String UNKNOWN = "UNKNOWN";
+  public static final String SERVICE = "SERVICE";
+  public static final String COLLECTION = "COLLECTION";
+  public static final String ENTRY = "ENTRY";
+  public static final String MEDIA = "MEDIA";
+  public static final String ENTRY_EDIT = "ENTRY_EDIT";
+  public static final String MEDIA_EDIT = "MEDIA_EDIT";
+  
+  public static final TargetType TYPE_UNKNOWN = new TargetType(UNKNOWN);
+  public static final TargetType TYPE_SERVICE = new TargetType(SERVICE);
+  public static final TargetType TYPE_COLLECTION = new TargetType(COLLECTION);
+  public static final TargetType TYPE_ENTRY = new TargetType(ENTRY);
+  public static final TargetType TYPE_MEDIA = new TargetType(MEDIA);
+  public static final TargetType TYPE_ENTRY_EDIT = new TargetType(ENTRY_EDIT);
+  public static final TargetType TYPE_MEDIA_EDIT = new TargetType(MEDIA_EDIT);
+  
+  public static TargetType get(String name) {
+    if (name == null) return null;
+    name = name.toUpperCase().intern();
+    if (name == UNKNOWN) return TYPE_UNKNOWN;
+    if (name == COLLECTION) return TYPE_COLLECTION;
+    if (name == ENTRY) return TYPE_ENTRY;
+    if (name == MEDIA) return TYPE_MEDIA;
+    if (name == ENTRY_EDIT) return TYPE_ENTRY_EDIT;
+    if (name == MEDIA_EDIT) return TYPE_MEDIA_EDIT;
+    return null;
+  }
+  
+  public static TargetType get(String name, boolean create) {
+    TargetType type = get(name);
+    return (type != null) ? type : (create) ? new TargetType(name) : null;
+  }
+  
+  private final String name;
+  
+  public TargetType(String name) {
+    if (name == null || name.length() == 0) throw new IllegalArgumentException();
+    this.name = name.toUpperCase();
+  }
+  
+  public String name() {
+    return name;
+  }
+  
+  public String toString() {
+    return name;
+  }
+
+  public int hashCode() {
+    final int PRIME = 31;
+    int result = 1;
+    result = PRIME * result + ((name == null) ? 0 : name.hashCode());
+    return result;
+  }
+
+  public boolean equals(Object obj) {
+    if (this == obj) return true;
+    if (obj == null) return false;
+    if (getClass() != obj.getClass()) return false;
+    final TargetType other = (TargetType) obj;
+    if (name == null) {
+      if (other.name != null) return false;
+    } else if (!name.equals(other.name))
+      return false;
+    return true;
+  }
+  
+}

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=442792&r1=442791&r2=442792
==============================================================================
--- 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 Tue Sep 12 19:00:35 2006
@@ -18,66 +18,30 @@
 package org.apache.abdera.protocol.server.servlet;
 
 import java.io.IOException;
-import java.util.Date;
-import java.util.List;
+import java.util.Enumeration;
+import java.util.HashMap;
 import java.util.Map;
 
 import javax.servlet.ServletConfig;
-import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.apache.abdera.Abdera;
-import org.apache.abdera.protocol.server.AbderaServer;
-import org.apache.abdera.protocol.server.RequestContext;
-import org.apache.abdera.protocol.server.RequestHandler;
-import org.apache.abdera.protocol.server.RequestHandlerManager;
-import org.apache.abdera.protocol.server.ResponseContext;
-import org.apache.abdera.protocol.server.exceptions.AbderaServerException;
-import org.apache.abdera.protocol.server.util.ServerConstants;
+import org.apache.abdera.protocol.server.ServiceContext;
+import org.apache.abdera.protocol.server.ServiceManager;
+import org.apache.abdera.protocol.server.servlet.RequestHandler;
+import org.apache.abdera.protocol.server.servlet.RequestHandlerManager;
 
 public class AbderaServlet 
-  extends HttpServlet 
-  implements ServerConstants {
+  extends HttpServlet {
 
-  private static final long serialVersionUID = -4273782501412352619L;
-
-  private Abdera abdera;
-  private AbderaServer abderaServer;
+  private static final long serialVersionUID = 2393643907128535158L;
   
-  @Override
-  public void init() throws ServletException {
-    ServletContext context = getServletContext();
-    if (context.getAttribute("abdera") == null) {
-      synchronized(context) {
-        ServletConfig config = getServletConfig();
-        this.abdera = new Abdera();
-        this.abderaServer = 
-          new AbderaServer(
-            abdera, 
-            config.getInitParameter(TARGET_RESOLVER), 
-            config.getInitParameter(HANDLER_MANAGER), 
-            config.getInitParameter(SUBJECT_RESOLVER), 
-            config.getInitParameter(PROVIDER_MANAGER));
-        context.setAttribute("abdera", abdera);
-        context.setAttribute("server", abderaServer);
-      }
-    }
-  }
-
-  /**
-   * The RequestContext will either be set on the HttpServletRequest by 
-   * some filter or servlet earlier in the invocation chain or will need
-   * to be created and set on the request 
-   */
-  private RequestContext getRequestContext(HttpServletRequest request) {
-    return new ServletRequestContext(abderaServer,request);
-  }
+  protected ServiceManager serviceManager;
   
-  private RequestHandlerManager getRequestHandlerManager() {
-    return abderaServer.getRequestHandlerManager();
+  public void init() throws ServletException {
+    serviceManager = ServiceManager.getInstance();
   }
   
   @Override
@@ -85,57 +49,29 @@
     HttpServletRequest request, 
     HttpServletResponse response) 
       throws ServletException, IOException {
-    RequestContext requestContext = getRequestContext(request);
-    ResponseContext responseContext = null;
-    RequestHandler handler = null;
-    RequestHandlerManager manager = null;
+    ServiceContext context = 
+      serviceManager.newServiceContext(
+        getProperties(getServletConfig()));
+    RequestHandlerManager manager = context.getRequestHandlerManager();
+    RequestHandler handler = manager.getRequestHandler();
     try {
-      manager = getRequestHandlerManager();
-      handler = (manager != null) ? 
-        manager.newRequestHandler(abderaServer) : null;
-      responseContext = (handler != null) ? 
-        handler.invoke(requestContext) :
-        new AbderaServerException(AbderaServerException.Code.NOTFOUND);
-    } catch (AbderaServerException exception) {  
-      responseContext = exception;
+      handler.process(context, request, response);
     } catch (Throwable t) {
-      responseContext = new AbderaServerException(t);
+      response.sendError(500);
     } finally {
-      if (manager != null)
-        manager.releaseRequestHandler(handler);
+      manager.release(handler);
     }
-    doOutput(response, responseContext); 
   }
-
-  private void doOutput(
-    HttpServletResponse response, 
-    ResponseContext context) 
-      throws IOException, ServletException {
-    if (context != null) {
-      response.setStatus(context.getStatus());
-      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);
-      Map<String, List<Object>> headers = context.getHeaders();
-      if (headers != null) {
-        for (Map.Entry<String, List<Object>> entry : headers.entrySet()) {
-          List<Object> values = entry.getValue();
-          if (values == null) 
-            continue;          
-          for (Object value : values) {
-            if (value instanceof Date)
-              response.setDateHeader(entry.getKey(), ((Date)value).getTime());
-            else
-              response.setHeader(entry.getKey(), value.toString());
-          }
-        }
-      }  
-      if (context.hasEntity())
-        context.writeTo(response.getOutputStream());
-    } else {
-      response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+  
+  private Map<String,String> getProperties(ServletConfig config) {
+    Map<String,String> properties = new HashMap<String,String>();
+    Enumeration e = config.getInitParameterNames();
+    while(e.hasMoreElements()) {
+      String key = (String) e.nextElement();
+      String val = config.getInitParameter(key);
+      properties.put(key, val);
     }
+    return properties;
   }
   
 }

Added: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/AbstractRequestHandler.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/AbstractRequestHandler.java?view=auto&rev=442792
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/AbstractRequestHandler.java (added)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/AbstractRequestHandler.java Tue Sep 12 19:00:35 2006
@@ -0,0 +1,227 @@
+/*
+* 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.io.OutputStream;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import javax.activation.MimeType;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.abdera.protocol.ResponseInfo;
+import org.apache.abdera.protocol.server.ServiceContext;
+import org.apache.abdera.protocol.server.provider.EmptyResponseContext;
+import org.apache.abdera.protocol.server.provider.Provider;
+import org.apache.abdera.protocol.server.provider.ProviderManager;
+import org.apache.abdera.protocol.server.provider.RequestContext;
+import org.apache.abdera.protocol.server.provider.ResponseContext;
+import org.apache.abdera.protocol.server.provider.Target;
+import org.apache.abdera.protocol.server.provider.TargetType;
+import org.apache.abdera.protocol.EntityTag;
+
+public abstract class AbstractRequestHandler 
+  implements RequestHandler {
+
+  public void process(
+    ServiceContext context, 
+    HttpServletRequest request,
+    HttpServletResponse response) 
+      throws IOException {
+    
+    ProviderManager manager = context.getProviderManager();
+    Provider provider = manager.getProvider();
+    RequestContext requestContext = getRequestContext(context,request);
+    
+    try {
+      if (preconditions(provider, requestContext, response)) {
+        output(response,process(provider, requestContext));
+      }
+    } catch (Throwable e) {
+      try {
+        output(response,new EmptyResponseContext(500));
+      } catch (Exception ex) {
+        response.sendError(500);
+      }
+    } finally {
+      manager.release(provider);
+    }
+  }
+  
+  protected boolean preconditions(
+    Provider provider, 
+    RequestContext request, 
+    HttpServletResponse response)
+      throws IOException {
+    // Check The Provider    
+    if (provider == null) { 
+      noprovider(response); 
+      return false;
+    }
+    // Check The Target
+    Target target = request.getTarget();
+    if (target == null) { 
+      notfound(response); 
+      return false;
+    }
+    // Check The Method
+    if (!checkMethod(request)) {
+      notallowed(
+        response, 
+        request.getMethod(), 
+        getAllowedMethods(target.getType()));
+      return false;
+    }
+    // Check The Conditions
+    ResponseInfo info = provider.getInfo(request);
+    switch(checkConditions(info, request)) {
+      case 412: preconditionfailed(response); return false;
+      case 304: notmodified(response); return false;
+    }
+    return true;
+  }
+  
+  protected abstract ResponseContext process(
+    Provider provider, 
+    RequestContext request);
+  
+  protected void output(
+    HttpServletResponse response, 
+    ResponseContext context) 
+      throws IOException, ServletException {
+    if (context != null) {
+      response.setStatus(context.getStatus());
+      long cl = context.getContentLength();
+      String cc = context.getCacheControl();
+      if (cl > -1) response.setHeader("Content-Length", Long.toString(cl));
+      if (cc != null && cc.length() > 0) response.setHeader("Cache-Control",cc);
+      try {
+        MimeType ct = context.getContentType();
+        if (ct != null) response.setContentType(ct.toString());
+      } catch (Exception e) {}
+      Map<String, List<Object>> headers = context.getHeaders();
+      if (headers != null) {
+        for (Map.Entry<String, List<Object>> entry : headers.entrySet()) {
+          List<Object> values = entry.getValue();
+          if (values == null) 
+            continue;          
+          for (Object value : values) {
+            if (value instanceof Date)
+              response.setDateHeader(entry.getKey(), ((Date)value).getTime());
+            else
+              response.setHeader(entry.getKey(), value.toString());
+          }
+        }
+      }  
+      if (context.hasEntity()) {
+        OutputStream out = response.getOutputStream();
+        context.writeTo(out);
+        out.close();
+      }  
+    } else {
+      response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+    }
+  }
+  
+  protected boolean checkMethod(
+    RequestContext context) 
+      throws IOException {
+    String method = context.getMethod();
+    Target target = context.getTarget();
+    String[] methods = getAllowedMethods(target.getType());
+    java.util.Arrays.sort(methods);
+    return (java.util.Arrays.binarySearch(methods, method) >= 0);
+  }
+
+  protected abstract String[] getAllowedMethods(TargetType type);
+  
+  protected RequestContext getRequestContext(
+    ServiceContext context, 
+    HttpServletRequest request) {
+      return new HttpServletRequestContext(context, request);
+  }
+  
+  protected int checkConditions(
+    ResponseInfo info, 
+    RequestContext request) {
+      EntityTag entity_tag = (info != null) ? info.getEntityTag() : null;
+      Date last_mod = (info != null) ? info.getLastModified() : null;
+      if (entity_tag != null) {
+        String ifmatch = request.getIfMatch();
+        if (ifmatch != null && 
+           (entity_tag == null || 
+            !EntityTag.matches(entity_tag,ifmatch))) {
+          return 412;
+        }
+        String ifnonematch = request.getIfNoneMatch();
+        if (ifnonematch != null && 
+            entity_tag != null && 
+            EntityTag.matches(entity_tag,ifnonematch)) {
+          return 304;
+        }
+      }
+      if (last_mod != null) {
+        Date ifmodsince = request.getIfModifiedSince();
+        if (ifmodsince != null && 
+            last_mod.getTime() <= ifmodsince.getTime()) return 304;
+        Date ifunmodsince = request.getIfUnmodifiedSince();
+        if (ifunmodsince != null && 
+            last_mod.getTime() > ifunmodsince.getTime()) return 412;
+      }
+      return 0;
+  }
+  
+  protected void preconditionfailed(HttpServletResponse response) throws IOException {
+    response.sendError(412, "Failed");
+  }
+  
+  protected void notmodified(HttpServletResponse response) throws IOException {
+    response.sendError(304, "Not Modified");
+  }
+  
+  protected void noprovider(HttpServletResponse response) throws IOException {
+    response.sendError(500, "No Provider");
+  }
+  
+  protected void notfound(HttpServletResponse response) throws IOException {
+    response.sendError(404, "Not Found");
+  }
+  
+  protected void notallowed(
+    HttpServletResponse response,
+    String method, 
+    String[] methods) 
+      throws IOException {
+    response.sendError(405, "Method '" + method + "' Not Allowed");
+    response.setHeader("Allow", combine(methods));;
+  }
+  
+  protected String combine(String... vals) {
+    StringBuffer buf = new StringBuffer();
+    for(String val : vals) {
+      if (buf.length() > 0) buf.append(", ");
+      buf.append(val);
+    }
+    return buf.toString();
+  }
+
+}

Added: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/AbstractRequestHandlerManager.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/AbstractRequestHandlerManager.java?view=auto&rev=442792
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/AbstractRequestHandlerManager.java (added)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/AbstractRequestHandlerManager.java Tue Sep 12 19:00:35 2006
@@ -0,0 +1,30 @@
+/*
+* 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 org.apache.abdera.protocol.util.PoolManager;
+
+public abstract class AbstractRequestHandlerManager 
+  extends PoolManager<RequestHandler>
+  implements RequestHandlerManager {
+
+  public RequestHandler getRequestHandler() {
+    return getInstance();
+  }
+
+}

Added: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/DefaultRequestHandler.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/DefaultRequestHandler.java?view=auto&rev=442792
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/DefaultRequestHandler.java (added)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/DefaultRequestHandler.java Tue Sep 12 19:00:35 2006
@@ -0,0 +1,122 @@
+/*
+* 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 org.apache.abdera.protocol.server.provider.AbstractResponseContext;
+import org.apache.abdera.protocol.server.provider.EmptyResponseContext;
+import org.apache.abdera.protocol.server.provider.Provider;
+import org.apache.abdera.protocol.server.provider.RequestContext;
+import org.apache.abdera.protocol.server.provider.ResponseContext;
+import org.apache.abdera.protocol.server.provider.TargetType;
+
+public class DefaultRequestHandler 
+  extends AbstractRequestHandler
+  implements RequestHandler {
+
+  protected ResponseContext process(
+    Provider provider, 
+    RequestContext request) {
+      String method = request.getMethod().intern();
+      TargetType type = request.getTarget().getType();
+      if (method == "GET") {
+        if (type == TargetType.TYPE_SERVICE) {
+          return provider.getService(request, true);
+        }
+        if (type == TargetType.TYPE_COLLECTION) {
+          return provider.getFeed(request, true);
+        }
+        if (type == TargetType.TYPE_ENTRY) {
+          return provider.getEntry(request, true, false);
+        }
+        if (type == TargetType.TYPE_ENTRY_EDIT) {
+          return provider.getEntry(request, true, true);
+        }
+        if (type == TargetType.TYPE_MEDIA) {
+          return provider.getMedia(request, true, false);
+        }
+        if (type == TargetType.TYPE_MEDIA_EDIT) {
+          return provider.getMedia(request, true, true);
+        }
+      }
+      else if (method == "HEAD") {
+        if (type == TargetType.TYPE_SERVICE) {
+          return provider.getService(request, false);
+        }
+        if (type == TargetType.TYPE_COLLECTION) {
+          return provider.getFeed(request, false);
+        }
+        if (type == TargetType.TYPE_ENTRY) {
+          return provider.getEntry(request, false, false);
+        }
+        if (type == TargetType.TYPE_ENTRY_EDIT) {
+          return provider.getEntry(request, false, true);
+        }
+        if (type == TargetType.TYPE_MEDIA) {
+          return provider.getMedia(request, false, false);
+        }
+        if (type == TargetType.TYPE_MEDIA_EDIT) {
+          return provider.getMedia(request, false, true);
+        }
+      }
+      else if (method == "POST") {
+        if (type == TargetType.TYPE_COLLECTION) {
+          return provider.createEntry(request);
+        }
+        if (type == TargetType.TYPE_ENTRY_EDIT) {
+          return provider.entryPost(request);
+        }
+        if (type == TargetType.TYPE_MEDIA_EDIT) {
+          return provider.mediaPost(request);
+        }
+      }
+      else if (method == "PUT") {
+        if (type == TargetType.TYPE_ENTRY_EDIT) {
+          return provider.updateEntry(request);
+        }
+        if (type == TargetType.TYPE_MEDIA_EDIT) {
+          return provider.updateMedia(request);
+        }
+      }
+      else if (method == "DELETE") {
+        if (type == TargetType.TYPE_ENTRY_EDIT) {
+          return provider.deleteEntry(request);
+        }
+        if (type == TargetType.TYPE_MEDIA_EDIT) {
+          return provider.deleteMedia(request);
+        }
+      } 
+      else if (method == "OPTIONS") {
+        AbstractResponseContext rc = new EmptyResponseContext(200);
+        rc.addHeader("Allow", combine(getAllowedMethods(type)));
+        return rc;
+      }
+      return null;
+  }
+  
+  protected String[] getAllowedMethods(TargetType type) {
+    if (type == null)                       return new String[0];
+    if (type == TargetType.TYPE_COLLECTION) return new String[] { "GET", "POST", "HEAD", "OPTIONS" };
+    if (type == TargetType.TYPE_ENTRY)      return new String[] { "GET", "HEAD", "OPTIONS" };
+    if (type == TargetType.TYPE_MEDIA)      return new String[] { "GET", "HEAD", "OPTIONS" };
+    if (type == TargetType.TYPE_ENTRY_EDIT) return new String[] { "GET", "DELETE", "PUT", "POST", "HEAD", "OPTIONS" };
+    if (type == TargetType.TYPE_MEDIA_EDIT) return new String[] { "GET", "DELETE", "PUT", "POST", "HEAD", "OPTIONS" };
+    if (type == TargetType.TYPE_SERVICE)    return new String[] { "GET", "HEAD", "OPTIONS" };
+    return new String[] { "GET", "HEAD", "OPTIONS" };
+  }
+  
+}

Added: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/DefaultRequestHandlerManager.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/DefaultRequestHandlerManager.java?view=auto&rev=442792
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/DefaultRequestHandlerManager.java (added)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/DefaultRequestHandlerManager.java Tue Sep 12 19:00:35 2006
@@ -0,0 +1,28 @@
+/*
+* 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;
+
+public class DefaultRequestHandlerManager 
+  extends AbstractRequestHandlerManager {
+
+  @Override
+  protected RequestHandler internalNewInstance() {
+    return new DefaultRequestHandler();
+  }
+
+}

Added: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/HttpServletRequestContext.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/HttpServletRequestContext.java?view=auto&rev=442792
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/HttpServletRequestContext.java (added)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/HttpServletRequestContext.java Tue Sep 12 19:00:35 2006
@@ -0,0 +1,221 @@
+/*
+* 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.io.InputStream;
+import java.io.Reader;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.security.Principal;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+import org.apache.abdera.Abdera;
+import org.apache.abdera.protocol.server.ServiceContext;
+import org.apache.abdera.protocol.server.auth.SubjectResolver;
+import org.apache.abdera.protocol.server.provider.AbstractRequestContext;
+import org.apache.abdera.protocol.server.provider.RequestContext;
+import org.apache.abdera.protocol.server.provider.TargetResolver;
+
+public class HttpServletRequestContext 
+  extends AbstractRequestContext
+  implements RequestContext {
+
+  private final HttpServletRequest request;
+  private HttpSession session;
+  
+  public HttpServletRequestContext(
+    ServiceContext context, 
+    HttpServletRequest request) {
+      super(
+        context, 
+        request.getMethod(), 
+        initRequestUri(request),
+        initBaseUri(context,request));
+      this.request = request;
+      this.session = request.getSession(false);
+      
+      SubjectResolver subjectResolver = context.getSubjectResolver();
+      subject = (subjectResolver != null)? 
+        subjectResolver.resolve((Principal)getProperty(Property.PRINCIPAL)) : null;
+      
+      TargetResolver targetResolver = context.getTargetResolver();
+      target = (targetResolver != null) ? 
+        targetResolver.resolve(this) : null;
+  }
+  
+  public Object getProperty(Property property) {
+    switch (property) {
+      case SESSIONID:         return (session != null) ? session.getId() : null;
+      case SESSIONCREATED:    return (session != null) ? new Date(session.getCreationTime()) : null;
+      case SESSIONACCESSED:   return (session != null) ? new Date(session.getLastAccessedTime()) : null;
+      case SESSIONTIMEOUT:    return (session != null) ? session.getMaxInactiveInterval() : -1;
+      case CHARACTERENCODING: return request.getCharacterEncoding();
+      case LOCALES:           return request.getLocales();
+      case PROTOCOL:          return request.getProtocol();
+      case REMOTEADDRESS:     return request.getRemoteAddr();
+      case REMOTEHOST:        return request.getRemoteHost();
+      case REMOTEUSER:        return request.getRemoteUser();
+      case SCHEME:            return request.getScheme();
+      case PRINCIPAL:         return request.getUserPrincipal();
+      default:
+        throw new UnsupportedOperationException("Property not supported"); 
+    }
+  }
+  
+  public Reader getReader() throws IOException {
+    return request.getReader();
+  }
+  
+  public InputStream getInputStream() throws IOException {
+    return request.getInputStream();
+  }
+  
+  private synchronized HttpSession getSession() {
+    if (session == null) session = request.getSession(true);
+    return session;
+  }
+  
+  public void setAttribute(Scope scope, String name, Object value) {
+    switch(scope) {
+      case REQUEST: request.setAttribute(name, value); break;
+      case SESSION: getSession().setAttribute(name, value); break;
+    }
+  }
+  
+  public Object getAttribute(Scope scope, String name) {
+    switch(scope) {
+      case REQUEST: return request.getAttribute(name);
+      case SESSION: return (session != null) ? session.getAttribute(name) : null;
+    }
+    return null;
+  }
+  
+  @SuppressWarnings("unchecked")
+  public String[] getAttributeNames(Scope scope) {
+    switch(scope) {
+      case REQUEST: enum2array(request.getAttributeNames());
+      case SESSION: return (session != null) ? enum2array(session.getAttributeNames()) : null;
+    }
+    return null;
+  }
+  
+  public String getParameter(String name) {
+    return request.getParameter(name);
+  }
+  
+  @SuppressWarnings("unchecked")
+  public String[] getParameterNames() {
+    return enum2array(request.getParameterNames());
+  }
+  
+  public List<String> getParameters(String name) {
+    return java.util.Arrays.asList(
+      request.getParameterValues(name));
+  }
+  
+  public Date getDateHeader(String name) {
+    return new Date(request.getDateHeader(name));
+  }
+
+  public String getHeader(String name) {
+    return request.getHeader(name);
+  }
+
+  @SuppressWarnings("unchecked")
+  public String[] getHeaderNames() {
+    return enum2array(request.getHeaderNames());
+  }
+
+  @SuppressWarnings("unchecked")
+  public List<String> getHeaders(String name) {
+    Enumeration<String> e = request.getHeaders(name);
+    return java.util.Collections.list(e);
+  }
+
+  @SuppressWarnings("unchecked")
+  private static String[] enum2array (Enumeration<String> e) {
+    List<String> list = java.util.Collections.list(e);
+    return list.toArray(new String[list.size()]);
+  }
+  
+  private static String getHost(
+      ServiceContext context, 
+      HttpServletRequest request) {
+        Abdera abdera = context.getAbdera();
+        String host = abdera.getConfiguration().getConfigurationOption(
+          "org.apache.abdera.protocol.server.Host");
+        return (host != null) ? 
+          host : 
+          request.getServerName();
+    }
+    
+    private static int getPort(
+      ServiceContext context, 
+      HttpServletRequest request) {
+      Abdera abdera = context.getAbdera();
+        String port = abdera.getConfiguration().getConfigurationOption(
+          "org.apache.abdera.protocol.server.Port");
+        return (port != null) ? 
+          Integer.parseInt(port) : 
+          request.getLocalPort();
+    }
+    
+    private static URI initBaseUri(
+      ServiceContext context, 
+      HttpServletRequest request) {
+        StringBuffer buffer = 
+          new StringBuffer(
+            (request.isSecure())?
+              "https":"http");
+        buffer.append("://");
+        buffer.append(getHost(context,request));
+        int port = getPort(context,request);
+        if (port != 80) {
+          buffer.append(":");
+          buffer.append(port);
+        }
+        buffer.append(request.getContextPath());
+        // So that .resolve() works appropriately.
+        buffer.append("/");
+        try {
+          return new URI(buffer.toString());
+        } catch (URISyntaxException e) {
+          throw new RuntimeException(e);
+        }
+    }
+    
+    private static URI initRequestUri(HttpServletRequest request) {
+      URI uri = null;
+      try {
+        StringBuffer buf = 
+          new StringBuffer(
+            request.getRequestURI());
+        String qs = request.getQueryString();
+        if (qs != null && qs.length() != 0)
+          buf.append("?" + request.getQueryString());
+        uri = new URI(buf.toString());
+      } catch (URISyntaxException e) {}
+      return uri;
+    }
+}

Added: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/RequestHandler.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/RequestHandler.java?view=auto&rev=442792
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/RequestHandler.java (added)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/RequestHandler.java Tue Sep 12 19:00:35 2006
@@ -0,0 +1,34 @@
+/*
+* 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 javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.abdera.protocol.server.ServiceContext;
+
+public interface RequestHandler {
+
+  void process(
+    ServiceContext context, 
+    HttpServletRequest request, 
+    HttpServletResponse response) throws IOException;
+  
+}

Added: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/RequestHandlerManager.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/RequestHandlerManager.java?view=auto&rev=442792
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/RequestHandlerManager.java (added)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/servlet/RequestHandlerManager.java Tue Sep 12 19:00:35 2006
@@ -0,0 +1,26 @@
+/*
+* 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;
+
+public interface RequestHandlerManager {
+
+  RequestHandler getRequestHandler();
+  
+  void release(RequestHandler handler);
+  
+}

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=442792&r1=442791&r2=442792
==============================================================================
--- 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 Tue Sep 12 19:00:35 2006
@@ -17,20 +17,16 @@
 */
 package org.apache.abdera.protocol.server.util;
 
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.Map;
-import java.util.Properties;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import org.apache.abdera.protocol.server.Target;
-import org.apache.abdera.protocol.server.TargetResolver;
+import org.apache.abdera.protocol.server.provider.AbstractTarget;
+import org.apache.abdera.protocol.server.provider.RequestContext;
+import org.apache.abdera.protocol.server.provider.Target;
+import org.apache.abdera.protocol.server.provider.TargetResolver;
+import org.apache.abdera.protocol.server.provider.TargetType;
 
 /**
  * <p>Provides a utility class helpful for determining which type of resource
@@ -42,132 +38,85 @@
  * also specifies the Resource Type.</p>
  * 
  * <pre>
+ *  RequestContext request = ...
  *  RegexTargetResolver tr = new RegexTargetResolver();
- *  tr.setPattern(ResourceType.INTROSPECTION, "/atom");
- *  tr.setPattern(ResourceType.COLLECTION, "/atom/([^/#?]+)");
- *  tr.setPattern(ResourceType.ENTRY, "/atom/([^/#?]+)/([^/#?]+)");
- *  tr.setPattern(ResourceType.ENTRY_EDIT, "/atom/([^/#?]+)/([^/#?]+)\\?edit");
- *  tr.setPattern(ResourceType.MEDIA,"/atom/([^/#?]+)/([^/#?]+)\\?media");
- *  tr.setPattern(ResourceType.MEDIA_EDIT,"/atom/([^/#?]+)/([^/#?]+)\\?edit-media");
+ *  tr.setPattern("/atom",ResourceType.INTROSPECTION);
+ *  tr.setPattern("/atom/([^/#?]+)",ResourceType.COLLECTION);
+ *  tr.setPattern("/atom/([^/#?]+)/([^/#?]+)",ResourceType.ENTRY);
+ *  tr.setPattern("/atom/([^/#?]+)/([^/#?]+)\\?edit",ResourceType.ENTRY_EDIT);
+ *  tr.setPattern("/atom/([^/#?]+)/([^/#?]+)\\?media",ResourceType.MEDIA);
+ *  tr.setPattern("/atom/([^/#?]+)/([^/#?]+)\\?edit-media",ResourceType.MEDIA_EDIT);
  *  
- *  Target target = tr.resolve("/atom/foo");
- *  System.out.println(target.getResourceType());
- *  System.out.println(targer.getValue(1));  // foo
+ *  Target target = tr.resolve(request);
+ *  System.out.println(target.getType());
+ *  System.out.println(targer.getParameter("foo"));
  * </pre>
  *  
  */
-public class RegexTargetResolver implements TargetResolver {
+public class RegexTargetResolver 
+  implements TargetResolver {
 
-  private final Map<ResourceType,Pattern> patterns;
+  private final Map<Pattern, TargetType> patterns;
   
   public RegexTargetResolver() {
-    this.patterns = new HashMap<ResourceType,Pattern>();
+    this.patterns = new HashMap<Pattern, TargetType>();
   }
   
-  public RegexTargetResolver(Map<ResourceType,String> patterns) {
-    this.patterns = new HashMap<ResourceType,Pattern>();
-    for (ResourceType type : patterns.keySet()) {
-      String p = patterns.get(type);
+  public RegexTargetResolver(Map<String, TargetType> patterns) {
+    this.patterns = new HashMap<Pattern, TargetType>();
+    for (String p : patterns.keySet()) {
+      TargetType type = patterns.get(p);
       Pattern pattern = Pattern.compile(p);
-      this.patterns.put(type, pattern);
+      this.patterns.put(pattern,type);
     }
   }
   
-  public RegexTargetResolver(Properties properties) {
-    this.patterns = new HashMap<ResourceType,Pattern>();
-    loadPatterns(properties);
-  }
-  
-  public synchronized void loadPatterns(Properties properties) {
-    this.patterns.clear();
-    for (Object key : properties.keySet()) {
-      String skey = (String) key;
-      String value = properties.getProperty(skey);
-      ResourceType type = ResourceType.getOrCreate(skey);
-      Pattern pattern = Pattern.compile(value);
-      this.patterns.put(type, pattern);
-    }
-  }
-  
-  public synchronized void loadPatterns(InputStream in) throws IOException {
-    Properties properties = new Properties();
-    properties.load(in);
-    loadPatterns(properties);
-  }
-  
-  public synchronized void loadPatterns(String file) throws IOException {
-    loadPatterns(new FileInputStream(file));
-  }
-  
-  public synchronized void setPattern(ResourceType type, String pattern) {
+  public synchronized void setPattern(String pattern, TargetType type) {
     Pattern p = Pattern.compile(pattern);
-    this.patterns.put(type, p);
+    this.patterns.put(p,type);
   }
   
-  public Target resolve(String path_info) {
-    for (ResourceType type : patterns.keySet()) {
-      Pattern pattern = patterns.get(type);
-      Matcher matcher = pattern.matcher(path_info);
-      if (matcher.matches()) return new RegexTarget(type, matcher);
+  public Target resolve(RequestContext request) {
+    String uri = request.getUri().toString();
+    for (Pattern pattern : patterns.keySet()) {
+      Matcher matcher = pattern.matcher(uri);
+      if (matcher.matches()) {
+        TargetType type = patterns.get(pattern);
+        return getTarget(type, request, matcher);
+      }
     }
     return null;
   }
   
-  public static class RegexTarget implements Target {
+  protected Target getTarget(
+    TargetType type, 
+    RequestContext request, 
+    Matcher matcher) {
+      return new RegexTarget(type, request, matcher);
+  }
+  
+  public static class RegexTarget
+    extends AbstractTarget
+    implements Target {
     
     private static final long serialVersionUID = 165211244926064449L;
     transient Matcher matcher;
-    private ResourceType type;
-    
-    RegexTarget(ResourceType type, Matcher matcher) {
-      this.type = type;
-      this.matcher = matcher;
-    }
-    
-    public ResourceType getResourceType() {
-      return this.type;
-    }
     
-    public String getValue(int token) {
-      try {
-        return this.matcher.group(token);
-      } catch (IndexOutOfBoundsException e) {
-        return null;
-      }
+    RegexTarget(
+      TargetType type, 
+      RequestContext context, 
+      Matcher matcher) {
+        super(type, context);
+        this.matcher = matcher;
     }
     
-    public boolean hasValue(int token) {
-      return getValue(token) != null;
-    }
-
-    public Iterator<String> iterator() {
-      return new TargetIterator(this);
-    }
-    
-    private void writeObject(ObjectOutputStream out) 
-      throws IOException {
-        out.defaultWriteObject();
-        out.writeObject(matcher.pattern().pattern());
-        out.writeObject(matcher.group(0));
-    }
-
-    private void readObject(ObjectInputStream in) 
-      throws IOException, 
-             ClassNotFoundException {
-       in.defaultReadObject();
-       String p = (String) in.readObject();
-       String v = (String) in.readObject();
-       Pattern pattern = Pattern.compile(p);
-       matcher = pattern.matcher(v);
-       matcher.matches();
-    }
-
     @Override
     public int hashCode() {
       final int PRIME = 31;
       int result = 1;
       String m = matcher.group(0);
       String p = matcher.pattern().pattern();
+      result = PRIME * result + super.hashCode();
       result = PRIME * result + ((m == null) ? 0 : m.hashCode());
       result = PRIME * result + ((p == null) ? 0 : p.hashCode());
       result = PRIME * result + ((type == null) ? 0 : type.hashCode());
@@ -184,6 +133,7 @@
       String p = matcher.pattern().pattern();
       String m2 = other.matcher.group(0);
       String p2 = other.matcher.pattern().pattern();
+      if (!super.equals(obj)) return false;
       if (m == null) {
         if (m2 != null)
           return false;
@@ -213,20 +163,17 @@
       buf.append("] = ");
       buf.append(type.toString());
       buf.append("\n");
-      int n = -1;
-      while(hasValue(++n)) {
+      String[] params = getParameterNames();
+      for (String param : params) {
         buf.append("    ");
-        buf.append(n);
+        buf.append(param);
         buf.append(" = ");
-        buf.append(getValue(n));
+        buf.append(getParameter(param));
         buf.append("\n");
       }
       return buf.toString();
     }
     
-    public Object clone() throws CloneNotSupportedException {
-      return super.clone();
-    }
   }
   
 }

Modified: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/ServerConstants.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/ServerConstants.java?view=diff&rev=442792&r1=442791&r2=442792
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/ServerConstants.java (original)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/ServerConstants.java Tue Sep 12 19:00:35 2006
@@ -19,26 +19,19 @@
 
 public interface ServerConstants {
 
-  public static final String REQUESTCONTEXT = 
-    "org.apache.abdera.protocol.server.RequestContext";
- 
-  public static final String HANDLER_MANAGER = 
-    "org.apache.abdera.protocol.server.RequestHandlerManager";
+
+  public static final String REQUEST_HANDLER_MANAGER = 
+    "org.apache.abdera.protocol.server.servlet.RequestHandlerManager";
   
-  public static final String PROVIDER_MANAGER = 
-    "org.apache.abdera.protocol.server.ProviderManager";
-  
-  public static final String TARGET_RESOLVER = 
-    "org.apache.abdera.protocol.server.TargetResolver";
+  public static final String PROVIDER_MANAGER =
+    "org.apache.abdera.protocol.server.provider.ProviderManager";
   
   public static final String SUBJECT_RESOLVER = 
-    "org.apache.abdera.protocol.server.SubjectResolver";
+    "org.apache.abdera.protocol.server.auth.SubjectResolver";
   
-  public static final String DEFAULT_SUBJECT_RESOLVER = 
-    "org.apache.abdera.protocol.server.util.SimpleSubjectResolver";
-  
-  public static final String X_OVERRIDE_HEADER = 
-    "X-HTTP-Method-Override";
+  public static final String TARGET_RESOLVER = 
+    "org.apache.abdera.protocol.server.provider.TargetResolver";
   
-  public static final String[] EMPTY = new String[0];
+  public static final String SERVICE_CONTEXT =
+    "org.apache.abdera.protocol.server.ServiceContext";
 }

Modified: incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/SimpleSubjectResolver.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/SimpleSubjectResolver.java?view=diff&rev=442792&r1=442791&r2=442792
==============================================================================
--- incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/SimpleSubjectResolver.java (original)
+++ incubator/abdera/java/trunk/server/src/main/java/org/apache/abdera/protocol/server/util/SimpleSubjectResolver.java Tue Sep 12 19:00:35 2006
@@ -22,7 +22,7 @@
 
 import javax.security.auth.Subject;
 
-import org.apache.abdera.protocol.server.SubjectResolver;
+import org.apache.abdera.protocol.server.auth.SubjectResolver;
 
 public class SimpleSubjectResolver 
   implements SubjectResolver {

Added: incubator/abdera/java/trunk/server/src/test/java/org/apache/abdera/test/server/UtilityTest.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/server/src/test/java/org/apache/abdera/test/server/UtilityTest.java?view=auto&rev=442792
==============================================================================
--- incubator/abdera/java/trunk/server/src/test/java/org/apache/abdera/test/server/UtilityTest.java (added)
+++ incubator/abdera/java/trunk/server/src/test/java/org/apache/abdera/test/server/UtilityTest.java Tue Sep 12 19:00:35 2006
@@ -0,0 +1,166 @@
+/*
+* 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.test.server;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.net.URI;
+import java.security.Principal;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+
+import org.apache.abdera.protocol.EntityTag;
+import org.apache.abdera.protocol.server.ServiceManager;
+import org.apache.abdera.protocol.server.provider.AbstractRequestContext;
+import org.apache.abdera.protocol.server.provider.Target;
+import org.apache.abdera.protocol.server.provider.TargetType;
+import org.apache.abdera.protocol.server.util.RegexTargetResolver;
+import org.apache.abdera.protocol.server.util.SimpleSubjectResolver;
+
+import junit.framework.TestCase;
+
+public class UtilityTest extends TestCase {
+
+  public static void testServiceManager() throws Exception {
+    ServiceManager sm = ServiceManager.getInstance();
+    assertNotNull(sm);
+    assertNotNull(sm.newServiceContext(new HashMap<String,String>()));
+  }
+  
+  public static void testEntityTag() throws Exception {
+    EntityTag etag1 = EntityTag.parse("\"foo\"");
+    assertEquals(etag1.getTag(),"foo");
+    assertFalse(etag1.isWeak());
+    
+    EntityTag etag2 = EntityTag.parse("W/\"foo\"");
+    assertEquals(etag2.getTag(),"foo");
+    assertTrue(etag2.isWeak());
+    
+    assertFalse(EntityTag.matches(etag1, etag2));
+    assertTrue(EntityTag.matches(etag1, etag2, true));
+    
+    EntityTag[] tags = EntityTag.parseTags("\"foo\", W/\"bar\"");
+    assertTrue(EntityTag.matchesAny(etag1, tags));
+    
+    assertTrue(EntityTag.matchesAny("\"bar\"", "\"foo\", W/\"bar\"", true));
+    
+    assertEquals(etag1.toString(), "\"foo\"");
+    assertEquals(etag2.toString(), "W/\"foo\"");
+  }
+  
+  public static void testRegexTargetResolver() throws Exception {
+    
+    RegexTargetResolver r = new RegexTargetResolver();
+    r.setPattern("/test", TargetType.TYPE_SERVICE);
+    r.setPattern("/test/([^/?#]+)", TargetType.TYPE_COLLECTION);
+    
+    DummyRequestContext drc = null;
+    Target target = null;
+    
+    drc = new DummyRequestContext("/test","http://example.org/");
+    target = r.resolve(drc);
+    assertNotNull(target);
+    assertEquals(target.getType(), TargetType.TYPE_SERVICE);
+    
+    drc = new DummyRequestContext("/test/foo","http://example.org/");
+    target = r.resolve(drc);
+    assertNotNull(target);
+    assertEquals(target.getType(), TargetType.TYPE_COLLECTION);
+    
+    drc = new DummyRequestContext("/test/foo/","http://example.org/");
+    target = r.resolve(drc);
+    assertNull(target);
+
+  }
+  
+  public static void testSubjectResolver() throws Exception {
+    DummyRequestContext drc = new DummyRequestContext("/test","http://example.org/");
+    assertNotNull(drc.getSubject());
+  }
+  
+  private static class DummyRequestContext extends AbstractRequestContext {
+
+    protected DummyRequestContext(String request, String base) throws Exception {
+      super(
+        ServiceManager.getInstance().newServiceContext(new HashMap<String,String>()), 
+        "POST", 
+        new URI(request), 
+        new URI(base));
+      
+      subject = context.getSubjectResolver().resolve(
+        (Principal) getProperty(Property.PRINCIPAL));
+    }
+
+    public Object getAttribute(Scope scope, String name) {
+      return null;
+    }
+
+    public String[] getAttributeNames(Scope scope) {
+      return null;
+    }
+
+    public InputStream getInputStream() throws IOException {
+      return null;
+    }
+
+    public String getParameter(String name) {
+      return null;
+    }
+
+    public String[] getParameterNames() {
+      return null;
+    }
+
+    public List<String> getParameters(String name) {
+      return null;
+    }
+
+    public Object getProperty(Property property) {
+      switch (property) {
+        case PRINCIPAL: return SimpleSubjectResolver.ANONYMOUS;
+      }
+      return null;
+    }
+
+    public Reader getReader() throws IOException {
+      return null;
+    }
+
+    public void setAttribute(Scope scope, String name, Object value) {
+    }
+
+    public Date getDateHeader(String name) {
+      return null;
+    }
+
+    public String getHeader(String name) {
+      return null;
+    }
+
+    public String[] getHeaderNames() {
+      return null;
+    }
+
+    public List<String> getHeaders(String name) {
+      return null;
+    }
+    
+  }
+}