Merged 1.4 to HEAD

svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4229 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4230 .
   svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4232 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4233 .
   svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4234 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4235 .
   svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4239 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4240 .
   svn resolved root\projects\web-client\source\java\org\alfresco\web\app\AlfrescoNavigationHandler.java
   svn resolved root\projects\web-client\source\web\WEB-INF\faces-config-beans.xml
   svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4241 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4242 .
   svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4243 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4244 .
   svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4244 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4245 .
   svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4245 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4246 .
   svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4247 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4248 .
   svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4248 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4249 .
   svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4250 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4251 .
   svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4251 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4252 .


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@4633 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2006-12-18 13:18:44 +00:00
parent 08759fbe26
commit 8e0a637886
21 changed files with 636 additions and 72 deletions

View File

@@ -206,6 +206,9 @@
<property name="mimetypeService">
<ref bean="mimetypeService" />
</property>
<property name="transformerRegistry">
<ref bean="contentTransformerRegistry" />
</property>
<property name="applicableTypes">
<list>
<value>{http://www.alfresco.org/model/content/1.0}content</value>

View File

@@ -67,6 +67,7 @@
<Service name="ContentService" mode="none">
<Method name="getWriter" mode="all"/>
<Method name="transform" mode="all"/>
</Service>
<Service name="CopyService" mode="none">

View File

@@ -25,4 +25,17 @@
</property>
</bean>
<bean name="tempFileMarkerInterceptor" class="org.alfresco.repo.model.filefolder.TempFileMarkerInterceptor">
<property name="nodeService">
<ref bean="nodeService" />
</property>
<property name="filterRegularExpressions">
<list>
<value><![CDATA[.*\.tmp]]></value>
<value><![CDATA[.*\.temp]]></value>
<value><![CDATA[\~.*]]></value>
</list>
</property>
</bean>
</beans>

View File

@@ -988,6 +988,7 @@
<idref local="exceptionTranslator"/>
<idref bean="FileFolderService_security"/>
<idref bean="FileFolderService_descriptor"/>
<idref bean="tempFileMarkerInterceptor"/>
</list>
</property>
</bean>

View File

@@ -20,10 +20,13 @@ import java.util.List;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.action.ParameterDefinitionImpl;
import org.alfresco.repo.content.transform.ContentTransformer;
import org.alfresco.repo.content.transform.ContentTransformerRegistry;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
@@ -67,6 +70,7 @@ public class TransformActionExecuter extends ActionExecuterAbstractBase
private ContentService contentService;
private CopyService copyService;
private MimetypeService mimetypeService;
private ContentTransformerRegistry transformerRegistry;
/**
* Set the mime type service
@@ -118,6 +122,16 @@ public class TransformActionExecuter extends ActionExecuterAbstractBase
this.copyService = copyService;
}
/**
* Set the transformer registry
*
* @param transformerRegistry the transformer registry
*/
public void setTransformerRegistry(ContentTransformerRegistry transformerRegistry)
{
this.transformerRegistry = transformerRegistry;
}
/**
* Add parameter definitions
*/
@@ -151,9 +165,22 @@ public class TransformActionExecuter extends ActionExecuterAbstractBase
// it is not content, so can't transform
return;
}
// Get the source mimetype
ContentData contentData = (ContentData)this.nodeService.getProperty(actionedUponNodeRef, ContentModel.PROP_CONTENT);
String sourceMimeType = contentData.getMimetype();
// Get the mime type
String mimeType = (String)ruleAction.getParameterValue(PARAM_MIME_TYPE);
// Check that a transformer is available to the transformation before we go any further
ContentTransformer contentTransformer = this.transformerRegistry.getTransformer(sourceMimeType, mimeType);
if (contentTransformer == null)
{
// Throw an exception since the transformer is not present
throw new NoTransformerException(sourceMimeType, mimeType);
}
// Get the details of the copy destination
NodeRef destinationParent = (NodeRef)ruleAction.getParameterValue(PARAM_DESTINATION_FOLDER);
QName destinationAssocTypeQName = (QName)ruleAction.getParameterValue(PARAM_ASSOC_TYPE_QNAME);

View File

