mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged V2.9 to HEAD
10531: Merged V2.2 to V2.9 9928: Optimise & consolidate get web project user role (ETWOTWO-568) 9962: Reverted rev 9902 of RuleServiceImpl 9964: Fixed transaction read-only declaration 9979: ETWOTWO-572: Allow OpenOffice to be called remotely 9987: Second attempt at fixing ETWOTWO-438: versionable aspect and invite user 10096: Fix for ETWOTWO-507 FSR Service Port 10224: Fix for ETWOTWO-507 (inconsistent results with add and delete together) 10225: Adding logging and making FSR work with absolute directories (ETWOTWO-70 and ETWOONE-81) 10254: ALFCOM-242, ALFCOM-230, ETWOTWO-437 10283: Fixed deployment installer builder to use IJ v1.2.7 10359: Add Display Group for deployment servers to JSF client (ETWOTWO-474) 10536: MT - simple setup/system test 10553: Hid domain objects completely within the UsageDeltaDAO git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@10613 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8' ?>
|
||||||
|
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
|
||||||
|
|
||||||
|
<beans>
|
||||||
|
|
||||||
|
<bean id="openOfficeConnection" class="net.sf.jooreports.openoffice.connection.SocketOpenOfficeConnection">
|
||||||
|
<constructor-arg type="java.lang.String" value="156.124.13.102"/>
|
||||||
|
<constructor-arg type="int" value="8100"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="transformer.OpenOffice" class="org.alfresco.repo.content.transform.RemoteOpenOfficeContentTransformer" parent="baseContentTransformer" >
|
||||||
|
<property name="connection">
|
||||||
|
<ref bean="openOfficeConnection" />
|
||||||
|
</property>
|
@@ -322,10 +322,13 @@
|
|||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="usageDeltaDao" class="org.alfresco.repo.usage.hibernate.HibernateUsageDeltaDAO">
|
<bean id="usageDeltaDao" class="org.alfresco.repo.domain.hibernate.HibernateUsageDeltaDAO">
|
||||||
<property name="sessionFactory">
|
<property name="sessionFactory">
|
||||||
<ref bean="sessionFactory"/>
|
<ref bean="sessionFactory"/>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="nodeDaoService">
|
||||||
|
<ref bean="nodeDaoServiceImpl" />
|
||||||
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="nodeDaoServiceImpl" class="org.alfresco.repo.node.db.hibernate.HibernateNodeDaoServiceImpl">
|
<bean id="nodeDaoServiceImpl" class="org.alfresco.repo.node.db.hibernate.HibernateNodeDaoServiceImpl">
|
||||||
|
@@ -302,6 +302,10 @@
|
|||||||
<title>Display Name</title>
|
<title>Display Name</title>
|
||||||
<type>d:text</type>
|
<type>d:text</type>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="wca:deployservergroup">
|
||||||
|
<title>Display Name</title>
|
||||||
|
<type>d:text</type>
|
||||||
|
</property>
|
||||||
<property name="wca:deployserverusername">
|
<property name="wca:deployserverusername">
|
||||||
<title>Username</title>
|
<title>Username</title>
|
||||||
<type>d:text</type>
|
<type>d:text</type>
|
||||||
|
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
<bean id="usageService" class="org.alfresco.repo.usage.UsageServiceImpl">
|
<bean id="usageService" class="org.alfresco.repo.usage.UsageServiceImpl">
|
||||||
<property name="usageDeltaDao" ref="usageDeltaDao"/>
|
<property name="usageDeltaDao" ref="usageDeltaDao"/>
|
||||||
<property name="nodeDaoService" ref="nodeDaoService"/>
|
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="contentUsageImpl" class="org.alfresco.repo.usage.ContentUsageImpl" init-method="init">
|
<bean id="contentUsageImpl" class="org.alfresco.repo.usage.ContentUsageImpl" init-method="init">
|
||||||
|
@@ -83,6 +83,7 @@ public interface WCMAppModel
|
|||||||
static final QName PROP_DEPLOYSERVERNAME = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deployservername");
|
static final QName PROP_DEPLOYSERVERNAME = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deployservername");
|
||||||
static final QName PROP_DEPLOYSERVERUSERNAME = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deployserverusername");
|
static final QName PROP_DEPLOYSERVERUSERNAME = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deployserverusername");
|
||||||
static final QName PROP_DEPLOYSERVERPASSWORD = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deployserverpassword");
|
static final QName PROP_DEPLOYSERVERPASSWORD = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deployserverpassword");
|
||||||
|
static final QName PROP_DEPLOYSERVERGROUP = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deployservergroup");
|
||||||
static final QName PROP_DEPLOYSERVERURL = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deployserverurl");
|
static final QName PROP_DEPLOYSERVERURL = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deployserverurl");
|
||||||
static final QName PROP_DEPLOYSERVERTARGET = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deployservertarget");
|
static final QName PROP_DEPLOYSERVERTARGET = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deployservertarget");
|
||||||
static final QName PROP_DEPLOYSOURCEPATH = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deploysourcepath");
|
static final QName PROP_DEPLOYSOURCEPATH = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deploysourcepath");
|
||||||
|
@@ -41,7 +41,6 @@ import org.alfresco.service.cmr.avm.AVMExistsException;
|
|||||||
import org.alfresco.service.cmr.avm.AVMNotFoundException;
|
import org.alfresco.service.cmr.avm.AVMNotFoundException;
|
||||||
import org.alfresco.service.cmr.avm.locking.AVMLock;
|
import org.alfresco.service.cmr.avm.locking.AVMLock;
|
||||||
import org.alfresco.service.cmr.avm.locking.AVMLockingService;
|
import org.alfresco.service.cmr.avm.locking.AVMLockingService;
|
||||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
|
||||||
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;
|
||||||
@@ -50,7 +49,7 @@ import org.alfresco.service.cmr.search.SearchService;
|
|||||||
import org.alfresco.service.cmr.security.AuthorityService;
|
import org.alfresco.service.cmr.security.AuthorityService;
|
||||||
import org.alfresco.service.cmr.security.AuthorityType;
|
import org.alfresco.service.cmr.security.AuthorityType;
|
||||||
import org.alfresco.service.cmr.security.PersonService;
|
import org.alfresco.service.cmr.security.PersonService;
|
||||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.util.MD5;
|
import org.alfresco.util.MD5;
|
||||||
import org.alfresco.util.Pair;
|
import org.alfresco.util.Pair;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
@@ -642,19 +641,39 @@ public class AVMLockingServiceImpl implements AVMLockingService
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check for content manager role - we allow access to all managers within the same store
|
// check for content manager role - we allow access to all managers within the same store
|
||||||
List<ChildAssociationRef> children = fNodeService.getChildAssocs(
|
// TODO as part of WCM refactor, consolidate with WebProject.getWebProjectUserRole
|
||||||
webProjectRef, WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL);
|
StringBuilder query = new StringBuilder(128);
|
||||||
for (ChildAssociationRef child : children)
|
query.append("+PARENT:\"").append(webProjectRef).append("\" ");
|
||||||
|
query.append("+TYPE:\"").append(WCMAppModel.TYPE_WEBUSER).append("\" ");
|
||||||
|
query.append("+@").append(NamespaceService.WCMAPP_MODEL_PREFIX).append("\\:username:\"");
|
||||||
|
query.append(user);
|
||||||
|
query.append("\"");
|
||||||
|
ResultSet resultSet = fSearchService.query(
|
||||||
|
new StoreRef(this.webProjectStore),
|
||||||
|
SearchService.LANGUAGE_LUCENE,
|
||||||
|
query.toString());
|
||||||
|
List<NodeRef> nodes = resultSet.getNodeRefs();
|
||||||
|
|
||||||
|
if (nodes.size() == 1)
|
||||||
{
|
{
|
||||||
NodeRef childRef = child.getChildRef();
|
String userrole = (String)fNodeService.getProperty(nodes.get(0), WCMAppModel.PROP_WEBUSERROLE);
|
||||||
if (fNodeService.getProperty(childRef, WCMAppModel.PROP_WEBUSERNAME).equals(user) &&
|
if (ROLE_CONTENT_MANAGER.equals(userrole))
|
||||||
fNodeService.getProperty(childRef, WCMAppModel.PROP_WEBUSERROLE).equals(ROLE_CONTENT_MANAGER))
|
|
||||||
{
|
{
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug(" GRANTED: Store match and user is ContentManager role in webproject.");
|
{
|
||||||
return true;
|
logger.debug("GRANTED: Store match and user is ContentManager role in webproject.");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (nodes.size() == 0)
|
||||||
|
{
|
||||||
|
logger.warn("hasAccess: user role not found for " + user);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.warn("hasAccess: more than one user role found for " + user);
|
||||||
|
}
|
||||||
|
|
||||||
// finally check the owners of the lock against the specified authority
|
// finally check the owners of the lock against the specified authority
|
||||||
List<String> owners = lock.getOwners();
|
List<String> owners = lock.getOwners();
|
||||||
|
@@ -0,0 +1,240 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
* As a special exception to the terms and conditions of version 2.0 of
|
||||||
|
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||||
|
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||||
|
* FLOSS exception. You should have recieved a copy of the text describing
|
||||||
|
* the FLOSS exception, and it is also available here:
|
||||||
|
* http://www.alfresco.com/legal/licensing"
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.content.transform;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import net.sf.jooreports.converter.DocumentFamily;
|
||||||
|
import net.sf.jooreports.converter.DocumentFormat;
|
||||||
|
import net.sf.jooreports.converter.DocumentFormatRegistry;
|
||||||
|
import net.sf.jooreports.converter.XmlDocumentFormatRegistry;
|
||||||
|
import net.sf.jooreports.openoffice.connection.OpenOfficeConnection;
|
||||||
|
import net.sf.jooreports.openoffice.connection.OpenOfficeException;
|
||||||
|
import net.sf.jooreports.openoffice.converter.StreamOpenOfficeDocumentConverter;
|
||||||
|
|
||||||
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
|
import org.alfresco.repo.content.MimetypeMap;
|
||||||
|
import org.alfresco.repo.content.transform.AbstractContentTransformer;
|
||||||
|
import org.alfresco.service.cmr.repository.ContentIOException;
|
||||||
|
import org.alfresco.service.cmr.repository.ContentReader;
|
||||||
|
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||||
|
import org.alfresco.service.cmr.repository.MimetypeService;
|
||||||
|
import org.alfresco.util.PropertyCheck;
|
||||||
|
import org.alfresco.util.TempFileProvider;
|
||||||
|
import org.springframework.core.io.DefaultResourceLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes use of the {@link http://sourceforge.net/projects/joott/JOOConverter} library to
|
||||||
|
* perform OpenOffice-drive conversions.
|
||||||
|
*
|
||||||
|
* @author Derek Hulley
|
||||||
|
* @author Juan David Zuluaga Arboleda
|
||||||
|
* @author Jared Ottley
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class RemoteOpenOfficeContentTransformer extends AbstractContentTransformer
|
||||||
|
{
|
||||||
|
private OpenOfficeConnection connection;
|
||||||
|
private StreamOpenOfficeDocumentConverter converter;
|
||||||
|
private String documentFormatsConfiguration;
|
||||||
|
private DocumentFormatRegistry formatRegistry;
|
||||||
|
|
||||||
|
public RemoteOpenOfficeContentTransformer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConnection(OpenOfficeConnection connection)
|
||||||
|
{
|
||||||
|
this.connection = connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a non-default location from which to load the document format mappings.
|
||||||
|
*
|
||||||
|
* @param path a resource location supporting the <b>file:</b> or <b>classpath:</b> prefixes
|
||||||
|
*/
|
||||||
|
public void setDocumentFormatsConfiguration(String path)
|
||||||
|
{
|
||||||
|
this.documentFormatsConfiguration = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isConnected()
|
||||||
|
{
|
||||||
|
return connection.isConnected();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void register()
|
||||||
|
{
|
||||||
|
PropertyCheck.mandatory("OpenOfficeContentTransformer", "connection", connection);
|
||||||
|
|
||||||
|
// load the document conversion configuration
|
||||||
|
if (documentFormatsConfiguration != null)
|
||||||
|
{
|
||||||
|
DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
InputStream is = resourceLoader.getResource(documentFormatsConfiguration).getInputStream();
|
||||||
|
formatRegistry = new XmlDocumentFormatRegistry(is);
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException(
|
||||||
|
"Unable to load document formats configuration file: " + documentFormatsConfiguration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
formatRegistry = new XmlDocumentFormatRegistry();
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up the converter
|
||||||
|
converter = new StreamOpenOfficeDocumentConverter(connection);
|
||||||
|
|
||||||
|
// Register
|
||||||
|
super.register();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see DocumentFormatRegistry
|
||||||
|
*/
|
||||||
|
public double getReliability(String sourceMimetype, String targetMimetype)
|
||||||
|
{
|
||||||
|
if (!isConnected())
|
||||||
|
{
|
||||||
|
// The connection management is must take care of this
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// there are some conversions that fail, despite the converter believing them possible
|
||||||
|
if (targetMimetype.equals(MimetypeMap.MIMETYPE_XHTML))
|
||||||
|
{
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
else if (targetMimetype.equals(MimetypeMap.MIMETYPE_WORDPERFECT))
|
||||||
|
{
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MimetypeService mimetypeService = getMimetypeService();
|
||||||
|
String sourceExtension = mimetypeService.getExtension(sourceMimetype);
|
||||||
|
String targetExtension = mimetypeService.getExtension(targetMimetype);
|
||||||
|
// query the registry for the source format
|
||||||
|
DocumentFormat sourceFormat = formatRegistry.getFormatByFileExtension(sourceExtension);
|
||||||
|
if (sourceFormat == null)
|
||||||
|
{
|
||||||
|
// no document format
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
// query the registry for the target format
|
||||||
|
DocumentFormat targetFormat = formatRegistry.getFormatByFileExtension(targetExtension);
|
||||||
|
if (targetFormat == null)
|
||||||
|
{
|
||||||
|
// no document format
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the family of the target document
|
||||||
|
DocumentFamily sourceFamily = sourceFormat.getFamily();
|
||||||
|
// does the format support the conversion
|
||||||
|
if (!targetFormat.isExportableFrom(sourceFamily))
|
||||||
|
{
|
||||||
|
// unable to export from source family of documents to the target format
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void transformInternal(
|
||||||
|
ContentReader reader,
|
||||||
|
ContentWriter writer,
|
||||||
|
Map<String, Object> options) throws Exception
|
||||||
|
{
|
||||||
|
String sourceMimetype = getMimetype(reader);
|
||||||
|
String targetMimetype = getMimetype(writer);
|
||||||
|
|
||||||
|
MimetypeService mimetypeService = getMimetypeService();
|
||||||
|
String sourceExtension = mimetypeService.getExtension(sourceMimetype);
|
||||||
|
String targetExtension = mimetypeService.getExtension(targetMimetype);
|
||||||
|
// query the registry for the source format
|
||||||
|
DocumentFormat sourceFormat = formatRegistry.getFormatByFileExtension(sourceExtension);
|
||||||
|
if (sourceFormat == null)
|
||||||
|
{
|
||||||
|
// source format is not recognised
|
||||||
|
throw new ContentIOException("No OpenOffice document format for source extension: " + sourceExtension);
|
||||||
|
}
|
||||||
|
// query the registry for the target format
|
||||||
|
DocumentFormat targetFormat = formatRegistry.getFormatByFileExtension(targetExtension);
|
||||||
|
if (targetFormat == null)
|
||||||
|
{
|
||||||
|
// target format is not recognised
|
||||||
|
throw new ContentIOException("No OpenOffice document format for target extension: " + targetExtension);
|
||||||
|
}
|
||||||
|
// get the family of the target document
|
||||||
|
DocumentFamily sourceFamily = sourceFormat.getFamily();
|
||||||
|
// does the format support the conversion
|
||||||
|
if (!targetFormat.isExportableFrom(sourceFamily))
|
||||||
|
{
|
||||||
|
throw new ContentIOException(
|
||||||
|
"OpenOffice conversion not supported: \n" +
|
||||||
|
" reader: " + reader + "\n" +
|
||||||
|
" writer: " + writer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create temporary files to convert from and to
|
||||||
|
File tempFromFile = TempFileProvider.createTempFile(
|
||||||
|
"OpenOfficeContentTransformer-source-",
|
||||||
|
"." + sourceExtension);
|
||||||
|
File tempToFile = TempFileProvider.createTempFile(
|
||||||
|
"OpenOfficeContentTransformer-target-",
|
||||||
|
"." + targetExtension);
|
||||||
|
// download the content from the source reader
|
||||||
|
reader.getContent(tempFromFile);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
converter.convert(tempFromFile, sourceFormat, tempToFile, targetFormat);
|
||||||
|
// conversion success
|
||||||
|
}
|
||||||
|
catch (OpenOfficeException e)
|
||||||
|
{
|
||||||
|
throw new ContentIOException("OpenOffice server conversion failed: \n" +
|
||||||
|
" reader: " + reader + "\n" +
|
||||||
|
" writer: " + writer + "\n" +
|
||||||
|
" from file: " + tempFromFile + "\n" +
|
||||||
|
" to file: " + tempToFile,
|
||||||
|
e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// upload the temp output to the writer given us
|
||||||
|
writer.putContent(tempToFile);
|
||||||
|
}
|
||||||
|
}
|
@@ -877,7 +877,7 @@ public class DeploymentServiceImpl implements DeploymentService
|
|||||||
}
|
}
|
||||||
report.add(event);
|
report.add(event);
|
||||||
String storeName = srcPath.substring(0, srcPath.indexOf(':'));
|
String storeName = srcPath.substring(0, srcPath.indexOf(':'));
|
||||||
System.out.println(storeName);
|
|
||||||
if (version < 0)
|
if (version < 0)
|
||||||
{
|
{
|
||||||
version = fAVMService.createSnapshot(storeName, null, null).get(storeName);
|
version = fAVMService.createSnapshot(storeName, null, null).get(storeName);
|
||||||
@@ -908,15 +908,28 @@ public class DeploymentServiceImpl implements DeploymentService
|
|||||||
callback.eventOccurred(event);
|
callback.eventOccurred(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (service != null)
|
if (service != null && ticket != null)
|
||||||
{
|
{
|
||||||
|
// TODO MER - Consider what happens if abort throws an exception itself, then we loose e?
|
||||||
service.abort(ticket);
|
service.abort(ticket);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new AVMException("Deployment to: " + target + " failed.", e);
|
throw new AVMException("Deployment to: " + target + " failed.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* deployDirectoryPush
|
||||||
|
* Compares the source and destination listings and updates report with update events required to make
|
||||||
|
* dest similar to src.
|
||||||
|
* @param service
|
||||||
|
* @param ticket
|
||||||
|
* @param report
|
||||||
|
* @param callbacks
|
||||||
|
* @param version
|
||||||
|
* @param srcPath
|
||||||
|
* @param dstPath
|
||||||
|
* @param matcher
|
||||||
|
*/
|
||||||
private void deployDirectoryPush(DeploymentReceiverService service, String ticket,
|
private void deployDirectoryPush(DeploymentReceiverService service, String ticket,
|
||||||
DeploymentReport report, List<DeploymentCallback> callbacks,
|
DeploymentReport report, List<DeploymentCallback> callbacks,
|
||||||
int version,
|
int version,
|
||||||
@@ -926,9 +939,12 @@ public class DeploymentServiceImpl implements DeploymentService
|
|||||||
List<FileDescriptor> dstListing = service.getListing(ticket, dstPath);
|
List<FileDescriptor> dstListing = service.getListing(ticket, dstPath);
|
||||||
Iterator<AVMNodeDescriptor> srcIter = srcListing.values().iterator();
|
Iterator<AVMNodeDescriptor> srcIter = srcListing.values().iterator();
|
||||||
Iterator<FileDescriptor> dstIter = dstListing.iterator();
|
Iterator<FileDescriptor> dstIter = dstListing.iterator();
|
||||||
|
// Here with two sorted directory listings
|
||||||
AVMNodeDescriptor src = null;
|
AVMNodeDescriptor src = null;
|
||||||
FileDescriptor dst = null;
|
FileDescriptor dst = null;
|
||||||
while (srcIter.hasNext() || dstIter.hasNext())
|
|
||||||
|
// Step through both directory listings
|
||||||
|
while (srcIter.hasNext() || dstIter.hasNext() || src != null || dst != null)
|
||||||
{
|
{
|
||||||
if (src == null)
|
if (src == null)
|
||||||
{
|
{
|
||||||
@@ -944,7 +960,11 @@ public class DeploymentServiceImpl implements DeploymentService
|
|||||||
dst = dstIter.next();
|
dst = dstIter.next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// This means no entry on src so delete.
|
if (fgLogger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
fgLogger.debug("comparing src:" + src + " dst:"+ dst);
|
||||||
|
}
|
||||||
|
// This means no entry on src so delete what is on dst.
|
||||||
if (src == null)
|
if (src == null)
|
||||||
{
|
{
|
||||||
String newDstPath = extendPath(dstPath, dst.getName());
|
String newDstPath = extendPath(dstPath, dst.getName());
|
||||||
@@ -980,9 +1000,12 @@ public class DeploymentServiceImpl implements DeploymentService
|
|||||||
src = null;
|
src = null;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Here with src and dst containing something
|
||||||
int diff = src.getName().compareToIgnoreCase(dst.getName());
|
int diff = src.getName().compareToIgnoreCase(dst.getName());
|
||||||
if (diff < 0)
|
if (diff < 0)
|
||||||
{
|
{
|
||||||
|
// src is less than dst - must be new content in src
|
||||||
if (!excluded(matcher, src.getPath(), null))
|
if (!excluded(matcher, src.getPath(), null))
|
||||||
{
|
{
|
||||||
copy(service, ticket, report, callbacks, version, src, dstPath, matcher);
|
copy(service, ticket, report, callbacks, version, src, dstPath, matcher);
|
||||||
@@ -992,6 +1015,7 @@ public class DeploymentServiceImpl implements DeploymentService
|
|||||||
}
|
}
|
||||||
if (diff == 0)
|
if (diff == 0)
|
||||||
{
|
{
|
||||||
|
// src and dst have same file name
|
||||||
if (src.getGuid().equals(dst.getGUID()))
|
if (src.getGuid().equals(dst.getGUID()))
|
||||||
{
|
{
|
||||||
src = null;
|
src = null;
|
||||||
|
@@ -22,7 +22,7 @@
|
|||||||
* the FLOSS exception, and it is also available here:
|
* the FLOSS exception, and it is also available here:
|
||||||
* http://www.alfresco.com/legal/licensing"
|
* http://www.alfresco.com/legal/licensing"
|
||||||
*/
|
*/
|
||||||
package org.alfresco.repo.usage;
|
package org.alfresco.repo.domain;
|
||||||
|
|
||||||
import org.alfresco.repo.domain.Node;
|
import org.alfresco.repo.domain.Node;
|
||||||
|
|
@@ -22,17 +22,21 @@
|
|||||||
* the FLOSS exception, and it is also available here:
|
* the FLOSS exception, and it is also available here:
|
||||||
* http://www.alfresco.com/legal/licensing"
|
* http://www.alfresco.com/legal/licensing"
|
||||||
*/
|
*/
|
||||||
package org.alfresco.repo.usage.hibernate;
|
package org.alfresco.repo.domain.hibernate;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.alfresco.repo.domain.Node;
|
import org.alfresco.repo.domain.Node;
|
||||||
|
import org.alfresco.repo.domain.UsageDelta;
|
||||||
|
import org.alfresco.repo.node.db.NodeDaoService;
|
||||||
import org.alfresco.repo.transaction.TransactionalDao;
|
import org.alfresco.repo.transaction.TransactionalDao;
|
||||||
import org.alfresco.repo.usage.UsageDelta;
|
|
||||||
import org.alfresco.repo.usage.UsageDeltaDAO;
|
import org.alfresco.repo.usage.UsageDeltaDAO;
|
||||||
|
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.util.GUID;
|
import org.alfresco.util.GUID;
|
||||||
|
import org.alfresco.util.ParameterCheck;
|
||||||
import org.hibernate.Query;
|
import org.hibernate.Query;
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
import org.springframework.orm.hibernate3.HibernateCallback;
|
import org.springframework.orm.hibernate3.HibernateCallback;
|
||||||
@@ -44,13 +48,19 @@ import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
|
|||||||
*/
|
*/
|
||||||
public class HibernateUsageDeltaDAO extends HibernateDaoSupport implements UsageDeltaDAO, TransactionalDao
|
public class HibernateUsageDeltaDAO extends HibernateDaoSupport implements UsageDeltaDAO, TransactionalDao
|
||||||
{
|
{
|
||||||
private static final String QUERY_GET_DELTAS = "usage.GetDeltas";
|
// private static final String QUERY_GET_DELTAS = "usage.GetDeltas";
|
||||||
private static final String QUERY_GET_TOTAL_DELTA_SIZE = "usage.GetTotalDeltaSize";
|
private static final String QUERY_GET_TOTAL_DELTA_SIZE = "usage.GetTotalDeltaSize";
|
||||||
private static final String QUERY_GET_USAGE_DELTA_NODES = "usage.GetUsageDeltaNodes";
|
private static final String QUERY_GET_USAGE_DELTA_NODES = "usage.GetUsageDeltaNodes";
|
||||||
|
private static final String QUERY_DELETE_DELTAS_FOR_NODE = "usage.DeleteUsageDeltasForNode";
|
||||||
|
|
||||||
/** a uuid identifying this unique instance */
|
/** a uuid identifying this unique instance */
|
||||||
private final String uuid;
|
private final String uuid;
|
||||||
|
private NodeDaoService nodeDaoService;
|
||||||
|
|
||||||
|
public void setNodeDaoService(NodeDaoService nodeDaoService)
|
||||||
|
{
|
||||||
|
this.nodeDaoService = nodeDaoService;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -119,34 +129,48 @@ public class HibernateUsageDeltaDAO extends HibernateDaoSupport implements Usage
|
|||||||
{
|
{
|
||||||
getSession().flush();
|
getSession().flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Node getNodeNotNull(NodeRef nodeRef) throws InvalidNodeRefException
|
||||||
|
{
|
||||||
|
ParameterCheck.mandatory("nodeRef", nodeRef);
|
||||||
|
|
||||||
|
Node unchecked = nodeDaoService.getNode(nodeRef);
|
||||||
|
if (unchecked == null)
|
||||||
|
{
|
||||||
|
throw new InvalidNodeRefException("Node does not exist: " + nodeRef, nodeRef);
|
||||||
|
}
|
||||||
|
return unchecked;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int deleteDeltas(NodeRef nodeRef)
|
||||||
|
{
|
||||||
|
Node node = getNodeNotNull(nodeRef);
|
||||||
|
return deleteDeltas(node.getId());
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public int deleteDeltas(final Node node)
|
public int deleteDeltas(final Long nodeId)
|
||||||
{
|
{
|
||||||
HibernateCallback callback = new HibernateCallback()
|
HibernateCallback callback = new HibernateCallback()
|
||||||
{
|
{
|
||||||
public Object doInHibernate(Session session)
|
public Object doInHibernate(Session session)
|
||||||
{
|
{
|
||||||
Query query = session.getNamedQuery(QUERY_GET_DELTAS);
|
Query query = session.getNamedQuery(QUERY_DELETE_DELTAS_FOR_NODE);
|
||||||
query.setParameter("node", node);
|
query.setParameter("nodeId", nodeId);
|
||||||
return query.list();
|
return query.executeUpdate();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// execute
|
// execute
|
||||||
List<UsageDelta> queryResults = (List<UsageDelta>)getHibernateTemplate().execute(callback);
|
Integer delCount = (Integer) getHibernateTemplate().execute(callback);
|
||||||
|
|
||||||
for (UsageDelta usageDelta : queryResults)
|
return delCount.intValue();
|
||||||
{
|
|
||||||
getHibernateTemplate().delete(usageDelta);
|
|
||||||
}
|
|
||||||
|
|
||||||
return queryResults.size();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public long getTotalDeltaSize(final Node node)
|
public long getTotalDeltaSize(NodeRef nodeRef)
|
||||||
{
|
{
|
||||||
|
final Node node = getNodeNotNull(nodeRef);
|
||||||
HibernateCallback callback = new HibernateCallback()
|
HibernateCallback callback = new HibernateCallback()
|
||||||
{
|
{
|
||||||
public Object doInHibernate(Session session)
|
public Object doInHibernate(Session session)
|
||||||
@@ -163,14 +187,21 @@ public class HibernateUsageDeltaDAO extends HibernateDaoSupport implements Usage
|
|||||||
return (queryResult == null ? 0 : queryResult);
|
return (queryResult == null ? 0 : queryResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void insertDelta(UsageDelta deltaInfo)
|
public void insertDelta(NodeRef usageNodeRef, long deltaSize)
|
||||||
{
|
{
|
||||||
|
Node node = getNodeNotNull(usageNodeRef);
|
||||||
|
|
||||||
|
UsageDelta delta = new UsageDeltaImpl();
|
||||||
|
// delta properties
|
||||||
|
delta.setNode(node);
|
||||||
|
delta.setDeltaSize(deltaSize);
|
||||||
|
|
||||||
// Save
|
// Save
|
||||||
getSession().save(deltaInfo);
|
getSession().save(delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public Set<Node> getUsageDeltaNodes()
|
public Set<NodeRef> getUsageDeltaNodes()
|
||||||
{
|
{
|
||||||
HibernateCallback callback = new HibernateCallback()
|
HibernateCallback callback = new HibernateCallback()
|
||||||
{
|
{
|
||||||
@@ -183,10 +214,10 @@ public class HibernateUsageDeltaDAO extends HibernateDaoSupport implements Usage
|
|||||||
};
|
};
|
||||||
// execute read-only tx
|
// execute read-only tx
|
||||||
List<Node> queryResults = (List<Node>)getHibernateTemplate().execute(callback);
|
List<Node> queryResults = (List<Node>)getHibernateTemplate().execute(callback);
|
||||||
Set<Node> results = new HashSet<Node>(queryResults.size());
|
Set<NodeRef> results = new HashSet<NodeRef>(queryResults.size(), 1.0F);
|
||||||
for (Node node : queryResults)
|
for (Node node : queryResults)
|
||||||
{
|
{
|
||||||
results.add(node);
|
results.add(node.getNodeRef());
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
@@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
<!-- The Usage Delta -->
|
<!-- The Usage Delta -->
|
||||||
|
|
||||||
<class name="org.alfresco.repo.usage.hibernate.UsageDeltaImpl"
|
<class name="org.alfresco.repo.domain.hibernate.UsageDeltaImpl"
|
||||||
proxy="org.alfresco.repo.usage.UsageDelta"
|
proxy="org.alfresco.repo.domain.UsageDelta"
|
||||||
table="alf_usage_delta"
|
table="alf_usage_delta"
|
||||||
dynamic-update="false"
|
dynamic-update="false"
|
||||||
dynamic-insert="false"
|
dynamic-insert="false"
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
select
|
select
|
||||||
sum(deltaSize)
|
sum(deltaSize)
|
||||||
from
|
from
|
||||||
org.alfresco.repo.usage.hibernate.UsageDeltaImpl as usage_delta
|
org.alfresco.repo.domain.hibernate.UsageDeltaImpl as usage_delta
|
||||||
where
|
where
|
||||||
usage_delta.node = :node
|
usage_delta.node = :node
|
||||||
</query>
|
</query>
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
select
|
select
|
||||||
distinct usage_delta.node
|
distinct usage_delta.node
|
||||||
from
|
from
|
||||||
org.alfresco.repo.usage.hibernate.UsageDeltaImpl as usage_delta
|
org.alfresco.repo.domain.hibernate.UsageDeltaImpl as usage_delta
|
||||||
</query>
|
</query>
|
||||||
|
|
||||||
<!-- Get usage deltas for a node -->
|
<!-- Get usage deltas for a node -->
|
||||||
@@ -71,9 +71,17 @@
|
|||||||
select
|
select
|
||||||
usage_delta
|
usage_delta
|
||||||
from
|
from
|
||||||
org.alfresco.repo.usage.hibernate.UsageDeltaImpl as usage_delta
|
org.alfresco.repo.domain.hibernate.UsageDeltaImpl as usage_delta
|
||||||
where
|
where
|
||||||
usage_delta.node = :node
|
usage_delta.node = :node
|
||||||
</query>
|
</query>
|
||||||
|
|
||||||
|
<query name="usage.DeleteUsageDeltasForNode">
|
||||||
|
delete
|
||||||
|
from
|
||||||
|
org.alfresco.repo.domain.hibernate.UsageDeltaImpl as usage
|
||||||
|
where
|
||||||
|
usage.node.id = :nodeId
|
||||||
|
</query>
|
||||||
|
|
||||||
</hibernate-mapping>
|
</hibernate-mapping>
|
@@ -22,10 +22,10 @@
|
|||||||
* the FLOSS exception, and it is also available here:
|
* the FLOSS exception, and it is also available here:
|
||||||
* http://www.alfresco.com/legal/licensing"
|
* http://www.alfresco.com/legal/licensing"
|
||||||
*/
|
*/
|
||||||
package org.alfresco.repo.usage.hibernate;
|
package org.alfresco.repo.domain.hibernate;
|
||||||
|
|
||||||
import org.alfresco.repo.domain.Node;
|
import org.alfresco.repo.domain.Node;
|
||||||
import org.alfresco.repo.usage.UsageDelta;
|
import org.alfresco.repo.domain.UsageDelta;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Usage Delta Implementation
|
* Usage Delta Implementation
|
@@ -684,7 +684,7 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
|
|||||||
{
|
{
|
||||||
logger.debug("Deleting usage deltas of node (if any)" + node.getId());
|
logger.debug("Deleting usage deltas of node (if any)" + node.getId());
|
||||||
}
|
}
|
||||||
usageDeltaDao.deleteDeltas(node);
|
usageDeltaDao.deleteDeltas(node.getId());
|
||||||
|
|
||||||
// update the node status
|
// update the node status
|
||||||
NodeRef nodeRef = node.getNodeRef();
|
NodeRef nodeRef = node.getNodeRef();
|
||||||
|
@@ -123,7 +123,7 @@ public class MissingContentReindexComponent extends AbstractReindexComponent
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
transactionService.getRetryingTransactionHelper().doInTransaction(reindexWork);
|
transactionService.getRetryingTransactionHelper().doInTransaction(reindexWork, true);
|
||||||
count++;
|
count++;
|
||||||
// check if we have to break out
|
// check if we have to break out
|
||||||
if (isShuttingDown())
|
if (isShuttingDown())
|
||||||
|
@@ -354,13 +354,8 @@ public class RuleServiceImpl implements RuleService, RuntimeRuleService
|
|||||||
public List<Rule> getRules(NodeRef nodeRef, boolean includeInherited, String ruleTypeName)
|
public List<Rule> getRules(NodeRef nodeRef, boolean includeInherited, String ruleTypeName)
|
||||||
{
|
{
|
||||||
List<Rule> rules = new ArrayList<Rule>();
|
List<Rule> rules = new ArrayList<Rule>();
|
||||||
|
|
||||||
// Extra check of CONSUMER permission was added to rule selection,
|
|
||||||
// to prevent Access Denied Exception due to the bug:
|
|
||||||
// https://issues.alfresco.com/browse/ETWOTWO-438
|
|
||||||
|
|
||||||
if (this.runtimeNodeService.exists(nodeRef) == true && checkNodeType(nodeRef) == true &&
|
if (this.runtimeNodeService.exists(nodeRef) == true && checkNodeType(nodeRef) == true)
|
||||||
permissionService.hasPermission(nodeRef, PermissionService.CONSUMER) == AccessStatus.ALLOWED)
|
|
||||||
{
|
{
|
||||||
if (includeInherited == true && this.runtimeNodeService.hasAspect(nodeRef, RuleModel.ASPECT_IGNORE_INHERITED_RULES) == false)
|
if (includeInherited == true && this.runtimeNodeService.hasAspect(nodeRef, RuleModel.ASPECT_IGNORE_INHERITED_RULES) == false)
|
||||||
{
|
{
|
||||||
@@ -375,7 +370,12 @@ public class RuleServiceImpl implements RuleService, RuntimeRuleService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.runtimeNodeService.hasAspect(nodeRef, RuleModel.ASPECT_RULES) == true)
|
// Extra check of CONSUMER permission was added to rule selection,
|
||||||
|
// to prevent Access Denied Exception due to the bug:
|
||||||
|
// https://issues.alfresco.com/browse/ETWOTWO-438
|
||||||
|
|
||||||
|
if (this.runtimeNodeService.hasAspect(nodeRef, RuleModel.ASPECT_RULES) == true &&
|
||||||
|
permissionService.hasPermission(nodeRef, PermissionService.READ) == AccessStatus.ALLOWED)
|
||||||
{
|
{
|
||||||
NodeRef ruleFolder = getSavedRuleFolderRef(nodeRef);
|
NodeRef ruleFolder = getSavedRuleFolderRef(nodeRef);
|
||||||
if (ruleFolder != null)
|
if (ruleFolder != null)
|
||||||
|
566
source/java/org/alfresco/repo/tenant/MultiTDemoSystemTest.java
Executable file
566
source/java/org/alfresco/repo/tenant/MultiTDemoSystemTest.java
Executable file
@@ -0,0 +1,566 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2008 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
* As a special exception to the terms and conditions of version 2.0 of
|
||||||
|
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||||
|
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||||
|
* FLOSS exception. You should have recieved a copy of the text describing
|
||||||
|
* the FLOSS exception, and it is also available here:
|
||||||
|
* http://www.alfresco.com/legal/licensing"
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.tenant;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
|
import org.alfresco.model.ApplicationModel;
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.repo.content.MimetypeMap;
|
||||||
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
|
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||||
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
|
import org.alfresco.service.cmr.repository.ContentService;
|
||||||
|
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
|
import org.alfresco.service.cmr.search.CategoryService;
|
||||||
|
import org.alfresco.service.cmr.search.ResultSet;
|
||||||
|
import org.alfresco.service.cmr.search.SearchService;
|
||||||
|
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||||
|
import org.alfresco.service.cmr.security.AuthorityService;
|
||||||
|
import org.alfresco.service.cmr.security.AuthorityType;
|
||||||
|
import org.alfresco.service.cmr.security.OwnableService;
|
||||||
|
import org.alfresco.service.cmr.security.PermissionService;
|
||||||
|
import org.alfresco.service.cmr.security.PersonService;
|
||||||
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
import org.alfresco.util.ApplicationContextHelper;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
|
||||||
|
public class MultiTDemoSystemTest extends TestCase
|
||||||
|
{
|
||||||
|
private static Log logger = LogFactory.getLog(MultiTDemoSystemTest.class);
|
||||||
|
|
||||||
|
private static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
|
||||||
|
|
||||||
|
private NodeService nodeService;
|
||||||
|
private AuthenticationService authenticationService;
|
||||||
|
private PersonService personService;
|
||||||
|
private SearchService searchService;
|
||||||
|
private ContentService contentService;
|
||||||
|
private PermissionService permissionService;
|
||||||
|
private OwnableService ownableService;
|
||||||
|
private TenantAdminService tenantAdminService;
|
||||||
|
private TenantService tenantService;
|
||||||
|
private AuthorityService authorityService;
|
||||||
|
private CategoryService categoryService;
|
||||||
|
|
||||||
|
public static final String TEST_TENANT_DOMAIN1 = "yyy.com";
|
||||||
|
public static final String TEST_TENANT_DOMAIN2 = "zzz.com";
|
||||||
|
|
||||||
|
private static List<String> tenants;
|
||||||
|
|
||||||
|
static {
|
||||||
|
tenants = new ArrayList<String>(2);
|
||||||
|
tenants.add(TEST_TENANT_DOMAIN1);
|
||||||
|
tenants.add(TEST_TENANT_DOMAIN2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final String ROOT_DIR = "./tenantstores";
|
||||||
|
|
||||||
|
public static final String TEST_ADMIN_BASENAME = "admin";
|
||||||
|
public static final String TEST_ADMIN_PASSWORD = "admin";
|
||||||
|
|
||||||
|
public static final String TEST_USER1 = "alice";
|
||||||
|
public static final String TEST_USER2 = "bob";
|
||||||
|
public static final String TEST_USER3 = "eve";
|
||||||
|
|
||||||
|
|
||||||
|
public static StoreRef SPACES_STORE = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore");
|
||||||
|
|
||||||
|
|
||||||
|
public MultiTDemoSystemTest()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setUp() throws Exception
|
||||||
|
{
|
||||||
|
super.setUp();
|
||||||
|
|
||||||
|
nodeService = (NodeService) ctx.getBean("NodeService");
|
||||||
|
authenticationService = (AuthenticationService) ctx.getBean("AuthenticationService");
|
||||||
|
tenantAdminService = (TenantAdminService) ctx.getBean("tenantAdminService");
|
||||||
|
tenantService = (TenantService) ctx.getBean("tenantService");
|
||||||
|
personService = (PersonService) ctx.getBean("PersonService");
|
||||||
|
searchService = (SearchService) ctx.getBean("SearchService");
|
||||||
|
contentService = (ContentService) ctx.getBean("ContentService");
|
||||||
|
permissionService = (PermissionService) ctx.getBean("PermissionService");
|
||||||
|
ownableService = (OwnableService) ctx.getBean("OwnableService");
|
||||||
|
authorityService = (AuthorityService) ctx.getBean("AuthorityService");
|
||||||
|
categoryService = (CategoryService) ctx.getBean("CategoryService");
|
||||||
|
|
||||||
|
AuthenticationUtil.setCurrentUser(AuthenticationUtil.getSystemUserName()); // force, to clear real user from previous test (runAs issue ?)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void tearDown() throws Exception
|
||||||
|
{
|
||||||
|
super.tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void testCreateTenants() throws Throwable
|
||||||
|
{
|
||||||
|
logger.info("Create tenants");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
for (final String tenantDomain : tenants)
|
||||||
|
{
|
||||||
|
// create tenants (if not already created)
|
||||||
|
AuthenticationUtil.runAs(new RunAsWork<Object>()
|
||||||
|
{
|
||||||
|
public Object doWork() throws Exception
|
||||||
|
{
|
||||||
|
if (! tenantAdminService.existsTenant(tenantDomain))
|
||||||
|
{
|
||||||
|
//tenantAdminService.createTenant(tenantDomain, TEST_ADMIN_PASSWORD.toCharArray(), ROOT_DIR + "/" + tenantDomain);
|
||||||
|
tenantAdminService.createTenant(tenantDomain, TEST_ADMIN_PASSWORD.toCharArray(), null); // use default root dir
|
||||||
|
|
||||||
|
logger.info("Created tenant " + tenantDomain);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, AuthenticationUtil.getSystemUserName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Throwable t)
|
||||||
|
{
|
||||||
|
StringWriter stackTrace = new StringWriter();
|
||||||
|
t.printStackTrace(new PrintWriter(stackTrace));
|
||||||
|
System.err.println(stackTrace.toString());
|
||||||
|
throw t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCreateUsers() throws Throwable
|
||||||
|
{
|
||||||
|
logger.info("Create demo users");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
for (final String tenantDomain : tenants)
|
||||||
|
{
|
||||||
|
String tenantAdminName = tenantService.getDomainUser(TenantService.ADMIN_BASENAME, tenantDomain);
|
||||||
|
|
||||||
|
AuthenticationUtil.runAs(new RunAsWork<Object>()
|
||||||
|
{
|
||||||
|
public Object doWork() throws Exception
|
||||||
|
{
|
||||||
|
createUser(TEST_USER1, tenantDomain, "welcome");
|
||||||
|
|
||||||
|
createUser(TEST_USER2, tenantDomain, "welcome");
|
||||||
|
|
||||||
|
if (tenantDomain.equals(TEST_TENANT_DOMAIN2))
|
||||||
|
{
|
||||||
|
createUser(TEST_USER3, tenantDomain, "welcome");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, tenantAdminName);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Throwable t)
|
||||||
|
{
|
||||||
|
StringWriter stackTrace = new StringWriter();
|
||||||
|
t.printStackTrace(new PrintWriter(stackTrace));
|
||||||
|
System.err.println(stackTrace.toString());
|
||||||
|
throw t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCreateGroups()
|
||||||
|
{
|
||||||
|
logger.info("Create demo groups");
|
||||||
|
|
||||||
|
for (final String tenantDomain : tenants)
|
||||||
|
{
|
||||||
|
String tenantAdminName = tenantService.getDomainUser("admin", tenantDomain);
|
||||||
|
|
||||||
|
AuthenticationUtil.runAs(new RunAsWork<Object>()
|
||||||
|
{
|
||||||
|
public Object doWork() throws Exception
|
||||||
|
{
|
||||||
|
createGroup("GrpA-"+tenantDomain, null);
|
||||||
|
createGroup("SubGrpA-"+tenantDomain, "GrpA-"+tenantDomain);
|
||||||
|
|
||||||
|
createGroup("GrpB-"+tenantDomain, null);
|
||||||
|
createGroup("SubGrpB-"+tenantDomain, "GrpB-"+tenantDomain);
|
||||||
|
|
||||||
|
if (tenantDomain.equals(TEST_TENANT_DOMAIN2))
|
||||||
|
{
|
||||||
|
createGroup("GrpC-"+tenantDomain, null);
|
||||||
|
createGroup("SubGrpC-"+tenantDomain, "GrpC-"+tenantDomain);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, tenantAdminName);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCreateCategories()
|
||||||
|
{
|
||||||
|
logger.info("Create demo categories");
|
||||||
|
|
||||||
|
for (final String tenantDomain : tenants)
|
||||||
|
{
|
||||||
|
String tenantAdminName = tenantService.getDomainUser(TenantService.ADMIN_BASENAME, tenantDomain);
|
||||||
|
|
||||||
|
AuthenticationUtil.runAs(new RunAsWork<Object>()
|
||||||
|
{
|
||||||
|
public Object doWork() throws Exception
|
||||||
|
{
|
||||||
|
NodeRef catRef = createCategory(SPACES_STORE, null, "CatA", "CatA-"+tenantDomain);
|
||||||
|
createCategory(SPACES_STORE, catRef, "SubCatA", "SubCatA-"+tenantDomain); // ignore return
|
||||||
|
|
||||||
|
catRef = createCategory(SPACES_STORE, null, "CatB", "CatB-"+tenantDomain);
|
||||||
|
createCategory(SPACES_STORE, catRef, "SubCatB", "SubCatB-"+tenantDomain); // ignore return
|
||||||
|
|
||||||
|
if (tenantDomain.equals(TEST_TENANT_DOMAIN2))
|
||||||
|
{
|
||||||
|
catRef = createCategory(SPACES_STORE, null, "CatC", "CatC-"+tenantDomain);
|
||||||
|
createCategory(SPACES_STORE, catRef, "SubCatC", "SubCatC-"+tenantDomain); // ignore return
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, tenantAdminName);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCreateFolders()
|
||||||
|
{
|
||||||
|
logger.info("Create demo folders");
|
||||||
|
|
||||||
|
List<String> users = new ArrayList<String>(3);
|
||||||
|
users.add(TEST_USER1);
|
||||||
|
users.add(TEST_USER2);
|
||||||
|
users.add(TEST_USER3);
|
||||||
|
|
||||||
|
for (final String tenantDomain : tenants)
|
||||||
|
{
|
||||||
|
for (String baseUserName : users)
|
||||||
|
{
|
||||||
|
if ((! baseUserName.equals(TEST_USER3)) || (tenantDomain.equals(TEST_TENANT_DOMAIN2)))
|
||||||
|
{
|
||||||
|
final String tenantUserName = tenantService.getDomainUser(baseUserName, tenantDomain);
|
||||||
|
|
||||||
|
AuthenticationUtil.runAs(new RunAsWork<Object>()
|
||||||
|
{
|
||||||
|
public Object doWork() throws Exception
|
||||||
|
{
|
||||||
|
NodeRef homeSpaceRef = getHomeSpaceFolderNode(tenantUserName);
|
||||||
|
|
||||||
|
NodeRef folderRef = createFolderNode(homeSpaceRef, "myfolder1");
|
||||||
|
createFolderNode(folderRef, "mysubfolder1"); // ignore return
|
||||||
|
|
||||||
|
folderRef = createFolderNode(homeSpaceRef, "myfolder2");
|
||||||
|
createFolderNode(folderRef, "mysubfolder2"); // ignore return
|
||||||
|
|
||||||
|
if (tenantDomain.equals(TEST_TENANT_DOMAIN2))
|
||||||
|
{
|
||||||
|
folderRef = createFolderNode(homeSpaceRef, "myfolder3");
|
||||||
|
createFolderNode(folderRef, "mysubfolder3"); // ignore return
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, tenantUserName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCreateUserContent()
|
||||||
|
{
|
||||||
|
logger.info("Create demo content");
|
||||||
|
|
||||||
|
List<String> users = new ArrayList<String>(3);
|
||||||
|
users.add(TEST_USER1);
|
||||||
|
users.add(TEST_USER2);
|
||||||
|
users.add(TEST_USER3);
|
||||||
|
|
||||||
|
for (final String tenantDomain : tenants)
|
||||||
|
{
|
||||||
|
for (String baseUserName : users)
|
||||||
|
{
|
||||||
|
if ((! baseUserName.equals(TEST_USER3)) || (tenantDomain.equals(TEST_TENANT_DOMAIN2)))
|
||||||
|
{
|
||||||
|
final String tenantUserName = tenantService.getDomainUser(baseUserName, tenantDomain);
|
||||||
|
|
||||||
|
AuthenticationUtil.runAs(new RunAsWork<Object>()
|
||||||
|
{
|
||||||
|
public Object doWork() throws Exception
|
||||||
|
{
|
||||||
|
NodeRef homeSpaceRef = getHomeSpaceFolderNode(tenantUserName);
|
||||||
|
addTextContent(homeSpaceRef, tenantUserName+" quick brown fox.txt", "The quick brown fox jumps over the lazy dog (tenant " + tenantDomain + ")");
|
||||||
|
|
||||||
|
if (tenantDomain.equals(TEST_TENANT_DOMAIN2))
|
||||||
|
{
|
||||||
|
addTextContent(homeSpaceRef, tenantUserName+" quick brown fox ANO.txt", "The quick brown fox jumps over the lazy dog ANO (tenant " + tenantDomain + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, tenantUserName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void createGroup(String shortName, String parentShortName)
|
||||||
|
{
|
||||||
|
// create new Group using authority Service
|
||||||
|
String groupName = this.authorityService.getName(AuthorityType.GROUP, shortName);
|
||||||
|
if (this.authorityService.authorityExists(groupName) == false)
|
||||||
|
{
|
||||||
|
String parentGroupName = null;
|
||||||
|
if (parentShortName != null)
|
||||||
|
{
|
||||||
|
parentGroupName = this.authorityService.getName(AuthorityType.GROUP, parentShortName);
|
||||||
|
if (this.authorityService.authorityExists(parentGroupName) == false)
|
||||||
|
{
|
||||||
|
logger.warn("Parent group does not exist: " + parentShortName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.authorityService.createAuthority(AuthorityType.GROUP, parentGroupName, shortName);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.warn("Group already exists: " + shortName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void createUser(String baseUserName, String tenantDomain, String password)
|
||||||
|
{
|
||||||
|
String userName = tenantService.getDomainUser(baseUserName, tenantDomain);
|
||||||
|
|
||||||
|
if (! this.authenticationService.authenticationExists(userName))
|
||||||
|
{
|
||||||
|
NodeRef baseHomeFolder = getUserHomesNodeRef(SPACES_STORE);
|
||||||
|
|
||||||
|
// Create the users home folder
|
||||||
|
NodeRef homeFolder = createHomeSpaceFolderNode(
|
||||||
|
baseHomeFolder,
|
||||||
|
baseUserName,
|
||||||
|
userName);
|
||||||
|
|
||||||
|
// Create the authentication
|
||||||
|
this.authenticationService.createAuthentication(userName, password.toCharArray());
|
||||||
|
|
||||||
|
// Create the person
|
||||||
|
Map<QName, Serializable> personProperties = new HashMap<QName, Serializable>();
|
||||||
|
personProperties.put(ContentModel.PROP_USERNAME, userName);
|
||||||
|
personProperties.put(ContentModel.PROP_HOMEFOLDER, homeFolder);
|
||||||
|
personProperties.put(ContentModel.PROP_FIRSTNAME, baseUserName);
|
||||||
|
personProperties.put(ContentModel.PROP_LASTNAME, baseUserName+"-"+tenantDomain); // add domain suffix here for demo only
|
||||||
|
personProperties.put(ContentModel.PROP_EMAIL, userName);
|
||||||
|
|
||||||
|
NodeRef newPerson = this.personService.createPerson(personProperties);
|
||||||
|
|
||||||
|
// ensure the user can access their own Person object
|
||||||
|
this.permissionService.setPermission(newPerson, userName, permissionService.getAllPermission(), true);
|
||||||
|
|
||||||
|
logger.info("Created user " + userName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private NodeRef getUserHomesNodeRef(StoreRef storeRef)
|
||||||
|
{
|
||||||
|
// get the users' home location
|
||||||
|
String path = "/app:company_home/app:user_homes";
|
||||||
|
|
||||||
|
ResultSet rs = this.searchService.query(storeRef, SearchService.LANGUAGE_XPATH, path);
|
||||||
|
|
||||||
|
NodeRef usersHomeNodeRef = null;
|
||||||
|
if (rs.length() == 0)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Cannot find user homes location: " + path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
usersHomeNodeRef = rs.getNodeRef(0);
|
||||||
|
}
|
||||||
|
return usersHomeNodeRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
private NodeRef createFolderNode(NodeRef parentFolderNodeRef, String nameValue)
|
||||||
|
{
|
||||||
|
if (nameValue != null)
|
||||||
|
{
|
||||||
|
Map<QName, Serializable> folderProps = new HashMap<QName, Serializable>();
|
||||||
|
folderProps.put(ContentModel.PROP_NAME, nameValue);
|
||||||
|
|
||||||
|
return this.nodeService.createNode(
|
||||||
|
parentFolderNodeRef,
|
||||||
|
ContentModel.ASSOC_CONTAINS,
|
||||||
|
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, nameValue),
|
||||||
|
ContentModel.TYPE_FOLDER,
|
||||||
|
folderProps).getChildRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private NodeRef createCategory(StoreRef storeRef, NodeRef parentCategoryRef, String name, String description)
|
||||||
|
{
|
||||||
|
// create category using categoryservice
|
||||||
|
NodeRef ref;
|
||||||
|
if (parentCategoryRef == null)
|
||||||
|
{
|
||||||
|
ref = this.categoryService.createRootCategory(storeRef, ContentModel.ASPECT_GEN_CLASSIFIABLE, name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ref = categoryService.createCategory(parentCategoryRef, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// apply the titled aspect - for description
|
||||||
|
Map<QName, Serializable> titledProps = new HashMap<QName, Serializable>(1, 1.0f);
|
||||||
|
titledProps.put(ContentModel.PROP_DESCRIPTION, description);
|
||||||
|
this.nodeService.addAspect(ref, ContentModel.ASPECT_TITLED, titledProps);
|
||||||
|
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
private NodeRef createHomeSpaceFolderNode(NodeRef folderNodeRef, String spaceName, String userName)
|
||||||
|
{
|
||||||
|
if (spaceName != null)
|
||||||
|
{
|
||||||
|
Map<QName, Serializable> folderProps = new HashMap<QName, Serializable>();
|
||||||
|
folderProps.put(ContentModel.PROP_NAME, spaceName);
|
||||||
|
|
||||||
|
NodeRef nodeRef = this.nodeService.createNode(
|
||||||
|
folderNodeRef,
|
||||||
|
ContentModel.ASSOC_CONTAINS,
|
||||||
|
QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, spaceName),
|
||||||
|
ContentModel.TYPE_FOLDER,
|
||||||
|
folderProps).getChildRef();
|
||||||
|
|
||||||
|
// apply the uifacets aspect - icon and title props
|
||||||
|
Map<QName, Serializable> uiFacetsProps = new HashMap<QName, Serializable>(3);
|
||||||
|
uiFacetsProps.put(ApplicationModel.PROP_ICON, "space-icon-default");
|
||||||
|
uiFacetsProps.put(ContentModel.PROP_TITLE, spaceName);
|
||||||
|
this.nodeService.addAspect(nodeRef, ApplicationModel.ASPECT_UIFACETS, uiFacetsProps);
|
||||||
|
|
||||||
|
setupHomeSpacePermissions(nodeRef, userName);
|
||||||
|
|
||||||
|
return nodeRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupHomeSpacePermissions(NodeRef homeSpaceRef, String userName)
|
||||||
|
{
|
||||||
|
// Admin Authority has full permissions by default (automatic - set in the permission config)
|
||||||
|
// give full permissions to the new user
|
||||||
|
this.permissionService.setPermission(homeSpaceRef, userName, permissionService.getAllPermission(), true);
|
||||||
|
|
||||||
|
// by default other users will only have GUEST access to the space contents
|
||||||
|
String permission = "Consumer";
|
||||||
|
|
||||||
|
if (permission != null && permission.length() != 0)
|
||||||
|
{
|
||||||
|
this.permissionService.setPermission(homeSpaceRef, permissionService.getAllAuthorities(), permission, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// the new user is the OWNER of their own space and always has full permissions
|
||||||
|
this.ownableService.setOwner(homeSpaceRef, userName);
|
||||||
|
this.permissionService.setPermission(homeSpaceRef, permissionService.getOwnerAuthority(), permissionService.getAllPermission(), true);
|
||||||
|
|
||||||
|
// now detach (if we did this first we could not set any permissions!)
|
||||||
|
this.permissionService.setInheritParentPermissions(homeSpaceRef, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private NodeRef getHomeSpaceFolderNode(String userName)
|
||||||
|
{
|
||||||
|
return (NodeRef)this.nodeService.getProperty(personService.getPerson(userName), ContentModel.PROP_HOMEFOLDER);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addTextContent(NodeRef spaceRef, String name, String textData)
|
||||||
|
{
|
||||||
|
Map<QName, Serializable> contentProps = new HashMap<QName, Serializable>();
|
||||||
|
contentProps.put(ContentModel.PROP_NAME, name);
|
||||||
|
|
||||||
|
ChildAssociationRef association = nodeService.createNode(spaceRef,
|
||||||
|
ContentModel.ASSOC_CONTAINS,
|
||||||
|
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name),
|
||||||
|
ContentModel.TYPE_CONTENT,
|
||||||
|
contentProps);
|
||||||
|
|
||||||
|
NodeRef content = association.getChildRef();
|
||||||
|
|
||||||
|
// add titled aspect (for Web Client display)
|
||||||
|
Map<QName, Serializable> titledProps = new HashMap<QName, Serializable>();
|
||||||
|
titledProps.put(ContentModel.PROP_TITLE, name);
|
||||||
|
titledProps.put(ContentModel.PROP_DESCRIPTION, name);
|
||||||
|
this.nodeService.addAspect(content, ContentModel.ASPECT_TITLED, titledProps);
|
||||||
|
|
||||||
|
ContentWriter writer = contentService.getWriter(content, ContentModel.PROP_CONTENT, true);
|
||||||
|
|
||||||
|
writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
|
||||||
|
writer.setEncoding("UTF-8");
|
||||||
|
|
||||||
|
writer.putContent(textData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// comment-in to run from command line
|
||||||
|
public static void main(String args[])
|
||||||
|
{
|
||||||
|
System.out.println(new Date());
|
||||||
|
junit.textui.TestRunner.run(MultiTDemoSystemTest.class);
|
||||||
|
System.out.println(new Date());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -47,30 +47,69 @@ public interface TenantService extends TenantBaseService
|
|||||||
|
|
||||||
public static final String ADMIN_BASENAME = "admin";
|
public static final String ADMIN_BASENAME = "admin";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the reference <b>with</b> the tenant-specific ID attached
|
||||||
|
*/
|
||||||
public NodeRef getName(NodeRef nodeRef);
|
public NodeRef getName(NodeRef nodeRef);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the reference <b>with</b> the tenant-specific ID attached
|
||||||
|
*/
|
||||||
public NodeRef getName(NodeRef inNodeRef, NodeRef nodeRef);
|
public NodeRef getName(NodeRef inNodeRef, NodeRef nodeRef);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the reference <b>with</b> the tenant-specific ID attached
|
||||||
|
*/
|
||||||
public StoreRef getName(StoreRef storeRef);
|
public StoreRef getName(StoreRef storeRef);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the reference <b>with</b> the tenant-specific ID attached
|
||||||
|
*/
|
||||||
public ChildAssociationRef getName(ChildAssociationRef childAssocRef);
|
public ChildAssociationRef getName(ChildAssociationRef childAssocRef);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the reference <b>with</b> the tenant-specific ID attached
|
||||||
|
*/
|
||||||
public StoreRef getName(String username, StoreRef storeRef);
|
public StoreRef getName(String username, StoreRef storeRef);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the reference <b>with</b> the tenant-specific ID attached
|
||||||
|
*/
|
||||||
public QName getName(NodeRef inNodeRef, QName name);
|
public QName getName(NodeRef inNodeRef, QName name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the reference <b>with</b> the tenant-specific ID attached
|
||||||
|
*/
|
||||||
public String getName(String name);
|
public String getName(String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the reference <b>without</b> the tenant-specific ID attached
|
||||||
|
*/
|
||||||
public QName getBaseName(QName name, boolean forceIfNonTenant);
|
public QName getBaseName(QName name, boolean forceIfNonTenant);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the reference <b>without</b> the tenant-specific ID attached
|
||||||
|
*/
|
||||||
public NodeRef getBaseName(NodeRef nodeRef);
|
public NodeRef getBaseName(NodeRef nodeRef);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the reference <b>without</b> the tenant-specific ID attached
|
||||||
|
*/
|
||||||
public StoreRef getBaseName(StoreRef storeRef);
|
public StoreRef getBaseName(StoreRef storeRef);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the reference <b>without</b> the tenant-specific ID attached
|
||||||
|
*/
|
||||||
public ChildAssociationRef getBaseName(ChildAssociationRef childAssocRef);
|
public ChildAssociationRef getBaseName(ChildAssociationRef childAssocRef);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the reference <b>without</b> the tenant-specific ID attached
|
||||||
|
*/
|
||||||
public String getBaseName(String name);
|
public String getBaseName(String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the reference <b>without</b> the tenant-specific ID attached
|
||||||
|
*/
|
||||||
public String getBaseName(String name, boolean forceIfNonTenant);
|
public String getBaseName(String name, boolean forceIfNonTenant);
|
||||||
|
|
||||||
public String getBaseNameUser(String name);
|
public String getBaseNameUser(String name);
|
||||||
|
@@ -26,7 +26,7 @@ package org.alfresco.repo.usage;
|
|||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.alfresco.repo.domain.Node;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The interface to persist usage delta information.
|
* The interface to persist usage delta information.
|
||||||
@@ -37,20 +37,21 @@ public interface UsageDeltaDAO
|
|||||||
/**
|
/**
|
||||||
* Create a usage delta entry.
|
* Create a usage delta entry.
|
||||||
*
|
*
|
||||||
* @param deltaInfo
|
* @param deltaSize the size change
|
||||||
*/
|
*/
|
||||||
public void insertDelta(UsageDelta deltaInfo);
|
public void insertDelta(NodeRef usageNodeRef, long deltaSize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the total delta size for a node.
|
* Get the total delta size for a node.
|
||||||
*
|
*
|
||||||
* @param node
|
* @param nodeRef the node reference
|
||||||
* @return sum of delta sizes (in bytes) - can be +ve or -ve
|
* @return sum of delta sizes (in bytes) - can be +ve or -ve
|
||||||
*/
|
*/
|
||||||
public long getTotalDeltaSize(Node node);
|
public long getTotalDeltaSize(NodeRef usageNodeRef);
|
||||||
|
|
||||||
|
public Set<NodeRef> getUsageDeltaNodes();
|
||||||
|
|
||||||
public Set<Node> getUsageDeltaNodes();
|
public int deleteDeltas(NodeRef nodeRef);
|
||||||
|
|
||||||
public int deleteDeltas(Node node);
|
public int deleteDeltas(Long nodeId);
|
||||||
}
|
}
|
||||||
|
@@ -24,80 +24,43 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.usage;
|
package org.alfresco.repo.usage;
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.alfresco.repo.domain.Node;
|
|
||||||
import org.alfresco.repo.node.db.NodeDaoService;
|
|
||||||
import org.alfresco.repo.usage.hibernate.UsageDeltaImpl;
|
|
||||||
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.usage.UsageService;
|
import org.alfresco.service.cmr.usage.UsageService;
|
||||||
import org.alfresco.util.ParameterCheck;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The implementation of the UsageService for tracking usages.
|
* The implementation of the UsageService for tracking usages.
|
||||||
*
|
*
|
||||||
|
* @author Jan Vonka
|
||||||
|
* @since 2.9
|
||||||
*/
|
*/
|
||||||
public class UsageServiceImpl implements UsageService
|
public class UsageServiceImpl implements UsageService
|
||||||
{
|
{
|
||||||
private UsageDeltaDAO usageDeltaDao;
|
private UsageDeltaDAO usageDeltaDao;
|
||||||
private NodeDaoService nodeDaoService;
|
|
||||||
|
|
||||||
public void setUsageDeltaDao(UsageDeltaDAO usageDeltaDao)
|
public void setUsageDeltaDao(UsageDeltaDAO usageDeltaDao)
|
||||||
{
|
{
|
||||||
this.usageDeltaDao = usageDeltaDao;
|
this.usageDeltaDao = usageDeltaDao;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNodeDaoService(NodeDaoService nodeDaoService)
|
|
||||||
{
|
|
||||||
this.nodeDaoService = nodeDaoService;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void insertDelta(NodeRef usageNodeRef, long deltaSize)
|
public void insertDelta(NodeRef usageNodeRef, long deltaSize)
|
||||||
{
|
{
|
||||||
UsageDelta delta = new UsageDeltaImpl();
|
usageDeltaDao.insertDelta(usageNodeRef, deltaSize);
|
||||||
|
|
||||||
// delta properties
|
|
||||||
delta.setNode(getNodeNotNull(usageNodeRef));
|
|
||||||
delta.setDeltaSize(deltaSize);
|
|
||||||
|
|
||||||
usageDeltaDao.insertDelta(delta);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getTotalDeltaSize(NodeRef usageNodeRef)
|
public long getTotalDeltaSize(NodeRef usageNodeRef)
|
||||||
{
|
{
|
||||||
return usageDeltaDao.getTotalDeltaSize(getNodeNotNull(usageNodeRef));
|
return usageDeltaDao.getTotalDeltaSize(usageNodeRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<NodeRef> getUsageDeltaNodes()
|
public Set<NodeRef> getUsageDeltaNodes()
|
||||||
{
|
{
|
||||||
Set<Node> nodes = usageDeltaDao.getUsageDeltaNodes();
|
return usageDeltaDao.getUsageDeltaNodes();
|
||||||
|
|
||||||
// convert nodes to nodeRefs (tenant-specific)
|
|
||||||
Set<NodeRef> results = new HashSet<NodeRef>(nodes.size());
|
|
||||||
for (Node node : nodes)
|
|
||||||
{
|
|
||||||
results.add(node.getNodeRef());
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int deleteDeltas(NodeRef usageNodeRef)
|
public int deleteDeltas(NodeRef usageNodeRef)
|
||||||
{
|
{
|
||||||
return usageDeltaDao.deleteDeltas(getNodeNotNull(usageNodeRef));
|
return usageDeltaDao.deleteDeltas(usageNodeRef);
|
||||||
}
|
|
||||||
|
|
||||||
private Node getNodeNotNull(NodeRef nodeRef) throws InvalidNodeRefException
|
|
||||||
{
|
|
||||||
ParameterCheck.mandatory("nodeRef", nodeRef);
|
|
||||||
|
|
||||||
Node unchecked = nodeDaoService.getNode(nodeRef);
|
|
||||||
if (unchecked == null)
|
|
||||||
{
|
|
||||||
throw new InvalidNodeRefException("Node does not exist: " + nodeRef, nodeRef);
|
|
||||||
}
|
|
||||||
return unchecked;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -33,6 +33,8 @@ import org.alfresco.service.cmr.repository.NodeRef;
|
|||||||
/**
|
/**
|
||||||
* The public API by which applications can create usage delta entries.
|
* The public API by which applications can create usage delta entries.
|
||||||
*
|
*
|
||||||
|
* @author Jan Vonka
|
||||||
|
* @since 2.9
|
||||||
*/
|
*/
|
||||||
@PublicService
|
@PublicService
|
||||||
public interface UsageService
|
public interface UsageService
|
||||||
|
Reference in New Issue
Block a user