[exo-jcr-commits] exo-jcr SVN: r3375 - in ws/trunk: exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl and 10 other directories.
do-not-reply at jboss.org
do-not-reply at jboss.org
Tue Nov 2 04:56:58 EDT 2010
Author: aparfonov
Date: 2010-11-02 04:56:55 -0400 (Tue, 02 Nov 2010)
New Revision: 3375
Added:
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ApplicationProviders.java
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ApplicationRegistry.java
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ProvidersRegistry.java
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/StartableApplication.java
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/resource/ApplicationResource.java
Modified:
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/ApplicationContext.java
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ApplicationContextImpl.java
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ProviderBinder.java
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/RequestHandlerImpl.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/provider/JAXBContextResolver.java
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/provider/JAXBElementEntityProvider.java
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/provider/JAXBObjectEntityProvider.java
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/resources/conf/portal/configuration.xml
ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/BaseTest.java
ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/impl/VariantsHandlerTest.java
ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/impl/provider/OtherEntityTest.java
ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/impl/provider/SourceEntityProviderTest.java
ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/impl/resource/ApplicationTest.java
ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/wadl/WadlProcessorTest.java
ws/trunk/exo.ws.rest.core/src/test/resources/conf/standalone/test-configuration.xml
ws/trunk/exo.ws.rest.ext/src/test/resources/conf/standalone/test-configuration.xml
Log:
EXOJCR-1024
Modified: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/ApplicationContext.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/ApplicationContext.java 2010-11-02 08:53:25 UTC (rev 3374)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/ApplicationContext.java 2010-11-02 08:56:55 UTC (rev 3375)
@@ -31,9 +31,9 @@
import javax.ws.rs.ext.Providers;
/**
- * Provides access to ContainerRequest, ContainerResponse and request URI
- * information.
- *
+ * Provides access to ContainerRequest, ContainerResponse and other context
+ * information information.
+ *
* @author <a href="mailto:andrew00x at gmail.com">Andrey Parfonov</a>
* @version $Id: $
*/
@@ -41,19 +41,20 @@
{
/**
- * Should be used to pass template values in context by using returned list in
- * matching to @see
- * {@link org.exoplatform.services.rest.uri.UriPattern#match(String, List)}
- * . List will be cleared during matching.
- *
+ * Should be used to pass template values in context by using returned list
+ * in matching at
+ * {@link org.exoplatform.services.rest.uri.UriPattern#match(String, List)} .
+ * List will be cleared during matching.
+ *
* @return the list for template values
*/
List<String> getParameterValues();
/**
- * Pass in context list of path template parameters @see {@link UriPattern}.
- *
+ * Pass in context list of path template parameters .
+ *
* @param parameterNames list of templates parameters
+ * @see UriPattern
*/
void setParameterNames(List<String> parameterNames);
@@ -64,9 +65,9 @@
* the root resource last.
* </p>
* So add each new resource at the begin of list.
- *
+ *
* @param resource the resource e. g. resource class, sub-resource method or
- * sub-resource locator.
+ * sub-resource locator
*/
void addMatchedResource(Object resource);
@@ -77,9 +78,9 @@
* resource URI last.
* </p>
* So add each new URI at the begin of list.
- *
- * @param uri the partial part of that matched to resource class, sub-resource
- * method or sub-resource locator.
+ *
+ * @param uri the partial part of that matched to resource class,
+ * sub-resource method or sub-resource locator
*/
void addMatchedURI(String uri);
@@ -89,43 +90,49 @@
Map<String, Object> getAttributes();
/**
- * @return See {@link Request}
+ * @return request
+ * @see Request
*/
Request getRequest();
/**
- * @return See {@link HttpHeaders}
+ * @return request HTTP headers
+ * @see HttpHeaders
*/
HttpHeaders getHttpHeaders();
-
-
+
/**
- * @return {@link InitialProperties}
+ * @return properties
+ * @see InitialProperties
*/
InitialProperties getInitialProperties();
/**
- * @return See {@link SecurityContext}
+ * @return security context
+ * @see SecurityContext
*/
SecurityContext getSecurityContext();
/**
- * @return See {@link GenericContainerRequest}
+ * @return JAX-RS request
+ * @see GenericContainerRequest
*/
GenericContainerRequest getContainerRequest();
/**
- * @return See {@link UriInfo}
+ * @return URI info
+ * @see UriInfo
*/
UriInfo getUriInfo();
/**
- * @return See {@link GenericContainerResponse}
+ * @return JAX-RS request
+ * @see GenericContainerResponse
*/
GenericContainerResponse getContainerResponse();
/**
- * @return {@link ProviderBinder}
+ * @return set of providers
* @see Providers
*/
ProviderBinder getProviders();
Modified: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ApplicationContextImpl.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ApplicationContextImpl.java 2010-11-02 08:53:25 UTC (rev 3374)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ApplicationContextImpl.java 2010-11-02 08:56:55 UTC (rev 3375)
@@ -51,21 +51,21 @@
private static ThreadLocal<ApplicationContext> current = new ThreadLocal<ApplicationContext>();
/**
- * Set ApplicationContext for current thread.
- *
- * @param context the ApplicationContext.
+ * @return current ApplicationContext.
*/
- public static void setCurrent(ApplicationContext context)
+ public static ApplicationContext getCurrent()
{
- current.set(context);
+ return current.get();
}
/**
- * @return current ApplicationContext.
+ * Set ApplicationContext for current thread.
+ *
+ * @param context the ApplicationContext.
*/
- public static ApplicationContext getCurrent()
+ public static void setCurrent(ApplicationContext context)
{
- return current.get();
+ current.set(context);
}
/**
@@ -92,13 +92,18 @@
* Mutable runtime attributes.
*/
private Map<String, Object> attributes;
-
+
/**
* Properties.
*/
private Map<String, String> properties;
/**
+ * Providers.
+ */
+ protected ProviderBinder providers;
+
+ /**
* See {@link GenericContainerRequest}.
*/
protected GenericContainerRequest request;
@@ -109,217 +114,156 @@
protected GenericContainerResponse response;
/**
- * Providers.
+ * Absolute path, full requested URI without query string and fragment.
*/
- protected ProviderBinder providers;
+ private URI absolutePath;
/**
- * Constructs new instance of ApplicationContext.
- *
- * @param request See {@link GenricContainerRequest}
- * @param response See {@link GenericContainerResponse}
- * @param providers See {@link ProviderBinder}
+ * Decoded relative path.
*/
- public ApplicationContextImpl(GenericContainerRequest request, GenericContainerResponse response,
- ProviderBinder providers)
- {
- this.request = request;
- this.response = response;
- this.providers = providers;
- }
+ private String path;
/**
- * {@inheritDoc}
+ * Not decoded relative path.
*/
- public List<String> getParameterValues()
- {
- return parameterValues;
- }
+ private String encodedPath;
/**
- * {@inheritDoc}
+ * Not decoded path template parameters.
*/
- public void setParameterNames(List<String> parameterNames)
- {
- if (encodedPathParameters == null)
- encodedPathParameters = new MultivaluedMapImpl();
+ private MultivaluedMap<String, String> encodedPathParameters;
- for (int i = 0; i < parameterNames.size(); i++)
- encodedPathParameters.add(parameterNames.get(i), parameterValues.get(i));
+ /**
+ * Decoded path template parameters.
+ */
+ private MultivaluedMap<String, String> pathParameters;
- }
+ /**
+ * List of not decoded path segments.
+ */
+ private List<PathSegment> encodedPathSegments;
/**
- * {@inheritDoc}
+ * Decoded path segments.
*/
- public void addMatchedResource(Object resource)
- {
- matchedResources.add(0, resource);
- }
+ private List<PathSegment> pathSegments;
/**
- * {@inheritDoc}
+ * Not decoded query parameters.
*/
- public void addMatchedURI(String uri)
- {
- encodedMatchedURIs.add(0, uri);
- matchedURIs.add(0, UriComponent.decode(uri, UriComponent.PATH_SEGMENT));
- }
+ private MultivaluedMap<String, String> encodedQueryParameters;
/**
- * {@inheritDoc}
+ * Decoded query parameters.
*/
- public Map<String, Object> getAttributes()
- {
- return attributes == null ? attributes = new HashMap<String, Object>() : attributes;
- }
+ private MultivaluedMap<String, String> queryParameters;
/**
- * {@inheritDoc}
+ * Constructs new instance of ApplicationContext.
+ *
+ * @param request See {@link GenricContainerRequest}
+ * @param response See {@link GenericContainerResponse}
+ * @param providerBinder
*/
- public Request getRequest()
+ public ApplicationContextImpl(GenericContainerRequest request, GenericContainerResponse response,
+ ProviderBinder providers)
{
- return request;
+ this.request = request;
+ this.response = response;
+ this.providers = providers;
}
/**
* {@inheritDoc}
*/
- public HttpHeaders getHttpHeaders()
+ public void addMatchedResource(Object resource)
{
- return request;
+ matchedResources.add(0, resource);
}
-
+
/**
* {@inheritDoc}
*/
- public InitialProperties getInitialProperties()
+ public void addMatchedURI(String uri)
{
- return this;
+ encodedMatchedURIs.add(0, uri);
+ matchedURIs.add(0, UriComponent.decode(uri, UriComponent.PATH_SEGMENT));
}
/**
* {@inheritDoc}
*/
- public SecurityContext getSecurityContext()
+ public URI getAbsolutePath()
{
- return request;
+ if (absolutePath != null)
+ {
+ return absolutePath;
+ }
+ return absolutePath = getRequestUriBuilder().replaceQuery(null).fragment(null).build();
}
/**
* {@inheritDoc}
*/
- public GenericContainerRequest getContainerRequest()
+ public UriBuilder getAbsolutePathBuilder()
{
- return request;
+ return UriBuilder.fromUri(getAbsolutePath());
}
/**
* {@inheritDoc}
*/
- public UriInfo getUriInfo()
+ public Map<String, Object> getAttributes()
{
- return this;
+ return attributes == null ? attributes = new HashMap<String, Object>() : attributes;
}
/**
* {@inheritDoc}
*/
- public GenericContainerResponse getContainerResponse()
+ public URI getBaseUri()
{
- return response;
+ return request.getBaseUri();
}
-
- // InitialProperties
/**
* {@inheritDoc}
*/
- public Map<String, String> getProperties()
+ public UriBuilder getBaseUriBuilder()
{
- return properties == null ? properties = new HashMap<String, String>() : properties;
+ return UriBuilder.fromUri(getBaseUri());
}
/**
* {@inheritDoc}
*/
- public String getProperty(String name)
+ public GenericContainerRequest getContainerRequest()
{
- return getProperties().get(name);
+ return request;
}
/**
* {@inheritDoc}
*/
- public void setProperty(String name, String value)
+ public GenericContainerResponse getContainerResponse()
{
- getProperties().put(name, value);
+ return response;
}
- // UriInfo
-
/**
- * Absolute path, full requested URI without query string and fragment.
- */
- private URI absolutePath;
-
- /**
- * Decoded relative path.
- */
- private String path;
-
- /**
- * Not decoded relative path.
- */
- private String encodedPath;
-
- /**
- * Not decoded path template parameters.
- */
- private MultivaluedMap<String, String> encodedPathParameters;
-
- /**
- * Decoded path template parameters.
- */
- private MultivaluedMap<String, String> pathParameters;
-
- /**
- * List of not decoded path segments.
- */
- private List<PathSegment> encodedPathSegments;
-
- /**
- * Decoded path segments.
- */
- private List<PathSegment> pathSegments;
-
- /**
- * Not decoded query parameters.
- */
- private MultivaluedMap<String, String> encodedQueryParameters;
-
- /**
- * Decoded query parameters.
- */
- private MultivaluedMap<String, String> queryParameters;
-
- /**
* {@inheritDoc}
*/
- public URI getAbsolutePath()
+ public HttpHeaders getHttpHeaders()
{
- if (absolutePath != null)
- return absolutePath;
-
- return absolutePath = getRequestUriBuilder().replaceQuery(null).fragment(null).build();
+ return request;
}
/**
* {@inheritDoc}
*/
- public UriBuilder getAbsolutePathBuilder()
+ public InitialProperties getInitialProperties()
{
- return UriBuilder.fromUri(getAbsolutePath());
+ return this;
}
/**
@@ -349,22 +293,14 @@
/**
* {@inheritDoc}
*/
- public URI getBaseUri()
+ public List<String> getParameterValues()
{
- return request.getBaseUri();
+ return parameterValues;
}
/**
* {@inheritDoc}
*/
- public UriBuilder getBaseUriBuilder()
- {
- return UriBuilder.fromUri(getBaseUri());
- }
-
- /**
- * {@inheritDoc}
- */
public String getPath()
{
return getPath(true);
@@ -376,17 +312,17 @@
public String getPath(boolean decode)
{
if (encodedPath == null)
+ {
encodedPath = getAbsolutePath().getRawPath().substring(getBaseUri().getRawPath().length());
-
+ }
if (decode)
{
if (path != null)
+ {
return path;
-
+ }
return path = UriComponent.decode(encodedPath, UriComponent.PATH);
-
}
-
return encodedPath;
}
@@ -404,15 +340,15 @@
public MultivaluedMap<String, String> getPathParameters(boolean decode)
{
if (encodedPathParameters == null)
+ {
throw new IllegalStateException("Path template variables not initialized yet.");
-
+ }
if (decode)
{
if (pathParameters == null)
{
pathParameters = new MultivaluedMapImpl();
}
-
if (pathParameters.size() != encodedPathParameters.size())
{
for (String key : encodedPathParameters.keySet())
@@ -426,7 +362,6 @@
}
return pathParameters;
}
-
return encodedPathParameters;
}
@@ -454,6 +389,30 @@
/**
* {@inheritDoc}
*/
+ public Map<String, String> getProperties()
+ {
+ return properties == null ? properties = new HashMap<String, String>() : properties;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getProperty(String name)
+ {
+ return getProperties().get(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ProviderBinder getProviders()
+ {
+ return providers;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public MultivaluedMap<String, String> getQueryParameters()
{
return getQueryParameters(true);
@@ -465,8 +424,10 @@
public MultivaluedMap<String, String> getQueryParameters(boolean decode)
{
if (decode)
+ {
return queryParameters != null ? queryParameters : (queryParameters =
UriComponent.parseQueryString(getRequestUri().getRawQuery(), true));
+ }
return encodedQueryParameters != null ? encodedQueryParameters : (encodedQueryParameters =
UriComponent.parseQueryString(getRequestUri().getRawQuery(), false));
}
@@ -474,6 +435,14 @@
/**
* {@inheritDoc}
*/
+ public Request getRequest()
+ {
+ return request;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public URI getRequestUri()
{
return request.getRequestUri();
@@ -490,9 +459,49 @@
/**
* {@inheritDoc}
*/
- public ProviderBinder getProviders()
+ public SecurityContext getSecurityContext()
{
- return providers;
+ return request;
}
+ /**
+ * {@inheritDoc}
+ */
+ public UriInfo getUriInfo()
+ {
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setParameterNames(List<String> parameterNames)
+ {
+ if (encodedPathParameters == null)
+ {
+ encodedPathParameters = new MultivaluedMapImpl();
+ }
+ for (int i = 0; i < parameterNames.size(); i++)
+ {
+ encodedPathParameters.add(parameterNames.get(i), parameterValues.get(i));
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setProperty(String name, String value)
+ {
+ getProperties().put(name, value);
+ }
+
+ /**
+ * @param providers providers
+ * @see javax.ws.rs.ext.Providers
+ */
+ public void setProviders(ProviderBinder providers)
+ {
+ this.providers = providers;
+ }
+
}
Added: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ApplicationProviders.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ApplicationProviders.java (rev 0)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ApplicationProviders.java 2010-11-02 08:56:55 UTC (rev 3375)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2009 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;
+
+/**
+ * Application specific set of providers. Providers which were delivered via
+ * subclass of javax.ws.rs.core.Application will have an advantage over default
+ * providers. Default (embedded in this framework) providers will be in use only
+ * if JAX-RS application does not provide own providers with same purposes.
+ *
+ * @author <a href="andrew00x at gmail.com">Andrey Parfonov</a>
+ * @version $Id$
+ */
+public class ApplicationProviders extends ProviderBinder
+{
+
+ private final String applicationId;
+
+ public ApplicationProviders(String applicationId)
+ {
+ this.applicationId = applicationId;
+ }
+
+ /**
+ * @return identifier (suppose to use FQN) of application-supplied subclass
+ * of {@link javax.ws.rs.core.Application} via this set of JAX-RS
+ * providers were delivered.
+ */
+ public String getApplication()
+ {
+ return applicationId;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void init()
+ {
+ }
+
+}
Property changes on: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ApplicationProviders.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ApplicationRegistry.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ApplicationRegistry.java (rev 0)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ApplicationRegistry.java 2010-11-02 08:56:55 UTC (rev 3375)
@@ -0,0 +1,171 @@
+/**
+ * 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;
+
+import org.exoplatform.container.ExoContainer;
+import org.exoplatform.container.ExoContainerContext;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+import org.exoplatform.services.rest.Filter;
+import org.exoplatform.services.rest.PerRequestObjectFactory;
+import org.exoplatform.services.rest.RequestFilter;
+import org.exoplatform.services.rest.ResponseFilter;
+import org.exoplatform.services.rest.SingletonObjectFactory;
+import org.exoplatform.services.rest.impl.resource.ApplicationResource;
+import org.exoplatform.services.rest.impl.resource.ResourceDescriptorValidator;
+import org.exoplatform.services.rest.method.MethodInvokerFilter;
+import org.exoplatform.services.rest.resource.AbstractResourceDescriptor;
+import org.picocontainer.Startable;
+
+import java.util.List;
+
+import javax.ws.rs.Path;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.ext.ContextResolver;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.MessageBodyReader;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.ws.rs.ext.Provider;
+
+/**
+ * Purpose of this class is to get all subclasses of
+ * {@link javax.ws.rs.core.Application} from eXo container and to process set of
+ * object of classes provided by it as JAX-RS components.
+ *
+ * @author <a href="mailto:andrew00x at gmail.com">Andrey Parfonov</a>
+ * @version $Id$
+ */
+public class ApplicationRegistry implements Startable
+{
+ /** Logger. */
+ private static final Log LOG = ExoLogger.getLogger(ApplicationRegistry.class);
+
+ protected final ExoContainer container;
+
+ protected final ResourceBinder resources;
+
+ protected final ProvidersRegistry providers;
+
+ protected final ResourceDescriptorValidator rdv = ResourceDescriptorValidator.getInstance();
+
+ public ApplicationRegistry(ExoContainerContext containerContext, ResourceBinder resources,
+ ProvidersRegistry providers, StartableApplication eXo /* Be sure eXo components are initialized. */)
+ {
+ this.resources = resources;
+ this.providers = providers;
+ this.container = containerContext.getContainer();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ public void start()
+ {
+ List<Application> all = container.getComponentInstancesOfType(Application.class);
+ for (Application app : all)
+ {
+ addApplication(app);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public void addApplication(Application app)
+ {
+ String applicationId = app.getClass().getName();
+ ApplicationProviders appProviders = new ApplicationProviders(applicationId);
+ for (Object obj : app.getSingletons())
+ {
+ Class clazz = obj.getClass();
+ if (clazz.getAnnotation(Path.class) != null)
+ {
+ AbstractResourceDescriptor descriptor = new ApplicationResource(applicationId, obj);
+ descriptor.accept(rdv);
+ resources.addResource(new SingletonObjectFactory<AbstractResourceDescriptor>(descriptor, obj));
+ }
+ else if (clazz.getAnnotation(Provider.class) != null)
+ {
+ if (obj instanceof ContextResolver)
+ appProviders.addContextResolver((ContextResolver)obj);
+ if (obj instanceof ExceptionMapper)
+ appProviders.addExceptionMapper((ExceptionMapper)obj);
+ if (obj instanceof MessageBodyReader)
+ appProviders.addMessageBodyReader((MessageBodyReader)obj);
+ if (obj instanceof MessageBodyWriter)
+ appProviders.addMessageBodyWriter((MessageBodyWriter)obj);
+ }
+ else if (clazz.getAnnotation(Filter.class) != null)
+ {
+ if (obj instanceof MethodInvokerFilter)
+ appProviders.addMethodInvokerFilter((MethodInvokerFilter)obj);
+ if (obj instanceof RequestFilter)
+ appProviders.addRequestFilter((RequestFilter)obj);
+ if (obj instanceof ResponseFilter)
+ appProviders.addResponseFilter((ResponseFilter)obj);
+ }
+ else
+ {
+ LOG.warn("Unknown class type: " + clazz.getName() + " found in " + applicationId);
+ }
+ }
+ for (Class clazz : app.getClasses())
+ {
+ if (clazz.getAnnotation(Path.class) != null)
+ {
+ AbstractResourceDescriptor descriptor = new ApplicationResource(applicationId, clazz);
+ descriptor.accept(rdv);
+ resources.addResource(new PerRequestObjectFactory<AbstractResourceDescriptor>(descriptor));
+ }
+ else if (clazz.getAnnotation(Provider.class) != null)
+ {
+ if (ContextResolver.class.isAssignableFrom(clazz))
+ appProviders.addContextResolver(clazz);
+ if (ExceptionMapper.class.isAssignableFrom(clazz))
+ appProviders.addExceptionMapper(clazz);
+ if (MessageBodyReader.class.isAssignableFrom(clazz))
+ appProviders.addMessageBodyReader(clazz);
+ if (MessageBodyWriter.class.isAssignableFrom(clazz))
+ appProviders.addMessageBodyWriter(clazz);
+ }
+ else if (clazz.getAnnotation(Filter.class) != null)
+ {
+ if (MethodInvokerFilter.class.isAssignableFrom(clazz))
+ appProviders.addMethodInvokerFilter(clazz);
+ if (RequestFilter.class.isAssignableFrom(clazz))
+ appProviders.addRequestFilter(clazz);
+ if (ResponseFilter.class.isAssignableFrom(clazz))
+ appProviders.addResponseFilter(clazz);
+ }
+ else
+ {
+ LOG.warn("Unknown class type: " + clazz.getName() + " found in: " + applicationId);
+ }
+ }
+ this.providers.addProviders(appProviders);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void stop()
+ {
+ }
+
+}
Property changes on: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ApplicationRegistry.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/ProviderBinder.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ProviderBinder.java 2010-11-02 08:53:25 UTC (rev 3374)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ProviderBinder.java 2010-11-02 08:56:55 UTC (rev 3375)
@@ -48,6 +48,7 @@
import org.exoplatform.services.rest.impl.provider.StringEntityProvider;
import org.exoplatform.services.rest.impl.resource.ResourceDescriptorValidator;
import org.exoplatform.services.rest.method.MethodInvokerFilter;
+import org.exoplatform.services.rest.provider.ExtendedProviders;
import org.exoplatform.services.rest.provider.ProviderDescriptor;
import org.exoplatform.services.rest.resource.ResourceDescriptorVisitor;
import org.exoplatform.services.rest.uri.UriPattern;
@@ -70,29 +71,33 @@
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.MessageBodyWriter;
-import javax.ws.rs.ext.Providers;
/**
+ * Prepared set of providers. Users of JAX-RS implementation are not expected to
+ * use this class directly. @Context annotation should be used to obtain
+ * actual set of providers in RESTful services. As alternative method :
+ * <pre>
+ * ApplicationContext context = ApplicationContextImpl.getCurrent();
+ * Providers providers = context.getProviders();
+ * </pre>
+ *
* @author <a href="mailto:andrew00x at gmail.com">Andrey Parfonov</a>
* @version $Id: $
*/
-public class ProviderBinder implements Providers
+public class ProviderBinder implements ExtendedProviders
{
- /**
- * Logger.
- */
- private static final Log LOG = ExoLogger.getLogger("exo.ws.rest.core.ProviderBinder");
+ /** Logger. */
+ private static final Log LOG = ExoLogger.getLogger(ProviderBinder.class);
- /**
- * Providers instance.
- *
- * @see Providers
- */
+ /** Default providers. */
private static AtomicReference<ProviderBinder> ainst = new AtomicReference<ProviderBinder>();
/**
- * @return instance of {@link ProviderBinder}
+ * Get actual set of providers. Users of JAX-RS implementation are not
+ * expected to call this method.
+ *
+ * @return actual set of providers
*/
public static ProviderBinder getInstance()
{
@@ -105,6 +110,12 @@
return t;
}
+ /**
+ * Set actual set of providers. Users of JAX-RS implementation are not
+ * expected to call this method.
+ *
+ * @param inst actual set of providers
+ */
public static void setInstance(ProviderBinder inst)
{
ainst.set(inst);
@@ -120,7 +131,6 @@
*/
protected void init()
{
- // TODO remove this hard code
ByteEntityProvider baep = new ByteEntityProvider();
addMessageBodyReader(baep);
addMessageBodyWriter(baep);
@@ -183,55 +193,66 @@
addContextResolver(JAXBContextResolver.class, null, ComponentLifecycleScope.CONTAINER);
addExceptionMapper(new DefaultExceptionMapper());
-
}
/**
- * Read message body providers. Also see {@link MediaTypeMultivaluedMap}.
+ * Read message body providers.
+ *
+ * @see MediaTypeMultivaluedMap .
*/
- private final MediaTypeMultivaluedMap<ObjectFactory<ProviderDescriptor>> writeProviders =
+ protected final MediaTypeMultivaluedMap<ObjectFactory<ProviderDescriptor>> writeProviders =
new MediaTypeMultivaluedMap<ObjectFactory<ProviderDescriptor>>();
/**
- * Read message body providers. Also see {@link MediaTypeMultivaluedMap}.
+ * Read message body providers.
+ *
+ * @see MediaTypeMultivaluedMap .
*/
- private final MediaTypeMultivaluedMap<ObjectFactory<ProviderDescriptor>> readProviders =
+ protected final MediaTypeMultivaluedMap<ObjectFactory<ProviderDescriptor>> readProviders =
new MediaTypeMultivaluedMap<ObjectFactory<ProviderDescriptor>>();
/**
- * Exception mappers, see {@link ExceptionMapper}.
+ * Exception mappers.
+ *
+ * @see ExceptionMapper .
*/
- private final Map<Class<? extends Throwable>, ObjectFactory<ProviderDescriptor>> exceptionMappers =
+ protected final Map<Class<? extends Throwable>, ObjectFactory<ProviderDescriptor>> exceptionMappers =
new HashMap<Class<? extends Throwable>, ObjectFactory<ProviderDescriptor>>();
/**
* Context resolvers.
+ *
+ * @see ContextResolver .
*/
- private final Map<Class<?>, MediaTypeMap<ObjectFactory<ProviderDescriptor>>> contextResolvers =
+ protected final Map<Class<?>, MediaTypeMap<ObjectFactory<ProviderDescriptor>>> contextResolvers =
new HashMap<Class<?>, MediaTypeMap<ObjectFactory<ProviderDescriptor>>>();
/**
- * Request filters, see {@link RequestFilter}.
+ * Request filters.
+ *
+ * @see RequestFilter .
*/
- private final UriPatternMap<ObjectFactory<FilterDescriptor>> requestFilters =
+ protected final UriPatternMap<ObjectFactory<FilterDescriptor>> requestFilters =
new UriPatternMap<ObjectFactory<FilterDescriptor>>();
/**
- * Response filters, see {@link ResponseFilter}.
+ * Response filters.
+ *
+ * @see ResponseFilter .
*/
- private final UriPatternMap<ObjectFactory<FilterDescriptor>> responseFilters =
+ protected final UriPatternMap<ObjectFactory<FilterDescriptor>> responseFilters =
new UriPatternMap<ObjectFactory<FilterDescriptor>>();
/**
* Method invoking filters.
+ *
+ * @see MethodInvokerFilter .
*/
- private final UriPatternMap<ObjectFactory<FilterDescriptor>> invokerFilters =
+ protected final UriPatternMap<ObjectFactory<FilterDescriptor>> invokerFilters =
new UriPatternMap<ObjectFactory<FilterDescriptor>>();
- /**
- * Validator.
- */
- private final ResourceDescriptorVisitor rdv = ResourceDescriptorValidator.getInstance();
+ /** Validator. */
+ protected final ResourceDescriptorVisitor rdv = ResourceDescriptorValidator.getInstance();
//
@@ -408,7 +429,6 @@
}
}
}
-
Collections.sort(l, MediaTypeHelper.MEDIA_TYPE_COMPARATOR);
return l;
}
@@ -424,18 +444,17 @@
{
if (mediaType == null)
{
- return _getContextResolver(pm, contextType, MediaTypeHelper.DEFAULT_TYPE);
+ return doGetContextResolver(pm, contextType, MediaTypeHelper.DEFAULT_TYPE);
}
-
- resolver = _getContextResolver(pm, contextType, mediaType);
- if (resolver == null)
+ resolver = doGetContextResolver(pm, contextType, mediaType);
+ if (resolver == null && !mediaType.isWildcardSubtype())
{
resolver =
- _getContextResolver(pm, contextType, new MediaType(mediaType.getType(), MediaType.MEDIA_TYPE_WILDCARD));
+ doGetContextResolver(pm, contextType, new MediaType(mediaType.getType(), MediaType.MEDIA_TYPE_WILDCARD));
}
- if (resolver == null)
+ if (resolver == null && !mediaType.isWildcardType())
{
- resolver = _getContextResolver(pm, contextType, MediaTypeHelper.DEFAULT_TYPE);
+ resolver = doGetContextResolver(pm, contextType, MediaTypeHelper.DEFAULT_TYPE);
}
}
return resolver;
@@ -463,21 +482,19 @@
{
if (mediaType == null)
{
- return _getMessageBodyReader(type, genericType, annotations, MediaTypeHelper.DEFAULT_TYPE);
+ return doGetMessageBodyReader(type, genericType, annotations, MediaTypeHelper.DEFAULT_TYPE);
}
-
- MessageBodyReader<T> reader = _getMessageBodyReader(type, genericType, annotations, mediaType);
- if (reader == null)
+ MessageBodyReader<T> reader = doGetMessageBodyReader(type, genericType, annotations, mediaType);
+ if (reader == null && !mediaType.isWildcardSubtype())
{
reader =
- _getMessageBodyReader(type, genericType, annotations, new MediaType(mediaType.getType(),
+ doGetMessageBodyReader(type, genericType, annotations, new MediaType(mediaType.getType(),
MediaType.MEDIA_TYPE_WILDCARD));
}
- if (reader == null)
+ if (reader == null && !mediaType.isWildcardType())
{
- reader = _getMessageBodyReader(type, genericType, annotations, MediaTypeHelper.DEFAULT_TYPE);
+ reader = doGetMessageBodyReader(type, genericType, annotations, MediaTypeHelper.DEFAULT_TYPE);
}
-
return reader;
}
@@ -489,19 +506,18 @@
{
if (mediaType == null)
{
- return _getMessageBodyWriter(type, genericType, annotations, MediaTypeHelper.DEFAULT_TYPE);
+ return doGetMessageBodyWriter(type, genericType, annotations, MediaTypeHelper.DEFAULT_TYPE);
}
-
- MessageBodyWriter<T> writer = _getMessageBodyWriter(type, genericType, annotations, mediaType);
- if (writer == null)
+ MessageBodyWriter<T> writer = doGetMessageBodyWriter(type, genericType, annotations, mediaType);
+ if (writer == null && !mediaType.isWildcardSubtype())
{
writer =
- _getMessageBodyWriter(type, genericType, annotations, new MediaType(mediaType.getType(),
+ doGetMessageBodyWriter(type, genericType, annotations, new MediaType(mediaType.getType(),
MediaType.MEDIA_TYPE_WILDCARD));
}
- if (writer == null)
+ if (writer == null && !mediaType.isWildcardType())
{
- writer = _getMessageBodyWriter(type, genericType, annotations, MediaTypeHelper.DEFAULT_TYPE);
+ writer = doGetMessageBodyWriter(type, genericType, annotations, MediaTypeHelper.DEFAULT_TYPE);
}
return writer;
}
@@ -612,8 +628,7 @@
}
/**
- * @param path request path
- * @return acceptable method invocation filters
+ * {@inheritDoc}
*/
public List<ObjectFactory<FilterDescriptor>> getMethodInvokerFilters(String path)
{
@@ -621,8 +636,7 @@
}
/**
- * @param path request path
- * @return acceptable request filters
+ * {@inheritDoc}
*/
public List<ObjectFactory<FilterDescriptor>> getRequestFilters(String path)
{
@@ -630,8 +644,7 @@
}
/**
- * @param path request path
- * @return acceptable response filters
+ * {@inheritDoc}
*/
public List<ObjectFactory<FilterDescriptor>> getResponseFilters(String path)
{
@@ -646,17 +659,14 @@
* @see #getRequestFilters(String)
* @see #getResponseFilters(String)
*/
- private List<ObjectFactory<FilterDescriptor>> getMatchedFilters(String path,
+ protected List<ObjectFactory<FilterDescriptor>> getMatchedFilters(String path,
UriPatternMap<ObjectFactory<FilterDescriptor>> m)
{
-
List<ObjectFactory<FilterDescriptor>> l = new ArrayList<ObjectFactory<FilterDescriptor>>();
-
List<String> capturingValues = new ArrayList<String>();
for (Map.Entry<UriPattern, List<ObjectFactory<FilterDescriptor>>> e : m.entrySet())
{
UriPattern uriPattern = e.getKey();
-
if (uriPattern != null)
{
if (e.getKey().match(path, capturingValues))
@@ -671,27 +681,24 @@
{
continue; // not matched
}
-
}
// if matched or UriPattern is null
l.addAll(e.getValue());
}
-
return l;
-
}
/**
* @param <T> context resolver actual type argument
* @param pm MediaTypeMap that contains ProviderFactories that may produce
- * objects that are instance of T
+ * objects that are instance of T
* @param contextType context type
* @param mediaType media type that can be used to restrict context resolver
- * choose
+ * choose
* @return ContextResolver or null if nothing was found
*/
@SuppressWarnings("unchecked")
- private <T> ContextResolver<T> _getContextResolver(MediaTypeMap<ObjectFactory<ProviderDescriptor>> pm,
+ protected <T> ContextResolver<T> doGetContextResolver(MediaTypeMap<ObjectFactory<ProviderDescriptor>> pm,
Class<T> contextType, MediaType mediaType)
{
for (Map.Entry<MediaType, ObjectFactory<ProviderDescriptor>> e : pm.entrySet())
@@ -716,7 +723,7 @@
* @return message body reader or null if no one was found.
*/
@SuppressWarnings("unchecked")
- private <T> MessageBodyReader<T> _getMessageBodyReader(Class<T> type, Type genericType, Annotation[] annotations,
+ protected <T> MessageBodyReader<T> doGetMessageBodyReader(Class<T> type, Type genericType, Annotation[] annotations,
MediaType mediaType)
{
for (ObjectFactory pf : readProviders.getList(mediaType))
@@ -742,7 +749,7 @@
* @return message body writer or null if no one was found.
*/
@SuppressWarnings("unchecked")
- private <T> MessageBodyWriter<T> _getMessageBodyWriter(Class<T> type, Type genericType, Annotation[] annotations,
+ protected <T> MessageBodyWriter<T> doGetMessageBodyWriter(Class<T> type, Type genericType, Annotation[] annotations,
MediaType mediaType)
{
for (ObjectFactory pf : writeProviders.getList(mediaType))
@@ -759,7 +766,7 @@
/**
* @param clazz ContextResolver class
* @param instance ContextResolver instance, may be null if not singleton
- * instance
+ * instance
* @param scope ComponentLifecycleScope
*/
@SuppressWarnings("unchecked")
@@ -800,9 +807,7 @@
break;
case SINGLETON :
if (instance == null)
- {
throw new NullPointerException("ContextResolver instance is null.");
- }
factory = new SingletonObjectFactory<ProviderDescriptor>(descriptor, instance);
break;
case CONTAINER :
@@ -848,16 +853,13 @@
break;
case SINGLETON :
if (instance == null)
- {
throw new NullPointerException("MessageBodyReader instance is null.");
- }
factory = new SingletonObjectFactory<ProviderDescriptor>(descriptor, instance);
break;
case CONTAINER :
factory = new ContainerObjectFactory<ProviderDescriptor>(descriptor);
break;
}
-
// MessageBodyReader is smart component and can determine which type it
// supports, see method MessageBodyReader.isReadable. So here does not
// check is reader for the same Java and media type already exists.
@@ -888,16 +890,13 @@
break;
case SINGLETON :
if (instance == null)
- {
throw new NullPointerException("MessageBodyWriter instance is null.");
- }
factory = new SingletonObjectFactory<ProviderDescriptor>(descriptor, instance);
break;
case CONTAINER :
factory = new ContainerObjectFactory<ProviderDescriptor>(descriptor);
break;
}
-
// MessageBodyWriter is smart component and can determine which type it
// supports, see method MessageBodyWriter.isWriteable. So here does not
// check is writer for the same Java and media type already exists.
@@ -911,7 +910,7 @@
/**
* @param clazz ExceptionMapper class
* @param instance ExceptionMapper instance, may be null if not singleton
- * instance
+ * instance
* @param scope ComponentLifecycleScope
*/
@SuppressWarnings("unchecked")
@@ -927,9 +926,8 @@
{
Type[] atypes = pt.getActualTypeArguments();
if (atypes.length > 1)
- {
throw new RuntimeException("Unable strong determine actual type argument, more then one type found.");
- }
+
Class<? extends Throwable> exc = (Class<? extends Throwable>)atypes[0];
if (exceptionMappers.get(exc) != null)
@@ -949,16 +947,13 @@
break;
case SINGLETON :
if (instance == null)
- {
throw new NullPointerException("ExceptionMapper instance is null.");
- }
factory = new SingletonObjectFactory<ProviderDescriptor>(descriptor, instance);
break;
case CONTAINER :
factory = new ContainerObjectFactory<ProviderDescriptor>(descriptor);
break;
}
-
exceptionMappers.put(exc, factory);
}
}
@@ -968,13 +963,12 @@
/**
* @param clazz RequestFilter class
* @param instance RequestFilter instance, may be null if not singleton
- * instance
+ * instance
* @param scope ComponentLifecycleScope
*/
public void addRequestFilter(Class<? extends RequestFilter> clazz, RequestFilter instance,
ComponentLifecycleScope scope)
{
-
FilterDescriptor descriptor = new FilterDescriptorImpl(clazz);
descriptor.accept(rdv);
@@ -986,29 +980,25 @@
break;
case SINGLETON :
if (instance == null)
- {
throw new NullPointerException("RequestFilter instance is null.");
- }
factory = new SingletonObjectFactory<FilterDescriptor>(descriptor, instance);
break;
case CONTAINER :
factory = new ContainerObjectFactory<FilterDescriptor>(descriptor);
break;
}
-
requestFilters.getList(descriptor.getUriPattern()).add(factory);
}
/**
* @param clazz ResponseFilter class
* @param instance ResponseFilter instance, may be null if not singleton
- * instance
+ * instance
* @param scope ComponentLifecycleScope
*/
public void addResponseFilter(Class<? extends ResponseFilter> clazz, ResponseFilter instance,
ComponentLifecycleScope scope)
{
-
FilterDescriptor descriptor = new FilterDescriptorImpl(clazz);
descriptor.accept(rdv);
@@ -1020,29 +1010,25 @@
break;
case SINGLETON :
if (instance == null)
- {
throw new NullPointerException("ResponseFilter instance is null.");
- }
factory = new SingletonObjectFactory<FilterDescriptor>(descriptor, instance);
break;
case CONTAINER :
factory = new ContainerObjectFactory<FilterDescriptor>(descriptor);
break;
}
-
responseFilters.getList(descriptor.getUriPattern()).add(factory);
}
/**
* @param clazz MethodInvokerFilter class
* @param instance MethodInvokerFilter instance, may be null if not singleton
- * instance
+ * instance
* @param scope ComponentLifecycleScope
*/
public void addMethodInvokerFilter(Class<? extends MethodInvokerFilter> clazz, MethodInvokerFilter instance,
ComponentLifecycleScope scope)
{
-
FilterDescriptor descriptor = new FilterDescriptorImpl(clazz);
descriptor.accept(rdv);
@@ -1054,16 +1040,13 @@
break;
case SINGLETON :
if (instance == null)
- {
throw new NullPointerException("MethodInvokerFilter instance is null.");
- }
factory = new SingletonObjectFactory<FilterDescriptor>(descriptor, instance);
break;
case CONTAINER :
factory = new ContainerObjectFactory<FilterDescriptor>(descriptor);
break;
}
-
invokerFilters.getList(descriptor.getUriPattern()).add(factory);
}
Added: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ProvidersRegistry.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ProvidersRegistry.java (rev 0)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ProvidersRegistry.java 2010-11-02 08:56:55 UTC (rev 3375)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2009 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;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author <a href="andrew00x at gmail.com">Andrey Parfonov</a>
+ * @version $Id$
+ */
+public class ProvidersRegistry
+{
+
+ protected Map<String, ApplicationProviders> all = new HashMap<String, ApplicationProviders>();
+
+ public void addProviders(ApplicationProviders ap)
+ {
+ all.put(ap.getApplication(), ap);
+ }
+
+ public ApplicationProviders getProviders(String applicationId)
+ {
+ return all.get(applicationId);
+ }
+
+}
Property changes on: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ProvidersRegistry.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/RequestDispatcher.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/RequestDispatcher.java 2010-11-02 08:53:25 UTC (rev 3374)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/RequestDispatcher.java 2010-11-02 08:56:55 UTC (rev 3375)
@@ -21,15 +21,21 @@
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.rest.ApplicationContext;
+import org.exoplatform.services.rest.ComponentLifecycleScope;
+import org.exoplatform.services.rest.FilterDescriptor;
import org.exoplatform.services.rest.GenericContainerRequest;
import org.exoplatform.services.rest.GenericContainerResponse;
import org.exoplatform.services.rest.ObjectFactory;
+import org.exoplatform.services.rest.RequestFilter;
+import org.exoplatform.services.rest.ResponseFilter;
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.impl.resource.ApplicationResource;
import org.exoplatform.services.rest.method.MethodInvoker;
+import org.exoplatform.services.rest.method.MethodInvokerFilter;
import org.exoplatform.services.rest.resource.AbstractResourceDescriptor;
import org.exoplatform.services.rest.resource.ResourceMethodDescriptor;
import org.exoplatform.services.rest.resource.ResourceMethodMap;
@@ -39,7 +45,10 @@
import org.exoplatform.services.rest.resource.SubResourceMethodMap;
import org.exoplatform.services.rest.uri.UriPattern;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
@@ -52,6 +61,10 @@
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
+import javax.ws.rs.ext.ContextResolver;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.MessageBodyReader;
+import javax.ws.rs.ext.MessageBodyWriter;
/**
* Lookup resource which can serve request.
@@ -62,33 +75,382 @@
public class RequestDispatcher
{
+ /**
+ * Set of providers which respects providers specified by JAX-RS
+ * Applications. Default (embedded) providers will be used only if
+ * application does not provide own providers with the same purposes.
+ */
+ private class ProvidersAdapter extends ProviderBinder
+ {
+ private ProviderBinder applicationProviders;
+
+ private ProviderBinder defaultProviders;
+
+ private ProvidersAdapter(ProviderBinder applicationProviders, ProviderBinder defaultProviders)
+ {
+ this.applicationProviders = applicationProviders;
+ this.defaultProviders = defaultProviders;
+ }
+
+ @Override
+ protected void init()
+ {
+ // Do not add default providers here.
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void addContextResolver(Class<? extends ContextResolver> clazz, ContextResolver instance,
+ ComponentLifecycleScope scope)
+ {
+ if (applicationProviders != null)
+ applicationProviders.addContextResolver(clazz, instance, scope);
+ else
+ // Keep default set of providers untouched.
+ throw new UnsupportedOperationException("addContextResolver");
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void addContextResolver(Class<? extends ContextResolver> clazz)
+ {
+ if (applicationProviders != null)
+ applicationProviders.addContextResolver(clazz);
+ else
+ // Keep default set of providers untouched.
+ throw new UnsupportedOperationException("addContextResolver");
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void addContextResolver(ContextResolver instance)
+ {
+ if (applicationProviders != null)
+ applicationProviders.addContextResolver(instance);
+ else
+ // Keep default set of providers untouched.
+ throw new UnsupportedOperationException("addContextResolver");
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void addExceptionMapper(Class<? extends ExceptionMapper> clazz, ExceptionMapper instance,
+ ComponentLifecycleScope scope)
+ {
+ if (applicationProviders != null)
+ applicationProviders.addExceptionMapper(clazz, instance, scope);
+ else
+ // Keep default set of providers untouched.
+ throw new UnsupportedOperationException("addExceptionMapper");
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void addExceptionMapper(Class<? extends ExceptionMapper> clazz)
+ {
+ if (applicationProviders != null)
+ applicationProviders.addExceptionMapper(clazz);
+ else
+ // Keep default set of providers untouched.
+ throw new UnsupportedOperationException("addExceptionMapper");
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void addExceptionMapper(ExceptionMapper instance)
+ {
+ if (applicationProviders != null)
+ applicationProviders.addExceptionMapper(instance);
+ else
+ // Keep default set of providers untouched.
+ throw new UnsupportedOperationException("addExceptionMapper");
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void addMessageBodyReader(Class<? extends MessageBodyReader> clazz, MessageBodyReader instance,
+ ComponentLifecycleScope scope)
+ {
+ if (applicationProviders != null)
+ applicationProviders.addMessageBodyReader(clazz, instance, scope);
+ else
+ // Keep default set of providers untouched.
+ throw new UnsupportedOperationException("addMessageBodyReader");
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void addMessageBodyReader(Class<? extends MessageBodyReader> clazz)
+ {
+ if (applicationProviders != null)
+ applicationProviders.addMessageBodyReader(clazz);
+ else
+ // Keep default set of providers untouched.
+ throw new UnsupportedOperationException("addMessageBodyReader");
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void addMessageBodyReader(MessageBodyReader instance)
+ {
+ if (applicationProviders != null)
+ applicationProviders.addMessageBodyReader(instance);
+ else
+ // Keep default set of providers untouched.
+ throw new UnsupportedOperationException("addMessageBodyReader");
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void addMessageBodyWriter(Class<? extends MessageBodyWriter> clazz, MessageBodyWriter instance,
+ ComponentLifecycleScope scope)
+ {
+ if (applicationProviders != null)
+ applicationProviders.addMessageBodyWriter(clazz, instance, scope);
+ else
+ // Keep default set of providers untouched.
+ throw new UnsupportedOperationException("addMessageBodyWriter");
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void addMessageBodyWriter(Class<? extends MessageBodyWriter> clazz)
+ {
+ if (applicationProviders != null)
+ applicationProviders.addMessageBodyWriter(clazz);
+ else
+ // Keep default set of providers untouched.
+ throw new UnsupportedOperationException("addMessageBodyWriter");
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void addMessageBodyWriter(MessageBodyWriter instance)
+ {
+ if (applicationProviders != null)
+ applicationProviders.addMessageBodyWriter(instance);
+ else
+ // Keep default set of providers untouched.
+ throw new UnsupportedOperationException("addMessageBodyWriter");
+ }
+
+ @Override
+ public void addMethodInvokerFilter(Class<? extends MethodInvokerFilter> clazz, MethodInvokerFilter instance,
+ ComponentLifecycleScope scope)
+ {
+ if (applicationProviders != null)
+ applicationProviders.addMethodInvokerFilter(clazz, instance, scope);
+ else
+ // Keep default set of providers untouched.
+ throw new UnsupportedOperationException("addMethodInvokerFilter");
+ }
+
+ @Override
+ public void addMethodInvokerFilter(Class<? extends MethodInvokerFilter> clazz)
+ {
+ if (applicationProviders != null)
+ applicationProviders.addMethodInvokerFilter(clazz);
+ else
+ // Keep default set of providers untouched.
+ throw new UnsupportedOperationException("addMethodInvokerFilter");
+ }
+
+ @Override
+ public void addMethodInvokerFilter(MethodInvokerFilter instance)
+ {
+ if (applicationProviders != null)
+ applicationProviders.addMethodInvokerFilter(instance);
+ else
+ // Keep default set of providers untouched.
+ throw new UnsupportedOperationException("addMethodInvokerFilter");
+ }
+
+ @Override
+ public void addRequestFilter(Class<? extends RequestFilter> clazz, RequestFilter instance,
+ ComponentLifecycleScope scope)
+ {
+ if (applicationProviders != null)
+ applicationProviders.addRequestFilter(clazz, instance, scope);
+ else
+ // Keep default set of providers untouched.
+ throw new UnsupportedOperationException("addRequestFilter");
+ }
+
+ @Override
+ public void addRequestFilter(Class<? extends RequestFilter> clazz)
+ {
+ if (applicationProviders != null)
+ applicationProviders.addRequestFilter(clazz);
+ else
+ // Keep default set of providers untouched.
+ throw new UnsupportedOperationException("addRequestFilter");
+ }
+
+ @Override
+ public void addRequestFilter(RequestFilter instance)
+ {
+ if (applicationProviders != null)
+ applicationProviders.addRequestFilter(instance);
+ else
+ // Keep default set of providers untouched.
+ throw new UnsupportedOperationException("addRequestFilter");
+ }
+
+ @Override
+ public void addResponseFilter(Class<? extends ResponseFilter> clazz, ResponseFilter instance,
+ ComponentLifecycleScope scope)
+ {
+ if (applicationProviders != null)
+ applicationProviders.addResponseFilter(clazz, instance, scope);
+ else
+ // Keep default set of providers untouched.
+ throw new UnsupportedOperationException("addResponseFilter");
+ }
+
+ @Override
+ public void addResponseFilter(Class<? extends ResponseFilter> clazz)
+ {
+ if (applicationProviders != null)
+ applicationProviders.addResponseFilter(clazz);
+ else
+ // Keep default set of providers untouched.
+ throw new UnsupportedOperationException("addResponseFilter");
+ }
+
+ @Override
+ public void addResponseFilter(ResponseFilter instance)
+ {
+ if (applicationProviders != null)
+ applicationProviders.addResponseFilter(instance);
+ else
+ // Keep default set of providers untouched.
+ throw new UnsupportedOperationException("addResponseFilter");
+ }
+
+ @Override
+ public List<MediaType> getAcceptableWriterMediaTypes(Class<?> type, Type genericType, Annotation[] annotations)
+ {
+ List<MediaType> mediaTypes = null;
+ if (applicationProviders != null)
+ mediaTypes = applicationProviders.getAcceptableWriterMediaTypes(type, genericType, annotations);
+ if (mediaTypes != null)
+ {
+ mediaTypes.addAll(defaultProviders.getAcceptableWriterMediaTypes(type, genericType, annotations));
+ return mediaTypes;
+ }
+ return defaultProviders.getAcceptableWriterMediaTypes(type, genericType, annotations);
+ }
+
+ @Override
+ public <T> ContextResolver<T> getContextResolver(Class<T> contextType, MediaType mediaType)
+ {
+ ContextResolver<T> resolver = null;
+ if (applicationProviders != null)
+ resolver = applicationProviders.getContextResolver(contextType, mediaType);
+ if (resolver == null)
+ resolver = defaultProviders.getContextResolver(contextType, mediaType);
+ return resolver;
+ }
+
+ @Override
+ public <T extends Throwable> ExceptionMapper<T> getExceptionMapper(Class<T> type)
+ {
+ ExceptionMapper<T> mapper = null;
+ if (applicationProviders != null)
+ mapper = applicationProviders.getExceptionMapper(type);
+ if (mapper == null)
+ mapper = defaultProviders.getExceptionMapper(type);
+ return mapper;
+ }
+
+ @Override
+ public <T> MessageBodyReader<T> getMessageBodyReader(Class<T> type, Type genericType, Annotation[] annotations,
+ MediaType mediaType)
+ {
+ MessageBodyReader<T> reader = null;
+ if (applicationProviders != null)
+ reader = applicationProviders.getMessageBodyReader(type, genericType, annotations, mediaType);
+ if (reader == null)
+ reader = defaultProviders.getMessageBodyReader(type, genericType, annotations, mediaType);
+ return reader;
+ }
+
+ @Override
+ public <T> MessageBodyWriter<T> getMessageBodyWriter(Class<T> type, Type genericType, Annotation[] annotations,
+ MediaType mediaType)
+ {
+ MessageBodyWriter<T> writer = null;
+ if (applicationProviders != null)
+ writer = applicationProviders.getMessageBodyWriter(type, genericType, annotations, mediaType);
+ if (writer == null)
+ writer = defaultProviders.getMessageBodyWriter(type, genericType, annotations, mediaType);
+ return writer;
+ }
+
+ @Override
+ public List<ObjectFactory<FilterDescriptor>> getMethodInvokerFilters(String path)
+ {
+ List<ObjectFactory<FilterDescriptor>> filters = defaultProviders.getMethodInvokerFilters(path);
+ if (applicationProviders != null)
+ filters.addAll(applicationProviders.getMethodInvokerFilters(path));
+ return filters;
+ }
+
+ @Override
+ public List<ObjectFactory<FilterDescriptor>> getRequestFilters(String path)
+ {
+ // NOTE!!! Return only application specific filters. Default filters
+ // should be already applied to request.
+ if (applicationProviders == null)
+ return Collections.emptyList();
+ return applicationProviders.getRequestFilters(path);
+ }
+
+ @Override
+ public List<ObjectFactory<FilterDescriptor>> getResponseFilters(String path)
+ {
+ // NOTE!!! Return only application specific filters. Default filters
+ // should be applied to response later.
+ if (applicationProviders == null)
+ return Collections.emptyList();
+ return applicationProviders.getResponseFilters(path);
+ }
+
+ }
+
/** Logger. */
private static final Log LOG = ExoLogger.getLogger("exo.ws.rest.core.RequestDispatcher");
/** See {@link ResourceBinder}. */
protected final ResourceBinder resourceBinder;
- private final MethodInvokerFactory invokerFactory;
+ protected final MethodInvokerFactory invokerFactory;
- /**
- * Constructs new instance of RequestDispatcher.
- *
- * @param resourceBinder See {@link ResourceBinder}
- */
- public RequestDispatcher(ResourceBinder resourceBinder, MethodInvokerFactory invokerFactory)
+ protected final ProvidersRegistry providersRegistry;
+
+ public RequestDispatcher(ResourceBinder resourceBinder, ProvidersRegistry providersRegistry,
+ MethodInvokerFactory invokerFactory)
{
this.resourceBinder = resourceBinder;
+ this.providersRegistry = providersRegistry;
this.invokerFactory = invokerFactory;
}
- /**
- * Constructs new instance of RequestDispatcher.
- *
- * @param resourceBinder See {@link ResourceBinder}
- */
+ public RequestDispatcher(ResourceBinder resourceBinder, ProvidersRegistry providers)
+ {
+ this(resourceBinder, providers, null);
+ }
+
+ @Deprecated
+ public RequestDispatcher(ResourceBinder resourceBinder, MethodInvokerFactory invokerFactory)
+ {
+ this(resourceBinder, null, invokerFactory);
+ }
+
+ @Deprecated
public RequestDispatcher(ResourceBinder resourceBinder)
{
- this(resourceBinder, null);
+ this(resourceBinder, null, null);
}
/**
@@ -105,20 +467,51 @@
// Get root resource
ObjectFactory<AbstractResourceDescriptor> resourceFactory = getRootResourse(parameterValues, requestPath);
+ AbstractResourceDescriptor resourceDescriptor = resourceFactory.getObjectModel();
+ if (providersRegistry != null)
+ {
+ // Be sure instance of ProvidersRegistry injected if this class is extended.
+ String applicationId = null;
+ if (resourceDescriptor instanceof ApplicationResource)
+ {
+ // If resource delivered with subclass of javax.ws.rs.core.Application
+ // it must be instance of ApplicationResource which provide application's identifier.
+ applicationId = ((ApplicationResource)resourceDescriptor).getApplication();
+ }
+ ProviderBinder applicationProviders = providersRegistry.getProviders(applicationId);
+ ((ApplicationContextImpl)context).setProviders(new ProvidersAdapter(applicationProviders, ProviderBinder
+ .getInstance()));
+ }
+ else
+ {
+ LOG.warn("ProvidersRegistry must set. ");
+ }
+
+ // Apply application specific request filters if any
+ for (ObjectFactory<FilterDescriptor> factory : context.getProviders().getRequestFilters(context.getPath()))
+ {
+ RequestFilter f = (RequestFilter)factory.getInstance(context);
+ f.doFilter(request);
+ }
+
// Take the tail of the request path, the tail will be requested path
// for lower resources, e. g. ResourceClass -> Sub-resource method/locator
String newRequestPath = getPathTail(parameterValues);
-
// save the resource class URI in hierarchy
context.addMatchedURI(requestPath.substring(0, requestPath.lastIndexOf(newRequestPath)));
-
context.setParameterNames(resourceFactory.getObjectModel().getUriPattern().getParameterNames());
// may thrown WebApplicationException
Object resource = resourceFactory.getInstance(context);
+ dispatch(request, response, context, resourceFactory, resource, newRequestPath);
- dispatch(request, response, context, resourceFactory, resource, newRequestPath);
+ // Apply application specific response filters if any
+ for (ObjectFactory<FilterDescriptor> factory : context.getProviders().getResponseFilters(context.getPath()))
+ {
+ ResponseFilter f = (ResponseFilter)factory.getInstance(context);
+ f.doFilter(response);
+ }
}
/**
@@ -154,34 +547,24 @@
ApplicationContext context, ObjectFactory<AbstractResourceDescriptor> resourceFactory, Object resource,
String requestPath)
{
-
List<String> parameterValues = context.getParameterValues();
int len = parameterValues.size();
-
// resource method or sub-resource method or sub-resource locator
-
ResourceMethodMap<ResourceMethodDescriptor> rmm = resourceFactory.getObjectModel().getResourceMethods();
SubResourceMethodMap srmm = resourceFactory.getObjectModel().getSubResourceMethods();
SubResourceLocatorMap srlm = resourceFactory.getObjectModel().getSubResourceLocators();
if ((parameterValues.get(len - 1) == null || "/".equals(parameterValues.get(len - 1))) && rmm.size() > 0)
{
- // resource method, then process HTTP method and consume/produce media
- // types
-
+ // resource method, then process HTTP method and consume/produce media types
List<ResourceMethodDescriptor> methods = new ArrayList<ResourceMethodDescriptor>();
boolean match = processResourceMethod(rmm, request, response, methods);
if (!match)
{
if (LOG.isDebugEnabled())
- {
LOG.debug("Not found resource method for method " + request.getMethod());
- }
-
return; // Error Response is preset
}
-
invokeResourceMethod(methods.get(0), resource, context, request, response);
-
}
else
{ // sub-resource method/locator
@@ -202,11 +585,8 @@
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
}
@@ -228,7 +608,6 @@
invokeSuResourceLocator(requestPath, locators.get(0), resource, context, request, response);
}
}
-
}
/**
@@ -246,7 +625,6 @@
{
// save resource in hierarchy
context.addMatchedResource(resource);
-
Class<?> returnType = rmd.getResponseType();
MethodInvoker invoker = rmd.getMethodInvoker();
Object o = invoker.invokeMethod(resource, rmd, context);
@@ -271,8 +649,7 @@
context.addMatchedResource(resource);
// save the sub-resource method URI in hierarchy
context.addMatchedURI(requestPath);
- // save parameters values, actually parameters was save before, now just
- // map parameter's names to values
+ // save parameters values, actually parameters was save before, now just map parameter's names to values
context.setParameterNames(srmd.getUriPattern().getParameterNames());
Class<?> returnType = srmd.getResponseType();
@@ -296,13 +673,11 @@
ApplicationContext context, GenericContainerRequest request, GenericContainerResponse response)
{
context.addMatchedResource(resource);
- // take the tail of the request path, the tail will be new request path
- // for lower resources
+ // take the tail of the request path, the tail will be new request path for lower resources
String newRequestPath = getPathTail(context.getParameterValues());
// save the resource class URI in hierarchy
context.addMatchedURI(requestPath.substring(0, requestPath.lastIndexOf(newRequestPath)));
- // save parameters values, actually parameters was save before, now just
- // map parameter's names to values
+ // save parameters values, actually parameters was save before, now just map parameter's names to values
context.setParameterNames(srld.getUriPattern().getParameterNames());
// NOTE Locators can't accept entity
@@ -385,7 +760,6 @@
{
response.setResponse(Response.ok(o, contentType).build());
}
-
}
/**
@@ -465,12 +839,12 @@
}
}
}
-
return true;
}
response.setResponse(Response.status(Response.Status.NOT_ACCEPTABLE).entity("Not Acceptable").type(
MediaType.TEXT_PLAIN).build());
+
return false;
}
@@ -550,7 +924,6 @@
locators.add(e.getValue());
}
}
-
return !locators.isEmpty();
}
@@ -570,9 +943,7 @@
if (resourceFactory == null)
{
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).entity(
"There is no any resources matched to request path " + requestPath).type(MediaType.TEXT_PLAIN).build());
Modified: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/RequestHandlerImpl.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/RequestHandlerImpl.java 2010-11-02 08:53:25 UTC (rev 3374)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/RequestHandlerImpl.java 2010-11-02 08:56:55 UTC (rev 3375)
@@ -23,7 +23,6 @@
import org.exoplatform.container.xml.ValueParam;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
-import org.exoplatform.services.rest.ApplicationContext;
import org.exoplatform.services.rest.ExtHttpHeaders;
import org.exoplatform.services.rest.FilterDescriptor;
import org.exoplatform.services.rest.GenericContainerRequest;
@@ -66,8 +65,9 @@
private static final Log LOG = ExoLogger.getLogger("exo.ws.rest.core.RequestHandlerImpl");
/**
- * Application properties. Properties from this map will be copied to ApplicationContext
- * and may be accessible via method {@link ApplicationContextImpl#getProperties()}.
+ * Application properties. Properties from this map will be copied to
+ * ApplicationContext and may be accessible via method
+ * {@link ApplicationContextImpl#getProperties()}.
*/
private static final Map<String, String> properties = new HashMap<String, String>();
@@ -84,8 +84,13 @@
public static final void setProperty(String name, String value)
{
if (value == null)
+ {
properties.remove(name);
- properties.put(name, value);
+ }
+ else
+ {
+ properties.put(name, value);
+ }
}
/**
@@ -104,9 +109,7 @@
properties.put(vp.getName(), vp.getValue());
}
}
-
this.dispatcher = dispatcher;
-
}
// RequestHandler
@@ -119,12 +122,13 @@
{
try
{
- ApplicationContext context = new ApplicationContextImpl(request, response, ProviderBinder.getInstance());
+ ProviderBinder defaultProviders = ProviderBinder.getInstance();
+ ApplicationContextImpl context = new ApplicationContextImpl(request, response, defaultProviders);
context.getProperties().putAll(properties);
ApplicationContextImpl.setCurrent(context);
- for (ObjectFactory<FilterDescriptor> factory : ProviderBinder.getInstance().getRequestFilters(
- context.getPath()))
+ // Apply default filters only.
+ for (ObjectFactory<FilterDescriptor> factory : defaultProviders.getRequestFilters(context.getPath()))
{
RequestFilter f = (RequestFilter)factory.getInstance(context);
f.doFilter(request);
@@ -132,7 +136,6 @@
try
{
-
dispatcher.dispatch(request, response);
if (response.getHttpHeaders().getFirst(ExtHttpHeaders.JAXRS_BODY_PROVIDED) == null)
{
@@ -142,16 +145,13 @@
response.getHttpHeaders().putSingle(ExtHttpHeaders.JAXRS_BODY_PROVIDED, jaxrsHeader);
}
}
-
}
catch (Exception e)
{
if (e instanceof WebApplicationException)
{
-
Response errorResponse = ((WebApplicationException)e).getResponse();
- ExceptionMapper excmap = ProviderBinder.getInstance().getExceptionMapper(WebApplicationException.class);
-
+ ExceptionMapper excmap = context.getProviders().getExceptionMapper(WebApplicationException.class);
int errorStatus = errorResponse.getStatus();
// should be some of 4xx status
if (errorStatus < 500)
@@ -169,7 +169,6 @@
LOG.warn("WebApplication exception occurs.", e.getCause());
}
}
- // -----
if (errorResponse.getEntity() == null)
{
if (excmap != null)
@@ -201,12 +200,14 @@
{
Throwable cause = e.getCause();
Class causeClazz = cause.getClass();
- ExceptionMapper excmap = ProviderBinder.getInstance().getExceptionMapper(causeClazz);
+ ExceptionMapper excmap = context.getProviders().getExceptionMapper(causeClazz);
while (causeClazz != null && excmap == null)
{
- excmap = ProviderBinder.getInstance().getExceptionMapper(causeClazz);
+ excmap = context.getProviders().getExceptionMapper(causeClazz);
if (excmap == null)
+ {
causeClazz = causeClazz.getSuperclass();
+ }
}
if (excmap != null)
{
@@ -229,15 +230,14 @@
}
}
- for (ObjectFactory<FilterDescriptor> factory : ProviderBinder.getInstance().getResponseFilters(
- context.getPath()))
+ // Apply default filters only.
+ for (ObjectFactory<FilterDescriptor> factory : defaultProviders.getResponseFilters(context.getPath()))
{
ResponseFilter f = (ResponseFilter)factory.getInstance(context);
f.doFilter(response);
}
response.writeResponse();
-
}
finally
{
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-11-02 08:53:25 UTC (rev 3374)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ResourceBinder.java 2010-11-02 08:56:55 UTC (rev 3375)
@@ -23,20 +23,15 @@
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.rest.ApplicationContext;
-import org.exoplatform.services.rest.Filter;
import org.exoplatform.services.rest.ObjectFactory;
import org.exoplatform.services.rest.ObjectModel;
import org.exoplatform.services.rest.PerRequestObjectFactory;
-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.DefaultMethodInvoker;
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;
import org.exoplatform.services.rest.resource.AbstractResourceDescriptor;
-import org.exoplatform.services.rest.resource.ResourceContainer;
import org.exoplatform.services.rest.resource.ResourceDescriptorVisitor;
import org.exoplatform.services.rest.uri.UriPattern;
import org.picocontainer.Startable;
@@ -50,11 +45,6 @@
import javax.ws.rs.Path;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.ext.ContextResolver;
-import javax.ws.rs.ext.ExceptionMapper;
-import javax.ws.rs.ext.MessageBodyReader;
-import javax.ws.rs.ext.MessageBodyWriter;
-import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.RuntimeDelegate;
/**
@@ -176,6 +166,7 @@
protected final ResourceDescriptorVisitor rdv = ResourceDescriptorValidator.getInstance();
/** @see RuntimeDelegate */
+ @Deprecated
protected final RuntimeDelegate rd;
/**
@@ -191,11 +182,14 @@
/** Resource listeners. */
protected final List<ResourceListener> resourceListeners = new ArrayList<ResourceListener>();
+ /**
+ * @deprecated Do not need container here any more.
+ */
protected final ExoContainer container;
public ResourceBinder(ExoContainerContext containerContext) throws Exception
{
- this(containerContext, null);
+ this(containerContext, (MethodInvokerFactory)null);
}
/**
@@ -218,97 +212,16 @@
/**
* @param application Application
* @see Application
+ * @deprecated Use
+ * {@link org.exoplatform.services.rest.impl.ApplicationRegistry#addApplication(Application)}
+ * instead of using this method .
*/
- @SuppressWarnings("unchecked")
public void addApplication(Application application)
{
- ProviderBinder providers = ProviderBinder.getInstance();
- for (Object obj : application.getSingletons())
- {
- if (obj.getClass().getAnnotation(Provider.class) != null)
- {
- // singleton provider
- if (obj instanceof ContextResolver)
- {
- providers.addContextResolver((ContextResolver)obj);
- }
- if (obj instanceof ExceptionMapper)
- {
- providers.addExceptionMapper((ExceptionMapper)obj);
- }
- if (obj instanceof MessageBodyReader)
- {
- providers.addMessageBodyReader((MessageBodyReader)obj);
- }
- if (obj instanceof MessageBodyWriter)
- {
- providers.addMessageBodyWriter((MessageBodyWriter)obj);
- }
- }
- else if (obj.getClass().getAnnotation(Filter.class) != null)
- {
- // singleton filter
- if (obj instanceof MethodInvokerFilter)
- {
- providers.addMethodInvokerFilter((MethodInvokerFilter)obj);
- }
- if (obj instanceof RequestFilter)
- {
- providers.addRequestFilter((RequestFilter)obj);
- }
- if (obj instanceof ResponseFilter)
- {
- providers.addResponseFilter((ResponseFilter)obj);
- }
- }
- else
- {
- addResource(obj, null); // singleton resource
- }
- }
- for (Class clazz : application.getClasses())
- {
- if (clazz.getAnnotation(Provider.class) != null)
- {
- // per-request provider
- if (ContextResolver.class.isAssignableFrom(clazz))
- {
- providers.addContextResolver(clazz);
- }
- if (ExceptionMapper.class.isAssignableFrom(clazz))
- {
- providers.addExceptionMapper(clazz);
- }
- if (MessageBodyReader.class.isAssignableFrom(clazz))
- {
- providers.addMessageBodyReader(clazz);
- }
- if (MessageBodyWriter.class.isAssignableFrom(clazz))
- {
- providers.addMessageBodyWriter(clazz);
- }
- }
- else if (clazz.getAnnotation(Filter.class) != null)
- {
- // per-request filter
- if (MethodInvokerFilter.class.isAssignableFrom(clazz))
- {
- providers.addMethodInvokerFilter(clazz);
- }
- if (RequestFilter.class.isAssignableFrom(clazz))
- {
- providers.addRequestFilter(clazz);
- }
- if (ResponseFilter.class.isAssignableFrom(clazz))
- {
- providers.addResponseFilter(clazz);
- }
- }
- else
- {
- addResource(clazz, null); // per-request resource
- }
- }
+ org.exoplatform.services.rest.impl.ApplicationRegistry appRegistry =
+ (org.exoplatform.services.rest.impl.ApplicationRegistry)container
+ .getComponentInstanceOfType(org.exoplatform.services.rest.impl.ApplicationRegistry.class);
+ appRegistry.addApplication(application);
}
/**
@@ -347,7 +260,9 @@
// validate AbstractResourceDescriptor
descriptor.accept(rdv);
if (properties != null)
+ {
descriptor.getProperties().putAll(properties);
+ }
addResource(new PerRequestObjectFactory<AbstractResourceDescriptor>(descriptor));
}
catch (Exception e)
@@ -392,7 +307,9 @@
// validate AbstractResourceDescriptor
descriptor.accept(rdv);
if (properties != null)
+ {
descriptor.getProperties().putAll(properties);
+ }
addResource(new SingletonObjectFactory<AbstractResourceDescriptor>(descriptor, resource));
}
catch (Exception e)
@@ -534,7 +451,9 @@
resource.getObjectModel().getSubResourceMethods().size()
+ resource.getObjectModel().getSubResourceLocators().size();
if (subresnum == 0)
+ {
continue;
+ }
}
resourceFactory = resource;
break;
@@ -681,37 +600,8 @@
/**
* {@inheritDoc}
*/
- @SuppressWarnings("unchecked")
public void start()
{
- // Lookup Applications
- List<Application> al = container.getComponentInstancesOfType(Application.class);
- for (Application a : al)
- {
- try
- {
- addApplication(a);
- }
- catch (Exception e)
- {
- LOG.error("Failed add JAX-RS application " + a.getClass().getName(), e);
- }
- }
-
- // Lookup all object which implements ResourceContainer interface and
- // process them to be add as root resources.
- for (Object resource : container.getComponentInstancesOfType(ResourceContainer.class))
- {
- try
- {
- addResource(resource, null);
- }
- catch (Exception e)
- {
- LOG.error("Failed add JAX-RS resource " + resource.getClass().getName(), e);
- }
- }
-
startResourceCleaner();
}
@@ -745,4 +635,5 @@
thread.setDaemon(true);
thread.start();
}
+
}
Added: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/StartableApplication.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/StartableApplication.java (rev 0)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/StartableApplication.java 2010-11-02 08:56:55 UTC (rev 3375)
@@ -0,0 +1,108 @@
+/**
+ * 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;
+
+import org.exoplatform.container.ExoContainer;
+import org.exoplatform.container.ExoContainerContext;
+import org.exoplatform.services.rest.RequestFilter;
+import org.exoplatform.services.rest.ResponseFilter;
+import org.exoplatform.services.rest.method.MethodInvokerFilter;
+import org.exoplatform.services.rest.resource.ResourceContainer;
+import org.picocontainer.Startable;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.ws.rs.core.Application;
+import javax.ws.rs.ext.ContextResolver;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.MessageBodyReader;
+import javax.ws.rs.ext.MessageBodyWriter;
+
+/**
+ * Purpose of this component is deliver all JAX-RS components registered in eXo
+ * container to {@link org.exoplatform.services.rest.impl.ApplicationRegistry}.
+ *
+ * @author <a href="mailto:andrew00x at gmail.com">Andrey Parfonov</a>
+ * @version $Id$
+ */
+public class StartableApplication extends Application implements Startable
+{
+
+ private ExoContainer container;
+
+ private Set<Class<?>> cls = new HashSet<Class<?>>();
+
+ private Set<Object> singletons = new HashSet<Object>();
+
+ public StartableApplication(ExoContainerContext containerContext)
+ {
+ container = containerContext.getContainer();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<Class<?>> getClasses()
+ {
+ return cls;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<Object> getSingletons()
+ {
+ return singletons;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void start()
+ {
+ for (Object resource : container.getComponentInstancesOfType(ResourceContainer.class))
+ singletons.add(resource);
+ for (Object resolver : container.getComponentInstancesOfType(ContextResolver.class))
+ singletons.add(resolver);
+ for (Object mapper : container.getComponentInstancesOfType(ExceptionMapper.class))
+ singletons.add(mapper);
+ for (Object reader : container.getComponentInstancesOfType(MessageBodyReader.class))
+ singletons.add(reader);
+ for (Object writer : container.getComponentInstancesOfType(MessageBodyWriter.class))
+ singletons.add(writer);
+ for (Object filter : container.getComponentInstancesOfType(RequestFilter.class))
+ singletons.add(filter);
+ for (Object filter : container.getComponentInstancesOfType(ResponseFilter.class))
+ singletons.add(filter);
+ for (Object filter : container.getComponentInstancesOfType(MethodInvokerFilter.class))
+ singletons.add(filter);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void stop()
+ {
+ }
+
+}
Property changes on: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/StartableApplication.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/provider/JAXBContextResolver.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/provider/JAXBContextResolver.java 2010-11-02 08:53:25 UTC (rev 3374)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/provider/JAXBContextResolver.java 2010-11-02 08:56:55 UTC (rev 3375)
@@ -36,7 +36,7 @@
/**
* Provide cache for {@link JAXBContext}.
- *
+ *
* @author <a href="mailto:andrew00x at gmail.com">Andrey Parfonov</a>
* @version $Id: $
*/
@@ -68,7 +68,7 @@
/**
* Return JAXBContext according to supplied type. If no one context found then
* try create new context and save it in cache.
- *
+ *
* @param classes classes to be bound
* @return JAXBContext
* @throws JAXBException if JAXBContext creation failed
@@ -86,7 +86,7 @@
/**
* Create and add in cache JAXBContext for supplied set of classes.
- *
+ *
* @param classes set of java classes to be bound
* @return JAXBContext
* @throws JAXBException if JAXBContext for supplied classes can't be created
@@ -102,7 +102,7 @@
/**
* Add prepared JAXBContext that will be mapped to set of class. In this case
* this class works as cache for JAXBContexts.
- *
+ *
* @param jaxbctx JAXBContext
* @param classes set of java classes to be bound
*/
@@ -124,6 +124,7 @@
try
{
createJAXBContext(c);
+ //System.out.printf("\nContext for class: {%s}\n\n ", c);
}
catch (JAXBException e)
{
Modified: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/provider/JAXBElementEntityProvider.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/provider/JAXBElementEntityProvider.java 2010-11-02 08:53:25 UTC (rev 3374)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/provider/JAXBElementEntityProvider.java 2010-11-02 08:56:55 UTC (rev 3375)
@@ -63,7 +63,7 @@
* @see Providers
*/
@Context
- private Providers providers;
+ Providers providers;
/**
* {@inheritDoc}
Modified: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/provider/JAXBObjectEntityProvider.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/provider/JAXBObjectEntityProvider.java 2010-11-02 08:53:25 UTC (rev 3374)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/provider/JAXBObjectEntityProvider.java 2010-11-02 08:56:55 UTC (rev 3375)
@@ -62,7 +62,7 @@
* @see Providers
*/
@Context
- private Providers providers;
+ Providers providers;
/**
* {@inheritDoc}
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-11-02 08:53:25 UTC (rev 3374)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/resource/AbstractResourceDescriptorImpl.java 2010-11-02 08:56:55 UTC (rev 3375)
@@ -224,7 +224,7 @@
{
fields.add(new FieldInjectorImpl(resourceClass, jfield));
}
- Class<?> sc = resourceClass;
+ Class<?> sc = resourceClass.getSuperclass();
while (sc != Object.class)
{
for (java.lang.reflect.Field jfield : sc.getDeclaredFields())
Added: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/resource/ApplicationResource.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/resource/ApplicationResource.java (rev 0)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/resource/ApplicationResource.java 2010-11-02 08:56:55 UTC (rev 3375)
@@ -0,0 +1,96 @@
+/**
+ * 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.resource;
+
+import org.exoplatform.services.rest.impl.method.MethodInvokerFactory;
+
+/**
+ * @author <a href="mailto:andrew00x at gmail.com">Andrey Parfonov</a>
+ * @version $Id$
+ */
+public class ApplicationResource extends AbstractResourceDescriptorImpl
+{
+
+ /**
+ * Identifier of application-supplied subclass of
+ * {@link javax.ws.rs.core.Application} via this component was delivered.
+ */
+ private final String applicationId;
+
+ /**
+ * @param applicationId identifier of application-supplied subclass of
+ * {@link javax.ws.rs.core.Application} via this component was
+ * delivered.
+ * @param resourceClass resource class
+ */
+ public ApplicationResource(String applicationId, Class<?> resourceClass)
+ {
+ super(resourceClass);
+ this.applicationId = applicationId;
+ }
+
+ /**
+ * @param applicationId identifier of application-supplied subclass of
+ * {@link javax.ws.rs.core.Application} via this component was
+ * delivered.
+ * @param resourceClass resource class
+ * @param invokerFactory invoker factory
+ */
+ public ApplicationResource(String applicationId, Class<?> resourceClass, MethodInvokerFactory invokerFactory)
+ {
+ super(resourceClass, invokerFactory);
+ this.applicationId = applicationId;
+ }
+
+ /**
+ * @param applicationId identifier of application-supplied subclass of
+ * {@link javax.ws.rs.core.Application} via this component was
+ * delivered.
+ * @param resource resource instance
+ * @param invokerFactory invoker factory
+ */
+ public ApplicationResource(String applicationId, Object resource, MethodInvokerFactory invokerFactory)
+ {
+ super(resource, invokerFactory);
+ this.applicationId = applicationId;
+ }
+
+ /**
+ * @param applicationId identifier of application-supplied subclass of
+ * {@link javax.ws.rs.core.Application} via this component was
+ * delivered.
+ * @param resource resource instance
+ */
+ public ApplicationResource(String applicationId, Object resource)
+ {
+ super(resource);
+ this.applicationId = applicationId;
+ }
+
+ /**
+ * @return identifier (suppose to use FQN) of application-supplied subclass
+ * of {@link javax.ws.rs.core.Application} via this component was
+ * delivered.
+ */
+ public String getApplication()
+ {
+ return applicationId;
+ }
+}
Property changes on: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/resource/ApplicationResource.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/resources/conf/portal/configuration.xml
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/resources/conf/portal/configuration.xml 2010-11-02 08:53:25 UTC (rev 3374)
+++ ws/trunk/exo.ws.rest.core/src/main/resources/conf/portal/configuration.xml 2010-11-02 08:56:55 UTC (rev 3375)
@@ -22,6 +22,15 @@
<configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">
<component>
+ <type>org.exoplatform.services.rest.impl.ApplicationRegistry</type>
+ </component>
+ <component>
+ <type>org.exoplatform.services.rest.impl.StartableApplication</type>
+ </component>
+ <component>
+ <type>org.exoplatform.services.rest.impl.ProvidersRegistry</type>
+ </component>
+ <component>
<type>org.exoplatform.services.rest.impl.RequestHandlerImpl</type>
</component>
<component>
Modified: ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/BaseTest.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/BaseTest.java 2010-11-02 08:53:25 UTC (rev 3374)
+++ ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/BaseTest.java 2010-11-02 08:56:55 UTC (rev 3375)
@@ -22,7 +22,9 @@
import org.exoplatform.container.StandaloneContainer;
import org.exoplatform.services.rest.impl.ApplicationContextImpl;
+import org.exoplatform.services.rest.impl.ApplicationRegistry;
import org.exoplatform.services.rest.impl.ProviderBinder;
+import org.exoplatform.services.rest.impl.ProvidersRegistry;
import org.exoplatform.services.rest.impl.RequestHandlerImpl;
import org.exoplatform.services.rest.impl.ResourceBinder;
import org.exoplatform.services.rest.tools.ResourceLauncher;
@@ -44,18 +46,29 @@
protected ResourceLauncher launcher;
+ protected ApplicationRegistry applicationRegistry;
+
+ protected ProvidersRegistry providersRegistry;
+
public void setUp() throws Exception
{
- StandaloneContainer.setConfigurationPath("src/test/resources/conf/standalone/test-configuration.xml");
+ String conf = getClass().getResource("/conf/standalone/test-configuration.xml").toString();
+ //StandaloneContainer.setConfigurationPath("src/test/resources/conf/standalone/test-configuration.xml");
+ StandaloneContainer.setConfigurationURL(conf);
container = StandaloneContainer.getInstance();
+
+ applicationRegistry = (ApplicationRegistry)container.getComponentInstanceOfType(ApplicationRegistry.class);
binder = (ResourceBinder)container.getComponentInstanceOfType(ResourceBinder.class);
requestHandler = (RequestHandlerImpl)container.getComponentInstanceOfType(RequestHandlerImpl.class);
- // reset providers to be sure it is clean
+ providersRegistry = (ProvidersRegistry)container.getComponentInstanceOfType(ProvidersRegistry.class);
+
+ // reset default providers to be sure it is clean.
ProviderBinder.setInstance(new ProviderBinder());
providers = ProviderBinder.getInstance();
- // System.out.println("##########################"+providers);
+
+ binder.clear();
+
ApplicationContextImpl.setCurrent(new ApplicationContextImpl(null, null, providers));
- binder.clear();
launcher = new ResourceLauncher(requestHandler);
}
Modified: ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/impl/VariantsHandlerTest.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/impl/VariantsHandlerTest.java 2010-11-02 08:53:25 UTC (rev 3374)
+++ ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/impl/VariantsHandlerTest.java 2010-11-02 08:56:55 UTC (rev 3375)
@@ -84,7 +84,7 @@
h.putSingle("Accept-Language", "uk");
r = new ContainerRequest("GET", null, null, null, h);
v = VariantsHandler.handleVariants(r, vs);
- // no language 'uk' in variants and '*/*;q=0.5' removed
+ // no language 'uk' in variants and '*/*;q=0.5' removed
assertNull(v); // 'Not Acceptable' (406) will be generated here
// ---
h.putSingle("Accept", glue("text/xml", "application/xml", "image/*", "text/html;q=0.9", "text/plain;q=0.8"));
Modified: ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/impl/provider/OtherEntityTest.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/impl/provider/OtherEntityTest.java 2010-11-02 08:53:25 UTC (rev 3374)
+++ ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/impl/provider/OtherEntityTest.java 2010-11-02 08:56:55 UTC (rev 3375)
@@ -23,6 +23,7 @@
import org.exoplatform.services.rest.impl.MultivaluedMapImpl;
import org.exoplatform.services.rest.tools.ByteArrayContainerResponseWriter;
import org.w3c.dom.Document;
+import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import java.io.ByteArrayInputStream;
@@ -95,8 +96,11 @@
@Consumes("application/xml")
public void m5(DOMSource dom) throws Exception
{
- assertEquals("root", dom.getNode().getFirstChild().getNodeName());
- assertEquals("hello world", dom.getNode().getFirstChild().getFirstChild().getTextContent());
+ Node root = dom.getNode().getFirstChild();
+ assertEquals("root", root.getNodeName());
+ Node data = root.getFirstChild();
+ assertEquals("data", data.getNodeName());
+ assertEquals("hello world", data.getFirstChild().getNodeValue());
}
@POST
@@ -105,9 +109,11 @@
public void m6(SAXSource sax) throws Exception
{
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(sax.getInputSource());
- assertEquals("root", doc.getDocumentElement().getNodeName());
- assertEquals("data", doc.getDocumentElement().getFirstChild().getNodeName());
- assertEquals("hello world", doc.getDocumentElement().getFirstChild().getTextContent());
+ Node root = doc.getDocumentElement();
+ assertEquals("root", root.getNodeName());
+ Node data = root.getFirstChild();
+ assertEquals("data", data.getNodeName());
+ assertEquals("hello world", data.getFirstChild().getNodeValue());
}
@POST
@@ -116,9 +122,11 @@
public void m7(StreamSource ss) throws Exception
{
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(ss.getInputStream());
- assertEquals("root", doc.getDocumentElement().getNodeName());
- assertEquals("data", doc.getDocumentElement().getFirstChild().getNodeName());
- assertEquals("hello world", doc.getDocumentElement().getFirstChild().getTextContent());
+ Node root = doc.getDocumentElement();
+ assertEquals("root", root.getNodeName());
+ Node data = root.getFirstChild();
+ assertEquals("data", data.getNodeName());
+ assertEquals("hello world", data.getFirstChild().getNodeValue());
}
}
Modified: ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/impl/provider/SourceEntityProviderTest.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/impl/provider/SourceEntityProviderTest.java 2010-11-02 08:53:25 UTC (rev 3374)
+++ ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/impl/provider/SourceEntityProviderTest.java 2010-11-02 08:56:55 UTC (rev 3375)
@@ -128,8 +128,9 @@
new ByteArrayInputStream(data));
Node root = src.getNode().getFirstChild();
assertEquals("root", root.getNodeName());
- assertEquals("message", root.getFirstChild().getNodeName());
- assertEquals("to be or not to be", root.getFirstChild().getTextContent());
+ Node message = root.getFirstChild();
+ assertEquals("message", message.getNodeName());
+ assertEquals("to be or not to be", message.getFirstChild().getNodeValue());
}
@SuppressWarnings("unchecked")
Modified: ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/impl/resource/ApplicationTest.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/impl/resource/ApplicationTest.java 2010-11-02 08:53:25 UTC (rev 3374)
+++ ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/impl/resource/ApplicationTest.java 2010-11-02 08:56:55 UTC (rev 3375)
@@ -24,15 +24,27 @@
import org.exoplatform.services.rest.GenericContainerResponse;
import org.exoplatform.services.rest.RequestFilter;
import org.exoplatform.services.rest.ResponseFilter;
+import org.exoplatform.services.rest.impl.ApplicationProviders;
import org.exoplatform.services.rest.impl.ContainerResponse;
+import org.exoplatform.services.rest.impl.provider.StringEntityProvider;
import org.exoplatform.services.rest.method.MethodInvokerFilter;
import org.exoplatform.services.rest.resource.GenericMethodResource;
+import org.exoplatform.services.rest.tools.ByteArrayContainerResponseWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.GET;
+import javax.ws.rs.POST;
import javax.ws.rs.Path;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
@@ -187,22 +199,28 @@
public void testRegistry()
{
- binder.addApplication(new Application1());
+ Application app = new Application1();
+ //binder.addApplication(app);
+ applicationRegistry.addApplication(app);
assertEquals(4, binder.getSize());
- assertEquals(1, providers.getRequestFilters(null).size());
- assertEquals(1, providers.getResponseFilters(null).size());
- assertEquals(1, providers.getMethodInvokerFilters(null).size());
- assertNotNull(providers.getExceptionMapper(RuntimeException.class));
- assertNotNull(providers.getExceptionMapper(IllegalStateException.class));
+ ApplicationProviders appProviders = providersRegistry.getProviders(app.getClass().getName());
+ assertEquals(1, appProviders.getRequestFilters(null).size());
+ assertEquals(1, appProviders.getResponseFilters(null).size());
+ assertEquals(1, appProviders.getMethodInvokerFilters(null).size());
+ assertNotNull(appProviders.getExceptionMapper(RuntimeException.class));
+ assertNotNull(appProviders.getExceptionMapper(IllegalStateException.class));
}
private static boolean requestFilter = false;
+
private static boolean responseFilter = false;
+
private static boolean invFilter = false;
public void testAsResources() throws Exception
{
- binder.addApplication(new Application1());
+ //binder.addApplication(new Application1());
+ applicationRegistry.addApplication(new Application1());
// per-request
ContainerResponse resp = launcher.service("GET", "/a", "", null, null, null);
assertEquals(200, resp.getStatus());
@@ -239,4 +257,76 @@
assertTrue(invFilter);
}
+ public static class Application2 extends Application
+ {
+
+ private final Set<Class<?>> perreq = new HashSet<Class<?>>();
+
+ private final Set<Object> singletons = new HashSet<Object>();
+
+ public Application2()
+ {
+ perreq.add(Resource5.class);
+ singletons.add(new StringEntityProvider1());
+ }
+
+ @Override
+ public Set<Class<?>> getClasses()
+ {
+ return perreq;
+ }
+
+ @Override
+ public Set<Object> getSingletons()
+ {
+ return singletons;
+ }
+
+ }
+
+ @Path("abc")
+ public static class Resource5
+ {
+ @POST
+ public String m0(String m)
+ {
+ assertEquals(message.toUpperCase(), m);
+ return m;
+ }
+ }
+
+ @Provider
+ public static class StringEntityProvider1 extends StringEntityProvider
+ {
+ @Override
+ public String readFrom(Class<String> type, Type genericType, Annotation[] annotations, MediaType mediaType,
+ MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException
+ {
+ return super.readFrom(type, genericType, annotations, mediaType, httpHeaders, entityStream)
+ .toUpperCase();
+ }
+
+ @Override
+ public void writeTo(String t, Class<?> type, Type genericType, Annotation[] annotations,
+ MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
+ throws IOException
+ {
+ super.writeTo(t.toLowerCase(), type, genericType, annotations, mediaType, httpHeaders, entityStream);
+ }
+ }
+
+ private static final String message = "prOVIDers preFERence";
+
+ public void testProvidersPreference() throws Exception
+ {
+ applicationRegistry.addApplication(new Application2());
+ // If StringEntityProvider1 override default reader/writer for String
+ // then string must be in upper case in service's method.
+ ByteArrayContainerResponseWriter writer = new ByteArrayContainerResponseWriter();
+ ContainerResponse resp = launcher.service("POST", "/abc", "", null, message.getBytes(), writer, null);
+ assertEquals(200, resp.getStatus());
+ // Must be returned in lower case.
+ assertEquals(message.toLowerCase(), new String(writer.getBody()));
+ }
+
}
Modified: ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/wadl/WadlProcessorTest.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/wadl/WadlProcessorTest.java 2010-11-02 08:53:25 UTC (rev 3374)
+++ ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/wadl/WadlProcessorTest.java 2010-11-02 08:56:55 UTC (rev 3375)
@@ -164,7 +164,8 @@
// boolean head = false;
for (int i = 0; i < nl.getLength(); i++)
{
- String t = nl.item(i).getTextContent();
+//System.out.println("\n\n\n\n"+nl.item(i).getClass()+"\n\n\n\n");
+ String t = nl.item(i).getNodeValue();
// if (t.equals("HEAD"))
// head = true;
if (t.equals("GET"))
@@ -173,7 +174,7 @@
// assertTrue(head && get);
assertTrue(get);
for (int i = 0; i < nl.getLength(); i++)
- System.out.println(">>>>> resource method : " + nl.item(i).getTextContent());
+ System.out.println(">>>>> resource method : " + nl.item(i).getNodeValue());
str =
(String)xp.evaluate("//wadl:resource[@path='a/{b}']/wadl:method[@id='m2']/@name", doc, XPathConstants.STRING);
assertEquals("POST", str);
@@ -199,7 +200,7 @@
// boolean subhead = false;
for (int i = 0; i < nl.getLength(); i++)
{
- String t = nl.item(i).getTextContent();
+ String t = nl.item(i).getNodeValue();
// if (t.equals("HEAD"))
// subhead = true;
if (t.equals("GET"))
@@ -208,7 +209,7 @@
// assertTrue(subhead && subget);
assertTrue(subget);
for (int i = 0; i < nl.getLength(); i++)
- System.out.println(">>>>> sub-resource method : " + nl.item(i).getTextContent());
+ System.out.println(">>>>> sub-resource method : " + nl.item(i).getNodeValue());
str =
(String)xp.evaluate("count(//wadl:resource[@path='a/{b}']/wadl:resource[@path='{c}/{d}/{e}']/wadl:method)",
doc, XPathConstants.STRING);
@@ -251,7 +252,7 @@
boolean childopt = false;
for (int i = 0; i < nl.getLength(); i++)
{
- String t = nl.item(i).getTextContent();
+ String t = nl.item(i).getNodeValue();
// if (t.equals("HEAD"))
// childhead = true;
if (t.equals("GET"))
@@ -262,7 +263,7 @@
// assertTrue(childhead && childget && childopt);
assertTrue(childget && childopt);
for (int i = 0; i < nl.getLength(); i++)
- System.out.println(">>>>> child resource method : " + nl.item(i).getTextContent());
+ System.out.println(">>>>> child resource method : " + nl.item(i).getNodeValue());
str =
(String)xp.evaluate("count(//wadl:resource[@path='a/{b}']/wadl:resource[@path='sub/{x}']/wadl:method)", doc,
Modified: ws/trunk/exo.ws.rest.core/src/test/resources/conf/standalone/test-configuration.xml
===================================================================
--- ws/trunk/exo.ws.rest.core/src/test/resources/conf/standalone/test-configuration.xml 2010-11-02 08:53:25 UTC (rev 3374)
+++ ws/trunk/exo.ws.rest.core/src/test/resources/conf/standalone/test-configuration.xml 2010-11-02 08:56:55 UTC (rev 3375)
@@ -52,6 +52,15 @@
</component>
<component>
+ <type>org.exoplatform.services.rest.impl.ApplicationRegistry</type>
+ </component>
+ <component>
+ <type>org.exoplatform.services.rest.impl.StartableApplication</type>
+ </component>
+ <component>
+ <type>org.exoplatform.services.rest.impl.ProvidersRegistry</type>
+ </component>
+ <component>
<type>org.exoplatform.services.rest.impl.RequestHandlerImpl</type>
</component>
<component>
Modified: ws/trunk/exo.ws.rest.ext/src/test/resources/conf/standalone/test-configuration.xml
===================================================================
--- ws/trunk/exo.ws.rest.ext/src/test/resources/conf/standalone/test-configuration.xml 2010-11-02 08:53:25 UTC (rev 3374)
+++ ws/trunk/exo.ws.rest.ext/src/test/resources/conf/standalone/test-configuration.xml 2010-11-02 08:56:55 UTC (rev 3375)
@@ -37,6 +37,15 @@
</init-params>
</component>
+ <component>
+ <type>org.exoplatform.services.rest.impl.ApplicationRegistry</type>
+ </component>
+ <component>
+ <type>org.exoplatform.services.rest.impl.StartableApplication</type>
+ </component>
+ <component>
+ <type>org.exoplatform.services.rest.impl.ProvidersRegistry</type>
+ </component>
<component>
<type>org.exoplatform.services.rest.impl.RequestHandlerImpl</type>
</component>
More information about the exo-jcr-commits
mailing list