mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Massive renaming. Delegate/Delegation becomes Referrer, Referent and things *do* make a little more sense.
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/BRANCHES/classified_renditions@111633 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -1,123 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8'?>
|
|
||||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xmlns:aop="http://www.springframework.org/schema/aop"
|
|
||||||
xmlns:context="http://www.springframework.org/schema/context"
|
|
||||||
xsi:schemaLocation="
|
|
||||||
http://www.springframework.org/schema/context
|
|
||||||
http://www.springframework.org/schema/context/spring-context-3.0.xsd
|
|
||||||
http://www.springframework.org/schema/beans
|
|
||||||
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
|
||||||
http://www.springframework.org/schema/aop
|
|
||||||
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
|
|
||||||
|
|
||||||
<!-- Metadata Delegation Service -->
|
|
||||||
<bean id="delegationAdminService"
|
|
||||||
class="org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationAdminServiceImpl" >
|
|
||||||
<property name="delegationRegistry" ref="delegationRegistry" />
|
|
||||||
<property name="nodeService" ref="NodeService" />
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="DelegationAdminService" class="org.springframework.aop.framework.ProxyFactoryBean">
|
|
||||||
<property name="proxyInterfaces">
|
|
||||||
<value>org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationAdminService</value>
|
|
||||||
</property>
|
|
||||||
<property name="target">
|
|
||||||
<ref bean="delegationAdminService"/>
|
|
||||||
</property>
|
|
||||||
<property name="interceptorNames">
|
|
||||||
<list>
|
|
||||||
<idref local="DelegationAdminService_transaction"/>
|
|
||||||
<idref bean="exceptionTranslator"/>
|
|
||||||
<idref local="DelegationAdminService_security"/>
|
|
||||||
</list>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="DelegationAdminService_transaction" class="org.springframework.transaction.interceptor.TransactionInterceptor">
|
|
||||||
<property name="transactionManager">
|
|
||||||
<ref bean="transactionManager"/>
|
|
||||||
</property>
|
|
||||||
<property name="transactionAttributes">
|
|
||||||
<props>
|
|
||||||
<prop key="*">${server.transaction.mode.default}</prop>
|
|
||||||
</props>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="DelegationAdminService_security" parent="baseSecurity">
|
|
||||||
<property name="objectDefinitionSource">
|
|
||||||
<value>
|
|
||||||
org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationAdminService.attachDelegate=ACL_ALLOW
|
|
||||||
org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationAdminService.detachDelegate=ACL_ALLOW
|
|
||||||
org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationAdminService.getDefinedDelegations=ACL_ALLOW
|
|
||||||
org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationAdminService.getDelegationFor=ACL_ALLOW
|
|
||||||
org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationAdminService.getDelegationsFrom=ACL_ALLOW
|
|
||||||
org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationAdminService.*=ACL_DENY
|
|
||||||
</value>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Metadata Delegation Service -->
|
|
||||||
<bean id="delegationService"
|
|
||||||
class="org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationServiceImpl" >
|
|
||||||
<property name="delegationAdminService" ref="DelegationAdminService" />
|
|
||||||
<property name="dictionaryService" ref="dictionaryService" />
|
|
||||||
<property name="nodeService" ref="NodeService" />
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="DelegationService" class="org.springframework.aop.framework.ProxyFactoryBean">
|
|
||||||
<property name="proxyInterfaces">
|
|
||||||
<value>org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationService</value>
|
|
||||||
</property>
|
|
||||||
<property name="target">
|
|
||||||
<ref bean="delegationService"/>
|
|
||||||
</property>
|
|
||||||
<property name="interceptorNames">
|
|
||||||
<list>
|
|
||||||
<idref local="DelegationService_transaction"/>
|
|
||||||
<idref bean="exceptionTranslator"/>
|
|
||||||
<idref local="DelegationService_security"/>
|
|
||||||
</list>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="DelegationService_transaction" class="org.springframework.transaction.interceptor.TransactionInterceptor">
|
|
||||||
<property name="transactionManager">
|
|
||||||
<ref bean="transactionManager"/>
|
|
||||||
</property>
|
|
||||||
<property name="transactionAttributes">
|
|
||||||
<props>
|
|
||||||
<prop key="*">${server.transaction.mode.default}</prop>
|
|
||||||
</props>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="DelegationService_security" parent="baseSecurity">
|
|
||||||
<property name="objectDefinitionSource">
|
|
||||||
<value>
|
|
||||||
org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationService.hasDelegateForAspect=ACL_ALLOW
|
|
||||||
org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationService.getDelegateFor=ACL_ALLOW
|
|
||||||
org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationService.getDelegateProperties=ACL_ALLOW
|
|
||||||
org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationService.getDelegateProperty=ACL_ALLOW
|
|
||||||
org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationService.hasAspectOnDelegate=ACL_ALLOW
|
|
||||||
org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationService.getDelegations=ACL_ALLOW
|
|
||||||
org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationService.*=ACL_DENY
|
|
||||||
</value>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean name="delegationRegistry"
|
|
||||||
class="org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationRegistry">
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean name="baseDelegateAssoc"
|
|
||||||
abstract="true"
|
|
||||||
class="org.alfresco.module.org_alfresco_module_rm.metadatadelegation.Delegation"
|
|
||||||
init-method="validateAndRegister">
|
|
||||||
<property name="delegationRegistry" ref="delegationRegistry" />
|
|
||||||
<property name="dictionaryService" ref="dictionaryService" />
|
|
||||||
</bean>
|
|
||||||
</beans>
|
|
@@ -0,0 +1,123 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:aop="http://www.springframework.org/schema/aop"
|
||||||
|
xmlns:context="http://www.springframework.org/schema/context"
|
||||||
|
xsi:schemaLocation="
|
||||||
|
http://www.springframework.org/schema/context
|
||||||
|
http://www.springframework.org/schema/context/spring-context-3.0.xsd
|
||||||
|
http://www.springframework.org/schema/beans
|
||||||
|
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||||
|
http://www.springframework.org/schema/aop
|
||||||
|
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
|
||||||
|
|
||||||
|
<!-- Metadata Referral Admin Service -->
|
||||||
|
<bean id="referralAdminService"
|
||||||
|
class="org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferralAdminServiceImpl" >
|
||||||
|
<property name="referralRegistry" ref="referralRegistry" />
|
||||||
|
<property name="nodeService" ref="NodeService" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="ReferralAdminService" class="org.springframework.aop.framework.ProxyFactoryBean">
|
||||||
|
<property name="proxyInterfaces">
|
||||||
|
<value>org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferralAdminService</value>
|
||||||
|
</property>
|
||||||
|
<property name="target">
|
||||||
|
<ref bean="referralAdminService"/>
|
||||||
|
</property>
|
||||||
|
<property name="interceptorNames">
|
||||||
|
<list>
|
||||||
|
<idref local="ReferralAdminService_transaction"/>
|
||||||
|
<idref bean="exceptionTranslator"/>
|
||||||
|
<idref local="ReferralAdminService_security"/>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="ReferralAdminService_transaction" class="org.springframework.transaction.interceptor.TransactionInterceptor">
|
||||||
|
<property name="transactionManager">
|
||||||
|
<ref bean="transactionManager"/>
|
||||||
|
</property>
|
||||||
|
<property name="transactionAttributes">
|
||||||
|
<props>
|
||||||
|
<prop key="*">${server.transaction.mode.default}</prop>
|
||||||
|
</props>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="ReferralAdminService_security" parent="baseSecurity">
|
||||||
|
<property name="objectDefinitionSource">
|
||||||
|
<value>
|
||||||
|
org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferralAdminService.attachReferrer=ACL_ALLOW
|
||||||
|
org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferralAdminService.detachReferrer=ACL_ALLOW
|
||||||
|
org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferralAdminService.getDefinedReferrals=ACL_ALLOW
|
||||||
|
org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferralAdminService.getReferralFor=ACL_ALLOW
|
||||||
|
org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferralAdminService.getAttachedReferralsFrom=ACL_ALLOW
|
||||||
|
org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferralAdminService.*=ACL_DENY
|
||||||
|
</value>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Referred Metadata Service -->
|
||||||
|
<bean id="referredMetadataService"
|
||||||
|
class="org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferredMetadataServiceImpl" >
|
||||||
|
<property name="referralAdminService" ref="ReferralAdminService" />
|
||||||
|
<property name="dictionaryService" ref="dictionaryService" />
|
||||||
|
<property name="nodeService" ref="NodeService" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="ReferredMetadataService" class="org.springframework.aop.framework.ProxyFactoryBean">
|
||||||
|
<property name="proxyInterfaces">
|
||||||
|
<value>org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferredMetadataService</value>
|
||||||
|
</property>
|
||||||
|
<property name="target">
|
||||||
|
<ref bean="referredMetadataService"/>
|
||||||
|
</property>
|
||||||
|
<property name="interceptorNames">
|
||||||
|
<list>
|
||||||
|
<idref local="ReferredMetadataService_transaction"/>
|
||||||
|
<idref bean="exceptionTranslator"/>
|
||||||
|
<idref local="ReferredMetadataService_security"/>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="ReferredMetadataService_transaction" class="org.springframework.transaction.interceptor.TransactionInterceptor">
|
||||||
|
<property name="transactionManager">
|
||||||
|
<ref bean="transactionManager"/>
|
||||||
|
</property>
|
||||||
|
<property name="transactionAttributes">
|
||||||
|
<props>
|
||||||
|
<prop key="*">${server.transaction.mode.default}</prop>
|
||||||
|
</props>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="ReferredMetadataService_security" parent="baseSecurity">
|
||||||
|
<property name="objectDefinitionSource">
|
||||||
|
<value>
|
||||||
|
org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferredMetadataService.isReferringMetadata=ACL_ALLOW
|
||||||
|
org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferredMetadataService.getReferentNode=ACL_ALLOW
|
||||||
|
org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferredMetadataService.getReferredProperties=ACL_ALLOW
|
||||||
|
org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferredMetadataService.getReferredProperty=ACL_ALLOW
|
||||||
|
org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferredMetadataService.hasReferredAspect=ACL_ALLOW
|
||||||
|
org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferredMetadataService.getAttachedReferrals=ACL_ALLOW
|
||||||
|
org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferredMetadataService.*=ACL_DENY
|
||||||
|
</value>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean name="referralRegistry"
|
||||||
|
class="org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferralRegistry">
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean name="baseReferralAssoc"
|
||||||
|
abstract="true"
|
||||||
|
class="org.alfresco.module.org_alfresco_module_rm.referredmetadata.MetadataReferral"
|
||||||
|
init-method="validateAndRegister">
|
||||||
|
<property name="referralRegistry" ref="referralRegistry" />
|
||||||
|
<property name="dictionaryService" ref="dictionaryService" />
|
||||||
|
</bean>
|
||||||
|
</beans>
|
@@ -267,8 +267,8 @@
|
|||||||
<!-- Import the RM webscript's -->
|
<!-- Import the RM webscript's -->
|
||||||
<import resource="classpath:alfresco/module/org_alfresco_module_rm/rm-webscript-context.xml"/>
|
<import resource="classpath:alfresco/module/org_alfresco_module_rm/rm-webscript-context.xml"/>
|
||||||
|
|
||||||
<!-- Import the Metadata Delegation Services -->
|
<!-- Import the Metadata Referral Services -->
|
||||||
<import resource="classpath:alfresco/module/org_alfresco_module_rm/metadata-delegation-context.xml"/>
|
<import resource="classpath:alfresco/module/org_alfresco_module_rm/metadata-referral-context.xml"/>
|
||||||
|
|
||||||
<!-- Import the Classified Content Services -->
|
<!-- Import the Classified Content Services -->
|
||||||
<import resource="classpath:alfresco/module/org_alfresco_module_rm/classified-content-context.xml"/>
|
<import resource="classpath:alfresco/module/org_alfresco_module_rm/classified-content-context.xml"/>
|
||||||
|
@@ -1,92 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2005-2015 Alfresco Software Limited.
|
|
||||||
*
|
|
||||||
* This file is part of Alfresco
|
|
||||||
*
|
|
||||||
* Alfresco is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Alfresco is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.alfresco.module.org_alfresco_module_rm.metadatadelegation;
|
|
||||||
|
|
||||||
import static org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationException.ChainedDelegationUnsupported;
|
|
||||||
|
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
|
||||||
import org.alfresco.service.namespace.QName;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A service to manage the delegation of aspect metadata.
|
|
||||||
* Using this service a node can be {@link #attachDelegate linked} to a delegate node for a configured set of aspects.
|
|
||||||
* (Note that this delegate node must already exist within the database.)
|
|
||||||
* Then any read request for relevant metadata such as hasAspect or getProperties can be delegated to the
|
|
||||||
* linked node.
|
|
||||||
* <p/>
|
|
||||||
* For a link to be made, there must be a {@link #getDefinedDelegations() defined Delegation} already in the system.
|
|
||||||
* This means that a peer-association type will have to have been declared and that a spring bean will have to have
|
|
||||||
* defined which aspects are to be handled by this {@code Delegation}.
|
|
||||||
*
|
|
||||||
* @author Neil Mc Erlean
|
|
||||||
* @since 3.0.a
|
|
||||||
*/
|
|
||||||
public interface DelegationAdminService
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Creates a link between two nodes such that the first {@code nodeRef} can 'inherit' or reuse some aspect
|
|
||||||
* metadata from another node - the {@code delegateNodeRef}.
|
|
||||||
* <p/>
|
|
||||||
* Note that links can currently only extend between two pairs of nodes and cannot be chained.
|
|
||||||
*
|
|
||||||
* @param nodeRef the node which is to inherit additional metadata.
|
|
||||||
* @param delegateNodeRef the node which will provide the additional metadata.
|
|
||||||
* @param assocType the type of the peer association which will link the two nodes.
|
|
||||||
* @return a {@link Delegation} object which defines the link type.
|
|
||||||
* @throws ChainedDelegationUnsupported if an attempt is made to attach nodes such that a chain would be made.
|
|
||||||
*/
|
|
||||||
Delegation attachDelegate(NodeRef nodeRef, NodeRef delegateNodeRef, QName assocType);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes an existing metadata delegation link between two nodes.
|
|
||||||
*
|
|
||||||
* @param nodeRef the node which has been linked to a delegate.
|
|
||||||
* @param assocType the type of the peer assocation forming the link.
|
|
||||||
* @return the removed {@link Delegation}.
|
|
||||||
*/
|
|
||||||
Delegation detachDelegate(NodeRef nodeRef, QName assocType);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the set of defined {@link Delegation}s.
|
|
||||||
*
|
|
||||||
* @return the set of defined Delegations.
|
|
||||||
*/
|
|
||||||
Set<Delegation> getDefinedDelegations();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the {@link Delegation} which contains the specified {@code aspectName} if there is one.
|
|
||||||
* Note that only one {@link Delegation} may declare that it handles any particular aspect.
|
|
||||||
*
|
|
||||||
* @param aspectName the name of the aspect whose {@link Delegation} is sought.
|
|
||||||
* @return the {@link Delegation} which handles the specified aspect, if there is one.
|
|
||||||
*/
|
|
||||||
Delegation getDelegationFor(QName aspectName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the set of {@link Delegation}s which are in effect from the specified {@code nodeRef}.
|
|
||||||
* From these, you can retrieve the types of peer associations which are linked to the specified
|
|
||||||
* {@code nodeRef} as well as the aspect types that are handled.
|
|
||||||
*
|
|
||||||
* @param nodeRef the NodeRef whose delegations are sought.
|
|
||||||
* @return the set of {@link Delegation}s from the specified nodeRef.
|
|
||||||
*/
|
|
||||||
Set<Delegation> getDelegationsFrom(NodeRef nodeRef);
|
|
||||||
}
|
|
@@ -1,167 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2005-2015 Alfresco Software Limited.
|
|
||||||
*
|
|
||||||
* This file is part of Alfresco
|
|
||||||
*
|
|
||||||
* Alfresco is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Alfresco is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.alfresco.module.org_alfresco_module_rm.metadatadelegation;
|
|
||||||
|
|
||||||
import static org.alfresco.util.collections.CollectionUtils.transform;
|
|
||||||
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationException.ChainedDelegationUnsupported;
|
|
||||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
|
||||||
import org.alfresco.service.namespace.QName;
|
|
||||||
import org.alfresco.util.collections.Function;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Neil Mc Erlean
|
|
||||||
* @since 3.0.a
|
|
||||||
*/
|
|
||||||
public class DelegationAdminServiceImpl implements DelegationAdminService
|
|
||||||
{
|
|
||||||
private DelegationRegistry registry;
|
|
||||||
private NodeService nodeService;
|
|
||||||
|
|
||||||
public void setNodeService(NodeService service)
|
|
||||||
{
|
|
||||||
this.nodeService = service;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDelegationRegistry(DelegationRegistry registry)
|
|
||||||
{
|
|
||||||
this.registry = registry;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public Delegation attachDelegate(NodeRef nodeRef, NodeRef delegateNodeRef, QName assocType)
|
|
||||||
{
|
|
||||||
final Delegation delegation = getDelegationForAssociation(assocType);
|
|
||||||
|
|
||||||
// Prevent the creation of chains of delegation from node A to B to C.
|
|
||||||
|
|
||||||
// If any nodes are already delegating to nodeRef for the specified assoc, then we can't chain.
|
|
||||||
final List<AssociationRef> existingDelegatorAssocs = nodeService.getSourceAssocs(nodeRef, assocType);
|
|
||||||
if ( !existingDelegatorAssocs.isEmpty())
|
|
||||||
{
|
|
||||||
final List<NodeRef> existingDelegators = transform(existingDelegatorAssocs,
|
|
||||||
new Function<AssociationRef, NodeRef>()
|
|
||||||
{
|
|
||||||
@Override public NodeRef apply(AssociationRef assocRef)
|
|
||||||
{
|
|
||||||
return assocRef.getSourceRef();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
throw new ChainedDelegationUnsupported("Cannot attach delegate", existingDelegators);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Likewise if this delegate node is already itself delegating elsewhere, we cannot chain.
|
|
||||||
final List<AssociationRef> existingDelegateAssocs = nodeService.getTargetAssocs(delegateNodeRef, assocType);
|
|
||||||
if ( !existingDelegateAssocs.isEmpty())
|
|
||||||
{
|
|
||||||
// If it's not empty, it should only have one value in it, but just in case...
|
|
||||||
final List<NodeRef> existingDelegates = transform(existingDelegateAssocs,
|
|
||||||
new Function<AssociationRef, NodeRef>()
|
|
||||||
{
|
|
||||||
@Override public NodeRef apply(AssociationRef assocRef)
|
|
||||||
{
|
|
||||||
return assocRef.getTargetRef();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
throw new ChainedDelegationUnsupported("Cannot attach delegate", existingDelegates);
|
|
||||||
}
|
|
||||||
|
|
||||||
// OK. We're good to go. We're not making a chain here.
|
|
||||||
nodeService.createAssociation(nodeRef, delegateNodeRef, assocType);
|
|
||||||
|
|
||||||
return delegation;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Delegation getDelegationForAssociation(QName assocType)
|
|
||||||
{
|
|
||||||
final Delegation delegation = registry.getDelegateForAssociation(assocType);
|
|
||||||
|
|
||||||
if (delegation == null)
|
|
||||||
{
|
|
||||||
throw new IllegalArgumentException("No " + Delegation.class.getSimpleName() +
|
|
||||||
" configured for assocType " + assocType);
|
|
||||||
}
|
|
||||||
return delegation;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public Delegation detachDelegate(NodeRef nodeRef, QName assocType)
|
|
||||||
{
|
|
||||||
// Is the association there?
|
|
||||||
final List<AssociationRef> assocs = nodeService.getTargetAssocs(nodeRef, assocType);
|
|
||||||
|
|
||||||
if (assocs == null || assocs.isEmpty())
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Delegation result = getDelegationForAssociation(assocType);
|
|
||||||
|
|
||||||
// There should only be one such association... but we'll remove them all just in case
|
|
||||||
for (AssociationRef assocRef : assocs)
|
|
||||||
{
|
|
||||||
nodeService.removeAssociation(nodeRef, assocRef.getTargetRef(), assocType);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public Delegation getDelegationFor(QName aspectName)
|
|
||||||
{
|
|
||||||
Delegation delegation = null;
|
|
||||||
|
|
||||||
for (Delegation d : getDefinedDelegations())
|
|
||||||
{
|
|
||||||
if (d.getAspects().contains(aspectName))
|
|
||||||
{
|
|
||||||
delegation = d;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return delegation;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public Set<Delegation> getDelegationsFrom(NodeRef nodeRef)
|
|
||||||
{
|
|
||||||
final Set<Delegation> allDelegations = getDefinedDelegations();
|
|
||||||
|
|
||||||
final Set<Delegation> result = new HashSet<>();
|
|
||||||
for (Delegation d : allDelegations)
|
|
||||||
{
|
|
||||||
final QName assocType = d.getAssocType();
|
|
||||||
if ( !nodeService.getTargetAssocs(nodeRef, assocType).isEmpty())
|
|
||||||
{
|
|
||||||
result.add(d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public Set<Delegation> getDefinedDelegations()
|
|
||||||
{
|
|
||||||
return registry.getDelegations();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,107 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2005-2015 Alfresco Software Limited.
|
|
||||||
*
|
|
||||||
* This file is part of Alfresco
|
|
||||||
*
|
|
||||||
* Alfresco is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Alfresco is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.alfresco.module.org_alfresco_module_rm.metadatadelegation;
|
|
||||||
|
|
||||||
import org.alfresco.error.AlfrescoRuntimeException;
|
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generic class for any runtime exceptions related to metadata delegates.
|
|
||||||
*
|
|
||||||
* @author Neil Mc Erlean
|
|
||||||
* @since 3.0.a
|
|
||||||
*/
|
|
||||||
public class DelegationException extends AlfrescoRuntimeException
|
|
||||||
{
|
|
||||||
public DelegationException(String msgId) { super(msgId); }
|
|
||||||
public DelegationException(String msgId, Throwable cause) { super(msgId, cause); }
|
|
||||||
|
|
||||||
public static class InvalidDelegation extends DelegationException
|
|
||||||
{
|
|
||||||
public InvalidDelegation(String msgId)
|
|
||||||
{
|
|
||||||
super(msgId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** A Metadata Delegation already exists. */
|
|
||||||
public static class DelegationAlreadyExists extends DelegationException
|
|
||||||
{
|
|
||||||
private final Delegation delegation;
|
|
||||||
|
|
||||||
public DelegationAlreadyExists(String msgId, Delegation delegation)
|
|
||||||
{
|
|
||||||
super(msgId);
|
|
||||||
this.delegation = delegation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A {@link Delegation} has not been found.
|
|
||||||
* Remember that a Delegation is the definition of a type of link.
|
|
||||||
*/
|
|
||||||
public static class DelegationNotFound extends DelegationException
|
|
||||||
{
|
|
||||||
public DelegationNotFound(String msgId)
|
|
||||||
{
|
|
||||||
super(msgId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A Delegate has not been found.
|
|
||||||
* Remember that a Delegate is an instance of a link between two nodes.
|
|
||||||
*/
|
|
||||||
public static class DelegateNotFound extends DelegationException
|
|
||||||
{
|
|
||||||
public DelegateNotFound(String msgId)
|
|
||||||
{
|
|
||||||
super(msgId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Exception to report that we currently do not support chained delegation.
|
|
||||||
*/
|
|
||||||
public static class ChainedDelegationUnsupported extends DelegationException
|
|
||||||
{
|
|
||||||
private final List<NodeRef> nodesAlreadyDelegating;
|
|
||||||
|
|
||||||
public ChainedDelegationUnsupported(String msgId, List<NodeRef> nodesAlreadyDelegating)
|
|
||||||
{
|
|
||||||
super(msgId);
|
|
||||||
this.nodesAlreadyDelegating = nodesAlreadyDelegating;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<NodeRef> getNodesAlreadyDelegating()
|
|
||||||
{
|
|
||||||
return this.nodesAlreadyDelegating;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public String toString()
|
|
||||||
{
|
|
||||||
StringBuilder msg = new StringBuilder();
|
|
||||||
msg.append(this.getClass().getSimpleName()).append(" Already delegating from: ")
|
|
||||||
.append(nodesAlreadyDelegating.toString());
|
|
||||||
return msg.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,85 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2005-2015 Alfresco Software Limited.
|
|
||||||
*
|
|
||||||
* This file is part of Alfresco
|
|
||||||
*
|
|
||||||
* Alfresco is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Alfresco is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.alfresco.module.org_alfresco_module_rm.metadatadelegation;
|
|
||||||
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationException.DelegationAlreadyExists;
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationException.InvalidDelegation;
|
|
||||||
import org.alfresco.service.namespace.QName;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a registry of {@link Delegation delegations} which have been defined in the system.
|
|
||||||
*
|
|
||||||
* @author Neil Mc Erlean
|
|
||||||
* @since 3.0.a
|
|
||||||
*/
|
|
||||||
public class DelegationRegistry
|
|
||||||
{
|
|
||||||
private final Set<Delegation> delegations = new HashSet<>();
|
|
||||||
|
|
||||||
public void register(Delegation delegation)
|
|
||||||
{
|
|
||||||
// Various validation steps to do here to ensure we get consistent, sensible Delegations registered.
|
|
||||||
if (delegations.contains(delegation))
|
|
||||||
{
|
|
||||||
throw new DelegationAlreadyExists("Cannot register duplicate delegation", delegation);
|
|
||||||
}
|
|
||||||
for (Delegation existingDelegation : delegations)
|
|
||||||
{
|
|
||||||
if (existingDelegation.getAssocType().equals(delegation.getAssocType()))
|
|
||||||
{
|
|
||||||
throw new InvalidDelegation("Cannot register two delegations with the same assocType. " +
|
|
||||||
"Existing: " + existingDelegation +
|
|
||||||
" New: " + delegation);
|
|
||||||
}
|
|
||||||
// Yes this is a for loop inside a for loop but we're assuming these sets will not be large.
|
|
||||||
for (QName existingAspect : existingDelegation.getAspects())
|
|
||||||
{
|
|
||||||
if (delegation.getAspects().contains(existingAspect))
|
|
||||||
{
|
|
||||||
throw new InvalidDelegation("Cannot register two delegations with the same aspect. " +
|
|
||||||
"Existing: " + existingDelegation +
|
|
||||||
" New: " + delegation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.delegations.add(delegation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<Delegation> getDelegations()
|
|
||||||
{
|
|
||||||
return Collections.unmodifiableSet(delegations);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Delegation getDelegateForAssociation(QName assocType)
|
|
||||||
{
|
|
||||||
for (Delegation d : delegations)
|
|
||||||
{
|
|
||||||
if (d.getAssocType().equals(assocType))
|
|
||||||
{
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,96 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2005-2015 Alfresco Software Limited.
|
|
||||||
*
|
|
||||||
* This file is part of Alfresco
|
|
||||||
*
|
|
||||||
* Alfresco is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Alfresco is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.alfresco.module.org_alfresco_module_rm.metadatadelegation;
|
|
||||||
|
|
||||||
import static org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationException.DelegationNotFound;
|
|
||||||
|
|
||||||
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
|
||||||
import org.alfresco.service.namespace.QName;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This service provides read-only access to delegated metadata.
|
|
||||||
* TODO complete.
|
|
||||||
*
|
|
||||||
* @author Neil Mc Erlean
|
|
||||||
* @since 3.0.a
|
|
||||||
*/
|
|
||||||
public interface DelegationService
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Checks if the specified nodeRef has an attached {@link Delegation} for the specified aspect.
|
|
||||||
*
|
|
||||||
* @param nodeRef the nodeRef which may or may not have a delegate node for the specified aspect.
|
|
||||||
* @param aspectName the name of the aspect for which the node may or may not have delegation.
|
|
||||||
* @return whether the node is delegating metadata reads for the specified aspect.
|
|
||||||
* @throws InvalidNodeRefException if the supplied nodeRef does not exist.
|
|
||||||
* @throws DelegationNotFound if no delegation for the specified aspect has been attached.
|
|
||||||
*/
|
|
||||||
boolean hasDelegateForAspect(NodeRef nodeRef, QName aspectName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the delegate node for the specified aspect, if there is one.
|
|
||||||
*
|
|
||||||
* @param nodeRef the node with the delegate.
|
|
||||||
* @param aspectName the aspect name.
|
|
||||||
* @return the nodeRef of the delegate if there is one, else {@code null}.
|
|
||||||
* @throws DelegationNotFound if no delegation for the specified aspect has been attached.
|
|
||||||
*/
|
|
||||||
NodeRef getDelegateFor(NodeRef nodeRef, QName aspectName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets all the property values from the delegate node for the specified aspect.
|
|
||||||
*
|
|
||||||
* @param nodeRef the node with the delegate.
|
|
||||||
* @param aspectName the aspect name which holds the properties we want.
|
|
||||||
* @return the property values as obtained from the delegate node.
|
|
||||||
*/
|
|
||||||
Map<QName, Serializable> getDelegateProperties(NodeRef nodeRef, QName aspectName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the specified property value from the delegate node.
|
|
||||||
*
|
|
||||||
* @param nodeRef the node with the delegate.
|
|
||||||
* @param propertyName the property name which we want.
|
|
||||||
* @return the property value as obtained from the delegate node.
|
|
||||||
*/
|
|
||||||
Serializable getDelegateProperty(NodeRef nodeRef, QName propertyName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines if a given aspect is present on a node's delegates.
|
|
||||||
*
|
|
||||||
* @param nodeRef the node for which a delegate is sought.
|
|
||||||
* @param aspectName the aspect which is to be checked.
|
|
||||||
* @return Returns true if the aspect has been applied to one of the given node's delegates,
|
|
||||||
* otherwise false
|
|
||||||
*/
|
|
||||||
boolean hasAspectOnDelegate(NodeRef nodeRef, QName aspectName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets all {@link Delegation delegations} currently attached to the specified node.
|
|
||||||
*
|
|
||||||
* @param nodeRef the node whose delegations are sought.
|
|
||||||
* @return Returns a map of all {@link Delegation delegations} by NodeRef for the specified nodeRef.
|
|
||||||
*/
|
|
||||||
Map<Delegation, NodeRef> getDelegations(NodeRef nodeRef);
|
|
||||||
}
|
|
||||||
|
|
@@ -16,9 +16,9 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.alfresco.module.org_alfresco_module_rm.metadatadelegation;
|
package org.alfresco.module.org_alfresco_module_rm.referredmetadata;
|
||||||
|
|
||||||
import org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationException.InvalidDelegation;
|
import org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferredMetadataException.InvalidMetadataReferral;
|
||||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
@@ -27,27 +27,29 @@ import java.util.Objects;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Delegation is a definition of a {@link #aspects set of aspects} whose metadata are to be delegated.
|
* A {@link MetadataReferral} is a definition of a {@link #aspects set of metadata} which are, in effect, shared
|
||||||
* Using a Delegation, you can attach a delegate node to any node and {@code hasAspect} and
|
* between multiple nodes.
|
||||||
* {@code getPropert[y|ies]} calls can be delegated to the delegate node.
|
* Using a {@link MetadataReferral}, you can link two NodeRefs such that {@code hasAspect} and
|
||||||
|
* {@code getPropert[y|ies]} calls on one node can can be delegated to the other. In this way a defined set of
|
||||||
|
* metadata on one node can be made available for read access via another node.
|
||||||
* <p/>
|
* <p/>
|
||||||
* The connection between the nodes is made with a specified {@link #assocType peer association}.
|
* The connection between the nodes is made with a specified {@link #assocType peer association}.
|
||||||
*<p/>
|
*<p/>
|
||||||
* Note that a Delegation is not an instance of a link between two nodes, but the definition of such a link.
|
* Note that a {@link MetadataReferral} is not an instance of a link between two nodes, but the definition of such a link.
|
||||||
*
|
*
|
||||||
* @author Neil Mc Erlean
|
* @author Neil Mc Erlean
|
||||||
* @since 3.0.a
|
* @since 2.4.a
|
||||||
*/
|
*/
|
||||||
public class Delegation
|
public class MetadataReferral
|
||||||
{
|
{
|
||||||
private DictionaryService dictionaryService;
|
private DictionaryService dictionaryService;
|
||||||
private DelegationRegistry delegationRegistry;
|
private ReferralRegistry referralRegistry;
|
||||||
private Set<QName> aspects;
|
private Set<QName> aspects;
|
||||||
private QName assocType;
|
private QName assocType;
|
||||||
|
|
||||||
public Delegation()
|
public MetadataReferral()
|
||||||
{
|
{
|
||||||
// Intentionally empty
|
// Intentionally empty.
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDictionaryService(DictionaryService service)
|
public void setDictionaryService(DictionaryService service)
|
||||||
@@ -55,9 +57,9 @@ public class Delegation
|
|||||||
this.dictionaryService = service;
|
this.dictionaryService = service;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDelegationRegistry(DelegationRegistry registry)
|
public void setReferralRegistry(ReferralRegistry registry)
|
||||||
{
|
{
|
||||||
this.delegationRegistry = registry;
|
this.referralRegistry = registry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAssocType(QName assocType)
|
public void setAssocType(QName assocType)
|
||||||
@@ -74,25 +76,25 @@ public class Delegation
|
|||||||
{
|
{
|
||||||
if (this.assocType == null)
|
if (this.assocType == null)
|
||||||
{
|
{
|
||||||
throw new InvalidDelegation("Illegal null assocType");
|
throw new InvalidMetadataReferral("Illegal null assocType");
|
||||||
}
|
}
|
||||||
if (aspects == null || aspects.isEmpty())
|
if (aspects == null || aspects.isEmpty())
|
||||||
{
|
{
|
||||||
throw new InvalidDelegation("Illegal null or empty aspects set");
|
throw new InvalidMetadataReferral("Illegal null or empty aspects set");
|
||||||
}
|
}
|
||||||
if (dictionaryService.getAssociation(assocType) == null)
|
if (dictionaryService.getAssociation(assocType) == null)
|
||||||
{
|
{
|
||||||
throw new InvalidDelegation("Association not found: " + assocType);
|
throw new InvalidMetadataReferral("Association not found: " + assocType);
|
||||||
}
|
}
|
||||||
for (QName aspect : aspects)
|
for (QName aspect : aspects)
|
||||||
{
|
{
|
||||||
if (dictionaryService.getAspect(aspect) == null)
|
if (dictionaryService.getAspect(aspect) == null)
|
||||||
{
|
{
|
||||||
throw new InvalidDelegation("Aspect not found: " + aspect);
|
throw new InvalidMetadataReferral("Aspect not found: " + aspect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.delegationRegistry.register(this);
|
this.referralRegistry.register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the type of the peer association linking the node to its delegate. */
|
/** Gets the type of the peer association linking the node to its delegate. */
|
||||||
@@ -101,7 +103,7 @@ public class Delegation
|
|||||||
return assocType;
|
return assocType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the set of aspects which are being delegated. */
|
/** Gets the set of aspects which are being referred. */
|
||||||
public Set<QName> getAspects()
|
public Set<QName> getAspects()
|
||||||
{
|
{
|
||||||
return Collections.unmodifiableSet(aspects);
|
return Collections.unmodifiableSet(aspects);
|
||||||
@@ -115,9 +117,9 @@ public class Delegation
|
|||||||
@Override public boolean equals(Object other)
|
@Override public boolean equals(Object other)
|
||||||
{
|
{
|
||||||
boolean result = false;
|
boolean result = false;
|
||||||
if (other instanceof Delegation)
|
if (other instanceof MetadataReferral)
|
||||||
{
|
{
|
||||||
Delegation that = (Delegation)other;
|
MetadataReferral that = (MetadataReferral)other;
|
||||||
result = this.aspects.equals(that.aspects) &&
|
result = this.aspects.equals(that.aspects) &&
|
||||||
this.assocType.equals(that.assocType);
|
this.assocType.equals(that.assocType);
|
||||||
}
|
}
|
@@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2015 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.module.org_alfresco_module_rm.referredmetadata;
|
||||||
|
|
||||||
|
import static org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferredMetadataException.ChainedMetadataReferralUnsupported;
|
||||||
|
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A service to manage the referral of aspect metadata.
|
||||||
|
* Using this service a node can be {@link #attachReferrer linked} to a referrer node for a specific set of aspects.
|
||||||
|
* (Note that this referrer node must already exist within the database.)
|
||||||
|
* Then any read request for relevant metadata such as hasAspect or getProperties can be delegated to the
|
||||||
|
* linked node.
|
||||||
|
* <p/>
|
||||||
|
* For a link to be made, there must be a {@link #getDefinedReferrals() defined MetadataReferral} already in the system.
|
||||||
|
* This means that a peer-association type will have to have been declared and that a spring bean will have to have
|
||||||
|
* defined which aspects are to be handled by this {@link MetadataReferral}.
|
||||||
|
*
|
||||||
|
* @author Neil Mc Erlean
|
||||||
|
* @since 2.4.a
|
||||||
|
*/
|
||||||
|
public interface ReferralAdminService
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Creates a link between two nodes such that the first {@code referrer} can 'inherit' or reuse some aspect
|
||||||
|
* metadata from another node - the {@code referrer}.
|
||||||
|
* <p/>
|
||||||
|
* Note that links can currently only extend between two pairs of nodes and cannot be chained.
|
||||||
|
*
|
||||||
|
* @param referrer the node which is to inherit additional metadata.
|
||||||
|
* @param referent the node which will provide the additional metadata.
|
||||||
|
* @param assocType the type of the peer association which will link the two nodes.
|
||||||
|
* @return a {@link MetadataReferral} object which defines the link type.
|
||||||
|
* @throws ChainedMetadataReferralUnsupported if an attempt is made to attach nodes such that a chain would be made.
|
||||||
|
*/
|
||||||
|
// FIXME Remove assocType entirely from the API
|
||||||
|
MetadataReferral attachReferrer(NodeRef referrer, NodeRef referent, QName assocType);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes an existing metadata link between two nodes.
|
||||||
|
*
|
||||||
|
* @param referrer the node which has been linked to a metadata source.
|
||||||
|
* @param assocType the type of the peer association forming the link.
|
||||||
|
* @return the removed {@link MetadataReferral}.
|
||||||
|
*/
|
||||||
|
MetadataReferral detachReferrer(NodeRef referrer, QName assocType);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the set of defined {@link MetadataReferral}s.
|
||||||
|
*
|
||||||
|
* @return the set of defined {@link MetadataReferral}.
|
||||||
|
*/
|
||||||
|
Set<MetadataReferral> getDefinedReferrals();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the {@link MetadataReferral} which contains the specified {@code aspectName} if there is one.
|
||||||
|
* Note that only one {@link MetadataReferral} may declare that it handles any particular aspect.
|
||||||
|
*
|
||||||
|
* @param aspectName the name of the aspect whose {@link MetadataReferral} is sought.
|
||||||
|
* @return the {@link MetadataReferral} which handles the specified aspect, if there is one.
|
||||||
|
*/
|
||||||
|
MetadataReferral getReferralFor(QName aspectName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the set of {@link MetadataReferral}s which are currently applied from the specified {@code referrer}.
|
||||||
|
* From these, the types of peer associations which are linked to the specified
|
||||||
|
* {@code referrer} as well as the aspect types that are handled can be retrieved.
|
||||||
|
*
|
||||||
|
* @param referrer the NodeRef whose {@link MetadataReferral}s are sought.
|
||||||
|
* @return the set of {@link MetadataReferral}s from the specified referrer.
|
||||||
|
*/
|
||||||
|
Set<MetadataReferral> getAttachedReferralsFrom(NodeRef referrer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the {@link MetadataReferral} from the specified {@code referrer} for the specified {@code aspectName},
|
||||||
|
* if there is one.
|
||||||
|
*
|
||||||
|
* @param referrer the node whose {@link MetadataReferral} is sought.
|
||||||
|
* @param aspectName the aspect name for which a {@link MetadataReferral} is sought.
|
||||||
|
* @return the {@link MetadataReferral} which is attached to the specified node if there is one, else {@code null}.
|
||||||
|
*/
|
||||||
|
MetadataReferral getAttachedReferralFrom(NodeRef referrer, QName aspectName);
|
||||||
|
}
|
@@ -0,0 +1,179 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2015 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.module.org_alfresco_module_rm.referredmetadata;
|
||||||
|
|
||||||
|
import static org.alfresco.util.collections.CollectionUtils.transform;
|
||||||
|
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferredMetadataException.ChainedMetadataReferralUnsupported;
|
||||||
|
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
import org.alfresco.util.collections.Function;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Neil Mc Erlean
|
||||||
|
* @since 2.4.a
|
||||||
|
*/
|
||||||
|
public class ReferralAdminServiceImpl implements ReferralAdminService
|
||||||
|
{
|
||||||
|
private ReferralRegistry registry;
|
||||||
|
private NodeService nodeService;
|
||||||
|
|
||||||
|
public void setNodeService(NodeService service)
|
||||||
|
{
|
||||||
|
this.nodeService = service;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReferralRegistry(ReferralRegistry registry)
|
||||||
|
{
|
||||||
|
this.registry = registry;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public MetadataReferral attachReferrer(NodeRef referrer, NodeRef referent, QName assocType)
|
||||||
|
{
|
||||||
|
final MetadataReferral metadataReferral = getReferralForAssociation(assocType);
|
||||||
|
|
||||||
|
// Prevent the creation of chains of metadata linking from node A to B to C.
|
||||||
|
|
||||||
|
// If any nodes are already linked to referrer for the specified assoc, then we can't chain.
|
||||||
|
final List<AssociationRef> existingReferrerAssocs = nodeService.getSourceAssocs(referrer, assocType);
|
||||||
|
if ( !existingReferrerAssocs.isEmpty())
|
||||||
|
{
|
||||||
|
final List<NodeRef> existingReferrers = transform(existingReferrerAssocs,
|
||||||
|
new Function<AssociationRef, NodeRef>()
|
||||||
|
{
|
||||||
|
@Override public NodeRef apply(AssociationRef assocRef)
|
||||||
|
{
|
||||||
|
return assocRef.getSourceRef();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
throw new ChainedMetadataReferralUnsupported("Cannot attach referrer", existingReferrers);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Likewise if this referent node is already itself linked elsewhere, we cannot chain.
|
||||||
|
final List<AssociationRef> existingReferentAssocs = nodeService.getTargetAssocs(referent, assocType);
|
||||||
|
if ( !existingReferentAssocs.isEmpty())
|
||||||
|
{
|
||||||
|
// If it's not empty, it should only have one value in it, but just in case...
|
||||||
|
final List<NodeRef> existingReferents = transform(existingReferentAssocs,
|
||||||
|
new Function<AssociationRef, NodeRef>()
|
||||||
|
{
|
||||||
|
@Override public NodeRef apply(AssociationRef assocRef)
|
||||||
|
{
|
||||||
|
return assocRef.getTargetRef();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
throw new ChainedMetadataReferralUnsupported("Cannot attach referent", existingReferents);
|
||||||
|
}
|
||||||
|
|
||||||
|
// OK. We're good to go. We're not making a chain here.
|
||||||
|
nodeService.createAssociation(referrer, referent, assocType);
|
||||||
|
|
||||||
|
return metadataReferral;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets the {@link MetadataReferral} which uses the specified {@code assocType}. */
|
||||||
|
private MetadataReferral getReferralForAssociation(QName assocType)
|
||||||
|
{
|
||||||
|
final MetadataReferral metadataReferral = registry.getReferralForAssociation(assocType);
|
||||||
|
|
||||||
|
if (metadataReferral == null)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("No " + MetadataReferral.class.getSimpleName() +
|
||||||
|
" configured for assocType " + assocType);
|
||||||
|
}
|
||||||
|
return metadataReferral;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public MetadataReferral detachReferrer(NodeRef referrer, QName assocType)
|
||||||
|
{
|
||||||
|
// Is the association there?
|
||||||
|
final List<AssociationRef> assocs = nodeService.getTargetAssocs(referrer, assocType);
|
||||||
|
|
||||||
|
if (assocs == null || assocs.isEmpty())
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MetadataReferral result = getReferralForAssociation(assocType);
|
||||||
|
|
||||||
|
// There should only be one such association... but we'll remove them all just in case
|
||||||
|
for (AssociationRef assocRef : assocs)
|
||||||
|
{
|
||||||
|
nodeService.removeAssociation(referrer, assocRef.getTargetRef(), assocType);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public MetadataReferral getReferralFor(QName aspectName)
|
||||||
|
{
|
||||||
|
MetadataReferral metadataReferral = null;
|
||||||
|
|
||||||
|
for (MetadataReferral d : getDefinedReferrals())
|
||||||
|
{
|
||||||
|
if (d.getAspects().contains(aspectName))
|
||||||
|
{
|
||||||
|
metadataReferral = d;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return metadataReferral;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public Set<MetadataReferral> getAttachedReferralsFrom(NodeRef referrer)
|
||||||
|
{
|
||||||
|
final Set<MetadataReferral> allMetadataReferrals = getDefinedReferrals();
|
||||||
|
|
||||||
|
final Set<MetadataReferral> result = new HashSet<>();
|
||||||
|
for (MetadataReferral d : allMetadataReferrals)
|
||||||
|
{
|
||||||
|
final QName assocType = d.getAssocType();
|
||||||
|
if ( !nodeService.getTargetAssocs(referrer, assocType).isEmpty())
|
||||||
|
{
|
||||||
|
result.add(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public MetadataReferral getAttachedReferralFrom(NodeRef referrer, QName aspectName)
|
||||||
|
{
|
||||||
|
final Set<MetadataReferral> allMetadataReferrals = getAttachedReferralsFrom(referrer);
|
||||||
|
|
||||||
|
for (MetadataReferral d : allMetadataReferrals)
|
||||||
|
{
|
||||||
|
if (d.getAspects().contains(aspectName)) return d;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public Set<MetadataReferral> getDefinedReferrals()
|
||||||
|
{
|
||||||
|
return registry.getMetadataReferrals();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2015 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.module.org_alfresco_module_rm.referredmetadata;
|
||||||
|
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferredMetadataException.MetadataReferralAlreadyExists;
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferredMetadataException.InvalidMetadataReferral;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a registry of {@link MetadataReferral}s which have been defined in the system.
|
||||||
|
*
|
||||||
|
* @author Neil Mc Erlean
|
||||||
|
* @since 2.4.a
|
||||||
|
*/
|
||||||
|
public class ReferralRegistry
|
||||||
|
{
|
||||||
|
private final Set<MetadataReferral> metadataReferrals = new HashSet<>();
|
||||||
|
|
||||||
|
public void register(MetadataReferral metadataReferral)
|
||||||
|
{
|
||||||
|
// Various validation steps to do here to ensure we get consistent, sensible referrals registered.
|
||||||
|
if (metadataReferrals.contains(metadataReferral))
|
||||||
|
{
|
||||||
|
throw new MetadataReferralAlreadyExists("Cannot register duplicate referral", metadataReferral);
|
||||||
|
}
|
||||||
|
for (MetadataReferral existingMetadataReferral : metadataReferrals)
|
||||||
|
{
|
||||||
|
if (existingMetadataReferral.getAssocType().equals(metadataReferral.getAssocType()))
|
||||||
|
{
|
||||||
|
throw new InvalidMetadataReferral("Cannot register two referrals with the same assocType. " +
|
||||||
|
"Existing: " + existingMetadataReferral +
|
||||||
|
" New: " + metadataReferral);
|
||||||
|
}
|
||||||
|
// Yes this is a for loop inside a for loop but we're assuming these sets will not be large.
|
||||||
|
for (QName existingAspect : existingMetadataReferral.getAspects())
|
||||||
|
{
|
||||||
|
if (metadataReferral.getAspects().contains(existingAspect))
|
||||||
|
{
|
||||||
|
throw new InvalidMetadataReferral("Cannot register two referrals with the same aspect. " +
|
||||||
|
"Existing: " + existingMetadataReferral +
|
||||||
|
" New: " + metadataReferral);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.metadataReferrals.add(metadataReferral);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<MetadataReferral> getMetadataReferrals()
|
||||||
|
{
|
||||||
|
return Collections.unmodifiableSet(metadataReferrals);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the {@link MetadataReferral} which is defined to use the specified {@code assocType}.
|
||||||
|
*
|
||||||
|
* @param assocType the peer association type whose {@link MetadataReferral} is sought.
|
||||||
|
* @return the {@link MetadataReferral} defined to use the specified {@code assocType} if there is one, else {@code null}.
|
||||||
|
*/
|
||||||
|
public MetadataReferral getReferralForAssociation(QName assocType)
|
||||||
|
{
|
||||||
|
for (MetadataReferral d : metadataReferrals)
|
||||||
|
{
|
||||||
|
if (d.getAssocType().equals(assocType))
|
||||||
|
{
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2015 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.module.org_alfresco_module_rm.referredmetadata;
|
||||||
|
|
||||||
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic class for any runtime exceptions related to metadata referrals.
|
||||||
|
*
|
||||||
|
* @author Neil Mc Erlean
|
||||||
|
* @since 2.4.a
|
||||||
|
*/
|
||||||
|
public class ReferredMetadataException extends AlfrescoRuntimeException
|
||||||
|
{
|
||||||
|
public ReferredMetadataException(String msgId) { super(msgId); }
|
||||||
|
public ReferredMetadataException(String msgId, Throwable cause) { super(msgId, cause); }
|
||||||
|
|
||||||
|
/** This exception may be thrown when a {@link MetadataReferral} was incorrectly initialised. */
|
||||||
|
public static class InvalidMetadataReferral extends ReferredMetadataException
|
||||||
|
{
|
||||||
|
public InvalidMetadataReferral(String msgId)
|
||||||
|
{
|
||||||
|
super(msgId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** This exception may be thrown when a {@link MetadataReferral} already exists. */
|
||||||
|
public static class MetadataReferralAlreadyExists extends ReferredMetadataException
|
||||||
|
{
|
||||||
|
private final MetadataReferral metadataReferral;
|
||||||
|
|
||||||
|
public MetadataReferralAlreadyExists(String msgId, MetadataReferral metadataReferral)
|
||||||
|
{
|
||||||
|
super(msgId);
|
||||||
|
this.metadataReferral = metadataReferral;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A {@link MetadataReferral} has not been found. */
|
||||||
|
public static class MetadataReferralNotFound extends ReferredMetadataException
|
||||||
|
{
|
||||||
|
public MetadataReferralNotFound(String msgId)
|
||||||
|
{
|
||||||
|
super(msgId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A referent Node has not been found. */
|
||||||
|
public static class ReferentNodeNotFound extends ReferredMetadataException
|
||||||
|
{
|
||||||
|
public ReferentNodeNotFound(String msgId)
|
||||||
|
{
|
||||||
|
super(msgId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Exception to report that chains of metadata referral are not currently supported. */
|
||||||
|
public static class ChainedMetadataReferralUnsupported extends ReferredMetadataException
|
||||||
|
{
|
||||||
|
private final List<NodeRef> existingReferrers;
|
||||||
|
|
||||||
|
public ChainedMetadataReferralUnsupported(String msgId, List<NodeRef> existingReferrers)
|
||||||
|
{
|
||||||
|
super(msgId);
|
||||||
|
this.existingReferrers = existingReferrers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<NodeRef> getExistingReferrers()
|
||||||
|
{
|
||||||
|
return this.existingReferrers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public String toString()
|
||||||
|
{
|
||||||
|
StringBuilder msg = new StringBuilder();
|
||||||
|
msg.append(this.getClass().getSimpleName()).append(" Already referring from: ")
|
||||||
|
.append(existingReferrers.toString());
|
||||||
|
return msg.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Exception to report that metadata referral is not supported for metadata defined on content types. */
|
||||||
|
public static class TypeMetadataReferralUnsupported extends ReferredMetadataException
|
||||||
|
{
|
||||||
|
public TypeMetadataReferralUnsupported(String msgId)
|
||||||
|
{
|
||||||
|
super(msgId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2015 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.module.org_alfresco_module_rm.referredmetadata;
|
||||||
|
|
||||||
|
import static org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferredMetadataException.MetadataReferralNotFound;
|
||||||
|
import static org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferredMetadataException.TypeMetadataReferralUnsupported;
|
||||||
|
|
||||||
|
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This service provides read-only access to linked metadata.
|
||||||
|
* TODO complete! Include definition of referent etc or link to package.html
|
||||||
|
*
|
||||||
|
* @author Neil Mc Erlean
|
||||||
|
* @since 2.4.a
|
||||||
|
*/
|
||||||
|
public interface ReferredMetadataService
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Checks if the specified referrer has an attached {@link MetadataReferral} for the specified aspect.
|
||||||
|
*
|
||||||
|
* @param potentialReferrer the referrer which may or may not be linked to a referent node.
|
||||||
|
* @param aspectName the name of the aspect.
|
||||||
|
* @return whether the node is linked to a referent node for the specified aspect.
|
||||||
|
* @throws InvalidNodeRefException if the supplied referrer does not exist.
|
||||||
|
* @throws MetadataReferralNotFound if no {@link MetadataReferral} is defined for the specified aspect.
|
||||||
|
*/
|
||||||
|
boolean isReferringMetadata(NodeRef potentialReferrer, QName aspectName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the referent node for the specified aspect, if there is one.
|
||||||
|
*
|
||||||
|
* @param referrer the node whose referent is sought.
|
||||||
|
* @param aspectName the aspect name.
|
||||||
|
* @return the referent of the provided referrer if there is one, else {@code null}.
|
||||||
|
* @throws InvalidNodeRefException if the supplied referrer does not exist.
|
||||||
|
* @throws MetadataReferralNotFound if no {@link MetadataReferral} is defined for the specified aspect.
|
||||||
|
*/
|
||||||
|
NodeRef getReferentNode(NodeRef referrer, QName aspectName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all the property values from the referent node for the specified aspect.
|
||||||
|
*
|
||||||
|
* @param referrer the referring node.
|
||||||
|
* @param aspectName the aspect name which holds the properties we want.
|
||||||
|
* @return the property values as obtained from the referent node.
|
||||||
|
*/
|
||||||
|
Map<QName, Serializable> getReferredProperties(NodeRef referrer, QName aspectName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the specified property value from the referent node.
|
||||||
|
*
|
||||||
|
* @param referrer the referring node.
|
||||||
|
* @param propertyName the property name whose value is sought.
|
||||||
|
* @return the property value as obtained from the referent node.
|
||||||
|
* @throws IllegalArgumentException if the specified property is not defined.
|
||||||
|
* @throws TypeMetadataReferralUnsupported if the specified property is not defined on an aspect.
|
||||||
|
*/
|
||||||
|
Serializable getReferredProperty(NodeRef referrer, QName propertyName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the specified aspect is present on a node's referent.
|
||||||
|
*
|
||||||
|
* @param referrer the referring node.
|
||||||
|
* @param aspectName the aspect which is to be checked on the referent node.
|
||||||
|
* @return Returns true if the aspect has been applied to the referent node,
|
||||||
|
* otherwise false
|
||||||
|
*/
|
||||||
|
boolean hasReferredAspect(NodeRef referrer, QName aspectName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all {@link MetadataReferral referrals} currently attached to the specified node.
|
||||||
|
*
|
||||||
|
* @param potentialReferrer the node whose attached {@link MetadataReferral referrals} are sought.
|
||||||
|
* @return Returns a map of all attached {@link MetadataReferral referrals} for the specified nodeRef.
|
||||||
|
* The map has the form {@code (key, value) = (MetadataReferral, referent Node for that Referral)}
|
||||||
|
* The map may be empty but will not be {@code null}.
|
||||||
|
*/
|
||||||
|
Map<MetadataReferral, NodeRef> getAttachedReferrals(NodeRef potentialReferrer);
|
||||||
|
}
|
||||||
|
|
@@ -16,10 +16,11 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.alfresco.module.org_alfresco_module_rm.metadatadelegation;
|
package org.alfresco.module.org_alfresco_module_rm.referredmetadata;
|
||||||
|
|
||||||
import static org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationException.DelegateNotFound;
|
import static org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferredMetadataException.MetadataReferralNotFound;
|
||||||
import static org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationException.DelegationNotFound;
|
import static org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferredMetadataException.ReferentNodeNotFound;
|
||||||
|
import static org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferredMetadataException.TypeMetadataReferralUnsupported;
|
||||||
import static org.alfresco.util.collections.CollectionUtils.filterKeys;
|
import static org.alfresco.util.collections.CollectionUtils.filterKeys;
|
||||||
|
|
||||||
import org.alfresco.service.cmr.dictionary.ClassDefinition;
|
import org.alfresco.service.cmr.dictionary.ClassDefinition;
|
||||||
@@ -40,17 +41,17 @@ import java.util.Set;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Neil Mc Erlean
|
* @author Neil Mc Erlean
|
||||||
* @since 3.0.a
|
* @since 2.4.a
|
||||||
*/
|
*/
|
||||||
public class DelegationServiceImpl implements DelegationService
|
public class ReferredMetadataServiceImpl implements ReferredMetadataService
|
||||||
{
|
{
|
||||||
private DelegationAdminService delegationAdminService;
|
private ReferralAdminService referralAdminService;
|
||||||
private DictionaryService dictionaryService;
|
private DictionaryService dictionaryService;
|
||||||
private NodeService nodeService;
|
private NodeService nodeService;
|
||||||
|
|
||||||
public void setDelegationAdminService(DelegationAdminService service)
|
public void setReferralAdminService(ReferralAdminService service)
|
||||||
{
|
{
|
||||||
this.delegationAdminService = service;
|
this.referralAdminService = service;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDictionaryService(DictionaryService service)
|
public void setDictionaryService(DictionaryService service)
|
||||||
@@ -63,54 +64,60 @@ public class DelegationServiceImpl implements DelegationService
|
|||||||
this.nodeService = service;
|
this.nodeService = service;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean hasDelegateForAspect(NodeRef nodeRef, QName aspectName)
|
@Override public boolean isReferringMetadata(NodeRef potentialReferrer, QName aspectName)
|
||||||
{
|
{
|
||||||
final Delegation delegation = delegationAdminService.getDelegationFor(aspectName);
|
if ( !nodeService.exists(potentialReferrer))
|
||||||
|
|
||||||
if ( !nodeService.exists(nodeRef))
|
|
||||||
{
|
{
|
||||||
throw new InvalidNodeRefException(nodeRef);
|
throw new InvalidNodeRefException(potentialReferrer);
|
||||||
}
|
}
|
||||||
else if (delegation == null)
|
|
||||||
|
final MetadataReferral metadataReferral = referralAdminService.getReferralFor(aspectName);
|
||||||
|
|
||||||
|
if (metadataReferral == null)
|
||||||
{
|
{
|
||||||
throw new DelegationNotFound("No delegation found for aspect: " + aspectName);
|
throw new MetadataReferralNotFound("No defined referral found for aspect: " + aspectName);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
final List<AssociationRef> targetAssocs = nodeService.getTargetAssocs(nodeRef, delegation.getAssocType());
|
final List<AssociationRef> targetAssocs = nodeService.getTargetAssocs(potentialReferrer, metadataReferral.getAssocType());
|
||||||
return !targetAssocs.isEmpty();
|
return !targetAssocs.isEmpty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public NodeRef getDelegateFor(NodeRef nodeRef, QName aspectName)
|
@Override public NodeRef getReferentNode(NodeRef referrer, QName aspectName)
|
||||||
{
|
{
|
||||||
final Delegation d = delegationAdminService.getDelegationFor(aspectName);
|
if ( !nodeService.exists(referrer))
|
||||||
|
{
|
||||||
|
throw new InvalidNodeRefException(referrer);
|
||||||
|
}
|
||||||
|
|
||||||
|
final MetadataReferral d = referralAdminService.getReferralFor(aspectName);
|
||||||
|
|
||||||
if (d == null)
|
if (d == null)
|
||||||
{
|
{
|
||||||
throw new DelegationNotFound("No delegation found for aspect: " + aspectName);
|
throw new MetadataReferralNotFound("No defined referral found for aspect: " + aspectName);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
final QName assocType = d.getAssocType();
|
final QName assocType = d.getAssocType();
|
||||||
final List<AssociationRef> assocs = nodeService.getTargetAssocs(nodeRef, assocType);
|
final List<AssociationRef> assocs = nodeService.getTargetAssocs(referrer, assocType);
|
||||||
|
|
||||||
return assocs.isEmpty() ? null : assocs.get(0).getTargetRef();
|
return assocs.isEmpty() ? null : assocs.get(0).getTargetRef();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public Map<QName, Serializable> getDelegateProperties(NodeRef nodeRef, final QName aspectName)
|
@Override public Map<QName, Serializable> getReferredProperties(NodeRef referrer, final QName aspectName)
|
||||||
{
|
{
|
||||||
final NodeRef delegateNode = getDelegateFor(nodeRef, aspectName);
|
final NodeRef referentNode = getReferentNode(referrer, aspectName);
|
||||||
|
|
||||||
if (delegateNode == null)
|
if (referentNode == null)
|
||||||
{
|
{
|
||||||
throw new DelegateNotFound("No delegate node found for " + nodeRef + " " + aspectName);
|
throw new ReferentNodeNotFound("No referent node found for " + referrer + " " + aspectName);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Map<QName, Serializable> allProps = nodeService.getProperties(delegateNode);
|
final Map<QName, Serializable> allProps = nodeService.getProperties(referentNode);
|
||||||
Map<QName, Serializable> aspectProps = filterKeys(allProps,
|
final Map<QName, Serializable> aspectProps = filterKeys(allProps,
|
||||||
new Function<QName, Boolean>()
|
new Function<QName, Boolean>()
|
||||||
{
|
{
|
||||||
@Override public Boolean apply(QName propName)
|
@Override public Boolean apply(QName propName)
|
||||||
@@ -125,7 +132,7 @@ public class DelegationServiceImpl implements DelegationService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public Serializable getDelegateProperty(NodeRef nodeRef, QName propertyName)
|
@Override public Serializable getReferredProperty(NodeRef referrer, QName propertyName)
|
||||||
{
|
{
|
||||||
final PropertyDefinition propDefn = dictionaryService.getProperty(propertyName);
|
final PropertyDefinition propDefn = dictionaryService.getProperty(propertyName);
|
||||||
|
|
||||||
@@ -141,38 +148,38 @@ public class DelegationServiceImpl implements DelegationService
|
|||||||
msg.append("Property '").append(propertyName).append("' is not defined on an aspect: ")
|
msg.append("Property '").append(propertyName).append("' is not defined on an aspect: ")
|
||||||
.append(aspectDefn.getName());
|
.append(aspectDefn.getName());
|
||||||
|
|
||||||
throw new IllegalArgumentException(msg.toString());
|
throw new TypeMetadataReferralUnsupported(msg.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<QName, Serializable> allPropValues = getDelegateProperties(nodeRef, aspectDefn.getName());
|
final Map<QName, Serializable> allPropValues = getReferredProperties(referrer, aspectDefn.getName());
|
||||||
return allPropValues.get(propertyName);
|
return allPropValues.get(propertyName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean hasAspectOnDelegate(NodeRef nodeRef, QName aspectName)
|
@Override public boolean hasReferredAspect(NodeRef referrer, QName aspectName)
|
||||||
{
|
{
|
||||||
final NodeRef delegateNode = getDelegateFor(nodeRef, aspectName);
|
final NodeRef referentNode = getReferentNode(referrer, aspectName);
|
||||||
|
|
||||||
if (delegateNode == null)
|
if (referentNode == null)
|
||||||
{
|
{
|
||||||
throw new DelegateNotFound("No delegate node found for " + nodeRef + " " + aspectName);
|
throw new ReferentNodeNotFound("No referent node found for " + referrer + " " + aspectName);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return nodeService.hasAspect(delegateNode, aspectName);
|
return nodeService.hasAspect(referentNode, aspectName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public Map<Delegation, NodeRef> getDelegations(NodeRef nodeRef)
|
@Override public Map<MetadataReferral, NodeRef> getAttachedReferrals(NodeRef potentialReferrer)
|
||||||
{
|
{
|
||||||
Set<Delegation> delegations = delegationAdminService.getDelegationsFrom(nodeRef);
|
Set<MetadataReferral> metadataReferrals = referralAdminService.getAttachedReferralsFrom(potentialReferrer);
|
||||||
|
|
||||||
Map<Delegation, NodeRef> result = new HashMap<>();
|
Map<MetadataReferral, NodeRef> result = new HashMap<>();
|
||||||
for (Delegation d : delegations)
|
for (MetadataReferral mr : metadataReferrals)
|
||||||
{
|
{
|
||||||
// We need only use the first aspect to get the Delegation object
|
// We need only use the first aspect to get the MetadataReferral object
|
||||||
if (!d.getAspects().isEmpty())
|
if (!mr.getAspects().isEmpty())
|
||||||
{
|
{
|
||||||
result.put(d, getDelegateFor(nodeRef, d.getAspects().iterator().next()));
|
result.put(mr, getReferentNode(potentialReferrer, mr.getAspects().iterator().next()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@@ -17,30 +17,31 @@
|
|||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* This package contains the types that deliver the Metadata Delegation feature.
|
* This package contains the types that deliver the Metadata Referral feature.
|
||||||
* Metadata delegation allows read-only <em>aspect</em> metadata for any given Alfresco node to
|
* Metadata referral allows node metadata to be shared between multiple Alfresco nodes.
|
||||||
* be sourced from another node, the delegate.
|
|
||||||
* <p/>
|
* <p/>
|
||||||
* In this way nodes can 'inherit' some of their metadata from another node which may
|
* In this way nodes can 'inherit' some of their metadata from another node which may
|
||||||
* have benefits when more than one node is required to share some of the same metadata.
|
* have benefits when more than one node is required to share some of the same metadata.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Multiple nodes may share the same delegate node and one node may be linked to multiple
|
* Only aspect metadata can be shared and it is only shared as read-only data to the other nodes.
|
||||||
* delegates.
|
* The node which contains the metadata values is the 'referent' node and any nodes which have been
|
||||||
|
* linked to the referent and share the metadata are known as referrers.
|
||||||
* <p/>
|
* <p/>
|
||||||
* The linking of nodes to their metadata delegates is done with Alfresco peer associations.
|
* Multiple nodes may share the same referent node and one node may be linked to multiple referrers.
|
||||||
|
* <p/>
|
||||||
|
* The linking of nodes to their metadata referents is done with Alfresco peer associations.
|
||||||
* Association types must be declared in an Alfresco content model in the normal way.
|
* Association types must be declared in an Alfresco content model in the normal way.
|
||||||
* Spring configuration is used to assign each association type a set of aspects which will
|
* Spring configuration is used to assign each association type a set of aspects which will
|
||||||
* be available from the delegate via the association.
|
* be available from the referent via the association.
|
||||||
* <p/>
|
* <p/>
|
||||||
* See {@link org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationAdminService}
|
* See {@link org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferralAdminService}
|
||||||
* for details on how to create and destroy delegation links between nodes.
|
* for details on how to create and destroy metadata links between nodes.
|
||||||
* <p/>
|
* <p/>
|
||||||
* The read-only access to delegated metadat is made available via the
|
* See {@link org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferredMetadataService}
|
||||||
* See {@link org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationService}
|
|
||||||
* for details on how the data access is performed.
|
* for details on how the data access is performed.
|
||||||
* <p/>
|
* <p/>
|
||||||
* See {@link org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationRegistry}
|
* See {@link org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferralRegistry}
|
||||||
* for details on what {@link org.alfresco.module.org_alfresco_module_rm.metadatadelegation.Delegation}s
|
* for details on what {@link org.alfresco.module.org_alfresco_module_rm.referredmetadata.MetadataReferral}s
|
||||||
* are defined in the system.
|
* are defined in the system.
|
||||||
*/
|
*/
|
||||||
package org.alfresco.module.org_alfresco_module_rm.metadatadelegation;
|
package org.alfresco.module.org_alfresco_module_rm.referredmetadata;
|
@@ -1,194 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2005-2015 Alfresco Software Limited.
|
|
||||||
*
|
|
||||||
* This file is part of Alfresco
|
|
||||||
*
|
|
||||||
* Alfresco is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Alfresco is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.alfresco.module.org_alfresco_module_rm.metadatadelegation;
|
|
||||||
|
|
||||||
import static java.util.Collections.emptyMap;
|
|
||||||
import static java.util.Arrays.asList;
|
|
||||||
import static org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationException.DelegateNotFound;
|
|
||||||
import static org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationException.DelegationNotFound;
|
|
||||||
import static org.alfresco.module.org_alfresco_module_rm.test.util.ExceptionUtils.expectedException;
|
|
||||||
import static org.alfresco.module.org_alfresco_module_rm.test.util.FPUtils.asSet;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
import static org.junit.Assert.assertFalse;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
import static org.mockito.Mockito.any;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.eq;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import org.alfresco.service.cmr.dictionary.ClassDefinition;
|
|
||||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
|
||||||
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
|
||||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
|
||||||
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.namespace.QName;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.mockito.InjectMocks;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.MockitoAnnotations;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unit tests for {@link DelegationServiceImpl}.
|
|
||||||
*
|
|
||||||
* @author Neil Mc Erlean
|
|
||||||
* @since 3.0.a
|
|
||||||
*/
|
|
||||||
public class DelegationServiceImplUnitTest
|
|
||||||
{
|
|
||||||
@InjectMocks private final DelegationServiceImpl delegationService = new DelegationServiceImpl();
|
|
||||||
|
|
||||||
@Mock DictionaryService mockDictionaryService;
|
|
||||||
@Mock NodeService mockNodeService;
|
|
||||||
@Mock DelegationAdminServiceImpl mockDelegationAdminService;
|
|
||||||
|
|
||||||
/** This node has a delegate node. */
|
|
||||||
private final NodeRef nodeWithDelegate = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "nodeWithDelegate");
|
|
||||||
/** This is the delgate for {@link #nodeWithDelegate}. */
|
|
||||||
private final NodeRef delegateNode = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "delegateNode");
|
|
||||||
/** This node has no delegate node. */
|
|
||||||
private final NodeRef nodeWithoutDelegate = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "nodeWithoutDelegate");
|
|
||||||
|
|
||||||
/** The type of the peer association that links the delegate to its source. */
|
|
||||||
private final QName delegateAssocType = QName.createQName("test", "delegateAssocType");
|
|
||||||
/** The instance of the association between {@link #nodeWithDelegate} and {@link #delegateNode}. */
|
|
||||||
private final AssociationRef delegateAssocRef = new AssociationRef(nodeWithDelegate, delegateAssocType, delegateNode);
|
|
||||||
|
|
||||||
/** Name of an aspect that has been delegated. */
|
|
||||||
private final QName delegatedAspect1 = QName.createQName("test", "delegatedAspect1");
|
|
||||||
/** Name of an aspect that has been delegated. */
|
|
||||||
private final QName delegatedAspect2 = QName.createQName("test", "delegatedAspect2");
|
|
||||||
/** Name of a content class (a type in this case) that has not been delegated.
|
|
||||||
* N.B. Types can't be delegated currently. */
|
|
||||||
private final QName undelegatedType = QName.createQName("test", "undelegatedType");
|
|
||||||
|
|
||||||
private final QName delegatedProp = QName.createQName("test", "delegatedProp");
|
|
||||||
private final Serializable delegatedPropValue = "hello";
|
|
||||||
private final QName undelegatedProp = QName.createQName("test", "undelegatedProp");
|
|
||||||
|
|
||||||
private final Delegation delegate = new Delegation()
|
|
||||||
{{
|
|
||||||
this.setAssocType(delegateAssocType);
|
|
||||||
this.setAspects(asSet(delegatedAspect1, delegatedAspect2));
|
|
||||||
}};
|
|
||||||
|
|
||||||
@Before public void setUp()
|
|
||||||
{
|
|
||||||
MockitoAnnotations.initMocks(this);
|
|
||||||
|
|
||||||
final PropertyDefinition aspectProp = mock(PropertyDefinition.class);
|
|
||||||
final ClassDefinition aspectDefn = mock(ClassDefinition.class);
|
|
||||||
when(aspectDefn.getName()).thenReturn(delegatedAspect1);
|
|
||||||
when(aspectProp.getContainerClass()).thenReturn(aspectDefn);
|
|
||||||
when(aspectDefn.isAspect()).thenReturn(true);
|
|
||||||
|
|
||||||
final PropertyDefinition typeProp = mock(PropertyDefinition.class);
|
|
||||||
final ClassDefinition typeDefn = mock(ClassDefinition.class);
|
|
||||||
when(typeDefn.getName()).thenReturn(undelegatedType);
|
|
||||||
when(typeProp.getContainerClass()).thenReturn(typeDefn);
|
|
||||||
when(typeDefn.isAspect()).thenReturn(false);
|
|
||||||
|
|
||||||
when(mockDictionaryService.getProperty(delegatedProp)).thenReturn(aspectProp);
|
|
||||||
|
|
||||||
when(mockDelegationAdminService.getDelegationsFrom(nodeWithDelegate)).thenReturn(asSet(delegate));
|
|
||||||
for (QName delegatedAspect : asSet(delegatedAspect1, delegatedAspect2))
|
|
||||||
{
|
|
||||||
when(mockDelegationAdminService.getDelegationFor(delegatedAspect)).thenReturn(delegate);
|
|
||||||
when(mockNodeService.hasAspect(delegateNode, delegatedAspect)).thenReturn(true);
|
|
||||||
}
|
|
||||||
when(mockNodeService.getSourceAssocs(delegateNode, delegateAssocType)).thenReturn(asList(delegateAssocRef));
|
|
||||||
when(mockNodeService.getTargetAssocs(nodeWithDelegate, delegateAssocType)).thenReturn(asList(delegateAssocRef));
|
|
||||||
when(mockNodeService.exists(any(NodeRef.class))).thenReturn(true);
|
|
||||||
when(mockNodeService.getProperties(delegateNode))
|
|
||||||
.thenReturn(new HashMap<QName, Serializable>()
|
|
||||||
{{
|
|
||||||
this.put(delegatedProp, delegatedPropValue);
|
|
||||||
}});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test public void hasDelegateForAspect()
|
|
||||||
{
|
|
||||||
assertTrue(delegationService.hasDelegateForAspect(nodeWithDelegate, delegatedAspect1));
|
|
||||||
expectedException(DelegationNotFound.class, () -> delegationService.hasDelegateForAspect(nodeWithoutDelegate, undelegatedType));
|
|
||||||
assertFalse(delegationService.hasDelegateForAspect(nodeWithoutDelegate, delegatedAspect1));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test public void getDelegateFor()
|
|
||||||
{
|
|
||||||
assertEquals(delegateNode, delegationService.getDelegateFor(nodeWithDelegate, delegatedAspect1));
|
|
||||||
expectedException(DelegationNotFound.class, () ->
|
|
||||||
{
|
|
||||||
delegationService.getDelegateFor(nodeWithDelegate, undelegatedType);
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
assertNull(delegationService.getDelegateFor(nodeWithoutDelegate, delegatedAspect1));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test public void getDelegateProperties()
|
|
||||||
{
|
|
||||||
final Map<QName, Serializable> expectedProps = new HashMap<>();
|
|
||||||
expectedProps.put(delegatedProp, delegatedPropValue);
|
|
||||||
|
|
||||||
assertEquals(expectedProps, delegationService.getDelegateProperties(nodeWithDelegate, delegatedAspect1));
|
|
||||||
|
|
||||||
expectedException(DelegationNotFound.class,
|
|
||||||
() -> delegationService.getDelegateProperties(nodeWithDelegate, undelegatedType));
|
|
||||||
|
|
||||||
expectedException(DelegateNotFound.class,
|
|
||||||
() -> delegationService.getDelegateProperties(nodeWithoutDelegate, delegatedAspect1));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test public void getDelegateProperty()
|
|
||||||
{
|
|
||||||
assertEquals(delegatedPropValue, delegationService.getDelegateProperty(nodeWithDelegate, delegatedProp));
|
|
||||||
|
|
||||||
expectedException(IllegalArgumentException.class,
|
|
||||||
() -> delegationService.getDelegateProperty(nodeWithDelegate, undelegatedProp));
|
|
||||||
|
|
||||||
expectedException(DelegationNotFound.class,
|
|
||||||
() -> delegationService.getDelegateProperties(nodeWithoutDelegate, delegatedProp));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test public void hasAspectOnDelegate()
|
|
||||||
{
|
|
||||||
assertTrue(delegationService.hasAspectOnDelegate(nodeWithDelegate, delegatedAspect1));
|
|
||||||
|
|
||||||
expectedException(DelegationNotFound.class,
|
|
||||||
() -> delegationService.hasAspectOnDelegate(nodeWithDelegate, undelegatedType));
|
|
||||||
|
|
||||||
expectedException(DelegateNotFound.class,
|
|
||||||
() -> delegationService.hasAspectOnDelegate(nodeWithoutDelegate, delegatedAspect1));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test public void getDelegations()
|
|
||||||
{
|
|
||||||
final Map<Delegation, NodeRef> expectedDelegations = new HashMap<>();
|
|
||||||
expectedDelegations.put(delegate, delegateNode);
|
|
||||||
|
|
||||||
assertEquals(expectedDelegations, delegationService.getDelegations(nodeWithDelegate));
|
|
||||||
assertEquals(emptyMap(), delegationService.getDelegations(nodeWithoutDelegate));
|
|
||||||
}
|
|
||||||
}
|
|
@@ -16,10 +16,10 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.alfresco.module.org_alfresco_module_rm.metadatadelegation;
|
package org.alfresco.module.org_alfresco_module_rm.referredmetadata;
|
||||||
|
|
||||||
import static java.util.Collections.emptySet;
|
import static java.util.Collections.emptySet;
|
||||||
import static org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationException.InvalidDelegation;
|
import static org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferredMetadataException.InvalidMetadataReferral;
|
||||||
import static org.alfresco.module.org_alfresco_module_rm.test.util.ExceptionUtils.expectedException;
|
import static org.alfresco.module.org_alfresco_module_rm.test.util.ExceptionUtils.expectedException;
|
||||||
import static org.alfresco.module.org_alfresco_module_rm.test.util.FPUtils.asListFrom;
|
import static org.alfresco.module.org_alfresco_module_rm.test.util.FPUtils.asListFrom;
|
||||||
import static org.alfresco.module.org_alfresco_module_rm.test.util.FPUtils.asSet;
|
import static org.alfresco.module.org_alfresco_module_rm.test.util.FPUtils.asSet;
|
||||||
@@ -41,17 +41,17 @@ import org.mockito.MockitoAnnotations;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@link Delegation}.
|
* Unit tests for {@link MetadataReferral}.
|
||||||
*
|
*
|
||||||
* @author Neil Mc Erlean
|
* @author Neil Mc Erlean
|
||||||
* @since 3.0.a
|
* @since 3.0.a
|
||||||
*/
|
*/
|
||||||
public class DelegationUnitTest
|
public class MetadataReferralUnitTest
|
||||||
{
|
{
|
||||||
@Mock DictionaryService mockDictionaryService;
|
@Mock DictionaryService mockDictionaryService;
|
||||||
@Mock NodeService mockNodeService;
|
@Mock NodeService mockNodeService;
|
||||||
|
|
||||||
private final DelegationAdminServiceImpl metadataDelegationService = new DelegationAdminServiceImpl();
|
private final ReferralAdminServiceImpl referralAdminService = new ReferralAdminServiceImpl();
|
||||||
|
|
||||||
private final NodeRef node1 = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "node1");
|
private final NodeRef node1 = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "node1");
|
||||||
private final NodeRef node2 = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "node2");
|
private final NodeRef node2 = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "node2");
|
||||||
@@ -63,66 +63,66 @@ public class DelegationUnitTest
|
|||||||
{
|
{
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
metadataDelegationService.setNodeService(mockNodeService);
|
referralAdminService.setNodeService(mockNodeService);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void nullOrEmptyDelegatesAreForbidden()
|
@Test public void nullOrEmptyReferralsAreForbidden()
|
||||||
{
|
{
|
||||||
List<Delegation> invalidDelegations = asListFrom(() -> new Delegation(),
|
List<MetadataReferral> invalidMetadataReferrals = asListFrom(() -> new MetadataReferral(),
|
||||||
() -> {
|
() -> {
|
||||||
Delegation d = new Delegation();
|
MetadataReferral mr = new MetadataReferral();
|
||||||
d.setAssocType(assoc1);
|
mr.setAssocType(assoc1);
|
||||||
d.setAspects(null);
|
mr.setAspects(null);
|
||||||
d.setDictionaryService(mockDictionaryService);
|
mr.setDictionaryService(mockDictionaryService);
|
||||||
return d;
|
return mr;
|
||||||
},
|
},
|
||||||
() -> {
|
() -> {
|
||||||
Delegation d = new Delegation();
|
MetadataReferral mr = new MetadataReferral();
|
||||||
d.setAssocType(assoc1);
|
mr.setAssocType(assoc1);
|
||||||
d.setAspects(emptySet());
|
mr.setAspects(emptySet());
|
||||||
d.setDictionaryService(mockDictionaryService);
|
mr.setDictionaryService(mockDictionaryService);
|
||||||
return d;
|
return mr;
|
||||||
},
|
},
|
||||||
() -> {
|
() -> {
|
||||||
Delegation d = new Delegation();
|
MetadataReferral mr = new MetadataReferral();
|
||||||
d.setAssocType(null);
|
mr.setAssocType(null);
|
||||||
d.setAspects(asSet(aspect1, aspect2));
|
mr.setAspects(asSet(aspect1, aspect2));
|
||||||
d.setDictionaryService(mockDictionaryService);
|
mr.setDictionaryService(mockDictionaryService);
|
||||||
return d;
|
return mr;
|
||||||
});
|
});
|
||||||
|
|
||||||
invalidDelegations.stream()
|
invalidMetadataReferrals.stream()
|
||||||
.forEach(d -> expectedException(InvalidDelegation.class, () -> {
|
.forEach(mr -> expectedException(InvalidMetadataReferral.class, () -> {
|
||||||
d.validateAndRegister();
|
mr.validateAndRegister();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=InvalidDelegation.class)
|
@Test(expected=InvalidMetadataReferral.class)
|
||||||
public void delegateMustHaveAssocThatExists()
|
public void referralMustHaveAssocThatExists()
|
||||||
{
|
{
|
||||||
when(mockDictionaryService.getAssociation(assoc1)).thenReturn(null);
|
when(mockDictionaryService.getAssociation(assoc1)).thenReturn(null);
|
||||||
when(mockDictionaryService.getAspect(aspect1)).thenReturn(mock(AspectDefinition.class));
|
when(mockDictionaryService.getAspect(aspect1)).thenReturn(mock(AspectDefinition.class));
|
||||||
|
|
||||||
Delegation d = new Delegation();
|
MetadataReferral mr = new MetadataReferral();
|
||||||
d.setAssocType(assoc1);
|
mr.setAssocType(assoc1);
|
||||||
d.setAspects(asSet(aspect1));
|
mr.setAspects(asSet(aspect1));
|
||||||
d.setDictionaryService(mockDictionaryService);
|
mr.setDictionaryService(mockDictionaryService);
|
||||||
d.validateAndRegister();
|
mr.validateAndRegister();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=InvalidDelegation.class)
|
@Test(expected=InvalidMetadataReferral.class)
|
||||||
public void delegateMustHaveAspectsAllOfWhichExist()
|
public void referralMustHaveAspectsAllOfWhichExist()
|
||||||
{
|
{
|
||||||
when(mockDictionaryService.getAssociation(assoc1)).thenReturn(mock(AssociationDefinition.class));
|
when(mockDictionaryService.getAssociation(assoc1)).thenReturn(mock(AssociationDefinition.class));
|
||||||
when(mockDictionaryService.getAspect(aspect1)).thenReturn(mock(AspectDefinition.class));
|
when(mockDictionaryService.getAspect(aspect1)).thenReturn(mock(AspectDefinition.class));
|
||||||
when(mockDictionaryService.getAspect(aspect2)).thenReturn(null);
|
when(mockDictionaryService.getAspect(aspect2)).thenReturn(null);
|
||||||
|
|
||||||
Delegation d = new Delegation();
|
MetadataReferral mr = new MetadataReferral();
|
||||||
d.setAssocType(assoc1);
|
mr.setAssocType(assoc1);
|
||||||
d.setAspects(asSet(aspect1, aspect2));
|
mr.setAspects(asSet(aspect1, aspect2));
|
||||||
d.setDictionaryService(mockDictionaryService);
|
mr.setDictionaryService(mockDictionaryService);
|
||||||
d.validateAndRegister();
|
mr.validateAndRegister();
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -16,10 +16,10 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.alfresco.module.org_alfresco_module_rm.metadatadelegation;
|
package org.alfresco.module.org_alfresco_module_rm.referredmetadata;
|
||||||
|
|
||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
import static org.alfresco.module.org_alfresco_module_rm.metadatadelegation.DelegationException.ChainedDelegationUnsupported;
|
import static org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferredMetadataException.ChainedMetadataReferralUnsupported;
|
||||||
import static org.alfresco.module.org_alfresco_module_rm.test.util.ExceptionUtils.expectedException;
|
import static org.alfresco.module.org_alfresco_module_rm.test.util.ExceptionUtils.expectedException;
|
||||||
import static org.alfresco.module.org_alfresco_module_rm.test.util.FPUtils.asSet;
|
import static org.alfresco.module.org_alfresco_module_rm.test.util.FPUtils.asSet;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
@@ -40,37 +40,37 @@ import org.mockito.Mock;
|
|||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@link DelegationAdminServiceImpl}.
|
* Unit tests for {@link ReferralAdminServiceImpl}.
|
||||||
*
|
*
|
||||||
* @author Neil Mc Erlean
|
* @author Neil Mc Erlean
|
||||||
* @since 3.0.a
|
* @since 2.4.a
|
||||||
*/
|
*/
|
||||||
public class DelegationAdminServiceImplUnitTest
|
public class ReferralAdminServiceImplUnitTest
|
||||||
{
|
{
|
||||||
@InjectMocks private final DelegationAdminServiceImpl delegationAdminService = new DelegationAdminServiceImpl();
|
@InjectMocks private final ReferralAdminServiceImpl referralAdminService = new ReferralAdminServiceImpl();
|
||||||
|
|
||||||
@Mock DictionaryService mockDictionaryService;
|
@Mock DictionaryService mockDictionaryService;
|
||||||
@Mock NodeService mockNodeService;
|
@Mock NodeService mockNodeService;
|
||||||
@Mock DelegationRegistry mockRegistry;
|
@Mock ReferralRegistry mockRegistry;
|
||||||
@Mock DelegationServiceImpl mockDelegationService;
|
@Mock ReferredMetadataServiceImpl mockReferredMetadataService;
|
||||||
|
|
||||||
private final NodeRef node1 = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "node1");
|
private final NodeRef node1 = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "node1");
|
||||||
private final NodeRef node2 = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "node2");
|
private final NodeRef node2 = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "node2");
|
||||||
private final NodeRef node3 = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "node3");
|
private final NodeRef node3 = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "node3");
|
||||||
|
|
||||||
private final QName assoc1 = QName.createQName("test", "assoc1");
|
private final QName assoc1 = QName.createQName("test", "assoc1");
|
||||||
private final QName assoc2 = QName.createQName("test", "assoc2");
|
|
||||||
|
|
||||||
private final QName aspect1 = QName.createQName("test", "aspect1");
|
private final QName aspect1 = QName.createQName("test", "aspect1");
|
||||||
private final QName aspect2 = QName.createQName("test", "aspect2");
|
private final QName aspect2 = QName.createQName("test", "aspect2");
|
||||||
|
|
||||||
|
private final QName assoc2 = QName.createQName("test", "assoc2");
|
||||||
private final QName aspect3 = QName.createQName("test", "aspect3");
|
private final QName aspect3 = QName.createQName("test", "aspect3");
|
||||||
|
|
||||||
private final Delegation delegate1 = new Delegation()
|
private final MetadataReferral referral1 = new MetadataReferral()
|
||||||
{{
|
{{
|
||||||
this.setAssocType(assoc1);
|
this.setAssocType(assoc1);
|
||||||
this.setAspects(asSet(aspect1, aspect2));
|
this.setAspects(asSet(aspect1, aspect2));
|
||||||
}};
|
}};
|
||||||
private final Delegation delegate2 = new Delegation()
|
private final MetadataReferral referral2 = new MetadataReferral()
|
||||||
{{
|
{{
|
||||||
this.setAssocType(assoc2);
|
this.setAssocType(assoc2);
|
||||||
this.setAspects(asSet(aspect3));
|
this.setAspects(asSet(aspect3));
|
||||||
@@ -80,61 +80,61 @@ public class DelegationAdminServiceImplUnitTest
|
|||||||
{
|
{
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
when(mockRegistry.getDelegations()).thenReturn(asSet(delegate1, delegate2));
|
when(mockRegistry.getMetadataReferrals()).thenReturn(asSet(referral1, referral2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IllegalArgumentException.class)
|
@Test(expected=IllegalArgumentException.class)
|
||||||
public void attachingDelegateWithNoAssociationConfiguredShouldFail()
|
public void attachingReferrerWithNoAssociationConfiguredShouldFail()
|
||||||
{
|
{
|
||||||
delegationAdminService.attachDelegate(node1, node2, assoc1);
|
referralAdminService.attachReferrer(node2, node1, assoc1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void attachDetach()
|
@Test public void attachDetach()
|
||||||
{
|
{
|
||||||
when(mockRegistry.getDelegateForAssociation(assoc1)).thenReturn(delegate1);
|
when(mockRegistry.getReferralForAssociation(assoc1)).thenReturn(referral1);
|
||||||
|
|
||||||
// attach
|
// attach
|
||||||
Delegation d = attachDelegate(node1, node2, assoc1);
|
MetadataReferral d = attachReferrer(node1, node2, assoc1);
|
||||||
|
|
||||||
// validate
|
// validate
|
||||||
assertEquals(assoc1, d.getAssocType());
|
assertEquals(assoc1, d.getAssocType());
|
||||||
assertEquals(asSet(aspect1, aspect2), d.getAspects());
|
assertEquals(asSet(aspect1, aspect2), d.getAspects());
|
||||||
assertTrue(mockDelegationService.hasDelegateForAspect(node1, aspect1));
|
assertTrue(mockReferredMetadataService.isReferringMetadata(node1, aspect1));
|
||||||
assertFalse(mockDelegationService.hasDelegateForAspect(node1, aspect3));
|
assertFalse(mockReferredMetadataService.isReferringMetadata(node1, aspect3));
|
||||||
|
|
||||||
// detach
|
// detach
|
||||||
assertEquals(d, delegationAdminService.detachDelegate(node1, assoc1));
|
assertEquals(d, referralAdminService.detachReferrer(node1, assoc1));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Delegation attachDelegate(NodeRef from, NodeRef to, QName assocType)
|
private MetadataReferral attachReferrer(NodeRef referrer, NodeRef referent, QName assocType)
|
||||||
{
|
{
|
||||||
Delegation d = delegationAdminService.attachDelegate(from, to, assocType);
|
MetadataReferral d = referralAdminService.attachReferrer(referrer, referent, assocType);
|
||||||
when(mockNodeService.getSourceAssocs(to, assocType)).thenReturn(asList(new AssociationRef(from, assocType, to)));
|
when(mockNodeService.getSourceAssocs(referent, assocType)).thenReturn(asList(new AssociationRef(referrer, assocType, referent)));
|
||||||
when(mockNodeService.getTargetAssocs(from, assocType)).thenReturn(asList(new AssociationRef(from, assocType, to)));
|
when(mockNodeService.getTargetAssocs(referrer, assocType)).thenReturn(asList(new AssociationRef(referrer, assocType, referent)));
|
||||||
for (QName aspect : d.getAspects())
|
for (QName aspect : d.getAspects())
|
||||||
{
|
{
|
||||||
when(mockDelegationService.hasDelegateForAspect(from, aspect)).thenReturn(true);
|
when(mockReferredMetadataService.isReferringMetadata(referrer, aspect)).thenReturn(true);
|
||||||
}
|
}
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void chainsOfDelegationShouldBePrevented()
|
@Test public void chainsOfDelegationShouldBePrevented()
|
||||||
{
|
{
|
||||||
when(mockRegistry.getDelegateForAssociation(assoc1)).thenReturn(delegate1);
|
when(mockRegistry.getReferralForAssociation(assoc1)).thenReturn(referral1);
|
||||||
|
|
||||||
// The node already has a delegation in place: node1 -> node2. We're trying to add to the
|
// The node already has a delegation in place: node1 -> node2. We're trying to add to the
|
||||||
// end of the chain: node2 -> node3
|
// end of the chain: node2 -> node3
|
||||||
when(mockNodeService.getSourceAssocs(node2, assoc1)).thenReturn(asList(new AssociationRef(node1, assoc1, node2)));
|
when(mockNodeService.getSourceAssocs(node2, assoc1)).thenReturn(asList(new AssociationRef(node1, assoc1, node2)));
|
||||||
when(mockNodeService.getTargetAssocs(node1, assoc1)).thenReturn(asList(new AssociationRef(node1, assoc1, node2)));
|
when(mockNodeService.getTargetAssocs(node1, assoc1)).thenReturn(asList(new AssociationRef(node1, assoc1, node2)));
|
||||||
|
|
||||||
expectedException(ChainedDelegationUnsupported.class, () -> {
|
expectedException(ChainedMetadataReferralUnsupported.class, () -> {
|
||||||
delegationAdminService.attachDelegate(node2, node3, assoc1);
|
referralAdminService.attachReferrer(node2, node3, assoc1);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Now try to add to the start of the chain: node3 -> node1
|
// Now try to add to the start of the chain: node3 -> node1
|
||||||
expectedException(ChainedDelegationUnsupported.class, () -> {
|
expectedException(ChainedMetadataReferralUnsupported.class, () -> {
|
||||||
delegationAdminService.attachDelegate(node3, node1, assoc1);
|
referralAdminService.attachReferrer(node3, node1, assoc1);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
@@ -0,0 +1,195 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2015 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.module.org_alfresco_module_rm.referredmetadata;
|
||||||
|
|
||||||
|
import static java.util.Collections.emptyMap;
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
|
import static org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferredMetadataException.ReferentNodeNotFound;
|
||||||
|
import static org.alfresco.module.org_alfresco_module_rm.referredmetadata.ReferredMetadataException.MetadataReferralNotFound;
|
||||||
|
import static org.alfresco.module.org_alfresco_module_rm.test.util.ExceptionUtils.expectedException;
|
||||||
|
import static org.alfresco.module.org_alfresco_module_rm.test.util.FPUtils.asSet;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Mockito.any;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.eq;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import org.alfresco.service.cmr.dictionary.ClassDefinition;
|
||||||
|
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||||
|
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||||
|
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||||
|
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.namespace.QName;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for {@link ReferredMetadataServiceImpl}.
|
||||||
|
*
|
||||||
|
* @author Neil Mc Erlean
|
||||||
|
* @since 3.0.a
|
||||||
|
*/
|
||||||
|
public class ReferredMetadataServiceImplUnitTest
|
||||||
|
{
|
||||||
|
@InjectMocks private final ReferredMetadataServiceImpl referredMetadataService = new ReferredMetadataServiceImpl();
|
||||||
|
|
||||||
|
@Mock DictionaryService mockDictionaryService;
|
||||||
|
@Mock NodeService mockNodeService;
|
||||||
|
@Mock ReferralAdminServiceImpl mockReferralAdminService;
|
||||||
|
|
||||||
|
/** This node has a referent node. */
|
||||||
|
private final NodeRef referringNode = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "referringNode");
|
||||||
|
/** This is the referent for {@link #referringNode}. */
|
||||||
|
private final NodeRef referentNode = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "referentNode");
|
||||||
|
/** This node has no referent node. */
|
||||||
|
private final NodeRef nodeWithoutReferent = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "nodeWithoutReferent");
|
||||||
|
|
||||||
|
/** The type of the peer association that links the referringNode to its source. */
|
||||||
|
private final QName referralAssocType = QName.createQName("test", "referralAssocType");
|
||||||
|
/** The instance of the association between {@link #referringNode} and {@link #referentNode}. */
|
||||||
|
private final AssociationRef attachedReferralAssocRef = new AssociationRef(referringNode, referralAssocType, referentNode);
|
||||||
|
|
||||||
|
/** Name of an aspect that has been referred. */
|
||||||
|
private final QName referredAspect1 = QName.createQName("test", "referredAspect1");
|
||||||
|
/** Name of an aspect that has been referred. */
|
||||||
|
private final QName referredAspect2 = QName.createQName("test", "referredAspect2");
|
||||||
|
/** Name of a content class (a type in this case) that has not been referred.
|
||||||
|
* N.B. Types can't be referred currently. */
|
||||||
|
private final QName unreferredType = QName.createQName("test", "unreferredType");
|
||||||
|
|
||||||
|
private final QName referredProp = QName.createQName("test", "referredProp");
|
||||||
|
private final Serializable referredPropValue = "hello";
|
||||||
|
private final QName unreferredProp = QName.createQName("test", "unreferredProp");
|
||||||
|
|
||||||
|
private final MetadataReferral referral = new MetadataReferral()
|
||||||
|
{{
|
||||||
|
this.setAssocType(referralAssocType);
|
||||||
|
this.setAspects(asSet(referredAspect1, referredAspect2));
|
||||||
|
}};
|
||||||
|
|
||||||
|
@Before public void setUp()
|
||||||
|
{
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
|
final PropertyDefinition aspectProp = mock(PropertyDefinition.class);
|
||||||
|
final ClassDefinition aspectDefn = mock(ClassDefinition.class);
|
||||||
|
when(aspectDefn.getName()).thenReturn(referredAspect1);
|
||||||
|
when(aspectProp.getContainerClass()).thenReturn(aspectDefn);
|
||||||
|
when(aspectDefn.isAspect()).thenReturn(true);
|
||||||
|
|
||||||
|
final PropertyDefinition typeProp = mock(PropertyDefinition.class);
|
||||||
|
final ClassDefinition typeDefn = mock(ClassDefinition.class);
|
||||||
|
when(typeDefn.getName()).thenReturn(unreferredType);
|
||||||
|
when(typeProp.getContainerClass()).thenReturn(typeDefn);
|
||||||
|
when(typeDefn.isAspect()).thenReturn(false);
|
||||||
|
|
||||||
|
when(mockDictionaryService.getProperty(referredProp)).thenReturn(aspectProp);
|
||||||
|
|
||||||
|
when(mockReferralAdminService.getAttachedReferralsFrom(referringNode)).thenReturn(asSet(referral));
|
||||||
|
for (QName referredAspect : asSet(referredAspect1, referredAspect2))
|
||||||
|
{
|
||||||
|
when(mockReferralAdminService.getReferralFor(referredAspect)).thenReturn(referral);
|
||||||
|
when(mockNodeService.hasAspect(referentNode, referredAspect)).thenReturn(true);
|
||||||
|
}
|
||||||
|
when(mockNodeService.getSourceAssocs(referentNode, referralAssocType)).thenReturn(asList(attachedReferralAssocRef));
|
||||||
|
when(mockNodeService.getTargetAssocs(referringNode, referralAssocType)).thenReturn(asList(attachedReferralAssocRef));
|
||||||
|
when(mockNodeService.exists(any(NodeRef.class))).thenReturn(true);
|
||||||
|
when(mockNodeService.getProperties(referentNode))
|
||||||
|
.thenReturn(new HashMap<QName, Serializable>()
|
||||||
|
{{
|
||||||
|
this.put(referredProp, referredPropValue);
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void isReferringMetadata()
|
||||||
|
{
|
||||||
|
assertTrue(referredMetadataService.isReferringMetadata(referringNode, referredAspect1));
|
||||||
|
expectedException(MetadataReferralNotFound.class,
|
||||||
|
() -> referredMetadataService.isReferringMetadata(nodeWithoutReferent, unreferredType));
|
||||||
|
assertFalse(referredMetadataService.isReferringMetadata(nodeWithoutReferent, referredAspect1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void getReferentNode()
|
||||||
|
{
|
||||||
|
assertEquals(referentNode, referredMetadataService.getReferentNode(referringNode, referredAspect1));
|
||||||
|
expectedException(MetadataReferralNotFound.class,
|
||||||
|
() -> {
|
||||||
|
referredMetadataService.getReferentNode(referringNode, unreferredType);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
assertNull(referredMetadataService.getReferentNode(nodeWithoutReferent, referredAspect1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void getReferredProperties()
|
||||||
|
{
|
||||||
|
final Map<QName, Serializable> expectedProps = new HashMap<>();
|
||||||
|
expectedProps.put(referredProp, referredPropValue);
|
||||||
|
|
||||||
|
assertEquals(expectedProps, referredMetadataService.getReferredProperties(referringNode, referredAspect1));
|
||||||
|
|
||||||
|
expectedException(MetadataReferralNotFound.class,
|
||||||
|
() -> referredMetadataService.getReferredProperties(referringNode, unreferredType));
|
||||||
|
|
||||||
|
expectedException(ReferentNodeNotFound.class,
|
||||||
|
() -> referredMetadataService.getReferredProperties(nodeWithoutReferent, referredAspect1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void getReferredProperty()
|
||||||
|
{
|
||||||
|
assertEquals(referredPropValue, referredMetadataService.getReferredProperty(referringNode, referredProp));
|
||||||
|
|
||||||
|
expectedException(IllegalArgumentException.class,
|
||||||
|
() -> referredMetadataService.getReferredProperty(referringNode, unreferredProp));
|
||||||
|
|
||||||
|
expectedException(MetadataReferralNotFound.class,
|
||||||
|
() -> referredMetadataService.getReferredProperties(nodeWithoutReferent, referredProp));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void hasReferredAspect()
|
||||||
|
{
|
||||||
|
assertTrue(referredMetadataService.hasReferredAspect(referringNode, referredAspect1));
|
||||||
|
|
||||||
|
expectedException(MetadataReferralNotFound.class,
|
||||||
|
() -> referredMetadataService.hasReferredAspect(referringNode, unreferredType));
|
||||||
|
|
||||||
|
expectedException(ReferentNodeNotFound.class,
|
||||||
|
() -> referredMetadataService.hasReferredAspect(nodeWithoutReferent, referredAspect1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void getAttachedReferrals()
|
||||||
|
{
|
||||||
|
final Map<MetadataReferral, NodeRef> expectedReferrals = new HashMap<>();
|
||||||
|
expectedReferrals.put(referral, referentNode);
|
||||||
|
|
||||||
|
assertEquals(expectedReferrals, referredMetadataService.getAttachedReferrals(referringNode));
|
||||||
|
assertEquals(emptyMap(), referredMetadataService.getAttachedReferrals(nodeWithoutReferent));
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user