Merged BRANCHES/DEV/CLOUD1-BUG-FIX to HEAD:

42432: CLOUD-795: Optimise activities feed: rollup multiple (WebDAV) document adds/deletes into a single activity


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@42563 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Jan Vonka
2012-10-12 09:07:35 +00:00
parent b2300ac794
commit 339870a595
4 changed files with 504 additions and 543 deletions

View File

@@ -41,5 +41,6 @@ public interface ActivityPoster
String siteId, String siteId,
String tenantDomain, String tenantDomain,
String parentPath, String parentPath,
FileInfo parentNodeInfo,
FileInfo contentNodeInfo) throws WebDAVServerException; FileInfo contentNodeInfo) throws WebDAVServerException;
} }

View File

@@ -20,15 +20,11 @@ package org.alfresco.repo.webdav;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.alfresco.model.ContentModel; import org.alfresco.repo.activities.ActivityType;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.tenant.TenantService; import org.alfresco.repo.tenant.TenantService;
import org.alfresco.service.cmr.activities.ActivityService; import org.alfresco.service.cmr.activities.ActivityService;
import org.alfresco.service.cmr.model.FileInfo; import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.util.Pair;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
@@ -40,13 +36,8 @@ import org.json.JSONObject;
*/ */
public class ActivityPosterImpl implements ActivityPoster public class ActivityPosterImpl implements ActivityPoster
{ {
private static final String FILE_ADDED = "org.alfresco.documentlibrary.file-added";
private static final String FILE_UPDATED = "org.alfresco.documentlibrary.file-updated";
private static final String FILE_DELETED = "org.alfresco.documentlibrary.file-deleted";
private String appTool; private String appTool;
private ActivityService activityService; private ActivityService activityService;
private NodeService nodeService;
private PersonService personService;
/** /**
@@ -64,12 +55,10 @@ public class ActivityPosterImpl implements ActivityPoster
* @param nodeService * @param nodeService
* @param personService * @param personService
*/ */
public ActivityPosterImpl(String appTool, ActivityService activityService, NodeService nodeService, PersonService personService) public ActivityPosterImpl(String appTool, ActivityService activityService)
{ {
this.appTool = appTool; this.appTool = appTool;
this.activityService = activityService; this.activityService = activityService;
this.nodeService = nodeService;
this.personService = personService;
} }
@@ -82,7 +71,7 @@ public class ActivityPosterImpl implements ActivityPoster
String tenantDomain, String tenantDomain,
FileInfo contentNodeInfo) throws WebDAVServerException FileInfo contentNodeInfo) throws WebDAVServerException
{ {
postFileActivity(FILE_ADDED, siteId, tenantDomain, null, contentNodeInfo); postFileActivity(ActivityType.FILE_ADDED, siteId, tenantDomain, null, null, contentNodeInfo);
} }
/** /**
@@ -94,7 +83,7 @@ public class ActivityPosterImpl implements ActivityPoster
String tenantDomain, String tenantDomain,
FileInfo contentNodeInfo) throws WebDAVServerException FileInfo contentNodeInfo) throws WebDAVServerException
{ {
postFileActivity(FILE_UPDATED, siteId, tenantDomain, null, contentNodeInfo); postFileActivity(ActivityType.FILE_UPDATED, siteId, tenantDomain, null, null, contentNodeInfo);
} }
/** /**
@@ -105,9 +94,10 @@ public class ActivityPosterImpl implements ActivityPoster
String siteId, String siteId,
String tenantDomain, String tenantDomain,
String parentPath, String parentPath,
FileInfo parentNodeInfo,
FileInfo contentNodeInfo) throws WebDAVServerException FileInfo contentNodeInfo) throws WebDAVServerException
{ {
postFileActivity(FILE_DELETED, siteId, tenantDomain, parentPath, contentNodeInfo); postFileActivity(ActivityType.FILE_DELETED, siteId, tenantDomain, parentPath, parentNodeInfo.getNodeRef(), contentNodeInfo);
} }
@@ -116,14 +106,13 @@ public class ActivityPosterImpl implements ActivityPoster
String siteId, String siteId,
String tenantDomain, String tenantDomain,
String parentPath, String parentPath,
NodeRef parentNodeRef,
FileInfo contentNodeInfo) throws WebDAVServerException FileInfo contentNodeInfo) throws WebDAVServerException
{ {
Pair<String, String> personName = getPersonName(); String fileName = contentNodeInfo.getName();
final String firstName = personName.getFirst(); NodeRef nodeRef = contentNodeInfo.getNodeRef();
final String lastName = personName.getSecond();
final String fileName = contentNodeInfo.getName(); JSONObject json = createActivityJSON(tenantDomain, parentPath, parentNodeRef, nodeRef, fileName);
final NodeRef nodeRef = contentNodeInfo.getNodeRef();
JSONObject json = createActivityJSON(tenantDomain, parentPath, nodeRef, firstName, lastName, fileName);
activityService.postActivity( activityService.postActivity(
activityType, activityType,
@@ -138,8 +127,6 @@ public class ActivityPosterImpl implements ActivityPoster
* *
* @param tenantDomain * @param tenantDomain
* @param nodeRef * @param nodeRef
* @param firstName
* @param lastName
* @param fileName * @param fileName
* @throws WebDAVServerException * @throws WebDAVServerException
* @return JSONObject * @return JSONObject
@@ -147,19 +134,25 @@ public class ActivityPosterImpl implements ActivityPoster
private JSONObject createActivityJSON( private JSONObject createActivityJSON(
String tenantDomain, String tenantDomain,
String parentPath, String parentPath,
NodeRef parentNodeRef,
NodeRef nodeRef, NodeRef nodeRef,
String firstName,
String lastName,
String fileName) throws WebDAVServerException String fileName) throws WebDAVServerException
{ {
JSONObject json = new JSONObject(); JSONObject json = new JSONObject();
try try
{ {
json.put("nodeRef", nodeRef); json.put("nodeRef", nodeRef);
if (parentNodeRef != null)
{
// Used for deleted files.
json.put("parentNodeRef", parentNodeRef);
}
if (parentPath != null) if (parentPath != null)
{ {
// Used for deleted files. // Used for deleted files.
json.put("page", "documentlibrary?path=" + parentPath); json.put("page", "documentlibrary?path=" + parentPath);
} }
else else
{ {
@@ -167,8 +160,7 @@ public class ActivityPosterImpl implements ActivityPoster
json.put("page", "document-details?nodeRef=" + nodeRef); json.put("page", "document-details?nodeRef=" + nodeRef);
} }
json.put("title", fileName); json.put("title", fileName);
json.put("firstName", firstName);
json.put("lastName", lastName);
if (!tenantDomain.equals(TenantService.DEFAULT_DOMAIN)) if (!tenantDomain.equals(TenantService.DEFAULT_DOMAIN))
{ {
// Only used in multi-tenant setups. // Only used in multi-tenant setups.
@@ -183,26 +175,6 @@ public class ActivityPosterImpl implements ActivityPoster
return json; return json;
} }
/**
* Creates the tuple (firstName, lastName) for the current user.
*
* @return Pair&lt;String, String&gt;
*/
private Pair<String, String> getPersonName()
{
String firstName = "";
String lastName = "";
String userName = AuthenticationUtil.getFullyAuthenticatedUser();
NodeRef person = personService.getPerson(userName);
if (person != null)
{
firstName = (String) nodeService.getProperty(person, ContentModel.PROP_FIRSTNAME);
lastName = (String) nodeService.getProperty(person, ContentModel.PROP_LASTNAME);
}
return new Pair<String, String>(firstName, lastName);
}
public void setAppTool(String appTool) public void setAppTool(String appTool)
{ {
this.appTool = appTool; this.appTool = appTool;
@@ -212,14 +184,4 @@ public class ActivityPosterImpl implements ActivityPoster
{ {
this.activityService = activityService; this.activityService = activityService;
} }
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setPersonService(PersonService personService)
{
this.personService = personService;
}
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005-2010 Alfresco Software Limited. * Copyright (C) 2005-2012 Alfresco Software Limited.
* *
* This file is part of Alfresco * This file is part of Alfresco
* *
@@ -146,7 +146,7 @@ public class DeleteMethod extends WebDAVMethod implements ActivityPostProducer
String parentPath = "/"; String parentPath = "/";
try try
{ {
parentPath = getDAVHelper().getPathFromNode(documentLibrary, parent.getNodeRef()); parentPath = getDAVHelper().getPathFromNode(documentLibrary, parent.getNodeRef());
} }
catch (FileNotFoundException error) catch (FileNotFoundException error)
{ {
@@ -156,7 +156,7 @@ public class DeleteMethod extends WebDAVMethod implements ActivityPostProducer
} }
} }
activityPoster.postFileDeleted(siteId, tenantDomain, parentPath, deletedFile); activityPoster.postFileDeleted(siteId, tenantDomain, parentPath, parent, deletedFile);
} }
} }

