[exo-jcr-commits] exo-jcr SVN: r2761 - in ws/trunk: exo.ws.rest.core/src/main/java/org/exoplatform/services/rest and 10 other directories.
do-not-reply at jboss.org
do-not-reply at jboss.org
Fri Jul 9 09:37:31 EDT 2010
Author: aparfonov
Date: 2010-07-09 09:37:30 -0400 (Fri, 09 Jul 2010)
New Revision: 2761
Added:
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ResourcePublicationException.java
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/tools/DummySecurityContext.java
Modified:
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/ObjectModel.java
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ConstructorDescriptorImpl.java
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/FilterDescriptorImpl.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/method/DefaultMethodInvoker.java
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/provider/ProviderDescriptorImpl.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/java/org/exoplatform/services/rest/impl/resource/PathValue.java
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/resource/AbstractResourceDescriptor.java
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/tools/ResourceLauncher.java
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/uri/UriPattern.java
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/ResourceBinderTest.java
ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/uri/UriPatternTest.java
ws/trunk/pom.xml
Log:
EXOJCR-823:
Modified: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/ObjectModel.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/ObjectModel.java 2010-07-09 10:16:44 UTC (rev 2760)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/ObjectModel.java 2010-07-09 13:37:30 UTC (rev 2761)
@@ -20,9 +20,11 @@
import java.util.List;
+import javax.ws.rs.core.MultivaluedMap;
+
/**
* Abstract description of object.
- *
+ *
* @author <a href="mailto:andrew00x at gmail.com">Andrey Parfonov</a>
* @version $Id: $
*/
@@ -30,7 +32,7 @@
{
/**
- * @return collections constructor, MAY return empty collection or null if
+ * @return collections constructor, return empty collection not null if
* object is singleton. There is no setter for this to add new
* ConstructorInjector use
* <code>ObjectModel.getConstructorDescriptors().add(ConstructorInjector)</code>
@@ -38,8 +40,8 @@
List<ConstructorDescriptor> getConstructorDescriptors();
/**
- * @return collections of object fields, MAY return empty collection or null
- * if object is singleton. There is no setter for this to add new
+ * @return collections of object fields, return empty collection not null if
+ * object is singleton. There is no setter for this to add new
* ConstructorInjector use
* <code>ObjectModel.getFieldInjectors().add(FieldInjector)</code>
*/
@@ -50,4 +52,19 @@
*/
Class<?> getObjectClass();
+ /**
+ * @param key
+ * @return property by key
+ * @see #getProperties()
+ */
+ List<String> getProperty(String key);
+
+ /**
+ * Optional attributes.
+ *
+ * @return all properties. If there is no any optional attributes then empty
+ * map returned never <code>null</code>
+ */
+ MultivaluedMap<String, String> getProperties();
+
}
Modified: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ConstructorDescriptorImpl.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ConstructorDescriptorImpl.java 2010-07-09 10:16:44 UTC (rev 2760)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ConstructorDescriptorImpl.java 2010-07-09 13:37:30 UTC (rev 2761)
@@ -233,11 +233,14 @@
}
catch (Exception e)
{
+ String msg = "Not able resolve constructor parameter " + cp;
Class<?> ac = a.annotationType();
if (ac == MatrixParam.class || ac == QueryParam.class || ac == PathParam.class)
- throw new WebApplicationException(e, Response.status(Response.Status.NOT_FOUND).build());
+ throw new WebApplicationException(e, Response.status(Response.Status.NOT_FOUND).entity(msg).type(
+ MediaType.TEXT_PLAIN).build());
- throw new WebApplicationException(e, Response.status(Response.Status.BAD_REQUEST).build());
+ throw new WebApplicationException(e, Response.status(Response.Status.BAD_REQUEST).entity(msg).type(
+ MediaType.TEXT_PLAIN).build());
}
}
else
Modified: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/FilterDescriptorImpl.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/FilterDescriptorImpl.java 2010-07-09 10:16:44 UTC (rev 2760)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/FilterDescriptorImpl.java 2010-07-09 13:37:30 UTC (rev 2761)
@@ -32,6 +32,7 @@
import java.util.List;
import javax.ws.rs.Path;
+import javax.ws.rs.core.MultivaluedMap;
/**
* @author <a href="mailto:andrew00x at gmail.com">Andrey Parfonov</a>
@@ -57,7 +58,7 @@
/**
* Filter class constructors.
- *
+ *
* @see ConstructorDescriptor
*/
private final List<ConstructorDescriptor> constructors;
@@ -67,6 +68,9 @@
*/
private final List<FieldInjector> fields;
+ /** Optional data. */
+ private MultivaluedMap<String, String> properties;
+
/**
* @param filterClass {@link Class} of filter
*/
@@ -173,6 +177,30 @@
/**
* {@inheritDoc}
*/
+ public MultivaluedMap<String, String> getProperties()
+ {
+ if (properties == null)
+ {
+ properties = new MultivaluedMapImpl();
+ }
+ return properties;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<String> getProperty(String key)
+ {
+ if (properties != null)
+ {
+ return properties.get(key);
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public UriPattern getUriPattern()
{
return uriPattern;
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-07-09 10:16:44 UTC (rev 2760)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/RequestDispatcher.java 2010-07-09 13:37:30 UTC (rev 2761)
@@ -62,14 +62,10 @@
public class RequestDispatcher
{
- /**
- * Logger.
- */
+ /** Logger. */
private static final Log LOG = ExoLogger.getLogger("exo.ws.rest.core.RequestDispatcher");
- /**
- * See {@link ResourceBinder}.
- */
+ /** See {@link ResourceBinder}. */
protected final ResourceBinder resourceBinder;
private final MethodInvokerFactory invokerFactory;
@@ -370,7 +366,6 @@
if (returnType == void.class || o == null)
{
response.setResponse(Response.noContent().build());
-
}
else if (Response.class.isAssignableFrom(returnType))
{
@@ -380,19 +375,14 @@
{
r.getMetadata().putSingle(HttpHeaders.CONTENT_TYPE, contentType);
}
-
response.setResponse(r);
-
}
else if (GenericEntity.class.isAssignableFrom(returnType))
{
-
response.setResponse(Response.ok(o, contentType).build());
-
}
else
{
-
response.setResponse(Response.ok(o, contentType).build());
}
@@ -565,60 +555,28 @@
}
/**
- * Get root resource
+ * Get root resource.
*
* @param parameterValues is taken from context
* @param requestPath is taken from context
* @return root resource
+ * @throws WebApplicationException if there is no matched root resources.
+ * Exception with prepared error response with 'Not Found' status
*/
protected ObjectFactory<AbstractResourceDescriptor> getRootResourse(List<String> parameterValues, String requestPath)
{
- ObjectFactory<AbstractResourceDescriptor> resourceFactory = null;
- List<ObjectFactory<AbstractResourceDescriptor>> resources = resourceBinder.getResources();
- // be sure no new entries added
- synchronized (resources)
- {
- for (ObjectFactory<AbstractResourceDescriptor> rc : resources)
- {
- if (rc.getObjectModel().getUriPattern().match(requestPath, parameterValues))
- {
- // all times will at least 1
- int len = parameterValues.size();
- // If capturing group contains last element and this element is
- // neither null nor '/' then ResourceClass must contains at least one
- // sub-resource method or sub-resource locator.
- if (parameterValues.get(len - 1) != null && !parameterValues.get(len - 1).equals("/"))
- {
- int subresnum =
- rc.getObjectModel().getSubResourceMethods().size()
- + rc.getObjectModel().getSubResourceLocators().size();
- if (subresnum == 0)
- {
- continue;
- }
- }
- resourceFactory = rc;
- break;
- }
- }
-
- }
-
+ ObjectFactory<AbstractResourceDescriptor> resourceFactory =
+ resourceBinder.getMatchedResource(requestPath, parameterValues);
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());
}
- else
- {
- return resourceFactory;
- }
+ return resourceFactory;
}
}
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-07-09 10:16:44 UTC (rev 2760)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/RequestHandlerImpl.java 2010-07-09 13:37:30 UTC (rev 2761)
@@ -18,21 +18,6 @@
*/
package org.exoplatform.services.rest.impl;
-import java.io.File;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.StreamingOutput;
-import javax.ws.rs.core.Response.ResponseBuilder;
-import javax.ws.rs.ext.ExceptionMapper;
-
import org.exoplatform.container.component.ComponentPlugin;
import org.exoplatform.container.xml.InitParams;
import org.exoplatform.container.xml.ValueParam;
@@ -53,6 +38,21 @@
import org.exoplatform.services.rest.provider.EntityProvider;
import org.picocontainer.Startable;
+import java.io.File;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.StreamingOutput;
+import javax.ws.rs.core.Response.ResponseBuilder;
+import javax.ws.rs.ext.ExceptionMapper;
+
/**
* @author <a href="mailto:andrew00x at gmail.com">Andrey Parfonov</a>
* @version $Id: $
@@ -67,7 +67,7 @@
/**
* Application properties. Properties from this map will be copied to ApplicationContext
- * and may be accessible via method {@link ApplicationContextImpl#getProperties()}.
+ * and may be accessible via method {@link ApplicationContextImpl#getProperties()}.
*/
private static final Map<String, String> properties = new HashMap<String, String>();
@@ -90,7 +90,7 @@
/**
* Constructs new instance of {@link RequestHandler}.
- *
+ *
* @param dispatcher See {@link RequestDispatcher}
* @param params init parameters
*/
@@ -248,7 +248,7 @@
/**
* Create error response with specified status and body message.
- *
+ *
* @param status response status
* @param message response message
* @return response
@@ -267,7 +267,7 @@
/**
* Get JAXR header for response status.
- *
+ *
* @param status response status
* @return JAXRS header or null.
*/
@@ -372,7 +372,7 @@
/**
* Processing {@link ComponentPlugin} for injection external components.
- *
+ *
* @param plugin See {@link ComponentPlugin}
*/
@SuppressWarnings("unchecked")
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-07-09 10:16:44 UTC (rev 2760)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ResourceBinder.java 2010-07-09 13:37:30 UTC (rev 2761)
@@ -22,12 +22,15 @@
import org.exoplatform.container.ExoContainerContext;
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;
@@ -45,6 +48,7 @@
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;
@@ -64,60 +68,60 @@
public class ResourceBinder
{
- /**
- * Logger.
- */
+ /** Logger. */
private static final Log LOG = ExoLogger.getLogger("exo.ws.rest.core.ResourceBinder");
+ /** Resource's comparator. */
protected static final Comparator<ObjectFactory<AbstractResourceDescriptor>> RESOURCE_COMPARATOR =
- new ResourceComparator();
-
- /**
- * Compare two {@link SingletonResourceFactory}.
- */
- private static final class ResourceComparator implements Comparator<ObjectFactory<AbstractResourceDescriptor>>
- {
- /**
- * Compare two ResourceClass for order.
- *
- * @param o1 first ResourceClass to be compared
- * @param o2 second ResourceClass to be compared
- * @return positive , zero or negative dependent of {@link UriPattern}
- * comparison
- * @see Comparator#compare(Object, Object)
- * @see UriPattern
- * @see UriPattern#URIPATTERN_COMPARATOR
- */
- public int compare(ObjectFactory<AbstractResourceDescriptor> o1, ObjectFactory<AbstractResourceDescriptor> o2)
+ new Comparator<ObjectFactory<AbstractResourceDescriptor>>()
{
- return UriPattern.URIPATTERN_COMPARATOR.compare(o1.getObjectModel().getUriPattern(), o2.getObjectModel()
- .getUriPattern());
- }
- };
+ /**
+ * Compare two ResourceClass for order.
+ *
+ * @param o1 first ResourceClass to be compared
+ * @param o2 second ResourceClass to be compared
+ * @return positive , zero or negative dependent of {@link UriPattern}
+ * comparison
+ * @see Comparator#compare(Object, Object)
+ * @see UriPattern
+ * @see UriPattern#URIPATTERN_COMPARATOR
+ */
+ public int compare(ObjectFactory<AbstractResourceDescriptor> o1, ObjectFactory<AbstractResourceDescriptor> o2)
+ {
+ return UriPattern.URIPATTERN_COMPARATOR.compare(o1.getObjectModel().getUriPattern(), o2.getObjectModel()
+ .getUriPattern());
+ }
+ };
- /**
- * Root resource descriptors.
- */
- protected final List<ObjectFactory<AbstractResourceDescriptor>> rootResources =
- new ArrayList<ObjectFactory<AbstractResourceDescriptor>>();
-
- /**
- * Validator.
- */
+ /** Validator. */
protected final ResourceDescriptorVisitor rdv = ResourceDescriptorValidator.getInstance();
+ /** Amount of available root resources. */
protected int size = 0;
+ /** @see RuntimeDelegate */
+ protected final RuntimeDelegate rd;
+
/**
- * @see RuntimeDelegate
+ * Producer of methods invokers. If not specified then
+ * {@link DefaultMethodInvoker} will be in use.
*/
- protected final RuntimeDelegate rd;
-
protected final MethodInvokerFactory invokerFactory;
+ /** List of all available root resources. */
+ protected final List<ObjectFactory<AbstractResourceDescriptor>> rootResources =
+ new ArrayList<ObjectFactory<AbstractResourceDescriptor>>();
+
+ public ResourceBinder(ExoContainerContext containerContext) throws Exception
+ {
+ this(containerContext, null);
+ }
+
/**
* @param containerContext eXo container context
+ * @param invokerFactory method invoker producer
* @throws Exception if can't set instance of {@link RuntimeDelegate}
+ * @see MethodInvokerFactory
*/
@SuppressWarnings("unchecked")
public ResourceBinder(ExoContainerContext containerContext, MethodInvokerFactory invokerFactory) throws Exception
@@ -127,8 +131,8 @@
// Initialize RuntimeDelegate instance
// This is first component in life cycle what needs.
// TODO better solution to initialize RuntimeDelegate
- rd = new RuntimeDelegateImpl();
- RuntimeDelegate.setInstance(rd);
+ RuntimeDelegate.setInstance(new RuntimeDelegateImpl());
+ rd = RuntimeDelegate.getInstance();
ExoContainer container = containerContext.getContainer();
@@ -150,16 +154,17 @@
// process them to be add as root resources.
for (Object resource : container.getComponentInstancesOfType(ResourceContainer.class))
{
- bind(resource);
+ try
+ {
+ addResource(resource, null);
+ }
+ catch (Exception e)
+ {
+ LOG.error("Failed add JAX-RS resource " + resource.getClass().getName(), e);
+ }
}
-
}
- public ResourceBinder(ExoContainerContext containerContext) throws Exception
- {
- this(containerContext, null);
- }
-
/**
* @param application Application
* @see Application
@@ -208,7 +213,7 @@
}
else
{
- bind(obj); // singleton resource
+ addResource(obj, null); // singleton resource
}
}
for (Class clazz : application.getClasses())
@@ -251,221 +256,252 @@
}
else
{
- bind(clazz); // per-request resource
+ addResource(clazz, null); // per-request resource
}
}
}
/**
- * Register supplied Object as root resource if it has valid JAX-RS
- * annotations and no one resource with the same UriPattern already
+ * Register supplied class as per-request root resource if it has valid
+ * JAX-RS annotations and no one resource with the same UriPattern already
* registered.
*
- * @param resource candidate to be root resource
- * @return true if resource was bound and false if resource was not bound
- * cause it is not root resource
+ * @param resourceClass class of candidate to be root resource
+ * @param properties optional resource properties. It may contains additional
+ * info about resource, e.g. description of resource, its
+ * responsibility, etc. This info can be retrieved
+ * {@link ObjectModel#getProperties()}. This parameter may be
+ * <code>null</code>
+ * @throws ResourcePublicationException if resource can't be published
+ * because to:
+ * <ul>
+ * <li>@javax.ws.rs.Path annotation is missing</li>
+ * <li>resource has not any method with JAX-RS annotations</li>
+ * <li>JAX-RS annotations are ambiguous or invalid</li>
+ * <li>resource with the sane {@link UriPattern} already registered</li>
+ * </ul>
+ * @see ObjectModel#getProperties()
+ * @see ObjectModel#getProperty(String)
*/
- public boolean bind(final Object resource)
+ public void addResource(final Class<?> resourceClass, MultivaluedMap<String, String> properties)
{
- final Path path = resource.getClass().getAnnotation(Path.class);
-
- AbstractResourceDescriptor descriptor = null;
- if (path != null)
+ Path path = resourceClass.getAnnotation(Path.class);
+ if (path == null)
{
- try
- {
- descriptor = new AbstractResourceDescriptorImpl(resource, invokerFactory);
- }
- catch (Exception e)
- {
- String msg = "Unexpected error occurs when process resource class " + resource.getClass().getName();
- LOG.error(msg, e);
- return false;
- }
+ throw new ResourcePublicationException("Resource class " + resourceClass.getName()
+ + " it is not root resource. " + "Path annotation javax.ws.rs.Path is not specified for this class.");
}
- else
+ try
{
- String msg =
- "Resource class " + resource.getClass().getName() + " it is not root resource. "
- + "Path annotation javax.ws.rs.Path is not specified for this class.";
- LOG.warn(msg);
- return false;
+ AbstractResourceDescriptor descriptor = new AbstractResourceDescriptorImpl(resourceClass, invokerFactory);
+ // validate AbstractResourceDescriptor
+ descriptor.accept(rdv);
+ if (properties != null)
+ descriptor.getProperties().putAll(properties);
+ addResource(new PerRequestObjectFactory<AbstractResourceDescriptor>(descriptor));
}
+ catch (Exception e)
+ {
+ throw new ResourcePublicationException(e.getMessage());
+ }
+ }
- // validate AbstractResourceDescriptor
+ /**
+ * Register supplied Object as singleton root resource if it has valid JAX-RS
+ * annotations and no one resource with the same UriPattern already
+ * registered.
+ *
+ * @param resource candidate to be root resource
+ * @param properties optional resource properties. It may contains additional
+ * info about resource, e.g. description of resource, its
+ * responsibility, etc. This info can be retrieved
+ * {@link ObjectModel#getProperties()}. This parameter may be
+ * <code>null</code>
+ * @throws ResourcePublicationException if resource can't be published
+ * because to:
+ * <ul>
+ * <li>@javax.ws.rs.Path annotation is missing</li>
+ * <li>resource has not any method with JAX-RS annotations</li>
+ * <li>JAX-RS annotations are ambiguous or invalid</li>
+ * <li>resource with the sane {@link UriPattern} already registered</li>
+ * </ul>
+ * @see ObjectModel#getProperties()
+ * @see ObjectModel#getProperty(String)
+ */
+ public void addResource(final Object resource, MultivaluedMap<String, String> properties)
+ {
+ Path path = resource.getClass().getAnnotation(Path.class);
+ if (path == null)
+ {
+ throw new ResourcePublicationException("Resource class " + resource.getClass().getName()
+ + " it is not root resource. " + "Path annotation javax.ws.rs.Path is not specified for this class.");
+ }
try
{
+ AbstractResourceDescriptor descriptor = new AbstractResourceDescriptorImpl(resource, invokerFactory);
+ // validate AbstractResourceDescriptor
descriptor.accept(rdv);
+ if (properties != null)
+ descriptor.getProperties().putAll(properties);
+ addResource(new SingletonObjectFactory<AbstractResourceDescriptor>(descriptor, resource));
}
catch (Exception e)
{
- LOG.error("Validation of root resource failed. ", e);
- return false;
+ throw new ResourcePublicationException(e.getMessage());
}
+ }
+ /**
+ * Register supplied root resource if no one resource with the same
+ * UriPattern already registered.
+ *
+ * @param resourceFactory root resource
+ * @throws ResourcePublicationException if resource can't be published
+ * because resource with the sane {@link UriPattern} already
+ * registered
+ */
+ public void addResource(final ObjectFactory<AbstractResourceDescriptor> resourceFactory)
+ {
+ UriPattern pattern = resourceFactory.getObjectModel().getUriPattern();
synchronized (rootResources)
{
- // check does exist other resource with the same URI pattern
- for (ObjectFactory<AbstractResourceDescriptor> exist : rootResources)
+ for (ObjectFactory<AbstractResourceDescriptor> resource : rootResources)
{
- if (exist.getObjectModel().getUriPattern().equals(descriptor.getUriPattern()))
+ if (resource.getObjectModel().getUriPattern().equals(resourceFactory.getObjectModel().getUriPattern()))
{
- String msg =
- "Resource class " + descriptor.getObjectClass().getName() + " can't be registered. Resource class "
- + exist.getClass().getName() + " with the same pattern "
- + exist.getObjectModel().getUriPattern().getTemplate() + " already registered.";
- LOG.warn(msg);
- return false;
+ throw new ResourcePublicationException("Resource class "
+ + resourceFactory.getObjectModel().getObjectClass().getName()
+ + " can't be registered. Resource class " + resource.getObjectModel().getObjectClass().getName()
+ + " with the same pattern " + pattern + " already registered.");
}
}
-
- // Singleton resource
- ObjectFactory<AbstractResourceDescriptor> res =
- new SingletonObjectFactory<AbstractResourceDescriptor>(descriptor, resource);
- rootResources.add(res);
+ rootResources.add(resourceFactory);
Collections.sort(rootResources, RESOURCE_COMPARATOR);
- LOG.info("Bind new resource " + res.getObjectModel().getUriPattern().getTemplate() + " : "
- + descriptor.getObjectClass());
+ size++;
+ if (LOG.isDebugEnabled())
+ LOG.debug("Add resource: " + resourceFactory.getObjectModel());
}
- size++;
- return true;
}
/**
+ * Register root resource.
+ *
* @param resourceClass class of candidate to be root resource
* @return true if resource was bound and false if resource was not bound
* cause it is not root resource
+ * @deprecated use {@link #addResource(Class, MultivaluedMap)} instead
*/
public boolean bind(final Class<?> resourceClass)
{
- final Path path = resourceClass.getAnnotation(Path.class);
-
- AbstractResourceDescriptor descriptor = null;
- if (path != null)
+ try
{
- try
- {
- descriptor = new AbstractResourceDescriptorImpl(resourceClass, invokerFactory);
- }
- catch (Exception e)
- {
- String msg = "Unexpected error occurs when process resource class " + resourceClass.getName();
- LOG.error(msg, e);
- return false;
- }
+ addResource(resourceClass, null);
+ return true;
}
- else
+ catch (ResourcePublicationException e)
{
- String msg =
- "Resource class " + resourceClass.getName() + " it is not root resource. "
- + "Path annotation javax.ws.rs.Path is not specified for this class.";
- LOG.warn(msg);
+ LOG.warn(e.getMessage());
return false;
}
+ }
- // validate AbstractResourceDescriptor
+ /**
+ * Register supplied Object as singleton root resource if it has valid JAX-RS
+ * annotations and no one resource with the same UriPattern already
+ * registered.
+ *
+ * @param resource candidate to be root resource
+ * @return true if resource was bound and false if resource was not bound
+ * cause it is not root resource
+ * @deprecated use {@link #addResource(Object, MultivaluedMap)} instead
+ */
+ public boolean bind(final Object resource)
+ {
try
{
- descriptor.accept(rdv);
+ addResource(resource, null);
+ return true;
}
- catch (Exception e)
+ catch (ResourcePublicationException e)
{
- LOG.error("Validation of root resource failed. ", e);
+ LOG.warn(e.getMessage());
return false;
}
-
- synchronized (rootResources)
- {
- // check does exist other resource with the same URI pattern
- for (ObjectFactory<AbstractResourceDescriptor> exist : rootResources)
- {
- AbstractResourceDescriptor existDescriptor = exist.getObjectModel();
- if (exist.getObjectModel().getUriPattern().equals(descriptor.getUriPattern()))
- {
-
- String msg =
- "Resource class " + descriptor.getObjectClass().getName() + " can't be registered. Resource class "
- + existDescriptor.getObjectClass().getName() + " with the same pattern "
- + exist.getObjectModel().getUriPattern().getTemplate() + " already registered.";
- LOG.warn(msg);
- return false;
- }
- }
- // per-request resource
- ObjectFactory<AbstractResourceDescriptor> res =
- new PerRequestObjectFactory<AbstractResourceDescriptor>(descriptor);
- rootResources.add(res);
- Collections.sort(rootResources, RESOURCE_COMPARATOR);
- LOG.info("Bind new resource " + res.getObjectModel().getUriPattern().getRegex() + " : " + resourceClass);
- }
- size++;
- return true;
}
/**
- * Remove root resource of supplied class from root resource collection.
- *
- * @param clazz root resource class
- * @return true if resource was unbound false otherwise
+ * Clear the list of ResourceContainer description.
*/
- @SuppressWarnings("unchecked")
- public boolean unbind(Class clazz)
+ public void clear()
{
synchronized (rootResources)
{
- Iterator<ObjectFactory<AbstractResourceDescriptor>> i = rootResources.iterator();
- while (i.hasNext())
- {
- ObjectFactory<AbstractResourceDescriptor> res = i.next();
- Class c = res.getObjectModel().getObjectClass();
- if (clazz.equals(c))
- {
- i.remove();
- LOG.info("Remove ResourceContainer " + res.getObjectModel().getUriPattern().getTemplate() + " : " + c);
- size--;
- return true;
- }
- }
- return false;
+ rootResources.clear();
+ size = 0;
}
}
- public boolean unbind(String uriTemplate)
+ /**
+ * Get root resource matched to <code>requestPath</code>.
+ *
+ * @param requestPath request path
+ * @param parameterValues see {@link ApplicationContext#getParameterValues()}
+ * @return root resource matched to <code>requestPath</code> or
+ * <code>null</code>
+ */
+ public ObjectFactory<AbstractResourceDescriptor> getMatchedResource(String requestPath, List<String> parameterValues)
{
+ ObjectFactory<AbstractResourceDescriptor> resourceFactory = null;
synchronized (rootResources)
{
- Iterator<ObjectFactory<AbstractResourceDescriptor>> i = rootResources.iterator();
- while (i.hasNext())
+ for (ObjectFactory<AbstractResourceDescriptor> resource : rootResources)
{
- ObjectFactory<AbstractResourceDescriptor> res = i.next();
- String t = res.getObjectModel().getUriPattern().getTemplate();
- if (t.equals(uriTemplate))
+ if (resource.getObjectModel().getUriPattern().match(requestPath, parameterValues))
{
- i.remove();
- LOG.info("Remove ResourceContainer " + res.getObjectModel().getUriPattern().getTemplate());
- size--;
- return true;
+ // all times will at least 1
+ int len = parameterValues.size();
+ // If capturing group contains last element and this element is
+ // neither null nor '/' then ResourceClass must contains at least one
+ // sub-resource method or sub-resource locator.
+ if (parameterValues.get(len - 1) != null && !parameterValues.get(len - 1).equals("/"))
+ {
+ int subresnum =
+ resource.getObjectModel().getSubResourceMethods().size()
+ + resource.getObjectModel().getSubResourceLocators().size();
+ if (subresnum == 0)
+ continue;
+ }
+ resourceFactory = resource;
+ break;
}
}
- return false;
}
+ return resourceFactory;
}
/**
- * Clear the list of ResourceContainer description.
+ * @return all registered root resources
*/
- public void clear()
+ public List<ObjectFactory<AbstractResourceDescriptor>> getResources()
{
- rootResources.clear();
- size = 0;
+ return rootResources;
}
/**
* @return all registered root resources
*/
- public List<ObjectFactory<AbstractResourceDescriptor>> getResources()
+ @Deprecated
+ public List<AbstractResourceDescriptor> getRootResources()
{
- return rootResources;
+ List<AbstractResourceDescriptor> l = new ArrayList<AbstractResourceDescriptor>(size);
+ synchronized (rootResources)
+ {
+ for (ObjectFactory<AbstractResourceDescriptor> f : rootResources)
+ {
+ l.add(f.getObjectModel());
+ }
+ }
+ return l;
}
/**
@@ -477,20 +513,98 @@
}
/**
- * @return all registered root resources
+ * Remove root resource of supplied class from root resource collection.
+ *
+ * @param clazz root resource class
+ * @return removed resource or <code>null</code> if resource of specified
+ * class not found
*/
- @Deprecated
- public List<AbstractResourceDescriptor> getRootResources()
+ @SuppressWarnings("unchecked")
+ public ObjectFactory<AbstractResourceDescriptor> removeResource(Class clazz)
{
- List<AbstractResourceDescriptor> l = new ArrayList<AbstractResourceDescriptor>(rootResources.size());
+ ObjectFactory<AbstractResourceDescriptor> resource = null;
synchronized (rootResources)
{
- for (ObjectFactory<AbstractResourceDescriptor> f : rootResources)
+ for (Iterator<ObjectFactory<AbstractResourceDescriptor>> iter = rootResources.iterator(); iter.hasNext()
+ && resource == null;)
{
- l.add(f.getObjectModel());
+ ObjectFactory<AbstractResourceDescriptor> next = iter.next();
+ Class<?> resourceClass = next.getObjectModel().getObjectClass();
+ if (clazz.equals(resourceClass))
+ {
+ iter.remove();
+ resource = next;
+ }
}
+ if (resource != null)
+ {
+ size--;
+ if (LOG.isDebugEnabled())
+ LOG.debug("Remove resource: " + resource.getObjectModel());
+ }
}
- return l;
+ return resource;
}
+ /**
+ * Remove root resource with specified UriTemplate from root resource
+ * collection.
+ *
+ * @param path root resource path
+ * @return removed resource or <code>null</code> if resource for specified
+ * template not found
+ */
+ public ObjectFactory<AbstractResourceDescriptor> removeResource(String path)
+ {
+ ObjectFactory<AbstractResourceDescriptor> resource = null;
+ UriPattern pattern = new UriPattern(path);
+ synchronized (rootResources)
+ {
+ for (Iterator<ObjectFactory<AbstractResourceDescriptor>> iter = rootResources.iterator(); iter.hasNext()
+ && resource == null;)
+ {
+ ObjectFactory<AbstractResourceDescriptor> next = iter.next();
+ UriPattern resourcePattern = next.getObjectModel().getUriPattern();
+ if (pattern.equals(resourcePattern))
+ {
+ iter.remove();
+ resource = next;
+ }
+ }
+ if (resource != null)
+ {
+ size--;
+ if (LOG.isDebugEnabled())
+ LOG.debug("Remove resource: " + resource.getObjectModel());
+ }
+ }
+ return resource;
+ }
+
+ /**
+ * Remove root resource of supplied class from root resource collection.
+ *
+ * @param clazz root resource class
+ * @return true if resource was unbound false otherwise
+ * @deprecated use {@link #removeResource(Class)}
+ */
+ @SuppressWarnings("unchecked")
+ public boolean unbind(Class clazz)
+ {
+ return null != removeResource(clazz);
+ }
+
+ /**
+ * Remove root resource with specified UriTemplate from root resource
+ * collection.
+ *
+ * @param path root resource path
+ * @return true if resource was unbound false otherwise
+ * @deprecated use {@link #removeResource(String)} instead
+ */
+ public boolean unbind(String path)
+ {
+ return null != removeResource(path);
+ }
+
}
Added: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ResourcePublicationException.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ResourcePublicationException.java (rev 0)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ResourcePublicationException.java 2010-07-09 13:37:30 UTC (rev 2761)
@@ -0,0 +1,39 @@
+/**
+ * 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;
+
+/**
+ * Throws if root resource can't be published, e.g. resource can't be registered
+ * because to conflict of root path
+ *
+ * @author <a href="mailto:andrew00x at gmail.com">Andrey Parfonov</a>
+ * @version $Id$
+ */
+public class ResourcePublicationException extends RuntimeException
+{
+
+ private static final long serialVersionUID = -7293299406099524107L;
+
+ public ResourcePublicationException(String message)
+ {
+ super(message);
+ }
+
+}
Property changes on: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/ResourcePublicationException.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/method/DefaultMethodInvoker.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/method/DefaultMethodInvoker.java 2010-07-09 10:16:44 UTC (rev 2760)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/method/DefaultMethodInvoker.java 2010-07-09 13:37:30 UTC (rev 2761)
@@ -28,15 +28,16 @@
import org.exoplatform.services.rest.method.MethodInvokerFilter;
import org.exoplatform.services.rest.resource.GenericMethodResource;
-import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
+import java.util.List;
import javax.ws.rs.MatrixParam;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
@@ -84,13 +85,16 @@
catch (Exception e)
{
+ String msg = "Not able resolve method parameter " + mp;
Class<?> ac = a.annotationType();
if (ac == MatrixParam.class || ac == QueryParam.class || ac == PathParam.class)
{
- throw new WebApplicationException(e, Response.status(Response.Status.NOT_FOUND).build());
+ throw new WebApplicationException(e, Response.status(Response.Status.NOT_FOUND).entity(msg).type(
+ MediaType.TEXT_PLAIN).build());
}
- throw new WebApplicationException(e, Response.status(Response.Status.BAD_REQUEST).build());
+ throw new WebApplicationException(e, Response.status(Response.Status.BAD_REQUEST).entity(msg).type(
+ MediaType.TEXT_PLAIN).build());
}
@@ -106,37 +110,62 @@
else
{
MediaType contentType = context.getContainerRequest().getMediaType();
- MultivaluedMap<String, String> headers = context.getContainerRequest().getRequestHeaders();
MessageBodyReader entityReader =
context.getProviders().getMessageBodyReader(mp.getParameterClass(), mp.getGenericType(),
mp.getAnnotations(), contentType);
if (entityReader == null)
{
- if (LOG.isDebugEnabled())
+ List<String> contentLength =
+ context.getContainerRequest().getRequestHeader(HttpHeaders.CONTENT_LENGTH);
+ int length = 0;
+ if (contentLength != null && contentLength.size() > 0)
{
- LOG.warn("Unsupported media type. ");
+ length = Integer.parseInt(contentLength.get(0));
}
- throw new WebApplicationException(Response.status(Response.Status.UNSUPPORTED_MEDIA_TYPE).build());
+ if (contentType == null && length == 0)
+ {
+ // If both Content-Length and Content-Type is not set
+ // consider there is no content. In this case we not able
+ // to determine reader required for content but
+ // 'Unsupported Media Type' (415) status looks strange if
+ // there is no content at all.
+ p[i++] = null;
+ }
+ else
+ {
+ String msg =
+ "Media type " + contentType + " is not supported. There is no corresponded entity reader.";
+ if (LOG.isDebugEnabled())
+ {
+ LOG.warn(msg);
+ }
+ throw new WebApplicationException(Response.status(Response.Status.UNSUPPORTED_MEDIA_TYPE).entity(
+ msg).type(MediaType.TEXT_PLAIN).build());
+ }
}
-
- try
+ else
{
- p[i++] =
- entityReader.readFrom(mp.getParameterClass(), mp.getGenericType(), mp.getAnnotations(),
- contentType, headers, entityStream);
- }
- catch (IOException e)
- {
-
- if (LOG.isDebugEnabled())
+ try
{
- e.printStackTrace();
+ MultivaluedMap<String, String> headers = context.getContainerRequest().getRequestHeaders();
+ p[i++] =
+ entityReader.readFrom(mp.getParameterClass(), mp.getGenericType(), mp.getAnnotations(),
+ contentType, headers, entityStream);
}
-
- throw new InternalException(e);
-
+ catch (Exception e)
+ {
+ if (LOG.isDebugEnabled())
+ {
+ e.printStackTrace();
+ }
+ if (e instanceof WebApplicationException)
+ {
+ throw (WebApplicationException)e;
+ }
+ throw new InternalException(e);
+ }
}
}
}
Modified: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/provider/ProviderDescriptorImpl.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/provider/ProviderDescriptorImpl.java 2010-07-09 10:16:44 UTC (rev 2760)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/provider/ProviderDescriptorImpl.java 2010-07-09 13:37:30 UTC (rev 2761)
@@ -23,6 +23,7 @@
import org.exoplatform.services.rest.FieldInjector;
import org.exoplatform.services.rest.impl.ConstructorDescriptorImpl;
import org.exoplatform.services.rest.impl.FieldInjectorImpl;
+import org.exoplatform.services.rest.impl.MultivaluedMapImpl;
import org.exoplatform.services.rest.impl.header.MediaTypeHelper;
import org.exoplatform.services.rest.provider.ProviderDescriptor;
import org.exoplatform.services.rest.resource.ResourceDescriptorVisitor;
@@ -35,6 +36,7 @@
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
/**
* @author <a href="mailto:andrew00x at gmail.com">Andrey Parfonov</a>
@@ -50,7 +52,7 @@
/**
* Resource class constructors.
- *
+ *
* @see {@link ConstructorDescriptor}
*/
private final List<ConstructorDescriptor> constructors;
@@ -72,6 +74,9 @@
*/
private final List<MediaType> produces;
+ /** Optional data. */
+ private MultivaluedMap<String, String> properties;
+
/**
* @param providerClass provider class
*/
@@ -168,6 +173,30 @@
/**
* {@inheritDoc}
*/
+ public MultivaluedMap<String, String> getProperties()
+ {
+ if (properties == null)
+ {
+ properties = new MultivaluedMapImpl();
+ }
+ return properties;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<String> getProperty(String key)
+ {
+ if (properties != null)
+ {
+ return properties.get(key);
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public List<MediaType> produces()
{
return produces;
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-07-09 10:16:44 UTC (rev 2760)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/resource/AbstractResourceDescriptorImpl.java 2010-07-09 13:37:30 UTC (rev 2761)
@@ -131,9 +131,7 @@
*/
private final List<FieldInjector> fields;
- /**
- * Optional data
- */
+ /** Optional data. */
private MultivaluedMap<String, String> properties;
private final MethodInvokerFactory invokerFactory;
Modified: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/resource/PathValue.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/resource/PathValue.java 2010-07-09 10:16:44 UTC (rev 2760)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl/resource/PathValue.java 2010-07-09 13:37:30 UTC (rev 2761)
@@ -20,7 +20,7 @@
/**
* Describe the Path annotation, see {@link javax.ws.rs.Path}.
- *
+ *
* @author <a href="mailto:andrew00x at gmail.com">Andrey Parfonov</a>
* @version $Id: $
*/
@@ -53,7 +53,7 @@
*/
public String toString()
{
- return "( " + path + " )";
+ return "(" + path + ")";
}
}
Modified: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/resource/AbstractResourceDescriptor.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/resource/AbstractResourceDescriptor.java 2010-07-09 10:16:44 UTC (rev 2760)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/resource/AbstractResourceDescriptor.java 2010-07-09 13:37:30 UTC (rev 2761)
@@ -22,14 +22,10 @@
import org.exoplatform.services.rest.impl.resource.PathValue;
import org.exoplatform.services.rest.uri.UriPattern;
-import java.util.List;
-
-import javax.ws.rs.core.MultivaluedMap;
-
/**
* Describe Resource Class or Root Resource Class. Resource Class is any Java
* class that uses JAX-RS annotations to implement corresponding Web resource.
- *
+ *
* @author <a href="mailto:andrew00x at gmail.com">Andrey Parfonov</a>
* @version $Id: $
*/
@@ -58,21 +54,6 @@
* @return sub-resource methods
*/
SubResourceMethodMap getSubResourceMethods();
-
- /**
- * Optional data
- *
- * @param key
- * @return property by key
- */
- List<String> getProperty(String key);
-
- /**
- * Optional data
- *
- * @return all properties
- */
- MultivaluedMap<String,String> getProperties();
/**
* @return See {@link UriPattern}
Added: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/tools/DummySecurityContext.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/tools/DummySecurityContext.java (rev 0)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/tools/DummySecurityContext.java 2010-07-09 13:37:30 UTC (rev 2761)
@@ -0,0 +1,95 @@
+/**
+ * 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.tools;
+
+import org.exoplatform.services.rest.impl.ContainerRequest;
+
+import java.io.InputStream;
+import java.net.URI;
+import java.security.Principal;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.ws.rs.core.MultivaluedMap;
+
+/**
+ * @author <a href="mailto:andrew00x at gmail.com">Andrey Parfonov</a>
+ * @version $Id$
+ */
+class DummySecurityContext extends ContainerRequest
+{
+ private DummyPrincipal dummyPrincipal;
+
+ public DummySecurityContext(String method, URI requestUri, URI baseUri, InputStream entityStream,
+ MultivaluedMap<String, String> httpHeaders)
+ {
+ super(method, requestUri, baseUri, entityStream, httpHeaders);
+ dummyPrincipal = new DummyPrincipal();
+ }
+
+ @Override
+ public String getAuthenticationScheme()
+ {
+ // Consider as Basic Authentication
+ return BASIC_AUTH;
+ }
+
+ @Override
+ public Principal getUserPrincipal()
+ {
+ return dummyPrincipal;
+ }
+
+ @Override
+ public boolean isSecure()
+ {
+ return false;
+ }
+
+ @Override
+ public boolean isUserInRole(String role)
+ {
+ return dummyPrincipal.isUserInRole(role);
+ }
+
+ class DummyPrincipal implements Principal
+ {
+
+ Set<String> roles = new HashSet<String>();
+
+ public DummyPrincipal()
+ {
+ roles.add("administrators");
+ roles.add("users");
+ }
+
+ public String getName()
+ {
+ return "root";
+ }
+
+ public boolean isUserInRole(String role)
+ {
+ return roles.contains(role);
+ }
+
+ }
+
+}
Property changes on: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/tools/DummySecurityContext.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/tools/ResourceLauncher.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/tools/ResourceLauncher.java 2010-07-09 10:16:44 UTC (rev 2760)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/tools/ResourceLauncher.java 2010-07-09 13:37:30 UTC (rev 2761)
@@ -77,8 +77,10 @@
if (writer == null)
writer = new DummyContainerResponseWriter();
+ // ContainerRequest request =
+ // new ContainerRequest(method, new URI(requestURI), new URI(baseURI), in, new InputHeadersMap(headers));
ContainerRequest request =
- new ContainerRequest(method, new URI(requestURI), new URI(baseURI), in, new InputHeadersMap(headers));
+ new DummySecurityContext(method, new URI(requestURI), new URI(baseURI), in, new InputHeadersMap(headers));
ContainerResponse response = new ContainerResponse(writer);
requestHandler.handleRequest(request, response);
return response;
Modified: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/uri/UriPattern.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/uri/UriPattern.java 2010-07-09 10:16:44 UTC (rev 2760)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/uri/UriPattern.java 2010-07-09 13:37:30 UTC (rev 2761)
@@ -39,10 +39,10 @@
* Sort the templates according to the string comparison of the template
* regular expressions.
* <p>
- * JSR-311 specification: "Sort the set of matching resource classes using the
- * number of characters in the regular expression not resulting from template
- * variables as the primary key and the number of matching groups as a
- * secondary key"
+ * JSR-311 specification: "Sort the set of matching resource classes using
+ * the number of characters in the regular expression not resulting from
+ * template variables as the primary key and the number of matching groups as
+ * a secondary key"
* </p>
*/
public static final Comparator<UriPattern> URIPATTERN_COMPARATOR = new UriPatternComparator();
@@ -76,7 +76,7 @@
if (o1.getNumberOfLiteralCharacters() > o2.getNumberOfLiteralCharacters())
return -1;
- // pattern with two variables less the pattern with four variables
+ // pattern with two variables less the pattern with four variables
if (o1.getParameterNames().size() < o2.getParameterNames().size())
return 1;
if (o1.getParameterNames().size() > o2.getParameterNames().size())
@@ -129,7 +129,7 @@
/**
* Constructs UriPattern.
- *
+ *
* @param template the source template
* @see {@link javax.ws.rs.Path}
*/
@@ -180,12 +180,12 @@
*/
public int hashCode()
{
- return template.hashCode() + regex.hashCode();
+ return getRegex().hashCode();
}
/**
* Get the regex pattern.
- *
+ *
* @return the regex pattern
*/
public Pattern getPattern()
@@ -195,7 +195,7 @@
/**
* Get the URI template as a String.
- *
+ *
* @return the URI template
*/
public String getTemplate()
@@ -205,7 +205,7 @@
/**
* Get the regular expression.
- *
+ *
* @return the regular expression
*/
public String getRegex()
@@ -215,7 +215,7 @@
/**
* Get the number of literal characters in the template.
- *
+ *
* @return number of literal characters in the template
*/
public int getNumberOfLiteralCharacters()
@@ -237,7 +237,7 @@
* greater then number of keys. It can be used for check is resource is
* matching to requested. If resource is match the last element in list must
* be '/' or null.
- *
+ *
* @param uri the URI string
* @param parameters target list
* @return true if URI string is match to pattern, false otherwise
@@ -289,7 +289,7 @@
/**
* Create URI from URI part. Each URI part can contains templates.
- *
+ *
* @param schema the schema URI part
* @param userInfo the user info URI part
* @param host the host name URI part
@@ -299,7 +299,7 @@
* @param fragment the fragment URI part
* @param values the values which must be used instead templates parameters
* @param encode if true then encode value before add it in URI, otherwise
- * value must be validate to legal characters
+ * value must be validate to legal characters
* @return the URI string
*/
public static String createUriWithValues(String schema, String userInfo, String host, int port, String path,
@@ -334,7 +334,7 @@
if (path != null)
{
- if (sb.length() > 0 && path.charAt(0) != '/')
+ if (sb.length() > 0 && path.length() > 0 && path.charAt(0) != '/')
sb.append('/');
appendUriPart(sb, path, UriComponent.PATH, values, encode);
}
@@ -356,7 +356,7 @@
/**
* Create URI from URI part. Each URI part can contains templates.
- *
+ *
* @param schema the schema URI part
* @param userInfo the user info URI part
* @param host the host name URI part
@@ -366,7 +366,7 @@
* @param fragment the fragment URI part
* @param values the values which must be used instead templates parameters
* @param encode if true then encode value before add it in URI, otherwise
- * value must be validate to legal characters
+ * value must be validate to legal characters
* @return the URI string
*/
public static String createUriWithValues(String schema, String userInfo, String host, int port, String path,
@@ -404,7 +404,7 @@
if (path != null)
{
- if (sb.length() > 0 && path.charAt(0) != '/')
+ if (sb.length() > 0 && path.length() > 0 && path.charAt(0) != '/')
sb.append('/');
p = appendUriPart(sb, path, UriComponent.PATH, values, p, m, encode);
}
@@ -431,7 +431,7 @@
* @param component the URI component
* @param values values map
* @param encode if true then encode value before add it in URI, otherwise
- * value must be validate to legal characters
+ * value must be validate to legal characters
*/
private static void appendUriPart(StringBuffer sb, String uriPart, int component,
Map<String, ? extends Object> values, boolean encode)
@@ -471,17 +471,17 @@
* @param component the URI component
* @param sourceValues the source array of values
* @param offset the offset in array
- * @param values values map, keep parameter/value pair which have been already
- * found. From java docs:
- * <p>
- * All instances of the same template parameter will be replaced by
- * the same value that corresponds to the position of the first
- * instance of the template parameter. e.g. the template
- * "{a}/{b}/{a}" with values {"x", "y", "z"} will result in the the
- * URI "x/y/x", <i>not</i> "x/y/z".
- * </p>
+ * @param values values map, keep parameter/value pair which have been
+ * already found. From java docs:
+ * <p>
+ * All instances of the same template parameter will be replaced by
+ * the same value that corresponds to the position of the first
+ * instance of the template parameter. e.g. the template "{a}/{b}/{a}"
+ * with values {"x", "y", "z"} will result in the the URI "x/y/x",
+ * <i>not</i> "x/y/z".
+ * </p>
* @param encode if true then encode value before add it in URI, otherwise
- * value must be validate to legal characters
+ * value must be validate to legal characters
* @return offset
*/
private static int appendUriPart(StringBuffer sb, String uriPart, int component, Object[] sourceValues, int offset,
@@ -539,7 +539,7 @@
/**
* Check does given URI string has templates.
- *
+ *
* @param uri the URI which must be checked
* @return true if URI has templates false otherwise
*/
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-07-09 10:16:44 UTC (rev 2760)
+++ ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/BaseTest.java 2010-07-09 13:37:30 UTC (rev 2761)
@@ -63,28 +63,28 @@
{
}
- public boolean registry(Object resource) throws Exception
+ public void registry(Object resource) throws Exception
{
// container.registerComponentInstance(resource);
- return binder.bind(resource);
+ binder.addResource(resource, null);
}
- public boolean registry(Class<?> resourceClass) throws Exception
+ public void registry(Class<?> resourceClass) throws Exception
{
// container.registerComponentImplementation(resourceClass.getName(), resourceClass);
- return binder.bind(resourceClass);
+ binder.addResource(resourceClass, null);
}
- public boolean unregistry(Object resource)
+ public void unregistry(Object resource)
{
// container.unregisterComponentByInstance(resource);
- return binder.unbind(resource.getClass());
+ binder.removeResource(resource.getClass());
}
- public boolean unregistry(Class<?> resourceClass)
+ public void unregistry(Class<?> resourceClass)
{
// container.unregisterComponent(resourceClass.getName());
- return binder.unbind(resourceClass);
+ binder.removeResource(resourceClass);
}
}
Modified: ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/impl/ResourceBinderTest.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/impl/ResourceBinderTest.java 2010-07-09 10:16:44 UTC (rev 2760)
+++ ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/impl/ResourceBinderTest.java 2010-07-09 13:37:30 UTC (rev 2761)
@@ -45,14 +45,14 @@
public void testBind()
{
- binder.bind(Resource.class);
+ binder.addResource(Resource.class, null);
assertEquals(1, binder.getSize());
}
public void testUnbind()
{
- binder.bind(Resource.class);
- binder.unbind(Resource.class);
+ binder.addResource(Resource.class, null);
+ binder.removeResource(Resource.class);
assertEquals(0, binder.getSize());
}
@@ -95,24 +95,51 @@
public void testSameResourceURI()
{
- assertTrue(binder.bind(SameURIResource1.class));
+ binder.addResource(SameURIResource1.class, null);
assertEquals(1, binder.getSize());
- assertFalse(binder.bind(SameURIResource2.class));
+ try
+ {
+ binder.addResource(SameURIResource2.class, null);
+ }
+ catch (ResourcePublicationException e)
+ {
+ }
assertEquals(1, binder.getSize());
+
binder.clear();
- assertTrue(binder.bind(SameURIResource2.class));
+ binder.addResource(SameURIResource2.class, null);
assertEquals(1, binder.getSize());
- assertFalse(binder.bind(SameURIResource1.class));
+ try
+ {
+ binder.addResource(SameURIResource1.class, null);
+ }
+ catch (ResourcePublicationException e)
+ {
+ }
assertEquals(1, binder.getSize());
+
binder.clear();
- assertTrue(binder.bind(new SameURIResource1()));
+ binder.addResource(new SameURIResource1(), null);
assertEquals(1, binder.getSize());
- assertFalse(binder.bind(new SameURIResource2()));
+ try
+ {
+ binder.addResource(new SameURIResource2(), null);
+ }
+ catch (ResourcePublicationException e)
+ {
+ }
assertEquals(1, binder.getSize());
+
binder.clear();
- assertTrue(binder.bind(new SameURIResource2()));
+ binder.addResource(new SameURIResource2(), null);
assertEquals(1, binder.getSize());
- assertFalse(binder.bind(new SameURIResource1()));
+ try
+ {
+ binder.addResource(new SameURIResource1(), null);
+ }
+ catch (ResourcePublicationException e)
+ {
+ }
assertEquals(1, binder.getSize());
}
Modified: ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/uri/UriPatternTest.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/uri/UriPatternTest.java 2010-07-09 10:16:44 UTC (rev 2760)
+++ ws/trunk/exo.ws.rest.core/src/test/java/org/exoplatform/services/rest/uri/UriPatternTest.java 2010-07-09 13:37:30 UTC (rev 2761)
@@ -129,15 +129,28 @@
}
- private static void testMatch(String pattern, String uri, String[] values)
+ private boolean log = false;
+
+ private void testMatch(String pattern, String uri, String[] values)
{
UriPattern p = new UriPattern(pattern);
- System.out.println("URI: " + uri);
- System.out.println("REGEX: " + p.getRegex());
+ if (log)
+ {
+ System.out.println("URI: " + uri);
+ System.out.println("REGEX: " + p.getRegex());
+ System.out.println("PATTERN: " + pattern);
+ System.out.println("TEMPLATE: " + p.getTemplate());
+ }
+
List<String> l = new ArrayList<String>();
assertTrue(p.match(uri, l));
- System.out.println("PARAMETERS: " + p.getParameterNames());
- System.out.println("VARIABLES: " + l);
+
+ if (log)
+ {
+ System.out.println("PARAMETERS: " + p.getParameterNames());
+ System.out.println("VARIABLES: " + l);
+ System.out.println();
+ }
assertEquals(values.length, l.size());
int i = 0;
for (String t : l)
Modified: ws/trunk/pom.xml
===================================================================
--- ws/trunk/pom.xml 2010-07-09 10:16:44 UTC (rev 2760)
+++ ws/trunk/pom.xml 2010-07-09 13:37:30 UTC (rev 2761)
@@ -1,11 +1,23 @@
+ <!--
- <!--
+ Copyright (C) 2009 eXo Platform SAS.
- 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.
- -->
+ 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.
+
+ -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
More information about the exo-jcr-commits
mailing list