/*
 * #%L
 * Alfresco Repository
 * %%
 * Copyright (C) 2005 - 2016 Alfresco Software Limited
 * %%
 * This file is part of the Alfresco software. 
 * If the software was purchased under a paid Alfresco license, the terms of 
 * the paid license agreement will prevail.  Otherwise, the software is 
 * provided under the following open source license terms:
 * 
 * Alfresco is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Alfresco is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with Alfresco. If not, see 
P extends Policy * @param behaviour Behaviour * @param definition PolicyDefinition
* @param policyInterface P * @param method Method * @param args Object[] */ @SuppressWarnings("unchecked") public
void queue(Behaviour behaviour, PolicyDefinition
definition, P policyInterface, Method method, Object[] args) { // Construct queue context, if required QueueContext queueContext = (QueueContext)AlfrescoTransactionSupport.getResource(QUEUE_CONTEXT_KEY); if (queueContext == null) { queueContext = new QueueContext(); AlfrescoTransactionSupport.bindResource(QUEUE_CONTEXT_KEY, queueContext); AlfrescoTransactionSupport.bindListener(this); } // Determine if behaviour instance has already been queued // Identity of ExecutionContext is Behaviour + KEY argument(s) ExecutionInstanceKey key = new ExecutionInstanceKey(behaviour, definition.getArguments(), args); ExecutionContext executionContext = queueContext.index.get(key); if (executionContext == null) { // Context does not exist // Create execution context for behaviour executionContext = new ExecutionContext
(); executionContext.method = method; executionContext.args = args; executionContext.policyInterface = policyInterface; // Defer or execute now? if (!queueContext.committed) { // queue behaviour for deferred execution queueContext.queue.offer(executionContext); } else { // execute now execute(executionContext); } queueContext.index.put(key, executionContext); } else { // Context does already exist // Update behaviour instance execution context, in particular, argument state that is marked END_TRANSACTION Arg[] argDefs = definition.getArguments(); for (int i = 0; i < argDefs.length; i++) { if (argDefs[i].equals(Arg.END_VALUE)) { executionContext.args[i] = args[i]; } } } } /* (non-Javadoc) * @see org.alfresco.repo.transaction.TransactionListener#flush() */ public void flush() { } /* (non-Javadoc) * @see org.alfresco.repo.transaction.TransactionListener#beforeCommit(boolean) */ @SuppressWarnings("unchecked") public void beforeCommit(boolean readOnly) { QueueContext queueContext = (QueueContext)AlfrescoTransactionSupport.getResource(QUEUE_CONTEXT_KEY); ExecutionContext context = queueContext.queue.poll(); while (context != null) { execute(context); context = queueContext.queue.poll(); } queueContext.committed = true; } /* (non-Javadoc) * @see org.alfresco.repo.transaction.TransactionListener#beforeCompletion() */ public void beforeCompletion() { } /* (non-Javadoc) * @see org.alfresco.repo.transaction.TransactionListener#afterCommit() */ public void afterCommit() { } /* (non-Javadoc) * @see org.alfresco.repo.transaction.TransactionListener#afterRollback() */ public void afterRollback() { } /** * Execution Instance Key - to uniquely identify an ExecutionContext */ private class ExecutionInstanceKey { public ExecutionInstanceKey(Behaviour behaviour, Arg[] argDefs, Object[] args) { this.behaviour = behaviour; for (int i = 0; i < argDefs.length; i++) { if (argDefs[i].equals(Arg.KEY)) { keys.add(args[i]); } } } Behaviour behaviour; ArrayList