diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/tenant/tenant.lib.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/tenant/tenant.lib.ftl
new file mode 100644
index 0000000000..3b18ffb51e
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/tenant/tenant.lib.ftl
@@ -0,0 +1,7 @@
+<#macro tenantJSON tenant>
+ {
+ "tenantDomain": "${tenant.tenantDomain}",
+ "enabled": "${tenant.enabled?string}",
+ "contentRoot": "${tenant.rootContentStoreDir!""}"
+ }
+#macro>
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/tenant/tenants.delete.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/tenant/tenants.delete.desc.xml
new file mode 100644
index 0000000000..15e348deb5
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/tenant/tenants.delete.desc.xml
@@ -0,0 +1,18 @@
+
+ Delete Tenant
+ The repository must be configured such that Multi-Tenancy is enabled.
+
You must have "administrator" privileges to delete a tenant.
+
+
WARNING: This operation cannot be recovered !!!
+ ]]>
+
+ /api/tenants/{tenantDomain}
+ argument
+ admin
+ required
+ draft_public_api
+ MultiTenantAdmin
+
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/tenant/tenants.delete.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/tenant/tenants.delete.json.ftl
new file mode 100644
index 0000000000..124ee87b86
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/tenant/tenants.delete.json.ftl
@@ -0,0 +1 @@
+<#import "tenant.lib.ftl" as tenantLib/>
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/tenant/tenants.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/tenant/tenants.get.desc.xml
new file mode 100644
index 0000000000..f79d0a6207
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/tenant/tenants.get.desc.xml
@@ -0,0 +1,16 @@
+
+ Get Tenants
+ The repository must be in Multi-Tenant mode (1st tenant created).
+
You must have "administrator" privileges to get list of tenants.
+ ]]>
+
+ /api/tenants
+ argument
+ admin
+ required
+ draft_public_api
+ MultiTenantAdmin
+
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/tenant/tenants.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/tenant/tenants.get.json.ftl
new file mode 100644
index 0000000000..d753794629
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/tenant/tenants.get.json.ftl
@@ -0,0 +1,10 @@
+<#import "tenant.lib.ftl" as tenantLib/>
+{
+ "tenants" :
+ [
+ <#list tenants as tenant>
+ <@tenantLib.tenantJSON tenant=tenant/>
+ <#if tenant_has_next>,#if>
+ #list>
+ ]
+}
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/tenant/tenants.post.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/tenant/tenants.post.desc.xml
new file mode 100644
index 0000000000..91fcaf1af1
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/tenant/tenants.post.desc.xml
@@ -0,0 +1,22 @@
+
+ Create Tenant
+ The repository must be in Multi-Tenant mode (1st tenant created).
+
You must have "administrator" privileges to create a tenant.
+
+
+ - tenantDomain
- mandatory
+ - tenantAdminPassword
- mandatory
+ - tenantContentStoreRoot
- optional
+
+ ]]>
+
+ /api/tenants
+ argument
+ admin
+ required
+ draft_public_api
+ MultiTenantAdmin
+
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/tenant/tenants.post.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/tenant/tenants.post.json.ftl
new file mode 100644
index 0000000000..124ee87b86
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/tenant/tenants.post.json.ftl
@@ -0,0 +1 @@
+<#import "tenant.lib.ftl" as tenantLib/>
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/upload/upload.post.js b/config/alfresco/templates/webscripts/org/alfresco/repository/upload/upload.post.js
index d72633b475..cc99b0e219 100644
--- a/config/alfresco/templates/webscripts/org/alfresco/repository/upload/upload.post.js
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/upload/upload.post.js
@@ -345,6 +345,11 @@ function main()
// Also perform the encoding guess step in the write() method to save an additional Writer operation.
newFile.properties.content.write(content, false, true);
newFile.save();
+
+
+ // TODO (THOR-175) - review
+ // Ensure the file is versionable (autoVersion = true, autoVersionProps = false)
+ newFile.ensureVersioningEnabled(true, false);
// NOTE: Removal of first request for thumbnails to improve upload performance
// Thumbnails are still requested by Share on first render of the doclist image.
diff --git a/config/alfresco/web-scripts-application-context.xml b/config/alfresco/web-scripts-application-context.xml
index f952cc4806..8c5743e058 100644
--- a/config/alfresco/web-scripts-application-context.xml
+++ b/config/alfresco/web-scripts-application-context.xml
@@ -137,7 +137,7 @@
js
-
+
Repository
-
-
+
@@ -1950,4 +1949,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/source/java/org/alfresco/repo/web/scripts/BaseWebScriptTest.java b/source/java/org/alfresco/repo/web/scripts/BaseWebScriptTest.java
index 767ac4d218..e010607ee7 100644
--- a/source/java/org/alfresco/repo/web/scripts/BaseWebScriptTest.java
+++ b/source/java/org/alfresco/repo/web/scripts/BaseWebScriptTest.java
@@ -151,7 +151,7 @@ public abstract class BaseWebScriptTest extends TestCase
* Sets custom context for Test Web Script Server (in-process only)
* @param customContext
*/
- protected void setCustomContext(String customContext)
+ public void setCustomContext(String customContext)
{
this.customContext = customContext;
}
@@ -254,7 +254,7 @@ public abstract class BaseWebScriptTest extends TestCase
/**
* Get the server for the previously-supplied {@link #setCustomContext(String) custom context}
*/
- protected TestWebScriptServer getServer()
+ public TestWebScriptServer getServer()
{
TestWebScriptServer server;
if (customContext == null)
diff --git a/source/java/org/alfresco/repo/web/scripts/RepositoryContainer.java b/source/java/org/alfresco/repo/web/scripts/RepositoryContainer.java
index 3b45b42a73..6479067bba 100644
--- a/source/java/org/alfresco/repo/web/scripts/RepositoryContainer.java
+++ b/source/java/org/alfresco/repo/web/scripts/RepositoryContainer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2012 Alfresco Software Limited.
+ * Copyright (C) 2005-2013 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -30,20 +30,15 @@ import java.io.OutputStream;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.Status;
import javax.transaction.UserTransaction;
import org.alfresco.error.AlfrescoRuntimeException;
-import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.model.Repository;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
-import org.alfresco.repo.tenant.TenantAdminService;
-import org.alfresco.repo.tenant.TenantDeployer;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport.TxnReadState;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
@@ -57,7 +52,6 @@ import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.TempFileProvider;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.springframework.beans.factory.ObjectFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.ContextRefreshedEvent;
@@ -73,7 +67,6 @@ import org.springframework.extensions.webscripts.Description.RequiredTransaction
import org.springframework.extensions.webscripts.Description.RequiredTransactionParameters;
import org.springframework.extensions.webscripts.Description.TransactionCapability;
import org.springframework.extensions.webscripts.Match;
-import org.springframework.extensions.webscripts.Registry;
import org.springframework.extensions.webscripts.Runtime;
import org.springframework.extensions.webscripts.ServerModel;
import org.springframework.extensions.webscripts.WebScript;
@@ -90,7 +83,7 @@ import org.springframework.util.FileCopyUtils;
*
* @author davidc
*/
-public class RepositoryContainer extends AbstractRuntimeContainer implements TenantDeployer
+public class RepositoryContainer extends AbstractRuntimeContainer
{
// Logger
protected static final Log logger = LogFactory.getLog(RepositoryContainer.class);
@@ -102,28 +95,7 @@ public class RepositoryContainer extends AbstractRuntimeContainer implements Ten
private RetryingTransactionHelper fallbackTransactionHelper;
private AuthorityService authorityService;
private DescriptorService descriptorService;
- private TenantAdminService tenantAdminService;
- private ObjectFactory registryFactory;
- private SimpleCache webScriptsRegistryCache;
- private ReadWriteLock webScriptsRegistryLock = new ReentrantReadWriteLock();
- private boolean initialized;
- /**
- * @param webScriptsRegistryCache
- */
- public void setWebScriptsRegistryCache(SimpleCache webScriptsRegistryCache)
- {
- this.webScriptsRegistryCache = webScriptsRegistryCache;
- }
-
- /**
- * @param registryFactory
- */
- public void setRegistryFactory(ObjectFactory registryFactory)
- {
- this.registryFactory = registryFactory;
- }
-
/**
* @param repository
*/
@@ -172,14 +144,6 @@ public class RepositoryContainer extends AbstractRuntimeContainer implements Ten
this.authorityService = authorityService;
}
- /**
- * @param tenantAdminService
- */
- public void setTenantAdminService(TenantAdminService tenantAdminService)
- {
- this.tenantAdminService = tenantAdminService;
- }
-
/* (non-Javadoc)
* @see org.alfresco.web.scripts.Container#getDescription()
*/
@@ -546,51 +510,6 @@ public class RepositoryContainer extends AbstractRuntimeContainer implements Ten
}
}
- /* (non-Javadoc)
- * @see org.alfresco.web.scripts.AbstractRuntimeContainer#getRegistry()
- */
- @Override
- public Registry getRegistry()
- {
- String tenantDomain = tenantAdminService.getCurrentUserDomain();
- Registry registry;
- webScriptsRegistryLock.readLock().lock();
- try
- {
- registry = webScriptsRegistryCache.get(tenantDomain);
- }
- finally
- {
- webScriptsRegistryLock.readLock().unlock();
- }
- if (registry == null)
- {
- webScriptsRegistryLock.writeLock().lock();
- try
- {
- // Double check now we have write lock
- registry = webScriptsRegistryCache.get(tenantDomain);
-
- // Initialize / reinitialize the registry in this thread only
- if (registry == null)
- {
- registry = (Registry) registryFactory.getObject();
- // We only need to reset the registry if the superclass thinks its already initialized
- if (initialized)
- {
- registry.reset();
- }
- webScriptsRegistryCache.put(tenantDomain, registry);
- }
- }
- finally
- {
- webScriptsRegistryLock.writeLock().unlock();
- }
- }
- return registry;
- }
-
/* (non-Javadoc)
* @see org.alfresco.web.scripts.AbstractRuntimeContainer#onApplicationEvent(org.springframework.context.ApplicationEvent)
*/
@@ -656,68 +575,17 @@ public class RepositoryContainer extends AbstractRuntimeContainer implements Ten
{
public Object execute() throws Exception
{
- destroy();
- init();
-
+ internalReset();
return null;
}
}, true, false);
}
- /* (non-Javadoc)
- * @see org.alfresco.repo.tenant.TenantDeployer#onEnableTenant()
- */
- public void onEnableTenant()
+ private void internalReset()
{
- init();
- }
-
- /* (non-Javadoc)
- * @see org.alfresco.repo.tenant.TenantDeployer#onDisableTenant()
- */
- public void onDisableTenant()
- {
- destroy();
- }
-
- /* (non-Javadoc)
- * @see org.alfresco.repo.tenant.TenantDeployer#init()
- */
- public void init()
- {
- tenantAdminService.register(this);
-
super.reset();
-
- initialized = true;
}
- /* (non-Javadoc)
- * @see org.alfresco.repo.tenant.TenantDeployer#destroy()
- */
- public void destroy()
- {
- try
- {
- webScriptsRegistryLock.writeLock().lock();
- webScriptsRegistryCache.remove(tenantAdminService.getCurrentUserDomain());
-
- if (logger.isTraceEnabled())
- {
- Exception e = new Exception("RepositoryContainer destroy called.");
- e.fillInStackTrace();
- logger.trace("", e);
- }
- }
- finally
- {
- webScriptsRegistryLock.writeLock().unlock();
- }
-
- initialized = false;
- }
-
-
/**
* Transactional Buffered Response
*/
diff --git a/source/java/org/alfresco/repo/web/scripts/TenantRepositoryContainer.java b/source/java/org/alfresco/repo/web/scripts/TenantRepositoryContainer.java
new file mode 100644
index 0000000000..c416f1e0c0
--- /dev/null
+++ b/source/java/org/alfresco/repo/web/scripts/TenantRepositoryContainer.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2005-2010 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco 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 Alfresco. If not, see .
+ */
+package org.alfresco.repo.web.scripts;
+
+import org.alfresco.repo.cache.SimpleCache;
+import org.alfresco.repo.security.authentication.AuthenticationUtil;
+import org.alfresco.repo.tenant.TenantAdminService;
+import org.alfresco.repo.tenant.TenantDeployer;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.ObjectFactory;
+import org.springframework.extensions.webscripts.Description.RequiredAuthentication;
+import org.springframework.extensions.webscripts.Registry;
+
+
+/**
+ * Tenant-aware Repository (server-tier) container for Web Scripts
+ *
+ * @author davidc
+ */
+public class TenantRepositoryContainer extends RepositoryContainer implements TenantDeployer
+{
+ // Logger
+ protected static final Log logger = LogFactory.getLog(TenantRepositoryContainer.class);
+
+ /** Component Dependencies */
+ private TenantAdminService tenantAdminService;
+ private ObjectFactory registryFactory;
+ private SimpleCache webScriptsRegistryCache;
+ private boolean initialized;
+
+ /**
+ * @param webScriptsRegistryCache
+ */
+ public void setWebScriptsRegistryCache(SimpleCache webScriptsRegistryCache)
+ {
+ this.webScriptsRegistryCache = webScriptsRegistryCache;
+ }
+
+ /**
+ * @param registryFactory
+ */
+ public void setRegistryFactory(ObjectFactory registryFactory)
+ {
+ this.registryFactory = registryFactory;
+ }
+
+ /**
+ * @param tenantAdminService
+ */
+ public void setTenantAdminService(TenantAdminService tenantAdminService)
+ {
+ this.tenantAdminService = tenantAdminService;
+ }
+
+ /* (non-Javadoc)
+ * @see org.alfresco.web.scripts.AbstractRuntimeContainer#getRegistry()
+ */
+ @Override
+ public Registry getRegistry()
+ {
+ String tenantDomain = tenantAdminService.getCurrentUserDomain();
+ Registry registry = webScriptsRegistryCache.get(tenantDomain);
+ if (registry == null)
+ {
+ registry = (Registry)registryFactory.getObject();
+ // We only need to reset the registry if the superclass thinks its already initialized
+ if (initialized)
+ {
+ registry.reset();
+ }
+ webScriptsRegistryCache.put(tenantDomain, registry);
+ }
+ return registry;
+ }
+
+ /* (non-Javadoc)
+ * @see org.alfresco.repo.tenant.TenantDeployer#onEnableTenant()
+ */
+ public void onEnableTenant()
+ {
+ init();
+ }
+
+ /* (non-Javadoc)
+ * @see org.alfresco.repo.tenant.TenantDeployer#onDisableTenant()
+ */
+ public void onDisableTenant()
+ {
+ destroy();
+ }
+
+ /* (non-Javadoc)
+ * @see org.alfresco.repo.tenant.TenantDeployer#init()
+ */
+ public void init()
+ {
+ tenantAdminService.register(this);
+
+ super.reset();
+
+ initialized = true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.alfresco.repo.tenant.TenantDeployer#destroy()
+ */
+ public void destroy()
+ {
+ webScriptsRegistryCache.remove(tenantAdminService.getCurrentUserDomain());
+
+ initialized = false;
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/web/scripts/TenantWebScriptServlet.java b/source/java/org/alfresco/repo/web/scripts/TenantWebScriptServlet.java
new file mode 100644
index 0000000000..5dce253113
--- /dev/null
+++ b/source/java/org/alfresco/repo/web/scripts/TenantWebScriptServlet.java
@@ -0,0 +1,74 @@
+/**
+ * Copyright (C) 2005-2009 Alfresco Software Limited.
+ *
+ * This file is part of the Spring Surf Extension project.
+ *
+ * Licensed 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.alfresco.repo.web.scripts;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.extensions.surf.util.I18NUtil;
+import org.springframework.extensions.webscripts.servlet.WebScriptServlet;
+import org.springframework.extensions.webscripts.servlet.WebScriptServletRuntime;
+
+
+/**
+ * Entry point for web scripts which can accept a tenant id in their servlet path
+ *
+ * @author davidc
+ */
+public class TenantWebScriptServlet extends WebScriptServlet
+{
+ public static final String DEFAULT_TENANT = "-default-";
+
+ private static final long serialVersionUID = 2954663814419046489L;
+
+ // Logger
+ private static final Log logger = LogFactory.getLog(TenantWebScriptServlet.class);
+
+ /* (non-Javadoc)
+ * @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
+ protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Processing tenant request (" + req.getMethod() + ") " + req.getRequestURL() + (req.getQueryString() != null ? "?" + req.getQueryString() : ""));
+
+ if (req.getCharacterEncoding() == null)
+ {
+ req.setCharacterEncoding("UTF-8");
+ }
+
+ setLanguageFromRequestHeader(req);
+
+ try
+ {
+ WebScriptServletRuntime runtime = new TenantWebScriptServletRuntime(container, authenticatorFactory, req, res, serverProperties);
+ runtime.executeScript();
+ }
+ finally
+ {
+ // clear threadlocal
+ I18NUtil.setLocale(null);
+ }
+ }
+}
diff --git a/source/java/org/alfresco/repo/web/scripts/TenantWebScriptServletRequest.java b/source/java/org/alfresco/repo/web/scripts/TenantWebScriptServletRequest.java
new file mode 100644
index 0000000000..16c7ec9082
--- /dev/null
+++ b/source/java/org/alfresco/repo/web/scripts/TenantWebScriptServletRequest.java
@@ -0,0 +1,104 @@
+/**
+ * Copyright (C) 2005-2009 Alfresco Software Limited.
+ *
+ * This file is part of the Spring Surf Extension project.
+ *
+ * Licensed 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.alfresco.repo.web.scripts;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.extensions.config.ServerProperties;
+import org.springframework.extensions.surf.util.URLDecoder;
+import org.springframework.extensions.webscripts.Match;
+import org.springframework.extensions.webscripts.Runtime;
+import org.springframework.extensions.webscripts.servlet.WebScriptServletRequest;
+
+
+/**
+ * Web Script Request which can handle a tenant id in their servlet path
+ *
+ * @author davidc
+ */
+public class TenantWebScriptServletRequest extends WebScriptServletRequest
+{
+ private String tenant;
+ private String pathInfo;
+
+ /**
+ * Construction
+ *
+ * @param container request generator
+ * @param req
+ * @param serviceMatch
+ */
+ public TenantWebScriptServletRequest(Runtime container, HttpServletRequest req, Match serviceMatch, ServerProperties serverProperties)
+ {
+ super(container, req, serviceMatch, serverProperties);
+
+ String realPathInfo = getRealPathInfo();
+
+ // remove tenant
+ int idx = realPathInfo.indexOf('/', 1);
+ tenant = realPathInfo.substring(1, idx == -1 ? realPathInfo.length() : idx);
+ pathInfo = realPathInfo.substring(tenant.length() + 1);
+ }
+
+ /* (non-Javadoc)
+ * @see org.alfresco.web.scripts.WebScriptRequest#getServiceContextPath()
+ */
+ public String getServiceContextPath()
+ {
+ return getHttpServletRequest().getContextPath() + getHttpServletRequest().getServletPath() + "/" + tenant;
+ }
+
+ /* (non-Javadoc)
+ * @see org.alfresco.web.scripts.WebScriptRequest#getPathInfo()
+ */
+ public String getPathInfo()
+ {
+ return pathInfo;
+ }
+
+ public String getTenant()
+ {
+ return tenant;
+ }
+
+ /* (non-Javadoc)
+ * @see org.alfresco.web.scripts.WebScriptRequest#getPathInfo()
+ */
+ private String getRealPathInfo()
+ {
+ // NOTE: Don't use req.getPathInfo() - it truncates the path at first semi-colon in Tomcat
+ final String requestURI = getHttpServletRequest().getRequestURI();
+ final String serviceContextPath = getHttpServletRequest().getContextPath() + getHttpServletRequest().getServletPath();
+ String pathInfo;
+
+ if (serviceContextPath.length() > requestURI.length())
+ {
+ // NOTE: assume a redirect has taken place e.g. tomcat welcome-page
+ // NOTE: this is unlikely, and we'll take the hit if the path contains a semi-colon
+ pathInfo = getHttpServletRequest().getPathInfo();
+ }
+ else
+ {
+ pathInfo = URLDecoder.decode(requestURI.substring(serviceContextPath.length()));
+ }
+
+ return pathInfo;
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/web/scripts/TenantWebScriptServletRuntime.java b/source/java/org/alfresco/repo/web/scripts/TenantWebScriptServletRuntime.java
new file mode 100644
index 0000000000..f5be0ecf00
--- /dev/null
+++ b/source/java/org/alfresco/repo/web/scripts/TenantWebScriptServletRuntime.java
@@ -0,0 +1,100 @@
+/**
+ * Copyright (C) 2005-2009 Alfresco Software Limited.
+ *
+ * This file is part of the Spring Surf Extension project.
+ *
+ * Licensed 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.alfresco.repo.web.scripts;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.extensions.config.ServerProperties;
+import org.springframework.extensions.surf.util.URLDecoder;
+import org.springframework.extensions.webscripts.Match;
+import org.springframework.extensions.webscripts.RuntimeContainer;
+import org.springframework.extensions.webscripts.WebScriptException;
+import org.springframework.extensions.webscripts.WebScriptRequest;
+import org.springframework.extensions.webscripts.servlet.ServletAuthenticatorFactory;
+import org.springframework.extensions.webscripts.servlet.WebScriptServletRuntime;
+
+
+/**
+ * HTTP Servlet Web Script Runtime which can handle a tenant id in a web script path
+ *
+ * @author davidc
+ */
+public class TenantWebScriptServletRuntime extends WebScriptServletRuntime
+{
+ public TenantWebScriptServletRuntime(RuntimeContainer container, ServletAuthenticatorFactory authFactory, HttpServletRequest req, HttpServletResponse res, ServerProperties serverProperties)
+ {
+ super(container, authFactory, req, res, serverProperties);
+ }
+
+ /* (non-Javadoc)
+ * @see org.alfresco.web.scripts.WebScriptRuntime#getScriptUrl()
+ */
+ @Override
+ protected String getScriptUrl()
+ {
+ // NOTE: Don't use req.getPathInfo() - it truncates the path at first semi-colon in Tomcat
+ final String requestURI = req.getRequestURI();
+ final String serviceContextPath = req.getContextPath() + req.getServletPath();
+ String pathInfo;
+
+ if (serviceContextPath.length() > requestURI.length())
+ {
+ // NOTE: assume a redirect has taken place e.g. tomcat welcome-page
+ // NOTE: this is unlikely, and we'll take the hit if the path contains a semi-colon
+ pathInfo = req.getPathInfo();
+ }
+ else
+ {
+ pathInfo = URLDecoder.decode(requestURI.substring(serviceContextPath.length()));
+ }
+
+ // ensure tenant is specified at beginning of path
+ // NOTE: must contain at least root / and single character for tenant name
+ if (pathInfo.length() < 2)
+ {
+ throw new WebScriptException("Missing tenant name in path: " + pathInfo);
+ }
+ // remove tenant
+ int idx = pathInfo.indexOf('/', 1);
+ pathInfo = pathInfo.substring(idx == -1 ? pathInfo.length() : idx);
+ return pathInfo;
+ }
+
+ /* (non-Javadoc)
+ * @see org.alfresco.web.scripts.WebScriptRuntime#createRequest(org.alfresco.web.scripts.WebScriptMatch)
+ */
+ @Override
+ protected WebScriptRequest createRequest(Match match)
+ {
+ // TODO: construct org.springframework.extensions.webscripts.servlet.WebScriptServletResponse when
+ // org.alfresco.web.scripts.WebScriptServletResponse (deprecated) is removed
+ servletReq = new TenantWebScriptServletRequest(this, req, match, serverProperties);
+ return servletReq;
+ }
+
+ /* (non-Javadoc)
+ * @see org.alfresco.web.scripts.WebScriptContainer#getName()
+ */
+ public String getName()
+ {
+ return "TenantServletRuntime";
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/web/scripts/invite/InviteByTicket.java b/source/java/org/alfresco/repo/web/scripts/invite/InviteByTicket.java
index b0c91d179f..5d73fb1c30 100644
--- a/source/java/org/alfresco/repo/web/scripts/invite/InviteByTicket.java
+++ b/source/java/org/alfresco/repo/web/scripts/invite/InviteByTicket.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2011 Alfresco Software Limited.
+ * Copyright (C) 2005-2013 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -25,6 +25,8 @@ import org.alfresco.repo.invitation.site.InviteInfo;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.template.TemplateNode;
import org.alfresco.repo.tenant.TenantService;
+import org.alfresco.repo.tenant.TenantUtil;
+import org.alfresco.repo.tenant.TenantUtil.TenantRunAsWork;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.invitation.Invitation;
import org.alfresco.service.cmr.invitation.InvitationExceptionNotFound;
@@ -102,14 +104,14 @@ public class InviteByTicket extends DeclarativeWebScript
// run as system user
String mtAwareSystemUser = tenantService.getDomainUser(AuthenticationUtil.getSystemUserName(), tenantDomain);
-
- Map ret = AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork