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>
|
||||
</bean>
|
||||
|
||||
<bean id="usageDeltaDao" class="org.alfresco.repo.usage.hibernate.HibernateUsageDeltaDAO">
|
||||
<bean id="usageDeltaDao" class="org.alfresco.repo.domain.hibernate.HibernateUsageDeltaDAO">
|
||||
<property name="sessionFactory">
|
||||
<ref bean="sessionFactory"/>
|
||||
</property>
|
||||
<property name="nodeDaoService">
|
||||
<ref bean="nodeDaoServiceImpl" />
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="nodeDaoServiceImpl" class="org.alfresco.repo.node.db.hibernate.HibernateNodeDaoServiceImpl">
|
||||
|
@@ -302,6 +302,10 @@
|
||||
<title>Display Name</title>
|
||||
<type>d:text</type>
|
||||
</property>
|
||||
<property name="wca:deployservergroup">
|
||||
<title>Display Name</title>
|
||||
<type>d:text</type>
|
||||
</property>
|
||||
<property name="wca:deployserverusername">
|
||||
<title>Username</title>
|
||||
<type>d:text</type>
|
||||
|
@@ -6,7 +6,6 @@
|
||||
|
||||
<bean id="usageService" class="org.alfresco.repo.usage.UsageServiceImpl">
|
||||
<property name="usageDeltaDao" ref="usageDeltaDao"/>
|
||||
<property name="nodeDaoService" ref="nodeDaoService"/>
|
||||
</bean>
|
||||
|
||||
<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_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_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_DEPLOYSERVERTARGET = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deployservertarget");
|
||||
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.locking.AVMLock;
|
||||
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.NodeService;
|
||||
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.AuthorityType;
|
||||
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.Pair;
|
||||
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
|
||||
List<ChildAssociationRef> children = fNodeService.getChildAssocs(
|
||||
webProjectRef, WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL);
|
||||
for (ChildAssociationRef child : children)
|
||||
// TODO as part of WCM refactor, consolidate with WebProject.getWebProjectUserRole
|
||||
StringBuilder query = new StringBuilder(128);
|
||||
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();
|
||||
if (fNodeService.getProperty(childRef, WCMAppModel.PROP_WEBUSERNAME).equals(user) &&
|
||||
fNodeService.getProperty(childRef, WCMAppModel.PROP_WEBUSERROLE).equals(ROLE_CONTENT_MANAGER))
|
||||
String userrole = (String)fNodeService.getProperty(nodes.get(0), WCMAppModel.PROP_WEBUSERROLE);
|
||||
if (ROLE_CONTENT_MANAGER.equals(userrole))
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
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
|
||||
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);
|
||||
String storeName = srcPath.substring(0, srcPath.indexOf(':'));
|
||||
System.out.println(storeName);
|
||||
|
||||
if (version < 0)
|
||||
{
|
||||
version = fAVMService.createSnapshot(storeName, null, null).get(storeName);
|
||||
@@ -908,15 +908,28 @@ public class DeploymentServiceImpl implements DeploymentService
|
||||
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);
|
||||
}
|
||||
|
||||
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,
|
||||
DeploymentReport report, List<DeploymentCallback> callbacks,
|
||||
int version,
|
||||
@@ -926,9 +939,12 @@ public class DeploymentServiceImpl implements DeploymentService
|
||||
List<FileDescriptor> dstListing = service.getListing(ticket, dstPath);
|
||||
Iterator<AVMNodeDescriptor> srcIter = srcListing.values().iterator();
|
||||
Iterator<FileDescriptor> dstIter = dstListing.iterator();
|
||||
// Here with two sorted directory listings
|
||||
AVMNodeDescriptor src = 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)
|
||||
{
|
||||
@@ -944,7 +960,11 @@ public class DeploymentServiceImpl implements DeploymentService
|
||||
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)
|
||||
{
|
||||
String newDstPath = extendPath(dstPath, dst.getName());
|
||||
@@ -980,9 +1000,12 @@ public class DeploymentServiceImpl implements DeploymentService
|
||||
src = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Here with src and dst containing something
|
||||
int diff = src.getName().compareToIgnoreCase(dst.getName());
|
||||
if (diff < 0)
|
||||
{
|
||||
// src is less than dst - must be new content in src
|
||||
if (!excluded(matcher, src.getPath(), null))
|
||||
{
|
||||
copy(service, ticket, report, callbacks, version, src, dstPath, matcher);
|
||||
@@ -992,6 +1015,7 @@ public class DeploymentServiceImpl implements DeploymentService
|
||||
}
|
||||
if (diff == 0)
|
||||
{
|
||||
// src and dst have same file name
|
||||
if (src.getGuid().equals(dst.getGUID()))
|
||||
{
|
||||
src = null;
|
||||
|
@@ -22,7 +22,7 @@
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.usage;
|
||||
package org.alfresco.repo.domain;
|
||||
|
||||
import org.alfresco.repo.domain.Node;
|
||||
|
@@ -22,17 +22,21 @@
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* 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.List;
|
||||
import java.util.Set;
|
||||
|
||||
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.usage.UsageDelta;
|
||||
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.ParameterCheck;
|
||||
import org.hibernate.Query;
|
||||
import org.hibernate.Session;
|
||||
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
|
||||
{
|
||||
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_USAGE_DELTA_NODES = "usage.GetUsageDeltaNodes";
|
||||
private static final String QUERY_DELETE_DELTAS_FOR_NODE = "usage.DeleteUsageDeltasForNode";
|
||||
|
||||
/** a uuid identifying this unique instance */
|
||||
private final String uuid;
|
||||
private NodeDaoService nodeDaoService;
|
||||
|
||||
public void setNodeDaoService(NodeDaoService nodeDaoService)
|
||||
{
|
||||
this.nodeDaoService = nodeDaoService;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -120,33 +130,47 @@ public class HibernateUsageDeltaDAO extends HibernateDaoSupport implements Usage
|
||||
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")
|
||||
public int deleteDeltas(final Node node)
|
||||
public int deleteDeltas(final Long nodeId)
|
||||
{
|
||||
HibernateCallback callback = new HibernateCallback()
|
||||
{
|
||||
public Object doInHibernate(Session session)
|
||||
{
|
||||
Query query = session.getNamedQuery(QUERY_GET_DELTAS);
|
||||
query.setParameter("node", node);
|
||||
return query.list();
|
||||
Query query = session.getNamedQuery(QUERY_DELETE_DELTAS_FOR_NODE);
|
||||
query.setParameter("nodeId", nodeId);
|
||||
return query.executeUpdate();
|
||||
}
|
||||
};
|
||||
|
||||
// execute
|
||||
List<UsageDelta> queryResults = (List<UsageDelta>)getHibernateTemplate().execute(callback);
|
||||
Integer delCount = (Integer) getHibernateTemplate().execute(callback);
|
||||
|
||||
for (UsageDelta usageDelta : queryResults)
|
||||
{
|
||||
getHibernateTemplate().delete(usageDelta);
|
||||
}
|
||||
|
||||
return queryResults.size();
|
||||
return delCount.intValue();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public long getTotalDeltaSize(final Node node)
|
||||
public long getTotalDeltaSize(NodeRef nodeRef)
|
||||
{
|
||||
final Node node = getNodeNotNull(nodeRef);
|
||||
HibernateCallback callback = new HibernateCallback()
|
||||
{
|
||||
public Object doInHibernate(Session session)
|
||||
@@ -163,14 +187,21 @@ public class HibernateUsageDeltaDAO extends HibernateDaoSupport implements Usage
|
||||
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
|
||||
getSession().save(deltaInfo);
|
||||
getSession().save(delta);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Set<Node> getUsageDeltaNodes()
|
||||
public Set<NodeRef> getUsageDeltaNodes()
|
||||
{
|
||||
HibernateCallback callback = new HibernateCallback()
|
||||
{
|
||||
@@ -183,10 +214,10 @@ public class HibernateUsageDeltaDAO extends HibernateDaoSupport implements Usage
|
||||
};
|
||||
// execute read-only tx
|
||||
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)
|
||||
{
|
||||
results.add(node);
|
||||
results.add(node.getNodeRef());
|
||||
}
|
||||
return results;
|
||||
}
|
@@ -16,8 +16,8 @@
|
||||
|
||||
<!-- The Usage Delta -->
|
||||
|
||||
<class name="org.alfresco.repo.usage.hibernate.UsageDeltaImpl"
|
||||
proxy="org.alfresco.repo.usage.UsageDelta"
|
||||
<class name="org.alfresco.repo.domain.hibernate.UsageDeltaImpl"
|
||||
proxy="org.alfresco.repo.domain.UsageDelta"
|
||||
table="alf_usage_delta"
|
||||
dynamic-update="false"
|
||||
dynamic-insert="false"
|
||||
@@ -52,7 +52,7 @@
|
||||
select
|
||||
sum(deltaSize)
|
||||
from
|
||||
org.alfresco.repo.usage.hibernate.UsageDeltaImpl as usage_delta
|
||||
org.alfresco.repo.domain.hibernate.UsageDeltaImpl as usage_delta
|
||||
where
|
||||
usage_delta.node = :node
|
||||
</query>
|
||||
@@ -63,7 +63,7 @@
|
||||
select
|
||||
distinct usage_delta.node
|
||||
from
|
||||
org.alfresco.repo.usage.hibernate.UsageDeltaImpl as usage_delta
|
||||
org.alfresco.repo.domain.hibernate.UsageDeltaImpl as usage_delta
|
||||
</query>
|
||||
|
||||
<!-- Get usage deltas for a node -->
|
||||
@@ -71,9 +71,17 @@
|
||||
select
|
||||
usage_delta
|
||||
from
|
||||
org.alfresco.repo.usage.hibernate.UsageDeltaImpl as usage_delta
|
||||
org.alfresco.repo.domain.hibernate.UsageDeltaImpl as usage_delta
|
||||
where
|
||||
usage_delta.node = :node
|
||||
</query>
|
||||
|
||||
<query name="usage.DeleteUsageDeltasForNode">
|
||||
delete
|
||||
from
|
||||
org.alfresco.repo.domain.hibernate.UsageDeltaImpl as usage
|
||||
where
|
||||
usage.node.id = :nodeId
|
||||
</query>
|
||||
|
||||
</hibernate-mapping>
|
@@ -22,10 +22,10 @@
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* 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.usage.UsageDelta;
|
||||
import org.alfresco.repo.domain.UsageDelta;
|
||||
|
||||
/**
|
||||
* Usage Delta Implementation
|
@@ -684,7 +684,7 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
|
||||
{
|
||||
logger.debug("Deleting usage deltas of node (if any)" + node.getId());
|
||||
}
|
||||
usageDeltaDao.deleteDeltas(node);
|
||||
usageDeltaDao.deleteDeltas(node.getId());
|
||||
|
||||
// update the node status
|
||||
NodeRef nodeRef = node.getNodeRef();
|
||||
|
@@ -123,7 +123,7 @@ public class MissingContentReindexComponent extends AbstractReindexComponent
|
||||
return null;
|
||||
}
|
||||
};
|
||||
transactionService.getRetryingTransactionHelper().doInTransaction(reindexWork);
|
||||
transactionService.getRetryingTransactionHelper().doInTransaction(reindexWork, true);
|
||||
count++;
|
||||
// check if we have to break out
|
||||
if (isShuttingDown())
|
||||
|
@@ -355,12 +355,7 @@ public class RuleServiceImpl implements RuleService, RuntimeRuleService
|
||||
{
|
||||
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 &&
|
||||
permissionService.hasPermission(nodeRef, PermissionService.CONSUMER) == AccessStatus.ALLOWED)
|
||||
if (this.runtimeNodeService.exists(nodeRef) == true && checkNodeType(nodeRef) == true)
|
||||
{
|
||||
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);
|
||||
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";
|
||||
|
||||
/**
|
||||
* @return the reference <b>with</b> the tenant-specific ID attached
|
||||
*/
|
||||
public NodeRef getName(NodeRef nodeRef);
|
||||
|
||||
/**
|
||||
* @return the reference <b>with</b> the tenant-specific ID attached
|
||||
*/
|
||||
public NodeRef getName(NodeRef inNodeRef, NodeRef nodeRef);
|
||||
|
||||
/**
|
||||
* @return the reference <b>with</b> the tenant-specific ID attached
|
||||
*/
|
||||
public StoreRef getName(StoreRef storeRef);
|
||||
|
||||
/**
|
||||
* @return the reference <b>with</b> the tenant-specific ID attached
|
||||
*/
|
||||
public ChildAssociationRef getName(ChildAssociationRef childAssocRef);
|
||||
|
||||
/**
|
||||
* @return the reference <b>with</b> the tenant-specific ID attached
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* @return the reference <b>with</b> the tenant-specific ID attached
|
||||
*/
|
||||
public String getName(String name);
|
||||
|
||||
/**
|
||||
* @return the reference <b>without</b> the tenant-specific ID attached
|
||||
*/
|
||||
public QName getBaseName(QName name, boolean forceIfNonTenant);
|
||||
|
||||
/**
|
||||
* @return the reference <b>without</b> the tenant-specific ID attached
|
||||
*/
|
||||
public NodeRef getBaseName(NodeRef nodeRef);
|
||||
|
||||
/**
|
||||
* @return the reference <b>without</b> the tenant-specific ID attached
|
||||
*/
|
||||
public StoreRef getBaseName(StoreRef storeRef);
|
||||
|
||||
/**
|
||||
* @return the reference <b>without</b> the tenant-specific ID attached
|
||||
*/
|
||||
public ChildAssociationRef getBaseName(ChildAssociationRef childAssocRef);
|
||||
|
||||
/**
|
||||
* @return the reference <b>without</b> the tenant-specific ID attached
|
||||
*/
|
||||
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 getBaseNameUser(String name);
|
||||
|
@@ -26,7 +26,7 @@ package org.alfresco.repo.usage;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.repo.domain.Node;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
|
||||
/**
|
||||
* The interface to persist usage delta information.
|
||||
@@ -37,20 +37,21 @@ public interface UsageDeltaDAO
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param node
|
||||
* @param nodeRef the node reference
|
||||
* @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;
|
||||
|
||||
import java.util.HashSet;
|
||||
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.usage.UsageService;
|
||||
import org.alfresco.util.ParameterCheck;
|
||||
|
||||
/**
|
||||
* The implementation of the UsageService for tracking usages.
|
||||
*
|
||||
* @author Jan Vonka
|
||||
* @since 2.9
|
||||
*/
|
||||
public class UsageServiceImpl implements UsageService
|
||||
{
|
||||
private UsageDeltaDAO usageDeltaDao;
|
||||
private NodeDaoService nodeDaoService;
|
||||
|
||||
public void setUsageDeltaDao(UsageDeltaDAO usageDeltaDao)
|
||||
{
|
||||
this.usageDeltaDao = usageDeltaDao;
|
||||
}
|
||||
|
||||
public void setNodeDaoService(NodeDaoService nodeDaoService)
|
||||
{
|
||||
this.nodeDaoService = nodeDaoService;
|
||||
}
|
||||
|
||||
|
||||
public void insertDelta(NodeRef usageNodeRef, long deltaSize)
|
||||
{
|
||||
UsageDelta delta = new UsageDeltaImpl();
|
||||
|
||||
// delta properties
|
||||
delta.setNode(getNodeNotNull(usageNodeRef));
|
||||
delta.setDeltaSize(deltaSize);
|
||||
|
||||
usageDeltaDao.insertDelta(delta);
|
||||
usageDeltaDao.insertDelta(usageNodeRef, deltaSize);
|
||||
}
|
||||
|
||||
public long getTotalDeltaSize(NodeRef usageNodeRef)
|
||||
{
|
||||
return usageDeltaDao.getTotalDeltaSize(getNodeNotNull(usageNodeRef));
|
||||
return usageDeltaDao.getTotalDeltaSize(usageNodeRef);
|
||||
}
|
||||
|
||||
public Set<NodeRef> getUsageDeltaNodes()
|
||||
{
|
||||
Set<Node> nodes = 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;
|
||||
return usageDeltaDao.getUsageDeltaNodes();
|
||||
}
|
||||
|
||||
public int deleteDeltas(NodeRef usageNodeRef)
|
||||
{
|
||||
return usageDeltaDao.deleteDeltas(getNodeNotNull(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;
|
||||
return usageDeltaDao.deleteDeltas(usageNodeRef);
|
||||
}
|
||||
}
|
||||
|
@@ -33,6 +33,8 @@ import org.alfresco.service.cmr.repository.NodeRef;
|
||||
/**
|
||||
* The public API by which applications can create usage delta entries.
|
||||
*
|
||||
* @author Jan Vonka
|
||||
* @since 2.9
|
||||
*/
|
||||
@PublicService
|
||||
public interface UsageService
|
||||
|
Reference in New Issue
Block a user