Author: heiko.braun(a)jboss.com
Date: 2007-10-31 10:35:27 -0400 (Wed, 31 Oct 2007)
New Revision: 4955
Added:
stack/native/branches/rest/src/main/java/org/jboss/rs/ResourceError.java
stack/native/branches/rest/src/main/java/org/jboss/rs/media/
stack/native/branches/rest/src/main/java/org/jboss/rs/media/ContentNegotiation.java
stack/native/branches/rest/src/main/java/org/jboss/rs/media/DefaultContentNegotiation.java
stack/native/branches/rest/src/main/java/org/jboss/rs/model/ResourceMatch.java
Modified:
stack/native/branches/rest/src/main/java/org/jboss/rs/model/NoMethodException.java
stack/native/branches/rest/src/main/java/org/jboss/rs/model/NoResourceException.java
stack/native/branches/rest/src/main/java/org/jboss/rs/model/ResourceMethod.java
stack/native/branches/rest/src/main/java/org/jboss/rs/model/ResourceModel.java
stack/native/branches/rest/src/main/java/org/jboss/rs/model/ResourceResolver.java
stack/native/branches/rest/src/main/java/org/jboss/rs/runtime/RuntimeContext.java
stack/native/branches/rest/src/main/java/org/jboss/rs/util/Convert.java
stack/native/branches/rest/src/test/java/org/jboss/test/rs/model/ResolverTestCase.java
stack/native/branches/rest/src/test/java/org/jboss/test/rs/model/RunRegex.java
stack/native/branches/rest/src/test/java/org/jboss/test/rs/model/WidgetList.java
Log:
Content negotiation, first cut
Added: stack/native/branches/rest/src/main/java/org/jboss/rs/ResourceError.java
===================================================================
--- stack/native/branches/rest/src/main/java/org/jboss/rs/ResourceError.java
(rev 0)
+++ stack/native/branches/rest/src/main/java/org/jboss/rs/ResourceError.java 2007-10-31
14:35:27 UTC (rev 4955)
@@ -0,0 +1,53 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.rs;
+
+/**
+ * @author Heiko.Braun(a)jboss.com
+ * @version $Revision$
+ */
+public class ResourceError extends Exception
+{
+ public int status;
+
+ public ResourceError(String message)
+ {
+ super(message);
+ }
+
+ public ResourceError(String message, Throwable cause)
+ {
+ super(message, cause);
+ }
+
+ public ResourceError(int status, String message)
+ {
+ super(message);
+ this.status = status;
+ }
+
+ public ResourceError(int status, String message, Throwable cause)
+ {
+ super(message, cause);
+ this.status = status;
+ }
+}
Property changes on:
stack/native/branches/rest/src/main/java/org/jboss/rs/ResourceError.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added:
stack/native/branches/rest/src/main/java/org/jboss/rs/media/ContentNegotiation.java
===================================================================
--- stack/native/branches/rest/src/main/java/org/jboss/rs/media/ContentNegotiation.java
(rev 0)
+++
stack/native/branches/rest/src/main/java/org/jboss/rs/media/ContentNegotiation.java 2007-10-31
14:35:27 UTC (rev 4955)
@@ -0,0 +1,42 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.rs.media;
+
+import org.jboss.rs.model.ResourceMethod;
+import org.jboss.rs.model.ResourceMatch;
+import org.jboss.rs.model.NoMethodException;
+import org.jboss.rs.runtime.RuntimeContext;
+
+import java.util.List;
+
+/**
+ * Matches available resource methods against the runtime context.<br>
+ * Since this is likely to change it can be plugged into the {@link
org.jboss.rs.model.ResourceResolver}.
+ *
+ * @author Heiko.Braun(a)jboss.com
+ * @version $Revision$
+ */
+public interface ContentNegotiation
+{
+ ResourceMethod match(RuntimeContext context,
List<ResourceMatch<ResourceMethod>> candidates)
+ throws NoMethodException;
+}
Property changes on:
stack/native/branches/rest/src/main/java/org/jboss/rs/media/ContentNegotiation.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Added:
stack/native/branches/rest/src/main/java/org/jboss/rs/media/DefaultContentNegotiation.java
===================================================================
---
stack/native/branches/rest/src/main/java/org/jboss/rs/media/DefaultContentNegotiation.java
(rev 0)
+++
stack/native/branches/rest/src/main/java/org/jboss/rs/media/DefaultContentNegotiation.java 2007-10-31
14:35:27 UTC (rev 4955)
@@ -0,0 +1,176 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.rs.media;
+
+import org.jboss.rs.model.ResourceMethod;
+import org.jboss.rs.model.ResourceMatch;
+import org.jboss.rs.model.NoMethodException;
+import org.jboss.rs.runtime.RuntimeContext;
+import org.jboss.rs.MethodHTTP;
+
+import javax.activation.MimeType;
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * Matches resource methods in the following order:
+ * <ol>
+ * <li>Request Method
+ * <li>Input mime-type
+ * <li>Output mime-type
+ * </ol>
+ *
+ * Failure in any of the above steps can result in a {@link
org.jboss.rs.model.NoMethodException}:
+ * <ol>
+ * <li>HTTP 405
+ * <li>HTTP 415
+ * <li>HTTP 406
+ * </ol>
+ *
+ * @see org.jboss.rs.model.ResourceResolver
+ *
+ * @author Heiko.Braun(a)jboss.com
+ * @version $Revision$
+ */
+public class DefaultContentNegotiation implements ContentNegotiation
+{
+
+ public ResourceMethod match(RuntimeContext context,
List<ResourceMatch<ResourceMethod>> candidates)
+ throws NoMethodException
+ {
+ ResourceMethod match = null;
+
+ for(ResourceMatch<ResourceMethod> candiate : candidates)
+ {
+
+ List<ResourceMethod> matches = matchByHTTPMethod(context, candidates);
+ matches = matchByInputMime(context, matches);
+ matches = matchByOutputMime(context, matches);
+
+ // TODO: sort results, requires abstracting of RegexQualifier to a more general
Qualifier
+ match = matches.get(0);
+ }
+
+ return match;
+ }
+
+ /**
+ * Match by request method -> HTTP 405
+ * @param context
+ * @param candidates
+ * @return
+ * @throws NoMethodException
+ */
+ private List<ResourceMethod> matchByHTTPMethod(RuntimeContext context,
List<ResourceMatch<ResourceMethod>> candidates)
+ throws NoMethodException
+ {
+ List<ResourceMethod> matches = new ArrayList<ResourceMethod>();
+
+ for(ResourceMatch<ResourceMethod> candiate : candidates)
+ {
+ if(context.getRequestMethod() == candiate.model.getMethodHTTP())
+ {
+ matches.add(candiate.model);
+ }
+ }
+
+ if(matches.isEmpty())
+ throw new NoMethodException(405, "The request method is not
supported");
+
+ return matches;
+ }
+
+ /**
+ * Match by supported input data format -> HTTP 415
+ * @param context
+ * @param candidates
+ * @return
+ * @throws NoMethodException
+ */
+ private List<ResourceMethod> matchByInputMime(RuntimeContext context,
List<ResourceMethod> candidates)
+ throws NoMethodException
+ {
+ List<ResourceMethod> matches = new ArrayList<ResourceMethod>();
+ MethodHTTP requestMethod = context.getRequestMethod();
+
+ // matching by input mime only works on POST and PUT
+ if(MethodHTTP.POST == requestMethod || MethodHTTP.PUT == requestMethod)
+ {
+ MimeType produceMime = context.getProvideMimeType();
+
+ for(ResourceMethod candiate : candidates)
+ {
+ for(MimeType consumeMime : candiate.getConsumeMimeTypes())
+ {
+ if(consumeMime.match(produceMime))
+ matches.add(candiate);
+ }
+ }
+
+ if(matches.isEmpty())
+ throw new NoMethodException(415, "No consumer for " +
produceMime);
+ }
+ else
+ {
+ // Not matching by input mime
+ matches = candidates;
+ }
+
+ return matches;
+ }
+
+
+ /**
+ * Match by supported output data format -> HTTP 406
+ *
+ * @param context
+ * @param candidates
+ * @return
+ * @throws NoMethodException
+ */
+ private List<ResourceMethod> matchByOutputMime(RuntimeContext context,
List<ResourceMethod> candidates)
+ throws NoMethodException
+ {
+ List<ResourceMethod> matches = new ArrayList<ResourceMethod>();
+ List<MimeType> requestConsumeMimes = context.getConsumeMimeTypes();
+
+ for(ResourceMethod candiate : candidates)
+ {
+ for(MimeType methodProduceMime : candiate.getProduceMimeTypes())
+ {
+ for(MimeType requestConsumeMime : requestConsumeMimes)
+ {
+ if(methodProduceMime.match(requestConsumeMime))
+ matches.add(candiate);
+ }
+ }
+ }
+
+ if(matches.isEmpty())
+ throw new NoMethodException(415, "No producer for " +
requestConsumeMimes);
+
+ return matches;
+ }
+
+
+
+}
Property changes on:
stack/native/branches/rest/src/main/java/org/jboss/rs/media/DefaultContentNegotiation.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified:
stack/native/branches/rest/src/main/java/org/jboss/rs/model/NoMethodException.java
===================================================================
---
stack/native/branches/rest/src/main/java/org/jboss/rs/model/NoMethodException.java 2007-10-31
13:37:22 UTC (rev 4954)
+++
stack/native/branches/rest/src/main/java/org/jboss/rs/model/NoMethodException.java 2007-10-31
14:35:27 UTC (rev 4955)
@@ -21,13 +21,14 @@
*/
package org.jboss.rs.model;
+import org.jboss.rs.ResourceError;
+
/**
* @author Heiko.Braun(a)jboss.com
* @version $Revision$
*/
-public class NoMethodException extends Exception
+public class NoMethodException extends ResourceError
{
-
public NoMethodException(String message)
{
super(message);
@@ -35,6 +36,16 @@
public NoMethodException(String message, Throwable cause)
{
- super(message, cause);
+ super(message, cause);
}
+
+ public NoMethodException(int status, String message)
+ {
+ super(status, message);
+ }
+
+ public NoMethodException(int status, String message, Throwable cause)
+ {
+ super(status, message, cause);
+ }
}
Modified:
stack/native/branches/rest/src/main/java/org/jboss/rs/model/NoResourceException.java
===================================================================
---
stack/native/branches/rest/src/main/java/org/jboss/rs/model/NoResourceException.java 2007-10-31
13:37:22 UTC (rev 4954)
+++
stack/native/branches/rest/src/main/java/org/jboss/rs/model/NoResourceException.java 2007-10-31
14:35:27 UTC (rev 4955)
@@ -21,13 +21,24 @@
*/
package org.jboss.rs.model;
+import org.jboss.rs.ResourceError;
+
/**
* @author Heiko.Braun(a)jboss.com
* @version $Revision$
*/
-public class NoResourceException extends Exception
+public class NoResourceException extends ResourceError
{
+ public NoResourceException(int status, String message)
+ {
+ super(status, message);
+ }
+ public NoResourceException(int status, String message, Throwable cause)
+ {
+ super(status, message, cause);
+ }
+
public NoResourceException(String message)
{
super(message);
Added: stack/native/branches/rest/src/main/java/org/jboss/rs/model/ResourceMatch.java
===================================================================
--- stack/native/branches/rest/src/main/java/org/jboss/rs/model/ResourceMatch.java
(rev 0)
+++
stack/native/branches/rest/src/main/java/org/jboss/rs/model/ResourceMatch.java 2007-10-31
14:35:27 UTC (rev 4955)
@@ -0,0 +1,48 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.rs.model;
+
+/**
+ * @author Heiko.Braun(a)jboss.com
+ * @version $Revision$
+ */
+public class ResourceMatch<T> implements Comparable
+{
+ public final T model;
+ public final RegexQualifier qualifier;
+
+ public ResourceMatch(T model, RegexQualifier weight)
+ {
+ this.model = model;
+ this.qualifier = weight;
+ }
+
+ public int compareTo(Object o)
+ {
+ return qualifier.compareTo(((ResourceMatch<T>)o).qualifier);
+ }
+
+ public String toString()
+ {
+ return "ResourceMatch {model="+model+", weight="+ qualifier
+"}";
+ }
+}
Property changes on:
stack/native/branches/rest/src/main/java/org/jboss/rs/model/ResourceMatch.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: stack/native/branches/rest/src/main/java/org/jboss/rs/model/ResourceMethod.java
===================================================================
---
stack/native/branches/rest/src/main/java/org/jboss/rs/model/ResourceMethod.java 2007-10-31
13:37:22 UTC (rev 4954)
+++
stack/native/branches/rest/src/main/java/org/jboss/rs/model/ResourceMethod.java 2007-10-31
14:35:27 UTC (rev 4955)
@@ -22,8 +22,14 @@
package org.jboss.rs.model;
import org.jboss.rs.MethodHTTP;
+import org.jboss.rs.util.Convert;
+import javax.ws.rs.ConsumeMime;
+import javax.ws.rs.ProduceMime;
+import javax.activation.MimeType;
import java.lang.reflect.Method;
+import java.util.List;
+import java.util.ArrayList;
/**
* @author Heiko.Braun(a)jboss.com
@@ -35,6 +41,9 @@
private String uriTemplate;
private Method invocationTarget;
+ private List<MimeType> consumeMimeTypes = new ArrayList<MimeType>();
+ private List<MimeType> produceMimeTypes = new ArrayList<MimeType>();
+
ResourceMethod(MethodHTTP method, String uriTemplate, Method invocationTarget)
{
this.uriTemplate = uriTemplate;
@@ -63,12 +72,51 @@
return invocationTarget;
}
+
+ public List<MimeType> getConsumeMimeTypes()
+ {
+ return consumeMimeTypes;
+ }
+
+ public List<MimeType> getProduceMimeTypes()
+ {
+ return produceMimeTypes;
+ }
+
void freeze()
{
- initFromUriTemplate(this.uriTemplate);
+ initFromUriTemplate(this.uriTemplate);
+ initMimeTypes();
}
+ private void initMimeTypes()
+ {
+ // In the absence of either of these annotations,
+ // support for any media type (“*/*”) is assumed.
+
+ if(invocationTarget.isAnnotationPresent(ConsumeMime.class))
+ {
+ ConsumeMime cm = invocationTarget.getAnnotation(ConsumeMime.class);
+ consumeMimeTypes.addAll(Convert.annotationToMimeType(cm));
+ }
+ else
+ {
+ consumeMimeTypes.add( Convert.ANY_MIME );
+ }
+
+ if(invocationTarget.isAnnotationPresent(ProduceMime.class))
+ {
+ ProduceMime pm = invocationTarget.getAnnotation(ProduceMime.class);
+ produceMimeTypes.addAll(Convert.annotationToMimeType(pm));
+ }
+ else
+ {
+ produceMimeTypes.add( Convert.ANY_MIME );
+ }
+ }
+
+
public String toString()
{
return "ResourceMethod {"+methodHTTP+"
uri="+uriTemplate+", regex="+regexPattern+"}";
Modified: stack/native/branches/rest/src/main/java/org/jboss/rs/model/ResourceModel.java
===================================================================
---
stack/native/branches/rest/src/main/java/org/jboss/rs/model/ResourceModel.java 2007-10-31
13:37:22 UTC (rev 4954)
+++
stack/native/branches/rest/src/main/java/org/jboss/rs/model/ResourceModel.java 2007-10-31
14:35:27 UTC (rev 4955)
@@ -34,8 +34,7 @@
private String uriTemplate;
private Class invocationTarget;
-
- /*TODO : parse resource methods => no UriTemplate but HttpMethod annotation */
+
private List<ResourceMethod> resourceMethods = new
ArrayList<ResourceMethod>();
private List<ResourceMethod> subResourceMethods = new
ArrayList<ResourceMethod>();
private List<ResourceLocator> resourceLocators = new
ArrayList<ResourceLocator>();
Modified:
stack/native/branches/rest/src/main/java/org/jboss/rs/model/ResourceResolver.java
===================================================================
---
stack/native/branches/rest/src/main/java/org/jboss/rs/model/ResourceResolver.java 2007-10-31
13:37:22 UTC (rev 4954)
+++
stack/native/branches/rest/src/main/java/org/jboss/rs/model/ResourceResolver.java 2007-10-31
14:35:27 UTC (rev 4955)
@@ -21,6 +21,8 @@
*/
package org.jboss.rs.model;
+import org.jboss.rs.media.ContentNegotiation;
+import org.jboss.rs.media.DefaultContentNegotiation;
import org.jboss.rs.runtime.RuntimeContext;
import java.util.ArrayList;
@@ -29,19 +31,34 @@
import java.util.List;
/**
- * Resolves resource methods from runtime context.
+ * Resolves resource methods from {@link
org.jboss.rs.runtime.RuntimeContext#getPath()}.<br>
+ * Once a set a of resource methods is identified, the resolver
+ * delegates to a {@link org.jboss.rs.media.ContentNegotiation} plugin
+ * to do the fine grained media type matching.
*
* @author Heiko.Braun(a)jboss.com
* @version $Revision$
*/
public class ResourceResolver
{
+ // the runtime context
private RuntimeContext context;
+ // pluggable content negotitation
+ private ContentNegotiation connegPlugin;
+
+ /**
+ * Provides a resolver with the default content negotitation.
+ *
+ * @param context the runtime context
+ * @return a configured resource resolver instance
+ */
public static ResourceResolver newInstance(RuntimeContext context)
{
- assert context!=null;
- return new ResourceResolver(context);
+ assert context!=null;
+ ResourceResolver resourceResolver = new ResourceResolver(context);
+ resourceResolver.connegPlugin = new DefaultContentNegotiation();
+ return resourceResolver;
}
private ResourceResolver(RuntimeContext context)
@@ -61,13 +78,13 @@
while(it1.hasNext())
{
ResourceModel model = it1.next();
- RegexQualifier qualifier = model.resolve(context.getUri());
+ RegexQualifier qualifier = model.resolve(context.getPath());
if(qualifier!=null)
includedResources.add( new ResourceMatch(model, qualifier) );
}
if(includedResources.isEmpty())
- throw new NoResourceException("No resource matches URI
'"+context.getUri()+"'");
+ throw new NoResourceException("No resource matches URI
'"+context.getPath()+"'");
Collections.sort(includedResources);
@@ -80,7 +97,7 @@
}
if(null == resourceMethod)
- throw new NoMethodException("No method for URI
'"+context.getUri());
+ throw new NoMethodException("No method for URI
'"+context.getPath());
// gotcha
return resourceMethod;
@@ -94,6 +111,7 @@
* @return
*/
private ResourceMethod dfsResourceMatch(ResourceMatch dfsEntry)
+ throws NoMethodException, NoResourceException
{
ResourceMethod resourceMethod = null;
String nextUriToken = dfsEntry.qualifier.nextUriToken;
@@ -113,6 +131,7 @@
}
private ResourceMatch resolveByLocator(ResourceMatch<ResourceModel>
resourceMatch)
+ throws NoResourceException
{
ResourceMatch match = null;
@@ -136,6 +155,7 @@
}
private ResourceMethod resolveResourceMethod(ResourceMatch<ResourceModel>
methodTarget, String uriToken)
+ throws NoMethodException
{
ResourceMethod match = null;
List<ResourceMatch<ResourceMethod>> matches = new
ArrayList<ResourceMatch<ResourceMethod>>();
@@ -175,48 +195,14 @@
return match;
}
-
- // TODO: error handling and media-type matching
+
private ResourceMethod
contentNegotiation(List<ResourceMatch<ResourceMethod>> matches)
+ throws NoMethodException
{
- ResourceMethod match = null;
- for(ResourceMatch<ResourceMethod> candiate : matches)
- {
- // Match by request method -> HTTP 405
- if(context.getRequestMethod() == candiate.model.getMethodHTTP())
- {
- match = candiate.model;
- break;
- }
-
- // Match by supported input data format -> HTTP 415
-
- // Match by supported output data format -> HTTP 406
-
- }
- return match;
+ assert connegPlugin !=null;
+
+ // delegate to conneg plugin
+ return connegPlugin.match(context, matches);
}
- class ResourceMatch<T> implements Comparable
- {
- final T model;
- final RegexQualifier qualifier;
-
- public ResourceMatch(T model, RegexQualifier weight)
- {
- this.model = model;
- this.qualifier = weight;
- }
-
- public int compareTo(Object o)
- {
- return qualifier.compareTo(((ResourceMatch<T>)o).qualifier);
- }
-
- public String toString()
- {
- return "ResourceMatch {model="+model+", weight="+ qualifier
+"}";
- }
- }
-
}
Modified:
stack/native/branches/rest/src/main/java/org/jboss/rs/runtime/RuntimeContext.java
===================================================================
---
stack/native/branches/rest/src/main/java/org/jboss/rs/runtime/RuntimeContext.java 2007-10-31
13:37:22 UTC (rev 4954)
+++
stack/native/branches/rest/src/main/java/org/jboss/rs/runtime/RuntimeContext.java 2007-10-31
14:35:27 UTC (rev 4955)
@@ -23,7 +23,12 @@
import org.jboss.rs.MethodHTTP;
import org.jboss.rs.model.ResourceModel;
+import org.jboss.rs.util.Convert;
+import javax.activation.MimeType;
+import javax.activation.MimeTypeParseException;
+import java.net.URI;
+import java.util.ArrayList;
import java.util.List;
/**
@@ -32,14 +37,22 @@
*/
public class RuntimeContext
{
+ // Request method
private MethodHTTP requestMethod;
+
+ // Request URI
+ private URI uri;
+
+ // Accepted response body mime types
+ private List<MimeType> consumeMimeTypes = new ArrayList<MimeType>();
+
+ // Request body content-type, available with POST or PUT requests
+ private MimeType provideMimeType;
+
+ // The associated runtime model for a web context
private List<ResourceModel> rootResources;
- private String uri;
- private Object requestMediaType;
- private Object responseMediaType;
-
- public RuntimeContext(MethodHTTP requestMethod, String uri, List<ResourceModel>
rootResources)
+ public RuntimeContext(MethodHTTP requestMethod, URI uri, List<ResourceModel>
rootResources)
{
this.requestMethod = requestMethod;
this.rootResources = rootResources;
@@ -57,8 +70,47 @@
return rootResources;
}
- public String getUri()
+ public void parseAcceptHeader(String headerValue)
{
- return uri;
+ consumeMimeTypes.addAll( Convert.mimeStringToMimeTypes(headerValue) );
}
+
+ public void parseContentTypeHeader(String headerValue)
+ {
+ try
+ {
+ this.provideMimeType = new MimeType(headerValue);
+ }
+ catch (MimeTypeParseException e)
+ {
+ throw new IllegalArgumentException("Failed to parse 'Content-Type'
header", e);
+ }
+ }
+
+ public List<MimeType> getConsumeMimeTypes()
+ {
+ return consumeMimeTypes;
+ }
+
+
+ public MimeType getProvideMimeType()
+ {
+ if(! (requestMethod == MethodHTTP.POST) )
+ throw new IllegalArgumentException(requestMethod + " does not provide a
'Content-Type header'");
+
+ assert provideMimeType !=null;
+
+ return provideMimeType;
+ }
+
+ /**
+ * @return the path info of the associated URI.
+ */
+ public String getPath()
+ {
+ String path = uri.getPath();
+ if(path.startsWith("/"))
+ path = path.substring(1);
+ return path;
+ }
}
Modified: stack/native/branches/rest/src/main/java/org/jboss/rs/util/Convert.java
===================================================================
--- stack/native/branches/rest/src/main/java/org/jboss/rs/util/Convert.java 2007-10-31
13:37:22 UTC (rev 4954)
+++ stack/native/branches/rest/src/main/java/org/jboss/rs/util/Convert.java 2007-10-31
14:35:27 UTC (rev 4955)
@@ -27,7 +27,14 @@
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.DELETE;
+import javax.ws.rs.ConsumeMime;
+import javax.ws.rs.ProduceMime;
+import javax.activation.MimeType;
+import javax.activation.MimeTypeParseException;
import java.lang.annotation.Annotation;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.StringTokenizer;
/**
* @author Heiko.Braun(a)jboss.com
@@ -37,6 +44,20 @@
{
public static Class[] REQUEST_TYPES = new Class[] { GET.class, POST.class, PUT.class,
DELETE.class };
+ public static MimeType ANY_MIME;
+
+ static
+ {
+ try
+ {
+ ANY_MIME = new MimeType("*/*");
+ }
+ catch (MimeTypeParseException e)
+ {
+ //
+ }
+ }
+
public static MethodHTTP annotationToMethodHTTP(Annotation a)
{
MethodHTTP m = null;
@@ -53,4 +74,54 @@
return m;
}
+
+ public static List<MimeType> annotationToMimeType(ConsumeMime consumeMime)
+ {
+ return mimeStringsToMimeTypes(consumeMime.value());
+ }
+
+ public static List<MimeType> annotationToMimeType(ProduceMime produceMime)
+ {
+ return mimeStringsToMimeTypes(produceMime.value());
+ }
+
+ public static List<MimeType> mimeStringToMimeTypes(String mime)
+ {
+ List<MimeType> mimes = new ArrayList<MimeType>();
+
+ try
+ {
+ StringTokenizer tokenizer = new StringTokenizer(mime, ",");
+ while(tokenizer.hasMoreTokens())
+ {
+ String tok = tokenizer.nextToken().trim();
+ mimes.add( new MimeType(tok) );
+ }
+ }
+ catch (MimeTypeParseException e)
+ {
+ throw new IllegalArgumentException("Failed to parse mime string
'"+mime+"'", e);
+ }
+
+ return mimes;
+ }
+
+ public static List<MimeType> mimeStringsToMimeTypes(String[] mimeStrings)
+ {
+ List<MimeType> mimes = new ArrayList<MimeType>();
+
+ try
+ {
+ for(String s : mimeStrings)
+ {
+ mimes.add( new MimeType(s) );
+ }
+ }
+ catch (MimeTypeParseException e)
+ {
+ throw new IllegalArgumentException("Failed to parse mime string
'"+mimeStrings+"'", e);
+ }
+
+ return mimes;
+ }
}
Modified:
stack/native/branches/rest/src/test/java/org/jboss/test/rs/model/ResolverTestCase.java
===================================================================
---
stack/native/branches/rest/src/test/java/org/jboss/test/rs/model/ResolverTestCase.java 2007-10-31
13:37:22 UTC (rev 4954)
+++
stack/native/branches/rest/src/test/java/org/jboss/test/rs/model/ResolverTestCase.java 2007-10-31
14:35:27 UTC (rev 4955)
@@ -32,6 +32,7 @@
import java.util.List;
import java.lang.reflect.Method;
+import java.net.URI;
/**
* @author Heiko.Braun(a)jboss.com
@@ -53,7 +54,8 @@
public void testRegexResolver1() throws Exception
{
- RuntimeContext context = new RuntimeContext(MethodHTTP.GET,
"widgets/Id/spec", rootModels );
+ URI uri = new
URI("http://jboss.com/widgets/Id/spec");
+ RuntimeContext context = defaultRuntimeContext(MethodHTTP.GET, uri);
ResourceResolver resolver = ResourceResolver.newInstance(context);
ResourceMethod method = resolver.resolve();
@@ -63,7 +65,10 @@
public void testRegexResolver2() throws Exception
{
- RuntimeContext context = new RuntimeContext(MethodHTTP.POST,
"widgets/special", rootModels );
+ URI uri = new
URI("http://jboss.com/widgets/special");
+ RuntimeContext context = defaultRuntimeContext(MethodHTTP.POST, uri);
+ context.parseContentTypeHeader("text/xml");
+
ResourceResolver resolver = ResourceResolver.newInstance(context);
ResourceMethod method = resolver.resolve();
@@ -74,37 +79,47 @@
public void testRegexResolver3() throws Exception
{
- RuntimeContext context = new RuntimeContext(MethodHTTP.GET,
"widgets/offers", rootModels );
+ URI uri = new
URI("http://jboss.com/widgets/offers");
+ RuntimeContext context = defaultRuntimeContext(MethodHTTP.GET, uri);
ResourceResolver resolver = ResourceResolver.newInstance(context);
ResourceMethod method = resolver.resolve();
assertNotNull(method);
- assertEquals("offers", method.getUriTemplate());
+ assertEquals("offers", method.getUriTemplate());
}
public void testRegexResolver4() throws Exception
{
- RuntimeContext context = new RuntimeContext(MethodHTTP.GET,
"widgets/Id/spec/SpecName", rootModels );
+ URI uri = new
URI("http://jboss.com/widgets/Id/spec/SpecName");
+ RuntimeContext context = defaultRuntimeContext(MethodHTTP.GET, uri);
ResourceResolver resolver = ResourceResolver.newInstance(context);
ResourceMethod method = resolver.resolve();
- assertNotNull(method);
- assertEquals("spec/{name}", method.getUriTemplate());
+ assertNotNull(method);
+ assertEquals("spec/{name}", method.getUriTemplate());
}
- public void testRegexResolver5() throws Exception
+ public void testRegexResolver5() throws Exception
{
- RuntimeContext context = new RuntimeContext(MethodHTTP.GET, "widgets",
rootModels );
+ URI uri = new
URI("http://jboss.com/widgets");
+ RuntimeContext context = defaultRuntimeContext(MethodHTTP.GET, uri);
ResourceResolver resolver = ResourceResolver.newInstance(context);
ResourceMethod method = resolver.resolve();
- assertNotNull(method);
+ assertNotNull(method);
Method target = method.getInvocationTarget();
String result = (String)target.invoke( target.getDeclaringClass().newInstance());
assertEquals("A widgetlist", result);
}
+ private RuntimeContext defaultRuntimeContext(MethodHTTP method, URI uri)
+ {
+ RuntimeContext context = new RuntimeContext(method, uri, rootModels );
+ context.parseAcceptHeader("*/*");
+ return context;
+ }
+
}
Modified: stack/native/branches/rest/src/test/java/org/jboss/test/rs/model/RunRegex.java
===================================================================
---
stack/native/branches/rest/src/test/java/org/jboss/test/rs/model/RunRegex.java 2007-10-31
13:37:22 UTC (rev 4954)
+++
stack/native/branches/rest/src/test/java/org/jboss/test/rs/model/RunRegex.java 2007-10-31
14:35:27 UTC (rev 4955)
@@ -23,6 +23,7 @@
import java.util.regex.Pattern;
import java.util.regex.Matcher;
+import java.net.URI;
/**
* @author Heiko.Braun(a)jboss.com
@@ -30,8 +31,12 @@
*/
public class RunRegex
{
- public static void main(String[] args)
+ public static void main(String[] args) throws Exception
{
+
+ URI uri = new
URI("http://jboss.com/widgets/special");
+ System.out.println(uri.getPath());
+
String s = "spec";
System.out.println("> " +s);
Pattern p = Pattern.compile("(\\bspec\\b)(.*?)(/)?");
Modified:
stack/native/branches/rest/src/test/java/org/jboss/test/rs/model/WidgetList.java
===================================================================
---
stack/native/branches/rest/src/test/java/org/jboss/test/rs/model/WidgetList.java 2007-10-31
13:37:22 UTC (rev 4954)
+++
stack/native/branches/rest/src/test/java/org/jboss/test/rs/model/WidgetList.java 2007-10-31
14:35:27 UTC (rev 4955)
@@ -25,6 +25,7 @@
import javax.ws.rs.UriParam;
import javax.ws.rs.UriTemplate;
import javax.ws.rs.POST;
+import javax.ws.rs.ConsumeMime;
@UriTemplate("widgets")
public class WidgetList
@@ -42,8 +43,9 @@
@POST
@UriTemplate("special")
- void getDiscounted(Widget special) {
-
+ @ConsumeMime({"text/xml", "application/xml"})
+ void setDiscounted(Widget special) {
+ // TODO: Should return a new location
}
@UriTemplate("{id}")