@@ -29,8 +29,10 @@ import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.service.Auditable;
import org.alfresco.service.NotAuditable;
import org.alfresco.service.cmr.audit.AuditInfo;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.SearchParameters;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -143,7 +145,6 @@ public class AuditComponentImpl implements AuditComponent
}
}
if (method.isAnnotationPresent(Auditable.class))
{
@@ -291,6 +292,18 @@ public class AuditComponentImpl implements AuditComponent
{
auditInfo.setKeyStore((StoreRef) returnObject);
}
else if (returnObject instanceof ChildAssociationRef)
{
ChildAssociationRef car = (ChildAssociationRef) returnObject;
auditInfo.setKeyStore(car.getChildRef().getStoreRef());
auditInfo.setKeyGUID(car.getChildRef().getId());
}
else
{
s_logger.warn("Key argument is not a node, store or child assoc ref for return object on "
+ publicServiceIdentifier.getPublicServiceName(mi) + "." + mi.getMethod().getName()
+ " it is " + returnObject.getClass().getName());
}
}
}
@@ -335,33 +348,43 @@ public class AuditComponentImpl implements AuditComponent
switch (auditable.key())
{
case ARG_0:
checkArgLength(mi, methodName, serviceName, 0);
key = mi.getArguments()[0];
break;
case ARG_1:
checkArgLength(mi, methodName, serviceName, 1);
key = mi.getArguments()[1];
break;
case ARG_2:
checkArgLength(mi, methodName, serviceName, 2);
key = mi.getArguments()[2];
break;
case ARG_3:
checkArgLength(mi, methodName, serviceName, 3);
key = mi.getArguments()[3];
break;
case ARG_4:
checkArgLength(mi, methodName, serviceName, 4);
key = mi.getArguments()[4];
break;
case ARG_5:
checkArgLength(mi, methodName, serviceName, 5);
key = mi.getArguments()[5];
break;
case ARG_6:
checkArgLength(mi, methodName, serviceName, 6);
key = mi.getArguments()[6];
break;
case ARG_7:
checkArgLength(mi, methodName, serviceName, 7);
key = mi.getArguments()[7];
break;
case ARG_8:
checkArgLength(mi, methodName, serviceName, 8);
key = mi.getArguments()[8];
break;
case ARG_9:
checkArgLength(mi, methodName, serviceName, 9);
key = mi.getArguments()[9];
break;
case NO_KEY:
@@ -379,6 +402,25 @@ public class AuditComponentImpl implements AuditComponent
{
auditInfo.setKeyStore((StoreRef) key);
}
else if (key instanceof ChildAssociationRef)
{
ChildAssociationRef car = (ChildAssociationRef) key;
auditInfo.setKeyStore(car.getParentRef().getStoreRef());
auditInfo.setKeyGUID(car.getParentRef().getId());
}
else if (key instanceof SearchParameters)
{
SearchParameters sp = (SearchParameters) key;
if (sp.getStores().size() > 0)
{
auditInfo.setKeyStore(sp.getStores().get(0));
}
}
else
{
s_logger.warn("Key argument is not a node, store or child assoc reference or search parameters on "
+ serviceName + "." + methodName + " it is " + key.getClass().getName());
}
}
auditInfo.setKeyPropertiesAfter(null);
auditInfo.setKeyPropertiesBefore(null);
@@ -422,6 +464,15 @@ public class AuditComponentImpl implements AuditComponent
return effectiveAuditMode;
}
private void checkArgLength(MethodInvocation mi, String methodName, String serviceName, int position)
{
if (mi.getArguments().length <= position)
{
s_logger.warn("Auditable annotation on "
+ serviceName + "." + methodName + " references non existant argument");
}
}
/**
* A simple audit entry Currently we ignore filtering here.
*/

View File

@@ -272,6 +272,28 @@
assoc.id
</query>
<query name="node.GetChildAssocRefsByQName">
select
assoc.typeQName,
assoc.qname,
assoc.isPrimary,
assoc.index,
child.id,
child.store.key.protocol,
child.store.key.identifier,
child.uuid as parentUuid
from
org.alfresco.repo.domain.hibernate.ChildAssocImpl as assoc
join assoc.parent as parent
join assoc.child as child
where
assoc.parent.id = :parentId and
assoc.qname = :childAssocQName
order by
assoc.index,
assoc.id
</query>
<query name="node.GetNodeAssoc">
select
assoc

View File

