Author: aparfonov
Date: 2010-05-12 05:51:45 -0400 (Wed, 12 May 2010)
New Revision: 2367
Added:
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/method/MethodInvokerFactory.java
Modified:
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/RequestDispatcher.java
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ResourceBinder.java
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/method/DefaultMethodInvoker.java
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/resource/AbstractResourceDescriptorImpl.java
Log:
EXOJCR-722 :
Modified:
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/RequestDispatcher.java
===================================================================
---
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/RequestDispatcher.java 2010-05-12
09:02:25 UTC (rev 2366)
+++
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/RequestDispatcher.java 2010-05-12
09:51:45 UTC (rev 2367)
@@ -27,6 +27,7 @@
import org.exoplatform.services.rest.SingletonObjectFactory;
import org.exoplatform.services.rest.impl.header.HeaderHelper;
import org.exoplatform.services.rest.impl.header.MediaTypeHelper;
+import org.exoplatform.services.rest.impl.method.MethodInvokerFactory;
import org.exoplatform.services.rest.impl.resource.AbstractResourceDescriptorImpl;
import org.exoplatform.services.rest.method.MethodInvoker;
import org.exoplatform.services.rest.resource.AbstractResourceDescriptor;
@@ -54,7 +55,7 @@
/**
* Lookup resource which can serve request.
- *
+ *
* @author <a href="mailto:andrew00x@gmail.com">Andrey
Parfonov</a>
* @version $Id: $
*/
@@ -71,19 +72,32 @@
*/
protected final ResourceBinder resourceBinder;
+ private final MethodInvokerFactory invokerFactory;
+
/**
* Constructs new instance of RequestDispatcher.
- *
+ *
* @param resourceBinder See {@link ResourceBinder}
*/
- public RequestDispatcher(ResourceBinder resourceBinder)
+ public RequestDispatcher(ResourceBinder resourceBinder, MethodInvokerFactory
invokerFactory)
{
this.resourceBinder = resourceBinder;
+ this.invokerFactory = invokerFactory;
}
/**
+ * Constructs new instance of RequestDispatcher.
+ *
+ * @param resourceBinder See {@link ResourceBinder}
+ */
+ public RequestDispatcher(ResourceBinder resourceBinder)
+ {
+ this(resourceBinder, null);
+ }
+
+ /**
* Dispatch {@link ContainerRequest} to resource which can serve request.
- *
+ *
* @param request See {@link GenericContainerRequest}
* @param response See {@link GenericContainerResponse}
*/
@@ -114,7 +128,7 @@
/**
* Get last element from path parameters. This element will be used as request
* path for child resources.
- *
+ *
* @param parameterValues See
* {@link ApplicationContextImpl#getParameterValues()}
* @return last element from given list or empty string if last element is
@@ -129,7 +143,7 @@
/**
* Process resource methods, sub-resource methods and sub-resource locators to
* find the best one for serve request.
- *
+ *
* @param request See {@link GenericContainerRequest}
* @param response See {@link GenericContainerResponse}
* @param context See {@link ApplicationContextImpl}
@@ -163,7 +177,9 @@
if (!match)
{
if (LOG.isDebugEnabled())
+ {
LOG.debug("Not found resource method for method " +
request.getMethod());
+ }
return; // Error Response is preset
}
@@ -190,8 +206,10 @@
if (!match && !hasAcceptableLocator)
{
if (LOG.isDebugEnabled())
+ {
LOG.debug("Not found sub-resource methods nor sub-resource locators
for path " + requestPath
+ " and method " + request.getMethod());
+ }
return; // Error Response is preset
}
@@ -219,7 +237,7 @@
/**
* Invoke resource methods.
- *
+ *
* @param rmd See {@link ResourceMethodDescriptor}
* @param resource instance of resource class
* @param context See {@link ApplicationContextImpl}
@@ -241,7 +259,7 @@
/**
* Invoke sub-resource methods.
- *
+ *
* @param requestPath request path
* @param srmd See {@link SubResourceMethodDescriptor}
* @param resource instance of resource class
@@ -269,7 +287,7 @@
/**
* Invoke sub-resource locators.
- *
+ *
* @param requestPath request path
* @param srld See {@link SubResourceLocatorDescriptor}
* @param resource instance of resource class
@@ -295,7 +313,7 @@
MethodInvoker invoker = srld.getMethodInvoker();
resource = invoker.invokeMethod(resource, srld, context);
- AbstractResourceDescriptor descriptor = new
AbstractResourceDescriptorImpl(resource);
+ AbstractResourceDescriptor descriptor = new
AbstractResourceDescriptorImpl(resource, invokerFactory);
SingletonObjectFactory<AbstractResourceDescriptor> locResource =
new SingletonObjectFactory<AbstractResourceDescriptor>(descriptor,
resource);
@@ -313,7 +331,7 @@
* then SubResourceLocatorDescriptor has higher priority. And finally if zero
* was returned then UriPattern is equals, in this case
* SubResourceMethodDescriptor must be selected.
- *
+ *
* @param srmd See {@link SubResourceMethodDescriptor}
* @param srld See {@link SubResourceLocatorDescriptor}
* @return result of comparison sub-resources
@@ -323,14 +341,16 @@
int r = UriPattern.URIPATTERN_COMPARATOR.compare(srmd.getUriPattern(),
srld.getUriPattern());
// NOTE If patterns are the same sub-resource method has priority
if (r == 0)
+ {
return -1;
+ }
return r;
}
/**
* Process result of invoked method, and set {@link Response} parameters
* dependent of returned object.
- *
+ *
* @param o result of invoked method
* @param returnType type of returned object
* @param request See {@link GenericContainerRequest}
@@ -356,7 +376,9 @@
Response r = (Response)o;
// If content-type is not set then add it
if (r.getMetadata().getFirst(HttpHeaders.CONTENT_TYPE) == null &&
r.getEntity() != null)
+ {
r.getMetadata().putSingle(HttpHeaders.CONTENT_TYPE, contentType);
+ }
response.setResponse(r);
@@ -405,7 +427,9 @@
for (T rmd : rmds)
{
if (MediaTypeHelper.isConsume(rmd.consumes(), contentType))
+ {
methods.add(rmd);
+ }
}
}
@@ -444,7 +468,9 @@
{
i.next();
if (n == p)
+ {
break; // get index p in list then stop removing
+ }
}
}
@@ -457,7 +483,7 @@
/**
* Process sub-resource methods.
- *
+ *
* @param srmm See {@link SubResourceLocatorMap}
* @param requestedPath part of requested path
* @param request See {@link GenericContainerRequest}
@@ -479,7 +505,9 @@
{
int len = capturingValues.size();
if (capturingValues.get(len - 1) != null &&
!"/".equals(capturingValues.get(len - 1)))
+ {
continue;
+ }
rmm = e.getValue();
break;
@@ -500,7 +528,9 @@
// for cast, Iterator contains SubResourceMethodDescriptor
Iterator i = l.iterator();
while (i.hasNext())
+ {
methods.add((SubResourceMethodDescriptor)i.next());
+ }
}
return match;
@@ -508,7 +538,7 @@
/**
* Process sub-resource locators.
- *
+ *
* @param srlm See {@link SubResourceLocatorMap}
* @param requestedPath part of requested path
* @param capturingValues the list for keeping template values
@@ -522,18 +552,20 @@
for (Map.Entry<UriPattern, SubResourceLocatorDescriptor> e :
srlm.entrySet())
{
if (e.getKey().match(requestedPath, capturingValues))
+ {
locators.add(e.getValue());
+ }
}
return !locators.isEmpty();
}
-
+
/**
* Get root resource
- *
- * @param parameterValues is taken from context
+ *
+ * @param parameterValues is taken from context
* @param requestPath is taken from context
- * @return root resource
+ * @return root resource
*/
protected ObjectFactory<AbstractResourceDescriptor>
getRootResourse(List<String> parameterValues, String requestPath)
{
@@ -557,7 +589,9 @@
rc.getObjectModel().getSubResourceMethods().size()
+ rc.getObjectModel().getSubResourceLocators().size();
if (subresnum == 0)
+ {
continue;
+ }
}
resourceFactory = rc;
break;
@@ -570,12 +604,16 @@
{
if (LOG.isDebugEnabled())
+ {
LOG.debug("Root resource not found for " + requestPath);
+ }
// Stop here, there is no matched root resource
throw new
WebApplicationException(Response.status(Response.Status.NOT_FOUND).build());
}
else
+ {
return resourceFactory;
+ }
}
}
Modified:
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ResourceBinder.java
===================================================================
---
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ResourceBinder.java 2010-05-12
09:02:25 UTC (rev 2366)
+++
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ResourceBinder.java 2010-05-12
09:51:45 UTC (rev 2367)
@@ -28,6 +28,7 @@
import org.exoplatform.services.rest.RequestFilter;
import org.exoplatform.services.rest.ResponseFilter;
import org.exoplatform.services.rest.SingletonObjectFactory;
+import org.exoplatform.services.rest.impl.method.MethodInvokerFactory;
import org.exoplatform.services.rest.impl.resource.AbstractResourceDescriptorImpl;
import org.exoplatform.services.rest.impl.resource.ResourceDescriptorValidator;
import org.exoplatform.services.rest.method.MethodInvokerFilter;
@@ -54,7 +55,7 @@
/**
* Lookup for root resource eXo container components at startup and
* register/unregister resources via specified methods.
- *
+ *
* @see AbstractResourceDescriptor
* @see SingletonResourceFactory
* @author <a href="mailto:andrew00x@gmail.com">Andrey
Parfonov</a>
@@ -78,7 +79,7 @@
{
/**
* Compare two ResourceClass for order.
- *
+ *
* @param o1 first ResourceClass to be compared
* @param o2 second ResourceClass to be compared
* @return positive , zero or negative dependent of {@link UriPattern}
@@ -112,13 +113,17 @@
*/
protected final RuntimeDelegate rd;
+ private final MethodInvokerFactory invokerFactory;
+
/**
* @param containerContext eXo container context
* @throws Exception if can't set instance of {@link RuntimeDelegate}
*/
@SuppressWarnings("unchecked")
- public ResourceBinder(ExoContainerContext containerContext) throws Exception
+ public ResourceBinder(ExoContainerContext containerContext, MethodInvokerFactory
invokerFactory) throws Exception
{
+ this.invokerFactory = invokerFactory;
+
// Initialize RuntimeDelegate instance
// This is first component in life cycle what needs.
// TODO better solution to initialize RuntimeDelegate
@@ -150,6 +155,11 @@
}
+ public ResourceBinder(ExoContainerContext containerContext) throws Exception
+ {
+ this(containerContext, null);
+ }
+
/**
* @param application Application
* @see Application
@@ -250,7 +260,7 @@
* Register supplied Object as root resource if it has valid JAX-RS
* annotations and no one resource with the same UriPattern already
* registered.
- *
+ *
* @param resource candidate to be root resource
* @return true if resource was bound and false if resource was not bound
* cause it is not root resource
@@ -264,7 +274,7 @@
{
try
{
- descriptor = new AbstractResourceDescriptorImpl(resource);
+ descriptor = new AbstractResourceDescriptorImpl(resource, invokerFactory);
}
catch (Exception e)
{
@@ -335,7 +345,7 @@
{
try
{
- descriptor = new AbstractResourceDescriptorImpl(resourceClass);
+ descriptor = new AbstractResourceDescriptorImpl(resourceClass,
invokerFactory);
}
catch (Exception e)
{
@@ -394,7 +404,7 @@
/**
* Remove root resource of supplied class from root resource collection.
- *
+ *
* @param clazz root resource class
* @return true if resource was unbound false otherwise
*/
@@ -476,7 +486,9 @@
synchronized (rootResources)
{
for (ObjectFactory<AbstractResourceDescriptor> f : rootResources)
+ {
l.add(f.getObjectModel());
+ }
}
return l;
}
Modified:
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/method/DefaultMethodInvoker.java
===================================================================
---
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/method/DefaultMethodInvoker.java 2010-05-12
09:02:25 UTC (rev 2366)
+++
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/method/DefaultMethodInvoker.java 2010-05-12
09:51:45 UTC (rev 2367)
@@ -44,11 +44,11 @@
/**
* Invoker for Resource Method, Sub-Resource Method and SubResource Locator.
- *
+ *
* @author <a href="mailto:andrew00x@gmail.com">Andrey
Parfonov</a>
* @version $Id: $
*/
-public final class DefaultMethodInvoker implements MethodInvoker
+public class DefaultMethodInvoker implements MethodInvoker
{
/**
@@ -86,7 +86,9 @@
Class<?> ac = a.annotationType();
if (ac == MatrixParam.class || ac == QueryParam.class || ac ==
PathParam.class)
+ {
throw new WebApplicationException(e,
Response.status(Response.Status.NOT_FOUND).build());
+ }
throw new WebApplicationException(e,
Response.status(Response.Status.BAD_REQUEST).build());
@@ -98,7 +100,9 @@
InputStream entityStream = context.getContainerRequest().getEntityStream();
if (entityStream == null)
+ {
p[i++] = null;
+ }
else
{
MediaType contentType = context.getContainerRequest().getMediaType();
@@ -110,14 +114,15 @@
if (entityReader == null)
{
if (LOG.isDebugEnabled())
+ {
LOG.warn("Unsupported media type. ");
+ }
throw new
WebApplicationException(Response.status(Response.Status.UNSUPPORTED_MEDIA_TYPE).build());
}
try
{
-
p[i++] =
entityReader.readFrom(mp.getParameterClass(), mp.getGenericType(),
mp.getAnnotations(),
contentType, headers, entityStream);
@@ -126,7 +131,9 @@
{
if (LOG.isDebugEnabled())
+ {
e.printStackTrace();
+ }
throw new InternalException(e);
@@ -135,6 +142,11 @@
}
}
+ return invokeMethod(resource, methodResource, p);
+ }
+
+ protected Object invokeMethod(Object resource, GenericMethodResource methodResource,
Object[] p)
+ {
try
{
return methodResource.getMethod().invoke(resource, p);
@@ -152,12 +164,16 @@
catch (InvocationTargetException invExc)
{
if (LOG.isDebugEnabled())
+ {
invExc.printStackTrace();
+ }
// get cause of exception that method produces
Throwable cause = invExc.getCause();
// if WebApplicationException than it may contain response
if (WebApplicationException.class == cause.getClass())
+ {
throw (WebApplicationException)cause;
+ }
throw new InternalException(cause);
}
Added:
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/method/MethodInvokerFactory.java
===================================================================
---
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/method/MethodInvokerFactory.java
(rev 0)
+++
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/method/MethodInvokerFactory.java 2010-05-12
09:51:45 UTC (rev 2367)
@@ -0,0 +1,36 @@
+/**
+ * Copyright (C) 2010 eXo Platform SAS.
+ *
+ * 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.exoplatform.services.rest.impl.method;
+
+import org.exoplatform.services.rest.method.MethodInvoker;
+
+/**
+ * @author <a href="mailto:andrew00x@gmail.com">Andrey
Parfonov</a>
+ * @version $Id$
+ */
+public interface MethodInvokerFactory
+{
+
+ /**
+ * @return {@link MethodInvoker}
+ */
+ MethodInvoker getMethodInvoker();
+
+}
Property changes on:
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/method/MethodInvokerFactory.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Modified:
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/resource/AbstractResourceDescriptorImpl.java
===================================================================
---
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/resource/AbstractResourceDescriptorImpl.java 2010-05-12
09:02:25 UTC (rev 2366)
+++
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/resource/AbstractResourceDescriptorImpl.java 2010-05-12
09:51:45 UTC (rev 2367)
@@ -18,7 +18,6 @@
*/
package org.exoplatform.services.rest.impl.resource;
-import org.exoplatform.services.rest.impl.MultivaluedMapImpl;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.rest.ComponentLifecycleScope;
@@ -26,11 +25,14 @@
import org.exoplatform.services.rest.FieldInjector;
import org.exoplatform.services.rest.impl.ConstructorDescriptorImpl;
import org.exoplatform.services.rest.impl.FieldInjectorImpl;
+import org.exoplatform.services.rest.impl.MultivaluedMapImpl;
import org.exoplatform.services.rest.impl.header.MediaTypeHelper;
import org.exoplatform.services.rest.impl.method.DefaultMethodInvoker;
+import org.exoplatform.services.rest.impl.method.MethodInvokerFactory;
import org.exoplatform.services.rest.impl.method.MethodParameterImpl;
import org.exoplatform.services.rest.impl.method.OptionsRequestMethodInvoker;
import org.exoplatform.services.rest.impl.method.ParameterHelper;
+import org.exoplatform.services.rest.method.MethodInvoker;
import org.exoplatform.services.rest.method.MethodParameter;
import org.exoplatform.services.rest.resource.AbstractResourceDescriptor;
import org.exoplatform.services.rest.resource.ResourceDescriptorVisitor;
@@ -98,28 +100,28 @@
/**
* Sub-resource methods. Sub-resource method has path annotation.
- *
+ *
* @see SubResourceMethodDescriptor
*/
private final SubResourceMethodMap subResourceMethods;
/**
* Sub-resource locators. Sub-resource locator has path annotation.
- *
+ *
* @see SubResourceLocatorDescriptor
*/
private final SubResourceLocatorMap subResourceLocators;
/**
* Resource methods. Resource method has not own path annotation.
- *
+ *
* @see ResourceMethodDescriptor
*/
private final ResourceMethodMap<ResourceMethodDescriptor> resourceMethods;
/**
* Resource class constructors.
- *
+ *
* @see ConstructorDescriptor
*/
private final List<ConstructorDescriptor> constructors;
@@ -128,32 +130,55 @@
* Resource class fields.
*/
private final List<FieldInjector> fields;
-
+
/**
* Optional data
*/
private MultivaluedMap<String, String> properties;
+ private final MethodInvokerFactory invokerFactory;
+
/**
- * Constructs new instance of AbstractResourceDescriptor without path
- * (sub-resource).
- *
+ * Constructs new instance of AbstractResourceDescriptor.
+ *
* @param resourceClass resource class
+ * @param invokerFactory invoker factory
*/
+ public AbstractResourceDescriptorImpl(Class<?> resourceClass,
MethodInvokerFactory invokerFactory)
+ {
+ this(resourceClass.getAnnotation(Path.class), resourceClass,
ComponentLifecycleScope.PER_REQUEST, invokerFactory);
+ }
+
+ /**
+ * Constructs new instance of AbstractResourceDescriptor.
+ *
+ * @param resource resource instance
+ * @param invokerFactory invoker factory
+ */
+ public AbstractResourceDescriptorImpl(Object resource, MethodInvokerFactory
invokerFactory)
+ {
+ this(resource.getClass().getAnnotation(Path.class), resource.getClass(),
ComponentLifecycleScope.SINGLETON,
+ invokerFactory);
+ }
+
+ /**
+ * Constructs new instance of AbstractResourceDescriptor.
+ *
+ * @param resourceClass resource class
+ */
public AbstractResourceDescriptorImpl(Class<?> resourceClass)
{
- this(resourceClass.getAnnotation(Path.class), resourceClass,
ComponentLifecycleScope.PER_REQUEST);
+ this(resourceClass.getAnnotation(Path.class), resourceClass,
ComponentLifecycleScope.PER_REQUEST, null);
}
/**
- * Constructs new instance of AbstractResourceDescriptor without path
- * (sub-resource).
- *
+ * Constructs new instance of AbstractResourceDescriptor.
+ *
* @param resource resource instance
*/
public AbstractResourceDescriptorImpl(Object resource)
{
- this(resource.getClass().getAnnotation(Path.class), resource.getClass(),
ComponentLifecycleScope.SINGLETON);
+ this(resource.getClass().getAnnotation(Path.class), resource.getClass(),
ComponentLifecycleScope.SINGLETON, null);
}
/**
@@ -162,7 +187,8 @@
* @param scope resource scope
* @see ComponentLifecycleScope
*/
- private AbstractResourceDescriptorImpl(Path path, Class<?> resourceClass,
ComponentLifecycleScope scope)
+ private AbstractResourceDescriptorImpl(Path path, Class<?> resourceClass,
ComponentLifecycleScope scope,
+ MethodInvokerFactory invokerFactory)
{
if (path != null)
{
@@ -210,7 +236,7 @@
if (Modifier.isPublic(modif) || Modifier.isProtected(modif))
{
FieldInjector inj = new FieldInjectorImpl(resourceClass, jfield);
- // Skip not annotated field. They will be not injected from container.
+ // Skip not annotated field. They will be not injected from container.
if (inj.getAnnotation() != null)
{
fields.add(new FieldInjectorImpl(resourceClass, jfield));
@@ -221,6 +247,8 @@
}
}
+ this.invokerFactory = invokerFactory;
+
this.resourceMethods = new ResourceMethodMap<ResourceMethodDescriptor>();
this.subResourceMethods = new SubResourceMethodMap();
this.subResourceLocators = new SubResourceLocatorMap();
@@ -233,7 +261,9 @@
public MultivaluedMap<String, String> getProperties()
{
if (properties == null)
+ {
properties = new MultivaluedMapImpl();
+ }
return properties;
}
@@ -243,10 +273,12 @@
public List<String> getProperty(String key)
{
if (properties != null)
+ {
return properties.get(key);
+ }
return null;
}
-
+
/**
* {@inheritDoc}
*/
@@ -365,13 +397,17 @@
Produces p = getMethodAnnotation(method, resourceClass, Produces.class,
false);
if (p == null)
+ {
p = resourceClass.getAnnotation(Produces.class); // from resource
+ }
// class
List<MediaType> produces = MediaTypeHelper.createProducesList(p);
Consumes c = getMethodAnnotation(method, resourceClass, Consumes.class,
false);
if (c == null)
+ {
c = resourceClass.getAnnotation(Consumes.class); // from resource
+ }
// class
List<MediaType> consumes = MediaTypeHelper.createConsumesList(c);
@@ -380,7 +416,7 @@
// resource method
ResourceMethodDescriptor res =
new ResourceMethodDescriptorImpl(method, httpMethod.value(), params,
this, consumes, produces,
- new DefaultMethodInvoker());
+ getMethodInvoker());
ResourceMethodDescriptor exist =
findMethodResourceMediaType(resourceMethods.getList(httpMethod.value()), res.consumes(),
res
.produces());
@@ -401,11 +437,10 @@
// sub-resource method
SubResourceMethodDescriptor subRes =
new SubResourceMethodDescriptorImpl(new PathValue(subPath.value()),
method, httpMethod.value(),
- params, this, consumes, produces, new DefaultMethodInvoker());
+ params, this, consumes, produces, getMethodInvoker());
SubResourceMethodDescriptor exist = null;
ResourceMethodMap<SubResourceMethodDescriptor> rmm =
-
(ResourceMethodMap<SubResourceMethodDescriptor>)subResourceMethods.getMethodMap(subRes
- .getUriPattern());
+ subResourceMethods.getMethodMap(subRes.getUriPattern());
// rmm is never null, empty map instead
List<SubResourceMethodDescriptor> l =
rmm.getList(httpMethod.value());
@@ -431,7 +466,7 @@
// sub-resource locator
SubResourceLocatorDescriptor loc =
new SubResourceLocatorDescriptorImpl(new PathValue(subPath.value()),
method, params, this,
- new DefaultMethodInvoker());
+ getMethodInvoker());
if (!subResourceLocators.containsKey(loc.getUriPattern()))
{
subResourceLocators.put(loc.getUriPattern(), loc);
@@ -464,12 +499,12 @@
resourceMethods.sort();
subResourceMethods.sort();
- // sub-resource locators already sorted
+ // sub-resource locators already sorted
}
/**
* Create list of {@link MethodParameter} .
- *
+ *
* @param resourceClass class
* @param method See {@link Method}
* @return list of {@link MethodParameter}
@@ -478,7 +513,9 @@
{
Class<?>[] parameterClasses = method.getParameterTypes();
if (parameterClasses.length == 0)
+ {
return java.util.Collections.emptyList();
+ }
Type[] parameterGenTypes = method.getGenericParameterTypes();
Annotation[][] annotations = method.getParameterAnnotations();
@@ -543,8 +580,8 @@
* <p>
* On receipt of a HEAD request an implementation MUST either: 1. Call method
* annotated with request method designation for HEAD or, if none present, 2.
- * Call method annotated with a request method designation GET and discard any
- * returned entity.
+ * Call method annotated with a request method designation GET and discard
+ * any returned entity.
* </p>
*/
protected void resolveHeadRequest()
@@ -552,7 +589,9 @@
List<ResourceMethodDescriptor> getRes = resourceMethods.get(HttpMethod.GET);
if (getRes == null || getRes.size() == 0)
+ {
return; // nothing to do, there is not 'GET' methods
+ }
// If there is no methods for 'HEAD' anyway never return null.
// Instead null empty List will be returned.
@@ -561,15 +600,19 @@
for (ResourceMethodDescriptor rmd : getRes)
{
if (findMethodResourceMediaType(headRes, rmd.consumes(), rmd.produces()) ==
null)
+ {
headRes.add(new ResourceMethodDescriptorImpl(rmd.getMethod(),
HttpMethod.HEAD, rmd.getMethodParameters(),
this, rmd.consumes(), rmd.produces(), rmd.getMethodInvoker()));
+ }
}
for (ResourceMethodMap<SubResourceMethodDescriptor> rmm :
subResourceMethods.values())
{
List<SubResourceMethodDescriptor> getSubres = rmm.get(HttpMethod.GET);
if (getSubres == null || getSubres.size() == 0)
+ {
continue; // nothing to do, there is not 'GET' methods
+ }
// If there is no methods for 'HEAD' anyway never return null.
// Instead null empty List will be returned.
@@ -578,12 +621,12 @@
Iterator<SubResourceMethodDescriptor> i = getSubres.iterator();
while (i.hasNext())
{
- SubResourceMethodDescriptor srmd = (SubResourceMethodDescriptor)i.next();
+ SubResourceMethodDescriptor srmd = i.next();
if (findMethodResourceMediaType(headSubres, srmd.consumes(), srmd.produces())
== null)
{
headSubres.add(new SubResourceMethodDescriptorImpl(srmd.getPathValue(),
srmd.getMethod(),
HttpMethod.HEAD, srmd.getMethodParameters(), this, srmd.consumes(),
srmd.produces(),
- new DefaultMethodInvoker()));
+ getMethodInvoker()));
}
}
}
@@ -610,14 +653,14 @@
o.add(new OptionsRequestResourceMethodDescriptorImpl(null, "OPTIONS",
mps, this, consumes, produces,
new OptionsRequestMethodInvoker()));
}
- // TODO need process sub-resources ?
+ // TODO need process sub-resources ?
}
/**
* Get all method with at least one annotation which has annotation
* <i>annotation</i>. It is useful for annotation {@link
javax.ws.rs.GET},
* etc. All HTTP method annotations has annotation {@link HttpMethod}.
- *
+ *
* @param <T> annotation type
* @param m method
* @param annotation annotation class
@@ -629,7 +672,9 @@
{
T endPoint = null;
if ((endPoint = a.annotationType().getAnnotation(annotation)) != null)
+ {
return endPoint;
+ }
}
return null;
}
@@ -637,13 +682,13 @@
/**
* Tries to get JAX-RS annotation on method from the root resource class's
* superclass or implemented interfaces.
- *
+ *
* @param <T> annotation type
* @param method method for discovering
* @param resourceClass class that contains discovered method
* @param annotationClass annotation type what we are looking for
* @param metaAnnotation false if annotation should be on method and true in
- * method should contain annotations that has supplied annotation
+ * method should contain annotations that has supplied annotation
* @return annotation from class or its ancestor or null if nothing found
*/
protected <T extends Annotation> T getMethodAnnotation(Method method,
Class<?> resourceClass,
@@ -652,9 +697,13 @@
T annotation = null;
if (metaAnnotation)
+ {
annotation = getMetaAnnotation(method, annotationClass);
+ }
else
+ {
annotation = method.getAnnotation(annotationClass);
+ }
if (annotation == null)
{
@@ -694,9 +743,13 @@
if (inhMethod != null)
{
if (metaAnnotation)
+ {
annotation = getMetaAnnotation(inhMethod, annotationClass);
+ }
else
+ {
annotation = inhMethod.getAnnotation(annotationClass);
+ }
}
}
@@ -706,7 +759,7 @@
/**
* Check is collection of {@link ResourceMethodDescriptor} already contains
* ResourceMethodDescriptor with the same media types.
- *
+ *
* @param rmds {@link Set} of {@link ResourceMethodDescriptor}
* @param consumes resource method consumed media type
* @param produces resource method produced media type
@@ -720,9 +773,13 @@
for (T rmd : rmds)
{
if (rmd.consumes().size() != consumes.size())
+ {
return null;
+ }
if (rmd.produces().size() != produces.size())
+ {
return null;
+ }
for (MediaType c1 : rmd.consumes())
{
boolean eq = false;
@@ -735,7 +792,9 @@
}
}
if (!eq)
+ {
return null;
+ }
}
for (MediaType p1 : rmd.produces())
@@ -750,7 +809,9 @@
}
}
if (!eq)
+ {
return null;
+ }
}
matched = rmd; // matched resource method
@@ -760,6 +821,15 @@
return matched;
}
+ protected MethodInvoker getMethodInvoker()
+ {
+ if (invokerFactory != null)
+ {
+ return invokerFactory.getMethodInvoker();
+ }
+ return new DefaultMethodInvoker();
+ }
+
/**
* {@inheritDoc}
*/