View File

@@ -1,488 +1,486 @@
/* /*
* Copyright (C) 2005-2011 Alfresco Software Limited. * Copyright (C) 2005-2012 Alfresco Software Limited.
* *
* This file is part of Alfresco * This file is part of Alfresco
* *
* Alfresco is free software: you can redistribute it and/or modify * Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by * it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* Alfresco is distributed in the hope that it will be useful, * Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details. * GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.alfresco.repo.webdav; package org.alfresco.repo.webdav;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.List; import java.util.List;
import javax.servlet.ServletConfig; import javax.servlet.ServletConfig;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.UnavailableException; import javax.servlet.UnavailableException;
import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.transaction.UserTransaction; import javax.transaction.UserTransaction;
import org.alfresco.repo.cache.SimpleCache; import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.security.authentication.AuthenticationContext; import org.alfresco.repo.security.authentication.AuthenticationContext;
import org.alfresco.repo.tenant.TenantService; import org.alfresco.repo.tenant.TenantService;
import org.alfresco.service.ServiceRegistry; import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.activities.ActivityService; import org.alfresco.service.cmr.activities.ActivityService;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.transaction.TransactionService;
import org.alfresco.service.transaction.TransactionService; import org.alfresco.util.FileFilterMode;
import org.alfresco.util.FileFilterMode; import org.alfresco.util.FileFilterMode.Client;
import org.alfresco.util.FileFilterMode.Client; import org.alfresco.util.PropertyCheck;
import org.alfresco.util.PropertyCheck; import org.apache.commons.logging.Log;
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.LogFactory; import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.context.support.WebApplicationContextUtils;
/**
/** * Servlet that accepts WebDAV requests for the hub. The request is served by the hub's content
* Servlet that accepts WebDAV requests for the hub. The request is served by the hub's content * repository framework and the response sent back using the WebDAV protocol.
* repository framework and the response sent back using the WebDAV protocol. *
* * @author gavinc
* @author gavinc */
*/ public class WebDAVServlet extends HttpServlet
public class WebDAVServlet extends HttpServlet {
{ private static final long serialVersionUID = 6900069445027527165L;
private static final long serialVersionUID = 6900069445027527165L;
// Logging
// Logging private static Log logger = LogFactory.getLog("org.alfresco.webdav.protocol");
private static Log logger = LogFactory.getLog("org.alfresco.webdav.protocol");
// Constants
// Constants public static final String WEBDAV_PREFIX = "webdav";
public static final String WEBDAV_PREFIX = "webdav"; //private static final String INTERNAL_SERVER_ERROR = "Internal Server Error: ";
//private static final String INTERNAL_SERVER_ERROR = "Internal Server Error: ";
// Init parameter names
// Init parameter names private static final String BEAN_INIT_PARAMS = "webdav.initParams";
private static final String BEAN_INIT_PARAMS = "webdav.initParams";
// Service registry, used by methods to find services to process requests
// Service registry, used by methods to find services to process requests private ServiceRegistry serviceRegistry;
private ServiceRegistry serviceRegistry;
private TransactionService transactionService;
private TransactionService transactionService; private static TenantService tenantService;
private static TenantService tenantService; private static NodeService nodeService;
private static NodeService nodeService; private static SearchService searchService;
private static SearchService searchService; private static NamespaceService namespaceService;
private static NamespaceService namespaceService;
// WebDAV method handlers
// WebDAV method handlers protected Hashtable<String,Class<? extends WebDAVMethod>> m_davMethods;
protected Hashtable<String,Class<? extends WebDAVMethod>> m_davMethods;
// note: cache is tenant-aware (if using EhCacheAdapter shared cache)
// note: cache is tenant-aware (if using EhCacheAdapter shared cache)
private static SimpleCache<String, NodeRef> singletonCache; // eg. for webdavRootNodeRef
private static SimpleCache<String, NodeRef> singletonCache; // eg. for webdavRootNodeRef private static final String KEY_WEBDAV_ROOT_NODEREF = "key.webdavRoot.noderef";
private static final String KEY_WEBDAV_ROOT_NODEREF = "key.webdavRoot.noderef";
private static String rootPath;
private static String rootPath;
private static NodeRef defaultRootNode; // for default domain
private static NodeRef defaultRootNode; // for default domain
// WebDAV helper class
// WebDAV helper class private WebDAVHelper m_davHelper;
private WebDAVHelper m_davHelper; private ActivityPoster activityPoster;
private ActivityPoster activityPoster;
/**
/** * @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest,
* @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest, * javax.servlet.http.HttpServletResponse)
* javax.servlet.http.HttpServletResponse) */
*/ protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException,
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
IOException {
{ long startTime = 0;
long startTime = 0; if (logger.isInfoEnabled())
if (logger.isInfoEnabled()) {
{ startTime = System.currentTimeMillis();
startTime = System.currentTimeMillis(); }
}
FileFilterMode.setClient(Client.webdav);
FileFilterMode.setClient(Client.webdav);
try
try {
{ // Create the appropriate WebDAV method for the request and execute it
// Create the appropriate WebDAV method for the request and execute it final WebDAVMethod method = createMethod(request, response);
final WebDAVMethod method = createMethod(request, response);
if (method == null)
if (method == null) {
{ if ( logger.isErrorEnabled())
if ( logger.isErrorEnabled()) logger.error("WebDAV method not implemented - " + request.getMethod());
logger.error("WebDAV method not implemented - " + request.getMethod());
// Return an error status
// Return an error status
response.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
response.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED); return;
return; }
} else if (method.getRootNodeRef() == null)
else if (method.getRootNodeRef() == null) {
{ if ( logger.isErrorEnabled())
if ( logger.isErrorEnabled()) logger.error("No root node for request");
logger.error("No root node for request");
// Return an error status
// Return an error status response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); return;
return; }
}
// Execute the WebDAV request, which must take care of its own transaction
// Execute the WebDAV request, which must take care of its own transaction method.execute();
method.execute(); }
} catch (Throwable e)
catch (Throwable e) {
{ if (!(e instanceof WebDAVServerException) && e.getCause() != null)
if (!(e instanceof WebDAVServerException) && e.getCause() != null) {
{ if (e.getCause() instanceof WebDAVServerException)
if (e.getCause() instanceof WebDAVServerException) {
{ e = e.getCause();
e = e.getCause(); }
} }
} // Work out how to handle the error
// Work out how to handle the error if (e instanceof WebDAVServerException)
if (e instanceof WebDAVServerException) {
{ WebDAVServerException error = (WebDAVServerException) e;
WebDAVServerException error = (WebDAVServerException) e; if (error.getCause() != null)
if (error.getCause() != null) {
{ StringWriter writer = new StringWriter();
StringWriter writer = new StringWriter(); PrintWriter print = new PrintWriter(writer);
PrintWriter print = new PrintWriter(writer); error.printStackTrace(print);
error.printStackTrace(print); logger.error(print.toString(), e);
logger.error(print.toString(), e); }
}
if (logger.isDebugEnabled())
if (logger.isDebugEnabled()) {
{ // Show what status code the method sent back
// Show what status code the method sent back
logger.debug(request.getMethod() + " is returning status code: " + error.getHttpStatusCode());
logger.debug(request.getMethod() + " is returning status code: " + error.getHttpStatusCode()); }
}
if (response.isCommitted())
if (response.isCommitted()) {
{ logger.warn("Could not return the status code to the client as the response has already been committed!");
logger.warn("Could not return the status code to the client as the response has already been committed!"); }
} else
else {
{ response.sendError(error.getHttpStatusCode());
response.sendError(error.getHttpStatusCode()); }
} }
} else
else {
{ StringWriter writer = new StringWriter();
StringWriter writer = new StringWriter(); PrintWriter print = new PrintWriter(writer);
PrintWriter print = new PrintWriter(writer); e.printStackTrace(print);
e.printStackTrace(print); logger.error(print.toString(), e);
logger.error(print.toString(), e);
if (response.isCommitted())
if (response.isCommitted()) {
{ logger.warn("Could not return the internal server error code to the client as the response has already been committed!");
logger.warn("Could not return the internal server error code to the client as the response has already been committed!"); }
} else
else {
{ response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); }
} }
} }
} finally
finally {
{ if (logger.isInfoEnabled())
if (logger.isInfoEnabled()) {
{ logger.info(request.getMethod() + " took " + (System.currentTimeMillis()-startTime) + "ms to execute ["+request.getRequestURI()+"]");
logger.info(request.getMethod() + " took " + (System.currentTimeMillis()-startTime) + "ms to execute ["+request.getRequestURI()+"]"); }
}
FileFilterMode.clearClient();
FileFilterMode.clearClient(); }
} }
}
/**
/** * Create a WebDAV method handler
* Create a WebDAV method handler *
* * @param request HttpServletRequest
* @param request HttpServletRequest * @param response HttpServletResponse
* @param response HttpServletResponse * @return WebDAVMethod
* @return WebDAVMethod */
*/ protected WebDAVMethod createMethod(HttpServletRequest request, HttpServletResponse response)
protected WebDAVMethod createMethod(HttpServletRequest request, HttpServletResponse response) {
{ // Get the type of the current request
// Get the type of the current request
String strHttpMethod = request.getMethod();
String strHttpMethod = request.getMethod();
if (logger.isDebugEnabled())
if (logger.isDebugEnabled()) logger.debug("WebDAV request " + strHttpMethod + " on path "
logger.debug("WebDAV request " + strHttpMethod + " on path " + request.getRequestURI());
+ request.getRequestURI());
Class<? extends WebDAVMethod> methodClass = m_davMethods.get(strHttpMethod);
Class<? extends WebDAVMethod> methodClass = m_davMethods.get(strHttpMethod); WebDAVMethod method = null;
WebDAVMethod method = null;
if (methodClass != null)
if (methodClass != null) {
{ try
try {
{ // Create the handler method
// Create the handler method method = methodClass.newInstance();
method = methodClass.newInstance(); method.setDetails(request, response, m_davHelper, getRootNodeRef());
method.setDetails(request, response, m_davHelper, getRootNodeRef());
// A very few WebDAV methods produce activity posts.
// A very few WebDAV methods produce activity posts. if (method instanceof ActivityPostProducer)
if (method instanceof ActivityPostProducer) {
{ ActivityPostProducer activityPostProducer = (ActivityPostProducer) method;
ActivityPostProducer activityPostProducer = (ActivityPostProducer) method; activityPostProducer.setActivityPoster(activityPoster);
activityPostProducer.setActivityPoster(activityPoster); }
} }
} catch (Exception ex)
catch (Exception ex) {
{ // Debug
// Debug
if ( logger.isDebugEnabled())
if ( logger.isDebugEnabled()) logger.debug(ex);
logger.debug(ex); }
} }
}
// Return the WebDAV method handler, or null if not supported
// Return the WebDAV method handler, or null if not supported
return method;
return method; }
}
private static NodeRef getRootNodeRef()
private static NodeRef getRootNodeRef() {
{ NodeRef rootNodeRef = singletonCache.get(KEY_WEBDAV_ROOT_NODEREF);
NodeRef rootNodeRef = singletonCache.get(KEY_WEBDAV_ROOT_NODEREF);
if (rootNodeRef == null)
if (rootNodeRef == null) {
{ rootNodeRef = tenantService.getRootNode(nodeService, searchService, namespaceService, rootPath, defaultRootNode);
rootNodeRef = tenantService.getRootNode(nodeService, searchService, namespaceService, rootPath, defaultRootNode); singletonCache.put(KEY_WEBDAV_ROOT_NODEREF, rootNodeRef);
singletonCache.put(KEY_WEBDAV_ROOT_NODEREF, rootNodeRef); }
}
return rootNodeRef;
return rootNodeRef; }
}
/**
/** * Initialize the servlet
* Initialize the servlet *
* * @param config ServletConfig
* @param config ServletConfig * @exception ServletException
* @exception ServletException */
*/ @SuppressWarnings("unchecked")
@SuppressWarnings("unchecked") public void init(ServletConfig config) throws ServletException
public void init(ServletConfig config) throws ServletException {
{ super.init(config);
super.init(config);
// Get service registry
// Get service registry WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
// If no context has been initialised, exit silently so config changes can be made
// If no context has been initialised, exit silently so config changes can be made if (context == null)
if (context == null) {
{ return;
return; }
}
// Get global configuration properties
// Get global configuration properties WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext()); WebDAVInitParameters initParams = (WebDAVInitParameters) wc.getBean(BEAN_INIT_PARAMS);
WebDAVInitParameters initParams = (WebDAVInitParameters) wc.getBean(BEAN_INIT_PARAMS);
// Render this servlet permanently unavailable if its enablement property is not set
// Render this servlet permanently unavailable if its enablement property is not set if (!initParams.getEnabled())
if (!initParams.getEnabled()) {
{ throw new UnavailableException("WebDAV not enabled.");
throw new UnavailableException("WebDAV not enabled."); }
}
// Get root paths
// Get root paths
String storeValue = initParams.getStoreName();
String storeValue = initParams.getStoreName();
rootPath = initParams.getRootPath();
rootPath = initParams.getRootPath();
// Get beans
// Get beans
serviceRegistry = (ServiceRegistry)context.getBean(ServiceRegistry.SERVICE_REGISTRY);
serviceRegistry = (ServiceRegistry)context.getBean(ServiceRegistry.SERVICE_REGISTRY);
transactionService = serviceRegistry.getTransactionService();
transactionService = serviceRegistry.getTransactionService(); tenantService = (TenantService) context.getBean("tenantService");
tenantService = (TenantService) context.getBean("tenantService");
AuthenticationService authService = (AuthenticationService) context.getBean("authenticationService");
AuthenticationService authService = (AuthenticationService) context.getBean("authenticationService");
nodeService = (NodeService) context.getBean("NodeService");
nodeService = (NodeService) context.getBean("NodeService"); searchService = (SearchService) context.getBean("SearchService");
searchService = (SearchService) context.getBean("SearchService"); namespaceService = (NamespaceService) context.getBean("NamespaceService");
namespaceService = (NamespaceService) context.getBean("NamespaceService"); ActivityService activityService = (ActivityService) context.getBean("activityService");
ActivityService activityService = (ActivityService) context.getBean("activityService"); singletonCache = (SimpleCache<String, NodeRef>)context.getBean("immutableSingletonCache");
PersonService personService = serviceRegistry.getPersonService();
singletonCache = (SimpleCache<String, NodeRef>)context.getBean("immutableSingletonCache"); // Collaborator used by WebDAV methods to create activity posts.
activityPoster = new ActivityPosterImpl("WebDAV", activityService);
// Collaborator used by WebDAV methods to create activity posts.
activityPoster = new ActivityPosterImpl("WebDAV", activityService, nodeService, personService); // Create the WebDAV helper
m_davHelper = (WebDAVHelper) context.getBean("webDAVHelper");
// Create the WebDAV helper
m_davHelper = (WebDAVHelper) context.getBean("webDAVHelper"); // Initialize the root node
initializeRootNode(storeValue, rootPath, context, nodeService, searchService, namespaceService, tenantService, transactionService);
// Initialize the root node
initializeRootNode(storeValue, rootPath, context, nodeService, searchService, namespaceService, tenantService, transactionService); // Create the WebDAV methods table
// Create the WebDAV methods table m_davMethods = new Hashtable<String, Class<? extends WebDAVMethod>>();
m_davMethods = new Hashtable<String, Class<? extends WebDAVMethod>>(); m_davMethods.put(WebDAV.METHOD_PROPFIND, PropFindMethod.class);
m_davMethods.put(WebDAV.METHOD_PROPPATCH, PropPatchMethod.class);
m_davMethods.put(WebDAV.METHOD_PROPFIND, PropFindMethod.class); m_davMethods.put(WebDAV.METHOD_COPY, CopyMethod.class);
m_davMethods.put(WebDAV.METHOD_PROPPATCH, PropPatchMethod.class); m_davMethods.put(WebDAV.METHOD_DELETE, DeleteMethod.class);
m_davMethods.put(WebDAV.METHOD_COPY, CopyMethod.class); m_davMethods.put(WebDAV.METHOD_GET, GetMethod.class);
m_davMethods.put(WebDAV.METHOD_DELETE, DeleteMethod.class); m_davMethods.put(WebDAV.METHOD_HEAD, HeadMethod.class);
m_davMethods.put(WebDAV.METHOD_GET, GetMethod.class); m_davMethods.put(WebDAV.METHOD_LOCK, LockMethod.class);
m_davMethods.put(WebDAV.METHOD_HEAD, HeadMethod.class); m_davMethods.put(WebDAV.METHOD_MKCOL, MkcolMethod.class);
m_davMethods.put(WebDAV.METHOD_LOCK, LockMethod.class); m_davMethods.put(WebDAV.METHOD_MOVE, MoveMethod.class);
m_davMethods.put(WebDAV.METHOD_MKCOL, MkcolMethod.class); m_davMethods.put(WebDAV.METHOD_OPTIONS, OptionsMethod.class);
m_davMethods.put(WebDAV.METHOD_MOVE, MoveMethod.class); m_davMethods.put(WebDAV.METHOD_POST, PostMethod.class);
m_davMethods.put(WebDAV.METHOD_OPTIONS, OptionsMethod.class); m_davMethods.put(WebDAV.METHOD_PUT, PutMethod.class);
m_davMethods.put(WebDAV.METHOD_POST, PostMethod.class); m_davMethods.put(WebDAV.METHOD_UNLOCK, UnlockMethod.class);
m_davMethods.put(WebDAV.METHOD_PUT, PutMethod.class); }
m_davMethods.put(WebDAV.METHOD_UNLOCK, UnlockMethod.class);
}
protected WebDAVHelper getDAVHelper() protected WebDAVHelper getDAVHelper()
{ {
return m_davHelper; return m_davHelper;
} }
/** /**
* @param storeValue * @param storeValue
* @param rootPath * @param rootPath
* @param context * @param context
* @param nodeService * @param nodeService
* @param searchService * @param searchService
* @param namespaceService * @param namespaceService
* @param tenantService * @param tenantService
* @param m_transactionService * @param m_transactionService
*/ */
private void initializeRootNode(String storeValue, String rootPath, WebApplicationContext context, NodeService nodeService, SearchService searchService, private void initializeRootNode(String storeValue, String rootPath, WebApplicationContext context, NodeService nodeService, SearchService searchService,
NamespaceService namespaceService, TenantService tenantService, TransactionService m_transactionService) NamespaceService namespaceService, TenantService tenantService, TransactionService m_transactionService)
{ {
// Use the system user as the authenticated context for the filesystem initialization // Use the system user as the authenticated context for the filesystem initialization
AuthenticationContext authComponent = (AuthenticationContext) context.getBean("authenticationContext"); AuthenticationContext authComponent = (AuthenticationContext) context.getBean("authenticationContext");
authComponent.setSystemUserAsCurrentUser(); authComponent.setSystemUserAsCurrentUser();
// Wrap the initialization in a transaction // Wrap the initialization in a transaction
UserTransaction tx = m_transactionService.getUserTransaction(true); UserTransaction tx = m_transactionService.getUserTransaction(true);
try try
{ {
// Start the transaction // Start the transaction
if (tx != null) if (tx != null)
tx.begin(); tx.begin();
StoreRef storeRef = new StoreRef(storeValue); StoreRef storeRef = new StoreRef(storeValue);
if (nodeService.exists(storeRef) == false) if (nodeService.exists(storeRef) == false)
{ {
throw new RuntimeException("No store for path: " + storeRef); throw new RuntimeException("No store for path: " + storeRef);
} }
NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef); NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
List<NodeRef> nodeRefs = searchService.selectNodes(storeRootNodeRef, rootPath, null, namespaceService, false); List<NodeRef> nodeRefs = searchService.selectNodes(storeRootNodeRef, rootPath, null, namespaceService, false);
if (nodeRefs.size() > 1) if (nodeRefs.size() > 1)
{ {
throw new RuntimeException("Multiple possible children for : \n" + " path: " + rootPath + "\n" + " results: " + nodeRefs); throw new RuntimeException("Multiple possible children for : \n" + " path: " + rootPath + "\n" + " results: " + nodeRefs);
} }
else if (nodeRefs.size() == 0) else if (nodeRefs.size() == 0)
{ {
throw new RuntimeException("Node is not found for : \n" + " root path: " + rootPath); throw new RuntimeException("Node is not found for : \n" + " root path: " + rootPath);
} }
defaultRootNode = nodeRefs.get(0); defaultRootNode = nodeRefs.get(0);
// Commit the transaction // Commit the transaction
if (tx != null) if (tx != null)
tx.commit(); tx.commit();
} }
catch (Exception ex) catch (Exception ex)
{ {
logger.error(ex); logger.error(ex);
} }
finally finally
{ {
// Clear the current system user // Clear the current system user
authComponent.clearCurrentSecurityContext(); authComponent.clearCurrentSecurityContext();
} }
} }
/** /**
* *
* @return root node for WebDAV * @return root node for WebDAV
*/ */
public static NodeRef getWebdavRootNode() public static NodeRef getWebdavRootNode()
{ {
return getRootNodeRef(); return getRootNodeRef();
} }
/** /**
* Bean to hold injected initialization parameters. * Bean to hold injected initialization parameters.
* *
* @author Derek Hulley * @author Derek Hulley
* @since V3.5 Team * @since V3.5 Team
*/ */
public static class WebDAVInitParameters public static class WebDAVInitParameters
{ {
private boolean enabled = false; private boolean enabled = false;
private String storeName; private String storeName;
private String rootPath; private String rootPath;
private String urlPathPrefix; private String urlPathPrefix;
public boolean getEnabled() public boolean getEnabled()
{ {
return enabled; return enabled;
} }
public void setEnabled(boolean enabled) public void setEnabled(boolean enabled)
{ {
this.enabled = enabled; this.enabled = enabled;
} }
/** /**
* @return Returns the name of the store * @return Returns the name of the store
* @throws ServletException if the store name was not set * @throws ServletException if the store name was not set
*/ */
public String getStoreName() throws ServletException public String getStoreName() throws ServletException
{ {
if (!PropertyCheck.isValidPropertyString(storeName)) if (!PropertyCheck.isValidPropertyString(storeName))
{ {
throw new ServletException("WebDAV missing 'storeName' value."); throw new ServletException("WebDAV missing 'storeName' value.");
} }
return storeName; return storeName;
} }
public void setStoreName(String storeName) public void setStoreName(String storeName)
{ {
this.storeName = storeName; this.storeName = storeName;
} }
/** /**
* @return Returns the WebDAV root path within the store * @return Returns the WebDAV root path within the store
* @throws ServletException if the root path was not set * @throws ServletException if the root path was not set
*/ */
public String getRootPath() throws ServletException public String getRootPath() throws ServletException
{ {
if (!PropertyCheck.isValidPropertyString(rootPath)) if (!PropertyCheck.isValidPropertyString(rootPath))
{ {
throw new ServletException("WebDAV missing 'rootPath' value."); throw new ServletException("WebDAV missing 'rootPath' value.");
} }
return rootPath; return rootPath;
} }
public void setRootPath(String rootPath) public void setRootPath(String rootPath)
{ {
this.rootPath = rootPath; this.rootPath = rootPath;
} }
/** /**
* Get the path prefix that generated URLs should exhibit, e.g. * Get the path prefix that generated URLs should exhibit, e.g.
@@ -517,5 +515,5 @@ public class WebDAVServlet extends HttpServlet
{ {
this.urlPathPrefix = urlPathPrefix; this.urlPathPrefix = urlPathPrefix;
} }
} }
} }