@@ -0,0 +1,117 @@
/*
* Copyright (C) 2005-2006 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.repo.model.filefolder;
import java.util.Collections;
import java.util.List;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* An interceptor for the {@link org.alfresco.service.cmr.model.FileFolderService FileFolderService}
* that marks files or folders with the <b>sys:temporary</b> aspect depending on the
* name pattern {@link #setFilterRegularExpressions(List) provided}.
*
* @author Derek Hulley
*/
public class TempFileMarkerInterceptor implements MethodInterceptor
{
private static Log logger = LogFactory.getLog(TempFileMarkerInterceptor.class);
private NodeService nodeService;
private List<String> filterRegularExpressions;
public TempFileMarkerInterceptor()
{
filterRegularExpressions = Collections.emptyList();
}
/**
* @param nodeService the service to use to apply the <b>sys:temporary</b> aspect
*/
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
/**
* A list of regular expressions that represent patterns of temporary files.
*
* @param regexps list of regular expressions
*
* @see String#matches(java.lang.String)
*/
public void setFilterRegularExpressions(List<String> regexps)
{
this.filterRegularExpressions = regexps;
}
/**
* Handles <b>rename</b>, <b>move</b>, <b>copy</b>
*/
public Object invoke(MethodInvocation invocation) throws Throwable
{
Object ret = invocation.proceed();
// execute and get the result
String methodName = invocation.getMethod().getName();
if (methodName.startsWith("create") ||
methodName.startsWith("rename") ||
methodName.startsWith("move") ||
methodName.startsWith("copy"))
{
FileInfo fileInfo = (FileInfo) ret;
String filename = fileInfo.getName();
if (logger.isDebugEnabled())
{
logger.debug("Checking filename returned by " + methodName + ": " + filename);
}
// check against all the regular expressions
for (String regexp : filterRegularExpressions)
{
if (!filename.matches(regexp))
{
// it is not a match - try next one
continue;
}
else
{
// it matched, so apply the aspect
NodeRef nodeRef = fileInfo.getNodeRef();
nodeService.addAspect(nodeRef, ContentModel.ASPECT_TEMPORARY, null);
// no further checking required
if (logger.isDebugEnabled())
{
logger.debug("Applied temporary marker: " + fileInfo);
}
break;
}
}
}
// done
return ret;
}
}

View File

