mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged V2.2 to HEAD
10931: Merged V2.1 to V2.2 9931: Fix for https://issues.alfresco.com/jira/browse/ETWOONE-295 10094: Further fix for ETWOONE-241: SAXException - XML parser apparently is not thread safe 10101: Resolve ACT 1282: wcm workflow falling over on Oracle while hitting in clause limit of 1000 expressions. 10188: https://issues.alfresco.com/jira/browse/ETWOONE-74 (Part 1) 10447: ETWOONE-328: performance improvement added to rule trigger code 10455: Fix for ETWOONE-306. 10292: Fix for ETWOONE-92: If two users update the same contents at the same time, you get InvalidNodeRefException 10293: Fix for ETWOONE-116: Send email action does not handle invalid email address 10294: Fix for ETWOONE-164: when a powerpoint 2007 pptx is stored in alfresco ... 10341: Action Evaluator request level cache git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@10934 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -411,6 +411,12 @@
|
|||||||
<!-- Are tickets only valid for a single use? -->
|
<!-- Are tickets only valid for a single use? -->
|
||||||
<property name="oneOff">
|
<property name="oneOff">
|
||||||
<value>false</value>
|
<value>false</value>
|
||||||
|
</property>
|
||||||
|
<!-- If ticketsEpire is true then how they should expire -->
|
||||||
|
<!-- AFTER_INACTIVITY, AFTER_FIXED_TIME, DO_NOT_EXPIRE -->
|
||||||
|
<!-- The default is AFTER_FIXED_TIME -->
|
||||||
|
<property name="expiryMode">
|
||||||
|
<value>AFTER_FIXED_TIME</value>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
@@ -421,6 +421,12 @@
|
|||||||
<ref bean="admLuceneIndexerAndSearcherFactory" />
|
<ref bean="admLuceneIndexerAndSearcherFactory" />
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean id="versionSearchService" class="org.alfresco.repo.search.SearcherComponent">
|
||||||
|
<property name="indexerAndSearcherFactory">
|
||||||
|
<ref bean="admLuceneUnIndexedIndexerAndSearcherFactory" />
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
|
||||||
<!-- -->
|
<!-- -->
|
||||||
@@ -438,13 +444,17 @@
|
|||||||
<entry key="workspace">
|
<entry key="workspace">
|
||||||
<ref bean="admLuceneIndexerAndSearcherFactory"></ref>
|
<ref bean="admLuceneIndexerAndSearcherFactory"></ref>
|
||||||
</entry>
|
</entry>
|
||||||
<entry key="versionStore">
|
|
||||||
<ref bean="admLuceneIndexerAndSearcherFactory"></ref>
|
|
||||||
</entry>
|
|
||||||
<entry key="avm">
|
<entry key="avm">
|
||||||
<ref bean="avmLuceneIndexerAndSearcherFactory"></ref>
|
<ref bean="avmLuceneIndexerAndSearcherFactory"></ref>
|
||||||
</entry>
|
</entry>
|
||||||
</map>
|
</map>
|
||||||
|
</property>
|
||||||
|
<property name="redirectedStoreBindings">
|
||||||
|
<map>
|
||||||
|
<entry key="workspace://lightWeightVersionStore">
|
||||||
|
<ref bean="admLuceneUnIndexedIndexerAndSearcherFactory"></ref>
|
||||||
|
</entry>
|
||||||
|
</map>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
@@ -544,6 +554,63 @@
|
|||||||
<ref bean="hibernateL1CacheBulkLoader"></ref>
|
<ref bean="hibernateL1CacheBulkLoader"></ref>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Indexer and searchers for lucene -->
|
||||||
|
<bean id="admLuceneUnIndexedIndexerAndSearcherFactory"
|
||||||
|
class="org.alfresco.repo.search.impl.lucene.ADMLuceneUnIndexedIndexAndSearcherFactory">
|
||||||
|
<property name="nodeService">
|
||||||
|
<ref bean="mlAwareNodeService" />
|
||||||
|
</property>
|
||||||
|
<property name="dictionaryService">
|
||||||
|
<ref bean="dictionaryService" />
|
||||||
|
</property>
|
||||||
|
<property name="nameSpaceService">
|
||||||
|
<ref bean="namespaceService" />
|
||||||
|
</property>
|
||||||
|
<property name="indexRootLocation">
|
||||||
|
<value>${dir.indexes}</value>
|
||||||
|
</property>
|
||||||
|
<property name="contentService">
|
||||||
|
<ref bean="contentService" />
|
||||||
|
</property>
|
||||||
|
<property name="queryRegister">
|
||||||
|
<ref bean="queryRegisterComponent" />
|
||||||
|
</property>
|
||||||
|
<property name="maxAtomicTransformationTime">
|
||||||
|
<value>${lucene.maxAtomicTransformationTime}</value> <!-- milliseconds allowed for inline text transformation -->
|
||||||
|
</property>
|
||||||
|
<property name="queryMaxClauses">
|
||||||
|
<value>${lucene.query.maxClauses}</value>
|
||||||
|
</property>
|
||||||
|
<property name="indexerBatchSize">
|
||||||
|
<value>${lucene.indexer.batchSize}</value>
|
||||||
|
</property>
|
||||||
|
<property name="lockDirectory">
|
||||||
|
<value>${dir.indexes.lock}</value>
|
||||||
|
</property>
|
||||||
|
<property name="indexerMaxFieldLength">
|
||||||
|
<value>${lucene.indexer.maxFieldLength}</value>
|
||||||
|
</property>
|
||||||
|
<property name="writeLockTimeout">
|
||||||
|
<value>${lucene.write.lock.timeout}</value>
|
||||||
|
</property>
|
||||||
|
<property name="commitLockTimeout">
|
||||||
|
<value>${lucene.commit.lock.timeout}</value>
|
||||||
|
</property>
|
||||||
|
<property name="lockPollInterval">
|
||||||
|
<value>${lucene.lock.poll.interval}</value>
|
||||||
|
</property>
|
||||||
|
<property name="defaultMLIndexAnalysisMode">
|
||||||
|
<value>EXACT_LANGUAGE_AND_ALL</value>
|
||||||
|
</property>
|
||||||
|
<property name="defaultMLSearchAnalysisMode">
|
||||||
|
<value>EXACT_LANGUAGE_AND_ALL</value>
|
||||||
|
</property>
|
||||||
|
<property name="threadPoolExecutor">
|
||||||
|
<ref bean="indexThreadPoolExecutor"></ref>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
<!-- Indexer and searchers for lucene -->
|
<!-- Indexer and searchers for lucene -->
|
||||||
<bean id="avmLuceneIndexerAndSearcherFactory"
|
<bean id="avmLuceneIndexerAndSearcherFactory"
|
||||||
@@ -677,7 +744,7 @@
|
|||||||
<ref bean="versionCounterService" />
|
<ref bean="versionCounterService" />
|
||||||
</property>
|
</property>
|
||||||
<property name="searcher">
|
<property name="searcher">
|
||||||
<ref bean="admSearchService" />
|
<ref bean="versionSearchService" />
|
||||||
</property>
|
</property>
|
||||||
<property name="dictionaryService">
|
<property name="dictionaryService">
|
||||||
<ref bean="dictionaryService" />
|
<ref bean="dictionaryService" />
|
||||||
|
@@ -34,7 +34,6 @@ import java.util.Set;
|
|||||||
import javax.mail.MessagingException;
|
import javax.mail.MessagingException;
|
||||||
import javax.mail.internet.MimeMessage;
|
import javax.mail.internet.MimeMessage;
|
||||||
|
|
||||||
import org.alfresco.error.AlfrescoRuntimeException;
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.action.ParameterDefinitionImpl;
|
import org.alfresco.repo.action.ParameterDefinitionImpl;
|
||||||
import org.alfresco.repo.template.DateCompareMethod;
|
import org.alfresco.repo.template.DateCompareMethod;
|
||||||
@@ -54,6 +53,7 @@ import org.alfresco.service.cmr.security.AuthorityType;
|
|||||||
import org.alfresco.service.cmr.security.PersonService;
|
import org.alfresco.service.cmr.security.PersonService;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.apache.commons.validator.EmailValidator;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
import org.springframework.mail.javamail.JavaMailSender;
|
import org.springframework.mail.javamail.JavaMailSender;
|
||||||
import org.springframework.mail.javamail.MimeMessageHelper;
|
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||||
@@ -261,7 +261,7 @@ public class MailActionExecuter extends ActionExecuterAbstractBase
|
|||||||
{
|
{
|
||||||
NodeRef person = personService.getPerson(authority);
|
NodeRef person = personService.getPerson(authority);
|
||||||
String address = (String)nodeService.getProperty(person, ContentModel.PROP_EMAIL);
|
String address = (String)nodeService.getProperty(person, ContentModel.PROP_EMAIL);
|
||||||
if (address != null && address.length() != 0)
|
if (address != null && address.length() != 0 && validateAddress(address))
|
||||||
{
|
{
|
||||||
recipients.add(address);
|
recipients.add(address);
|
||||||
}
|
}
|
||||||
@@ -351,6 +351,28 @@ public class MailActionExecuter extends ActionExecuterAbstractBase
|
|||||||
logger.error("Failed to send email to " + to, e);
|
logger.error("Failed to send email to " + to, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if address has valid format
|
||||||
|
* @param address
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private boolean validateAddress(String address)
|
||||||
|
{
|
||||||
|
boolean result = false;
|
||||||
|
|
||||||
|
EmailValidator emailValidator = EmailValidator.getInstance();
|
||||||
|
if (emailValidator.isValid(address))
|
||||||
|
{
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.error("Failed to send email to '" + address + "' as the address is incorrectly formatted" );
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ref The node representing the current document ref
|
* @param ref The node representing the current document ref
|
||||||
|
@@ -538,7 +538,8 @@ public class RuleServiceImpl implements RuleService, RuntimeRuleService
|
|||||||
* @param ruleNodeRef the rule node reference
|
* @param ruleNodeRef the rule node reference
|
||||||
* @return the rule
|
* @return the rule
|
||||||
*/
|
*/
|
||||||
public Rule getRule(NodeRef ruleNodeRef)
|
@SuppressWarnings("unchecked")
|
||||||
|
public Rule getRule(NodeRef ruleNodeRef)
|
||||||
{
|
{
|
||||||
// Get the rule properties
|
// Get the rule properties
|
||||||
Map<QName, Serializable> props = this.runtimeNodeService.getProperties(ruleNodeRef);
|
Map<QName, Serializable> props = this.runtimeNodeService.getProperties(ruleNodeRef);
|
||||||
|
@@ -129,14 +129,14 @@ public class RuleTypeImpl extends CommonResourceAbstractBase implements RuleType
|
|||||||
this.nodeService.exists(actionedUponNodeRef) == true &&
|
this.nodeService.exists(actionedUponNodeRef) == true &&
|
||||||
this.nodeService.hasAspect(actionedUponNodeRef, ContentModel.ASPECT_TEMPORARY) == false)
|
this.nodeService.hasAspect(actionedUponNodeRef, ContentModel.ASPECT_TEMPORARY) == false)
|
||||||
{
|
{
|
||||||
if (this.ruleService.hasRules(nodeRef) == true)
|
List<Rule> rules = this.ruleService.getRules(
|
||||||
|
nodeRef,
|
||||||
|
true,
|
||||||
|
this.name);
|
||||||
|
|
||||||
|
if (rules.size() != 0)
|
||||||
{
|
{
|
||||||
List<Rule> rules = this.ruleService.getRules(
|
for (Rule rule : rules)
|
||||||
nodeRef,
|
|
||||||
true,
|
|
||||||
this.name);
|
|
||||||
|
|
||||||
for (Rule rule : rules)
|
|
||||||
{
|
{
|
||||||
if (logger.isDebugEnabled() == true)
|
if (logger.isDebugEnabled() == true)
|
||||||
{
|
{
|
||||||
|
@@ -42,15 +42,15 @@ import org.alfresco.service.namespace.NamespaceService;
|
|||||||
*/
|
*/
|
||||||
public class ADMLuceneIndexerAndSearcherFactory extends AbstractLuceneIndexerAndSearcherFactory implements SupportsBackgroundIndexing
|
public class ADMLuceneIndexerAndSearcherFactory extends AbstractLuceneIndexerAndSearcherFactory implements SupportsBackgroundIndexing
|
||||||
{
|
{
|
||||||
private DictionaryService dictionaryService;
|
protected DictionaryService dictionaryService;
|
||||||
|
|
||||||
private NamespaceService nameSpaceService;
|
private NamespaceService nameSpaceService;
|
||||||
|
|
||||||
private NodeService nodeService;
|
protected NodeService nodeService;
|
||||||
|
|
||||||
private FullTextSearchIndexer fullTextSearchIndexer;
|
protected FullTextSearchIndexer fullTextSearchIndexer;
|
||||||
|
|
||||||
private ContentService contentService;
|
protected ContentService contentService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the dictinary service
|
* Set the dictinary service
|
||||||
|
@@ -393,6 +393,18 @@ public class ADMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<NodeRef> imp
|
|||||||
indexer.initialise(storeRef, deltaId);
|
indexer.initialise(storeRef, deltaId);
|
||||||
return indexer;
|
return indexer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ADMLuceneNoActionIndexerImpl getNoActionIndexer(StoreRef storeRef, String deltaId, LuceneConfig config) throws LuceneIndexException
|
||||||
|
{
|
||||||
|
if (s_logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
s_logger.debug("Creating indexer");
|
||||||
|
}
|
||||||
|
ADMLuceneNoActionIndexerImpl indexer = new ADMLuceneNoActionIndexerImpl();
|
||||||
|
indexer.setLuceneConfig(config);
|
||||||
|
indexer.initialise(storeRef, deltaId);
|
||||||
|
return indexer;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transactional support Used by the resource manager for indexers.
|
* Transactional support Used by the resource manager for indexers.
|
||||||
|
@@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
* As a special exception to the terms and conditions of version 2.0 of
|
||||||
|
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||||
|
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||||
|
* FLOSS exception. You should have recieved a copy of the text describing
|
||||||
|
* the FLOSS exception, and it is also available here:
|
||||||
|
* http://www.alfresco.com/legal/licensing"
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.search.impl.lucene;
|
||||||
|
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
|
||||||
|
public class ADMLuceneNoActionIndexerImpl extends ADMLuceneIndexerImpl
|
||||||
|
{
|
||||||
|
|
||||||
|
public ADMLuceneNoActionIndexerImpl()
|
||||||
|
{
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createChildRelationship(ChildAssociationRef relationshipRef) throws LuceneIndexException
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createNode(ChildAssociationRef relationshipRef) throws LuceneIndexException
|
||||||
|
{
|
||||||
|
NodeRef childRef = relationshipRef.getChildRef();
|
||||||
|
// If we have the root node we delete all other root nodes first
|
||||||
|
if ((relationshipRef.getParentRef() == null) && childRef.equals(nodeService.getRootNode(childRef.getStoreRef())))
|
||||||
|
{
|
||||||
|
// do the root node only
|
||||||
|
super.createNode(relationshipRef);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteChildRelationship(ChildAssociationRef relationshipRef) throws LuceneIndexException
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteNode(ChildAssociationRef relationshipRef) throws LuceneIndexException
|
||||||
|
{
|
||||||
|
NodeRef childRef = relationshipRef.getChildRef();
|
||||||
|
// If we have the root node we delete all other root nodes first
|
||||||
|
if ((relationshipRef.getParentRef() == null) && childRef.equals(nodeService.getRootNode(childRef.getStoreRef())))
|
||||||
|
{
|
||||||
|
// do the root node only
|
||||||
|
super.deleteNode(relationshipRef);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateChildRelationship(ChildAssociationRef relationshipBeforeRef, ChildAssociationRef relationshipAfterRef) throws LuceneIndexException
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateNode(NodeRef nodeRef) throws LuceneIndexException
|
||||||
|
{
|
||||||
|
if((nodeService.hasAspect(nodeRef, ContentModel.ASPECT_ROOT) && nodeRef.equals(nodeService.getRootNode(nodeRef.getStoreRef()))))
|
||||||
|
{
|
||||||
|
super.updateNode(nodeRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
* As a special exception to the terms and conditions of version 2.0 of
|
||||||
|
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||||
|
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||||
|
* FLOSS exception. You should have recieved a copy of the text describing
|
||||||
|
* the FLOSS exception, and it is also available here:
|
||||||
|
* http://www.alfresco.com/legal/licensing"
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.search.impl.lucene;
|
||||||
|
|
||||||
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
|
|
||||||
|
public class ADMLuceneUnIndexedIndexAndSearcherFactory extends ADMLuceneIndexerAndSearcherFactory
|
||||||
|
{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected LuceneIndexer createIndexer(StoreRef storeRef, String deltaId)
|
||||||
|
{
|
||||||
|
ADMLuceneNoActionIndexerImpl indexer = ADMLuceneIndexerImpl.getNoActionIndexer(storeRef, deltaId, this);
|
||||||
|
indexer.setNodeService(nodeService);
|
||||||
|
indexer.setDictionaryService(dictionaryService);
|
||||||
|
// indexer.setLuceneIndexLock(luceneIndexLock);
|
||||||
|
indexer.setFullTextSearchIndexer(fullTextSearchIndexer);
|
||||||
|
indexer.setContentService(contentService);
|
||||||
|
indexer.setMaxAtomicTransformationTime(getMaxTransformationTime());
|
||||||
|
return indexer;
|
||||||
|
}
|
||||||
|
}
|
@@ -48,6 +48,7 @@ import net.sf.acegisecurity.providers.dao.SaltSource;
|
|||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.cache.SimpleCache;
|
import org.alfresco.repo.cache.SimpleCache;
|
||||||
|
import org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl.ExpiryMode;
|
||||||
import org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl.Ticket;
|
import org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl.Ticket;
|
||||||
import org.alfresco.repo.tenant.TenantService;
|
import org.alfresco.repo.tenant.TenantService;
|
||||||
import org.alfresco.service.ServiceRegistry;
|
import org.alfresco.service.ServiceRegistry;
|
||||||
@@ -139,8 +140,7 @@ public class AuthenticationTest extends TestCase
|
|||||||
authenticationManager = (AuthenticationManager) ctx.getBean("authenticationManager");
|
authenticationManager = (AuthenticationManager) ctx.getBean("authenticationManager");
|
||||||
saltSource = (SaltSource) ctx.getBean("saltSource");
|
saltSource = (SaltSource) ctx.getBean("saltSource");
|
||||||
|
|
||||||
TransactionService transactionService = (TransactionService) ctx.getBean(ServiceRegistry.TRANSACTION_SERVICE
|
TransactionService transactionService = (TransactionService) ctx.getBean(ServiceRegistry.TRANSACTION_SERVICE.getLocalName());
|
||||||
.getLocalName());
|
|
||||||
userTransaction = transactionService.getUserTransaction();
|
userTransaction = transactionService.getUserTransaction();
|
||||||
userTransaction.begin();
|
userTransaction.begin();
|
||||||
|
|
||||||
@@ -155,8 +155,7 @@ public class AuthenticationTest extends TestCase
|
|||||||
systemNodeRef = nodeService.createNode(rootNodeRef, children, system, container).getChildRef();
|
systemNodeRef = nodeService.createNode(rootNodeRef, children, system, container).getChildRef();
|
||||||
typesNodeRef = nodeService.createNode(systemNodeRef, children, types, container).getChildRef();
|
typesNodeRef = nodeService.createNode(systemNodeRef, children, types, container).getChildRef();
|
||||||
Map<QName, Serializable> props = createPersonProperties("Andy");
|
Map<QName, Serializable> props = createPersonProperties("Andy");
|
||||||
personAndyNodeRef = nodeService.createNode(typesNodeRef, children, ContentModel.TYPE_PERSON, container, props)
|
personAndyNodeRef = nodeService.createNode(typesNodeRef, children, ContentModel.TYPE_PERSON, container, props).getChildRef();
|
||||||
.getChildRef();
|
|
||||||
assertNotNull(personAndyNodeRef);
|
assertNotNull(personAndyNodeRef);
|
||||||
|
|
||||||
deleteAndy();
|
deleteAndy();
|
||||||
@@ -270,6 +269,10 @@ public class AuthenticationTest extends TestCase
|
|||||||
authenticationService.authenticate("Andy_ Woof/Domain", "".toCharArray());
|
authenticationService.authenticate("Andy_ Woof/Domain", "".toCharArray());
|
||||||
assertEquals("Andy_ Woof/Domain", authenticationService.getCurrentUserName());
|
assertEquals("Andy_ Woof/Domain", authenticationService.getCurrentUserName());
|
||||||
|
|
||||||
|
authenticationService.createAuthentication("Andy `\u00ac\u00a6!\u00a3$%^&*()-_=+\t\n\u0000[]{};'#:@~,./<>?\\|", "".toCharArray());
|
||||||
|
authenticationService.authenticate("Andy `\u00ac\u00a6!\u00a3$%^&*()-_=+\t\n\u0000[]{};'#:@~,./<>?\\|", "".toCharArray());
|
||||||
|
assertEquals("Andy `\u00ac\u00a6!\u00a3$%^&*()-_=+\t\n\u0000[]{};'#:@~,./<>?\\|", authenticationService.getCurrentUserName());
|
||||||
|
|
||||||
if (! tenantService.isEnabled())
|
if (! tenantService.isEnabled())
|
||||||
{
|
{
|
||||||
authenticationService.createAuthentication("Andy `\u00ac\u00a6!\u00a3$%^&*()-_=+\t\n\u0000[]{};'#:@~,./<>?\\|", "".toCharArray());
|
authenticationService.createAuthentication("Andy `\u00ac\u00a6!\u00a3$%^&*()-_=+\t\n\u0000[]{};'#:@~,./<>?\\|", "".toCharArray());
|
||||||
@@ -307,8 +310,7 @@ public class AuthenticationTest extends TestCase
|
|||||||
assertTrue(AndyDetails.isCredentialsNonExpired());
|
assertTrue(AndyDetails.isCredentialsNonExpired());
|
||||||
assertTrue(AndyDetails.isEnabled());
|
assertTrue(AndyDetails.isEnabled());
|
||||||
assertNotSame("cabbage", AndyDetails.getPassword());
|
assertNotSame("cabbage", AndyDetails.getPassword());
|
||||||
assertEquals(AndyDetails.getPassword(), passwordEncoder.encodePassword("cabbage", saltSource
|
assertEquals(AndyDetails.getPassword(), passwordEncoder.encodePassword("cabbage", saltSource.getSalt(AndyDetails)));
|
||||||
.getSalt(AndyDetails)));
|
|
||||||
assertEquals(1, AndyDetails.getAuthorities().length);
|
assertEquals(1, AndyDetails.getAuthorities().length);
|
||||||
|
|
||||||
// Object oldSalt = dao.getSalt(AndyDetails);
|
// Object oldSalt = dao.getSalt(AndyDetails);
|
||||||
@@ -465,8 +467,6 @@ public class AuthenticationTest extends TestCase
|
|||||||
// assertNull(dao.getUserOrNull("Andy"));
|
// assertNull(dao.getUserOrNull("Andy"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void testTicket()
|
public void testTicket()
|
||||||
{
|
{
|
||||||
dao.createUser("Andy", "ticket".toCharArray());
|
dao.createUser("Andy", "ticket".toCharArray());
|
||||||
@@ -568,6 +568,147 @@ public class AuthenticationTest extends TestCase
|
|||||||
// assertNull(dao.getUserOrNull("Andy"));
|
// assertNull(dao.getUserOrNull("Andy"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testTicketExpiryMode()
|
||||||
|
{
|
||||||
|
InMemoryTicketComponentImpl tc = new InMemoryTicketComponentImpl();
|
||||||
|
tc.setOneOff(false);
|
||||||
|
tc.setTicketsExpire(true);
|
||||||
|
tc.setValidDuration("P5S");
|
||||||
|
tc.setTicketsCache(ticketsCache);
|
||||||
|
tc.setExpiryMode(ExpiryMode.AFTER_FIXED_TIME.toString());
|
||||||
|
|
||||||
|
dao.createUser("Andy", "ticket".toCharArray());
|
||||||
|
|
||||||
|
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Andy", "ticket");
|
||||||
|
token.setAuthenticated(false);
|
||||||
|
|
||||||
|
Authentication result = authenticationManager.authenticate(token);
|
||||||
|
result.setAuthenticated(true);
|
||||||
|
|
||||||
|
String ticket = tc.getNewTicket(getUserName(result));
|
||||||
|
tc.validateTicket(ticket);
|
||||||
|
assertEquals(ticketComponent.getCurrentTicket("Andy"), ticket);
|
||||||
|
tc.validateTicket(ticket);
|
||||||
|
assertEquals(ticketComponent.getCurrentTicket("Andy"), ticket);
|
||||||
|
tc.validateTicket(ticket);
|
||||||
|
assertEquals(ticketComponent.getCurrentTicket("Andy"), ticket);
|
||||||
|
|
||||||
|
synchronized (this)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
wait(10000);
|
||||||
|
}
|
||||||
|
catch (InterruptedException e)
|
||||||
|
{
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
tc.validateTicket(ticket);
|
||||||
|
assertNotNull(null);
|
||||||
|
}
|
||||||
|
catch (AuthenticationException e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
tc.validateTicket(ticket);
|
||||||
|
assertNotNull(null);
|
||||||
|
}
|
||||||
|
catch (AuthenticationException e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
tc.validateTicket(ticket);
|
||||||
|
assertNotNull(null);
|
||||||
|
}
|
||||||
|
catch (AuthenticationException e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (this)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
wait(10000);
|
||||||
|
}
|
||||||
|
catch (InterruptedException e)
|
||||||
|
{
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
tc.validateTicket(ticket);
|
||||||
|
assertNotNull(null);
|
||||||
|
}
|
||||||
|
catch (AuthenticationException e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
tc.setExpiryMode(ExpiryMode.AFTER_INACTIVITY.toString());
|
||||||
|
ticket = tc.getNewTicket(getUserName(result));
|
||||||
|
|
||||||
|
for (int i = 0; i < 50; i++)
|
||||||
|
{
|
||||||
|
synchronized (this)
|
||||||
|
{
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
wait(100);
|
||||||
|
}
|
||||||
|
catch (InterruptedException e)
|
||||||
|
{
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
tc.validateTicket(ticket);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (this)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
wait(10000);
|
||||||
|
}
|
||||||
|
catch (InterruptedException e)
|
||||||
|
{
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
tc.validateTicket(ticket);
|
||||||
|
assertNotNull(null);
|
||||||
|
}
|
||||||
|
catch (AuthenticationException e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
dao.deleteUser("Andy");
|
||||||
|
// assertNull(dao.getUserOrNull("Andy"));
|
||||||
|
}
|
||||||
|
|
||||||
public void testTicketExpires()
|
public void testTicketExpires()
|
||||||
{
|
{
|
||||||
InMemoryTicketComponentImpl tc = new InMemoryTicketComponentImpl();
|
InMemoryTicketComponentImpl tc = new InMemoryTicketComponentImpl();
|
||||||
@@ -704,7 +845,7 @@ public class AuthenticationTest extends TestCase
|
|||||||
// assertNull(dao.getUserOrNull("Andy"));
|
// assertNull(dao.getUserOrNull("Andy"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testAuthenticationServiceGetNewTicket()
|
public void testAuthenticationServiceGetNewTicket()
|
||||||
{
|
{
|
||||||
authenticationService.createAuthentication("GUEST", "".toCharArray());
|
authenticationService.createAuthentication("GUEST", "".toCharArray());
|
||||||
@@ -718,16 +859,16 @@ public class AuthenticationTest extends TestCase
|
|||||||
|
|
||||||
// assert the user is authenticated
|
// assert the user is authenticated
|
||||||
assertEquals("Andy", authenticationService.getCurrentUserName());
|
assertEquals("Andy", authenticationService.getCurrentUserName());
|
||||||
|
|
||||||
String ticket1 = authenticationService.getCurrentTicket();
|
String ticket1 = authenticationService.getCurrentTicket();
|
||||||
|
|
||||||
authenticationService.authenticate("Andy", "auth1".toCharArray());
|
authenticationService.authenticate("Andy", "auth1".toCharArray());
|
||||||
|
|
||||||
// assert the user is authenticated
|
// assert the user is authenticated
|
||||||
assertEquals("Andy", authenticationService.getCurrentUserName());
|
assertEquals("Andy", authenticationService.getCurrentUserName());
|
||||||
|
|
||||||
String ticket2 = authenticationService.getCurrentTicket();
|
String ticket2 = authenticationService.getCurrentTicket();
|
||||||
|
|
||||||
assertFalse(ticket1.equals(ticket2));
|
assertFalse(ticket1.equals(ticket2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -49,7 +49,7 @@ public class InMemoryTicketComponentImpl implements TicketComponent
|
|||||||
* Ticket prefix
|
* Ticket prefix
|
||||||
*/
|
*/
|
||||||
public static final String GRANTED_AUTHORITY_TICKET_PREFIX = "TICKET_";
|
public static final String GRANTED_AUTHORITY_TICKET_PREFIX = "TICKET_";
|
||||||
|
|
||||||
private static ThreadLocal<String> currentTicket = new ThreadLocal<String>();
|
private static ThreadLocal<String> currentTicket = new ThreadLocal<String>();
|
||||||
|
|
||||||
private boolean ticketsExpire;
|
private boolean ticketsExpire;
|
||||||
@@ -61,10 +61,11 @@ public class InMemoryTicketComponentImpl implements TicketComponent
|
|||||||
private String guid;
|
private String guid;
|
||||||
|
|
||||||
private SimpleCache<String, Ticket> ticketsCache; // Can't use Ticket as it's private
|
private SimpleCache<String, Ticket> ticketsCache; // Can't use Ticket as it's private
|
||||||
|
|
||||||
|
private ExpiryMode expiryMode = ExpiryMode.AFTER_FIXED_TIME;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IOC constructor
|
* IOC constructor
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public InMemoryTicketComponentImpl()
|
public InMemoryTicketComponentImpl()
|
||||||
{
|
{
|
||||||
@@ -89,7 +90,7 @@ public class InMemoryTicketComponentImpl implements TicketComponent
|
|||||||
{
|
{
|
||||||
expiryDate = Duration.add(new Date(), validDuration);
|
expiryDate = Duration.add(new Date(), validDuration);
|
||||||
}
|
}
|
||||||
Ticket ticket = new Ticket(ticketsExpire, expiryDate, userName);
|
Ticket ticket = new Ticket(ticketsExpire ? expiryMode : ExpiryMode.DO_NOT_EXPIRE, expiryDate, userName, validDuration);
|
||||||
ticketsCache.put(ticket.getTicketId(), ticket);
|
ticketsCache.put(ticket.getTicketId(), ticket);
|
||||||
String ticketString = GRANTED_AUTHORITY_TICKET_PREFIX + ticket.getTicketId();
|
String ticketString = GRANTED_AUTHORITY_TICKET_PREFIX + ticket.getTicketId();
|
||||||
currentTicket.set(ticketString);
|
currentTicket.set(ticketString);
|
||||||
@@ -119,6 +120,7 @@ public class InMemoryTicketComponentImpl implements TicketComponent
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to find a ticket
|
* Helper method to find a ticket
|
||||||
|
*
|
||||||
* @param ticketString
|
* @param ticketString
|
||||||
* @return - the ticket
|
* @return - the ticket
|
||||||
*/
|
*/
|
||||||
@@ -129,7 +131,8 @@ public class InMemoryTicketComponentImpl implements TicketComponent
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to extract the ticket id from the ticket string
|
* Helper method to extract the ticket id from the ticket string
|
||||||
|
*
|
||||||
* @param ticketString
|
* @param ticketString
|
||||||
* @return - the ticket key
|
* @return - the ticket key
|
||||||
*/
|
*/
|
||||||
@@ -271,14 +274,14 @@ public class InMemoryTicketComponentImpl implements TicketComponent
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Ticket
|
* Ticket
|
||||||
|
*
|
||||||
* @author andyh
|
* @author andyh
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public static class Ticket implements Serializable
|
public static class Ticket implements Serializable
|
||||||
{
|
{
|
||||||
private static final long serialVersionUID = -5904510560161261049L;
|
private static final long serialVersionUID = -5904510560161261049L;
|
||||||
|
|
||||||
private boolean expires;
|
private ExpiryMode expires;
|
||||||
|
|
||||||
private Date expiryDate;
|
private Date expiryDate;
|
||||||
|
|
||||||
@@ -287,18 +290,18 @@ public class InMemoryTicketComponentImpl implements TicketComponent
|
|||||||
private String ticketId;
|
private String ticketId;
|
||||||
|
|
||||||
private String guid;
|
private String guid;
|
||||||
|
|
||||||
|
private Duration validDuration;
|
||||||
|
|
||||||
Ticket(boolean expires, Date expiryDate, String userName)
|
Ticket(ExpiryMode expires, Date expiryDate, String userName, Duration validDuration)
|
||||||
{
|
{
|
||||||
this.expires = expires;
|
this.expires = expires;
|
||||||
this.expiryDate = expiryDate;
|
this.expiryDate = expiryDate;
|
||||||
this.userName = userName;
|
this.userName = userName;
|
||||||
|
this.validDuration = validDuration;
|
||||||
this.guid = UUIDGenerator.getInstance().generateRandomBasedUUID().toString();
|
this.guid = UUIDGenerator.getInstance().generateRandomBasedUUID().toString();
|
||||||
|
|
||||||
|
|
||||||
String encode = (expires ? "T" : "F") +
|
String encode = (expires.toString()) + ((expiryDate == null) ? new Date().toString() : expiryDate.toString()) + userName + guid;
|
||||||
((expiryDate == null) ? new Date().toString(): expiryDate.toString()) +
|
|
||||||
userName + guid;
|
|
||||||
MessageDigest digester;
|
MessageDigest digester;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -314,18 +317,18 @@ public class InMemoryTicketComponentImpl implements TicketComponent
|
|||||||
}
|
}
|
||||||
catch (NoSuchAlgorithmException e1)
|
catch (NoSuchAlgorithmException e1)
|
||||||
{
|
{
|
||||||
CRC32 crc = new CRC32();
|
CRC32 crc = new CRC32();
|
||||||
crc.update(encode.getBytes());
|
crc.update(encode.getBytes());
|
||||||
byte[] bytes = new byte[4];
|
byte[] bytes = new byte[4];
|
||||||
long value = crc.getValue();
|
long value = crc.getValue();
|
||||||
bytes[0] = (byte)(value & 0xFF);
|
bytes[0] = (byte) (value & 0xFF);
|
||||||
value >>>= 4;
|
value >>>= 4;
|
||||||
bytes[1] = (byte)(value & 0xFF);
|
bytes[1] = (byte) (value & 0xFF);
|
||||||
value >>>= 4;
|
value >>>= 4;
|
||||||
bytes[2] = (byte)(value & 0xFF);
|
bytes[2] = (byte) (value & 0xFF);
|
||||||
value >>>= 4;
|
value >>>= 4;
|
||||||
bytes[3] = (byte)(value & 0xFF);
|
bytes[3] = (byte) (value & 0xFF);
|
||||||
this.ticketId = new String(Hex.encodeHex(bytes));
|
this.ticketId = new String(Hex.encodeHex(bytes));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -337,14 +340,33 @@ public class InMemoryTicketComponentImpl implements TicketComponent
|
|||||||
*/
|
*/
|
||||||
boolean hasExpired()
|
boolean hasExpired()
|
||||||
{
|
{
|
||||||
if (expires && (expiryDate != null) && (expiryDate.compareTo(new Date()) < 0))
|
Date now = new Date();
|
||||||
{
|
switch (expires)
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
case AFTER_FIXED_TIME:
|
||||||
|
if ((expiryDate != null) && (expiryDate.compareTo(now) < 0))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
case AFTER_INACTIVITY:
|
||||||
|
if ((expiryDate != null) && (expiryDate.compareTo(now) < 0))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
expiryDate = Duration.add(now, validDuration);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
case DO_NOT_EXPIRE:
|
||||||
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean equals(Object o)
|
public boolean equals(Object o)
|
||||||
@@ -358,9 +380,7 @@ public class InMemoryTicketComponentImpl implements TicketComponent
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Ticket t = (Ticket) o;
|
Ticket t = (Ticket) o;
|
||||||
return (this.expires == t.expires)
|
return (this.expires == t.expires) && this.expiryDate.equals(t.expiryDate) && this.userName.equals(t.userName) && this.ticketId.equals(t.ticketId);
|
||||||
&& this.expiryDate.equals(t.expiryDate) && this.userName.equals(t.userName)
|
|
||||||
&& this.ticketId.equals(t.ticketId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int hashCode()
|
public int hashCode()
|
||||||
@@ -368,7 +388,7 @@ public class InMemoryTicketComponentImpl implements TicketComponent
|
|||||||
return ticketId.hashCode();
|
return ticketId.hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean getExpires()
|
protected ExpiryMode getExpires()
|
||||||
{
|
{
|
||||||
return expires;
|
return expires;
|
||||||
}
|
}
|
||||||
@@ -390,10 +410,11 @@ public class InMemoryTicketComponentImpl implements TicketComponent
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Are tickets single use
|
* Are tickets single use
|
||||||
* @param oneOff
|
*
|
||||||
*/
|
* @param oneOff
|
||||||
|
*/
|
||||||
public void setOneOff(boolean oneOff)
|
public void setOneOff(boolean oneOff)
|
||||||
{
|
{
|
||||||
this.oneOff = oneOff;
|
this.oneOff = oneOff;
|
||||||
@@ -401,6 +422,7 @@ public class InMemoryTicketComponentImpl implements TicketComponent
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Do tickets expire
|
* Do tickets expire
|
||||||
|
*
|
||||||
* @param ticketsExpire
|
* @param ticketsExpire
|
||||||
*/
|
*/
|
||||||
public void setTicketsExpire(boolean ticketsExpire)
|
public void setTicketsExpire(boolean ticketsExpire)
|
||||||
@@ -408,8 +430,19 @@ public class InMemoryTicketComponentImpl implements TicketComponent
|
|||||||
this.ticketsExpire = ticketsExpire;
|
this.ticketsExpire = ticketsExpire;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How should tickets expire.
|
||||||
|
* @param exipryMode
|
||||||
|
*/
|
||||||
|
public void setExpiryMode(String expiryMode)
|
||||||
|
{
|
||||||
|
this.expiryMode = ExpiryMode.valueOf(expiryMode);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* How long are tickets valid (XML duration as a string)
|
* How long are tickets valid (XML duration as a string)
|
||||||
|
*
|
||||||
* @param validDuration
|
* @param validDuration
|
||||||
*/
|
*/
|
||||||
public void setValidDuration(String validDuration)
|
public void setValidDuration(String validDuration)
|
||||||
@@ -430,12 +463,12 @@ public class InMemoryTicketComponentImpl implements TicketComponent
|
|||||||
public String getCurrentTicket(String userName)
|
public String getCurrentTicket(String userName)
|
||||||
{
|
{
|
||||||
String ticket = currentTicket.get();
|
String ticket = currentTicket.get();
|
||||||
if(ticket == null)
|
if (ticket == null)
|
||||||
{
|
{
|
||||||
return getNewTicket(userName);
|
return getNewTicket(userName);
|
||||||
}
|
}
|
||||||
String ticketUser = getAuthorityForTicket(ticket);
|
String ticketUser = getAuthorityForTicket(ticket);
|
||||||
if(userName.equals(ticketUser))
|
if (userName.equals(ticketUser))
|
||||||
{
|
{
|
||||||
return ticket;
|
return ticket;
|
||||||
}
|
}
|
||||||
@@ -449,9 +482,14 @@ public class InMemoryTicketComponentImpl implements TicketComponent
|
|||||||
{
|
{
|
||||||
clearCurrentSecurityContext();
|
clearCurrentSecurityContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void clearCurrentSecurityContext()
|
public static void clearCurrentSecurityContext()
|
||||||
{
|
{
|
||||||
currentTicket.set(null);
|
currentTicket.set(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum ExpiryMode
|
||||||
|
{
|
||||||
|
AFTER_INACTIVITY, AFTER_FIXED_TIME, DO_NOT_EXPIRE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -47,6 +47,7 @@ import org.springframework.beans.factory.BeanFactory;
|
|||||||
public class ForEachFork extends JBPMSpringActionHandler
|
public class ForEachFork extends JBPMSpringActionHandler
|
||||||
{
|
{
|
||||||
private static final long serialVersionUID = 4643103713602441652L;
|
private static final long serialVersionUID = 4643103713602441652L;
|
||||||
|
|
||||||
private ServiceRegistry services;
|
private ServiceRegistry services;
|
||||||
|
|
||||||
private Element foreach;
|
private Element foreach;
|
||||||
@@ -190,7 +191,7 @@ public class ForEachFork extends JBPMSpringActionHandler
|
|||||||
protected String getTokenName(Token parent, String transitionName, int loopIndex)
|
protected String getTokenName(Token parent, String transitionName, int loopIndex)
|
||||||
{
|
{
|
||||||
String tokenName = null;
|
String tokenName = null;
|
||||||
if (transitionName != null)
|
if (transitionName != null && transitionName.length() > 0)
|
||||||
{
|
{
|
||||||
if (!parent.hasChild(transitionName))
|
if (!parent.hasChild(transitionName))
|
||||||
{
|
{
|
||||||
@@ -210,12 +211,13 @@ public class ForEachFork extends JBPMSpringActionHandler
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// no transition name
|
// no transition name
|
||||||
int size = ( parent.getChildren()!=null ? parent.getChildren().size()+1 : 1 );
|
int size = (parent.getChildren() != null) ? parent.getChildren().size() + 1 : 1;
|
||||||
tokenName = Integer.toString(size);
|
tokenName = "FOREACHFORK" + Integer.toString(size);
|
||||||
}
|
}
|
||||||
return tokenName + "." + loopIndex;
|
return tokenName + "." + loopIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fork Transition
|
* Fork Transition
|
||||||
*/
|
*/
|
||||||
|
@@ -84,6 +84,7 @@ import org.hibernate.Session;
|
|||||||
import org.hibernate.criterion.Conjunction;
|
import org.hibernate.criterion.Conjunction;
|
||||||
import org.hibernate.criterion.Disjunction;
|
import org.hibernate.criterion.Disjunction;
|
||||||
import org.hibernate.criterion.Order;
|
import org.hibernate.criterion.Order;
|
||||||
|
import org.hibernate.criterion.Projections;
|
||||||
import org.hibernate.criterion.Property;
|
import org.hibernate.criterion.Property;
|
||||||
import org.hibernate.criterion.Restrictions;
|
import org.hibernate.criterion.Restrictions;
|
||||||
import org.hibernate.proxy.HibernateProxy;
|
import org.hibernate.proxy.HibernateProxy;
|
||||||
@@ -1302,7 +1303,6 @@ public class JBPMEngine extends BPMEngine
|
|||||||
*/
|
*/
|
||||||
private Criteria createTaskQueryCriteria(Session session, WorkflowTaskQuery query)
|
private Criteria createTaskQueryCriteria(Session session, WorkflowTaskQuery query)
|
||||||
{
|
{
|
||||||
Criteria process = null;
|
|
||||||
Criteria task = session.createCriteria(TaskInstance.class);
|
Criteria task = session.createCriteria(TaskInstance.class);
|
||||||
|
|
||||||
// task id
|
// task id
|
||||||
@@ -1358,35 +1358,9 @@ public class JBPMEngine extends BPMEngine
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// process active?
|
// process criteria
|
||||||
if (query.isActive() != null)
|
Criteria process = createProcessCriteria(task, query);
|
||||||
{
|
|
||||||
process = (process == null) ? task.createCriteria("processInstance") : process;
|
|
||||||
if (query.isActive())
|
|
||||||
{
|
|
||||||
process.add(Restrictions.isNull("end"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
process.add(Restrictions.isNotNull("end"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// process id
|
|
||||||
if (query.getProcessId() != null)
|
|
||||||
{
|
|
||||||
process = (process == null) ? task.createCriteria("processInstance") : process;
|
|
||||||
process.add(Restrictions.eq("id", getJbpmId(query.getProcessId())));
|
|
||||||
}
|
|
||||||
|
|
||||||
// process name
|
|
||||||
if (query.getProcessName() != null)
|
|
||||||
{
|
|
||||||
process = (process == null) ? task.createCriteria("processInstance") : process;
|
|
||||||
Criteria processDef = process.createCriteria("processDefinition");
|
|
||||||
processDef.add(Restrictions.eq("name", query.getProcessName().toPrefixString(namespaceService)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// process custom properties
|
// process custom properties
|
||||||
if (query.getProcessCustomProps() != null)
|
if (query.getProcessCustomProps() != null)
|
||||||
{
|
{
|
||||||
@@ -1398,7 +1372,7 @@ public class JBPMEngine extends BPMEngine
|
|||||||
{
|
{
|
||||||
// create criteria for process variables
|
// create criteria for process variables
|
||||||
Criteria variables = session.createCriteria(VariableInstance.class);
|
Criteria variables = session.createCriteria(VariableInstance.class);
|
||||||
variables.setProjection(Property.forName("processInstance"));
|
variables.setProjection(Projections.distinct(Property.forName("processInstance")));
|
||||||
Disjunction values = Restrictions.disjunction();
|
Disjunction values = Restrictions.disjunction();
|
||||||
for (Map.Entry<QName, Object> prop : props.entrySet())
|
for (Map.Entry<QName, Object> prop : props.entrySet())
|
||||||
{
|
{
|
||||||
@@ -1409,6 +1383,9 @@ public class JBPMEngine extends BPMEngine
|
|||||||
}
|
}
|
||||||
variables.add(values);
|
variables.add(values);
|
||||||
|
|
||||||
|
// note: constrain process variables to same criteria as tasks
|
||||||
|
createProcessCriteria(variables, query);
|
||||||
|
|
||||||
// retrieve list of processes matching specified variables
|
// retrieve list of processes matching specified variables
|
||||||
List<ProcessInstance> processList = variables.list();
|
List<ProcessInstance> processList = variables.list();
|
||||||
Object[] processIds = null;
|
Object[] processIds = null;
|
||||||
@@ -1491,6 +1468,49 @@ public class JBPMEngine extends BPMEngine
|
|||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create process-specific query criteria
|
||||||
|
*
|
||||||
|
* @param root
|
||||||
|
* @param query
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private Criteria createProcessCriteria(Criteria root, WorkflowTaskQuery query)
|
||||||
|
{
|
||||||
|
Criteria process = null;
|
||||||
|
|
||||||
|
// process active?
|
||||||
|
if (query.isActive() != null)
|
||||||
|
{
|
||||||
|
process = (process == null) ? root.createCriteria("processInstance") : process;
|
||||||
|
if (query.isActive())
|
||||||
|
{
|
||||||
|
process.add(Restrictions.isNull("end"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
process.add(Restrictions.isNotNull("end"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// process id
|
||||||
|
if (query.getProcessId() != null)
|
||||||
|
{
|
||||||
|
process = (process == null) ? root.createCriteria("processInstance") : process;
|
||||||
|
process.add(Restrictions.eq("id", getJbpmId(query.getProcessId())));
|
||||||
|
}
|
||||||
|
|
||||||
|
// process name
|
||||||
|
if (query.getProcessName() != null)
|
||||||
|
{
|
||||||
|
process = (process == null) ? root.createCriteria("processInstance") : process;
|
||||||
|
Criteria processDef = process.createCriteria("processDefinition");
|
||||||
|
processDef.add(Restrictions.eq("name", query.getProcessName().toPrefixString(namespaceService)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return process;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a jBPM Task Instance
|
* Gets a jBPM Task Instance
|
||||||
* @param taskSession jBPM task session
|
* @param taskSession jBPM task session
|
||||||
|
Reference in New Issue
Block a user