exo-jcr SVN: r3376 - ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/provider.
by do-not-reply@jboss.org
Author: aparfonov
Date: 2010-11-02 04:59:39 -0400 (Tue, 02 Nov 2010)
New Revision: 3376
Added:
ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/provider/ExtendedProviders.java
Log:
EXOJCR-1024
Added: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/provider/ExtendedProviders.java
===================================================================
--- ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/provider/ExtendedProviders.java (rev 0)
+++ ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/provider/ExtendedProviders.java 2010-11-02 08:59:39 UTC (rev 3376)
@@ -0,0 +1,68 @@
+/*
+ * 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.provider;
+
+import org.exoplatform.services.rest.FilterDescriptor;
+import org.exoplatform.services.rest.ObjectFactory;
+import org.exoplatform.services.rest.impl.header.MediaTypeHelper;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.List;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.ext.Providers;
+
+/**
+ * @author <a href="andrew00x(a)gmail.com">Andrey Parfonov</a>
+ * @version $Id$
+ */
+public interface ExtendedProviders extends Providers
+{
+
+ /**
+ * Get list of most acceptable writer's media type for specified type.
+ *
+ * @param type type
+ * @param genericType generic type
+ * @param annotations annotations
+ * @return sorted acceptable media type collection
+ * @see MediaTypeHelper#MEDIA_TYPE_COMPARATOR
+ */
+ List<MediaType> getAcceptableWriterMediaTypes(Class<?> type, Type genericType, Annotation[] annotations);
+
+ /**
+ * @param path request path
+ * @return acceptable method invocation filters
+ */
+ List<ObjectFactory<FilterDescriptor>> getMethodInvokerFilters(String path);
+
+ /**
+ * @param path request path
+ * @return acceptable request filters
+ */
+ List<ObjectFactory<FilterDescriptor>> getRequestFilters(String path);
+
+ /**
+ * @param path request path
+ * @return acceptable response filters
+ */
+ List<ObjectFactory<FilterDescriptor>> getResponseFilters(String path);
+
+}
Property changes on: ws/trunk/exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/provider/ExtendedProviders.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
13 years, 6 months
exo-jcr SVN: r3375 - in ws/trunk: exo.ws.rest.core/src/main/java/org/exoplatform/services/rest/impl and 10 other directories.
by do-not-reply@jboss.org
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@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(a)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@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@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(a)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@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@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@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>
13 years, 6 months
exo-jcr SVN: r3374 - in jcr/trunk/exo.jcr.component.ftp/src/main/java/org/exoplatform/services/ftp: client and 1 other directories.
by do-not-reply@jboss.org
Author: dkuleshov
Date: 2010-11-02 04:53:25 -0400 (Tue, 02 Nov 2010)
New Revision: 3374
Modified:
jcr/trunk/exo.jcr.component.ftp/src/main/java/org/exoplatform/services/ftp/FtpServer.java
jcr/trunk/exo.jcr.component.ftp/src/main/java/org/exoplatform/services/ftp/FtpServerImpl.java
jcr/trunk/exo.jcr.component.ftp/src/main/java/org/exoplatform/services/ftp/FtpServiceImpl.java
jcr/trunk/exo.jcr.component.ftp/src/main/java/org/exoplatform/services/ftp/client/FtpClientSessionImpl.java
jcr/trunk/exo.jcr.component.ftp/src/main/java/org/exoplatform/services/ftp/command/FtpCommandImpl.java
Log:
EXOJCR-1014: now FTP server does show list of workspaces after repository restoring
Modified: jcr/trunk/exo.jcr.component.ftp/src/main/java/org/exoplatform/services/ftp/FtpServer.java
===================================================================
--- jcr/trunk/exo.jcr.component.ftp/src/main/java/org/exoplatform/services/ftp/FtpServer.java 2010-11-02 07:25:50 UTC (rev 3373)
+++ jcr/trunk/exo.jcr.component.ftp/src/main/java/org/exoplatform/services/ftp/FtpServer.java 2010-11-02 08:53:25 UTC (rev 3374)
@@ -45,6 +45,10 @@
int getClientsCount();
+ /**
+ *
+ * @return {@link ManageableRepository} or <code>null</code> if repository can not be retrieved
+ */
ManageableRepository getRepository();
FtpCommand getCommand(String commandName);
Modified: jcr/trunk/exo.jcr.component.ftp/src/main/java/org/exoplatform/services/ftp/FtpServerImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.ftp/src/main/java/org/exoplatform/services/ftp/FtpServerImpl.java 2010-11-02 07:25:50 UTC (rev 3373)
+++ jcr/trunk/exo.jcr.component.ftp/src/main/java/org/exoplatform/services/ftp/FtpServerImpl.java 2010-11-02 08:53:25 UTC (rev 3374)
@@ -26,6 +26,8 @@
import org.exoplatform.services.ftp.config.FtpConfig;
import org.exoplatform.services.ftp.data.FtpDataChannelManager;
import org.exoplatform.services.ftp.data.FtpDataChannelManagerImpl;
+import org.exoplatform.services.jcr.RepositoryService;
+import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
import org.exoplatform.services.jcr.core.ManageableRepository;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
@@ -37,6 +39,8 @@
import java.net.Socket;
import java.util.ArrayList;
+import javax.jcr.RepositoryException;
+
/**
* Created by The eXo Platform SAS Author : Vitaly Guly <gavrik-vetal(a)ukr.net/mail.ru>
*
@@ -52,7 +56,7 @@
private Catalog commandCatalog;
- private ManageableRepository repository;
+ private RepositoryService repositoryService;
private FtpConfig configuration;
@@ -62,11 +66,11 @@
private ArrayList<FtpClientSession> clients = new ArrayList<FtpClientSession>();
- public FtpServerImpl(FtpConfig configuration, CommandService commandService, ManageableRepository repository)
+ public FtpServerImpl(FtpConfig configuration, CommandService commandService, RepositoryService repositoryService)
throws Exception
{
this.configuration = configuration;
- this.repository = repository;
+ this.repositoryService = repositoryService;
InputStream commandStream = getClass().getResourceAsStream(COMMAND_PATH);
@@ -153,7 +157,21 @@
public ManageableRepository getRepository()
{
- return repository;
+
+ try
+ {
+ return repositoryService.getDefaultRepository();
+ }
+ catch (RepositoryException e)
+ {
+ log.info("Repository exception. " + e.getMessage(), e);
+ }
+ catch (RepositoryConfigurationException e)
+ {
+ log.info("Repository configuration exception. " + e.getMessage(), e);
+ }
+
+ return null;
}
public FtpCommand getCommand(String commandName)
Modified: jcr/trunk/exo.jcr.component.ftp/src/main/java/org/exoplatform/services/ftp/FtpServiceImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.ftp/src/main/java/org/exoplatform/services/ftp/FtpServiceImpl.java 2010-11-02 07:25:50 UTC (rev 3373)
+++ jcr/trunk/exo.jcr.component.ftp/src/main/java/org/exoplatform/services/ftp/FtpServiceImpl.java 2010-11-02 08:53:25 UTC (rev 3374)
@@ -61,7 +61,7 @@
log.info("Start service.");
try
{
- ftpServer = new FtpServerImpl(config, commandService, repositoryService.getRepository());
+ ftpServer = new FtpServerImpl(config, commandService, repositoryService);
ftpServer.start();
}
catch (Exception e)
Modified: jcr/trunk/exo.jcr.component.ftp/src/main/java/org/exoplatform/services/ftp/client/FtpClientSessionImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.ftp/src/main/java/org/exoplatform/services/ftp/client/FtpClientSessionImpl.java 2010-11-02 07:25:50 UTC (rev 3373)
+++ jcr/trunk/exo.jcr.component.ftp/src/main/java/org/exoplatform/services/ftp/client/FtpClientSessionImpl.java 2010-11-02 08:53:25 UTC (rev 3374)
@@ -329,6 +329,10 @@
public Session getSession(String workspaceName) throws Exception
{
+ if (ftpServer.getRepository() == null)
+ {
+ throw new RepositoryException("Repository can not be retrieved.");
+ }
Session curSession = sessionFactory.getSession(workspaceName, ftpServer.getRepository());
curSession.refresh(false);
return curSession;
Modified: jcr/trunk/exo.jcr.component.ftp/src/main/java/org/exoplatform/services/ftp/command/FtpCommandImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.ftp/src/main/java/org/exoplatform/services/ftp/command/FtpCommandImpl.java 2010-11-02 07:25:50 UTC (rev 3373)
+++ jcr/trunk/exo.jcr.component.ftp/src/main/java/org/exoplatform/services/ftp/command/FtpCommandImpl.java 2010-11-02 08:53:25 UTC (rev 3374)
@@ -111,6 +111,10 @@
{
if (newPath.size() == 0)
{
+ if (clientSession().getFtpServer().getRepository() == null)
+ {
+ throw new RepositoryException("Repository can not be retrieved.");
+ }
String[] workspaces = clientSession().getFtpServer().getRepository().getWorkspaceNames();
for (int i = 0; i < workspaces.length; i++)
{
13 years, 6 months
exo-jcr SVN: r3373 - in jcr/branches/1.14-CNK/exo.jcr.component.core: src/main/java/org/exoplatform/services/jcr/impl/core/query and 6 other directories.
by do-not-reply@jboss.org
Author: nzamosenchuk
Date: 2010-11-02 03:25:50 -0400 (Tue, 02 Nov 2010)
New Revision: 3373
Added:
jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/chunk/
jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/chunk/ChunkIndexerCacheLoader.java
jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/chunk/ChunkService.java
jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/chunk/ChunkServiceImpl.java
jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/chunk/JBossCacheChunkIndexChangesFilter.java
jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/PersistentIndexChunk.java
Modified:
jcr/branches/1.14-CNK/exo.jcr.component.core/pom.xml
jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/AbstractQueryHandler.java
jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/QueryHandler.java
jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/ChunkIndex.java
jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java
jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/AbstractWriteOnlyCacheLoader.java
jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/PrivilegedCacheHelper.java
jcr/branches/1.14-CNK/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-jbosscache-indexer.xml
jcr/branches/1.14-CNK/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-jcr-config.xml
Log:
EXOJCR-987 : POC commit. Nodes can join and leave the cluster. Some places contain hardcode and woraround, that are acceptable for now
Modified: jcr/branches/1.14-CNK/exo.jcr.component.core/pom.xml
===================================================================
--- jcr/branches/1.14-CNK/exo.jcr.component.core/pom.xml 2010-11-01 10:50:31 UTC (rev 3372)
+++ jcr/branches/1.14-CNK/exo.jcr.component.core/pom.xml 2010-11-02 07:25:50 UTC (rev 3373)
@@ -30,7 +30,7 @@
<name>eXo JCR :: Component :: Core Service</name>
<description>eXo JCR Service core component</description>
<properties>
- <jcr.test.configuration.file>/conf/standalone/test-configuration.xml</jcr.test.configuration.file>
+ <jcr.test.configuration.file>/conf/standalone/cluster/test-configuration.xml</jcr.test.configuration.file>
<jbosscache.shareable>true</jbosscache.shareable>
</properties>
<dependencies>
@@ -434,6 +434,9 @@
<exclude>org/exoplatform/services/jcr/**/impl/**/SQLBenchmarkTest.java</exclude>
<exclude>org/exoplatform/services/jcr/**/impl/**/TestLockPerstistentDataManager.java</exclude>
<exclude>org/exoplatform/services/jcr/**/impl/**/TestCleanableFileStreamValueData.java</exclude>
+ <!-- After restore - default changes filter is used, so no ChunkService injected into serachManager, but
+ ChunkIndex is hardcoded and requires ChunkService -->
+ <exclude>org/exoplatform/services/jcr/**/TestSVNodeDataOptimization.java</exclude>
</excludes>
</configuration>
</plugin>
Modified: jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/AbstractQueryHandler.java
===================================================================
--- jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/AbstractQueryHandler.java 2010-11-01 10:50:31 UTC (rev 3372)
+++ jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/AbstractQueryHandler.java 2010-11-02 07:25:50 UTC (rev 3373)
@@ -18,6 +18,7 @@
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
import org.exoplatform.services.jcr.datamodel.NodeData;
+import org.exoplatform.services.jcr.impl.core.query.jbosscache.chunk.ChunkService;
import org.exoplatform.services.jcr.impl.core.query.lucene.ChunkIndex;
import org.exoplatform.services.jcr.impl.core.query.lucene.DefaultIndexUpdateMonitor;
import org.exoplatform.services.jcr.impl.core.query.lucene.IndexInfos;
@@ -74,6 +75,12 @@
*/
protected IndexInfos indexInfos;
+ /**
+ * TODO: re-view this part of dependency delivery
+ * Temporary solution to deliver ChunkService to ChunkIndex (former MultiIndex)
+ */
+ protected ChunkService chunkService;
+
private IndexUpdateMonitor indexUpdateMonitor;
public boolean isInitialized()
@@ -82,6 +89,22 @@
}
/**
+ * @see org.exoplatform.services.jcr.impl.core.query.QueryHandler#getChunkService()
+ */
+ public ChunkService getChunkService()
+ {
+ return chunkService;
+ }
+
+ /**
+ * @see org.exoplatform.services.jcr.impl.core.query.QueryHandler#setChunkService(org.exoplatform.services.jcr.impl.core.query.jbosscache.chunk.ChunkService)
+ */
+ public void setChunkService(ChunkService chunkService)
+ {
+ this.chunkService = chunkService;
+ }
+
+ /**
* @see org.exoplatform.services.jcr.impl.core.query.QueryHandler#setIndexerIoModeHandler(org.exoplatform.services.jcr.impl.core.query.IndexerIoModeHandler)
*/
public void setIndexerIoModeHandler(IndexerIoModeHandler modeHandler) throws IOException
@@ -209,6 +232,7 @@
*
* @param idleTime the query handler idle time.
*/
+ @Deprecated
public void setIdleTime(String idleTime)
{
log.warn("Parameter 'idleTime' is not supported anymore. "
Modified: jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/QueryHandler.java
===================================================================
--- jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/QueryHandler.java 2010-11-01 10:50:31 UTC (rev 3372)
+++ jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/QueryHandler.java 2010-11-02 07:25:50 UTC (rev 3373)
@@ -21,6 +21,7 @@
import org.exoplatform.services.jcr.datamodel.NodeData;
import org.exoplatform.services.jcr.impl.core.SessionDataManager;
import org.exoplatform.services.jcr.impl.core.SessionImpl;
+import org.exoplatform.services.jcr.impl.core.query.jbosscache.chunk.ChunkService;
import org.exoplatform.services.jcr.impl.core.query.lucene.ChunkIndex;
import org.exoplatform.services.jcr.impl.core.query.lucene.IndexInfos;
import org.exoplatform.services.jcr.impl.core.query.lucene.IndexUpdateMonitor;
@@ -161,7 +162,7 @@
* @param indexInfos
*/
void setIndexInfos(IndexInfos indexInfos);
-
+
/**
* Returns {@link IndexInfos} instance that was set into QueryHandler.
* @return
@@ -178,4 +179,16 @@
*/
void setIndexUpdateMonitor(IndexUpdateMonitor indexUpdateMonitor);
+ /**
+ * Temporary solution to deliver {@link ChunkService} to {@link ChunkIndex} (former MultiIndex)
+ * @param chunkService
+ */
+ void setChunkService(ChunkService chunkService);
+
+ /**
+ * Temporary solution to deliver {@link ChunkService} to {@link ChunkIndex} (former MultiIndex)
+ * @return
+ */
+ ChunkService getChunkService();
+
}
Added: jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/chunk/ChunkIndexerCacheLoader.java
===================================================================
--- jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/chunk/ChunkIndexerCacheLoader.java (rev 0)
+++ jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/chunk/ChunkIndexerCacheLoader.java 2010-11-02 07:25:50 UTC (rev 3373)
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 2003-2009 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.core.query.jbosscache.chunk;
+
+import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.impl.core.query.QueryHandler;
+import org.exoplatform.services.jcr.impl.core.query.SearchManager;
+import org.exoplatform.services.jcr.impl.core.query.jbosscache.ChangesFilterListsWrapper;
+import org.exoplatform.services.jcr.impl.storage.jbosscache.AbstractWriteOnlyCacheLoader;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.Modification;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jcr.RepositoryException;
+
+/**
+ * @author <a href="mailto:nikolazius@gmail.com">Nikolay Zamosenchuk</a>
+ * @version $Id: IndexerCacheLoader.java 34360 2009-07-22 23:58:59Z nzamosenchuk $
+ *
+ */
+public class ChunkIndexerCacheLoader extends AbstractWriteOnlyCacheLoader
+{
+ private static final Log log = ExoLogger.getLogger("exo.jcr.component.core.IndexerCacheLoader");
+
+ /**
+ * A map of all the indexers that has been registered
+ */
+ private final Map<Fqn<String>, Indexer> indexers = new HashMap<Fqn<String>, Indexer>();
+
+ /**
+ * @see org.jboss.cache.loader.AbstractCacheLoader#commit(java.lang.Object)
+ */
+ @Override
+ public void commit(Object tx) throws Exception
+ {
+ // do nothing. Everything is done on prepare phase.
+ }
+
+ /**
+ * This method will register a new Indexer according to the given parameters.
+ *
+ * @param searchManager
+ * @param parentSearchManager
+ * @param handler
+ * @param parentHandler
+ * @throws RepositoryConfigurationException
+ */
+ public void register(SearchManager searchManager, SearchManager parentSearchManager, QueryHandler handler,
+ QueryHandler parentHandler, ChunkService chunkService) throws RepositoryConfigurationException
+ {
+ indexers.put(Fqn.fromElements(searchManager.getWsId()), new Indexer(searchManager, parentSearchManager, handler,
+ parentHandler, chunkService));
+ if (log.isDebugEnabled())
+ {
+ log.debug("Register " + searchManager.getWsId() + " " + this + " in " + indexers);
+ }
+ }
+
+ /**
+ * @see org.jboss.cache.loader.CacheLoader#put(org.jboss.cache.Fqn, java.lang.Object, java.lang.Object)
+ */
+ public Object put(Fqn name, Object key, Object value) throws Exception
+ {
+ return null;
+ }
+
+ /**
+ * @see org.exoplatform.services.jcr.impl.storage.jbosscache.AbstractWriteOnlyCacheLoader#put(org.jboss.cache.Fqn, java.util.Map)
+ */
+ public void put(Fqn fqn, Map<Object, Object> data) throws Exception
+ {
+ // ignoring call cacheRoot.addChild(PARAMETER_ROOT).setResident(true);
+ if (log.isDebugEnabled())
+ {
+ log.info("Received list wrapper, start indexing...");
+ }
+
+ // TODO Review it!!
+ if (fqn.getLastElementAsString().equals(ChunkServiceImpl.CHUNK_LIST))
+ {
+ // skipping all the rest of the code if service data written
+ log.info("skipping fqn " + fqn);
+ return;
+ }
+
+ Set<Integer> processingChunks = null;
+
+ ChunkService chunkService = null;
+
+ Indexer indexer = indexers.get(fqn.getParent());
+ if (indexer == null)
+ {
+ log.warn("No indexer could be found for the fqn " + fqn.getParent());
+ if (log.isDebugEnabled())
+ {
+ log.debug("The current content of the map of indexers is " + indexers);
+ }
+ }
+ else
+ {
+ try
+ {
+ // updating index
+ ChangesFilterListsWrapper wrapper =
+ new ChangesFilterListsWrapper(new HashSet<String>(), new HashSet<String>(), new HashSet<String>(),
+ new HashSet<String>());
+
+ // combine wrappers. Aggregating them into one wrapper, to pass through SearchManager and SearchIndex
+ chunkService = indexer.getChunkService();
+ processingChunks = chunkService.getAssignedChunks(true);
+ chunkService.acquireJob();
+
+ for (Integer chunkId : processingChunks)
+ {
+ ChangesFilterListsWrapper wrapperPart = (ChangesFilterListsWrapper)data.get(chunkId);
+ if (wrapperPart != null)
+ {
+ wrapper.getAddedNodes().addAll((wrapperPart).getAddedNodes());
+ wrapper.getParentAddedNodes().addAll((wrapperPart).getParentAddedNodes());
+ wrapper.getRemovedNodes().addAll((wrapperPart).getRemovedNodes());
+ wrapper.getParentRemovedNodes().addAll((wrapperPart).getParentRemovedNodes());
+ }
+ }
+ indexer.updateIndex(wrapper.getAddedNodes(), wrapper.getRemovedNodes(), wrapper.getParentAddedNodes(),
+ wrapper.getParentRemovedNodes());
+ }
+ finally
+ {
+ if (chunkService != null)
+ {
+ chunkService.releaseJob();
+ }
+ // removing processed chunk jobs
+ if (processingChunks != null)
+ {
+ for (Integer chunkId : processingChunks)
+ {
+ cache.remove(fqn, chunkId);
+ }
+ }
+ // if no attributes present in JBC node remove it.
+ if (cache.getNode(fqn).getKeys().isEmpty())
+ {
+ cache.removeNode(fqn);
+ }
+ }
+ }
+
+ }
+
+ /**
+ * @see org.exoplatform.services.jcr.impl.storage.jbosscache.AbstractWriteOnlyCacheLoader#put(java.util.List)
+ */
+ @Override
+ public void put(List<Modification> modifications) throws Exception
+ {
+ // do nothing. Index is updated on prepare phase.
+ }
+
+ /**
+ * @see org.jboss.cache.loader.CacheLoader#remove(org.jboss.cache.Fqn)
+ */
+ public void remove(Fqn arg0) throws Exception
+ {
+ // do nothing
+ }
+
+ @Override
+ public void removeData(Fqn arg0) throws Exception
+ {
+ log.info("REMOVE DATA: FQN = " + arg0);
+ }
+
+ /**
+ * This class will update the indexes of the related workspace
+ */
+ private static class Indexer
+ {
+
+ private final SearchManager searchManager;
+
+ private final SearchManager parentSearchManager;
+
+ private final QueryHandler handler;
+
+ private final QueryHandler parentHandler;
+
+ private final ChunkService chunkService;
+
+ public Indexer(SearchManager searchManager, SearchManager parentSearchManager, QueryHandler handler,
+ QueryHandler parentHandler, ChunkService chunkService) throws RepositoryConfigurationException
+ {
+ this.searchManager = searchManager;
+ this.parentSearchManager = parentSearchManager;
+ this.handler = handler;
+ this.parentHandler = parentHandler;
+ this.chunkService = chunkService;
+ }
+
+ public ChunkService getChunkService()
+ {
+ return chunkService;
+ }
+
+ /**
+ * Flushes lists of added/removed nodes to SearchManagers, starting indexing.
+ *
+ * @param addedNodes
+ * @param removedNodes
+ * @param parentAddedNodes
+ * @param parentRemovedNodes
+ */
+ protected void updateIndex(Set<String> addedNodes, Set<String> removedNodes, Set<String> parentAddedNodes,
+ Set<String> parentRemovedNodes)
+ {
+ // pass lists to search manager
+ if (searchManager != null && (addedNodes.size() > 0 || removedNodes.size() > 0))
+ {
+ try
+ {
+ searchManager.updateIndex(removedNodes, addedNodes);
+ }
+ catch (RepositoryException e)
+ {
+ log.error("Error indexing changes " + e, e);
+ }
+ catch (IOException e)
+ {
+ log.error("Error indexing changes " + e, e);
+ try
+ {
+ handler.logErrorChanges(removedNodes, addedNodes);
+ }
+ catch (IOException ioe)
+ {
+ log.warn("Exception occure when errorLog writed. Error log is not complete. " + ioe, ioe);
+ }
+ }
+ }
+ // pass lists to parent search manager
+ if (parentSearchManager != null && (parentAddedNodes.size() > 0 || parentRemovedNodes.size() > 0))
+ {
+ try
+ {
+ parentSearchManager.updateIndex(parentRemovedNodes, parentAddedNodes);
+ }
+ catch (RepositoryException e)
+ {
+ log.error("Error indexing changes " + e, e);
+ }
+ catch (IOException e)
+ {
+ log.error("Error indexing changes " + e, e);
+ try
+ {
+ parentHandler.logErrorChanges(removedNodes, addedNodes);
+ }
+ catch (IOException ioe)
+ {
+ log.warn("Exception occure when errorLog writed. Error log is not complete. " + ioe, ioe);
+ }
+ }
+ }
+ }
+ }
+}
Property changes on: jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/chunk/ChunkIndexerCacheLoader.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/chunk/ChunkService.java
===================================================================
--- jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/chunk/ChunkService.java (rev 0)
+++ jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/chunk/ChunkService.java 2010-11-02 07:25:50 UTC (rev 3373)
@@ -0,0 +1,87 @@
+/*
+ * 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.jcr.impl.core.query.jbosscache.chunk;
+
+import org.exoplatform.services.jcr.impl.core.query.IndexerIoModeHandler;
+
+import java.util.Set;
+
+/**
+ * This service defines all the methods needed to be able to:
+ * <ul>
+ * <li>split the Lucene indexes into several chunks</li>
+ * <li>assign the chunks to a cluster node</li>
+ * <li>assign JCR Node to a chunk</li>
+ * </ul>
+ *
+ * @author Nicolas Filotto
+ * @author <a href="mailto:nikolazius@gmail.com">Nikolay Zamosenchuk</a>
+ * @version $Id: ChunkService.java 34360 2009-07-22 23:58:59Z nzamosenchuk $
+ *
+ */
+public interface ChunkService
+{
+
+ /**
+ * Returns the configured number of index chunks
+ * @return number of chunks
+ */
+ int getChunkCount();
+
+ /**
+ * Gives the id of the chunk corresponding to the given node id
+ * @param nodeId the node Id for which we want to find the corresponding chunk id
+ * @return the corresponding chunk index
+ */
+ int getChunkId(String nodeId);
+
+ /**
+ * TODO review this method
+ * Gives the full list of all the ids of chunks managed by the local machine
+ * @param blocking block current thread is reassigning is in progress
+ * @return the list of chunk ids managed by the local machine
+ */
+ Set<Integer> getAssignedChunks(boolean blocking);
+
+ /**
+ * Returns the instance of {@link IndexerIoModeHandler} managed by {@link ChunkService}. So
+ * {@link ChunkService} instance has an ability to control indexer I/O mode.
+ * @return instance of IndexerIoModeHandler
+ */
+ IndexerIoModeHandler getModeHandler();
+
+ /**
+ * Must be threadsafe! Notifies {@link ChunkService} that one more thread is working
+ * for indexing now. This is a job tracking feature. It is responsible for releasing
+ * and re-acquiring IndexChunks when cluster view changes. {@link ChunkService} must be
+ * aware of indexes that can be released and re-assigned to another JCR instance. After
+ * cluster view changed and no more jobs are currently than Chunks are marked as free.
+ */
+ void acquireJob();
+
+ /**
+ * Must be threadsafe! Notifies {@link ChunkService} that one thread is no more
+ * working for indexing now. This is a job tracking feature. It is responsible for releasing
+ * and re-acquiring IndexChunks when cluster view changes. {@link ChunkService} must be
+ * aware of indexes that can be released and re-assigned to another JCR instance. After
+ * cluster view changed and no more jobs are currently than Chunks are marked as free.
+ */
+ void releaseJob();
+
+}
\ No newline at end of file
Property changes on: jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/chunk/ChunkService.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/chunk/ChunkServiceImpl.java
===================================================================
--- jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/chunk/ChunkServiceImpl.java (rev 0)
+++ jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/chunk/ChunkServiceImpl.java 2010-11-02 07:25:50 UTC (rev 3373)
@@ -0,0 +1,406 @@
+/*
+ * 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.jcr.impl.core.query.jbosscache.chunk;
+
+import org.exoplatform.services.jcr.impl.core.query.IndexerIoMode;
+import org.exoplatform.services.jcr.impl.core.query.IndexerIoModeHandler;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+import org.jboss.cache.Cache;
+import org.jboss.cache.CacheSPI;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.Node;
+import org.jboss.cache.notifications.annotation.CacheListener;
+import org.jboss.cache.notifications.annotation.NodeModified;
+import org.jboss.cache.notifications.annotation.ViewChanged;
+import org.jboss.cache.notifications.event.NodeModifiedEvent;
+import org.jboss.cache.notifications.event.NodeRemovedEvent;
+import org.jboss.cache.notifications.event.ViewChangedEvent;
+import org.jboss.cache.notifications.event.NodeModifiedEvent.ModificationType;
+import org.jgroups.Address;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * ASSIGNING:
+ * 1. {@link ChunkServiceImpl#onClusterViewChanged(ViewChangedEvent)} : notification to start ASSIGNING process, block {@link ChunkServiceImpl#getAssignedChunks()}
+ * 2. wait until all local threads invokes {@link ChunkServiceImpl#releaseJob()}
+ * 3. cleanup corresponding attributes in cache and the whole JBC node if attributes are empty (Chunk<-->ClusterNode attributes).
+ * Set IOMode read only
+ * 4. if JBC node was removed by local machine - ({@link ChunkServiceImpl#onNodeRemoved(NodeRemovedEvent)}) assign chunks, unblock, set IOMode write
+ * 5. Else, if {@link ChunkServiceImpl#onNodeModified(NodeModifiedEvent)} then read map and unblock, set IOMode write
+ *
+ * @author <a href="mailto:nikolazius@gmail.com">Nikolay Zamosenchuk</a>
+ * @version $Id: ChunkServiceImpl.java 34360 2009-07-22 23:58:59Z nzamosenchuk $
+ *
+ */
+@CacheListener
+public class ChunkServiceImpl implements ChunkService
+{
+ public static final String CHUNK_LIST = "$chunks";
+
+ private static final Log log = ExoLogger.getLogger("exo.jcr.component.core.ChunkService");
+
+ private final IndexerIoModeHandler modeHandler;
+
+ private int chunkNum;
+
+ private final AtomicInteger jobCount = new AtomicInteger(0);
+
+ private final Cache<Serializable, Object> cache;
+
+ private final Fqn rootFqn;
+
+ private ServiceState state;
+
+ private Object reassigninMonitor = new Object();
+
+ private Set<Integer> currentlyAssigned;
+
+ private List<Address> clusterView;
+
+ public ChunkServiceImpl(int chunkNum, Cache<Serializable, Object> cache, Fqn rootFqn)
+ {
+ super();
+ this.chunkNum = chunkNum;
+ this.cache = cache;
+ this.cache.addCacheListener(this);
+ this.modeHandler = new IndexerIoModeHandler(IndexerIoMode.READ_ONLY);
+ this.rootFqn = rootFqn;
+ this.currentlyAssigned = new HashSet<Integer>();
+ this.state = ServiceState.ASSIGNING;
+ clusterView = new ArrayList<Address>(cache.getMembers());
+ Collections.sort(clusterView);
+ // first initial start
+ Map<Serializable, Object> data = cache.getData(Fqn.fromElements(rootFqn, CHUNK_LIST));
+ if (data == null || data.isEmpty())
+ {
+ log.info(rootFqn + "\t creating ChunkSErviceImpl, doing init...");
+ doAssign();
+ }
+ else
+ {
+ log.info(rootFqn + "\t creating ChunkSErviceImpl, skipping init...");
+ if (data.size() == chunkNum)
+ {
+ log.info(rootFqn + "\t creating ChunkSErviceImpl, reading:" + data);
+ Address local = cache.getLocalAddress();
+ // if local address already present in data map - then it has been already assugned
+ for (Object address : data.values())
+ {
+ if (local.equals(address))
+ {
+ readAssigned(data);
+ doFinishAssign();
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ private void doStartAssign(List<Address> members)
+ {
+ // mark index as ASSIGNING
+ // Waiting till all the local jobs finished
+ if (this.state != ServiceState.ASSIGNING)
+ {
+ this.state = ServiceState.ASSIGNING;
+ // cleaning currently assigned chunks
+ log.info(rootFqn.toString() + "\tdoStartAssign. Members = " + members.toString());
+
+ if (((CacheSPI)cache).getRPCManager().isCoordinator())
+ {
+ log.info(rootFqn.toString() + "\tonCLusterViewChanged cleaning suspected member");
+ // cleaning up suspected member
+ if (((CacheSPI)cache).getRPCManager().isCoordinator())
+ {
+ for (Address address : clusterView)
+ {
+ Map<Serializable, Object> data = cache.getData(Fqn.fromElements(rootFqn, CHUNK_LIST));
+ if (!members.contains(address))
+ {
+ // this member is suspected
+ // trying to remove information about chunks used by it
+ for (Integer i = 0; i < chunkNum; i++)
+ {
+ if (data.get(i) != null && data.get(i).equals(address))
+ {
+ cache.remove(Fqn.fromElements(rootFqn, CHUNK_LIST), i);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (jobCount.get() == 0)
+ {
+ doReleaseChunks();
+ }
+ }
+ }
+
+ private void doAssign()
+ {
+ List<Address> members = new ArrayList<Address>(cache.getMembers());
+ Collections.sort(members);
+ log.info(rootFqn.toString() + "\tdoAssign. Members = " + members.toString());
+
+ Address localAddress = cache.getLocalAddress();
+
+ if (members.size() == 0)
+ {
+ throw new UnsupportedOperationException("List of memebers is empty. Not yet implemented usecase.");
+ }
+ {
+ log.info(rootFqn.toString() + "\tdoAssign. LocalMachine is coordinator, performing...");
+ // initializing the list of chunks in cache
+ Map<Integer, Address> chunkDistribution = new HashMap<Integer, Address>();
+ int clusterSize = members.size();
+ for (Integer i = 0; i < chunkNum; i++)
+ {
+ chunkDistribution.put(i, members.get(i % clusterSize));
+ if (members.get(i % clusterSize).equals(localAddress))
+ {
+ currentlyAssigned.add(i);
+ }
+ }
+ log.info(rootFqn.toString() + "\tdoAssign. Putting ChunkDistribution = " + chunkDistribution.toString());
+ this.cache.put(Fqn.fromElements(rootFqn, CHUNK_LIST), chunkDistribution);
+ log.info(rootFqn.toString() + "\tdoAssign. Put done ");
+ //this.cache.getNode(Fqn.fromElements(rootFqn, CHUNK_LIST)).setResident(true);
+ doFinishAssign();
+ }
+ }
+
+ private void readAssigned(Map<Serializable, Object> chunkDistribution)
+ {
+ {
+ // read in local variable current chunks
+ Address localAddress = cache.getLocalAddress();
+ // TODO
+ if (currentlyAssigned.isEmpty())
+ {
+ //Map<Serializable, Object> chunkDistribution = cache.getData(Fqn.fromElements(rootFqn, CHUNK_LIST));
+ for (Integer i = 0; i < chunkNum; i++)
+ {
+ if (chunkDistribution.get(i) != null && chunkDistribution.get(i).equals(localAddress))
+ {
+ currentlyAssigned.add(i);
+ }
+ }
+ }
+ }
+ }
+
+ private void doFinishAssign()
+ {
+ log.info(rootFqn.toString() + "\tdoFinishAssign: currentlyAssigned: " + currentlyAssigned);
+ this.state = ServiceState.NORMAL;
+ modeHandler.setMode(IndexerIoMode.READ_WRITE);
+ synchronized (reassigninMonitor)
+ {
+ log.info(rootFqn.toString() + "\tdoFinishAssign. ASSIGNING finished: Notifying");
+ reassigninMonitor.notifyAll();
+ }
+ }
+
+ /**
+ * Closes indexWriters on owning indexes and cleans up corresponding items from map: Map<Chunk, CluserNode>
+ * stored in cache.
+ */
+ private void doReleaseChunks()
+ {
+ // Notifies ChunkIndex to release indexes
+ modeHandler.setMode(IndexerIoMode.READ_ONLY);
+ // clean up Map<Chunk, CluserNode>
+ Iterator<Integer> it = currentlyAssigned.iterator();
+ log.info(rootFqn.toString() + "\tdoReleaseChunks. Removing from info cache...");
+ try
+ {
+ Thread.sleep(4000);
+ }
+ catch (InterruptedException e1)
+ {
+ // TODO Auto-generated catch block
+ e1.printStackTrace();
+ }
+ while (it.hasNext())
+ {
+ Integer chunkId = it.next();
+ Object remove = this.cache.remove(Fqn.fromElements(rootFqn, CHUNK_LIST), chunkId);
+ if (remove == null)
+ {
+ System.out.println("NULL RETURNED BY REMOVE " + rootFqn + " " + chunkId);
+ }
+ }
+ log.info(rootFqn.toString() + "\tdoReleaseChunks. Removed info ");
+ currentlyAssigned.clear();
+ // if this is the last one cluster machine releasing it's chunks - clean the node containing info about chunks.
+ Node listNode = this.cache.getNode(Fqn.fromElements(rootFqn, CHUNK_LIST));
+ if (listNode != null && listNode.getData().isEmpty())
+ {
+ try
+ {
+ log.info(rootFqn.toString() + "\tdoReleaseChunks. Removing node ");
+
+ this.cache.removeNode(Fqn.fromElements(rootFqn, CHUNK_LIST));
+ log.info(rootFqn.toString() + "\tdoReleaseChunks. Removed node ");
+ doAssign();
+ }
+ catch (Exception e)
+ {
+ System.out.println("EXCEPTION FOUND:");
+ e.printStackTrace();
+ }
+ }
+ else
+ {
+ if (listNode != null)
+ {
+ log.info("not removed!!! WS=" + rootFqn + " " + listNode.getData() + " localaddr="
+ + cache.getLocalAddress());
+ }
+ }
+ }
+
+ /**
+ * @see org.exoplatform.services.jcr.impl.core.query.jbosscache.chunk.ChunkService#getAssignedChunks()
+ */
+ public Set<Integer> getAssignedChunks(boolean blocking)
+ {
+ // Block until chunk transfer not finished
+ if (state != ServiceState.NORMAL && blocking)
+ {
+ synchronized (reassigninMonitor)
+ {
+ log.info(rootFqn.toString() + "\tgetAssignedChunks. Waitning ASSIGNING finished");
+ while (state != ServiceState.NORMAL)
+ {
+ try
+ {
+ reassigninMonitor.wait();
+ }
+ catch (InterruptedException e)
+ {
+ log.error("InterruptedException");
+ }
+ }
+ }
+ log.info(rootFqn.toString() + "\tgetAssignedChunks. ASSIGNING finished: Working");
+ }
+ return new HashSet<Integer>(currentlyAssigned);
+ }
+
+ /**
+ * @see org.exoplatform.services.jcr.impl.core.query.jbosscache.chunk.ChunkService#getChunkCount()
+ */
+ public int getChunkCount()
+ {
+ return chunkNum;
+ }
+
+ /**
+ * @see org.exoplatform.services.jcr.impl.core.query.jbosscache.chunk.ChunkService#getChunkId(java.lang.String)
+ */
+ public int getChunkId(String nodeId)
+ {
+ return Math.abs(nodeId.hashCode()) % chunkNum;
+ }
+
+ /**
+ * @see org.exoplatform.services.jcr.impl.core.query.jbosscache.chunk.ChunkService#acquireJob()
+ */
+ public void acquireJob()
+ {
+ jobCount.incrementAndGet();
+ }
+
+ /**
+ * @see org.exoplatform.services.jcr.impl.core.query.jbosscache.chunk.ChunkService#releaseJob()
+ */
+ public void releaseJob()
+ {
+ int currentJobs = jobCount.decrementAndGet();
+ if (this.state == ServiceState.ASSIGNING && currentJobs == 0)
+ {
+ // all local threads finished their jobs, so indexes can be released
+ doReleaseChunks();
+ }
+ }
+
+ /**
+ * @see org.exoplatform.services.jcr.impl.core.query.jbosscache.chunk.ChunkService#getModeHandler()
+ */
+ public IndexerIoModeHandler getModeHandler()
+ {
+ return modeHandler;
+ }
+
+ /**
+ * Listener, receiving the events, when cluster changes
+ * @param e
+ */
+ @ViewChanged
+ public void onClusterViewChanged(ViewChangedEvent e)
+ {
+ List<Address> members = new ArrayList<Address>(e.getNewView().getMembers());
+ Collections.sort(members);
+ if (!e.isPre())
+ {
+ log.info(rootFqn.toString() + "\tonCLusterViewChanged doing start assign");
+ // initiate the process of ASSIGNING
+ doStartAssign(members);
+ }
+ }
+
+ /**
+ * Listener, receiving the events, when node is modified. It handles only events when
+ *
+ * @param e
+ */
+ @NodeModified
+ public void onNodeModified(NodeModifiedEvent e)
+ {
+ // if this modification is PUT_MAP belongs to /WS1/CHUNK_LISTS and current state is ASSIGNING
+ if (!e.isPre() && this.state == ServiceState.ASSIGNING
+ && e.getFqn().equals(Fqn.fromElements(rootFqn, CHUNK_LIST))
+ && e.getModificationType() == ModificationType.PUT_MAP)
+ {
+ // re-assigning is about to finish. Map<Chunk, ClusterNode> already filled
+ readAssigned(e.getData());
+ doFinishAssign();
+ }
+ }
+
+ private enum ServiceState {
+ NORMAL, ASSIGNING;
+ }
+
+}
Property changes on: jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/chunk/ChunkServiceImpl.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/chunk/JBossCacheChunkIndexChangesFilter.java
===================================================================
--- jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/chunk/JBossCacheChunkIndexChangesFilter.java (rev 0)
+++ jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/chunk/JBossCacheChunkIndexChangesFilter.java 2010-11-02 07:25:50 UTC (rev 3373)
@@ -0,0 +1,252 @@
+/*
+ * 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.jcr.impl.core.query.jbosscache.chunk;
+
+import org.exoplatform.container.configuration.ConfigurationManager;
+import org.exoplatform.services.jcr.config.QueryHandlerEntry;
+import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.impl.core.query.IndexerChangesFilter;
+import org.exoplatform.services.jcr.impl.core.query.IndexerIoModeHandler;
+import org.exoplatform.services.jcr.impl.core.query.IndexingTree;
+import org.exoplatform.services.jcr.impl.core.query.QueryHandler;
+import org.exoplatform.services.jcr.impl.core.query.SearchManager;
+import org.exoplatform.services.jcr.impl.core.query.jbosscache.ChangesFilterListsWrapper;
+import org.exoplatform.services.jcr.impl.util.io.PrivilegedCacheHelper;
+import org.exoplatform.services.jcr.jbosscache.ExoJBossCacheFactory;
+import org.exoplatform.services.jcr.jbosscache.ExoJBossCacheFactory.CacheType;
+import org.exoplatform.services.jcr.util.IdGenerator;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+import org.jboss.cache.Cache;
+import org.jboss.cache.CacheException;
+import org.jboss.cache.CacheSPI;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.config.CacheLoaderConfig;
+import org.jboss.cache.config.CacheLoaderConfig.IndividualCacheLoaderConfig;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jcr.RepositoryException;
+
+/**
+ * @author <a href="mailto:Sergey.Kabashnyuk@exoplatform.org">Sergey Kabashnyuk</a>
+ * @version $Id: exo-jboss-codetemplates.xml 34360 2009-07-22 23:58:59Z ksm $
+ *
+ */
+public class JBossCacheChunkIndexChangesFilter extends IndexerChangesFilter
+{
+ /**
+ * Logger instance for this class
+ */
+ private final Log log = ExoLogger.getLogger("exo.jcr.component.core.JBossCacheIndexChangesFilter");
+
+ public static final String PARAM_JBOSSCACHE_CONFIGURATION = "jbosscache-configuration";
+
+ public static final String PARAM_JBOSSCACHE_PUSHSTATE = "jbosscache-sscl-push.state.enabled";
+
+ public static final String PARAM_JBOSSCACHE_PUSHSTATE_TIMEOUT = "jbosscache-sscl-push.state.timeout";
+
+ /**
+ * Indicate whether the JBoss Cache instance used can be shared with other caches
+ */
+ public static final String PARAM_JBOSSCACHE_SHAREABLE = "jbosscache-shareable";
+
+ public static final Boolean PARAM_JBOSSCACHE_SHAREABLE_DEFAULT = Boolean.FALSE;
+
+ private final Cache<Serializable, Object> cache;
+
+ private final Fqn<String> rootFqn;
+
+ public static final String LISTWRAPPER = "$lists".intern();
+
+ private final ChunkService chunkService;
+
+ /**
+ * @param searchManager
+ * @param config
+ * @param indexingTree
+ * @throws RepositoryConfigurationException
+ */
+ public JBossCacheChunkIndexChangesFilter(SearchManager searchManager, SearchManager parentSearchManager,
+ QueryHandlerEntry config, IndexingTree indexingTree, IndexingTree parentIndexingTree, QueryHandler handler,
+ QueryHandler parentHandler, ConfigurationManager cfm) throws IOException, RepositoryException,
+ RepositoryConfigurationException
+ {
+ super(searchManager, parentSearchManager, config, indexingTree, parentIndexingTree, handler, parentHandler, cfm);
+ // create cache using custom factory
+ ExoJBossCacheFactory<Serializable, Object> factory = new ExoJBossCacheFactory<Serializable, Object>(cfm);
+ Cache<Serializable, Object> initCache = factory.createCache(config);
+
+ // initialize IndexerCacheLoader
+ ChunkIndexerCacheLoader indexerCacheLoader = new ChunkIndexerCacheLoader();
+
+ // create CacheLoaderConfig
+ IndividualCacheLoaderConfig individualCacheLoaderConfig = new IndividualCacheLoaderConfig();
+ // set CacheLoader
+ individualCacheLoaderConfig.setCacheLoader(indexerCacheLoader);
+ // set parameters
+ individualCacheLoaderConfig.setFetchPersistentState(false);
+ individualCacheLoaderConfig.setAsync(false);
+ individualCacheLoaderConfig.setIgnoreModifications(false);
+ individualCacheLoaderConfig.setPurgeOnStartup(false);
+ // create CacheLoaderConfig
+ CacheLoaderConfig cacheLoaderConfig = new CacheLoaderConfig();
+ cacheLoaderConfig.setShared(false);
+ cacheLoaderConfig.setPassivation(false);
+ cacheLoaderConfig.addIndividualCacheLoaderConfig(individualCacheLoaderConfig);
+ // insert CacheLoaderConfig
+ initCache.getConfiguration().setCacheLoaderConfig(cacheLoaderConfig);
+ this.rootFqn = Fqn.fromElements(searchManager.getWsId());
+ this.cache =
+ ExoJBossCacheFactory.getUniqueInstance(CacheType.INDEX_CACHE, rootFqn, initCache, config.getParameterBoolean(
+ PARAM_JBOSSCACHE_SHAREABLE, PARAM_JBOSSCACHE_SHAREABLE_DEFAULT));
+
+ PrivilegedCacheHelper.create(cache);
+ PrivilegedCacheHelper.start(cache);
+
+ this.chunkService = new ChunkServiceImpl(4, cache, rootFqn);
+
+ indexerCacheLoader = (ChunkIndexerCacheLoader)((CacheSPI)cache).getCacheLoaderManager().getCacheLoader();
+ indexerCacheLoader.register(searchManager, parentSearchManager, handler, parentHandler, this.chunkService);
+ // TODO Dummy IOModeHandler
+ IndexerIoModeHandler modeHandler = chunkService.getModeHandler(); //new IndexerIoModeHandler(IndexerIoMode.READ_WRITE);
+ handler.setIndexerIoModeHandler(modeHandler);
+ parentHandler.setIndexerIoModeHandler(modeHandler);
+
+ // TODO: review this injection
+ handler.setChunkService(chunkService);
+ parentHandler.setChunkService(chunkService);
+
+ if (!parentHandler.isInitialized())
+ {
+ parentHandler.init();
+ }
+ if (!handler.isInitialized())
+ {
+ handler.init();
+ }
+ }
+
+ /**
+ * @see org.exoplatform.services.jcr.impl.core.query.IndexerChangesFilter#doUpdateIndex(java.util.Set, java.util.Set, java.util.Set, java.util.Set)
+ */
+ @Override
+ protected void doUpdateIndex(Set<String> removedNodes, Set<String> addedNodes, Set<String> parentRemovedNodes,
+ Set<String> parentAddedNodes)
+ {
+ String id = IdGenerator.generate();
+ try
+ {
+ // this map contains ChangesListWrapper in it's values. Key is the index of Chunk,
+ // starting from 0.
+ Map<Serializable, Object> map = new HashMap<Serializable, Object>();
+
+ // removedNodes
+ for (String uuid : removedNodes)
+ {
+ Integer chunkId = chunkService.getChunkId(uuid);
+ ChangesFilterListsWrapper list = (ChangesFilterListsWrapper)map.get(chunkId);
+ if (list == null)
+ {
+ list =
+ new ChangesFilterListsWrapper(new HashSet<String>(), new HashSet<String>(), new HashSet<String>(),
+ new HashSet<String>());
+ map.put(chunkId, list);
+ }
+ list.getRemovedNodes().add(uuid);
+ }
+
+ // addedNodes
+ for (String uuid : addedNodes)
+ {
+ Integer chunkId = chunkService.getChunkId(uuid);
+ ChangesFilterListsWrapper list = (ChangesFilterListsWrapper)map.get(chunkId);
+ if (list == null)
+ {
+ list =
+ new ChangesFilterListsWrapper(new HashSet<String>(), new HashSet<String>(), new HashSet<String>(),
+ new HashSet<String>());
+ map.put(chunkId, list);
+ }
+ list.getAddedNodes().add(uuid);
+ }
+
+ // parentRemovedNodes
+ for (String uuid : parentRemovedNodes)
+ {
+ Integer chunkId = chunkService.getChunkId(uuid);
+ ChangesFilterListsWrapper list = (ChangesFilterListsWrapper)map.get(chunkId);
+ if (list == null)
+ {
+ list =
+ new ChangesFilterListsWrapper(new HashSet<String>(), new HashSet<String>(), new HashSet<String>(),
+ new HashSet<String>());
+ map.put(chunkId, list);
+ }
+ list.getParentRemovedNodes().add(uuid);
+ }
+
+ // parentAddedNodes
+ for (String uuid : parentAddedNodes)
+ {
+ Integer chunkId = chunkService.getChunkId(uuid);
+ ChangesFilterListsWrapper list = (ChangesFilterListsWrapper)map.get(chunkId);
+ if (list == null)
+ {
+ list =
+ new ChangesFilterListsWrapper(new HashSet<String>(), new HashSet<String>(), new HashSet<String>(),
+ new HashSet<String>());
+ map.put(chunkId, list);
+ }
+ list.getParentAddedNodes().add(uuid);
+ }
+
+ PrivilegedCacheHelper.put(cache, Fqn.fromRelativeElements(rootFqn, id + "MAP"), map);
+ }
+ catch (CacheException e)
+ {
+ log.error(e.getLocalizedMessage(), e);
+ logErrorChanges(handler, removedNodes, addedNodes);
+ logErrorChanges(parentHandler, parentRemovedNodes, parentAddedNodes);
+ }
+ }
+
+ /**
+ * Log errors
+ * @param logHandler
+ * @param removedNodes
+ * @param addedNodes
+ */
+ private void logErrorChanges(QueryHandler logHandler, Set<String> removedNodes, Set<String> addedNodes)
+ {
+ try
+ {
+ logHandler.logErrorChanges(addedNodes, removedNodes);
+ }
+ catch (IOException ioe)
+ {
+ log.warn("Exception occure when errorLog writed. Error log is not complete. " + ioe, ioe);
+ }
+ }
+}
Property changes on: jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/chunk/JBossCacheChunkIndexChangesFilter.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/ChunkIndex.java
===================================================================
--- jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/ChunkIndex.java 2010-11-01 10:50:31 UTC (rev 3372)
+++ jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/ChunkIndex.java 2010-11-02 07:25:50 UTC (rev 3373)
@@ -22,8 +22,11 @@
import org.exoplatform.services.jcr.dataflow.ItemDataConsumer;
import org.exoplatform.services.jcr.datamodel.ItemData;
import org.exoplatform.services.jcr.datamodel.NodeData;
-import org.exoplatform.services.jcr.impl.core.query.ChunkService;
+import org.exoplatform.services.jcr.impl.core.query.IndexerIoMode;
+import org.exoplatform.services.jcr.impl.core.query.IndexerIoModeHandler;
+import org.exoplatform.services.jcr.impl.core.query.IndexerIoModeListener;
import org.exoplatform.services.jcr.impl.core.query.IndexingTree;
+import org.exoplatform.services.jcr.impl.core.query.jbosscache.chunk.ChunkService;
import org.exoplatform.services.jcr.impl.core.query.lucene.directory.DirectoryManager;
import org.exoplatform.services.jcr.impl.util.SecurityHelper;
import org.slf4j.Logger;
@@ -47,7 +50,7 @@
/**
* TODO REWRITE JAVADOC!!!
*/
-public class ChunkIndex
+public class ChunkIndex implements IndexerIoModeListener
{
/**
@@ -116,6 +119,8 @@
private final ChunkService chunkService;
+ private final IndexerIoModeHandler modeHandler;
+
/**
* Creates a new MultiIndex.
*
@@ -127,7 +132,8 @@
* @throws IOException
* if an error occurs
*/
- ChunkIndex(SearchIndex handler, IndexingTree indexingTree) throws IOException
+ ChunkIndex(SearchIndex handler, IndexingTree indexingTree, IndexerIoModeHandler modeHandler,
+ ChunkService chunkService) throws IOException
{
this.directoryManager = handler.getDirectoryManager();
// this method is run in privileged mode internally
@@ -137,8 +143,26 @@
this.indexingTree = indexingTree;
this.nsMappings = handler.getNamespaceMappings();
// TODO remove this stub
- this.chunkService = new ChunkServiceImpl();
+ this.chunkService = chunkService;
+ if (chunkService == null)
+ {
+ System.out.println("\n\n\n");
+ System.out.println("null");
+ System.out.println("\n\n\n");
+ try
+ {
+ throw new Exception();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ this.modeHandler = modeHandler;
+ this.modeHandler.addIndexerIoModeListener(this);
+
// this method is run in privileged mode internally
IndexingQueueStore store = new IndexingQueueStore(indexDir);
@@ -147,7 +171,7 @@
// open persistent indexes
- Set<Integer> assignedChunks = chunkService.getAssignedChunks();
+ Set<Integer> assignedChunks = chunkService.getAssignedChunks(false);
for (int i = 0; i < chunkService.getChunkCount(); i++)
{
@@ -166,7 +190,7 @@
PersistentIndexChunk index =
new PersistentIndexChunk(i, handler.getTextAnalyzer(), handler.getSimilarity(), cache, indexingQueue,
directoryManager, !assignedChunks.contains(Integer.valueOf(i)));
-
+
index.setMaxFieldLength(handler.getMaxFieldLength());
index.setUseCompoundFile(handler.getUseCompoundFile());
index.setTermInfosIndexDivisor(handler.getTermInfosIndexDivisor());
@@ -519,6 +543,7 @@
*/
public synchronized void update(final Collection<String> remove, final Collection<Document> add) throws IOException
{
+ log.info("Indexing: added " + add.size() + " and removed " + remove.size());
SecurityHelper.doPriviledgedIOExceptionAction(new PrivilegedExceptionAction<Object>()
{
public Object run() throws Exception
@@ -563,10 +588,14 @@
}
}
}
- // TODO for owning indexes only
+ // commit owning indexes only
+ Set<Integer> chunkIds = chunkService.getAssignedChunks(false);
for (PersistentIndexChunk idx : indexes)
{
- idx.commit();
+ if (chunkIds.contains(Integer.valueOf(idx.getId())))
+ {
+ idx.commit();
+ }
}
}
finally
@@ -579,7 +608,7 @@
}
/**
- * Checks the indexing queue for finished text extrator jobs and updates the
+ * Checks the indexing queue for finished text extractor jobs and updates the
* index accordingly if there are any new ones.
*
* @param transactionPresent
@@ -745,4 +774,38 @@
}
});
}
+
+ private synchronized void doReleaseChunks()
+ {
+ for (PersistentIndexChunk idx : indexes)
+ {
+ idx.setReadOnly(true);
+ }
+ }
+
+ private synchronized void doAcquireChunks()
+ {
+ Set<Integer> chunkIds = chunkService.getAssignedChunks(false);
+ for (Integer id : chunkIds)
+ {
+ indexes.get(id).setReadOnly(false);
+ }
+ }
+
+ /**
+ * @see org.exoplatform.services.jcr.impl.core.query.IndexerIoModeListener#onChangeMode(org.exoplatform.services.jcr.impl.core.query.IndexerIoMode)
+ */
+ public void onChangeMode(IndexerIoMode mode)
+ {
+ switch (mode)
+ {
+ case READ_ONLY :
+ doReleaseChunks();
+ break;
+ case READ_WRITE :
+ doAcquireChunks();
+ break;
+ }
+
+ }
}
\ No newline at end of file
Added: jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/PersistentIndexChunk.java
===================================================================
--- jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/PersistentIndexChunk.java (rev 0)
+++ jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/PersistentIndexChunk.java 2010-11-02 07:25:50 UTC (rev 3373)
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.exoplatform.services.jcr.impl.core.query.lucene;
+
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.Similarity;
+import org.exoplatform.services.jcr.impl.core.query.lucene.directory.DirectoryManager;
+
+import java.io.IOException;
+
+/**
+ * TODO Write javadoc. This index extends Abstract with checks, if index is
+ * owned by this machine
+ * Implements a lucene index which is based on a
+ * {@link org.apache.jackrabbit.core.fs.FileSystem}.
+ */
+class PersistentIndexChunk extends AbstractIndex
+{
+
+ // TODO review checks. Some more methods should check if index is read only.
+
+ /** The Id of this persistent index */
+ private final int id;
+
+ private boolean readOnly;
+
+ /**
+ * Creates a new <code>PersistentIndex</code>.
+ *
+ * @param name the name of this index.
+ * @param analyzer the analyzer for text tokenizing.
+ * @param similarity the similarity implementation.
+ * @param cache the document number cache
+ * @param indexingQueue the indexing queue.
+ * @param directoryManager the directory manager.
+ * @param readOnly if current index is not owned by local machine
+ * @throws IOException if an error occurs while opening / creating the
+ * index.
+ */
+ PersistentIndexChunk(int id, Analyzer analyzer, Similarity similarity, DocNumberCache cache,
+ IndexingQueue indexingQueue, final DirectoryManager directoryManager, boolean readOnly) throws IOException
+ {
+ super(analyzer, similarity, directoryManager.getDirectory("chunk_" + id), cache, indexingQueue);
+ this.id = id;
+ this.readOnly = readOnly;
+ }
+
+ @Override
+ void addDocuments(Document[] docs) throws IOException
+ {
+ if (readOnly)
+ {
+ throw new IOException("Index is not owned by current instance of ChunkIndex and can't be modified!");
+ }
+ super.addDocuments(docs);
+ }
+
+ @Override
+ protected void commit() throws IOException
+ {
+ if (readOnly)
+ {
+ throw new IOException("Index is not owned by current instance of ChunkIndex and can't be modified!");
+ }
+ super.commit();
+ }
+
+ @Override
+ protected synchronized void commit(boolean optimize) throws IOException
+ {
+ if (readOnly)
+ {
+ throw new IOException("Index is not owned by current instance of ChunkIndex and can't be modified!");
+ }
+ super.commit(optimize);
+ }
+
+ @Override
+ protected synchronized IndexWriter getIndexWriter() throws IOException
+ {
+ if (readOnly)
+ {
+ throw new IOException("Index is not owned by current instance of ChunkIndex and can't be modified!");
+ }
+ return super.getIndexWriter();
+ }
+
+ @Override
+ int removeDocument(Term idTerm) throws IOException
+ {
+ if (readOnly)
+ {
+ throw new IOException("Index is not owned by current instance of ChunkIndex and can't be modified!");
+ }
+ return super.removeDocument(idTerm);
+ }
+
+ /**
+ * Returns the name of this index.
+ * @return the name of this index.
+ */
+ int getId()
+ {
+ return id;
+ }
+
+ public void setReadOnly(boolean readOnly)
+ {
+ this.readOnly = readOnly;
+ if (readOnly)
+ {
+ releaseWriterAndReaders();
+ }
+ }
+}
Property changes on: jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/PersistentIndexChunk.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java
===================================================================
--- jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java 2010-11-01 10:50:31 UTC (rev 3372)
+++ jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java 2010-11-02 07:25:50 UTC (rev 3373)
@@ -570,7 +570,7 @@
indexingConfig = createIndexingConfiguration(nsMappings);
analyzer.setIndexingConfig(indexingConfig);
- index = new ChunkIndex(this, context.getIndexingTree());
+ index = new ChunkIndex(this, context.getIndexingTree(), modeHandler, chunkService);
// if RW mode, create initial index and start check
if (modeHandler.getMode() == IndexerIoMode.READ_WRITE)
{
Modified: jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/AbstractWriteOnlyCacheLoader.java
===================================================================
--- jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/AbstractWriteOnlyCacheLoader.java 2010-11-01 10:50:31 UTC (rev 3372)
+++ jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jbosscache/AbstractWriteOnlyCacheLoader.java 2010-11-02 07:25:50 UTC (rev 3373)
@@ -74,6 +74,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public void prepare(Object tx, List<Modification> modifications, boolean onePhase) throws Exception
{
throw new WriteOnlyCacheLoaderException("The method 'prepare(Object tx, List<Modification> modifications, boolean onePhase)' should not be called.");
@@ -84,7 +85,8 @@
*/
public Object remove(Fqn arg0, Object arg1) throws Exception
{
- throw new WriteOnlyCacheLoaderException("The method 'remove(Fqn arg0, Object arg1)' should not be called.");
+// throw new WriteOnlyCacheLoaderException("The method 'remove(Fqn arg0, Object arg1)' should not be called.");
+ return null;
}
/**
@@ -106,6 +108,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public abstract void put(List<Modification> modifications) throws Exception ;
}
Modified: jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/PrivilegedCacheHelper.java
===================================================================
--- jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/PrivilegedCacheHelper.java 2010-11-01 10:50:31 UTC (rev 3372)
+++ jcr/branches/1.14-CNK/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/PrivilegedCacheHelper.java 2010-11-02 07:25:50 UTC (rev 3373)
@@ -27,6 +27,7 @@
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
+import java.util.Map;
/**
* @author <a href="anatoliy.bazko(a)exoplatform.org">Anatoliy Bazko</a>
@@ -163,4 +164,42 @@
}
}
}
+
+ /**
+ * Put in cache in privileged mode.
+ *
+ * @param cache
+ */
+ public static void put(final Cache<Serializable, Object> cache, final Fqn fqn, final Map<Serializable, Object> data)
+ throws CacheException
+ {
+ PrivilegedExceptionAction<Object> action = new PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ cache.put(fqn, data);
+ return null;
+ }
+ };
+ try
+ {
+ AccessController.doPrivileged(action);
+ }
+ catch (PrivilegedActionException pae)
+ {
+ Throwable cause = pae.getCause();
+ if (cause instanceof CacheException)
+ {
+ throw (CacheException)cause;
+ }
+ else if (cause instanceof RuntimeException)
+ {
+ throw (RuntimeException)cause;
+ }
+ else
+ {
+ throw new RuntimeException(cause);
+ }
+ }
+ }
}
Modified: jcr/branches/1.14-CNK/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-jbosscache-indexer.xml
===================================================================
--- jcr/branches/1.14-CNK/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-jbosscache-indexer.xml 2010-11-01 10:50:31 UTC (rev 3372)
+++ jcr/branches/1.14-CNK/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-jbosscache-indexer.xml 2010-11-02 07:25:50 UTC (rev 3373)
@@ -4,18 +4,18 @@
<locking useLockStriping="false" concurrencyLevel="500" lockParentForChildInsertRemove="false"
lockAcquisitionTimeout="20000" />
<!-- Configure the TransactionManager -->
- <transaction transactionManagerLookupClass="org.jboss.cache.transaction.JBossStandaloneJTAManagerLookup" />
+ <!-- transaction transactionManagerLookupClass="org.jboss.cache.transaction.JBossStandaloneJTAManagerLookup" /-->
<clustering mode="replication" clusterName="${jbosscache-cluster-name}">
- <stateRetrieval timeout="20000" fetchInMemoryState="false" />
- <sync />
+ <stateRetrieval timeout="20000" fetchInMemoryState="true" />
+ <sync replTimeout = "30000"/>
</clustering>
<!-- Eviction configuration -->
- <eviction wakeUpInterval="5000">
+ <!--eviction wakeUpInterval="5000">
<default algorithmClass="org.jboss.cache.eviction.FIFOAlgorithm" eventQueueSize="1000000">
<property name="maxNodes" value="10000" />
<property name="minTimeToLive" value="60000" />
</default>
- </eviction>
+ </eviction-->
</jbosscache>
Modified: jcr/branches/1.14-CNK/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-jcr-config.xml
===================================================================
--- jcr/branches/1.14-CNK/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-jcr-config.xml 2010-11-01 10:50:31 UTC (rev 3372)
+++ jcr/branches/1.14-CNK/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-jcr-config.xml 2010-11-02 07:25:50 UTC (rev 3373)
@@ -59,7 +59,7 @@
<properties>
<property name="index-dir" value="target/temp/index/db1/ws" />
<property name="changesfilter-class"
- value="org.exoplatform.services.jcr.impl.core.query.jbosscache.JBossCacheIndexChangesFilter" />
+ value="org.exoplatform.services.jcr.impl.core.query.jbosscache.chunk.JBossCacheChunkIndexChangesFilter" />
<property name="jbosscache-configuration" value="test-jbosscache-indexer.xml" />
<property name="jgroups-configuration" value="udp-mux.xml" />
<property name="jgroups-multiplexer-stack" value="false" />
@@ -123,7 +123,7 @@
<properties>
<property name="index-dir" value="target/temp/index/db1/ws1" />
<property name="changesfilter-class"
- value="org.exoplatform.services.jcr.impl.core.query.jbosscache.JBossCacheIndexChangesFilter" />
+ value="org.exoplatform.services.jcr.impl.core.query.jbosscache.chunk.JBossCacheChunkIndexChangesFilter" />
<property name="jbosscache-configuration" value="test-jbosscache-indexer.xml" />
<property name="jgroups-configuration" value="udp-mux.xml" />
<property name="jgroups-multiplexer-stack" value="false" />
@@ -197,7 +197,7 @@
<properties>
<property name="index-dir" value="target/temp/index/db1/ws2" />
<property name="changesfilter-class"
- value="org.exoplatform.services.jcr.impl.core.query.jbosscache.JBossCacheIndexChangesFilter" />
+ value="org.exoplatform.services.jcr.impl.core.query.jbosscache.chunk.JBossCacheChunkIndexChangesFilter" />
<property name="jbosscache-configuration" value="test-jbosscache-indexer.xml" />
<property name="jgroups-configuration" value="udp-mux.xml" />
<property name="jgroups-multiplexer-stack" value="false" />
@@ -285,7 +285,7 @@
<properties>
<property name="index-dir" value="target/temp/index/db1/ws3" />
<property name="changesfilter-class"
- value="org.exoplatform.services.jcr.impl.core.query.jbosscache.JBossCacheIndexChangesFilter" />
+ value="org.exoplatform.services.jcr.impl.core.query.jbosscache.chunk.JBossCacheChunkIndexChangesFilter" />
<property name="jbosscache-configuration" value="test-jbosscache-indexer.xml" />
<property name="jgroups-configuration" value="udp-mux.xml" />
<property name="jgroups-multiplexer-stack" value="false" />
@@ -378,7 +378,7 @@
<properties>
<property name="index-dir" value="target/temp/index/db1tck/ws" />
<property name="changesfilter-class"
- value="org.exoplatform.services.jcr.impl.core.query.jbosscache.JBossCacheIndexChangesFilter" />
+ value="org.exoplatform.services.jcr.impl.core.query.jbosscache.chunk.JBossCacheChunkIndexChangesFilter" />
<property name="jbosscache-configuration" value="test-jbosscache-indexer.xml" />
<property name="jgroups-configuration" value="udp-mux.xml" />
<property name="jgroups-multiplexer-stack" value="false" />
@@ -459,7 +459,7 @@
<properties>
<property name="index-dir" value="target/temp/index/db1tck/ws1" />
<property name="changesfilter-class"
- value="org.exoplatform.services.jcr.impl.core.query.jbosscache.JBossCacheIndexChangesFilter" />
+ value="org.exoplatform.services.jcr.impl.core.query.jbosscache.chunk.JBossCacheChunkIndexChangesFilter" />
<property name="jbosscache-configuration" value="test-jbosscache-indexer.xml" />
<property name="jgroups-configuration" value="udp-mux.xml" />
<property name="jgroups-multiplexer-stack" value="false" />
@@ -538,7 +538,7 @@
<properties>
<property name="index-dir" value="target/temp/index/db1tck/ws2" />
<property name="changesfilter-class"
- value="org.exoplatform.services.jcr.impl.core.query.jbosscache.JBossCacheIndexChangesFilter" />
+ value="org.exoplatform.services.jcr.impl.core.query.jbosscache.chunk.JBossCacheChunkIndexChangesFilter" />
<property name="jbosscache-configuration" value="test-jbosscache-indexer.xml" />
<property name="jgroups-configuration" value="udp-mux.xml" />
<property name="jgroups-multiplexer-stack" value="false" />
13 years, 6 months
exo-jcr SVN: r3372 - in jcr/branches/1.12.x/exo.jcr.component.core: src/main/java/org/exoplatform/services/jcr/impl/core and 7 other directories.
by do-not-reply@jboss.org
Author: tolusha
Date: 2010-11-01 06:50:31 -0400 (Mon, 01 Nov 2010)
New Revision: 3372
Added:
jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/access/TestPermissions.java
Modified:
jcr/branches/1.12.x/exo.jcr.component.core/pom.xml
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NamespaceDataPersister.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/ScratchWorkspaceInitializer.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/registration/JCRNodeTypeDataPersister.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/version/VersionHistoryImpl.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/version/VersionImpl.java
jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/version/VersionHistoryDataHelper.java
jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/util/ConfigurationHelper.java
jcr/branches/1.12.x/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-configuration.xml
jcr/branches/1.12.x/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-jcr-config.xml
jcr/branches/1.12.x/exo.jcr.component.core/src/test/resources/conf/standalone/test-configuration-sjdbc.xml
jcr/branches/1.12.x/exo.jcr.component.core/src/test/resources/conf/standalone/test-configuration.xml
jcr/branches/1.12.x/exo.jcr.component.core/src/test/resources/conf/standalone/test-jcr-config-sjdbc.xml
jcr/branches/1.12.x/exo.jcr.component.core/src/test/resources/conf/standalone/test-jcr-config.xml
Log:
JCR-1491: Use can perform versionable operation checkin/checkout/restore etc event he hasn't permission to system workspace
Modified: jcr/branches/1.12.x/exo.jcr.component.core/pom.xml
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/pom.xml 2010-11-01 10:04:33 UTC (rev 3371)
+++ jcr/branches/1.12.x/exo.jcr.component.core/pom.xml 2010-11-01 10:50:31 UTC (rev 3372)
@@ -677,7 +677,6 @@
<exclude>org/exoplatform/services/jcr/**/impl/**/TestRepositoryManagement.java</exclude>
<exclude>org/exoplatform/services/jcr/**/impl/**/TestSaveConfiguration.java</exclude>
<exclude>org/exoplatform/services/jcr/**/impl/**/ValueStoragePluginTest.java</exclude>
- <exclude>org/exoplatform/services/jcr/**/impl/**/TestWorkspaceRestore.java</exclude>
<exclude>org/exoplatform/services/jcr/**/impl/**/TestSessionCleaner.java</exclude>
<exclude>org/exoplatform/services/jcr/**/impl/**/Base*.java</exclude>
<exclude>org/exoplatform/services/jcr/**/impl/**/TestJCRSerializationStream.java</exclude>
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NamespaceDataPersister.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NamespaceDataPersister.java 2010-11-01 10:04:33 UTC (rev 3371)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NamespaceDataPersister.java 2010-11-01 10:50:31 UTC (rev 3372)
@@ -352,12 +352,13 @@
if (addACL)
{
- AccessControlList acl = new AccessControlList();
InternalQName[] mixins = new InternalQName[]{Constants.EXO_OWNEABLE, Constants.EXO_PRIVILEGEABLE};
exoNamespaces =
TransientNodeData.createNodeData(nsSystem, Constants.EXO_NAMESPACES, Constants.NT_UNSTRUCTURED, mixins);
+ AccessControlList acl = exoNamespaces.getACL();
+
TransientPropertyData primaryType =
TransientPropertyData.createPropertyData(exoNamespaces, Constants.JCR_PRIMARYTYPE, PropertyType.NAME,
false, new TransientValueData(exoNamespaces.getPrimaryTypeName()));
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java 2010-11-01 10:04:33 UTC (rev 3371)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/NodeImpl.java 2010-11-01 10:50:31 UTC (rev 3372)
@@ -354,6 +354,13 @@
UnsupportedRepositoryOperationException, RepositoryException
{
+ if (!session.getAccessManager().hasPermission(getACL(),
+ new String[]{PermissionType.ADD_NODE, PermissionType.SET_PROPERTY}, session.getUserState().getIdentity()))
+ {
+ throw new AccessDeniedException("Access denied: cancel merge operation " + getPath() + " for: "
+ + session.getUserID() + " item owner " + getACL().getOwner());
+ }
+
checkValid();
PlainChangesLog changesLog = new PlainChangesLogImpl(session.getId());
@@ -404,6 +411,13 @@
checkValid();
+ if (!session.getAccessManager().hasPermission(getACL(),
+ new String[]{PermissionType.ADD_NODE, PermissionType.SET_PROPERTY}, session.getUserState().getIdentity()))
+ {
+ throw new AccessDeniedException("Access denied: checkin operation " + getPath() + " for: "
+ + session.getUserID() + " item owner " + getACL().getOwner());
+ }
+
if (!this.isNodeType(Constants.MIX_VERSIONABLE))
throw new UnsupportedRepositoryOperationException(
"Node.checkin() is not supported for not mix:versionable node ");
@@ -441,7 +455,7 @@
dataManager.getTransactManager().save(changesLog);
- VersionImpl version = (VersionImpl)dataManager.getItemByIdentifier(verIdentifier, true);
+ VersionImpl version = (VersionImpl)dataManager.getItemByIdentifier(verIdentifier, true, false);
session.getActionHandler().postCheckin(this);
return version;
@@ -455,6 +469,13 @@
checkValid();
+ if (!session.getAccessManager().hasPermission(getACL(), new String[]{PermissionType.SET_PROPERTY},
+ session.getUserState().getIdentity()))
+ {
+ throw new AccessDeniedException("Access denied: checkout operation " + getPath() + " for: "
+ + session.getUserID() + " item owner " + getACL().getOwner());
+ }
+
if (!this.isNodeType(Constants.MIX_VERSIONABLE))
throw new UnsupportedRepositoryOperationException(
"Node.checkout() is not supported for not mix:versionable node ");
@@ -612,6 +633,12 @@
public void doneMerge(Version version) throws VersionException, InvalidItemStateException,
UnsupportedRepositoryOperationException, RepositoryException
{
+ if (!session.getAccessManager().hasPermission(getACL(),
+ new String[]{PermissionType.ADD_NODE, PermissionType.SET_PROPERTY}, session.getUserState().getIdentity()))
+ {
+ throw new AccessDeniedException("Access denied: done merge operation " + getPath() + " for: "
+ + session.getUserID() + " item owner " + getACL().getOwner());
+ }
PlainChangesLog changesLog = new PlainChangesLogImpl(session.getId());
@@ -686,7 +713,8 @@
ItemType.PROPERTY);
try
{
- return (Version)session.getNodeByUUID(ValueDataConvertor.readString(bvProp.getValues().get(0)));
+ return (Version)dataManager.getItemByIdentifier(ValueDataConvertor.readString(bvProp.getValues().get(0)),
+ true, false);
}
catch (IOException e)
{
@@ -1415,6 +1443,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public void loadData(ItemData data, NodeData parent) throws RepositoryException, InvalidItemStateException,
ConstraintViolationException
{
@@ -1492,6 +1521,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public ItemDefinitionData getItemDefinitionData()
{
return definition;
@@ -1579,8 +1609,17 @@
checkValid();
+ if (!session.getAccessManager().hasPermission(getACL(),
+ new String[]{PermissionType.ADD_NODE, PermissionType.SET_PROPERTY}, session.getUserState().getIdentity()))
+ {
+ throw new AccessDeniedException("Access denied: merge operation " + getPath() + " for: "
+ + session.getUserID() + " item owner " + getACL().getOwner());
+ }
+
if (session.hasPendingChanges())
+ {
throw new InvalidItemStateException("Session has pending changes ");
+ }
Map<String, String> failed = new HashMap<String, String>();
@@ -1799,6 +1838,13 @@
checkValid();
+ if (!session.getAccessManager().hasPermission(getACL(),
+ new String[]{PermissionType.ADD_NODE, PermissionType.SET_PROPERTY}, session.getUserState().getIdentity()))
+ {
+ throw new AccessDeniedException("Access denied: restore operation " + getPath() + " for: "
+ + session.getUserID() + " item owner " + getACL().getOwner());
+ }
+
if (!this.isNodeType(Constants.MIX_VERSIONABLE))
throw new UnsupportedRepositoryOperationException("Node is not versionable " + getPath());
@@ -1839,6 +1885,13 @@
// restore at relPath
checkValid();
+ if (!session.getAccessManager().hasPermission(getACL(),
+ new String[]{PermissionType.ADD_NODE, PermissionType.SET_PROPERTY}, session.getUserState().getIdentity()))
+ {
+ throw new AccessDeniedException("Access denied: restore operation " + getPath() + " for: "
+ + session.getUserID() + " item owner " + getACL().getOwner());
+ }
+
if (session.hasPendingChanges())
throw new InvalidItemStateException("Session has pending changes ");
@@ -2337,7 +2390,7 @@
try
{
return (VersionHistoryImpl)dataManager.getItemByIdentifier(new String(vhProp.getValues().get(0)
- .getAsByteArray()), pool);
+ .getAsByteArray()), pool, false);
}
catch (IOException e)
{
@@ -3033,7 +3086,7 @@
// check read conditions
if (canRead(item))
{
- next = (ItemImpl)session.getTransientNodesManager().readItem(item, nodeData(), true, false);
+ next = session.getTransientNodesManager().readItem(item, nodeData(), true, false);
}
else
{
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/ScratchWorkspaceInitializer.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/ScratchWorkspaceInitializer.java 2010-11-01 10:04:33 UTC (rev 3371)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/ScratchWorkspaceInitializer.java 2010-11-01 10:50:31 UTC (rev 3372)
@@ -139,9 +139,6 @@
: Constants.NT_UNSTRUCTURED;
this.dataManager = dataManager;
- // this.nsPersister = nsPersister;
- // this.ntRegistry = ntRegistry;
-
}
public NodeData initWorkspace() throws RepositoryException
@@ -273,13 +270,14 @@
if (addACL)
{
- AccessControlList acl = new AccessControlList();
InternalQName[] mixins = new InternalQName[]{Constants.EXO_OWNEABLE, Constants.EXO_PRIVILEGEABLE};
jcrSystem =
TransientNodeData.createNodeData(root, Constants.JCR_SYSTEM, Constants.NT_UNSTRUCTURED, mixins,
Constants.SYSTEM_UUID);
+ AccessControlList acl = jcrSystem.getACL();
+
TransientPropertyData primaryType =
TransientPropertyData.createPropertyData(jcrSystem, Constants.JCR_PRIMARYTYPE, PropertyType.NAME, false,
new TransientValueData(jcrSystem.getPrimaryTypeName()));
@@ -340,15 +338,6 @@
dataManager.save(new TransactionChangesLog(changesLog));
- //nsPersister.initStorage(jcrSystem, addACL, NamespaceRegistryImpl.DEF_NAMESPACES);
- // nodeTypes save
- // changesLog = new PlainChangesLogImpl();
- // changesLog.addAll(ntPersister.initNodetypesRoot(jcrSystem,
- // addACL).getAllStates());
- // changesLog.addAll(ntPersister.initStorage(nodeTypeDataManager.getAllNodeTypes()).getAllStates());
- // ntPersister.saveChanges(changesLog);
-
- // nodeTypeDataManager.initDefaultNodeTypes(addACL);
return jcrSystem;
}
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java 2010-11-01 10:04:33 UTC (rev 3371)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java 2010-11-01 10:50:31 UTC (rev 3372)
@@ -300,6 +300,28 @@
public ItemImpl getItem(NodeData parent, QPathEntry name, boolean pool, ItemType itemType)
throws RepositoryException
{
+ return getItem(parent, name, pool, itemType, true);
+ }
+
+ /**
+ * For internal use. Return Item by parent NodeDada and the name of searched item.
+ *
+ * @param parent
+ * - parent of the searched item
+ * @param name
+ * - item name
+ * @param itemType
+ * - item type
+ * @param pool
+ * - indicates does the item fall in pool
+ * @param apiRead
+ * - if true will call postRead Action and check permissions
+ * @return existed item or null if not found
+ * @throws RepositoryException
+ */
+ public ItemImpl getItem(NodeData parent, QPathEntry name, boolean pool, ItemType itemType, boolean apiRead)
+ throws RepositoryException
+ {
long start = System.currentTimeMillis();
if (log.isDebugEnabled())
{
@@ -309,7 +331,7 @@
ItemImpl item = null;
try
{
- return item = readItem(getItemData(parent, name, itemType), pool);
+ return item = readItem(getItemData(parent, name, itemType), parent, pool, apiRead);
}
finally
{
@@ -433,7 +455,7 @@
* @param pool boolean, if true will reload pooled ItemImpl
* @param apiRead boolean, if true will call postRead Action and check permissions
* @return ItemImpl
- * @throws RepositoryException if errro occurs
+ * @throws RepositoryException if error occurs
*/
protected ItemImpl readItem(ItemData itemData, NodeData parent, boolean pool, boolean apiRead)
throws RepositoryException
@@ -483,6 +505,23 @@
*/
public ItemImpl getItemByIdentifier(String identifier, boolean pool) throws RepositoryException
{
+ return getItemByIdentifier(identifier, pool, true);
+ }
+
+ /**
+ * For internal use. Return item by identifier in this transient storage then in workspace container.
+ *
+ * @param identifier
+ * - identifier of searched item
+ * @param pool
+ * - indicates does the item fall in pool
+ * @param apiRead
+ * - if true will call postRead Action and check permissions
+ * @return existed item data or null if not found
+ * @throws RepositoryException
+ */
+ public ItemImpl getItemByIdentifier(String identifier, boolean pool, boolean apiRead) throws RepositoryException
+ {
long start = System.currentTimeMillis();
if (log.isDebugEnabled())
{
@@ -492,7 +531,7 @@
ItemImpl item = null;
try
{
- return item = readItem(getItemData(identifier), pool);
+ return item = readItem(getItemData(identifier), null, pool, apiRead);
}
finally
{
@@ -656,7 +695,7 @@
if (accessManager.hasPermission(parent.getACL(), new String[]{PermissionType.READ}, session.getUserState()
.getIdentity()))
{
- PropertyImpl item = (PropertyImpl)readItem(data, null, true, false);
+ PropertyImpl item = (PropertyImpl)readItem(data, parent, true, false);
refs.add(item);
session.getActionHandler().postRead(item);
@@ -1027,12 +1066,17 @@
*/
public void delete(ItemData itemData) throws RepositoryException
{
- delete(itemData, itemData.getQPath());
+ delete(itemData, itemData.getQPath(), false);
}
public void delete(ItemData itemData, QPath ancestorToSave) throws RepositoryException
{
+ delete(itemData, ancestorToSave, false);
+ }
+ protected void delete(ItemData itemData, QPath ancestorToSave, boolean isInternall) throws RepositoryException
+ {
+
List<? extends ItemData> list = mergeList(itemData, transactionableManager, true, MERGE_ITEMS);
List<ItemState> deletes = new ArrayList<ItemState>();
@@ -1057,7 +1101,8 @@
{
rootAdded = true;
}
- deletes.add(new ItemState(data, ItemState.DELETED, fireEvent, ancestorToSave, false));
+
+ deletes.add(new ItemState(data, ItemState.DELETED, fireEvent, ancestorToSave, isInternall));
// if subnode contains JCR_VERSIONHISTORY property
// we should remove version storage manually
if (checkRemoveChildVersionStorages && !data.isNode()
@@ -1090,7 +1135,7 @@
// 4 add item itself if not added
if (!rootAdded)
{
- deletes.add(new ItemState(itemData, ItemState.DELETED, fireEvent, ancestorToSave, false));
+ deletes.add(new ItemState(itemData, ItemState.DELETED, fireEvent, ancestorToSave, isInternall));
ItemImpl pooled = itemsPool.remove(itemData.getIdentifier());
if (pooled != null)
@@ -1210,7 +1255,7 @@
vhnode.accept(cvremover);
// remove VH
- delete(vhnode, ancestorToSave);
+ delete(vhnode, ancestorToSave, true);
}
/**
@@ -1524,6 +1569,17 @@
+ parent.getACL().getOwner());
}
}
+ else if (changedItem.isMixinChanged())
+ {
+ if (!accessManager.hasPermission(parent.getACL(), new String[]{PermissionType.ADD_NODE,
+ PermissionType.SET_PROPERTY}, session.getUserState().getIdentity()))
+ {
+ throw new AccessDeniedException("Access denied: ADD_NODE or SET_PROPERTY"
+ + changedItem.getData().getQPath().getAsString() + " for: " + session.getUserID() + " item owner "
+ + parent.getACL().getOwner());
+ }
+ }
+
}
else if (changedItem.isAdded() || changedItem.isUpdated())
{
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/registration/JCRNodeTypeDataPersister.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/registration/JCRNodeTypeDataPersister.java 2010-11-01 10:04:33 UTC (rev 3371)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/registration/JCRNodeTypeDataPersister.java 2010-11-01 10:50:31 UTC (rev 3372)
@@ -155,13 +155,14 @@
if (addACL)
{
- AccessControlList acl = new AccessControlList();
InternalQName[] mixins = new InternalQName[]{Constants.EXO_OWNEABLE, Constants.EXO_PRIVILEGEABLE};
jcrNodetypes =
TransientNodeData.createNodeData(nsSystem, Constants.JCR_NODETYPES, Constants.NT_UNSTRUCTURED, mixins,
Constants.NODETYPESROOT_UUID);
+ AccessControlList acl = jcrNodetypes.getACL();
+
TransientPropertyData primaryType =
TransientPropertyData.createPropertyData(jcrNodetypes, Constants.JCR_PRIMARYTYPE, PropertyType.NAME, false,
new TransientValueData(jcrNodetypes.getPrimaryTypeName()));
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/version/VersionHistoryImpl.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/version/VersionHistoryImpl.java 2010-11-01 10:04:33 UTC (rev 3371)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/version/VersionHistoryImpl.java 2010-11-01 10:50:31 UTC (rev 3372)
@@ -186,7 +186,7 @@
JCRName jcrVersionName = locationFactory.parseJCRName(versionName);
VersionImpl version =
(VersionImpl)dataManager.getItem(nodeData(), new QPathEntry(jcrVersionName.getInternalName(), 1), pool,
- ItemType.NODE);
+ ItemType.NODE, false);
if (version == null)
throw new VersionException("There are no version with name '" + versionName + "' in the version history "
+ getPath());
@@ -205,7 +205,7 @@
if (versionData == null)
throw new RepositoryException("There are no label '" + label + "' in the version history " + getPath());
- VersionImpl version = (VersionImpl)dataManager.getItemByIdentifier(versionData.getIdentifier(), true);
+ VersionImpl version = (VersionImpl)dataManager.getItemByIdentifier(versionData.getIdentifier(), true, false);
if (version == null)
throw new VersionException("There are no version with label '" + label + "' in the version history "
@@ -357,7 +357,7 @@
for (ValueData pvalue : predecessorsData.getValues())
{
String pidentifier = new String(pvalue.getAsByteArray());
- VersionImpl predecessor = (VersionImpl)dataManager.getItemByIdentifier(pidentifier, false);
+ VersionImpl predecessor = (VersionImpl)dataManager.getItemByIdentifier(pidentifier, false, false);
// actually predecessor is V2's successor
if (predecessor != null)
{// V2's successor
@@ -395,7 +395,7 @@
for (ValueData svalue : successorsData.getValues())
{
String sidentifier = new String(svalue.getAsByteArray());
- VersionImpl successor = (VersionImpl)dataManager.getItemByIdentifier(sidentifier, false);
+ VersionImpl successor = (VersionImpl)dataManager.getItemByIdentifier(sidentifier, false, false);
if (successor != null)
{
// case of VH graph merge
@@ -586,7 +586,7 @@
{
throw new RepositoryException(e);
}
- VersionImpl predecessor = (VersionImpl)dataManager.getItemByIdentifier(new String(pib), false);
+ VersionImpl predecessor = (VersionImpl)dataManager.getItemByIdentifier(new String(pib), false, false);
predecessor.addSuccessor(versionData.getIdentifier(), changesLog);
predecessorsNew.add(new TransientValueData(pib));
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/version/VersionImpl.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/version/VersionImpl.java 2010-11-01 10:04:33 UTC (rev 3371)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/version/VersionImpl.java 2010-11-01 10:50:31 UTC (rev 3372)
@@ -157,7 +157,7 @@
for (int i = 0; i < predecessorsValues.size(); i++)
{
String videntifier = new String(predecessorsValues.get(i).getAsByteArray());
- VersionImpl version = (VersionImpl)dataManager.getItemByIdentifier(videntifier, false);
+ VersionImpl version = (VersionImpl)dataManager.getItemByIdentifier(videntifier, false, false);
if (version != null)
{
predecessors[i] = version;
@@ -438,7 +438,7 @@
checkValid();
VersionHistoryImpl vhistory =
- (VersionHistoryImpl)dataManager.getItemByIdentifier(nodeData().getParentIdentifier(), true);
+ (VersionHistoryImpl)dataManager.getItemByIdentifier(nodeData().getParentIdentifier(), true, false);
if (vhistory == null)
{
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/version/VersionHistoryDataHelper.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/version/VersionHistoryDataHelper.java 2010-11-01 10:04:33 UTC (rev 3371)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/version/VersionHistoryDataHelper.java 2010-11-01 10:50:31 UTC (rev 3372)
@@ -335,19 +335,19 @@
// update all
QPath vpath = versionable.getQPath();
- changes.add(new ItemState(versionHistory, ItemState.ADDED, true, vpath));
- changes.add(new ItemState(vhPrimaryType, ItemState.ADDED, true, vpath));
- changes.add(new ItemState(vhUuid, ItemState.ADDED, true, vpath));
- changes.add(new ItemState(vhVersionableUuid, ItemState.ADDED, true, vpath));
+ changes.add(new ItemState(versionHistory, ItemState.ADDED, true, vpath, true));
+ changes.add(new ItemState(vhPrimaryType, ItemState.ADDED, true, vpath, true));
+ changes.add(new ItemState(vhUuid, ItemState.ADDED, true, vpath, true));
+ changes.add(new ItemState(vhVersionableUuid, ItemState.ADDED, true, vpath, true));
- changes.add(new ItemState(vhVersionLabels, ItemState.ADDED, true, vpath));
- changes.add(new ItemState(vlPrimaryType, ItemState.ADDED, true, vpath));
+ changes.add(new ItemState(vhVersionLabels, ItemState.ADDED, true, vpath, true));
+ changes.add(new ItemState(vlPrimaryType, ItemState.ADDED, true, vpath, true));
- changes.add(new ItemState(rootVersionData, ItemState.ADDED, true, vpath));
- changes.add(new ItemState(rvPrimaryType, ItemState.ADDED, true, vpath));
- changes.add(new ItemState(rvMixinTypes, ItemState.ADDED, true, vpath));
- changes.add(new ItemState(rvUuid, ItemState.ADDED, true, vpath));
- changes.add(new ItemState(rvCreated, ItemState.ADDED, true, vpath));
+ changes.add(new ItemState(rootVersionData, ItemState.ADDED, true, vpath, true));
+ changes.add(new ItemState(rvPrimaryType, ItemState.ADDED, true, vpath, true));
+ changes.add(new ItemState(rvMixinTypes, ItemState.ADDED, true, vpath, true));
+ changes.add(new ItemState(rvUuid, ItemState.ADDED, true, vpath, true));
+ changes.add(new ItemState(rvCreated, ItemState.ADDED, true, vpath, true));
changes.add(ItemState.createAddedState(vh));
changes.add(ItemState.createAddedState(bv));
Added: jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/access/TestPermissions.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/access/TestPermissions.java (rev 0)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/access/TestPermissions.java 2010-11-01 10:50:31 UTC (rev 3372)
@@ -0,0 +1,250 @@
+/*
+ * 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.jcr.impl.access;
+
+import org.exoplatform.services.jcr.BaseStandaloneTest;
+import org.exoplatform.services.jcr.access.PermissionType;
+import org.exoplatform.services.jcr.access.SystemIdentity;
+import org.exoplatform.services.jcr.core.CredentialsImpl;
+import org.exoplatform.services.jcr.impl.core.NodeImpl;
+import org.exoplatform.services.jcr.impl.core.SessionImpl;
+
+import javax.jcr.AccessDeniedException;
+import javax.jcr.Credentials;
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.version.Version;
+
+/**
+ * @author <a href="anatoliy.bazko(a)exoplatform.org">Anatoliy Bazko</a>
+ * @version $Id: TestRemoveSysteNode.java 111 2010-11-11 11:11:11Z tolusha $
+ */
+public class TestPermissions extends BaseStandaloneTest
+{
+
+ protected SessionImpl sessionMaryWS;
+
+ protected SessionImpl sessionMaryWS1;
+
+ protected SessionImpl sessionWS;
+
+ protected SessionImpl sessionWS1;
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected String getRepositoryName()
+ {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setUp() throws Exception
+ {
+ super.setUp();
+
+ Repository repository = repositoryService.getRepository("db2");
+ Credentials credentials = new CredentialsImpl("admin", "admin".toCharArray());
+ sessionWS = (SessionImpl)repository.login(credentials, "ws");
+ sessionWS1 = (SessionImpl)repository.login(credentials, "ws1");
+
+ repository = repositoryService.getRepository("db2");
+ credentials = new CredentialsImpl("mary", "exo".toCharArray());
+ sessionMaryWS = (SessionImpl)repository.login(credentials, "ws");
+ sessionMaryWS1 = (SessionImpl)repository.login(credentials, "ws1");
+
+ // add node with only read permission for mary
+ NodeImpl node = (NodeImpl)sessionWS1.getRootNode().addNode("MARY-ReadOnly");
+ node.addMixin("exo:privilegeable");
+ node.addMixin("exo:owneable");
+ node.setPermission("mary", new String[]{PermissionType.READ});
+ node.setPermission("admin", PermissionType.ALL);
+ node.removePermission(SystemIdentity.ANY);
+ node.addNode("test");
+ sessionWS1.save();
+
+ sessionWS1.getRootNode().addNode("MARY-ReadWrite");
+ sessionWS1.save();
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ sessionMaryWS.logout();
+ sessionMaryWS1.logout();
+ sessionWS.logout();
+ sessionWS1.logout();
+
+ super.tearDown();
+ }
+
+ /**
+ * Test if Mary can read root node of system workspace.
+ */
+ public void testGetRootNodeWSFailed() throws Exception
+ {
+ try
+ {
+ sessionMaryWS.getRootNode();
+
+ fail("Exception should be thrown.");
+ }
+ catch (AccessDeniedException e)
+ {
+ }
+ }
+
+ /**
+ * Test if Mary can perform versions operations in workspace where she has all right
+ * and in same time she has not rights in system workspace.
+ */
+ public void testCheckinCheckoutWS1Success() throws Exception
+ {
+ NodeImpl node = (NodeImpl)sessionMaryWS1.getRootNode().getNode("MARY-ReadWrite");
+ node.addMixin("mix:versionable");
+ sessionMaryWS1.save();
+
+ node.checkin();
+ node.checkout();
+
+ Version version = node.getVersionHistory().getVersion("1");
+ version.getPredecessors();
+ version.getSuccessors();
+ version.getContainingHistory();
+
+ node.restore("1", true);
+
+ node.remove();
+ sessionMaryWS1.save();
+ }
+
+ /**
+ * Test if Mary can add mixin on node with only read permission.
+ */
+ public void testAddMixinWS1Failed() throws Exception
+ {
+ NodeImpl node = (NodeImpl)sessionMaryWS1.getRootNode().getNode("MARY-ReadOnly").getNode("test");
+
+ try
+ {
+ node.addMixin("mix:versionable");
+ sessionMaryWS1.save();
+
+ fail("Exception should be thrown.");
+ }
+ catch (AccessDeniedException e)
+ {
+ }
+ }
+
+ /**
+ * Test if Mary can remove mixin on node with only read permission.
+ */
+ public void testRemoveMixinWS1Failed() throws Exception
+ {
+ NodeImpl node = (NodeImpl)sessionWS1.getRootNode().getNode("MARY-ReadOnly").getNode("test");
+ node.addMixin("mix:versionable");
+ sessionWS1.save();
+
+ node = (NodeImpl)sessionMaryWS1.getRootNode().getNode("MARY-ReadOnly").getNode("test");
+
+ try
+ {
+ node.removeMixin("mix:versionable");
+ sessionMaryWS1.save();
+
+ fail("Exception should be thrown.");
+ }
+ catch (AccessDeniedException e)
+ {
+ }
+ }
+
+ /**
+ * Test if Mary can checkin on node with only read permission.
+ */
+ public void testCheckinWS1Failed() throws Exception
+ {
+ Node node = sessionWS1.getRootNode().getNode("MARY-ReadOnly").getNode("test");
+ node.addMixin("mix:versionable");
+ sessionWS1.save();
+
+ node = sessionMaryWS1.getRootNode().getNode("MARY-ReadOnly").getNode("test");
+
+ try
+ {
+ node.checkin();
+ fail("Exception should be thrown.");
+ }
+ catch (AccessDeniedException e)
+ {
+ }
+ }
+
+ /**
+ * Test if Mary can checkout on node with only read permission.
+ */
+ public void testCheckoutWS1Failed() throws Exception
+ {
+ Node node = sessionWS1.getRootNode().getNode("MARY-ReadOnly").getNode("test");
+ node.addMixin("mix:versionable");
+ sessionWS1.save();
+
+ node.checkin();
+
+ node = sessionMaryWS1.getRootNode().getNode("MARY-ReadOnly").getNode("test");
+
+ try
+ {
+ node.checkout();
+ fail("Exception should be thrown.");
+ }
+ catch (AccessDeniedException e)
+ {
+ }
+ }
+
+ /**
+ * Test if Mary can restore on node with only read permission.
+ */
+ public void testRestoreWS1Failed() throws Exception
+ {
+ Node node = sessionWS1.getRootNode().getNode("MARY-ReadOnly").getNode("test");
+ node.addMixin("mix:versionable");
+ sessionWS1.save();
+
+ node.checkin();
+ node.checkout();
+
+ node = sessionMaryWS1.getRootNode().getNode("MARY-ReadOnly").getNode("test");
+
+ try
+ {
+ node.restore("1", true);
+ fail("Exception should be thrown.");
+ }
+ catch (AccessDeniedException e)
+ {
+ }
+ }
+}
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/util/ConfigurationHelper.java
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/util/ConfigurationHelper.java 2010-11-01 10:04:33 UTC (rev 3371)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/util/ConfigurationHelper.java 2010-11-01 10:50:31 UTC (rev 3372)
@@ -118,13 +118,9 @@
params.add(new SimpleParameterEntry("multi-db", isMultiDb ? "true" : "false"));
params.add(new SimpleParameterEntry("update-storage", "true"));
params.add(new SimpleParameterEntry("max-buffer-size", "204800"));
+ params.add(new SimpleParameterEntry(JDBCWorkspaceDataContainer.DB_DIALECT, entry.getParameterValue(
+ JDBCWorkspaceDataContainer.DB_DIALECT, "auto")));
- if (entry.getParameterValue(JDBCWorkspaceDataContainer.DB_DIALECT) != null)
- {
- params.add(new SimpleParameterEntry(JDBCWorkspaceDataContainer.DB_DIALECT, entry
- .getParameterValue(JDBCWorkspaceDataContainer.DB_DIALECT)));
- }
-
String oldSwap = entry.getParameterValue("swap-directory");
String newSwap = oldSwap.substring(0, oldSwap.lastIndexOf('/')) + '/' + wsName;
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-configuration.xml
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-configuration.xml 2010-11-01 10:04:33 UTC (rev 3371)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-configuration.xml 2010-11-01 10:50:31 UTC (rev 3372)
@@ -369,6 +369,60 @@
<init-params>
<value-param>
<name>bind-name</name>
+ <value>jdbcjcrdb2</value>
+ </value-param>
+ <value-param>
+ <name>class-name</name>
+ <value>javax.sql.DataSource</value>
+ </value-param>
+ <value-param>
+ <name>factory</name>
+ <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
+ </value-param>
+ <properties-param>
+ <name>ref-addresses</name>
+ <description>ref-addresses</description>
+ <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
+ <property name="url" value="jdbc:hsqldb:file:target/temp/data/portaldb2"/>
+ <property name="username" value="sa"/>
+ <property name="password" value=""/>
+ </properties-param>
+ </init-params>
+ </component-plugin>
+ <component-plugin>
+ <name>bind.datasource</name>
+ <set-method>addPlugin</set-method>
+ <type>org.exoplatform.services.naming.BindReferencePlugin</type>
+ <init-params>
+ <value-param>
+ <name>bind-name</name>
+ <value>jdbcjcr1db2</value>
+ </value-param>
+ <value-param>
+ <name>class-name</name>
+ <value>javax.sql.DataSource</value>
+ </value-param>
+ <value-param>
+ <name>factory</name>
+ <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
+ </value-param>
+ <properties-param>
+ <name>ref-addresses</name>
+ <description>ref-addresses</description>
+ <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
+ <property name="url" value="jdbc:hsqldb:file:target/temp/data/jcrdb2"/>
+ <property name="username" value="sa"/>
+ <property name="password" value=""/>
+ </properties-param>
+ </init-params>
+ </component-plugin>
+ <component-plugin>
+ <name>bind.datasource</name>
+ <set-method>addPlugin</set-method>
+ <type>org.exoplatform.services.naming.BindReferencePlugin</type>
+ <init-params>
+ <value-param>
+ <name>bind-name</name>
<value>jdbcjcrtck</value>
</value-param>
<value-param>
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-jcr-config.xml
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-jcr-config.xml 2010-11-01 10:04:33 UTC (rev 3371)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/test/resources/conf/standalone/cluster/test-jcr-config.xml 2010-11-01 10:50:31 UTC (rev 3372)
@@ -311,8 +311,145 @@
</properties>
</lock-manager>
</workspace>
+ </workspaces>
+ </repository>
+ <repository name="db2" system-workspace="ws" default-workspace="ws">
+ <security-domain>exo-domain</security-domain>
+ <!-- access-control>optional</access-control -->
+ <!-- access-control>disable</access-control -->
+ <session-max-age>1h</session-max-age>
+ <authentication-policy>org.exoplatform.services.jcr.impl.core.access.JAASAuthenticator</authentication-policy>
+ <workspaces>
+ <workspace name="ws">
+ <!-- for system storage -->
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.CQJDBCWorkspaceDataContainer">
+ <properties>
+ <property name="source-name" value="jdbcjcrdb2" />
+ <property name="multi-db" value="true" />
+ <property name="update-storage" value="false" />
+ <property name="max-buffer-size" value="200k" />
+ <property name="swap-directory" value="target/temp/swap/wsdb2" />
+ </properties>
+ <value-storages>
+ <value-storage id="ws"
+ class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
+ <properties>
+ <property name="path" value="target/temp/values/wsdb2" />
+ </properties>
+ <filters>
+ <filter property-type="Binary" min-value-size="100K" />
+ </filters>
+ </value-storage>
+ </value-storages>
+ </container>
+ <initializer class="org.exoplatform.services.jcr.impl.core.ScratchWorkspaceInitializer">
+ <properties>
+ <property name="root-nodetype" value="nt:unstructured" />
+ <property name="root-permissions" value="*:/platform/administrators read;*:/platform/administrators add_node;*:/platform/administrators set_property;*:/platform/administrators remove" />
+ </properties>
+ </initializer>
+ <cache enabled="true" class="org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.JBossCacheWorkspaceStorageCache">
+ <properties>
+ <property name="jbosscache-configuration" value="test-jbosscache-data.xml" />
+ <property name="jgroups-configuration" value="udp-mux.xml" />
+ <property name="jgroups-multiplexer-stack" value="true" />
+ <property name="jbosscache-cluster-name" value="JCR-cluster-db2-ws" />
+ </properties>
+ </cache>
+ <query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
+ <properties>
+ <property name="index-dir" value="target/temp/index/db2/ws" />
+ <property name="changesfilter-class" value="org.exoplatform.services.jcr.impl.core.query.jbosscache.JBossCacheIndexChangesFilter" />
+ <property name="jbosscache-configuration" value="test-jbosscache-indexer.xml" />
+ <property name="jgroups-configuration" value="udp-mux.xml" />
+ <property name="jgroups-multiplexer-stack" value="true" />
+ <property name="jbosscache-cluster-name" value="JCR-cluster-indexer-db2-ws" />
+ </properties>
+ </query-handler>
+ <lock-manager class="org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl">
+ <properties>
+ <property name="time-out" value="15m" />
+ <property name="jbosscache-configuration" value="test-jbosscache-lock.xml" />
+ <property name="jgroups-configuration" value="udp-mux.xml" />
+ <property name="jgroups-multiplexer-stack" value="true" />
+ <property name="jbosscache-cluster-name" value="JCR-cluster-locks-db2-ws" />
+ <property name="jbosscache-cl-cache.jdbc.table.name" value="jcrlocks_db2tck_ws" />
+ <property name="jbosscache-cl-cache.jdbc.table.create" value="true" />
+ <property name="jbosscache-cl-cache.jdbc.table.drop" value="false" />
+ <property name="jbosscache-cl-cache.jdbc.table.primarykey" value="jcrlocks_db2tck_ws_pk" />
+ <property name="jbosscache-cl-cache.jdbc.fqn.column" value="fqn" />
+ <property name="jbosscache-cl-cache.jdbc.node.column" value="node" />
+ <property name="jbosscache-cl-cache.jdbc.parent.column" value="parent" />
+ <property name="jbosscache-cl-cache.jdbc.datasource" value="jdbcjcr" />
+ </properties>
+ </lock-manager>
+ </workspace>
+ <workspace name="ws1">
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.CQJDBCWorkspaceDataContainer">
+ <properties>
+ <property name="source-name" value="jdbcjcr1db2" />
+ <property name="multi-db" value="true" />
+ <property name="update-storage" value="false" />
+ <property name="max-buffer-size" value="200k" />
+ <property name="swap-directory" value="target/temp/swap/ws1db2" />
+ </properties>
+ <value-storages>
+ <value-storage id="ws1"
+ class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
+ <properties>
+ <property name="path" value="target/temp/values/ws1db2" />
+ </properties>
+ <filters>
+ <filter property-type="Binary" min-value-size="100K" />
+ </filters>
+ </value-storage>
+ </value-storages>
+ </container>
+ <initializer class="org.exoplatform.services.jcr.impl.core.ScratchWorkspaceInitializer">
+ <properties>
+ <property name="root-nodetype" value="nt:unstructured" />
+ <property name="root-permissions" value="any read;any add_node;any set_property;any remove" />
+ </properties>
+ </initializer>
+ <cache enabled="true"
+ class="org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.JBossCacheWorkspaceStorageCache">
+ <properties>
+ <property name="jbosscache-configuration" value="test-jbosscache-data.xml" />
+ <property name="jgroups-configuration" value="udp-mux.xml" />
+ <property name="jgroups-multiplexer-stack" value="true" />
+ <property name="jbosscache-cluster-name" value="JCR-cluster-db2-ws1" />
+ </properties>
+ </cache>
+ <query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
+ <properties>
+ <property name="index-dir" value="target/temp/index/db2/ws1" />
+ <property name="changesfilter-class" value="org.exoplatform.services.jcr.impl.core.query.jbosscache.JBossCacheIndexChangesFilter" />
+ <property name="jbosscache-configuration" value="test-jbosscache-indexer.xml" />
+ <property name="jgroups-configuration" value="udp-mux.xml" />
+ <property name="jgroups-multiplexer-stack" value="true" />
+ <property name="jbosscache-cluster-name" value="JCR-cluster-indexer-db2-ws1" />
+ </properties>
+ </query-handler>
+ <lock-manager class="org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl">
+ <properties>
+ <property name="time-out" value="15m" />
+ <property name="jbosscache-configuration" value="test-jbosscache-lock.xml" />
+ <property name="jgroups-configuration" value="udp-mux.xml" />
+ <property name="jgroups-multiplexer-stack" value="true" />
+ <property name="jbosscache-cluster-name" value="JCR-cluster-locks-db2-ws1" />
+ <property name="jbosscache-cl-cache.jdbc.table.name" value="jcrlocks_db2_ws1" />
+ <property name="jbosscache-cl-cache.jdbc.table.create" value="true" />
+ <property name="jbosscache-cl-cache.jdbc.table.drop" value="false" />
+ <property name="jbosscache-cl-cache.jdbc.table.primarykey" value="jcrlocks_db2_ws1_pk" />
+ <property name="jbosscache-cl-cache.jdbc.fqn.column" value="fqn" />
+ <property name="jbosscache-cl-cache.jdbc.node.column" value="node" />
+ <property name="jbosscache-cl-cache.jdbc.parent.column" value="parent" />
+ <property name="jbosscache-cl-cache.jdbc.datasource" value="jdbcjcr" />
+ </properties>
+ </lock-manager>
+ </workspace>
</workspaces>
</repository>
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/test/resources/conf/standalone/test-configuration-sjdbc.xml
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/test/resources/conf/standalone/test-configuration-sjdbc.xml 2010-11-01 10:04:33 UTC (rev 3371)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/test/resources/conf/standalone/test-configuration-sjdbc.xml 2010-11-01 10:50:31 UTC (rev 3372)
@@ -289,6 +289,33 @@
<init-params>
<value-param>
<name>bind-name</name>
+ <value>jdbcjcrdb2</value>
+ </value-param>
+ <value-param>
+ <name>class-name</name>
+ <value>javax.sql.DataSource</value>
+ </value-param>
+ <value-param>
+ <name>factory</name>
+ <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
+ </value-param>
+ <properties-param>
+ <name>ref-addresses</name>
+ <description>ref-addresses</description>
+ <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
+ <property name="url" value="jdbc:hsqldb:file:target/temp/data/portaldb2"/>
+ <property name="username" value="sa"/>
+ <property name="password" value=""/>
+ </properties-param>
+ </init-params>
+ </component-plugin>
+ <component-plugin>
+ <name>bind.datasource</name>
+ <set-method>addPlugin</set-method>
+ <type>org.exoplatform.services.naming.BindReferencePlugin</type>
+ <init-params>
+ <value-param>
+ <name>bind-name</name>
<value>jdbcjcrtck</value>
</value-param>
<value-param>
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/test/resources/conf/standalone/test-configuration.xml
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/test/resources/conf/standalone/test-configuration.xml 2010-11-01 10:04:33 UTC (rev 3371)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/test/resources/conf/standalone/test-configuration.xml 2010-11-01 10:50:31 UTC (rev 3372)
@@ -255,7 +255,7 @@
</properties-param>
</init-params>
</component-plugin>
- <component-plugin>
+ <component-plugin>
<name>bind.datasource</name>
<set-method>addPlugin</set-method>
<type>org.exoplatform.services.naming.BindReferencePlugin</type>
@@ -336,7 +336,7 @@
</properties-param>
</init-params>
</component-plugin>
- <component-plugin>
+ <component-plugin>
<name>bind.datasource</name>
<set-method>addPlugin</set-method>
<type>org.exoplatform.services.naming.BindReferencePlugin</type>
@@ -370,6 +370,60 @@
<init-params>
<value-param>
<name>bind-name</name>
+ <value>jdbcjcrdb2</value>
+ </value-param>
+ <value-param>
+ <name>class-name</name>
+ <value>javax.sql.DataSource</value>
+ </value-param>
+ <value-param>
+ <name>factory</name>
+ <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
+ </value-param>
+ <properties-param>
+ <name>ref-addresses</name>
+ <description>ref-addresses</description>
+ <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
+ <property name="url" value="jdbc:hsqldb:file:target/temp/data/portaldb2"/>
+ <property name="username" value="sa"/>
+ <property name="password" value=""/>
+ </properties-param>
+ </init-params>
+ </component-plugin>
+ <component-plugin>
+ <name>bind.datasource</name>
+ <set-method>addPlugin</set-method>
+ <type>org.exoplatform.services.naming.BindReferencePlugin</type>
+ <init-params>
+ <value-param>
+ <name>bind-name</name>
+ <value>jdbcjcr1db2</value>
+ </value-param>
+ <value-param>
+ <name>class-name</name>
+ <value>javax.sql.DataSource</value>
+ </value-param>
+ <value-param>
+ <name>factory</name>
+ <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
+ </value-param>
+ <properties-param>
+ <name>ref-addresses</name>
+ <description>ref-addresses</description>
+ <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
+ <property name="url" value="jdbc:hsqldb:file:target/temp/data/jcrdb2"/>
+ <property name="username" value="sa"/>
+ <property name="password" value=""/>
+ </properties-param>
+ </init-params>
+ </component-plugin>
+ <component-plugin>
+ <name>bind.datasource</name>
+ <set-method>addPlugin</set-method>
+ <type>org.exoplatform.services.naming.BindReferencePlugin</type>
+ <init-params>
+ <value-param>
+ <name>bind-name</name>
<value>jdbcjcrtck</value>
</value-param>
<value-param>
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/test/resources/conf/standalone/test-jcr-config-sjdbc.xml
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/test/resources/conf/standalone/test-jcr-config-sjdbc.xml 2010-11-01 10:04:33 UTC (rev 3371)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/test/resources/conf/standalone/test-jcr-config-sjdbc.xml 2010-11-01 10:50:31 UTC (rev 3372)
@@ -287,6 +287,126 @@
</workspaces>
</repository>
+ <repository name="db2" system-workspace="ws" default-workspace="ws">
+ <security-domain>exo-domain</security-domain>
+ <!-- access-control>optional</access-control -->
+ <!-- access-control>disable</access-control -->
+ <session-max-age>1h</session-max-age>
+ <authentication-policy>org.exoplatform.services.jcr.impl.core.access.JAASAuthenticator</authentication-policy>
+ <workspaces>
+ <workspace name="ws">
+ <!-- for system storage -->
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.CQJDBCWorkspaceDataContainer">
+ <properties>
+ <property name="source-name" value="jdbcjcrdb2" />
+ <property name="dialect" value="auto" />
+ <property name="multi-db" value="false" />
+ <property name="update-storage" value="false" />
+ <property name="max-buffer-size" value="200k" />
+ <property name="swap-directory" value="target/temp/swap/wsdb2" />
+ </properties>
+ <value-storages>
+ <value-storage id="ws" class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
+ <properties>
+ <property name="path" value="target/temp/values/wsdb2" />
+ </properties>
+ <filters>
+ <filter property-type="Binary" min-value-size="100K" />
+ </filters>
+ </value-storage>
+ </value-storages>
+ </container>
+ <initializer class="org.exoplatform.services.jcr.impl.core.ScratchWorkspaceInitializer">
+ <properties>
+ <property name="root-nodetype" value="nt:unstructured" />
+ <property name="root-permissions" value="*:/platform/administrators read;*:/platform/administrators add_node;*:/platform/administrators set_property;*:/platform/administrators remove" />
+ </properties>
+ </initializer>
+ <cache enabled="true" class="org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.JBossCacheWorkspaceStorageCache">
+ <properties>
+ <property name="jbosscache-configuration" value="conf/standalone/test-jbosscache-config.xml" />
+ <property name="jbosscache-shareable" value="${jbosscache-shareable}" />
+ </properties>
+ </cache>
+ <query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
+ <properties>
+ <property name="index-dir" value="target/temp/index/db2/ws" />
+ </properties>
+ </query-handler>
+ <lock-manager class="org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl">
+ <properties>
+ <property name="time-out" value="15m" />
+ <property name="jbosscache-configuration" value="conf/standalone/test-jbosscache-lock.xml" />
+ <property name="jbosscache-cl-cache.jdbc.table.name" value="jcrlocks_db2_ws" />
+ <property name="jbosscache-cl-cache.jdbc.table.create" value="true" />
+ <property name="jbosscache-cl-cache.jdbc.table.drop" value="false" />
+ <property name="jbosscache-cl-cache.jdbc.table.primarykey" value="jcrlocks_db2_ws_pk" />
+ <property name="jbosscache-cl-cache.jdbc.fqn.column" value="fqn" />
+ <property name="jbosscache-cl-cache.jdbc.node.column" value="node" />
+ <property name="jbosscache-cl-cache.jdbc.parent.column" value="parent" />
+ <property name="jbosscache-cl-cache.jdbc.datasource" value="jdbcjcrdb2" />
+ <property name="jbosscache-shareable" value="${jbosscache-shareable}" />
+ </properties>
+ </lock-manager>
+ </workspace>
+
+ <workspace name="ws1">
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.CQJDBCWorkspaceDataContainer">
+ <properties>
+ <property name="source-name" value="jdbcjcrdb2" />
+ <property name="dialect" value="auto" />
+ <property name="multi-db" value="false" />
+ <property name="update-storage" value="false" />
+ <property name="max-buffer-size" value="200k" />
+ <property name="swap-directory" value="target/temp/swap/ws1db2" />
+ </properties>
+ <value-storages>
+ <value-storage id="ws1" class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
+ <properties>
+ <property name="path" value="target/temp/values/ws1db2" />
+ </properties>
+ <filters>
+ <filter property-type="Binary" min-value-size="100K" />
+ </filters>
+ </value-storage>
+ </value-storages>
+ </container>
+ <initializer class="org.exoplatform.services.jcr.impl.core.ScratchWorkspaceInitializer">
+ <properties>
+ <property name="root-nodetype" value="nt:unstructured" />
+ <property name="root-permissions" value="any read;any add_node;any set_property;any remove" />
+ </properties>
+ </initializer>
+ <cache enabled="true" class="org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.JBossCacheWorkspaceStorageCache">
+ <properties>
+ <property name="jbosscache-configuration" value="conf/standalone/test-jbosscache-config.xml" />
+ <property name="jbosscache-shareable" value="${jbosscache-shareable}" />
+ </properties>
+ </cache>
+ <query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
+ <properties>
+ <property name="index-dir" value="target/temp/index/db2/ws1" />
+ </properties>
+ </query-handler>
+ <lock-manager class="org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl">
+ <properties>
+ <property name="time-out" value="15m" />
+ <property name="jbosscache-configuration" value="conf/standalone/test-jbosscache-lock.xml" />
+ <property name="jbosscache-cl-cache.jdbc.table.name" value="jcrlocks_db2_ws1" />
+ <property name="jbosscache-cl-cache.jdbc.table.create" value="true" />
+ <property name="jbosscache-cl-cache.jdbc.table.drop" value="false" />
+ <property name="jbosscache-cl-cache.jdbc.table.primarykey" value="jcrlocks_db2_ws1_pk" />
+ <property name="jbosscache-cl-cache.jdbc.fqn.column" value="fqn" />
+ <property name="jbosscache-cl-cache.jdbc.node.column" value="node" />
+ <property name="jbosscache-cl-cache.jdbc.parent.column" value="parent" />
+ <property name="jbosscache-cl-cache.jdbc.datasource" value="jdbcjcrdb2" />
+ <property name="jbosscache-shareable" value="${jbosscache-shareable}" />
+ </properties>
+ </lock-manager>
+ </workspace>
+ </workspaces>
+ </repository>
+
<repository name="db1tck" system-workspace="ws" default-workspace="ws">
<security-domain>exo-domain</security-domain>
<!-- access-control>optional</access-control -->
Modified: jcr/branches/1.12.x/exo.jcr.component.core/src/test/resources/conf/standalone/test-jcr-config.xml
===================================================================
--- jcr/branches/1.12.x/exo.jcr.component.core/src/test/resources/conf/standalone/test-jcr-config.xml 2010-11-01 10:04:33 UTC (rev 3371)
+++ jcr/branches/1.12.x/exo.jcr.component.core/src/test/resources/conf/standalone/test-jcr-config.xml 2010-11-01 10:50:31 UTC (rev 3372)
@@ -286,6 +286,127 @@
</workspace>
</workspaces>
</repository>
+
+ <repository name="db2" system-workspace="ws" default-workspace="ws">
+ <security-domain>exo-domain</security-domain>
+ <!-- access-control>optional</access-control -->
+ <!-- access-control>disable</access-control -->
+ <session-max-age>1h</session-max-age>
+ <authentication-policy>org.exoplatform.services.jcr.impl.core.access.JAASAuthenticator</authentication-policy>
+ <workspaces>
+ <workspace name="ws">
+ <!-- for system storage -->
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.CQJDBCWorkspaceDataContainer">
+ <properties>
+ <property name="source-name" value="jdbcjcrdb2" />
+ <property name="dialect" value="auto" />
+ <property name="multi-db" value="true" />
+ <property name="update-storage" value="false" />
+ <property name="max-buffer-size" value="200k" />
+ <property name="swap-directory" value="target/temp/swap/wsdb2" />
+ </properties>
+ <value-storages>
+ <value-storage id="ws" class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
+ <properties>
+ <property name="path" value="target/temp/values/wsdb2" />
+ </properties>
+ <filters>
+ <filter property-type="Binary" min-value-size="100K" />
+ </filters>
+ </value-storage>
+ </value-storages>
+ </container>
+ <initializer class="org.exoplatform.services.jcr.impl.core.ScratchWorkspaceInitializer">
+ <properties>
+ <property name="root-nodetype" value="nt:unstructured" />
+ <property name="root-permissions" value="*:/platform/administrators read;*:/platform/administrators add_node;*:/platform/administrators set_property;*:/platform/administrators remove" />
+ </properties>
+ </initializer>
+ <cache enabled="true" class="org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.JBossCacheWorkspaceStorageCache">
+ <properties>
+ <property name="jbosscache-configuration" value="conf/standalone/test-jbosscache-config.xml" />
+ <property name="jbosscache-shareable" value="${jbosscache-shareable}" />
+ </properties>
+ </cache>
+ <query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
+ <properties>
+ <property name="index-dir" value="target/temp/index/db2/ws" />
+ </properties>
+ </query-handler>
+ <lock-manager class="org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl">
+ <properties>
+ <property name="time-out" value="15m" />
+ <property name="jbosscache-configuration" value="conf/standalone/test-jbosscache-lock.xml" />
+ <property name="jbosscache-cl-cache.jdbc.table.name" value="jcrlocks_db2_ws" />
+ <property name="jbosscache-cl-cache.jdbc.table.create" value="true" />
+ <property name="jbosscache-cl-cache.jdbc.table.drop" value="false" />
+ <property name="jbosscache-cl-cache.jdbc.table.primarykey" value="jcrlocks_db2_ws_pk" />
+ <property name="jbosscache-cl-cache.jdbc.fqn.column" value="fqn" />
+ <property name="jbosscache-cl-cache.jdbc.node.column" value="node" />
+ <property name="jbosscache-cl-cache.jdbc.parent.column" value="parent" />
+ <property name="jbosscache-cl-cache.jdbc.datasource" value="jdbcjcrdb2" />
+ <property name="jbosscache-shareable" value="${jbosscache-shareable}" />
+ </properties>
+ </lock-manager>
+ </workspace>
+
+ <workspace name="ws1">
+ <container class="org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.CQJDBCWorkspaceDataContainer">
+ <properties>
+ <property name="source-name" value="jdbcjcr1db2" />
+ <property name="dialect" value="auto" />
+ <property name="multi-db" value="true" />
+ <property name="update-storage" value="false" />
+ <property name="max-buffer-size" value="200k" />
+ <property name="swap-directory" value="target/temp/swap/ws1db2" />
+ </properties>
+ <value-storages>
+ <value-storage id="ws1" class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
+ <properties>
+ <property name="path" value="target/temp/values/ws1db2" />
+ </properties>
+ <filters>
+ <filter property-type="Binary" min-value-size="100K" />
+ </filters>
+ </value-storage>
+ </value-storages>
+ </container>
+ <initializer class="org.exoplatform.services.jcr.impl.core.ScratchWorkspaceInitializer">
+ <properties>
+ <property name="root-nodetype" value="nt:unstructured" />
+ <property name="root-permissions" value="any read;any add_node;any set_property;any remove" />
+ </properties>
+ </initializer>
+ <cache enabled="true" class="org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.JBossCacheWorkspaceStorageCache">
+ <properties>
+ <property name="jbosscache-configuration" value="conf/standalone/test-jbosscache-config.xml" />
+ <property name="jbosscache-shareable" value="${jbosscache-shareable}" />
+ </properties>
+ </cache>
+ <query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
+ <properties>
+ <property name="index-dir" value="target/temp/index/db2/ws1" />
+ </properties>
+ </query-handler>
+ <lock-manager class="org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl">
+ <properties>
+ <property name="time-out" value="15m" />
+ <property name="jbosscache-configuration" value="conf/standalone/test-jbosscache-lock.xml" />
+ <property name="jbosscache-cl-cache.jdbc.table.name" value="jcrlocks_db2_ws1" />
+ <property name="jbosscache-cl-cache.jdbc.table.create" value="true" />
+ <property name="jbosscache-cl-cache.jdbc.table.drop" value="false" />
+ <property name="jbosscache-cl-cache.jdbc.table.primarykey" value="jcrlocks_db2_ws1_pk" />
+ <property name="jbosscache-cl-cache.jdbc.fqn.column" value="fqn" />
+ <property name="jbosscache-cl-cache.jdbc.node.column" value="node" />
+ <property name="jbosscache-cl-cache.jdbc.parent.column" value="parent" />
+ <property name="jbosscache-cl-cache.jdbc.datasource" value="jdbcjcr1db2" />
+ <property name="jbosscache-shareable" value="${jbosscache-shareable}" />
+ </properties>
+ </lock-manager>
+ </workspace>
+ </workspaces>
+ </repository>
+
<repository name="db1tck" system-workspace="ws" default-workspace="ws">
<security-domain>exo-domain</security-domain>
13 years, 6 months
exo-jcr SVN: r3371 - in jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr: impl/core and 1 other directory.
by do-not-reply@jboss.org
Author: tolusha
Date: 2010-11-01 06:04:33 -0400 (Mon, 01 Nov 2010)
New Revision: 3371
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/ItemState.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java
Log:
JCR-1485: The access permission should be checked in the method readItem to ensure that the security cannot be avoided. The access permission should be checked only when apiRead == false since when apiRead == true we check the permissions at JCR level. Check also the access permission in the constructor of ItemState when isInternalCreated == true
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/ItemState.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/ItemState.java 2010-10-29 15:43:22 UTC (rev 3370)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/dataflow/ItemState.java 2010-11-01 10:04:33 UTC (rev 3371)
@@ -18,6 +18,7 @@
*/
package org.exoplatform.services.jcr.dataflow;
+import org.exoplatform.services.jcr.core.security.JCRRuntimePermissions;
import org.exoplatform.services.jcr.datamodel.ItemData;
import org.exoplatform.services.jcr.datamodel.QPath;
import org.exoplatform.services.log.ExoLogger;
@@ -102,7 +103,7 @@
* @param ancestorToSave
* - path of item which should be called in save (usually for session.move())
* @param isInternalCreated
- * - indicates that item is created internaly by system
+ * - indicates that item is created internally by system
*/
public ItemState(ItemData data, int state, boolean eventFire, QPath ancestorToSave, boolean isInternalCreated)
{
@@ -112,6 +113,16 @@
public ItemState(ItemData data, int state, boolean eventFire, QPath ancestorToSave, boolean isInternalCreated,
boolean isPersisted)
{
+ if (isInternalCreated)
+ {
+ // Need privileges
+ SecurityManager security = System.getSecurityManager();
+ if (security != null)
+ {
+ security.checkPermission(JCRRuntimePermissions.INVOKE_INTERNAL_API_PERMISSION);
+ }
+ }
+
this.data = data;
this.state = state;
this.eventFire = eventFire;
@@ -208,6 +219,7 @@
return ancestorToSave;
}
+ @Override
public boolean equals(Object obj)
{
if (this == obj)
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java 2010-10-29 15:43:22 UTC (rev 3370)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java 2010-11-01 10:04:33 UTC (rev 3371)
@@ -357,13 +357,6 @@
public ItemImpl getItem(NodeData parent, QPathEntry name, boolean pool, ItemType itemType, boolean apiRead)
throws RepositoryException
{
- // Need privileges
- SecurityManager security = System.getSecurityManager();
- if (security != null)
- {
- security.checkPermission(JCRRuntimePermissions.INVOKE_INTERNAL_API_PERMISSION);
- }
-
long start = System.currentTimeMillis();
if (log.isDebugEnabled())
{
@@ -577,6 +570,16 @@
protected ItemImpl readItem(ItemData itemData, NodeData parent, boolean pool, boolean apiRead)
throws RepositoryException
{
+ if (!apiRead)
+ {
+ // Need privileges
+ SecurityManager security = System.getSecurityManager();
+ if (security != null)
+ {
+ security.checkPermission(JCRRuntimePermissions.INVOKE_INTERNAL_API_PERMISSION);
+ }
+ }
+
if (itemData != null)
{
ItemImpl item;
@@ -639,13 +642,6 @@
*/
public ItemImpl getItemByIdentifier(String identifier, boolean pool, boolean apiRead) throws RepositoryException
{
- // Need privileges
- SecurityManager security = System.getSecurityManager();
- if (security != null)
- {
- security.checkPermission(JCRRuntimePermissions.INVOKE_INTERNAL_API_PERMISSION);
- }
-
long start = System.currentTimeMillis();
if (log.isDebugEnabled())
{
13 years, 6 months