@@ -65,6 +65,7 @@ import org.alfresco.service.cmr.repository.NodeRef.Status;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.QNamePattern;
import org.alfresco.service.namespace.RegexQNamePattern;
import org.alfresco.util.ParameterCheck;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -1041,8 +1042,39 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
public List<ChildAssociationRef> getChildAssocs(NodeRef nodeRef, QNamePattern typeQNamePattern, QNamePattern qnamePattern)
{
Node node = getNodeNotNull(nodeRef);
// get the assocs pointing from it
Collection<ChildAssociationRef> childAssocRefs = nodeDaoService.getChildAssocRefs(node);
Collection<ChildAssociationRef> childAssocRefs = null;
// if the type is the wildcard type, and the qname is not a search, then use a shortcut query
if (typeQNamePattern.equals(RegexQNamePattern.MATCH_ALL) && qnamePattern instanceof QName)
{
// get all child associations with the specific qualified name
childAssocRefs = nodeDaoService.getChildAssocRefs(node, (QName)qnamePattern);
}
else
{
// get all child associations
childAssocRefs = nodeDaoService.getChildAssocRefs(node);
// remove non-matching assocs
Iterator<ChildAssociationRef> iterator = childAssocRefs.iterator();
while (iterator.hasNext())
{
ChildAssociationRef childAssocRef = iterator.next();
// does the qname match the pattern?
if (!qnamePattern.isMatch(childAssocRef.getQName()) || !typeQNamePattern.isMatch(childAssocRef.getTypeQName()))
{
// no match - remove
iterator.remove();
}
}
}
// sort the results
List<ChildAssociationRef> orderedList = reorderChildAssocs(childAssocRefs);
// done
return orderedList;
}
private List<ChildAssociationRef> reorderChildAssocs(Collection<ChildAssociationRef> childAssocRefs)
{
// shortcut if there are no assocs
if (childAssocRefs.size() == 0)
{
@@ -1058,18 +1090,9 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
while(iterator.hasNext())
{
ChildAssociationRef childAssocRef = iterator.next();
// does the qname match the pattern?
if (!qnamePattern.isMatch(childAssocRef.getQName()) || !typeQNamePattern.isMatch(childAssocRef.getTypeQName()))
{
// no match - remove
iterator.remove();
}
else
{
childAssocRef.setNthSibling(nthSibling);
nthSibling++;
}
}
// done
return orderedList;
}

View File

@@ -159,6 +159,14 @@ public interface NodeDaoService
*/
public Collection<ChildAssociationRef> getChildAssocRefs(Node parentNode);
/**
* Get a collection of all child association references for a given parent node.
*
* @param parentNode the parent node
* @return Returns a collection of association references
*/
public Collection<ChildAssociationRef> getChildAssocRefs(Node parentNode, QName assocQName);
/**
* @return Returns a matching association or null if one was not found
*

View File

@@ -85,6 +85,7 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
private static final String QUERY_GET_CHILD_ASSOCS = "node.GetChildAssocs";
private static final String QUERY_GET_CHILD_ASSOC_BY_TYPE_AND_NAME = "node.GetChildAssocByTypeAndName";
private static final String QUERY_GET_CHILD_ASSOC_REFS = "node.GetChildAssocRefs";
private static final String QUERY_GET_CHILD_ASSOC_REFS_BY_QNAME = "node.GetChildAssocRefsByQName";
private static final String QUERY_GET_NODE_ASSOC = "node.GetNodeAssoc";
private static final String QUERY_GET_NODE_ASSOCS_TO_AND_FROM = "node.GetNodeAssocsToAndFrom";
private static final String QUERY_GET_TARGET_ASSOCS = "node.GetTargetAssocs";
@@ -100,6 +101,9 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
private static TransactionAwareSingleton<Long> serverIdSingleton = new TransactionAwareSingleton<Long>();
private final String ipAddress;
/** used for debugging */
private Set<String> changeTxnIdSet;
/**
*
*/
@@ -114,6 +118,8 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
{
throw new AlfrescoRuntimeException("Failed to get server IP address", e);
}
changeTxnIdSet = new HashSet<String>(0);
}
/**
@@ -206,17 +212,32 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
Serializable txnId = (Serializable) AlfrescoTransactionSupport.getResource(RESOURCE_KEY_TRANSACTION_ID);
if (txnId == null)
{
String changeTxnId = AlfrescoTransactionSupport.getTransactionId();
// no transaction instance has been bound to the transaction
transaction = new TransactionImpl();
transaction.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
transaction.setChangeTxnId(changeTxnId);
transaction.setServer(getServer());
txnId = getHibernateTemplate().save(transaction);
// bind the id
AlfrescoTransactionSupport.bindResource(RESOURCE_KEY_TRANSACTION_ID, txnId);
if (logger.isDebugEnabled())
{
if (!changeTxnIdSet.add(changeTxnId))
{
// the txn id was already used!
logger.error("Change transaction ID already used: " + transaction);
}
logger.debug("Created new transaction: " + transaction);
}
}
else
{
transaction = (Transaction) getHibernateTemplate().get(TransactionImpl.class, txnId);
if (logger.isDebugEnabled())
{
logger.debug("Using existing transaction: " + transaction);
}
}
return transaction;
}
@@ -355,7 +376,9 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
}
else
{
status.getTransaction().setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
// make sure that the status has the latest transaction attached
Transaction currentTxn = getCurrentTransaction();
status.setTransaction(currentTxn);
}
}
@@ -655,6 +678,38 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
}
};
List<Object[]> queryResults = (List<Object[]>) getHibernateTemplate().execute(callback);
Collection<ChildAssociationRef> refs = convertToChildAssocRefs(parentNode, queryResults);
// done
return refs;
}
@SuppressWarnings("unchecked")
public Collection<ChildAssociationRef> getChildAssocRefs(final Node parentNode, final QName assocQName)
{
HibernateCallback callback = new HibernateCallback()
{
public Object doInHibernate(Session session)
{
Query query = session
.getNamedQuery(HibernateNodeDaoServiceImpl.QUERY_GET_CHILD_ASSOC_REFS_BY_QNAME)
.setLong("parentId", parentNode.getId())
.setParameter("childAssocQName", assocQName);
return query.list();
}
};
List<Object[]> queryResults = (List<Object[]>) getHibernateTemplate().execute(callback);
Collection<ChildAssociationRef> refs = convertToChildAssocRefs(parentNode, queryResults);
// done
return refs;
}
/**
* <pre>
* assocTypeQName, assocQName, assocIsPrimary, assocIndex, ?, childProtocol, childIdentifier, childUuid
* </pre>
*/
private Collection<ChildAssociationRef> convertToChildAssocRefs(Node parentNode, List<Object[]> queryResults)
{
Collection<ChildAssociationRef> refs = new ArrayList<ChildAssociationRef>(queryResults.size());
NodeRef parentNodeRef = parentNode.getNodeRef();
for (Object[] row : queryResults)

View File

@@ -1325,14 +1325,11 @@ public class LuceneIndexerImpl2 extends LuceneBase2 implements LuceneIndexer2
counter.increment();
}
// TODO: DC: Should this also include aspect child definitions?
QName nodeTypeRef = nodeService.getType(nodeRef);
TypeDefinition nodeTypeDef = getDictionaryService().getType(nodeTypeRef);
// check for child associations
if (includeDirectoryDocuments)
{
if (nodeTypeDef != null && nodeTypeDef.getChildAssociations().size() > 0)
if (mayHaveChildren(nodeRef))
{
if (directPaths.contains(pair.getFirst()))
{
@@ -1429,6 +1426,34 @@ public class LuceneIndexerImpl2 extends LuceneBase2 implements LuceneIndexer2
return docs;
}
/**
* Does the node type or any applied aspect allow this node to have child associations?
*
* @param nodeRef
* @return
*/
private boolean mayHaveChildren(NodeRef nodeRef)
{
// 1) Does the type support children?
QName nodeTypeRef = nodeService.getType(nodeRef);
TypeDefinition nodeTypeDef = getDictionaryService().getType(nodeTypeRef);
if ((nodeTypeDef != null) && (nodeTypeDef.getChildAssociations().size() > 0))
{
return true;
}
// 2) Do any of the applied aspects support children?
Set<QName> aspects = nodeService.getAspects(nodeRef);
for (QName aspect : aspects)
{
AspectDefinition aspectDef = getDictionaryService().getAspect(aspect);
if ((aspectDef != null) && (aspectDef.getChildAssociations().size() > 0))
{
return true;
}
}
return false;
}
private ArrayList<NodeRef> getParents(Path path)
{
ArrayList<NodeRef> parentsInDepthOrderStartingWithSelf = new ArrayList<NodeRef>(8);

View File

@@ -108,6 +108,8 @@ public class LuceneTest2 extends TestCase
QName orderInt = QName.createQName(TEST_NAMESPACE, "orderInt");
QName aspectWithChildren = QName.createQName(TEST_NAMESPACE, "aspectWithChildren");
TransactionService transactionService;
NodeService nodeService;
@@ -391,6 +393,38 @@ public class LuceneTest2 extends TestCase
super(arg0);
}
public void testAuxDataIsPresent() throws Exception
{
luceneFTS.pause();
testTX.commit();
testTX = transactionService.getUserTransaction();
testTX.begin();
runBaseTests();
LuceneSearcherImpl2 searcher = LuceneSearcherImpl2.getSearcher(rootNodeRef.getStoreRef(), indexerAndSearcher);
searcher.setNodeService(nodeService);
searcher.setDictionaryService(dictionaryService);
searcher.setNamespacePrefixResolver(getNamespacePrefixReolsver("namespace"));
ResultSet results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "ID:\"" + n14 + "\"", null, null);
assertEquals(1, results.length()); // one node
results.close();
nodeService.addAspect(n14, aspectWithChildren, null);
testTX.commit();
testTX = transactionService.getUserTransaction();
testTX.begin();
searcher = LuceneSearcherImpl2.getSearcher(rootNodeRef.getStoreRef(), indexerAndSearcher);
searcher.setNodeService(nodeService);
searcher.setDictionaryService(dictionaryService);
searcher.setNamespacePrefixResolver(getNamespacePrefixReolsver("namespace"));
results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "ID:\"" + n14 + "\"", null, null);
assertEquals(10, results.length()); // one node + 9 aux paths to n14
results.close();
}
public void testFirst() throws Exception
{
testReadAgainstDelta();

View File

@@ -267,6 +267,22 @@
</types>
<aspects>
<aspect name="test:aspectWithChildren">
<title>Aspect With Children</title>
<associations>
<child-association name="test:unused">
<source>
<mandatory>false</mandatory>
<many>true</many>
</source>
<target>
<class>sys:base</class>
<mandatory>false</mandatory>
<many>true</many>
</target>
</child-association>
</associations>
</aspect>
<aspect name="test:testSuperAspect">
<title>Test Super Aspect</title>
</aspect>

View File

@@ -389,10 +389,13 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
return AccessStatus.ALLOWED;
}
// Get the current authentications
// Use the smart authentication cache to improve permissions performance
Authentication auth = authenticationComponent.getCurrentAuthentication();
Set<String> authorisations = getAuthorisations(auth, nodeRef);
Serializable key = generateKey(
authorisations,
nodeRef,
@@ -415,6 +418,11 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
return AccessStatus.DENIED;
}
if (authenticationComponent.getCurrentUserName().equals(authenticationComponent.getSystemUserName()))
{
return AccessStatus.ALLOWED;
}
//
// TODO: Dynamic permissions via evaluators
//

