mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
Merged V3.2 to HEAD
17294: Fix for ETHREEOH-3194 - It's impossible to find Blogs and Discussions by title. 17301: Activity Service fixes (ETHREEOH-1362 & ETHREEOH-1741) 17302: Fix for ETHREEOH-2849 JPG to GIF transformation fails when using imagemagick cmd line options listed in our wiki 17305: AVM - fix AVMStoreDescriptor ( creator/createDate) returned by getStores 17306: Fix for ETHREEOH-1578 - Incorrect behavior of Calendar in Month view ... 17318: Merged V3.1 to V3.2 17317: Fix for ETHREEOH-3236 It is impossible to change start location, everything is reverted to My Alfresco 17320: Merged V3.1 to V3.2 17287 - Fix for ETHREEOH-110- It is impossible to browse events by tags 17326: iBatis mapping fixes for AVM on Oracle (including ETHREEOH-3205) 17327: Merged V3.1 to V3.2 17324: Fix for ETHREEOH-2723 Script error appears when trying to edit Home Space Name for user 17329: Merged V3.1 to V3.2 17180: Merged V2.2 to V3.1 17164: Fixes for deletion of large hierarchies: (ETHREEOH-2161 and ETHREEOH-2650) 17179: (RECORD ONLY) Merged V3.1 to V2.2 ... 17330: Fix for SiteActivityTest failure (caused by earlier -ve test data) 17331: Merged V3.1 to V3.2 17190: Further fixes for ETHREEOH-2161: Delete process hangs when deleting large directory structure (with rules applied) 17207: Fix fallout from work on ETHREEOH-2161: Delete process hangs when deleting large directory structure (with rules applied) 17215: Added back firing of policies for archive stores 17351: Build fix check in to DBNodeService. Will be followed by full fix when available. 17353: Applied TransactionListenerAdapter ___________________________________________________________________ Modified: svn:mergeinfo Reverse-merged /alfresco/BRANCHES/V3.1:r13091 Merged /alfresco/BRANCHES/V2.2:r13089,13091,14190-14191,14199,14210,14216,14229,14655,14825,14869,17164,17179 Merged /alfresco/BRANCHES/V3.1:r17180,17190,17207,17215,17287,17317,17324 Merged /alfresco/BRANCHES/V3.2:r17294,17301-17302,17305-17306,17318,17320,17326-17327,17329-17331,17351,17353 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@18056 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
<!DOCTYPE sqlMap
|
<!DOCTYPE sqlMap
|
||||||
PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
|
PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
|
||||||
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
|
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
|
||||||
|
|
||||||
<sqlMap namespace="alfresco.activities">
|
<sqlMap namespace="alfresco.activities">
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
<typeAlias alias="ActivityFeed" type="org.alfresco.repo.domain.activities.ActivityFeedEntity"/>
|
<typeAlias alias="ActivityFeed" type="org.alfresco.repo.domain.activities.ActivityFeedEntity"/>
|
||||||
<typeAlias alias="FeedControl" type="org.alfresco.repo.domain.activities.FeedControlEntity"/>
|
<typeAlias alias="FeedControl" type="org.alfresco.repo.domain.activities.FeedControlEntity"/>
|
||||||
<typeAlias alias="ActivityPost" type="org.alfresco.repo.domain.activities.ActivityPostEntity"/>
|
<typeAlias alias="ActivityPost" type="org.alfresco.repo.domain.activities.ActivityPostEntity"/>
|
||||||
|
|
||||||
<resultMap id="ActivityFeedResult" class="ActivityFeed">
|
<resultMap id="ActivityFeedResult" class="ActivityFeed">
|
||||||
<result property="id" column="id" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
<result property="id" column="id" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||||
<result property="feedUserId" column="feed_user_id"/>
|
<result property="feedUserId" column="feed_user_id"/>
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
<result property="activitySummaryFormat" column="activity_format"/>
|
<result property="activitySummaryFormat" column="activity_format"/>
|
||||||
<result property="feedDate" column="feed_date"/>
|
<result property="feedDate" column="feed_date"/>
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<resultMap id="FeedControlResult" class="FeedControl">
|
<resultMap id="FeedControlResult" class="FeedControl">
|
||||||
<result property="id" column="id" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
<result property="id" column="id" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||||
<result property="feedUserId" column="feed_user_id"/>
|
<result property="feedUserId" column="feed_user_id"/>
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
<result property="appTool" column="app_tool"/>
|
<result property="appTool" column="app_tool"/>
|
||||||
<result property="lastModified" column="last_modified"/>
|
<result property="lastModified" column="last_modified"/>
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<resultMap id="ActivityPostResult" class="ActivityPost">
|
<resultMap id="ActivityPostResult" class="ActivityPost">
|
||||||
<result property="id" column="sequence_id" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
<result property="id" column="sequence_id" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||||
<result property="activityData" column="activity_data"/>
|
<result property="activityData" column="activity_data"/>
|
||||||
@@ -170,14 +170,14 @@
|
|||||||
where feed_user_id = #feedUserId#
|
where feed_user_id = #feedUserId#
|
||||||
]]>
|
]]>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="select_activity_feedcontrol" parameterClass="FeedControl" resultClass="long">
|
<select id="select_activity_feedcontrol" parameterClass="FeedControl" resultClass="long">
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
select id as id
|
select id as id
|
||||||
from alf_activity_feed_control
|
from alf_activity_feed_control
|
||||||
where feed_user_id = #feedUserId#
|
where feed_user_id = #feedUserId#
|
||||||
and site_network = #siteNetwork#
|
and ((site_network = #siteNetwork#) or ((#siteNetwork# is null) and (site_network is null)))
|
||||||
and app_tool = #appTool#
|
and ((app_tool = #appTool#) or ((#appTool# is null) and (app_tool is null)))
|
||||||
]]>
|
]]>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
@@ -185,11 +185,11 @@
|
|||||||
<![CDATA[
|
<![CDATA[
|
||||||
delete from alf_activity_feed_control
|
delete from alf_activity_feed_control
|
||||||
where feed_user_id = #feedUserId#
|
where feed_user_id = #feedUserId#
|
||||||
and site_network = #siteNetwork#
|
and ((site_network = #siteNetwork#) or ((#siteNetwork# is null) and (site_network is null)))
|
||||||
and app_tool = #appTool#
|
and ((app_tool = #appTool#) or ((#appTool# is null) and (app_tool is null)))
|
||||||
]]>
|
]]>
|
||||||
</delete>
|
</delete>
|
||||||
|
|
||||||
<select id="select_activity_posts" parameterClass="ActivityPost" resultClass="ActivityPost">
|
<select id="select_activity_posts" parameterClass="ActivityPost" resultClass="ActivityPost">
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
select
|
select
|
||||||
@@ -211,7 +211,7 @@
|
|||||||
status = #status#
|
status = #status#
|
||||||
]]>
|
]]>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="select_activity_posts_by_status_only" parameterClass="ActivityPost" resultClass="ActivityPost">
|
<select id="select_activity_posts_by_status_only" parameterClass="ActivityPost" resultClass="ActivityPost">
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
select
|
select
|
||||||
@@ -230,25 +230,25 @@
|
|||||||
status = #status#
|
status = #status#
|
||||||
]]>
|
]]>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="select_activity_post_max_seq" resultClass="long">
|
<select id="select_activity_post_max_seq" resultClass="long">
|
||||||
select max(sequence_id) as maxId
|
select max(sequence_id) as maxId
|
||||||
from alf_activity_post
|
from alf_activity_post
|
||||||
where status = 'POSTED'
|
where status = 'POSTED'
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="select_activity_post_min_seq" resultClass="long">
|
<select id="select_activity_post_min_seq" resultClass="long">
|
||||||
select min(sequence_id) as minId
|
select min(sequence_id) as minId
|
||||||
from alf_activity_post
|
from alf_activity_post
|
||||||
where status = 'POSTED'
|
where status = 'POSTED'
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="select_activity_post_max_jobtasknode" resultClass="int">
|
<select id="select_activity_post_max_jobtasknode" resultClass="int">
|
||||||
select max(job_task_node) as maxJobTaskNode
|
select max(job_task_node) as maxJobTaskNode
|
||||||
from alf_activity_post
|
from alf_activity_post
|
||||||
where status = 'POSTED'
|
where status = 'POSTED'
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<delete id="delete_activity_posts_older_than_date" parameterClass="ActivityPost">
|
<delete id="delete_activity_posts_older_than_date" parameterClass="ActivityPost">
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
delete from alf_activity_post
|
delete from alf_activity_post
|
||||||
@@ -256,17 +256,17 @@
|
|||||||
and status = #status#
|
and status = #status#
|
||||||
]]>
|
]]>
|
||||||
</delete>
|
</delete>
|
||||||
|
|
||||||
<update id="update_activity_post_data" parameterClass="ActivityPost">
|
<update id="update_activity_post_data" parameterClass="ActivityPost">
|
||||||
update alf_activity_post set status = #status#, activity_data=#activityData#, site_network=#siteNetwork#, last_modified=#lastModified#
|
update alf_activity_post set status = #status#, activity_data=#activityData#, site_network=#siteNetwork#, last_modified=#lastModified#
|
||||||
where sequence_id = #id#
|
where sequence_id = #id#
|
||||||
and status != #status#
|
and status != #status#
|
||||||
</update>
|
</update>
|
||||||
|
|
||||||
<update id="update_activity_post_status" parameterClass="ActivityPost">
|
<update id="update_activity_post_status" parameterClass="ActivityPost">
|
||||||
update alf_activity_post set status = #status#, last_modified=#lastModified#
|
update alf_activity_post set status = #status#, last_modified=#lastModified#
|
||||||
where sequence_id = #id#
|
where sequence_id = #id#
|
||||||
and status != #status#
|
and status != #status#
|
||||||
</update>
|
</update>
|
||||||
|
|
||||||
</sqlMap>
|
</sqlMap>
|
@@ -181,7 +181,7 @@
|
|||||||
<parameter property="longValue" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
<parameter property="longValue" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||||
<parameter property="floatValue" jdbcType="FLOAT" javaType="java.lang.Float"/>
|
<parameter property="floatValue" jdbcType="FLOAT" javaType="java.lang.Float"/>
|
||||||
<parameter property="doubleValue" jdbcType="DOUBLE" javaType="java.lang.Double"/>
|
<parameter property="doubleValue" jdbcType="DOUBLE" javaType="java.lang.Double"/>
|
||||||
<parameter property="stringValue" jdbcType="TEXT" javaType="java.lang.String"/>
|
<parameter property="stringValue" jdbcType="VARCHAR" javaType="java.lang.String"/>
|
||||||
<parameter property="serializableValue" jdbcType="BLOB" javaType="java.io.Serializable"/>
|
<parameter property="serializableValue" jdbcType="BLOB" javaType="java.io.Serializable"/>
|
||||||
<parameter property="nodeId" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
<parameter property="nodeId" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||||
<parameter property="qnameId" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
<parameter property="qnameId" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||||
@@ -195,7 +195,7 @@
|
|||||||
<parameter property="longValue" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
<parameter property="longValue" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||||
<parameter property="floatValue" jdbcType="FLOAT" javaType="java.lang.Float"/>
|
<parameter property="floatValue" jdbcType="FLOAT" javaType="java.lang.Float"/>
|
||||||
<parameter property="doubleValue" jdbcType="DOUBLE" javaType="java.lang.Double"/>
|
<parameter property="doubleValue" jdbcType="DOUBLE" javaType="java.lang.Double"/>
|
||||||
<parameter property="stringValue" jdbcType="TEXT" javaType="java.lang.String"/>
|
<parameter property="stringValue" jdbcType="VARCHAR" javaType="java.lang.String"/>
|
||||||
<parameter property="serializableValue" jdbcType="BLOB" javaType="java.io.Serializable"/>
|
<parameter property="serializableValue" jdbcType="BLOB" javaType="java.io.Serializable"/>
|
||||||
<parameter property="avmStoreId" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
<parameter property="avmStoreId" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||||
<parameter property="qnameId" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
<parameter property="qnameId" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||||
@@ -697,6 +697,7 @@
|
|||||||
avm_version_roots
|
avm_version_roots
|
||||||
where
|
where
|
||||||
avm_store_id = ?
|
avm_store_id = ?
|
||||||
|
order by version_id
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="select_AVMVersionRootsByTo" parameterMap="parameter_IdToMap" resultMap="result_AVMVersionRoot">
|
<select id="select_AVMVersionRootsByTo" parameterMap="parameter_IdToMap" resultMap="result_AVMVersionRoot">
|
||||||
@@ -708,7 +709,7 @@
|
|||||||
where
|
where
|
||||||
avm_store_id = ? and
|
avm_store_id = ? and
|
||||||
create_date <= ?
|
create_date <= ?
|
||||||
order by version_id;
|
order by version_id
|
||||||
]]>
|
]]>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
@@ -720,7 +721,7 @@
|
|||||||
where
|
where
|
||||||
avm_store_id = ? and
|
avm_store_id = ? and
|
||||||
create_date >= ?
|
create_date >= ?
|
||||||
order by version_id;
|
order by version_id
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="select_AVMVersionRootsBetween" parameterMap="parameter_IdFromToMap" resultMap="result_AVMVersionRoot">
|
<select id="select_AVMVersionRootsBetween" parameterMap="parameter_IdFromToMap" resultMap="result_AVMVersionRoot">
|
||||||
@@ -731,7 +732,7 @@
|
|||||||
where
|
where
|
||||||
avm_store_id = ? and
|
avm_store_id = ? and
|
||||||
create_date between ? and ?
|
create_date between ? and ?
|
||||||
order by version_id;
|
order by version_id
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<!-- Optimistic update of the version root -->
|
<!-- Optimistic update of the version root -->
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
<parameter property="longValue" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
<parameter property="longValue" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||||
<parameter property="floatValue" jdbcType="FLOAT" javaType="java.lang.Float"/>
|
<parameter property="floatValue" jdbcType="FLOAT" javaType="java.lang.Float"/>
|
||||||
<parameter property="doubleValue" jdbcType="DOUBLE" javaType="java.lang.Double"/>
|
<parameter property="doubleValue" jdbcType="DOUBLE" javaType="java.lang.Double"/>
|
||||||
<parameter property="stringValue" jdbcType="TEXT" javaType="java.lang.String"/>
|
<parameter property="stringValue" jdbcType="VARCHAR" javaType="java.lang.String"/>
|
||||||
<parameter property="serializableValue" jdbcType="BLOB" javaType="java.io.Serializable"/>
|
<parameter property="serializableValue" jdbcType="BLOB" javaType="java.io.Serializable"/>
|
||||||
<parameter property="avmStoreId" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
<parameter property="avmStoreId" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||||
<parameter property="qnameId" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
<parameter property="qnameId" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||||
|
@@ -196,9 +196,6 @@
|
|||||||
<ref bean="nodeDaoService" />
|
<ref bean="nodeDaoService" />
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
<bean id="nodeCleanup.moveChildrenToCorrectStore"
|
|
||||||
class="org.alfresco.repo.node.db.DbNodeServiceImpl$MoveChildrenToCorrectStore"
|
|
||||||
parent="nodeCleanupBase"/>
|
|
||||||
<bean id="nodeCleanup.indexChildrenWhereRequired"
|
<bean id="nodeCleanup.indexChildrenWhereRequired"
|
||||||
class="org.alfresco.repo.node.db.IndexChildrenWhereRequiredWorker"
|
class="org.alfresco.repo.node.db.IndexChildrenWhereRequiredWorker"
|
||||||
parent="nodeCleanupBase"/>
|
parent="nodeCleanupBase"/>
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
<!-- Rules Service -->
|
<!-- Rules Service -->
|
||||||
|
|
||||||
<bean id="ruleService" class="org.alfresco.repo.rule.RuleServiceImpl">
|
<bean id="ruleService" class="org.alfresco.repo.rule.RuleServiceImpl" init-method="init">
|
||||||
<property name="nodeService">
|
<property name="nodeService">
|
||||||
<ref bean="NodeService"/>
|
<ref bean="NodeService"/>
|
||||||
</property>
|
</property>
|
||||||
@@ -21,9 +21,15 @@
|
|||||||
<property name="dictionaryService">
|
<property name="dictionaryService">
|
||||||
<ref bean="dictionaryService"/>
|
<ref bean="dictionaryService"/>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="policyComponent">
|
||||||
|
<ref bean="policyComponent"/>
|
||||||
|
</property>
|
||||||
<property name="permissionService">
|
<property name="permissionService">
|
||||||
<ref bean="permissionService"/>
|
<ref bean="permissionService"/>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="nodeRulesCache">
|
||||||
|
<ref bean="nodeRulesCache"/>
|
||||||
|
</property>
|
||||||
<property name="rulesDisabled">
|
<property name="rulesDisabled">
|
||||||
<value>false</value>
|
<value>false</value>
|
||||||
</property>
|
</property>
|
||||||
|
@@ -6,6 +6,7 @@ public interface ActionModel
|
|||||||
{
|
{
|
||||||
static final String ACTION_MODEL_URI = "http://www.alfresco.org/model/action/1.0";
|
static final String ACTION_MODEL_URI = "http://www.alfresco.org/model/action/1.0";
|
||||||
static final String ACTION_MODEL_PREFIX = "act";
|
static final String ACTION_MODEL_PREFIX = "act";
|
||||||
|
static final QName TYPE_ACTION_BASE = QName.createQName(ACTION_MODEL_URI, "actionbase");
|
||||||
static final QName TYPE_ACTION = QName.createQName(ACTION_MODEL_URI, "action");
|
static final QName TYPE_ACTION = QName.createQName(ACTION_MODEL_URI, "action");
|
||||||
static final QName PROP_DEFINITION_NAME = QName.createQName(ACTION_MODEL_URI, "definitionName");
|
static final QName PROP_DEFINITION_NAME = QName.createQName(ACTION_MODEL_URI, "definitionName");
|
||||||
static final QName PROP_ACTION_TITLE = QName.createQName(ACTION_MODEL_URI, "actionTitle");
|
static final QName PROP_ACTION_TITLE = QName.createQName(ACTION_MODEL_URI, "actionTitle");
|
||||||
|
@@ -48,12 +48,6 @@ public class ActivityPostServiceImpl implements ActivityPostService
|
|||||||
{
|
{
|
||||||
private static final Log logger = LogFactory.getLog(ActivityServiceImpl.class);
|
private static final Log logger = LogFactory.getLog(ActivityServiceImpl.class);
|
||||||
|
|
||||||
private static final int MAX_LEN_USER_ID = 255; // needs to match schema: feed_user_id, post_user_id
|
|
||||||
private static final int MAX_LEN_SITE_ID = 255; // needs to match schema: site_network
|
|
||||||
private static final int MAX_LEN_ACTIVITY_TYPE = 255; // needs to match schema: activity_type
|
|
||||||
private static final int MAX_LEN_ACTIVITY_DATA = 4000; // needs to match schema: activity_data
|
|
||||||
private static final int MAX_LEN_APP_TOOL_ID = 36; // needs to match schema: app_tool
|
|
||||||
|
|
||||||
private ActivityPostDAO postDAO;
|
private ActivityPostDAO postDAO;
|
||||||
private TenantService tenantService;
|
private TenantService tenantService;
|
||||||
private int estGridSize = 1;
|
private int estGridSize = 1;
|
||||||
@@ -148,9 +142,9 @@ public class ActivityPostServiceImpl implements ActivityPostService
|
|||||||
{
|
{
|
||||||
siteId = "";
|
siteId = "";
|
||||||
}
|
}
|
||||||
else if (siteId.length() > MAX_LEN_SITE_ID)
|
else if (siteId.length() > ActivityPostDAO.MAX_LEN_SITE_ID)
|
||||||
{
|
{
|
||||||
throw new AlfrescoRuntimeException("Invalid siteId - exceeds " + MAX_LEN_SITE_ID + " chars: " + siteId);
|
throw new IllegalArgumentException("Invalid siteId - exceeds " + ActivityPostDAO.MAX_LEN_SITE_ID + " chars: " + siteId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// optional - default to empty string
|
// optional - default to empty string
|
||||||
@@ -158,17 +152,17 @@ public class ActivityPostServiceImpl implements ActivityPostService
|
|||||||
{
|
{
|
||||||
appTool = "";
|
appTool = "";
|
||||||
}
|
}
|
||||||
else if (appTool.length() > MAX_LEN_APP_TOOL_ID)
|
else if (appTool.length() > ActivityPostDAO.MAX_LEN_APP_TOOL_ID)
|
||||||
{
|
{
|
||||||
throw new AlfrescoRuntimeException("Invalid app tool - exceeds " + MAX_LEN_APP_TOOL_ID + " chars: " + appTool);
|
throw new IllegalArgumentException("Invalid app tool - exceeds " + ActivityPostDAO.MAX_LEN_APP_TOOL_ID + " chars: " + appTool);
|
||||||
}
|
}
|
||||||
|
|
||||||
// required
|
// required
|
||||||
ParameterCheck.mandatoryString("activityType", activityType);
|
ParameterCheck.mandatoryString("activityType", activityType);
|
||||||
|
|
||||||
if (activityType.length() > MAX_LEN_ACTIVITY_TYPE)
|
if (activityType.length() > ActivityPostDAO.MAX_LEN_ACTIVITY_TYPE)
|
||||||
{
|
{
|
||||||
throw new AlfrescoRuntimeException("Invalid activity type - exceeds " + MAX_LEN_ACTIVITY_TYPE + " chars: " + activityType);
|
throw new IllegalArgumentException("Invalid activity type - exceeds " + ActivityPostDAO.MAX_LEN_ACTIVITY_TYPE + " chars: " + activityType);
|
||||||
}
|
}
|
||||||
|
|
||||||
// optional - default to empty string
|
// optional - default to empty string
|
||||||
@@ -176,24 +170,24 @@ public class ActivityPostServiceImpl implements ActivityPostService
|
|||||||
{
|
{
|
||||||
activityData = "";
|
activityData = "";
|
||||||
}
|
}
|
||||||
else if (activityType.length() > MAX_LEN_ACTIVITY_DATA)
|
else if (activityData.length() > ActivityPostDAO.MAX_LEN_ACTIVITY_DATA)
|
||||||
{
|
{
|
||||||
throw new AlfrescoRuntimeException("Invalid activity data - exceeds " + MAX_LEN_ACTIVITY_DATA + " chars: " + activityData);
|
throw new IllegalArgumentException("Invalid activity data - exceeds " + ActivityPostDAO.MAX_LEN_ACTIVITY_DATA + " chars: " + activityData);
|
||||||
}
|
}
|
||||||
|
|
||||||
// required
|
// required
|
||||||
ParameterCheck.mandatoryString("currentUser", currentUser);
|
ParameterCheck.mandatoryString("currentUser", currentUser);
|
||||||
|
|
||||||
if (currentUser.length() > MAX_LEN_USER_ID)
|
if (currentUser.length() > ActivityPostDAO.MAX_LEN_USER_ID)
|
||||||
{
|
{
|
||||||
throw new AlfrescoRuntimeException("Invalid user - exceeds " + MAX_LEN_USER_ID + " chars: " + currentUser);
|
throw new IllegalArgumentException("Invalid user - exceeds " + ActivityPostDAO.MAX_LEN_USER_ID + " chars: " + currentUser);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (AlfrescoRuntimeException e)
|
catch (IllegalArgumentException e)
|
||||||
{
|
{
|
||||||
// log error and throw exception
|
// log error and throw exception
|
||||||
logger.error(e);
|
logger.error(e);
|
||||||
throw e;
|
throw new IllegalArgumentException("Failed to post activity: " + e, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@@ -45,6 +45,7 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
import org.alfresco.repo.domain.activities.ActivityFeedDAO;
|
||||||
import org.alfresco.repo.domain.activities.ActivityFeedEntity;
|
import org.alfresco.repo.domain.activities.ActivityFeedEntity;
|
||||||
import org.alfresco.repo.domain.activities.ActivityPostEntity;
|
import org.alfresco.repo.domain.activities.ActivityPostEntity;
|
||||||
import org.alfresco.repo.domain.activities.FeedControlEntity;
|
import org.alfresco.repo.domain.activities.FeedControlEntity;
|
||||||
@@ -113,7 +114,7 @@ public abstract class FeedTaskProcessor
|
|||||||
Map<String, Set<String>> siteConnectedUsers = new TreeMap<String, Set<String>>();
|
Map<String, Set<String>> siteConnectedUsers = new TreeMap<String, Set<String>>();
|
||||||
|
|
||||||
Map<String, Template> templateCache = new TreeMap<String, Template>();
|
Map<String, Template> templateCache = new TreeMap<String, Template>();
|
||||||
|
|
||||||
// for each activity post ...
|
// for each activity post ...
|
||||||
for (ActivityPostEntity activityPost : activityPosts)
|
for (ActivityPostEntity activityPost : activityPosts)
|
||||||
{
|
{
|
||||||
@@ -179,7 +180,7 @@ public abstract class FeedTaskProcessor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fmTemplates.size() == 0)
|
if (fmTemplates.size() == 0)
|
||||||
{
|
{
|
||||||
logger.error(">>> Skipping activity post " + activityPost.getId() + " since no specific/generic templates for activityType: " + activityType );
|
logger.error(">>> Skipping activity post " + activityPost.getId() + " since no specific/generic templates for activityType: " + activityType );
|
||||||
@@ -199,18 +200,17 @@ public abstract class FeedTaskProcessor
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String thisSite = activityPost.getSiteNetwork();
|
||||||
|
|
||||||
model.put("activityType", activityPost.getActivityType());
|
model.put("activityType", activityPost.getActivityType());
|
||||||
model.put("siteNetwork", activityPost.getSiteNetwork());
|
model.put("siteNetwork", thisSite);
|
||||||
model.put("userId", activityPost.getUserId());
|
model.put("userId", activityPost.getUserId());
|
||||||
model.put("id", activityPost.getId());
|
model.put("id", activityPost.getId());
|
||||||
model.put("date", activityPost.getPostDate()); // post date rather than time that feed is generated
|
model.put("date", activityPost.getPostDate()); // post date rather than time that feed is generated
|
||||||
model.put("xmldate", new ISO8601DateFormatMethod());
|
model.put("xmldate", new ISO8601DateFormatMethod());
|
||||||
model.put("repoEndPoint", ctx.getRepoEndPoint());
|
model.put("repoEndPoint", ctx.getRepoEndPoint());
|
||||||
|
|
||||||
// Get the members of this site
|
// Get the members of this site - save hammering the repository by reusing cached site members
|
||||||
String thisSite = activityPost.getSiteNetwork();
|
|
||||||
|
|
||||||
// Save hammering the repository by reusing cached site members
|
|
||||||
Set<String> connectedUsers = siteConnectedUsers.get(thisSite);
|
Set<String> connectedUsers = siteConnectedUsers.get(thisSite);
|
||||||
if (connectedUsers == null)
|
if (connectedUsers == null)
|
||||||
{
|
{
|
||||||
@@ -237,7 +237,7 @@ public abstract class FeedTaskProcessor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
startTransaction();
|
startTransaction();
|
||||||
@@ -258,15 +258,15 @@ public abstract class FeedTaskProcessor
|
|||||||
}
|
}
|
||||||
|
|
||||||
// filter based on opt-out feed controls (if any)
|
// filter based on opt-out feed controls (if any)
|
||||||
if (! acceptActivity(activityPost, feedControls))
|
if (! acceptActivity(activityPost, feedControls))
|
||||||
{
|
{
|
||||||
excludedConnections++;
|
excludedConnections++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (String fmTemplate : fmTemplates)
|
for (String fmTemplate : fmTemplates)
|
||||||
{
|
{
|
||||||
// determine format - based on template naming convention
|
// determine format - based on template naming convention
|
||||||
String formatFound = null;
|
String formatFound = null;
|
||||||
for (String format : formats)
|
for (String format : formats)
|
||||||
{
|
{
|
||||||
@@ -275,7 +275,7 @@ public abstract class FeedTaskProcessor
|
|||||||
formatFound = format;
|
formatFound = format;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (formatFound == null)
|
if (formatFound == null)
|
||||||
{
|
{
|
||||||
@@ -283,48 +283,55 @@ public abstract class FeedTaskProcessor
|
|||||||
logger.warn("Unknown format for: " + fmTemplate + " default to '"+formatFound+"'");
|
logger.warn("Unknown format for: " + fmTemplate + " default to '"+formatFound+"'");
|
||||||
}
|
}
|
||||||
|
|
||||||
ActivityFeedEntity feed = new ActivityFeedEntity();
|
ActivityFeedEntity feed = new ActivityFeedEntity();
|
||||||
|
|
||||||
// Generate activity feed summary
|
// Generate activity feed summary
|
||||||
feed.setFeedUserId(connectedUser);
|
feed.setFeedUserId(connectedUser);
|
||||||
feed.setPostUserId(postingUserId);
|
feed.setPostUserId(postingUserId);
|
||||||
feed.setActivityType(activityType);
|
feed.setActivityType(activityType);
|
||||||
|
|
||||||
if (formatFound.equals("json"))
|
if (formatFound.equals("json"))
|
||||||
{
|
{
|
||||||
// allows generic JSON template to simply pass straight through
|
// allows generic JSON template to simply pass straight through
|
||||||
model.put("activityData", activityPost.getActivityData());
|
model.put("activityData", activityPost.getActivityData());
|
||||||
}
|
}
|
||||||
|
|
||||||
String activitySummary = processFreemarker(templateCache, fmTemplate, cfg, model);
|
String activitySummary = processFreemarker(templateCache, fmTemplate, cfg, model);
|
||||||
if (! activitySummary.equals(""))
|
if (! activitySummary.equals(""))
|
||||||
{
|
{
|
||||||
feed.setActivitySummary(activitySummary);
|
if (activitySummary.length() > ActivityFeedDAO.MAX_LEN_ACTIVITY_SUMMARY)
|
||||||
feed.setActivitySummaryFormat(formatFound);
|
{
|
||||||
feed.setSiteNetwork(thisSite);
|
logger.warn("Skip feed entry (activity post " + activityPost.getId() + ") since activity summary - exceeds " + ActivityFeedDAO.MAX_LEN_ACTIVITY_SUMMARY + " chars: " + activitySummary);
|
||||||
feed.setAppTool(activityPost.getAppTool());
|
}
|
||||||
feed.setPostDate(activityPost.getPostDate());
|
else
|
||||||
feed.setPostId(activityPost.getId());
|
{
|
||||||
feed.setFeedDate(new Date());
|
feed.setActivitySummary(activitySummary);
|
||||||
|
feed.setActivitySummaryFormat(formatFound);
|
||||||
// Insert activity feed
|
feed.setSiteNetwork(thisSite);
|
||||||
insertFeedEntry(feed); // ignore returned feedId
|
feed.setAppTool(activityPost.getAppTool());
|
||||||
|
feed.setPostDate(activityPost.getPostDate());
|
||||||
totalGenerated++;
|
feed.setPostId(activityPost.getId());
|
||||||
}
|
feed.setFeedDate(new Date());
|
||||||
else
|
|
||||||
{
|
// Insert activity feed
|
||||||
if (logger.isDebugEnabled())
|
insertFeedEntry(feed); // ignore returned feedId
|
||||||
|
|
||||||
|
totalGenerated++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
logger.debug("Empty template result for activityType '" + activityType + "' using format '" + formatFound + "' hence skip feed entry (activity post " + activityPost.getId() + ")");
|
logger.debug("Empty template result for activityType '" + activityType + "' using format '" + formatFound + "' hence skip feed entry (activity post " + activityPost.getId() + ")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updatePostStatus(activityPost.getId(), ActivityPostEntity.STATUS.PROCESSED);
|
updatePostStatus(activityPost.getId(), ActivityPostEntity.STATUS.PROCESSED);
|
||||||
|
|
||||||
commitTransaction();
|
commitTransaction();
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
@@ -366,21 +373,21 @@ public abstract class FeedTaskProcessor
|
|||||||
|
|
||||||
protected String callWebScript(String urlString, String ticket) throws MalformedURLException, URISyntaxException, IOException
|
protected String callWebScript(String urlString, String ticket) throws MalformedURLException, URISyntaxException, IOException
|
||||||
{
|
{
|
||||||
URL url = new URL(urlString);
|
URL url = new URL(urlString);
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
logger.debug(">>> Request URI: " + url.toURI());
|
logger.debug(">>> Request URI: " + url.toURI());
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
|
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
|
||||||
conn.setRequestMethod("GET");
|
conn.setRequestMethod("GET");
|
||||||
|
|
||||||
if (ticket != null)
|
if (ticket != null)
|
||||||
{
|
{
|
||||||
// add Base64 encoded authorization header
|
// add Base64 encoded authorization header
|
||||||
// refer to: http://wiki.alfresco.com/wiki/Web_Scripts_Framework#HTTP_Basic_Authentication
|
// refer to: http://wiki.alfresco.com/wiki/Web_Scripts_Framework#HTTP_Basic_Authentication
|
||||||
conn.addRequestProperty("Authorization", "Basic " + Base64.encodeBytes(ticket.getBytes()));
|
conn.addRequestProperty("Authorization", "Basic " + Base64.encodeBytes(ticket.getBytes()));
|
||||||
}
|
}
|
||||||
|
|
||||||
String result = null;
|
String result = null;
|
||||||
@@ -389,34 +396,35 @@ public abstract class FeedTaskProcessor
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
is = conn.getInputStream();
|
is = conn.getInputStream();
|
||||||
br = new BufferedReader(new InputStreamReader(is));
|
br = new BufferedReader(new InputStreamReader(is));
|
||||||
|
|
||||||
String line = null;
|
String line = null;
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuffer sb = new StringBuffer();
|
||||||
while(((line = br.readLine()) !=null)) {
|
while(((line = br.readLine()) !=null))
|
||||||
sb.append(line);
|
{
|
||||||
}
|
sb.append(line);
|
||||||
|
}
|
||||||
result = sb.toString();
|
|
||||||
|
result = sb.toString();
|
||||||
if (logger.isDebugEnabled())
|
|
||||||
{
|
if (logger.isDebugEnabled())
|
||||||
int responseCode = conn.getResponseCode();
|
{
|
||||||
logger.debug(">>> Response code: " + responseCode);
|
int responseCode = conn.getResponseCode();
|
||||||
}
|
logger.debug(">>> Response code: " + responseCode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
if (br != null) { br.close(); };
|
if (br != null) { br.close(); };
|
||||||
if (is != null) { is.close(); };
|
if (is != null) { is.close(); };
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Set<String> getSiteMembers(RepoCtx ctx, String siteId) throws Exception
|
protected Set<String> getSiteMembers(RepoCtx ctx, String siteId) throws Exception
|
||||||
{
|
{
|
||||||
Set<String> members = new HashSet<String>();
|
Set<String> members = new HashSet<String>();
|
||||||
if ((siteId != null) && (siteId.length() != 0))
|
if ((siteId != null) && (siteId.length() != 0))
|
||||||
{
|
{
|
||||||
@@ -516,10 +524,10 @@ public abstract class FeedTaskProcessor
|
|||||||
|
|
||||||
return activityTemplates;
|
return activityTemplates;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Configuration getFreemarkerConfiguration(RepoCtx ctx)
|
protected Configuration getFreemarkerConfiguration(RepoCtx ctx)
|
||||||
{
|
{
|
||||||
Configuration cfg = new Configuration();
|
Configuration cfg = new Configuration();
|
||||||
cfg.setObjectWrapper(new DefaultObjectWrapper());
|
cfg.setObjectWrapper(new DefaultObjectWrapper());
|
||||||
|
|
||||||
// custom template loader
|
// custom template loader
|
||||||
@@ -670,7 +678,7 @@ public abstract class FeedTaskProcessor
|
|||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -128,20 +128,23 @@ public class PostLookup
|
|||||||
|
|
||||||
for (final ActivityPostEntity activityPost : activityPosts)
|
for (final ActivityPostEntity activityPost : activityPosts)
|
||||||
{
|
{
|
||||||
try
|
final String postUserId = activityPost.getUserId();
|
||||||
|
|
||||||
|
// MT share
|
||||||
|
String tenantDomain = tenantService.getUserDomain(postUserId);
|
||||||
|
|
||||||
|
AuthenticationUtil.runAs(new RunAsWork<Object>()
|
||||||
{
|
{
|
||||||
postDAO.startTransaction();
|
public Object doWork() throws Exception
|
||||||
|
|
||||||
final JSONObject jo = new JSONObject(new JSONTokener(activityPost.getActivityData()));
|
|
||||||
final String postUserId = activityPost.getUserId();
|
|
||||||
|
|
||||||
// MT share
|
|
||||||
String tenantDomain = tenantService.getUserDomain(postUserId);
|
|
||||||
|
|
||||||
AuthenticationUtil.runAs(new RunAsWork<Object>()
|
|
||||||
{
|
{
|
||||||
public Object doWork() throws Exception
|
try
|
||||||
{
|
{
|
||||||
|
postDAO.startTransaction();
|
||||||
|
|
||||||
|
JSONObject jo = new JSONObject(new JSONTokener(activityPost.getActivityData()));
|
||||||
|
|
||||||
|
String activityDataStr = null;
|
||||||
|
|
||||||
if (! jo.isNull("nodeRef"))
|
if (! jo.isNull("nodeRef"))
|
||||||
{
|
{
|
||||||
String nodeRefStr = jo.getString("nodeRef");
|
String nodeRefStr = jo.getString("nodeRef");
|
||||||
@@ -149,8 +152,7 @@ public class PostLookup
|
|||||||
|
|
||||||
// lookup additional node data
|
// lookup additional node data
|
||||||
JSONObject activityData = lookupNode(nodeRef, postUserId, jo);
|
JSONObject activityData = lookupNode(nodeRef, postUserId, jo);
|
||||||
|
activityDataStr = activityData.toString();
|
||||||
activityPost.setActivityData(activityData.toString());
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -161,42 +163,67 @@ public class PostLookup
|
|||||||
jo.put("firstName", firstLastName.getFirst());
|
jo.put("firstName", firstLastName.getFirst());
|
||||||
jo.put("lastName", firstLastName.getSecond());
|
jo.put("lastName", firstLastName.getSecond());
|
||||||
|
|
||||||
activityPost.setActivityData(jo.toString());
|
activityDataStr = jo.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (activityDataStr != null)
|
||||||
|
{
|
||||||
|
activityPost.setActivityData(activityDataStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (activityPost.getActivityData().length() > ActivityPostDAO.MAX_LEN_ACTIVITY_DATA)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Invalid activity data - exceeds " + ActivityPostDAO.MAX_LEN_ACTIVITY_DATA + " chars: " + activityPost.getActivityData());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (activityPost.getSiteNetwork().length() > ActivityPostDAO.MAX_LEN_SITE_ID)
|
||||||
|
{
|
||||||
|
// belts-and-braces - should not get here since checked during post (and not modified)
|
||||||
|
throw new IllegalArgumentException("Invalid siteId - exceeds " + ActivityPostDAO.MAX_LEN_SITE_ID + " chars: " + activityPost.getSiteNetwork());
|
||||||
|
}
|
||||||
|
|
||||||
activityPost.setLastModified(new Date());
|
activityPost.setLastModified(new Date());
|
||||||
|
|
||||||
postDAO.updatePost(activityPost.getId(), activityPost.getSiteNetwork(), activityPost.getActivityData(), ActivityPostEntity.STATUS.POSTED);
|
postDAO.updatePost(activityPost.getId(), activityPost.getSiteNetwork(), activityPost.getActivityData(), ActivityPostEntity.STATUS.POSTED);
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
activityPost.setStatus(ActivityPostEntity.STATUS.POSTED.toString()); // for debug output
|
activityPost.setStatus(ActivityPostEntity.STATUS.POSTED.toString()); // for debug output
|
||||||
logger.debug("Updated: " + activityPost);
|
logger.debug("Updated: " + activityPost);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
postDAO.commitTransaction();
|
||||||
}
|
}
|
||||||
}, tenantService.getDomainUser(AuthenticationUtil.getSystemUserName(), tenantDomain));
|
catch (IllegalArgumentException e)
|
||||||
|
{
|
||||||
postDAO.commitTransaction();
|
// log error, but consume exception (skip this post)
|
||||||
}
|
logger.error("Skipping activity post " + activityPost.getId() + ": " + e);
|
||||||
catch (JSONException e)
|
postDAO.updatePostStatus(activityPost.getId(), ActivityPostEntity.STATUS.ERROR);
|
||||||
{
|
|
||||||
// log error, but consume exception (skip this post)
|
postDAO.commitTransaction();
|
||||||
logger.error("Skipping activity post " + activityPost.getId() + ": " + e);
|
}
|
||||||
postDAO.updatePostStatus(activityPost.getId(), ActivityPostEntity.STATUS.ERROR);
|
catch (JSONException e)
|
||||||
|
{
|
||||||
postDAO.commitTransaction();
|
// log error, but consume exception (skip this post)
|
||||||
}
|
logger.error("Skipping activity post " + activityPost.getId() + ": " + e);
|
||||||
catch (SQLException e)
|
postDAO.updatePostStatus(activityPost.getId(), ActivityPostEntity.STATUS.ERROR);
|
||||||
{
|
|
||||||
logger.error("Exception during update of post", e);
|
postDAO.commitTransaction();
|
||||||
throw new JobExecutionException(e);
|
}
|
||||||
}
|
catch (SQLException e)
|
||||||
finally
|
{
|
||||||
{
|
logger.error("Exception during update of post", e);
|
||||||
postDAO.endTransaction();
|
throw new JobExecutionException(e);
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
postDAO.endTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, tenantService.getDomainUser(AuthenticationUtil.getSystemUserName(), tenantDomain));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (SQLException e)
|
catch (SQLException e)
|
||||||
|
@@ -1284,7 +1284,8 @@ public class AVMRepository
|
|||||||
List<AVMStoreDescriptor> result = new ArrayList<AVMStoreDescriptor>(storeEntities.size());
|
List<AVMStoreDescriptor> result = new ArrayList<AVMStoreDescriptor>(storeEntities.size());
|
||||||
for (AVMStoreEntity storeEntity : storeEntities)
|
for (AVMStoreEntity storeEntity : storeEntities)
|
||||||
{
|
{
|
||||||
AVMStore store = new AVMStoreImpl();
|
AVMStoreImpl store = new AVMStoreImpl();
|
||||||
|
store.setId(storeEntity.getId());
|
||||||
store.setName(storeEntity.getName());
|
store.setName(storeEntity.getName());
|
||||||
result.add(store.getDescriptor());
|
result.add(store.getDescriptor());
|
||||||
}
|
}
|
||||||
|
@@ -43,6 +43,7 @@ import org.alfresco.repo.avm.util.RawServices;
|
|||||||
import org.alfresco.repo.avm.util.SimplePath;
|
import org.alfresco.repo.avm.util.SimplePath;
|
||||||
import org.alfresco.repo.domain.DbAccessControlList;
|
import org.alfresco.repo.domain.DbAccessControlList;
|
||||||
import org.alfresco.repo.domain.PropertyValue;
|
import org.alfresco.repo.domain.PropertyValue;
|
||||||
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.repo.security.permissions.ACLCopyMode;
|
import org.alfresco.repo.security.permissions.ACLCopyMode;
|
||||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||||
import org.alfresco.service.cmr.avm.AVMBadArgumentException;
|
import org.alfresco.service.cmr.avm.AVMBadArgumentException;
|
||||||
@@ -1273,8 +1274,8 @@ public class AVMStoreImpl implements AVMStore
|
|||||||
{
|
{
|
||||||
// Get the creator ensuring that nulls are not hit
|
// Get the creator ensuring that nulls are not hit
|
||||||
PropertyValue creatorValue = getProperty(ContentModel.PROP_CREATOR);
|
PropertyValue creatorValue = getProperty(ContentModel.PROP_CREATOR);
|
||||||
String creator = creatorValue == null ? "system" : (String) creatorValue.getValue(DataTypeDefinition.TEXT);
|
String creator = (creatorValue == null ? AuthenticationUtil.SYSTEM_USER_NAME : (String) creatorValue.getValue(DataTypeDefinition.TEXT));
|
||||||
creator = (creator == null) ? "system" : creator;
|
creator = (creator == null ? AuthenticationUtil.SYSTEM_USER_NAME : creator);
|
||||||
// Get the created date ensuring that nulls are not hit
|
// Get the created date ensuring that nulls are not hit
|
||||||
PropertyValue createdValue = getProperty(ContentModel.PROP_CREATED);
|
PropertyValue createdValue = getProperty(ContentModel.PROP_CREATED);
|
||||||
Date created = createdValue == null ? (new Date()) : (Date) createdValue.getValue(DataTypeDefinition.DATE);
|
Date created = createdValue == null ? (new Date()) : (Date) createdValue.getValue(DataTypeDefinition.DATE);
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -78,4 +78,16 @@ public class ImageTransformationOptions extends TransformationOptions
|
|||||||
{
|
{
|
||||||
return resizeOptions;
|
return resizeOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
StringBuilder msg = new StringBuilder(100);
|
||||||
|
msg.append(this.getClass().getSimpleName())
|
||||||
|
.append("[ commandOptions=").append(commandOptions)
|
||||||
|
.append(", resizeOptions=").append(resizeOptions)
|
||||||
|
.append("]");
|
||||||
|
|
||||||
|
return msg.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -33,6 +33,13 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public interface ActivityFeedDAO extends ActivitiesDAO
|
public interface ActivityFeedDAO extends ActivitiesDAO
|
||||||
{
|
{
|
||||||
|
public static final int MAX_LEN_USER_ID = 255; // needs to match schema: feed_user_id, post_user_id
|
||||||
|
public static final int MAX_LEN_SITE_ID = 255; // needs to match schema: site_network
|
||||||
|
public static final int MAX_LEN_ACTIVITY_TYPE = 255; // needs to match schema: activity_type
|
||||||
|
public static final int MAX_LEN_ACTIVITY_SUMMARY = 4000; // needs to match schema: activity_summary
|
||||||
|
public static final int MAX_LEN_ACTIVITY_FORMAT = 255; // needs to match schema: activity_format
|
||||||
|
public static final int MAX_LEN_APP_TOOL_ID = 36; // needs to match schema: app_tool
|
||||||
|
|
||||||
public long insertFeedEntry(ActivityFeedEntity activityFeed) throws SQLException;
|
public long insertFeedEntry(ActivityFeedEntity activityFeed) throws SQLException;
|
||||||
|
|
||||||
public int deleteFeedEntries(Date keepDate) throws SQLException;
|
public int deleteFeedEntries(Date keepDate) throws SQLException;
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 Alfresco Software Limited.
|
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -33,6 +33,12 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public interface ActivityPostDAO extends ActivitiesDAO
|
public interface ActivityPostDAO extends ActivitiesDAO
|
||||||
{
|
{
|
||||||
|
public static final int MAX_LEN_USER_ID = 255; // needs to match schema: feed_user_id, post_user_id
|
||||||
|
public static final int MAX_LEN_SITE_ID = 255; // needs to match schema: site_network
|
||||||
|
public static final int MAX_LEN_ACTIVITY_TYPE = 255; // needs to match schema: activity_type
|
||||||
|
public static final int MAX_LEN_ACTIVITY_DATA = 4000; // needs to match schema: activity_data
|
||||||
|
public static final int MAX_LEN_APP_TOOL_ID = 36; // needs to match schema: app_tool
|
||||||
|
|
||||||
public List<ActivityPostEntity> selectPosts(ActivityPostEntity activityPost) throws SQLException;
|
public List<ActivityPostEntity> selectPosts(ActivityPostEntity activityPost) throws SQLException;
|
||||||
|
|
||||||
public Long getMaxActivitySeq() throws SQLException;
|
public Long getMaxActivitySeq() throws SQLException;
|
||||||
|
@@ -141,20 +141,18 @@ public class AVMVersionRootDAOImpl extends AbstractAVMVersionRootDAOImpl
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected List<AVMVersionRootEntity> getVersionRootEntitiesByTo(long storeId, long to)
|
protected List<AVMVersionRootEntity> getVersionRootEntitiesByTo(long storeId, long to)
|
||||||
{
|
{
|
||||||
Map<String, Object> params = new HashMap<String, Object>(3);
|
Map<String, Object> params = new HashMap<String, Object>(2);
|
||||||
params.put("id", storeId);
|
params.put("id", storeId);
|
||||||
params.put("to", to);
|
params.put("to", to);
|
||||||
params.put("from", null);
|
|
||||||
return (List<AVMVersionRootEntity>) template.queryForList(SELECT_AVM_VERSION_ROOTS_BY_TO, params);
|
return (List<AVMVersionRootEntity>) template.queryForList(SELECT_AVM_VERSION_ROOTS_BY_TO, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected List<AVMVersionRootEntity> getVersionRootEntitiesByFrom(long storeId, long from)
|
protected List<AVMVersionRootEntity> getVersionRootEntitiesByFrom(long storeId, long from)
|
||||||
{
|
{
|
||||||
Map<String, Object> params = new HashMap<String, Object>(3);
|
Map<String, Object> params = new HashMap<String, Object>(2);
|
||||||
params.put("id", storeId);
|
params.put("id", storeId);
|
||||||
params.put("from", from);
|
params.put("from", from);
|
||||||
params.put("to", null);
|
|
||||||
return (List<AVMVersionRootEntity>) template.queryForList(SELECT_AVM_VERSION_ROOTS_BY_FROM, params);
|
return (List<AVMVersionRootEntity>) template.queryForList(SELECT_AVM_VERSION_ROOTS_BY_FROM, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -581,6 +581,7 @@
|
|||||||
assoc.id
|
assoc.id
|
||||||
</query>
|
</query>
|
||||||
|
|
||||||
|
<!-- WARNING: This query is not performant and should not be used. -->
|
||||||
<query name="node.GetNodesWithChildrenInDifferentStore">
|
<query name="node.GetNodesWithChildrenInDifferentStore">
|
||||||
select
|
select
|
||||||
parent.id,
|
parent.id,
|
||||||
|
@@ -1008,54 +1008,92 @@ public abstract class BaseNodeServiceTest extends BaseSpringTest
|
|||||||
{
|
{
|
||||||
private NodeService nodeService;
|
private NodeService nodeService;
|
||||||
private List<NodeRef> deletedNodeRefs;
|
private List<NodeRef> deletedNodeRefs;
|
||||||
|
private List<NodeRef> beforeDeleteNodeRefs;
|
||||||
|
|
||||||
public BadOnDeleteNodePolicy(NodeService nodeService, List<NodeRef> deletedNodeRefs)
|
private boolean onDeleteCreateChild = true;
|
||||||
|
|
||||||
|
public BadOnDeleteNodePolicy(NodeService nodeService,
|
||||||
|
List<NodeRef> beforeDeleteNodeRefs,
|
||||||
|
List<NodeRef> deletedNodeRefs)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
this.nodeService = nodeService;
|
this.nodeService = nodeService;
|
||||||
|
this.beforeDeleteNodeRefs = beforeDeleteNodeRefs;
|
||||||
this.deletedNodeRefs = deletedNodeRefs;
|
this.deletedNodeRefs = deletedNodeRefs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void beforeDeleteNode(NodeRef nodeRef)
|
public void beforeDeleteNode(NodeRef nodeRef)
|
||||||
{
|
{
|
||||||
// add a new child to the child, i.e. just before it is deleted
|
// add the child to the list
|
||||||
ChildAssociationRef assocRef = nodeService.createNode(
|
beforeDeleteNodeRefs.add(nodeRef);
|
||||||
|
|
||||||
|
if(onDeleteCreateChild)
|
||||||
|
{
|
||||||
|
// add a new child to the child, i.e. just before it is deleted
|
||||||
|
ChildAssociationRef assocRef = nodeService.createNode(
|
||||||
nodeRef,
|
nodeRef,
|
||||||
ASSOC_TYPE_QNAME_TEST_CHILDREN,
|
ASSOC_TYPE_QNAME_TEST_CHILDREN,
|
||||||
QName.createQName("pre-delete new child"),
|
QName.createQName("pre-delete new child"),
|
||||||
ContentModel.TYPE_CONTAINER);
|
ContentModel.TYPE_CONTAINER);
|
||||||
// set some child node properties
|
// set some child node properties
|
||||||
nodeService.setProperty(nodeRef, PROP_QNAME_BOOLEAN_VALUE, "true");
|
nodeService.setProperty(nodeRef, PROP_QNAME_BOOLEAN_VALUE, "true");
|
||||||
// add an aspect to the child
|
// add an aspect to the child
|
||||||
nodeService.addAspect(nodeRef, ASPECT_QNAME_TEST_TITLED, null);
|
nodeService.addAspect(nodeRef, ASPECT_QNAME_TEST_TITLED, null);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onDeleteNode(ChildAssociationRef childAssocRef, boolean isArchivedNode)
|
public void onDeleteNode(ChildAssociationRef childAssocRef, boolean isArchivedNode)
|
||||||
{
|
{
|
||||||
// add the child to the list
|
// add the child to the list
|
||||||
deletedNodeRefs.add(childAssocRef.getChildRef());
|
deletedNodeRefs.add(childAssocRef.getChildRef());
|
||||||
// now perform some nasties on the node's parent, i.e. add a new child
|
|
||||||
NodeRef parentRef = childAssocRef.getParentRef();
|
if(onDeleteCreateChild)
|
||||||
NodeRef childRef = childAssocRef.getChildRef();
|
{
|
||||||
ChildAssociationRef assocRef = nodeService.createNode(
|
// now perform some nasties on the node's parent, i.e. add a new child
|
||||||
|
NodeRef parentRef = childAssocRef.getParentRef();
|
||||||
|
NodeRef childRef = childAssocRef.getChildRef();
|
||||||
|
ChildAssociationRef assocRef = nodeService.createNode(
|
||||||
parentRef,
|
parentRef,
|
||||||
ASSOC_TYPE_QNAME_TEST_CHILDREN,
|
ASSOC_TYPE_QNAME_TEST_CHILDREN,
|
||||||
QName.createQName("post-delete new child"),
|
QName.createQName("post-delete new child"),
|
||||||
ContentModel.TYPE_CONTAINER);
|
ContentModel.TYPE_CONTAINER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setOnDeleteCreateChild(boolean onDeleteCreateChild)
|
||||||
|
{
|
||||||
|
this.onDeleteCreateChild = onDeleteCreateChild;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isOnDeleteCreateChild()
|
||||||
|
{
|
||||||
|
return onDeleteCreateChild;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDelete() throws Exception
|
public void testDelete() throws Exception
|
||||||
{
|
{
|
||||||
|
final List<NodeRef> beforeDeleteNodeRefs = new ArrayList<NodeRef>(5);
|
||||||
final List<NodeRef> deletedNodeRefs = new ArrayList<NodeRef>(5);
|
final List<NodeRef> deletedNodeRefs = new ArrayList<NodeRef>(5);
|
||||||
|
|
||||||
NodeServicePolicies.OnDeleteNodePolicy policy = new BadOnDeleteNodePolicy(nodeService, deletedNodeRefs);
|
BadOnDeleteNodePolicy nasty = new BadOnDeleteNodePolicy(nodeService, beforeDeleteNodeRefs, deletedNodeRefs);
|
||||||
|
nasty.setOnDeleteCreateChild(false);
|
||||||
|
NodeServicePolicies.OnDeleteNodePolicy policy = nasty;
|
||||||
|
|
||||||
// bind to listen to the deletion of a node
|
// bind to listen to the deletion of a node
|
||||||
policyComponent.bindClassBehaviour(
|
policyComponent.bindClassBehaviour(
|
||||||
QName.createQName(NamespaceService.ALFRESCO_URI, "onDeleteNode"),
|
QName.createQName(NamespaceService.ALFRESCO_URI, "onDeleteNode"),
|
||||||
policy,
|
policy,
|
||||||
new JavaBehaviour(policy, "onDeleteNode"));
|
new JavaBehaviour(policy, "onDeleteNode"));
|
||||||
|
|
||||||
|
policyComponent.bindClassBehaviour(
|
||||||
|
QName.createQName(NamespaceService.ALFRESCO_URI, "beforeDeleteNode"),
|
||||||
|
policy,
|
||||||
|
new JavaBehaviour(policy, "beforeDeleteNode"));
|
||||||
|
|
||||||
// build the node and commit the node graph
|
// build the node and commit the node graph
|
||||||
Map<QName, ChildAssociationRef> assocRefs = buildNodeGraph(nodeService, rootNodeRef);
|
Map<QName, ChildAssociationRef> assocRefs = buildNodeGraph(nodeService, rootNodeRef);
|
||||||
NodeRef n1Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "root_p_n1")).getChildRef();
|
NodeRef n1Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "root_p_n1")).getChildRef();
|
||||||
@@ -1072,11 +1110,86 @@ public abstract class BaseNodeServiceTest extends BaseSpringTest
|
|||||||
assertEquals("Node not cascade deleted", 0, countNodesByReference(n6Ref));
|
assertEquals("Node not cascade deleted", 0, countNodesByReference(n6Ref));
|
||||||
assertEquals("Node not cascade deleted", 0, countNodesByReference(n8Ref));
|
assertEquals("Node not cascade deleted", 0, countNodesByReference(n8Ref));
|
||||||
|
|
||||||
|
// check before delete delete policy has been called
|
||||||
|
assertTrue("n1Ref before delete policy not called", beforeDeleteNodeRefs.contains(n1Ref));
|
||||||
|
assertTrue("n3Ref before delete policy not called", beforeDeleteNodeRefs.contains(n3Ref));
|
||||||
|
assertTrue("n6Ref before delete policy not called", beforeDeleteNodeRefs.contains(n6Ref));
|
||||||
|
assertTrue("n8Ref before delete policy not called", beforeDeleteNodeRefs.contains(n8Ref));
|
||||||
|
|
||||||
|
// check delete policy has been called
|
||||||
|
assertTrue("n1Ref delete policy not called", deletedNodeRefs.contains(n1Ref));
|
||||||
|
assertTrue("n3Ref delete policy not called", deletedNodeRefs.contains(n3Ref));
|
||||||
|
assertTrue("n6Ref delete policy not called", deletedNodeRefs.contains(n6Ref));
|
||||||
|
assertTrue("n8Ref delete policy not called", deletedNodeRefs.contains(n8Ref));
|
||||||
|
|
||||||
// commit to check
|
// commit to check
|
||||||
setComplete();
|
setComplete();
|
||||||
endTransaction();
|
endTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * This test is similar to the test above but the delete policies do nasty stuff such as
|
||||||
|
// * creating children of the soon to be deleted children.
|
||||||
|
// *
|
||||||
|
// * In particular, it verifies that we don't get stuck in an infinite loop.
|
||||||
|
// * @throws Exception
|
||||||
|
// */
|
||||||
|
// public void testDeleteWithBadlyBehavedPolicies() throws Exception
|
||||||
|
// {
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// final List<NodeRef> beforeDeleteNodeRefs = new ArrayList<NodeRef>(5);
|
||||||
|
// final List<NodeRef> deletedNodeRefs = new ArrayList<NodeRef>(5);
|
||||||
|
//
|
||||||
|
// BadOnDeleteNodePolicy nasty = new BadOnDeleteNodePolicy(nodeService, beforeDeleteNodeRefs, deletedNodeRefs);
|
||||||
|
// nasty.setOnDeleteCreateChild(true);
|
||||||
|
// NodeServicePolicies.OnDeleteNodePolicy policy = nasty;
|
||||||
|
//
|
||||||
|
// // bind to listen to the deletion of a node
|
||||||
|
// policyComponent.bindClassBehaviour(
|
||||||
|
// QName.createQName(NamespaceService.ALFRESCO_URI, "onDeleteNode"),
|
||||||
|
// policy,
|
||||||
|
// new JavaBehaviour(policy, "onDeleteNode"));
|
||||||
|
//
|
||||||
|
// policyComponent.bindClassBehaviour(
|
||||||
|
// QName.createQName(NamespaceService.ALFRESCO_URI, "beforeDeleteNode"),
|
||||||
|
// policy,
|
||||||
|
// new JavaBehaviour(policy, "beforeDeleteNode"));
|
||||||
|
//
|
||||||
|
// // build the node and commit the node graph
|
||||||
|
// Map<QName, ChildAssociationRef> assocRefs = buildNodeGraph(nodeService, rootNodeRef);
|
||||||
|
// NodeRef n1Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "root_p_n1")).getChildRef();
|
||||||
|
// NodeRef n3Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "n1_p_n3")).getChildRef();
|
||||||
|
// NodeRef n4Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "n2_p_n4")).getChildRef();
|
||||||
|
// NodeRef n6Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "n3_p_n6")).getChildRef();
|
||||||
|
// NodeRef n8Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "n6_p_n8")).getChildRef();
|
||||||
|
//
|
||||||
|
// // delete n1
|
||||||
|
// nodeService.deleteNode(n1Ref);
|
||||||
|
//
|
||||||
|
// // turn off nasty policy - may upset other tests
|
||||||
|
// nasty.setOnDeleteCreateChild(false);
|
||||||
|
//
|
||||||
|
// // Just a cut down set of tests to validate that something has happened, the real point of the test is to see how
|
||||||
|
// // the end of the transaction fails.
|
||||||
|
//
|
||||||
|
// assertEquals("Node not directly deleted", 0, countNodesByReference(n1Ref));
|
||||||
|
// assertTrue("n1Ref before delete policy not called", beforeDeleteNodeRefs.contains(n1Ref));
|
||||||
|
// assertTrue("n1Ref delete policy not called", deletedNodeRefs.contains(n1Ref));
|
||||||
|
//
|
||||||
|
// // commit to check
|
||||||
|
// setComplete();
|
||||||
|
// endTransaction();
|
||||||
|
// fail("test has not detected orphan children");
|
||||||
|
// }
|
||||||
|
// catch (Exception e)
|
||||||
|
// {
|
||||||
|
// // We expect to get here with this test.
|
||||||
|
// e.printStackTrace();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private int countChildrenOfNode(NodeRef nodeRef)
|
private int countChildrenOfNode(NodeRef nodeRef)
|
||||||
{
|
{
|
||||||
|
@@ -42,12 +42,12 @@ import org.alfresco.model.ContentModel;
|
|||||||
import org.alfresco.repo.domain.Node;
|
import org.alfresco.repo.domain.Node;
|
||||||
import org.alfresco.repo.node.AbstractNodeServiceImpl;
|
import org.alfresco.repo.node.AbstractNodeServiceImpl;
|
||||||
import org.alfresco.repo.node.StoreArchiveMap;
|
import org.alfresco.repo.node.StoreArchiveMap;
|
||||||
import org.alfresco.repo.node.cleanup.AbstractNodeCleanupWorker;
|
|
||||||
import org.alfresco.repo.node.db.NodeDaoService.NodeRefQueryCallback;
|
|
||||||
import org.alfresco.repo.node.index.NodeIndexer;
|
import org.alfresco.repo.node.index.NodeIndexer;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
import org.alfresco.repo.transaction.TransactionListener;
|
||||||
|
import org.alfresco.repo.transaction.TransactionListenerAdapter;
|
||||||
|
import org.alfresco.repo.transaction.TransactionalResourceHelper;
|
||||||
import org.alfresco.service.cmr.dictionary.AspectDefinition;
|
import org.alfresco.service.cmr.dictionary.AspectDefinition;
|
||||||
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
|
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
|
||||||
import org.alfresco.service.cmr.dictionary.ChildAssociationDefinition;
|
import org.alfresco.service.cmr.dictionary.ChildAssociationDefinition;
|
||||||
@@ -94,13 +94,12 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
|||||||
private NodeDaoService nodeDaoService;
|
private NodeDaoService nodeDaoService;
|
||||||
private StoreArchiveMap storeArchiveMap;
|
private StoreArchiveMap storeArchiveMap;
|
||||||
private NodeService avmNodeService;
|
private NodeService avmNodeService;
|
||||||
private NodeIndexer nodeIndexer;
|
private NodeIndexer nodeIndexer;
|
||||||
private boolean cascadeInTransaction;
|
private final static String KEY_PRE_COMMIT_ADD_NODE = "DbNodeServiceImpl.PreCommitAddNode";
|
||||||
|
|
||||||
public DbNodeServiceImpl()
|
public DbNodeServiceImpl()
|
||||||
{
|
{
|
||||||
storeArchiveMap = new StoreArchiveMap(); // in case it is not set
|
storeArchiveMap = new StoreArchiveMap(); // in case it is not set
|
||||||
cascadeInTransaction = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNodeDaoService(NodeDaoService nodeDaoService)
|
public void setNodeDaoService(NodeDaoService nodeDaoService)
|
||||||
@@ -128,15 +127,11 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set whether store delete and archive operations must cascade to all children
|
* @deprecated the functionality did not see wide enough usage to warrant the maintenance
|
||||||
* in the same transaction.
|
|
||||||
*
|
|
||||||
* @param cascadeInTransaction <tt>true</tt> (default) to cascade during
|
|
||||||
* delete and archive
|
|
||||||
*/
|
*/
|
||||||
public void setCascadeInTransaction(boolean cascadeInTransaction)
|
public void setCascadeInTransaction(boolean cascadeInTransaction)
|
||||||
{
|
{
|
||||||
this.cascadeInTransaction = cascadeInTransaction;
|
logger.warn("NodeService property 'cascadeInTransaction' is no longer available.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -339,12 +334,81 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
|||||||
addMissingAspects(childNodePair, propertiesBefore, propertiesAfter);
|
addMissingAspects(childNodePair, propertiesBefore, propertiesAfter);
|
||||||
addMissingAspects(parentNodePair, assocTypeQName);
|
addMissingAspects(parentNodePair, assocTypeQName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* track new node ref so we can validate its path.
|
||||||
|
*
|
||||||
|
* it may be valid now, but who knows what will happen between
|
||||||
|
* now and commit!
|
||||||
|
*/
|
||||||
|
trackNewNodeRef(childAssocRef.getChildRef());
|
||||||
|
|
||||||
// Index
|
// Index
|
||||||
nodeIndexer.indexCreateNode(childAssocRef);
|
nodeIndexer.indexCreateNode(childAssocRef);
|
||||||
|
|
||||||
// done
|
// done
|
||||||
return childAssocRef;
|
return childAssocRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Track a new node ref so we can validate its path at commit time.
|
||||||
|
*
|
||||||
|
* It may have a valid path now, but who knows what will happen between
|
||||||
|
* now and commit!
|
||||||
|
*
|
||||||
|
* @param newNodeRef the node to track
|
||||||
|
*/
|
||||||
|
private void trackNewNodeRef(NodeRef newNodeRef)
|
||||||
|
{
|
||||||
|
// // bind a pre-commit listener to validate any new node associations
|
||||||
|
// Set<NodeRef> newNodes = TransactionalResourceHelper.getSet(KEY_PRE_COMMIT_ADD_NODE);
|
||||||
|
// if (newNodes.size() == 0)
|
||||||
|
// {
|
||||||
|
// PreCommitNewNodeListener listener = new PreCommitNewNodeListener();
|
||||||
|
// AlfrescoTransactionSupport.bindListener(listener);
|
||||||
|
// }
|
||||||
|
// newNodes.add(newNodeRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* loose interest in tracking a node ref
|
||||||
|
*
|
||||||
|
* for example if its been deleted or moved
|
||||||
|
* @param nodeRef the node ref to untrack
|
||||||
|
*/
|
||||||
|
private void untrackNodeRef(NodeRef nodeRef)
|
||||||
|
{
|
||||||
|
// Set<NodeRef> newNodes = TransactionalResourceHelper.getSet(KEY_PRE_COMMIT_ADD_NODE);
|
||||||
|
// if (newNodes.size() > 0)
|
||||||
|
// {
|
||||||
|
// newNodes.remove(nodeRef);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
private class PreCommitNewNodeListener extends TransactionListenerAdapter
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void beforeCommit(boolean readOnly)
|
||||||
|
{
|
||||||
|
if (readOnly)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Set<NodeRef> nodeRefs = TransactionalResourceHelper.getSet(KEY_PRE_COMMIT_ADD_NODE);
|
||||||
|
// for (NodeRef nodeRef : nodeRefs)
|
||||||
|
// {
|
||||||
|
// // Need to check for exists the node may be created
|
||||||
|
// // and deleted within the same transaction
|
||||||
|
// if(exists(nodeRef))
|
||||||
|
// {
|
||||||
|
// System.out.println("Checking bideRef " + nodeRef);
|
||||||
|
// // Check that the primary path is valid for this node
|
||||||
|
// getPaths(nodeRef, false);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
nodeRefs.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds all the default aspects and properties required for the given type.
|
* Adds all the default aspects and properties required for the given type.
|
||||||
@@ -798,10 +862,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
|||||||
invokeBeforeDeleteNode(nodeRef);
|
invokeBeforeDeleteNode(nodeRef);
|
||||||
|
|
||||||
// Cascade delecte as required
|
// Cascade delecte as required
|
||||||
if (cascadeInTransaction)
|
deletePrimaryChildrenNotArchived(nodePair);
|
||||||
{
|
|
||||||
deletePrimaryChildrenNotArchived(nodePair, true);
|
|
||||||
}
|
|
||||||
// perform a normal deletion
|
// perform a normal deletion
|
||||||
nodeDaoService.deleteNode(nodeId);
|
nodeDaoService.deleteNode(nodeId);
|
||||||
// Invoke policy behaviours
|
// Invoke policy behaviours
|
||||||
@@ -820,17 +881,18 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
|||||||
*/
|
*/
|
||||||
archiveNode(nodeRef, archiveStoreRef);
|
archiveNode(nodeRef, archiveStoreRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove the deleted node from the list of new nodes
|
||||||
|
untrackNodeRef(nodeRef);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* delete primary children - private method for deleteNode.
|
* delete primary children - private method for deleteNode.
|
||||||
*
|
*
|
||||||
* recurses through children when deleting a node. Does not archive.
|
* recurses through children when deleting a node. Does not archive.
|
||||||
*
|
|
||||||
* @param nodePair
|
|
||||||
* @param cascade
|
|
||||||
*/
|
*/
|
||||||
private void deletePrimaryChildrenNotArchived(Pair<Long, NodeRef> nodePair, boolean cascade)
|
private void deletePrimaryChildrenNotArchived(Pair<Long, NodeRef> nodePair)
|
||||||
{
|
{
|
||||||
Long nodeId = nodePair.getFirst();
|
Long nodeId = nodePair.getFirst();
|
||||||
// Get the node's primary children
|
// Get the node's primary children
|
||||||
@@ -859,10 +921,10 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Get all the QNames to remove
|
// Get all the QNames to remove
|
||||||
nodeDaoService.getPrimaryChildAssocs(nodeId, callback);
|
nodeDaoService.getPrimaryChildAssocs(nodeId, callback);
|
||||||
// Each child must be deleted
|
// Each child must be deleted
|
||||||
for (Pair<Long, NodeRef> childNodePair : childNodePairs)
|
for (Pair<Long, NodeRef> childNodePair : childNodePairs)
|
||||||
{
|
{
|
||||||
// Fire node policies. This ensures that each node in the hierarchy gets a notification fired.
|
// Fire node policies. This ensures that each node in the hierarchy gets a notification fired.
|
||||||
Long childNodeId = childNodePair.getFirst();
|
Long childNodeId = childNodePair.getFirst();
|
||||||
NodeRef childNodeRef = childNodePair.getSecond();
|
NodeRef childNodeRef = childNodePair.getSecond();
|
||||||
@@ -872,16 +934,16 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
|||||||
|
|
||||||
invokeBeforeDeleteNode(childNodeRef);
|
invokeBeforeDeleteNode(childNodeRef);
|
||||||
|
|
||||||
// Cascade first, if required.
|
// Cascade first
|
||||||
// This ensures that the beforeDelete policy is fired for all nodes in the hierarchy before
|
// This ensures that the beforeDelete policy is fired for all nodes in the hierarchy before
|
||||||
// the actual delete starts.
|
// the actual delete starts.
|
||||||
if (cascade)
|
deletePrimaryChildrenNotArchived(childNodePair);
|
||||||
{
|
|
||||||
deletePrimaryChildrenNotArchived(childNodePair, true);
|
|
||||||
}
|
|
||||||
// Delete the child
|
// Delete the child
|
||||||
nodeDaoService.deleteNode(childNodeId);
|
nodeDaoService.deleteNode(childNodeId);
|
||||||
invokeOnDeleteNode(childParentAssocRef, childNodeType, childNodeQNames, false);
|
invokeOnDeleteNode(childParentAssocRef, childNodeType, childNodeQNames, false);
|
||||||
|
|
||||||
|
// loose interest in tracking this node ref
|
||||||
|
untrackNodeRef(childNodeRef);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2197,12 +2259,8 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
|||||||
invokeOnMoveNode(oldParentAssocRef, newParentAssocRef);
|
invokeOnMoveNode(oldParentAssocRef, newParentAssocRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have to cascade in the transaction, then pull the children over to the new store
|
// Pull children to the new store
|
||||||
if (cascadeInTransaction)
|
pullNodeChildrenToSameStore(newNodeToMovePair, true);
|
||||||
{
|
|
||||||
// Pull children to the new store
|
|
||||||
pullNodeChildrenToSameStore(newNodeToMovePair, true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Done
|
// Done
|
||||||
return newParentAssocRef;
|
return newParentAssocRef;
|
||||||
@@ -2231,7 +2289,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
|||||||
* do not need to be remade. If the children are in the same store, only the <code>indexChildren</code>
|
* do not need to be remade. If the children are in the same store, only the <code>indexChildren</code>
|
||||||
* value is needed.
|
* value is needed.
|
||||||
*/
|
*/
|
||||||
private void pullNodeChildrenToSameStore(Pair<Long, NodeRef> nodePair, boolean cascade, boolean indexChildren)
|
private void pullNodeChildrenToSameStore(Pair<Long, NodeRef> nodePair, boolean indexChildren)
|
||||||
{
|
{
|
||||||
Long nodeId = nodePair.getFirst();
|
Long nodeId = nodePair.getFirst();
|
||||||
NodeRef nodeRef = nodePair.getSecond();
|
NodeRef nodeRef = nodePair.getSecond();
|
||||||
@@ -2291,7 +2349,6 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
|||||||
// Index
|
// Index
|
||||||
if (indexChildren)
|
if (indexChildren)
|
||||||
{
|
{
|
||||||
nodeIndexer.indexDeleteNode(oldParentAssocPair.getSecond());
|
|
||||||
nodeIndexer.indexCreateNode(newParentAssocPair.getSecond());
|
nodeIndexer.indexCreateNode(newParentAssocPair.getSecond());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -2302,11 +2359,8 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
|||||||
// Fire node policies. This ensures that each node in the hierarchy gets a notification fired.
|
// Fire node policies. This ensures that each node in the hierarchy gets a notification fired.
|
||||||
invokeOnDeleteNode(oldParentAssocPair.getSecond(), childNodeTypeQName, childNodeAspectQNames, true);
|
invokeOnDeleteNode(oldParentAssocPair.getSecond(), childNodeTypeQName, childNodeAspectQNames, true);
|
||||||
invokeOnCreateNode(newParentAssocPair.getSecond());
|
invokeOnCreateNode(newParentAssocPair.getSecond());
|
||||||
// Cascade, if required
|
// Cascade
|
||||||
if (cascade)
|
pullNodeChildrenToSameStore(newChildNodePair, indexChildren);
|
||||||
{
|
|
||||||
pullNodeChildrenToSameStore(newChildNodePair, cascade, indexChildren);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2418,107 +2472,4 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
|||||||
nodeDaoService.setChildNameUnique(assocId, newName);
|
nodeDaoService.setChildNameUnique(assocId, newName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class MoveChildrenToCorrectStore extends AbstractNodeCleanupWorker
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
protected List<String> doCleanInternal() throws Throwable
|
|
||||||
{
|
|
||||||
return dbNodeService.moveChildrenToCorrectStore();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private List<String> moveChildrenToCorrectStore()
|
|
||||||
{
|
|
||||||
List<String> results = new ArrayList<String>(1000);
|
|
||||||
// Repeat the process for each store
|
|
||||||
List<Pair<Long, StoreRef>> storePairs = nodeDaoService.getStores();
|
|
||||||
for (Pair<Long, StoreRef> storePair : storePairs)
|
|
||||||
{
|
|
||||||
List<String> storeResults = moveChildrenToCorrectStore(storePair.getFirst());
|
|
||||||
results.addAll(storeResults);
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<String> moveChildrenToCorrectStore(final Long storeId)
|
|
||||||
{
|
|
||||||
final List<Pair<Long, NodeRef>> parentNodePairs = new ArrayList<Pair<Long, NodeRef>>(100);
|
|
||||||
final NodeRefQueryCallback callback = new NodeRefQueryCallback()
|
|
||||||
{
|
|
||||||
public boolean handle(Pair<Long, NodeRef> nodePair)
|
|
||||||
{
|
|
||||||
parentNodePairs.add(nodePair);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
RetryingTransactionCallback<Object> getNodesCallback = new RetryingTransactionCallback<Object>()
|
|
||||||
{
|
|
||||||
public Object execute() throws Throwable
|
|
||||||
{
|
|
||||||
nodeDaoService.getNodesWithChildrenInDifferentStore(storeId, Long.MIN_VALUE, 100, callback);
|
|
||||||
// Done
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
transactionService.getRetryingTransactionHelper().doInTransaction(getNodesCallback, true, true);
|
|
||||||
// Process the nodes in random order
|
|
||||||
Collections.shuffle(parentNodePairs);
|
|
||||||
// Iterate and operate
|
|
||||||
List<String> results = new ArrayList<String>(100);
|
|
||||||
for (final Pair<Long, NodeRef> parentNodePair : parentNodePairs)
|
|
||||||
{
|
|
||||||
RetryingTransactionCallback<String> fixNodesCallback = new RetryingTransactionCallback<String>()
|
|
||||||
{
|
|
||||||
public String execute() throws Throwable
|
|
||||||
{
|
|
||||||
// Pull the children to the same store with full indexing - but don't cascade.
|
|
||||||
pullNodeChildrenToSameStore(parentNodePair, true, true);
|
|
||||||
// Done
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
RetryingTransactionHelper txnHelper = transactionService.getRetryingTransactionHelper();
|
|
||||||
txnHelper.setMaxRetries(1);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
txnHelper.doInTransaction(fixNodesCallback, false, true);
|
|
||||||
String msg =
|
|
||||||
"Moved child nodes to parent node's store: \n" +
|
|
||||||
" Parent node: " + parentNodePair.getFirst();
|
|
||||||
results.add(msg);
|
|
||||||
}
|
|
||||||
catch (Throwable e)
|
|
||||||
{
|
|
||||||
String msg =
|
|
||||||
"Failed to move child nodes to parent node's store." +
|
|
||||||
" Set log level to WARN for this class to get exception log: \n" +
|
|
||||||
" Parent node: " + parentNodePair.getFirst() + "\n" +
|
|
||||||
" Error: " + e.getMessage();
|
|
||||||
// It failed; do a full log in WARN mode
|
|
||||||
if (logger.isWarnEnabled())
|
|
||||||
{
|
|
||||||
logger.warn(msg, e);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logger.error(msg);
|
|
||||||
}
|
|
||||||
results.add(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Done
|
|
||||||
if (logger.isDebugEnabled())
|
|
||||||
{
|
|
||||||
StringBuilder sb = new StringBuilder(256);
|
|
||||||
sb.append("Moved children to correct stores: \n")
|
|
||||||
.append(" Results:\n");
|
|
||||||
for (String msg : results)
|
|
||||||
{
|
|
||||||
sb.append(" ").append(msg).append("\n");
|
|
||||||
}
|
|
||||||
logger.debug(sb.toString());
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -38,8 +38,6 @@ import org.springframework.extensions.surf.util.I18NUtil;
|
|||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.content.MimetypeMap;
|
import org.alfresco.repo.content.MimetypeMap;
|
||||||
import org.alfresco.repo.node.BaseNodeServiceTest;
|
import org.alfresco.repo.node.BaseNodeServiceTest;
|
||||||
import org.alfresco.repo.node.StoreArchiveMap;
|
|
||||||
import org.alfresco.repo.node.cleanup.NodeCleanupRegistry;
|
|
||||||
import org.alfresco.repo.node.db.NodeDaoService.NodePropertyHandler;
|
import org.alfresco.repo.node.db.NodeDaoService.NodePropertyHandler;
|
||||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||||
@@ -50,7 +48,6 @@ import org.alfresco.service.cmr.repository.ContentData;
|
|||||||
import org.alfresco.service.cmr.repository.MLText;
|
import org.alfresco.service.cmr.repository.MLText;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
import org.alfresco.service.cmr.repository.StoreRef;
|
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||||
import org.alfresco.service.transaction.TransactionService;
|
import org.alfresco.service.transaction.TransactionService;
|
||||||
@@ -73,7 +70,6 @@ public class DbNodeServiceImplTest extends BaseNodeServiceTest
|
|||||||
{
|
{
|
||||||
// Force cascading
|
// Force cascading
|
||||||
DbNodeServiceImpl dbNodeServiceImpl = (DbNodeServiceImpl) applicationContext.getBean("dbNodeServiceImpl");
|
DbNodeServiceImpl dbNodeServiceImpl = (DbNodeServiceImpl) applicationContext.getBean("dbNodeServiceImpl");
|
||||||
dbNodeServiceImpl.setCascadeInTransaction(true);
|
|
||||||
|
|
||||||
return (NodeService) applicationContext.getBean("dbNodeService");
|
return (NodeService) applicationContext.getBean("dbNodeService");
|
||||||
}
|
}
|
||||||
@@ -402,49 +398,6 @@ public class DbNodeServiceImplTest extends BaseNodeServiceTest
|
|||||||
nodeService.deleteNode(nodeRef);
|
nodeService.deleteNode(nodeRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCleanup() throws Exception
|
|
||||||
{
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
StoreArchiveMap storeArchiveMap = (StoreArchiveMap) applicationContext.getBean("storeArchiveMap");
|
|
||||||
DbNodeServiceImpl ns = (DbNodeServiceImpl) applicationContext.getBean("dbNodeServiceImpl");
|
|
||||||
ns.setCascadeInTransaction(false);
|
|
||||||
|
|
||||||
NodeRef parentNodeRef = nodeService.createNode(
|
|
||||||
rootNodeRef,
|
|
||||||
ASSOC_TYPE_QNAME_TEST_CHILDREN,
|
|
||||||
QName.createQName(NAMESPACE, this.getName()),
|
|
||||||
ContentModel.TYPE_FOLDER).getChildRef();
|
|
||||||
NodeRef childNodeRef = nodeService.createNode(
|
|
||||||
parentNodeRef,
|
|
||||||
ContentModel.ASSOC_CONTAINS,
|
|
||||||
QName.createQName(NAMESPACE, this.getName()),
|
|
||||||
ContentModel.TYPE_FOLDER).getChildRef();
|
|
||||||
|
|
||||||
// Ensure that the archive feature is enabled
|
|
||||||
StoreRef archiveStoreRef = ns.createStore("test", getName() + "-" + System.currentTimeMillis());
|
|
||||||
storeArchiveMap.put(parentNodeRef.getStoreRef(), archiveStoreRef);
|
|
||||||
|
|
||||||
// Delete parent. Cascade is OFF, so children should be left in their current store.
|
|
||||||
ns.deleteNode(parentNodeRef);
|
|
||||||
// Check that the node n1 is in the archive store
|
|
||||||
assertFalse("Parent should be deleted", ns.exists(parentNodeRef));
|
|
||||||
NodeRef parentArchiveRef = new NodeRef(archiveStoreRef, parentNodeRef.getId());
|
|
||||||
assertTrue("Parent should be in the archive store", ns.exists(parentArchiveRef));
|
|
||||||
|
|
||||||
// Force a commit here
|
|
||||||
setComplete();
|
|
||||||
endTransaction();
|
|
||||||
|
|
||||||
NodeCleanupRegistry nodeCleanupRegistry = new NodeCleanupRegistry();
|
|
||||||
DbNodeServiceImpl.MoveChildrenToCorrectStore worker = new DbNodeServiceImpl.MoveChildrenToCorrectStore();
|
|
||||||
worker.setTransactionService(transactionService);
|
|
||||||
worker.setDbNodeService(ns);
|
|
||||||
worker.setNodeDaoService(nodeDaoService);
|
|
||||||
|
|
||||||
// Run cleanup
|
|
||||||
worker.doClean();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a property to a node and checks that it can be found using the low-level DB query
|
* Adds a property to a node and checks that it can be found using the low-level DB query
|
||||||
*/
|
*/
|
||||||
|
@@ -357,6 +357,8 @@ public interface NodeDaoService
|
|||||||
* @param minNodeId the min node ID to return
|
* @param minNodeId the min node ID to return
|
||||||
* @param count the maximum number of results
|
* @param count the maximum number of results
|
||||||
* @param resultsCallback the node callback
|
* @param resultsCallback the node callback
|
||||||
|
*
|
||||||
|
* @deprecated Since 2.2SP6, 3.1SP2, 3.2: not performant and not relevant to any use-cases
|
||||||
*/
|
*/
|
||||||
@DirtySessionAnnotation(markDirty=false)
|
@DirtySessionAnnotation(markDirty=false)
|
||||||
public void getNodesWithChildrenInDifferentStore(
|
public void getNodesWithChildrenInDifferentStore(
|
||||||
|
@@ -3232,6 +3232,9 @@ public class HibernateNodeDaoServiceImpl
|
|||||||
// Done
|
// Done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Not performant. Do not use.
|
||||||
|
*/
|
||||||
public void getNodesWithChildrenInDifferentStore(
|
public void getNodesWithChildrenInDifferentStore(
|
||||||
final Long storeId,
|
final Long storeId,
|
||||||
final Long minNodeId,
|
final Long minNodeId,
|
||||||
|
@@ -26,6 +26,7 @@ package org.alfresco.repo.rule;
|
|||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -35,6 +36,11 @@ import java.util.Set;
|
|||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.action.ActionModel;
|
import org.alfresco.repo.action.ActionModel;
|
||||||
import org.alfresco.repo.action.RuntimeActionService;
|
import org.alfresco.repo.action.RuntimeActionService;
|
||||||
|
import org.alfresco.repo.cache.NullCache;
|
||||||
|
import org.alfresco.repo.cache.SimpleCache;
|
||||||
|
import org.alfresco.repo.node.NodeServicePolicies;
|
||||||
|
import org.alfresco.repo.policy.JavaBehaviour;
|
||||||
|
import org.alfresco.repo.policy.PolicyComponent;
|
||||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
||||||
import org.alfresco.repo.transaction.TransactionListener;
|
import org.alfresco.repo.transaction.TransactionListener;
|
||||||
import org.alfresco.service.cmr.action.Action;
|
import org.alfresco.service.cmr.action.Action;
|
||||||
@@ -51,6 +57,7 @@ import org.alfresco.service.cmr.rule.RuleServiceException;
|
|||||||
import org.alfresco.service.cmr.rule.RuleType;
|
import org.alfresco.service.cmr.rule.RuleType;
|
||||||
import org.alfresco.service.cmr.security.AccessStatus;
|
import org.alfresco.service.cmr.security.AccessStatus;
|
||||||
import org.alfresco.service.cmr.security.PermissionService;
|
import org.alfresco.service.cmr.security.PermissionService;
|
||||||
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||||
import org.alfresco.util.GUID;
|
import org.alfresco.util.GUID;
|
||||||
@@ -67,7 +74,12 @@ import org.apache.commons.logging.LogFactory;
|
|||||||
*
|
*
|
||||||
* @author Roy Wetherall
|
* @author Roy Wetherall
|
||||||
*/
|
*/
|
||||||
public class RuleServiceImpl implements RuleService, RuntimeRuleService
|
public class RuleServiceImpl
|
||||||
|
implements RuleService, RuntimeRuleService,
|
||||||
|
NodeServicePolicies.BeforeCreateChildAssociationPolicy,
|
||||||
|
NodeServicePolicies.OnCreateNodePolicy,
|
||||||
|
NodeServicePolicies.OnUpdateNodePolicy,
|
||||||
|
NodeServicePolicies.OnAddAspectPolicy
|
||||||
{
|
{
|
||||||
/** key against which to store rules pending on the current transaction */
|
/** key against which to store rules pending on the current transaction */
|
||||||
private static final String KEY_RULES_PENDING = "RuleServiceImpl.PendingRules";
|
private static final String KEY_RULES_PENDING = "RuleServiceImpl.PendingRules";
|
||||||
@@ -79,44 +91,30 @@ public class RuleServiceImpl implements RuleService, RuntimeRuleService
|
|||||||
private String ASSOC_NAME_RULES_PREFIX = "rules";
|
private String ASSOC_NAME_RULES_PREFIX = "rules";
|
||||||
private RegexQNamePattern ASSOC_NAME_RULES_REGEX = new RegexQNamePattern(RuleModel.RULE_MODEL_URI, "^" + ASSOC_NAME_RULES_PREFIX + ".*");
|
private RegexQNamePattern ASSOC_NAME_RULES_REGEX = new RegexQNamePattern(RuleModel.RULE_MODEL_URI, "^" + ASSOC_NAME_RULES_PREFIX + ".*");
|
||||||
|
|
||||||
/**
|
|
||||||
* The logger
|
|
||||||
*/
|
|
||||||
private static Log logger = LogFactory.getLog(RuleServiceImpl.class);
|
private static Log logger = LogFactory.getLog(RuleServiceImpl.class);
|
||||||
|
|
||||||
/**
|
|
||||||
* The permission-safe node service
|
|
||||||
*/
|
|
||||||
private NodeService nodeService;
|
private NodeService nodeService;
|
||||||
|
|
||||||
/**
|
|
||||||
* The runtime node service (ignores permissions)
|
|
||||||
*/
|
|
||||||
private NodeService runtimeNodeService;
|
private NodeService runtimeNodeService;
|
||||||
|
|
||||||
/**
|
|
||||||
* The action service
|
|
||||||
*/
|
|
||||||
private ActionService actionService;
|
private ActionService actionService;
|
||||||
|
|
||||||
/**
|
|
||||||
* The dictionary service
|
|
||||||
*/
|
|
||||||
private DictionaryService dictionaryService;
|
private DictionaryService dictionaryService;
|
||||||
|
private PolicyComponent policyComponent;
|
||||||
/**
|
|
||||||
* The permission service
|
|
||||||
*/
|
|
||||||
private PermissionService permissionService;
|
private PermissionService permissionService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The action service implementation which we need for some things.
|
* The action service implementation which we need for some things.
|
||||||
*/
|
*/
|
||||||
RuntimeActionService runtimeActionService;
|
private RuntimeActionService runtimeActionService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cache of raw rules (not inherited or interpreted) for a given node
|
||||||
|
*/
|
||||||
|
private SimpleCache<NodeRef, List<Rule>> nodeRulesCache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of disabled node refs. The rules associated with these nodes will node be added to the pending list, and
|
* List of disabled node refs. The rules associated with these nodes will node be added to the pending list, and
|
||||||
* therefore not fired. This list is transient.
|
* therefore not fired. This list is transient.
|
||||||
|
*
|
||||||
|
* TODO: (DH) Make this txn-local
|
||||||
*/
|
*/
|
||||||
private Set<NodeRef> disabledNodeRefs = new HashSet<NodeRef>(5);
|
private Set<NodeRef> disabledNodeRefs = new HashSet<NodeRef>(5);
|
||||||
|
|
||||||
@@ -148,8 +146,6 @@ public class RuleServiceImpl implements RuleService, RuntimeRuleService
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the permission-safe node service
|
* Set the permission-safe node service
|
||||||
*
|
|
||||||
* @param nodeService the permission-safe node service
|
|
||||||
*/
|
*/
|
||||||
public void setNodeService(NodeService nodeService)
|
public void setNodeService(NodeService nodeService)
|
||||||
{
|
{
|
||||||
@@ -158,8 +154,6 @@ public class RuleServiceImpl implements RuleService, RuntimeRuleService
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the direct node service
|
* Set the direct node service
|
||||||
*
|
|
||||||
* @param nodeService the node service
|
|
||||||
*/
|
*/
|
||||||
public void setRuntimeNodeService(NodeService runtimeNodeService)
|
public void setRuntimeNodeService(NodeService runtimeNodeService)
|
||||||
{
|
{
|
||||||
@@ -168,8 +162,6 @@ public class RuleServiceImpl implements RuleService, RuntimeRuleService
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the action service
|
* Set the action service
|
||||||
*
|
|
||||||
* @param actionService the action service
|
|
||||||
*/
|
*/
|
||||||
public void setActionService(ActionService actionService)
|
public void setActionService(ActionService actionService)
|
||||||
{
|
{
|
||||||
@@ -178,8 +170,6 @@ public class RuleServiceImpl implements RuleService, RuntimeRuleService
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the runtime action service
|
* Set the runtime action service
|
||||||
*
|
|
||||||
* @param actionRegistration the action service
|
|
||||||
*/
|
*/
|
||||||
public void setRuntimeActionService(RuntimeActionService runtimeActionService)
|
public void setRuntimeActionService(RuntimeActionService runtimeActionService)
|
||||||
{
|
{
|
||||||
@@ -188,24 +178,41 @@ public class RuleServiceImpl implements RuleService, RuntimeRuleService
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the dictionary service
|
* Set the dictionary service
|
||||||
*
|
|
||||||
* @param dictionaryService the dictionary service
|
|
||||||
*/
|
*/
|
||||||
public void setDictionaryService(DictionaryService dictionaryService)
|
public void setDictionaryService(DictionaryService dictionaryService)
|
||||||
{
|
{
|
||||||
this.dictionaryService = dictionaryService;
|
this.dictionaryService = dictionaryService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the policy component to listen for various events
|
||||||
|
*/
|
||||||
|
public void setPolicyComponent(PolicyComponent policyComponent)
|
||||||
|
{
|
||||||
|
this.policyComponent = policyComponent;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the permission service
|
* Set the permission service
|
||||||
*
|
|
||||||
* @param permissionService the permission service
|
|
||||||
*/
|
*/
|
||||||
public void setPermissionService(PermissionService permissionService)
|
public void setPermissionService(PermissionService permissionService)
|
||||||
{
|
{
|
||||||
this.permissionService = permissionService;
|
this.permissionService = permissionService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the cache to hold node's individual rules. This cache <b>must not be shared</b>
|
||||||
|
* across transactions.
|
||||||
|
*
|
||||||
|
* @param nodeRulesCache a cache of raw rules contained on a node
|
||||||
|
*
|
||||||
|
* @see NullCache
|
||||||
|
*/
|
||||||
|
public void setNodeRulesCache(SimpleCache<NodeRef, List<Rule>> nodeRulesCache)
|
||||||
|
{
|
||||||
|
this.nodeRulesCache = nodeRulesCache;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the global rules disabled flag
|
* Set the global rules disabled flag
|
||||||
*
|
*
|
||||||
@@ -216,6 +223,88 @@ public class RuleServiceImpl implements RuleService, RuntimeRuleService
|
|||||||
this.globalRulesDisabled = rulesDisabled;
|
this.globalRulesDisabled = rulesDisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers to listen for events of interest. For instance, the creation or deletion of a rule folder
|
||||||
|
* will affect the caching of rules.
|
||||||
|
*/
|
||||||
|
public void init()
|
||||||
|
{
|
||||||
|
policyComponent.bindAssociationBehaviour(
|
||||||
|
QName.createQName(NamespaceService.ALFRESCO_URI, "beforeCreateChildAssociation"),
|
||||||
|
RuleModel.ASPECT_RULES,
|
||||||
|
RuleModel.ASSOC_RULE_FOLDER,
|
||||||
|
new JavaBehaviour(this, "beforeCreateChildAssociation"));
|
||||||
|
policyComponent.bindClassBehaviour(
|
||||||
|
QName.createQName(NamespaceService.ALFRESCO_URI, "onAddAspect"),
|
||||||
|
RuleModel.ASPECT_RULES,
|
||||||
|
new JavaBehaviour(this, "onAddAspect"));
|
||||||
|
policyComponent.bindClassBehaviour(
|
||||||
|
QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateNode"),
|
||||||
|
RuleModel.ASPECT_RULES,
|
||||||
|
new JavaBehaviour(this, "onUpdateNode"));
|
||||||
|
policyComponent.bindClassBehaviour(
|
||||||
|
QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateNode"),
|
||||||
|
RuleModel.TYPE_RULE,
|
||||||
|
new JavaBehaviour(this, "onCreateNode"));
|
||||||
|
policyComponent.bindClassBehaviour(
|
||||||
|
QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateNode"),
|
||||||
|
RuleModel.TYPE_RULE,
|
||||||
|
new JavaBehaviour(this, "onUpdateNode"));
|
||||||
|
policyComponent.bindClassBehaviour(
|
||||||
|
QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateNode"),
|
||||||
|
ActionModel.TYPE_ACTION_BASE,
|
||||||
|
new JavaBehaviour(this, "onCreateNode"));
|
||||||
|
policyComponent.bindClassBehaviour(
|
||||||
|
QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateNode"),
|
||||||
|
ActionModel.TYPE_ACTION_BASE,
|
||||||
|
new JavaBehaviour(this, "onUpdateNode"));
|
||||||
|
policyComponent.bindClassBehaviour(
|
||||||
|
QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateNode"),
|
||||||
|
ActionModel.TYPE_ACTION_PARAMETER,
|
||||||
|
new JavaBehaviour(this, "onCreateNode"));
|
||||||
|
policyComponent.bindClassBehaviour(
|
||||||
|
QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateNode"),
|
||||||
|
ActionModel.TYPE_ACTION_PARAMETER,
|
||||||
|
new JavaBehaviour(this, "onUpdateNode"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cache invalidation
|
||||||
|
*/
|
||||||
|
public void beforeCreateChildAssociation(
|
||||||
|
NodeRef parentNodeRef,
|
||||||
|
NodeRef childNodeRef,
|
||||||
|
QName assocTypeQName,
|
||||||
|
QName assocQName,
|
||||||
|
boolean isNewNode)
|
||||||
|
{
|
||||||
|
nodeRulesCache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cache invalidation
|
||||||
|
*/
|
||||||
|
public void onUpdateNode(NodeRef nodeRef)
|
||||||
|
{
|
||||||
|
nodeRulesCache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cache invalidation
|
||||||
|
*/
|
||||||
|
public void onCreateNode(ChildAssociationRef childAssocRef)
|
||||||
|
{
|
||||||
|
nodeRulesCache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cache invalidation
|
||||||
|
*/
|
||||||
|
public void onAddAspect(NodeRef nodeRef, QName aspectTypeQName)
|
||||||
|
{
|
||||||
|
nodeRulesCache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the saved rule folder reference
|
* Gets the saved rule folder reference
|
||||||
*
|
*
|
||||||
@@ -355,60 +444,78 @@ public class RuleServiceImpl implements RuleService, RuntimeRuleService
|
|||||||
{
|
{
|
||||||
List<Rule> rules = new ArrayList<Rule>();
|
List<Rule> rules = new ArrayList<Rule>();
|
||||||
|
|
||||||
if (this.runtimeNodeService.exists(nodeRef) == true && checkNodeType(nodeRef) == true)
|
if (!this.runtimeNodeService.exists(nodeRef) || !checkNodeType(nodeRef))
|
||||||
{
|
{
|
||||||
if (includeInherited == true && this.runtimeNodeService.hasAspect(nodeRef, RuleModel.ASPECT_IGNORE_INHERITED_RULES) == false)
|
// Node has gone or is not the correct type
|
||||||
|
return rules;
|
||||||
|
}
|
||||||
|
if (includeInherited == true && this.runtimeNodeService.hasAspect(nodeRef, RuleModel.ASPECT_IGNORE_INHERITED_RULES) == false)
|
||||||
|
{
|
||||||
|
// Get any inherited rules
|
||||||
|
for (Rule rule : getInheritedRules(nodeRef, ruleTypeName, null))
|
||||||
{
|
{
|
||||||
// Get any inherited rules
|
// Ensure rules are not duplicated in the list
|
||||||
for (Rule rule : getInheritedRules(nodeRef, ruleTypeName, null))
|
if (rules.contains(rule) == false)
|
||||||
{
|
{
|
||||||
// Ensure rules are not duplicated in the list
|
rules.add(rule);
|
||||||
if (rules.contains(rule) == false)
|
|
||||||
{
|
|
||||||
rules.add(rule);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Extra check of CONSUMER permission was added to rule selection,
|
// Get the node's own rules and add them to the list
|
||||||
// to prevent Access Denied Exception due to the bug:
|
List<Rule> nodeRules = getRulesForNode(nodeRef);
|
||||||
// https://issues.alfresco.com/browse/ETWOTWO-438
|
for (Rule rule : nodeRules)
|
||||||
|
{
|
||||||
if (this.runtimeNodeService.hasAspect(nodeRef, RuleModel.ASPECT_RULES) == true &&
|
if ((rules.contains(rule) == false) &&
|
||||||
permissionService.hasPermission(nodeRef, PermissionService.READ) == AccessStatus.ALLOWED)
|
(ruleTypeName == null || rule.getRuleTypes().contains(ruleTypeName) == true))
|
||||||
{
|
{
|
||||||
NodeRef ruleFolder = getSavedRuleFolderRef(nodeRef);
|
rules.add(rule);
|
||||||
if (ruleFolder != null)
|
|
||||||
{
|
|
||||||
List<Rule> allRules = new ArrayList<Rule>();
|
|
||||||
|
|
||||||
// Get the rules for this node
|
|
||||||
List<ChildAssociationRef> ruleChildAssocRefs =
|
|
||||||
this.runtimeNodeService.getChildAssocs(ruleFolder, RegexQNamePattern.MATCH_ALL, ASSOC_NAME_RULES_REGEX);
|
|
||||||
for (ChildAssociationRef ruleChildAssocRef : ruleChildAssocRefs)
|
|
||||||
{
|
|
||||||
// Create the rule and add to the list
|
|
||||||
NodeRef ruleNodeRef = ruleChildAssocRef.getChildRef();
|
|
||||||
Rule rule = getRule(ruleNodeRef);
|
|
||||||
allRules.add(rule);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build the list of rules that is returned to the client
|
|
||||||
for (Rule rule : allRules)
|
|
||||||
{
|
|
||||||
if ((rules.contains(rule) == false) &&
|
|
||||||
(ruleTypeName == null || rule.getRuleTypes().contains(ruleTypeName) == true))
|
|
||||||
{
|
|
||||||
rules.add(rule);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rules;
|
return rules;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<Rule> getRulesForNode(NodeRef nodeRef)
|
||||||
|
{
|
||||||
|
// Extra check of CONSUMER permission was added to rule selection,
|
||||||
|
// to prevent Access Denied Exception due to the bug:
|
||||||
|
// https://issues.alfresco.com/browse/ETWOTWO-438
|
||||||
|
|
||||||
|
if (!runtimeNodeService.hasAspect(nodeRef, RuleModel.ASPECT_RULES) ||
|
||||||
|
permissionService.hasPermission(nodeRef, PermissionService.READ) != AccessStatus.ALLOWED)
|
||||||
|
{
|
||||||
|
// Doesn't have the aspect or the user doesn't have access
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
List<Rule> nodeRules = nodeRulesCache.get(nodeRef);
|
||||||
|
if (nodeRules != null)
|
||||||
|
{
|
||||||
|
// We have already processed this node
|
||||||
|
return nodeRules;
|
||||||
|
}
|
||||||
|
// Not in the cache, so go and get the rules
|
||||||
|
nodeRules = new ArrayList<Rule>();
|
||||||
|
NodeRef ruleFolder = getSavedRuleFolderRef(nodeRef);
|
||||||
|
if (ruleFolder != null)
|
||||||
|
{
|
||||||
|
// Get the rules for this node
|
||||||
|
List<ChildAssociationRef> ruleChildAssocRefs =
|
||||||
|
this.runtimeNodeService.getChildAssocs(ruleFolder, RegexQNamePattern.MATCH_ALL, ASSOC_NAME_RULES_REGEX);
|
||||||
|
for (ChildAssociationRef ruleChildAssocRef : ruleChildAssocRefs)
|
||||||
|
{
|
||||||
|
// Create the rule and add to the list
|
||||||
|
NodeRef ruleNodeRef = ruleChildAssocRef.getChildRef();
|
||||||
|
Rule rule = getRule(ruleNodeRef);
|
||||||
|
nodeRules.add(rule);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Store this in the cache for later re-use
|
||||||
|
nodeRulesCache.put(nodeRef, nodeRules);
|
||||||
|
// Done
|
||||||
|
return nodeRules;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.alfresco.service.cmr.rule.RuleService#countRules(org.alfresco.service.cmr.repository.NodeRef)
|
* @see org.alfresco.service.cmr.rule.RuleService#countRules(org.alfresco.service.cmr.repository.NodeRef)
|
||||||
*/
|
*/
|
||||||
@@ -651,6 +758,8 @@ public class RuleServiceImpl implements RuleService, RuntimeRuleService
|
|||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
enableRules();
|
enableRules();
|
||||||
|
// Drop the rules from the cache
|
||||||
|
nodeRulesCache.remove(nodeRef);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -728,6 +837,8 @@ public class RuleServiceImpl implements RuleService, RuntimeRuleService
|
|||||||
enableRules(nodeRef);
|
enableRules(nodeRef);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Drop the rules from the cache
|
||||||
|
nodeRulesCache.remove(nodeRef);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -757,6 +868,8 @@ public class RuleServiceImpl implements RuleService, RuntimeRuleService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Drop the rules from the cache
|
||||||
|
nodeRulesCache.remove(nodeRef);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -767,7 +880,6 @@ public class RuleServiceImpl implements RuleService, RuntimeRuleService
|
|||||||
/**
|
/**
|
||||||
* @see org.alfresco.repo.rule.RuntimeRuleService#addRulePendingExecution(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.rule.Rule)
|
* @see org.alfresco.repo.rule.RuntimeRuleService#addRulePendingExecution(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.rule.Rule)
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void addRulePendingExecution(NodeRef actionableNodeRef, NodeRef actionedUponNodeRef, Rule rule)
|
public void addRulePendingExecution(NodeRef actionableNodeRef, NodeRef actionedUponNodeRef, Rule rule)
|
||||||
{
|
{
|
||||||
addRulePendingExecution(actionableNodeRef, actionedUponNodeRef, rule, false);
|
addRulePendingExecution(actionableNodeRef, actionedUponNodeRef, rule, false);
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 Alfresco Software Limited.
|
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -36,10 +36,16 @@ public class FeedControl implements Serializable
|
|||||||
|
|
||||||
public FeedControl(String siteId, String appToolId)
|
public FeedControl(String siteId, String appToolId)
|
||||||
{
|
{
|
||||||
if (siteId == null) siteId = "";
|
if (siteId == null)
|
||||||
|
{
|
||||||
|
siteId = "";
|
||||||
|
}
|
||||||
this.siteId = siteId;
|
this.siteId = siteId;
|
||||||
|
|
||||||
if (appToolId == null) appToolId = "";
|
if (appToolId == null)
|
||||||
|
{
|
||||||
|
appToolId = "";
|
||||||
|
}
|
||||||
this.appToolId = appToolId;
|
this.appToolId = appToolId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user