View File

@@ -23,6 +23,7 @@ import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.GrantedAuthority;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.permissions.PermissionEntry;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AccessPermission;
@@ -84,6 +85,46 @@ public class PermissionServiceTest extends AbstractPermissionTest
"andy", AccessStatus.ALLOWED);
}
public void testSystemUserPermissions()
{
AuthenticationUtil.setSystemUserAsCurrentUser();
try
{
assertFalse(serviceRegistry.getPermissionService().hasPermission(rootNodeRef, PermissionService.CONSUMER) == AccessStatus.ALLOWED);
assertTrue(serviceRegistry.getPermissionService().hasPermission(rootNodeRef, PermissionService.DELETE) == AccessStatus.ALLOWED);
assertTrue(serviceRegistry.getPermissionService().hasPermission(rootNodeRef, PermissionService.READ) == AccessStatus.ALLOWED);
assertTrue(serviceRegistry.getPermissionService().hasPermission(rootNodeRef, PermissionService.ADD_CHILDREN) == AccessStatus.ALLOWED);
assertFalse(serviceRegistry.getPermissionService().hasPermission(rootNodeRef, PermissionService.CANCEL_CHECK_OUT) == AccessStatus.ALLOWED);
assertTrue(serviceRegistry.getPermissionService().hasPermission(rootNodeRef, PermissionService.CHECK_OUT) == AccessStatus.ALLOWED);
assertFalse(serviceRegistry.getPermissionService().hasPermission(rootNodeRef, PermissionService.COORDINATOR) == AccessStatus.ALLOWED);
}
finally
{
AuthenticationUtil.clearCurrentSecurityContext();
}
}
public void testAdminUserPermissions()
{
runAs("admin");
try
{
assertFalse(serviceRegistry.getPermissionService().hasPermission(rootNodeRef, PermissionService.CONSUMER) == AccessStatus.ALLOWED);
assertTrue(serviceRegistry.getPermissionService().hasPermission(rootNodeRef, PermissionService.DELETE) == AccessStatus.ALLOWED);
assertTrue(serviceRegistry.getPermissionService().hasPermission(rootNodeRef, PermissionService.READ) == AccessStatus.ALLOWED);
assertTrue(serviceRegistry.getPermissionService().hasPermission(rootNodeRef, PermissionService.ADD_CHILDREN) == AccessStatus.ALLOWED);
assertFalse(serviceRegistry.getPermissionService().hasPermission(rootNodeRef, PermissionService.CANCEL_CHECK_OUT) == AccessStatus.ALLOWED);
assertTrue(serviceRegistry.getPermissionService().hasPermission(rootNodeRef, PermissionService.CHECK_OUT) == AccessStatus.ALLOWED);
assertFalse(serviceRegistry.getPermissionService().hasPermission(rootNodeRef, PermissionService.COORDINATOR) == AccessStatus.ALLOWED);
}
finally
{
AuthenticationUtil.clearCurrentSecurityContext();
}
}
public void testWeSetConsumerOnRootIsNotSupportedByHasPermisssionAsItIsTheWrongType()
{
runAs("andy");

View File

@@ -203,6 +203,8 @@ public class ACLEntryVoter implements AccessDecisionVoter, InitializingBean
Method method = invocation.getMethod();
Class[] params = method.getParameterTypes();
Boolean hasMethodEntry = null;
for (ConfigAttributeDefintion cad : supportedDefinitions)
{
NodeRef testNodeRef = null;
@@ -213,14 +215,18 @@ public class ACLEntryVoter implements AccessDecisionVoter, InitializingBean
}
else if (cad.typeString.equals(ACL_METHOD))
{
if(hasMethodEntry == null)
{
hasMethodEntry = Boolean.FALSE;
}
if (authenticationService.getCurrentUserName().equals(cad.authority))
{
return AccessDecisionVoter.ACCESS_GRANTED;
hasMethodEntry = Boolean.TRUE;
}
else
else if(authorityService.getAuthorities().contains(cad.authority))
{
return authorityService.getAuthorities().contains(cad.authority) ? AccessDecisionVoter.ACCESS_GRANTED
: AccessDecisionVoter.ACCESS_DENIED;
hasMethodEntry = Boolean.TRUE;
}
}
else if (cad.parameter >= invocation.getArguments().length)
@@ -353,8 +359,15 @@ public class ACLEntryVoter implements AccessDecisionVoter, InitializingBean
}
}
if((hasMethodEntry == null) || (hasMethodEntry.booleanValue()))
{
return AccessDecisionVoter.ACCESS_GRANTED;
}
else
{
return AccessDecisionVoter.ACCESS_DENIED;
}
}
private List<ConfigAttributeDefintion> extractSupportedDefinitions(ConfigAttributeDefinition config)
{

View File

@@ -89,7 +89,6 @@ public class ACLEntryVoterTest extends AbstractPermissionTest
}
public void testBasicDenyStore() throws Exception
{
runAs("andy");
@@ -276,7 +275,8 @@ public class ACLEntryVoterTest extends AbstractPermissionTest
{
runAs("andy");
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ),
"andy", AccessStatus.ALLOWED));
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("testOneNodeRef", new Class[] { NodeRef.class });
@@ -293,12 +293,12 @@ public class ACLEntryVoterTest extends AbstractPermissionTest
method.invoke(proxy, new Object[] { rootNodeRef });
}
public void testBasicAllow() throws Exception
{
runAs("andy");
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ),
"andy", AccessStatus.ALLOWED));
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("testOneNodeRef", new Class[] { NodeRef.class });
@@ -319,7 +319,8 @@ public class ACLEntryVoterTest extends AbstractPermissionTest
{
runAs("andy");
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ),
"andy", AccessStatus.ALLOWED));
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("testOneStoreRef", new Class[] { StoreRef.class });
@@ -340,7 +341,8 @@ public class ACLEntryVoterTest extends AbstractPermissionTest
{
runAs("andy");
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ),
"andy", AccessStatus.ALLOWED));
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("testOneChildAssociationRef", new Class[] { ChildAssociationRef.class });
@@ -361,7 +363,8 @@ public class ACLEntryVoterTest extends AbstractPermissionTest
{
runAs("andy");
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ),
"andy", AccessStatus.ALLOWED));
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("testOneChildAssociationRef", new Class[] { ChildAssociationRef.class });
@@ -382,7 +385,8 @@ public class ACLEntryVoterTest extends AbstractPermissionTest
{
runAs("andy");
permissionService.setPermission(new SimplePermissionEntry(systemNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
permissionService.setPermission(new SimplePermissionEntry(systemNodeRef, getPermission(PermissionService.READ),
"andy", AccessStatus.ALLOWED));
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("testOneChildAssociationRef", new Class[] { ChildAssociationRef.class });
@@ -411,9 +415,10 @@ public class ACLEntryVoterTest extends AbstractPermissionTest
{
runAs("andy");
permissionService.setPermission(new SimplePermissionEntry(systemNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ_CHILDREN), "andy",
AccessStatus.ALLOWED));
permissionService.setPermission(new SimplePermissionEntry(systemNodeRef, getPermission(PermissionService.READ),
"andy", AccessStatus.ALLOWED));
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef,
getPermission(PermissionService.READ_CHILDREN), "andy", AccessStatus.ALLOWED));
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("testOneChildAssociationRef", new Class[] { ChildAssociationRef.class });
@@ -458,7 +463,8 @@ public class ACLEntryVoterTest extends AbstractPermissionTest
}
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ),
"andy", AccessStatus.ALLOWED));
method.invoke(proxy, new Object[] { rootNodeRef, null, null, null });
}
@@ -489,7 +495,8 @@ public class ACLEntryVoterTest extends AbstractPermissionTest
}
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ),
"andy", AccessStatus.ALLOWED));
method.invoke(proxy, new Object[] { null, rootNodeRef, null, null });
}
@@ -520,7 +527,8 @@ public class ACLEntryVoterTest extends AbstractPermissionTest
}
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ),
"andy", AccessStatus.ALLOWED));
method.invoke(proxy, new Object[] { null, null, rootNodeRef, null });
}
@@ -551,7 +559,8 @@ public class ACLEntryVoterTest extends AbstractPermissionTest
}
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ),
"andy", AccessStatus.ALLOWED));
method.invoke(proxy, new Object[] { null, null, null, rootNodeRef });
}
@@ -584,7 +593,8 @@ public class ACLEntryVoterTest extends AbstractPermissionTest
}
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ),
"andy", AccessStatus.ALLOWED));
method.invoke(proxy, new Object[] { nodeService.getPrimaryParent(rootNodeRef), null, null, null });
}
@@ -617,7 +627,8 @@ public class ACLEntryVoterTest extends AbstractPermissionTest
}
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ),
"andy", AccessStatus.ALLOWED));
method.invoke(proxy, new Object[] { null, nodeService.getPrimaryParent(rootNodeRef), null, null });
}
@@ -650,7 +661,8 @@ public class ACLEntryVoterTest extends AbstractPermissionTest
}
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ),
"andy", AccessStatus.ALLOWED));
method.invoke(proxy, new Object[] { null, null, nodeService.getPrimaryParent(rootNodeRef), null });
}
@@ -683,7 +695,8 @@ public class ACLEntryVoterTest extends AbstractPermissionTest
}
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ), "andy", AccessStatus.ALLOWED));
permissionService.setPermission(new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ),
"andy", AccessStatus.ALLOWED));
method.invoke(proxy, new Object[] { null, null, null, nodeService.getPrimaryParent(rootNodeRef) });
}
@@ -692,18 +705,16 @@ public class ACLEntryVoterTest extends AbstractPermissionTest
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod(
"testMethod",
new Class[] { });
Method method = o.getClass().getMethod("testMethod", new Class[] {});
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_METHOD.andy")));
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_METHOD.andy", "ACL_METHOD.BANANA")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
method.invoke(proxy, new Object[] { });
method.invoke(proxy, new Object[] {});
}
public void testMethodACL2() throws Exception
@@ -711,20 +722,61 @@ public class ACLEntryVoterTest extends AbstractPermissionTest
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod(
"testMethod",
new Class[] { });
Method method = o.getClass().getMethod("testMethod", new Class[] {});
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_METHOD."+PermissionService.ALL_AUTHORITIES)));
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_METHOD.BANANA", "ACL_METHOD."
+ PermissionService.ALL_AUTHORITIES)));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
method.invoke(proxy, new Object[] { });
method.invoke(proxy, new Object[] {});
}
public void testMethodACL3() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("testMethod", new Class[] {});
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_METHOD.andy", "ACL_METHOD."
+ PermissionService.ALL_AUTHORITIES)));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
method.invoke(proxy, new Object[] {});
}
public void testMethodACL4() throws Exception
{
runAs("andy");
Object o = new ClassWithMethods();
Method method = o.getClass().getMethod("testMethod", new Class[] {});
AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisorAdapterRegistry.wrap(new Interceptor("ACL_METHOD.woof", "ACL_METHOD.BOO")));
proxyFactory.setTargetSource(new SingletonTargetSource(o));
Object proxy = proxyFactory.getProxy();
try
{
method.invoke(proxy, new Object[] {});
}
catch (InvocationTargetException e)
{
}
}
public static class ClassWithMethods
{
@@ -764,6 +816,38 @@ public class ACLEntryVoterTest extends AbstractPermissionTest
{
ConfigAttributeDefinition cad = new ConfigAttributeDefinition();
Interceptor(final String config1, final String config2)
{
cad.addConfigAttribute(new ConfigAttribute()
{
/**
* Comment for <code>serialVersionUID</code>
*/
private static final long serialVersionUID = 1L;
public String getAttribute()
{
return config1;
}
});
cad.addConfigAttribute(new ConfigAttribute()
{
/**
* Comment for <code>serialVersionUID</code>
*/
private static final long serialVersionUID = 1L;
public String getAttribute()
{
return config2;
}
});
}
Interceptor(final String config)
{
cad.addConfigAttribute(new ConfigAttribute()

View File

@@ -400,7 +400,10 @@ public interface NodeService
/**
* Gets all child associations where the pattern of the association qualified
* name is a match.
* name is a match. Using a {@link org.alfresco.service.namespace.RegexQNamePattern#MATCH_ALL wildcard}
* for the type and a specific {@link QName qualified name} for the association is
* akin to using the XPath browse expression <b>./{url}localname</b> in the context of the
* parent node.
*
* @param nodeRef the parent node - usually a <b>container</b>
* @param typeQNamePattern the pattern that the type qualified name of the association must match

View File

@@ -215,7 +215,7 @@ public interface RuleService
* @param rule the rule
* @return the owning node reference
*/
@Auditable(key = Auditable.Key.ARG_0, parameters = {"rule"})
@Auditable(key = Auditable.Key.RETURN, parameters = {"rule"})
public NodeRef getOwningNodeRef(Rule rule);
/**
@@ -227,6 +227,6 @@ public interface RuleService
* @param action the action
* @return the owning node reference
*/
@Auditable(key = Auditable.Key.ARG_0, parameters = {"action"})
@Auditable(key = Auditable.Key.RETURN, parameters = {"action"})
public NodeRef getOwningNodeRef(Action action);
}

View File

@@ -42,6 +42,25 @@ public class RegexQNamePattern implements QNamePattern
{
return true;
}
@Override
public boolean equals(Object obj)
{
// this is equal if the object's class is the same as this instances
if (obj == null)
{
return false;
}
else if (obj.getClass().equals(this.getClass()))
{
return true;
}
else
{
return false;
}
}
};
private String namespaceUriPattern;