Morning merge.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@2851 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Britt Park
2006-05-11 17:01:57 +00:00
parent 6418bb6d23
commit a22ddfb666
74 changed files with 905 additions and 1190 deletions

View File

@@ -1,83 +0,0 @@
/*
* Copyright (C) 2005 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.jcr.example;
import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.Repository;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import org.alfresco.jcr.api.JCRNodeRef;
import org.alfresco.model.ContentModel;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Example that demonstrate use of JCR and Alfresco API calls.
*
* @author David Caruana
*/
public class MixedExample
{
public static void main(String[] args)
throws Exception
{
// Setup Spring and Transaction Service
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:alfresco/application-context.xml");
ServiceRegistry registry = (ServiceRegistry)context.getBean(ServiceRegistry.SERVICE_REGISTRY);
NodeService nodeService = (NodeService)registry.getNodeService();
// Retrieve Repository
Repository repository = (Repository)context.getBean("JCR.Repository");
// Login to workspace
// Note: Default workspace is the one used by Alfresco Web Client which contains all the Spaces
// and their documents
Session session = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
try
{
// Retrieve Company Home
Node root = session.getRootNode();
Node companyHome = root.getNode("app:company_home");
// Read Company Home Name
Property name = companyHome.getProperty("cm:name");
System.out.println("Name = " + name.getString());
// Update Node via Alfresco Node Service API
NodeRef companyHomeRef = JCRNodeRef.getNodeRef(companyHome);
nodeService.setProperty(companyHomeRef, ContentModel.PROP_NAME, "Updated Company Home Name");
// Re-read via JCR
System.out.println("Updated name = " + name.getString());
}
finally
{
session.logout();
System.exit(0);
}
}
}

View File

@@ -1,87 +0,0 @@
/*
* Copyright (C) 2005 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.jcr.example;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.Property;
import javax.jcr.PropertyIterator;
import javax.jcr.Repository;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Simple Example that demonstrate login and retrieval of top-level Spaces
* under Company Home.
*
* @author David Caruana
*/
public class SimpleExample
{
public static void main(String[] args)
throws Exception
{
// Setup Spring and Transaction Service
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:alfresco/application-context.xml");
// Retrieve Repository
Repository repository = (Repository)context.getBean("JCR.Repository");
// Login to workspace
// Note: Default workspace is the one used by Alfresco Web Client which contains all the Spaces
// and their documents
Session session = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
try
{
// Retrieve Company Home
Node root = session.getRootNode();
Node companyHome = root.getNode("app:company_home");
// Iterator through children of Company Home
NodeIterator iterator = companyHome.getNodes();
while(iterator.hasNext())
{
Node child = iterator.nextNode();
System.out.println(child.getName());
PropertyIterator propIterator = child.getProperties();
while(propIterator.hasNext())
{
Property prop = propIterator.nextProperty();
if (!prop.getDefinition().isMultiple())
{
System.out.println(" " + prop.getName() + " = " + prop.getString());
}
}
}
}
finally
{
session.logout();
System.exit(0);
}
}
}

View File

@@ -1,400 +0,0 @@
/*
* Copyright (C) 2005 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.jcr.example;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Calendar;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.PathNotFoundException;
import javax.jcr.Property;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import javax.jcr.Value;
import javax.jcr.Workspace;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import javax.jcr.version.Version;
import javax.jcr.version.VersionHistory;
import javax.jcr.version.VersionIterator;
import org.alfresco.jcr.api.JCRNodeRef;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.PermissionService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
/**
* Example that demonstrates read and write of a simple WIKI model
*
* Please refer to http://www.alfresco.org/mediawiki/index.php/Introducing_the_Alfresco_Java_Content_Repository_API
* for a complete description of this example.
*
* @author David Caruana
*/
public class WIKIExample
{
public static void main(String[] args)
throws Exception
{
//
// Repository Initialisation
//
// access the Alfresco JCR Repository (here it's via programmatic approach, but it could also be injected)
System.out.println("Initialising Repository...");
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:org/alfresco/jcr/example/wiki-context.xml");
Repository repository = (Repository)context.getBean("JCR.Repository");
// display information about the repository
System.out.println("Repository Description...");
String[] keys = repository.getDescriptorKeys();
for (String key : keys)
{
String value = repository.getDescriptor(key);
System.out.println(" " + key + " = " + value);
}
//
// Create a WIKI structure
//
// Note: Here we're using the Alfresco Content Model and custom WIKI model to create
// WIKI pages and Content that are accessible via the Alfresco Web Client
//
// login to workspace (here we rely on the default workspace defined by JCR.Repository bean)
Session session = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
try
{
System.out.println("Creating WIKI...");
// first, access the company home
Node rootNode = session.getRootNode();
System.out.println("Root node: path=" + rootNode.getPath() + ", type=" + rootNode.getPrimaryNodeType().getName());
Node companyHome = rootNode.getNode("app:company_home");
System.out.println("Company home node: path=" + companyHome.getPath() + ", type=" + companyHome.getPrimaryNodeType().getName());
// remove the WIKI structure if it already exists
try
{
Node encyclopedia = companyHome.getNode("wiki:encyclopedia");
encyclopedia.remove();
System.out.println("Existing WIKI found and removed");
}
catch(PathNotFoundException e)
{
// doesn't exist, no need to remove
}
// create the root WIKI folder
Node encyclopedia = companyHome.addNode("wiki:encyclopedia", "cm:folder");
encyclopedia.setProperty("cm:name", "WIKI Encyclopedia");
encyclopedia.setProperty("cm:description", "");
// create first wiki page
Node page1 = encyclopedia.addNode("wiki:entry1", "wiki:page");
page1.setProperty("cm:name", "Rose");
page1.setProperty("cm:description", "");
page1.setProperty("cm:title", "The rose");
page1.setProperty("cm:content", "A rose is a flowering shrub.");
page1.setProperty("wiki:category", new String[] {"flower", "plant", "rose"});
// create second wiki page
Node page2 = encyclopedia.addNode("wiki:entry2", "wiki:page");
page2.setProperty("cm:name", "Shakespeare");
page2.setProperty("cm:description", "");
page2.setProperty("cm:title", "William Shakespeare");
page2.setProperty("cm:content", "A famous poet who likes roses.");
page2.setProperty("wiki:restrict", true);
page2.setProperty("wiki:category", new String[] {"poet"});
// create an image (note: we're using an input stream to allow setting of binary content)
Node contentNode = encyclopedia.addNode("wiki:image", "cm:content");
contentNode.setProperty("cm:name", "Dog");
contentNode.setProperty("cm:description", "");
contentNode.setProperty("cm:title", "My dog at New Year party");
ClassPathResource resource = new ClassPathResource("org/alfresco/jcr/example/wikiImage.gif");
contentNode.setProperty("cm:content", resource.getInputStream());
session.save();
System.out.println("WIKI created");
}
finally
{
session.logout();
}
//
// Access the WIKI structure
//
// login to workspace (here we rely on the default workspace defined by JCR.Repository bean)
session = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
try
{
System.out.println("Accessing WIKI...");
// access a wiki node directly from root node (by path and by UUID)
Node rootNode = session.getRootNode();
Node encyclopedia = rootNode.getNode("app:company_home/wiki:encyclopedia");
Node direct = session.getNodeByUUID(encyclopedia.getUUID());
System.out.println("Found WIKI root correctly: " + encyclopedia.equals(direct));
// access a wiki property directly from root node
Node entry1 = rootNode.getNode("app:company_home/wiki:encyclopedia/wiki:entry1");
String title = entry1.getProperty("cm:title").getString();
System.out.println("Found WIKI page 1 title: " + title);
Calendar modified = entry1.getProperty("cm:modified").getDate();
System.out.println("Found WIKI page 1 last modified date: " + modified.getTime());
// browse all wiki entries
System.out.println("WIKI browser:");
NodeIterator entries = encyclopedia.getNodes();
while (entries.hasNext())
{
Node entry = entries.nextNode();
outputContentNode(entry);
}
// perform a search
System.out.println("Search results:");
Workspace workspace = session.getWorkspace();
QueryManager queryManager = workspace.getQueryManager();
Query query = queryManager.createQuery("//app:company_home/wiki:encyclopedia/*[@cm:title = 'The rose']", Query.XPATH);
//Query query = queryManager.createQuery("//app:company_home/wiki:encyclopedia/*[jcr:contains(., 'rose')]", Query.XPATH);
QueryResult result = query.execute();
NodeIterator it = result.getNodes();
while (it.hasNext())
{
Node n = it.nextNode();
outputContentNode(n);
}
// export content (system view format)
File systemView = new File("systemview.xml");
FileOutputStream systemViewOut = new FileOutputStream(systemView);
session.exportSystemView("/app:company_home/wiki:encyclopedia", systemViewOut, false, false);
// export content (document view format)
File docView = new File("docview.xml");
FileOutputStream docViewOut = new FileOutputStream(docView);
session.exportDocumentView("/app:company_home/wiki:encyclopedia", docViewOut, false, false);
System.out.println("WIKI exported");
}
finally
{
session.logout();
}
//
// Advanced Usage
//
// 1) Check-out / Check-in and version history retrieval
session = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
try
{
//
// Version WIKI Page 1
//
// first, access the page
Node rootNode = session.getRootNode();
Node entry1 = rootNode.getNode("app:company_home/wiki:encyclopedia/wiki:entry1");
// enable versioning capability
entry1.addMixin("mix:versionable");
// update the properties and content
entry1.setProperty("cm:title", "The Rise");
entry1.setProperty("cm:content", "A rose is a flowering shrub of the genus Rosa.");
Value[] categories = entry1.getProperty("wiki:category").getValues();
Value[] newCategories = new Value[categories.length + 1];
System.arraycopy(categories, 0, newCategories, 0, categories.length);
newCategories[categories.length] = session.getValueFactory().createValue("poet");
entry1.setProperty("wiki:category", newCategories);
// and checkin the changes
entry1.checkin();
// checkout, fix wiki title and checkin again
entry1.checkout();
entry1.setProperty("cm:title", "The Rose");
entry1.checkin();
session.save();
System.out.println("Versioned WIKI Page 1");
}
finally
{
session.logout();
}
// 2) Permission checks
session = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
try
{
//
// Browse WIKI Page 1 Version History
//
// first, access the page
Node rootNode = session.getRootNode();
Node entry1 = rootNode.getNode("app:company_home/wiki:encyclopedia/wiki:entry1");
// retrieve the history for thte page
VersionHistory versionHistory = entry1.getVersionHistory();
VersionIterator versionIterator = versionHistory.getAllVersions();
// for each version, output the node as it was versioned
while (versionIterator.hasNext())
{
Version version = versionIterator.nextVersion();
NodeIterator nodeIterator = version.getNodes();
while (nodeIterator.hasNext())
{
Node versionedNode = nodeIterator.nextNode();
System.out.println(" Version: " + version.getName());
System.out.println(" Created: " + version.getCreated().getTime());
outputContentNode(versionedNode);
}
}
//
// Permission Checks
//
System.out.println("Testing Permissions:");
// check for JCR 'read' permission
session.checkPermission("app:company_home/wiki:encyclopedia/wiki:entry1", "read");
System.out.println("Session has 'read' permission on app:company_home/wiki:encyclopedia/wiki:entry1");
// check for Alfresco 'Take Ownership' permission
session.checkPermission("app:company_home/wiki:encyclopedia/wiki:entry1", PermissionService.TAKE_OWNERSHIP);
System.out.println("Session has 'take ownership' permission on app:company_home/wiki:encyclopedia/wiki:entry1");
}
finally
{
session.logout();
}
//
// Mixing JCR and Alfresco API calls
//
// Provide mimetype for WIKI content properties
//
session = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
try
{
// Retrieve the Alfresco Repository Service Registry
ServiceRegistry registry = (ServiceRegistry)context.getBean(ServiceRegistry.SERVICE_REGISTRY);
// set the mime type on both WIKI pages and Image
Node rootNode = session.getRootNode();
// note: we have to checkout entry1 first - it's versioned
Node entry1 = rootNode.getNode("app:company_home/wiki:encyclopedia/wiki:entry1");
entry1.checkout();
setMimetype(registry, entry1, "cm:content", MimetypeMap.MIMETYPE_TEXT_PLAIN);
entry1.checkin();
Node entry2 = rootNode.getNode("app:company_home/wiki:encyclopedia/wiki:entry2");
setMimetype(registry, entry2, "cm:content", MimetypeMap.MIMETYPE_TEXT_PLAIN);
Node image = rootNode.getNode("app:company_home/wiki:encyclopedia/wiki:image");
setMimetype(registry, image, "cm:content", MimetypeMap.MIMETYPE_IMAGE_GIF);
// save the changes
session.save();
System.out.println("Updated WIKI mimetypes via Alfresco calls");
}
finally
{
session.logout();
}
// exit
System.out.println("Completed successfully.");
System.exit(0);
}
private static void outputContentNode(Node node)
throws RepositoryException
{
// output common content properties
System.out.println(" Node " + node.getUUID());
System.out.println(" title: " + node.getProperty("cm:title").getString());
// output properties specific to WIKI page
if (node.getPrimaryNodeType().getName().equals("wiki:page"))
{
System.out.println(" content: " + node.getProperty("cm:content").getString());
System.out.println(" restrict: " + node.getProperty("wiki:restrict").getString());
// output multi-value property
Property categoryProperty = node.getProperty("wiki:category");
Value[] categories = categoryProperty.getValues();
for (Value category : categories)
{
System.out.println(" category: " + category.getString());
}
}
}
private static void setMimetype(ServiceRegistry registry, Node node, String propertyName, String mimeType)
throws RepositoryException
{
// convert the JCR Node to an Alfresco Node Reference
NodeRef nodeRef = JCRNodeRef.getNodeRef(node);
// retrieve the Content Property (represented as a ContentData object in Alfresco)
NodeService nodeService = registry.getNodeService();
ContentData content = (ContentData)nodeService.getProperty(nodeRef, ContentModel.PROP_CONTENT);
// update the Mimetype
content = ContentData.setMimetype(content, mimeType);
nodeService.setProperty(nodeRef, ContentModel.PROP_CONTENT, content);
}
}

View File

@@ -1,16 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
<import resource="classpath:alfresco/application-context.xml" />
<bean id="testDictionaryBootstrap" parent="dictionaryModelBootstrap" depends-on="JCR.DictionaryBootstrap">
<property name="models">
<list>
<value>org/alfresco/jcr/example/wikiModel.xml</value>
</list>
</property>
</bean>
</beans>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 753 KiB

View File

@@ -1,34 +0,0 @@
<model name="wiki:wikimodel" xmlns="http://www.alfresco.org/model/dictionary/1.0">
<imports>
<import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d" />
<import uri="http://www.alfresco.org/model/content/1.0" prefix="cm" />
</imports>
<namespaces>
<namespace uri="http://www.alfresco.org/model/jcr/example/wiki/1.0" prefix="wiki" />
</namespaces>
<types>
<type name="wiki:page">
<title>WIKI Page</title>
<parent>cm:content</parent>
<properties>
<property name="wiki:restrict">
<type>d:boolean</type>
<default>false</default>
</property>
<property name="wiki:category">
<type>d:text</type>
<multiple>true</multiple>
</property>
</properties>
<mandatory-aspects>
<aspect>cm:titled</aspect>
</mandatory-aspects>
</type>
</types>
</model>

View File

@@ -62,7 +62,6 @@ import org.alfresco.jcr.util.JCRProxyFactory;
import org.alfresco.jcr.version.VersionHistoryImpl;
import org.alfresco.jcr.version.VersionImpl;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.version.VersionModel;
import org.alfresco.service.cmr.dictionary.AspectDefinition;
import org.alfresco.service.cmr.dictionary.ChildAssociationDefinition;
import org.alfresco.service.cmr.dictionary.ClassDefinition;
@@ -74,7 +73,6 @@ import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.repository.Path.Element;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.version.VersionService;
@@ -230,7 +228,8 @@ public class NodeImpl extends ItemImpl implements Node
Map<QName, ChildAssociationDefinition> childAssocs = classDef.getChildAssociations();
for (ChildAssociationDefinition childAssocDef : childAssocs.values())
{
if (dictionaryService.isSubClass(nodeType, childAssocDef.getTargetClass().getName()))
QName targetClass = childAssocDef.getTargetClass().getName();
if (dictionaryService.isSubClass(nodeType, targetClass))
{
if (nodeTypeChildAssocDef != null)
{

View File

@@ -16,7 +16,10 @@
*/
package org.alfresco.repo.action;
import java.util.List;
import org.alfresco.service.cmr.action.ActionDefinition;
import org.alfresco.service.namespace.QName;
/**
* Rule action implementation class
@@ -35,6 +38,9 @@ public class ActionDefinitionImpl extends ParameterizedItemDefinitionImpl
* The rule action executor
*/
private String ruleActionExecutor;
/** List of applicable types */
private List<QName> applicableTypes;
/**
* Constructor
@@ -65,4 +71,24 @@ public class ActionDefinitionImpl extends ParameterizedItemDefinitionImpl
{
return ruleActionExecutor;
}
/**
* Gets the list of applicable types
*
* @return the list of qnames
*/
public List<QName> getApplicableTypes()
{
return this.applicableTypes;
}
/**
* Sets the list of applicable types
*
* @param applicableTypes the applicable types
*/
public void setApplicableTypes(List<QName> applicableTypes)
{
this.applicableTypes = applicableTypes;
}
}

View File

@@ -38,6 +38,7 @@ import org.alfresco.service.cmr.action.ActionService;
import org.alfresco.service.cmr.action.ActionServiceException;
import org.alfresco.service.cmr.action.CompositeAction;
import org.alfresco.service.cmr.action.ParameterizedItem;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
@@ -98,6 +99,9 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
*/
private SearchService searchService;
/** The dictionary service */
private DictionaryService dictionaryService;
/** The authentication component */
private AuthenticationComponent authenticationComponent;
@@ -161,6 +165,16 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
this.authenticationComponent = authenticationComponent;
}
/**
* Set the dictionary service
*
* @param dictionaryService the dictionary service
*/
public void setDictionaryService(DictionaryService dictionaryService)
{
this.dictionaryService = dictionaryService;
}
/**
* Set the asynchronous action execution queue
*
@@ -217,6 +231,44 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
{
return new ArrayList<ActionDefinition>(this.actionDefinitions.values());
}
/**
* @see org.alfresco.service.cmr.action.ActionService#getActionDefinitions(org.alfresco.service.cmr.repository.NodeRef)
*/
public List<ActionDefinition> getActionDefinitions(NodeRef nodeRef)
{
if (nodeRef == null)
{
return getActionDefinitions();
}
else
{
// TODO for now we will only filter by type, we will introduce filtering by aspect later
QName nodeType = this.nodeService.getType(nodeRef);
List<ActionDefinition> result = new ArrayList<ActionDefinition>();
for (ActionDefinition actionDefinition : getActionDefinitions())
{
List<QName> appliciableTypes = actionDefinition.getApplicableTypes();
if (appliciableTypes != null && appliciableTypes.isEmpty() == false)
{
for (QName applicableType : actionDefinition.getApplicableTypes())
{
if (this.dictionaryService.isSubClass(nodeType, applicableType))
{
result.add(actionDefinition);
break;
}
}
}
else
{
result.add(actionDefinition);
}
}
return result;
}
}
/**
* @see org.alfresco.service.cmr.action.ActionService#getActionConditionDefinition(java.lang.String)

View File

@@ -55,6 +55,7 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
private static final String BAD_NAME = "badName";
private NodeRef nodeRef;
private NodeRef folder;
@Override
protected void onSetUpInTransaction() throws Exception
@@ -71,6 +72,12 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
this.nodeRef,
ContentModel.PROP_CONTENT,
new ContentData(null, MimetypeMap.MIMETYPE_TEXT_PLAIN, 0L, null));
this.folder = this.nodeService.createNode(
this.rootNodeRef,
ContentModel.ASSOC_CHILDREN,
QName.createQName("{test}testFolder"),
ContentModel.TYPE_FOLDER).getChildRef();
}
/**
@@ -94,11 +101,17 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
List<ActionDefinition> defintions = this.actionService.getActionDefinitions();
assertNotNull(defintions);
assertFalse(defintions.isEmpty());
int totalCount = defintions.size();
for (ActionDefinition definition : defintions)
{
System.out.println(definition.getTitle());
}
// Get the action defintions for a folder type (there should be less than the total available)
List<ActionDefinition> definitions = this.actionService.getActionDefinitions(this.folder);
assertNotNull(definitions);
assertTrue(totalCount > definitions.size());
}
/**

View File

@@ -73,7 +73,7 @@ public abstract class ParameterizedItemAbstractBase extends CommonResourceAbstra
protected List<ParameterDefinition> getParameterDefintions()
{
List<ParameterDefinition> result = new ArrayList<ParameterDefinition>();
addParameterDefintions(result);
addParameterDefinitions(result);
return result;
}
@@ -82,7 +82,7 @@ public abstract class ParameterizedItemAbstractBase extends CommonResourceAbstra
*
* @param paramList the parameter definitions list
*/
protected abstract void addParameterDefintions(List<ParameterDefinition> paramList);
protected abstract void addParameterDefinitions(List<ParameterDefinition> paramList);
/**
* Sets the action service

View File

@@ -83,11 +83,11 @@ public class CompareMimeTypeEvaluator extends ComparePropertyValueEvaluator
}
/**
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefintions(java.util.List)
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefinitions(java.util.List)
*/
@Override
protected void addParameterDefintions(List<ParameterDefinition> paramList)
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
super.addParameterDefintions(paramList);
super.addParameterDefinitions(paramList);
}
}

View File

@@ -145,7 +145,7 @@ public class ComparePropertyValueEvaluator extends ActionConditionEvaluatorAbstr
* Add paremeter defintions
*/
@Override
protected void addParameterDefintions(List<ParameterDefinition> paramList)
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
paramList.add(new ParameterDefinitionImpl(PARAM_PROPERTY, DataTypeDefinition.QNAME, false, getParamDisplayLabel(PARAM_PROPERTY)));
paramList.add(new ParameterDefinitionImpl(PARAM_CONTENT_PROPERTY, DataTypeDefinition.TEXT, false, getParamDisplayLabel(PARAM_CONTENT_PROPERTY)));

View File

@@ -73,10 +73,10 @@ public class HasAspectEvaluator extends ActionConditionEvaluatorAbstractBase
}
/**
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefintions(java.util.List)
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefinitions(java.util.List)
*/
@Override
protected void addParameterDefintions(List<ParameterDefinition> paramList)
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
paramList.add(new ParameterDefinitionImpl(PARAM_ASPECT, DataTypeDefinition.QNAME, true, getParamDisplayLabel(PARAM_ASPECT)));
}

View File

@@ -81,10 +81,10 @@ public class HasVersionHistoryEvaluator extends ActionConditionEvaluatorAbstract
}
/**
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefintions(java.util.List)
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefinitions(java.util.List)
*/
@Override
protected void addParameterDefintions(List<ParameterDefinition> paramList)
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
}

View File

@@ -81,7 +81,7 @@ public class InCategoryEvaluator extends ActionConditionEvaluatorAbstractBase
* Add the parameter definitions
*/
@Override
protected void addParameterDefintions(List<ParameterDefinition> paramList)
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
paramList.add(new ParameterDefinitionImpl(PARAM_CATEGORY_ASPECT, DataTypeDefinition.QNAME, true, getParamDisplayLabel(PARAM_CATEGORY_ASPECT)));
paramList.add(new ParameterDefinitionImpl(PARAM_CATEGORY_VALUE, DataTypeDefinition.NODE_REF, true, getParamDisplayLabel(PARAM_CATEGORY_VALUE)));

View File

@@ -91,10 +91,10 @@ public class IsSubTypeEvaluator extends ActionConditionEvaluatorAbstractBase
}
/**
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefintions(java.util.List)
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefinitions(java.util.List)
*/
@Override
protected void addParameterDefintions(List<ParameterDefinition> paramList)
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
paramList.add(new ParameterDefinitionImpl(PARAM_TYPE, DataTypeDefinition.QNAME, true, getParamDisplayLabel(PARAM_TYPE)));
}

View File

@@ -43,10 +43,10 @@ public class NoConditionEvaluator extends ActionConditionEvaluatorAbstractBase
}
/**
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefintions(java.util.List)
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefinitions(java.util.List)
*/
@Override
protected void addParameterDefintions(List<ParameterDefinition> paramList)
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
// No parameters to add
}

View File

@@ -16,11 +16,15 @@
*/
package org.alfresco.repo.action.executer;
import java.util.ArrayList;
import java.util.List;
import org.alfresco.repo.action.ActionDefinitionImpl;
import org.alfresco.repo.action.ParameterizedItemAbstractBase;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ActionDefinition;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
/**
* Rule action executor abstract base.
@@ -38,6 +42,9 @@ public abstract class ActionExecuterAbstractBase extends ParameterizedItemAbstra
* Indicated whether the action is public or internal
*/
protected boolean publicAction = true;
/** List of types and aspects for which this action is applicable */
protected List<QName> applicableTypes = new ArrayList<QName>();
/**
* Init method
@@ -59,6 +66,19 @@ public abstract class ActionExecuterAbstractBase extends ParameterizedItemAbstra
{
this.publicAction = publicAction;
}
/**
* Set the list of types for which this action is applicable
*
* @param applicableTypes arry of applicable types
*/
public void setApplicableTypes(String[] applicableTypes)
{
for (String type : applicableTypes)
{
this.applicableTypes.add(QName.createQName(type));
}
}
/**
* Get rule action definition
@@ -75,6 +95,7 @@ public abstract class ActionExecuterAbstractBase extends ParameterizedItemAbstra
((ActionDefinitionImpl)this.actionDefinition).setAdhocPropertiesAllowed(getAdhocPropertiesAllowed());
((ActionDefinitionImpl)this.actionDefinition).setRuleActionExecutor(this.name);
((ActionDefinitionImpl)this.actionDefinition).setParameterDefinitions(getParameterDefintions());
((ActionDefinitionImpl)this.actionDefinition).setApplicableTypes(this.applicableTypes);
}
return this.actionDefinition;
}

View File

@@ -99,10 +99,10 @@ public class AddFeaturesActionExecuter extends ActionExecuterAbstractBase
}
/**
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefintions(java.util.List)
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefinitions(java.util.List)
*/
@Override
protected void addParameterDefintions(List<ParameterDefinition> paramList)
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
paramList.add(new ParameterDefinitionImpl(PARAM_ASPECT_NAME, DataTypeDefinition.QNAME, true, getParamDisplayLabel(PARAM_ASPECT_NAME)));
}

View File

@@ -107,7 +107,7 @@ public class CheckInActionExecuter extends ActionExecuterAbstractBase
}
@Override
protected void addParameterDefintions(List<ParameterDefinition> paramList)
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
paramList.add(new ParameterDefinitionImpl(PARAM_DESCRIPTION, DataTypeDefinition.TEXT, false, getParamDisplayLabel(PARAM_DESCRIPTION)));
}

View File

@@ -74,7 +74,7 @@ public class CheckOutActionExecuter extends ActionExecuterAbstractBase
* Add the parameter defintions
*/
@Override
protected void addParameterDefintions(List<ParameterDefinition> paramList)
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
paramList.add(new ParameterDefinitionImpl(PARAM_DESTINATION_FOLDER, DataTypeDefinition.NODE_REF, false, getParamDisplayLabel(PARAM_DESTINATION_FOLDER)));
paramList.add(new ParameterDefinitionImpl(PARAM_ASSOC_TYPE_QNAME, DataTypeDefinition.QNAME, false, getParamDisplayLabel(PARAM_ASSOC_TYPE_QNAME)));

View File

@@ -70,7 +70,7 @@ public class CompositeActionExecuter extends ActionExecuterAbstractBase
* Add parameter definitions
*/
@Override
protected void addParameterDefintions(List<ParameterDefinition> paramList)
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
// No parameters
}

View File

@@ -198,7 +198,7 @@ public class ContentMetadataExtracter extends ActionExecuterAbstractBase
}
@Override
protected void addParameterDefintions(List<ParameterDefinition> arg0)
protected void addParameterDefinitions(List<ParameterDefinition> arg0)
{
// None!
}

View File

@@ -82,10 +82,10 @@ public class CopyActionExecuter extends ActionExecuterAbstractBase
/**
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefintions(java.util.List)
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefinitions(java.util.List)
*/
@Override
protected void addParameterDefintions(List<ParameterDefinition> paramList)
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
paramList.add(new ParameterDefinitionImpl(PARAM_DESTINATION_FOLDER, DataTypeDefinition.NODE_REF, true, getParamDisplayLabel(PARAM_DESTINATION_FOLDER)));
paramList.add(new ParameterDefinitionImpl(PARAM_ASSOC_TYPE_QNAME, DataTypeDefinition.QNAME, true, getParamDisplayLabel(PARAM_ASSOC_TYPE_QNAME)));

View File

@@ -65,10 +65,10 @@ public class CreateVersionActionExecuter extends ActionExecuterAbstractBase
}
/**
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefintions(java.util.List)
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefinitions(java.util.List)
*/
@Override
protected void addParameterDefintions(List<ParameterDefinition> paramList)
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
}

View File

@@ -143,10 +143,10 @@ public class ExecuteAllRulesActionExecuter extends ActionExecuterAbstractBase
}
/**
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefintions(java.util.List)
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefinitions(java.util.List)
*/
@Override
protected void addParameterDefintions(List<ParameterDefinition> paramList)
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
paramList.add(new ParameterDefinitionImpl(PARAM_EXECUTE_INHERITED_RULES, DataTypeDefinition.BOOLEAN, false, getParamDisplayLabel(PARAM_EXECUTE_INHERITED_RULES)));
}

View File

@@ -187,9 +187,9 @@ public class ExporterActionExecuter extends ActionExecuterAbstractBase
}
/**
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefintions(java.util.List)
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefinitions(java.util.List)
*/
protected void addParameterDefintions(List<ParameterDefinition> paramList)
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
paramList.add(new ParameterDefinitionImpl(PARAM_PACKAGE_NAME, DataTypeDefinition.TEXT, true,
getParamDisplayLabel(PARAM_PACKAGE_NAME)));

View File

@@ -58,9 +58,9 @@ public class ImageTransformActionExecuter extends TransformActionExecuter
* Add parameter definitions
*/
@Override
protected void addParameterDefintions(List<ParameterDefinition> paramList)
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
super.addParameterDefintions(paramList);
super.addParameterDefinitions(paramList);
paramList.add(new ParameterDefinitionImpl(PARAM_CONVERT_COMMAND, DataTypeDefinition.TEXT, false, getParamDisplayLabel(PARAM_CONVERT_COMMAND)));
}

View File

@@ -134,9 +134,9 @@ public class ImporterActionExecuter extends ActionExecuterAbstractBase
}
/**
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefintions(java.util.List)
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefinitions(java.util.List)
*/
protected void addParameterDefintions(List<ParameterDefinition> paramList)
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
paramList.add(new ParameterDefinitionImpl(PARAM_DESTINATION_FOLDER, DataTypeDefinition.NODE_REF,
true, getParamDisplayLabel(PARAM_DESTINATION_FOLDER)));

View File

@@ -82,7 +82,7 @@ public class LinkCategoryActionExecuter extends ActionExecuterAbstractBase
* Add the parameter definitions
*/
@Override
protected void addParameterDefintions(List<ParameterDefinition> paramList)
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
paramList.add(new ParameterDefinitionImpl(PARAM_CATEGORY_ASPECT, DataTypeDefinition.QNAME, true, getParamDisplayLabel(PARAM_CATEGORY_ASPECT)));
paramList.add(new ParameterDefinitionImpl(PARAM_CATEGORY_VALUE, DataTypeDefinition.NODE_REF, true, getParamDisplayLabel(PARAM_CATEGORY_VALUE)));

View File

@@ -300,7 +300,7 @@ public class MailActionExecuter extends ActionExecuterAbstractBase
* Add the parameter definitions
*/
@Override
protected void addParameterDefintions(List<ParameterDefinition> paramList)
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
paramList.add(new ParameterDefinitionImpl(PARAM_TO, DataTypeDefinition.TEXT, false, getParamDisplayLabel(PARAM_TO)));
paramList.add(new ParameterDefinitionImpl(PARAM_TO_MANY, DataTypeDefinition.ANY, false, getParamDisplayLabel(PARAM_TO_MANY)));

View File

@@ -51,7 +51,7 @@ public class MoveActionExecuter extends ActionExecuterAbstractBase
}
@Override
protected void addParameterDefintions(List<ParameterDefinition> paramList)
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
paramList.add(new ParameterDefinitionImpl(PARAM_DESTINATION_FOLDER, DataTypeDefinition.NODE_REF, true, getParamDisplayLabel(PARAM_DESTINATION_FOLDER)));
paramList.add(new ParameterDefinitionImpl(PARAM_ASSOC_TYPE_QNAME, DataTypeDefinition.QNAME, true, getParamDisplayLabel(PARAM_ASSOC_TYPE_QNAME)));

View File

@@ -68,10 +68,10 @@ public class RemoveFeaturesActionExecuter extends ActionExecuterAbstractBase
}
/**
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefintions(java.util.List)
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefinitions(java.util.List)
*/
@Override
protected void addParameterDefintions(List<ParameterDefinition> paramList)
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
paramList.add(new ParameterDefinitionImpl(PARAM_ASPECT_NAME, DataTypeDefinition.QNAME, true, getParamDisplayLabel(PARAM_ASPECT_NAME)));
}

View File

@@ -62,9 +62,9 @@ public class RepositoryExporterActionExecuter extends ActionExecuterAbstractBase
}
/**
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefintions(java.util.List)
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefinitions(java.util.List)
*/
protected void addParameterDefintions(List<ParameterDefinition> paramList)
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
paramList.add(new ParameterDefinitionImpl(PARAM_PACKAGE_NAME, DataTypeDefinition.TEXT, true,
getParamDisplayLabel(PARAM_PACKAGE_NAME)));

View File

@@ -114,9 +114,9 @@ public class ScriptActionExecutor extends ActionExecuterAbstractBase
}
/**
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefintions(java.util.List)
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefinitions(java.util.List)
*/
protected void addParameterDefintions(List<ParameterDefinition> paramList)
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
paramList.add(new ParameterDefinitionImpl(PARAM_SCRIPTREF, DataTypeDefinition.NODE_REF, true, getParamDisplayLabel(PARAM_SCRIPTREF)));
paramList.add(new ParameterDefinitionImpl(PARAM_SPACEREF, DataTypeDefinition.NODE_REF, false, getParamDisplayLabel(PARAM_SPACEREF)));

View File

@@ -74,7 +74,7 @@ public class SetPropertyValueActionExecuter extends ActionExecuterAbstractBase
* Add parameter definitions
*/
@Override
protected void addParameterDefintions(List<ParameterDefinition> paramList)
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
paramList.add(new ParameterDefinitionImpl(PARAM_PROPERTY, DataTypeDefinition.QNAME, true, getParamDisplayLabel(PARAM_PROPERTY)));
paramList.add(new ParameterDefinitionImpl(PARAM_VALUE, DataTypeDefinition.ANY, true, getParamDisplayLabel(PARAM_VALUE)));

View File

@@ -53,7 +53,7 @@ public class SimpleWorkflowActionExecuter extends ActionExecuterAbstractBase
}
@Override
protected void addParameterDefintions(List<ParameterDefinition> paramList)
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
paramList.add(new ParameterDefinitionImpl(PARAM_APPROVE_STEP, DataTypeDefinition.TEXT, false, getParamDisplayLabel(PARAM_APPROVE_STEP)));
paramList.add(new ParameterDefinitionImpl(PARAM_APPROVE_FOLDER, DataTypeDefinition.NODE_REF, false, getParamDisplayLabel(PARAM_APPROVE_FOLDER)));

View File

@@ -92,10 +92,10 @@ public class SpecialiseTypeActionExecuter extends ActionExecuterAbstractBase
}
/**
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefintions(java.util.List)
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefinitions(java.util.List)
*/
@Override
protected void addParameterDefintions(List<ParameterDefinition> paramList)
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
paramList.add(new ParameterDefinitionImpl(PARAM_TYPE_NAME, DataTypeDefinition.QNAME, true, getParamDisplayLabel(PARAM_TYPE_NAME)));
}

View File

@@ -123,7 +123,7 @@ public class TransformActionExecuter extends ActionExecuterAbstractBase
* Add parameter definitions
*/
@Override
protected void addParameterDefintions(List<ParameterDefinition> paramList)
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
{
paramList.add(new ParameterDefinitionImpl(PARAM_MIME_TYPE, DataTypeDefinition.TEXT, true, getParamDisplayLabel(PARAM_MIME_TYPE)));
paramList.add(new ParameterDefinitionImpl(PARAM_DESTINATION_FOLDER, DataTypeDefinition.NODE_REF, true, getParamDisplayLabel(PARAM_DESTINATION_FOLDER)));

View File

@@ -38,6 +38,7 @@ import org.alfresco.service.cmr.dictionary.DictionaryException;
*
* @author Derek Hulley
*/
@SuppressWarnings("unused")
public class ConstraintsTest extends TestCase
{
@Override
@@ -229,8 +230,8 @@ public class ConstraintsTest extends TestCase
public void testRegexConstraintFilename() throws Exception
{
// we assume UTF-8
String expression = ".*[\\\"\\*\\\\\\>\\<\\?\\/\\:\\|\\xA3\\xAC\\%\\&\\+\\;]+.*";
String invalidChars = "\"*\\><?/:|£%&+;";
String expression = new String(".*[\\\"\\*\\\\\\>\\<\\?\\/\\:\\|\\¬\\£\\%\\&\\+\\;]+.*".getBytes("UTF-8"));
String invalidChars = new String("\"*\\><?/:|%&+;£".getBytes("UTF-8"));
RegexConstraint constraint = new RegexConstraint();
constraint.setExpression(expression);

View File

@@ -72,4 +72,10 @@ public interface DbAccessControlEntry
* @param allowed
*/
public void setAllowed(boolean allowed);
/**
* Helper method to delete the instance and make sure that all
* inverse associations are properly maintained.
*/
public void delete();
}

View File

@@ -16,6 +16,10 @@
*/
package org.alfresco.repo.domain;
import java.util.Set;
import org.alfresco.repo.domain.hibernate.DbAccessControlEntryImpl;
/**
* The interface to support persistence of node access control entries in hibernate
@@ -30,17 +34,29 @@ public interface DbAccessControlList
public void setNode(Node node);
/**
*
* @return Returns the access control entries for this access control list
*/
public Set<DbAccessControlEntry> getEntries();
/**
* Get inheritance behaviour
* @return
* @return Returns the inheritance status of this list
*/
public boolean getInherits();
/**
* Set inheritance behaviour
* @param inherits
* @param inherits true to set the permissions to inherit
*/
public void setInherits(boolean inherits);
public int deleteEntriesForAuthority(String authorityKey);
public int deleteEntriesForPermission(DbPermissionKey permissionKey);
public int deleteEntry(String authorityKey, DbPermissionKey permissionKey);
/**
* Delete the entries related to this access control list
@@ -48,4 +64,18 @@ public interface DbAccessControlList
* @return Returns the number of entries deleted
*/
public int deleteEntries();
public DbAccessControlEntry getEntry(String authorityKey, DbPermissionKey permissionKey);
/**
* Factory method to create an entry and wire it up.
* Note that the returned value may still be transient. Saving it should be fine, but
* is not required.
*
* @param permission the mandatory permission association with this entry
* @param authority the mandatory authority. Must not be transient.
* @param allowed allowed or disallowed. Must not be transient.
* @return Returns the new entry
*/
public DbAccessControlEntryImpl newEntry(DbPermission permission, DbAuthority authority, boolean allowed);
}

View File

@@ -51,4 +51,10 @@ public interface DbPermission extends Serializable
* @param name the name of the permission
*/
public void setName(String name);
/**
* @return Returns a key combining the {@link #getTypeQname() type}
* and {@link #getName() name}
*/
public DbPermissionKey getKey();
}

View File

@@ -0,0 +1,102 @@
/*
* Copyright (C) 2005 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.domain;
import java.io.Serializable;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.EqualsHelper;
/**
* Compound key for persistence of {@link org.alfresco.repo.domain.DbPermission}.
*
* @author Derek Hulley
*/
public class DbPermissionKey implements Serializable
{
private static final long serialVersionUID = -1667797216480779296L;
private QName typeQname;
private String name;
public DbPermissionKey()
{
}
public DbPermissionKey(QName typeQname, String name)
{
this.typeQname = typeQname;
this.name = name;
}
public String toString()
{
return ("DbPermissionKey" +
"[ type=" + typeQname +
", name=" + name +
"]");
}
public int hashCode()
{
return this.name.hashCode();
}
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
else if (!(obj instanceof DbPermissionKey))
{
return false;
}
DbPermissionKey that = (DbPermissionKey) obj;
return (EqualsHelper.nullSafeEquals(this.typeQname, that.typeQname)
&& EqualsHelper.nullSafeEquals(this.name, that.name)
);
}
public QName getTypeQname()
{
return typeQname;
}
/**
* Tamper-proof method only to be used by introspectors
*/
@SuppressWarnings("unused")
private void setTypeQname(QName typeQname)
{
this.typeQname = typeQname;
}
public String getName()
{
return name;
}
/**
* Tamper-proof method only to be used by introspectors
*/
@SuppressWarnings("unused")
private void setName(String name)
{
this.name = name;
}
}

View File

@@ -80,5 +80,5 @@ public interface Node
public DbAccessControlList getAccessControlList();
// public void setAccessControlList(DbAccessControlList accessControlList);
public void setAccessControlList(DbAccessControlList accessControlList);
}

View File

@@ -151,11 +151,12 @@ public class ChildAssocImpl implements ChildAssoc
return false;
}
ChildAssoc that = (ChildAssoc) obj;
return (this.getIsPrimary() == that.getIsPrimary()
&& EqualsHelper.nullSafeEquals(this.getTypeQName(), that.getTypeQName())
return (
EqualsHelper.nullSafeEquals(this.getTypeQName(), that.getTypeQName())
&& EqualsHelper.nullSafeEquals(this.getQname(), that.getQname())
&& EqualsHelper.nullSafeEquals(this.getParent(), that.getParent())
&& EqualsHelper.nullSafeEquals(this.getChild(), that.getChild()));
&& EqualsHelper.nullSafeEquals(this.getChild(), that.getChild())
);
}
public int hashCode()

View File

@@ -27,7 +27,7 @@ import org.alfresco.util.EqualsHelper;
*
* @author andyh
*/
public class DbAccessControlEntryImpl implements DbAccessControlEntry
public class DbAccessControlEntryImpl extends LifecycleAdapter implements DbAccessControlEntry
{
/** The object id */
private long id;
@@ -56,7 +56,7 @@ public class DbAccessControlEntryImpl implements DbAccessControlEntry
sb.append("DbAccessControlEntryImpl")
.append("[ id=").append(id)
.append(", acl=").append(accessControlList.getId())
.append(", permission=").append(permission.getId())
.append(", permission=").append(permission.getKey())
.append(", authority=").append(authority.getRecipient())
.append("]");
return sb.toString();
@@ -74,16 +74,14 @@ public class DbAccessControlEntryImpl implements DbAccessControlEntry
return false;
}
DbAccessControlEntry other = (DbAccessControlEntry) o;
return (this.allowed == other.isAllowed())
&& EqualsHelper.nullSafeEquals(this.accessControlList, other.getAccessControlList())
&& EqualsHelper.nullSafeEquals(this.permission, other.getPermission())
&& EqualsHelper.nullSafeEquals(this.authority, other.getAuthority());
return (EqualsHelper.nullSafeEquals(this.permission, other.getPermission())
&& EqualsHelper.nullSafeEquals(this.authority, other.getAuthority()));
}
@Override
public int hashCode()
{
int hashCode = accessControlList.hashCode();
int hashCode = 0;
if (permission != null)
{
hashCode = hashCode * 37 + permission.hashCode();
@@ -92,33 +90,9 @@ public class DbAccessControlEntryImpl implements DbAccessControlEntry
{
hashCode = hashCode * 37 + authority.hashCode();
}
hashCode = hashCode * 37 + (allowed ? 1 : 0);
return hashCode;
}
/**
* Factory method to create an entry and wire it in to the contained nodePermissionEntry
*
* @param accessControlList the list of entries that this one belongs to
* @param permission the mandatory permission association with this entry
* @param authority the mandatory authority
* @param allowed allowed or disallowed
* @return Returns an unpersisted entity
*/
public static DbAccessControlEntryImpl create(
DbAccessControlList accessControlList,
DbPermission permission,
DbAuthority authority,
boolean allowed)
{
DbAccessControlEntryImpl accessControlEntry = new DbAccessControlEntryImpl();
accessControlEntry.setAccessControlList(accessControlList);
accessControlEntry.setPermission(permission);
accessControlEntry.setAuthority(authority);
accessControlEntry.setAllowed(allowed);
return accessControlEntry;
}
public long getId()
{
return id;
@@ -171,4 +145,13 @@ public class DbAccessControlEntryImpl implements DbAccessControlEntry
{
this.allowed = allowed;
}
public void delete()
{
// remove the instance from the access control list
@SuppressWarnings("unused")
boolean removed = getAccessControlList().getEntries().remove(this);
// delete the instance
getSession().delete(this);
}
}

View File

@@ -16,13 +16,20 @@
*/
package org.alfresco.repo.domain.hibernate;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.alfresco.repo.domain.DbAccessControlEntry;
import org.alfresco.repo.domain.DbAccessControlList;
import org.alfresco.repo.domain.DbAuthority;
import org.alfresco.repo.domain.DbPermission;
import org.alfresco.repo.domain.DbPermissionKey;
import org.alfresco.repo.domain.Node;
import org.alfresco.util.EqualsHelper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.CallbackException;
import org.hibernate.Query;
import org.hibernate.Session;
/**
@@ -36,8 +43,14 @@ public class DbAccessControlListImpl extends LifecycleAdapter implements DbAcces
private long id;
private Node node;
private Set<DbAccessControlEntry> entries;
private boolean inherits;
public DbAccessControlListImpl()
{
entries = new HashSet<DbAccessControlEntry>(5);
}
@Override
public String toString()
{
@@ -45,6 +58,7 @@ public class DbAccessControlListImpl extends LifecycleAdapter implements DbAcces
sb.append("DbAccessControlListImpl")
.append("[ id=").append(id)
.append(", node=").append(node)
.append(", entries=").append(entries.size())
.append(", inherits=").append(inherits)
.append("]");
return sb.toString();
@@ -73,35 +87,6 @@ public class DbAccessControlListImpl extends LifecycleAdapter implements DbAcces
return (node == null ? 0 : node.hashCode());
}
public int deleteEntries()
{
/*
* This can use a delete direct to the database as well, but then care must be taken
* to evict the instances from the session.
*/
// bypass L2 cache and get all entries for this list
Query query = getSession()
.getNamedQuery(PermissionsDaoComponentImpl.QUERY_GET_AC_ENTRIES_FOR_AC_LIST)
.setLong("accessControlListId", this.id);
int count = HibernateHelper.deleteQueryResults(getSession(), query);
// done
if (logger.isDebugEnabled())
{
logger.debug("Deleted " + count + " access entries for access control list " + this.id);
}
return count;
}
/**
* Ensures that all this access control list's entries have been deleted.
*/
public boolean onDelete(Session session) throws CallbackException
{
deleteEntries();
return super.onDelete(session);
}
public long getId()
{
return id;
@@ -126,9 +111,18 @@ public class DbAccessControlListImpl extends LifecycleAdapter implements DbAcces
this.node = node;
}
public DbAccessControlListImpl()
public Set<DbAccessControlEntry> getEntries()
{
super();
return entries;
}
/**
* For Hibernate use
*/
@SuppressWarnings("unused")
private void setEntries(Set<DbAccessControlEntry> entries)
{
this.entries = entries;
}
public boolean getInherits()
@@ -140,4 +134,112 @@ public class DbAccessControlListImpl extends LifecycleAdapter implements DbAcces
{
this.inherits = inherits;
}
/**
* @see #deleteEntry(String, DbPermissionKey)
*/
public int deleteEntriesForAuthority(String authority)
{
return deleteEntry(authority, null);
}
/**
* @see #deleteEntry(String, DbPermissionKey)
*/
public int deleteEntriesForPermission(DbPermissionKey permissionKey)
{
return deleteEntry(null, permissionKey);
}
public int deleteEntry(String authority, DbPermissionKey permissionKey)
{
List<DbAccessControlEntry> toDelete = new ArrayList<DbAccessControlEntry>(2);
for (DbAccessControlEntry entry : entries)
{
if (authority != null && !authority.equals(entry.getAuthority().getRecipient()))
{
// authority is not a match
continue;
}
else if (permissionKey != null && !permissionKey.equals(entry.getPermission().getKey()))
{
// permission is not a match
continue;
}
toDelete.add(entry);
}
// delete them
for (DbAccessControlEntry entry : toDelete)
{
// remove from the entry list
entry.delete();
}
// done
if (logger.isDebugEnabled())
{
logger.debug("Deleted " + toDelete.size() + " access entries: \n" +
" access control list: " + id + "\n" +
" authority: " + authority + "\n" +
" permission: " + permissionKey);
}
return toDelete.size();
}
public int deleteEntries()
{
/*
* We don't do the full delete-remove-from-set thing here. Just delete each child entity
* and then clear the entry set.
*/
Session session = getSession();
List<DbAccessControlEntry> toDelete = new ArrayList<DbAccessControlEntry>(entries);
// delete each entry
for (DbAccessControlEntry entry : toDelete)
{
session.delete(entry);
}
// clear the list
int count = entries.size();
entries.clear();
// done
if (logger.isDebugEnabled())
{
logger.debug("Deleted " + count + " access entries for access control list " + this.id);
}
return count;
}
public DbAccessControlEntry getEntry(String authority, DbPermissionKey permissionKey)
{
for (DbAccessControlEntry entry : entries)
{
DbAuthority authorityEntity = entry.getAuthority();
DbPermission permissionEntity = entry.getPermission();
// check for a match
if (authorityEntity.getRecipient().equals(authority)
&& permissionEntity.getKey().equals(permissionKey))
{
// found it
return entry;
}
}
return null;
}
public DbAccessControlEntryImpl newEntry(DbPermission permission, DbAuthority authority, boolean allowed)
{
DbAccessControlEntryImpl accessControlEntry = new DbAccessControlEntryImpl();
// fill
accessControlEntry.setAccessControlList(this);
accessControlEntry.setPermission(permission);
accessControlEntry.setAuthority(authority);
accessControlEntry.setAllowed(allowed);
// save it
getSession().save(accessControlEntry);
// maintain inverse set on the acl
getEntries().add(accessControlEntry);
// done
return accessControlEntry;
}
}

View File

@@ -38,11 +38,11 @@ public class DbAuthorityImpl extends LifecycleAdapter implements DbAuthority
private static Log logger = LogFactory.getLog(DbAuthorityImpl.class);
private String recipient;
private Set<String> externalKeys = new HashSet<String>();
private Set<String> externalKeys;
public DbAuthorityImpl()
{
super();
externalKeys = new HashSet<String>();
}
@Override
@@ -76,8 +76,8 @@ public class DbAuthorityImpl extends LifecycleAdapter implements DbAuthority
// bypass L2 cache and get all entries for this list
Query query = getSession()
.getNamedQuery(PermissionsDaoComponentImpl.QUERY_GET_AC_ENTRIES_FOR_AUTHORITY)
.setString("recipient", this.recipient);
int count = HibernateHelper.deleteQueryResults(getSession(), query);
.setString("authorityRecipient", this.recipient);
int count = HibernateHelper.deleteDbAccessControlEntries(getSession(), query);
// done
if (logger.isDebugEnabled())
{
@@ -115,4 +115,16 @@ public class DbAuthorityImpl extends LifecycleAdapter implements DbAuthority
{
this.externalKeys = externalKeys;
}
/**
* Helper method to find an authority based on its natural key
*
* @param session the Hibernate session to use
* @param authority the authority name
* @return Returns an existing instance or null if not found
*/
public static DbAuthority find(Session session, String authority)
{
return (DbAuthority) session.get(DbAuthorityImpl.class, authority);
}
}

View File

@@ -17,6 +17,7 @@
package org.alfresco.repo.domain.hibernate;
import org.alfresco.repo.domain.DbPermission;
import org.alfresco.repo.domain.DbPermissionKey;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.EqualsHelper;
import org.apache.commons.logging.Log;
@@ -90,7 +91,7 @@ public class DbPermissionImpl extends LifecycleAdapter implements DbPermission
Query query = getSession()
.getNamedQuery(PermissionsDaoComponentImpl.QUERY_GET_AC_ENTRIES_FOR_PERMISSION)
.setSerializable("permissionId", this.id);
int count = HibernateHelper.deleteQueryResults(getSession(), query);
int count = HibernateHelper.deleteDbAccessControlEntries(getSession(), query);
// done
if (logger.isDebugEnabled())
{
@@ -142,6 +143,11 @@ public class DbPermissionImpl extends LifecycleAdapter implements DbPermission
this.name = name;
}
public DbPermissionKey getKey()
{
return new DbPermissionKey(typeQname, name);
}
/**
* Helper method to find a permission based on its natural key
*

View File

@@ -16,8 +16,7 @@
*/
package org.alfresco.repo.domain.hibernate;
import org.hibernate.CacheMode;
import org.hibernate.ObjectDeletedException;
import org.alfresco.repo.domain.DbAccessControlEntry;
import org.hibernate.Query;
import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults;
@@ -32,36 +31,25 @@ public class HibernateHelper
{
/**
* Helper method to scroll through the results of a query and delete all the
* results, performing batch flushes. This will handle large resultsets by
* pulling the results directly in from the query. For certain circumstances, it
* may be better to perform a bulk delete directly instead.
* resulting access control entries, performing batch flushes.
*
* @param session the session to use for the deletions
* @param query the query with all parameters set
* @return Returns the number of entities deleted, regardless of type
* @param query the query with all parameters set and that will return
* {@link org.alfresco.repo.domain.DbAccessControlEntry access control entry} instances
* @return Returns the number of entries deleted
*/
public static int deleteQueryResults(Session session, Query query)
public static int deleteDbAccessControlEntries(Session session, Query query)
{
ScrollableResults entities = query.setCacheMode(CacheMode.IGNORE).scroll(ScrollMode.FORWARD_ONLY);
ScrollableResults entities = query.scroll(ScrollMode.FORWARD_ONLY);
int count = 0;
while (entities.next())
{
Object[] entityResults = entities.get();
for (Object object : entityResults)
DbAccessControlEntry entry = (DbAccessControlEntry) entities.get(0);
entry.delete();
if (++count % 50 == 0)
{
try
{
session.delete(object);
}
catch (ObjectDeletedException e)
{
// ignore - it's what we wanted
}
if (++count % 50 == 0)
{
session.flush();
session.clear();
}
session.flush();
session.clear();
}
}
return count;

View File

@@ -18,6 +18,7 @@ package org.alfresco.repo.domain.hibernate;
import java.io.Serializable;
import org.alfresco.error.AlfrescoRuntimeException;
import org.hibernate.CallbackException;
import org.hibernate.Session;
import org.hibernate.classic.Lifecycle;
@@ -37,6 +38,10 @@ public abstract class LifecycleAdapter implements Lifecycle
*/
protected Session getSession()
{
if (session == null)
{
throw new AlfrescoRuntimeException("Hibernate entity is not part of a session: " + this);
}
return session;
}

View File

@@ -28,9 +28,9 @@
name="store"
class="org.alfresco.repo.domain.hibernate.StoreImpl"
not-null="true"
lazy="no-proxy"
lazy="proxy"
optimistic-lock="true"
fetch="select">
fetch="join">
<column name="protocol" not-null="true" />
<column name="identifier" not-null="true" />
</many-to-one>
@@ -43,8 +43,8 @@
name="accessControlList"
class="org.alfresco.repo.domain.hibernate.DbAccessControlListImpl"
property-ref="node"
lazy="no-proxy"
fetch="select"
lazy="false"
fetch="join"
cascade="delete" />
<!-- forward assoc to properties -->
<map
@@ -74,55 +74,59 @@
<set
name="aspects"
table="node_aspects"
lazy="true"
sort="unsorted"
lazy="false"
fetch="join"
inverse="false"
fetch="select"
sort="unsorted"
optimistic-lock="true"
cascade="delete" >
<key column="node_id" not-null="true" />
<element column="qname" type="QName" length="200"/>
</set>
<!-- inverse assoc to parent childassocs -->
<bag
<set
name="parentAssocs"
lazy="true"
inverse="true"
lazy="true"
fetch="select"
cascade="none"
optimistic-lock="true"
fetch="select" >
optimistic-lock="true" >
<key column="child_node_id" />
<one-to-many class="org.alfresco.repo.domain.hibernate.ChildAssocImpl" />
</bag>
</set>
<!-- inverse assoc to child childassocs -->
<bag
<set
name="childAssocs"
inverse="true"
lazy="true"
fetch="select"
cascade="none"
optimistic-lock="true"
fetch="select" >
optimistic-lock="true" >
<key column="parent_node_id" />
<one-to-many class="org.alfresco.repo.domain.hibernate.ChildAssocImpl" />
</bag>
</set>
<!-- inverse assoc to source nodeassocs -->
<bag
<set
name="sourceNodeAssocs"
inverse="true"
lazy="true"
fetch="select"
cascade="none"
optimistic-lock="true" >
<key column="target_node_id" />
<one-to-many class="org.alfresco.repo.domain.hibernate.NodeAssocImpl" />
</bag>
</set>
<!-- inverse assoc to target nodeassocs -->
<bag
<set
name="targetNodeAssocs"
inverse="true"
lazy="true"
fetch="select"
cascade="none"
optimistic-lock="true" >
<key column="source_node_id" />
<one-to-many class="org.alfresco.repo.domain.hibernate.NodeAssocImpl" />
</bag>
</set>
</class>
<class
@@ -145,10 +149,10 @@
name="node"
class="org.alfresco.repo.domain.hibernate.NodeImpl"
column="node_id"
unique="false"
not-null="false"
lazy="false"
fetch="join"
lazy="false" />
unique="false"
not-null="false" />
<property name="changeTxnId" column="change_txn_id" type="string" length="56" not-null="true" />
<property name="deleted" column="deleted" type="boolean" not-null="true" />
</class>
@@ -165,10 +169,6 @@
<id name="id" column="id" type="long" >
<generator class="native" />
</id>
<property name="typeQName" column="type_qname" type="QName" length="255" not-null="true" />
<property name="qname" column="qname" type="QName" length="255" not-null="true" />
<property name="isPrimary" column="is_primary" />
<property name="index" column="assoc_index" />
<!-- forward assoc to parent node -->
<many-to-one
name="parent"
@@ -189,6 +189,10 @@
not-null="true" >
<column name="child_node_id" />
</many-to-one>
<property name="typeQName" column="type_qname" type="QName" length="255" not-null="true" />
<property name="qname" column="qname" type="QName" length="255" not-null="true" />
<property name="isPrimary" column="is_primary" />
<property name="index" column="assoc_index" />
</class>
<class
@@ -199,21 +203,27 @@
<id name="id" column="id" type="long" >
<generator class="native" />
</id>
<property name="typeQName" column="type_qname" type="QName" length="255" not-null="true" />
<!-- forward assoc to source node -->
<many-to-one
name="source"
class="org.alfresco.repo.domain.hibernate.NodeImpl"
not-null="true" >
<column name="source_node_id" />
</many-to-one>
<!-- forward assoc to target node -->
<many-to-one
name="target"
class="org.alfresco.repo.domain.hibernate.NodeImpl"
not-null="true" >
<column name="target_node_id" />
</many-to-one>
<natural-id mutable="true">
<!-- forward assoc to source node -->
<many-to-one
name="source"
class="org.alfresco.repo.domain.hibernate.NodeImpl"
lazy="false"
fetch="join"
not-null="true" >
<column name="source_node_id" />
</many-to-one>
<!-- forward assoc to target node -->
<many-to-one
name="target"
class="org.alfresco.repo.domain.hibernate.NodeImpl"
lazy="false"
fetch="join"
not-null="true" >
<column name="target_node_id" />
</many-to-one>
<property name="typeQName" column="type_qname" type="QName" length="255" not-null="true" />
</natural-id>
</class>
<query name="store.GetAllStores">

View File

@@ -16,7 +16,6 @@
*/
package org.alfresco.repo.domain.hibernate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
@@ -34,6 +33,7 @@ import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.repo.domain.Store;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.EqualsHelper;
/**
* Bean containing all the persistence data representing a <b>node</b>.
@@ -65,10 +65,10 @@ public class NodeImpl extends LifecycleAdapter implements Node
public NodeImpl()
{
aspects = new HashSet<QName>(5);
sourceNodeAssocs = new ArrayList<NodeAssoc>(3);
targetNodeAssocs = new ArrayList<NodeAssoc>(3);
parentAssocs = new ArrayList<ChildAssoc>(3);
childAssocs = new ArrayList<ChildAssoc>(3);
sourceNodeAssocs = new HashSet<NodeAssoc>(5);
targetNodeAssocs = new HashSet<NodeAssoc>(5);
parentAssocs = new HashSet<ChildAssoc>(5);
childAssocs = new HashSet<ChildAssoc>(11);
properties = new HashMap<QName, PropertyValue>(5);
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
@@ -134,12 +134,13 @@ public class NodeImpl extends LifecycleAdapter implements Node
return false;
}
Node that = (Node) obj;
return (this.getNodeRef().equals(that.getNodeRef()));
return (EqualsHelper.nullSafeEquals(getStore(), that.getStore())
&& EqualsHelper.nullSafeEquals(getUuid(), that.getUuid()));
}
public int hashCode()
{
return getNodeRef().hashCode();
return getUuid().hashCode();
}
// @Override
@@ -316,11 +317,7 @@ public class NodeImpl extends LifecycleAdapter implements Node
return accessControlList;
}
/**
* For Hibernate use
*/
@SuppressWarnings("unused")
private void setAccessControlList(DbAccessControlList accessControlList)
public void setAccessControlList(DbAccessControlList accessControlList)
{
this.accessControlList = accessControlList;
}

View File

@@ -26,6 +26,16 @@
not-null="true">
<column name="node_id" />
</many-to-one>
<set name="entries"
inverse="true"
lazy="false"
cascade="delete"
optimistic-lock="true"
fetch="join" >
<key column="acl_id" />
<one-to-many class="org.alfresco.repo.domain.hibernate.DbAccessControlEntryImpl" />
</set>
<property name="inherits" column="inherits" type="boolean" not-null="true" />
@@ -47,29 +57,29 @@
<natural-id mutable="true" >
<many-to-one
name="accessControlList"
class="org.alfresco.repo.domain.hibernate.DbAccessControlListImpl"
column="acl_id"
lazy="no-proxy"
fetch="select"
optimistic-lock="true"
not-null="true" />
name="accessControlList"
class="org.alfresco.repo.domain.hibernate.DbAccessControlListImpl"
column="acl_id"
lazy="no-proxy"
fetch="select"
optimistic-lock="true"
not-null="true" />
<many-to-one
name="permission"
class="org.alfresco.repo.domain.hibernate.DbPermissionImpl"
column="permission_id"
lazy="no-proxy"
fetch="select"
optimistic-lock="true"
not-null="true" />
name="permission"
class="org.alfresco.repo.domain.hibernate.DbPermissionImpl"
column="permission_id"
lazy="no-proxy"
fetch="select"
optimistic-lock="true"
not-null="true" />
<many-to-one
name="authority"
class="org.alfresco.repo.domain.hibernate.DbAuthorityImpl"
column="authority_id"
lazy="no-proxy"
fetch="select"
optimistic-lock="true"
not-null="true" />
name="authority"
class="org.alfresco.repo.domain.hibernate.DbAuthorityImpl"
column="authority_id"
lazy="no-proxy"
fetch="select"
optimistic-lock="true"
not-null="true" />
</natural-id>
<property name="allowed" column="allowed" type="boolean" not-null="true" />
@@ -83,7 +93,7 @@
dynamic-insert="false"
dynamic-update="false"
select-before-update="false"
lazy="true"
lazy="false"
optimistic-lock="version" >
<id name="id" column="id" type="long" >
@@ -104,7 +114,7 @@
dynamic-insert="false"
dynamic-update="false"
select-before-update="false"
lazy="true"
lazy="false"
optimistic-lock="version" >
<id name="recipient" column="recipient" type="string" length="100" />
@@ -133,24 +143,6 @@
permission.name = :permissionName
</query>
<query name="permission.GetAccessControlEntriesForAccessControlList" cacheable="true" >
select
ace
from
org.alfresco.repo.domain.hibernate.DbAccessControlEntryImpl as ace
where
ace.accessControlList.id = :accessControlListId
</query>
<query name="permission.GetAccessControlEntriesForPermission">
select
ace
from
org.alfresco.repo.domain.hibernate.DbAccessControlEntryImpl as ace
where
ace.permission.id = :permissionId
</query>
<query name="permission.GetAccessControlEntriesForAuthority">
select
ace
@@ -160,41 +152,4 @@
ace.authority.recipient = :authorityRecipient
</query>
<query name="permission.GetAccessControlEntriesForAuthorityAndNode">
select
ace
from
org.alfresco.repo.domain.hibernate.DbAccessControlEntryImpl as ace
where
ace.authority.recipient = :authorityRecipient and
ace.accessControlList.node.store.key.protocol = :storeProtocol and
ace.accessControlList.node.store.key.identifier = :storeIdentifier and
ace.accessControlList.node.uuid = :nodeUuid
</query>
<query name="permission.GetAccessControlEntryForAll">
select
ace
from
org.alfresco.repo.domain.hibernate.DbAccessControlEntryImpl as ace
where
ace.permission.typeQname = :permissionTypeQName and
ace.permission.name = :permissionName and
ace.authority.recipient = :authorityRecipient and
ace.accessControlList.node.store.key.protocol = :storeProtocol and
ace.accessControlList.node.store.key.identifier = :storeIdentifier and
ace.accessControlList.node.uuid = :nodeUuid
</query>
<query name="permission.GetAccessControlListForNode" cacheable="true" >
select
acl
from
org.alfresco.repo.domain.hibernate.DbAccessControlListImpl as acl
where
acl.node.store.key.protocol = :storeProtocol and
acl.node.store.key.identifier = :storeIdentifier and
acl.node.uuid = :nodeUuid
</query>
</hibernate-mapping>

View File

@@ -16,16 +16,16 @@
*/
package org.alfresco.repo.domain.hibernate;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.domain.DbAccessControlEntry;
import org.alfresco.repo.domain.DbAccessControlList;
import org.alfresco.repo.domain.DbAuthority;
import org.alfresco.repo.domain.DbPermission;
import org.alfresco.repo.domain.DbPermissionKey;
import org.alfresco.repo.domain.Node;
import org.alfresco.repo.node.db.NodeDaoService;
import org.alfresco.repo.security.permissions.NodePermissionEntry;
@@ -55,16 +55,12 @@ import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
*/
public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements PermissionsDaoComponent
{
private static final boolean INHERIT_PERMISSIONS_DEFAULT = true;
public static final String QUERY_GET_PERMISSION = "permission.GetPermission";
public static final String QUERY_GET_AC_LIST_FOR_NODE = "permission.GetAccessControlListForNode";
public static final String QUERY_GET_AC_ENTRIES_FOR_AC_LIST = "permission.GetAccessControlEntriesForAccessControlList";
public static final String QUERY_GET_AC_ENTRIES_FOR_AUTHORITY = "permission.GetAccessControlEntriesForAuthority";
public static final String QUERY_GET_AC_ENTRIES_FOR_PERMISSION = "permission.GetAccessControlEntriesForPermission";
public static final String QUERY_GET_AC_ENTRIES_FOR_AUTHORITY_AND_NODE = "permission.GetAccessControlEntriesForAuthorityAndNode";
public static final String QUERY_GET_AC_ENTRY_FOR_ALL = "permission.GetAccessControlEntryForAll";
private NodeDaoService nodeDaoService;
private SimpleCache<NodeRef, SimpleNodePermissionEntry> nullPermissionCache;
public PermissionsDaoComponentImpl()
{
@@ -76,11 +72,6 @@ public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements
this.nodeDaoService = nodeDaoService;
}
public void setNullPermissionCache(SimpleCache<NodeRef, SimpleNodePermissionEntry> nullPermissionCache)
{
this.nullPermissionCache = nullPermissionCache;
}
public NodePermissionEntry getPermissions(NodeRef nodeRef)
{
// Create the object if it is not found.
@@ -88,20 +79,22 @@ public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements
// If the object does not exist it will repeatedly query to check its
// non existence.
NodePermissionEntry npe = nullPermissionCache.get(nodeRef);
if (npe != null)
NodePermissionEntry npe = null;
DbAccessControlList acl = null;
Node node = getNode(nodeRef, false);
if (node != null)
{
return npe;
// get the persisted version
acl = getAccessControlList(node, false);
}
// get the persisted version
DbAccessControlList acl = getAccessControlList(nodeRef, false);
if (acl == null)
{
// there isn't an access control list for the node - spoof a null one
SimpleNodePermissionEntry snpe = new SimpleNodePermissionEntry(
nodeRef, true, Collections.<SimplePermissionEntry> emptySet());
nodeRef,
true,
Collections.<SimplePermissionEntry> emptySet());
npe = snpe;
nullPermissionCache.put(nodeRef, snpe);
}
else
{
@@ -122,46 +115,18 @@ public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements
* @param create - create the object if it is missing
* @return Returns the current access control list or null if not found
*/
private DbAccessControlList getAccessControlList(final NodeRef nodeRef, boolean create)
private DbAccessControlList getAccessControlList(Node node, boolean create)
{
// get the access control list for the node
HibernateCallback callback = new HibernateCallback()
DbAccessControlList acl = node.getAccessControlList();
if (acl == null && create)
{
public Object doInHibernate(Session session)
{
Query query = session.getNamedQuery(PermissionsDaoComponentImpl.QUERY_GET_AC_LIST_FOR_NODE);
query.setString("storeProtocol", nodeRef.getStoreRef().getProtocol())
.setString("storeIdentifier", nodeRef.getStoreRef().getIdentifier())
.setString("nodeUuid", nodeRef.getId());
return query.list();
}
};
@SuppressWarnings("unchecked")
List<DbAccessControlList> results = (List<DbAccessControlList>) getHibernateTemplate().execute(callback);
DbAccessControlList acl = null;
if (results.size() == 0)
{
// create it
if (create)
{
acl = createAccessControlList(nodeRef);
}
// else null will be returned
}
else if (results.size() > 0)
{
acl = (DbAccessControlList) results.get(0);
}
else if (results.size() > 1)
{
logger.warn("Duplicate access control lists for node: " + nodeRef);
acl = (DbAccessControlList) results.get(0);
acl = createAccessControlList(node);
}
// done
if (logger.isDebugEnabled())
{
logger.debug("Retrieved access control list: \n" +
" node: " + nodeRef + "\n" +
" node: " + node.getNodeRef() + "\n" +
" list: " + acl);
}
return acl;
@@ -171,17 +136,17 @@ public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements
* Creates an access control list for the node and removes the entry from
* the nullPermsionCache.
*/
private DbAccessControlList createAccessControlList(final NodeRef nodeRef)
private DbAccessControlList createAccessControlList(Node node)
{
// get the node referenced
Node node = getNode(nodeRef);
DbAccessControlList acl = new DbAccessControlListImpl();
acl.setNode(node);
acl.setInherits(true);
acl.setInherits(INHERIT_PERMISSIONS_DEFAULT);
getHibernateTemplate().save(acl);
nullPermissionCache.remove(nodeRef);
// maintain inverse
node.setAccessControlList(acl);
NodeRef nodeRef = node.getNodeRef();
// done
if (logger.isDebugEnabled())
@@ -195,12 +160,14 @@ public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements
/**
* @param nodeRef the node reference
* @return Returns the node for the given reference, or null
* @param mustExist true if an exception must be thrown if the node does not exist
* @return Returns the node for the given reference, or null if <code>mustExist == false</code>
* @throws InvalidNodeRefException if the node must exist but doesn't
*/
private Node getNode(NodeRef nodeRef)
private Node getNode(NodeRef nodeRef, boolean mustExist)
{
Node node = nodeDaoService.getNode(nodeRef);
if (node == null)
if (node == null && mustExist)
{
throw new InvalidNodeRefException(nodeRef);
}
@@ -209,17 +176,25 @@ public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements
public void deletePermissions(NodeRef nodeRef)
{
DbAccessControlList acl = getAccessControlList(nodeRef, false);
Node node = getNode(nodeRef, false);
if (node == null)
{
return;
}
DbAccessControlList acl = getAccessControlList(node, false);
if (acl != null)
{
// delete the access control list - it will cascade to the entries
getHibernateTemplate().delete(acl);
// maintain inverse
node.setAccessControlList(null);
}
}
@SuppressWarnings("unchecked")
public void deletePermissions(final String authority)
{
// get the authority
HibernateCallback callback = new HibernateCallback()
{
public Object doInHibernate(Session session)
@@ -227,7 +202,7 @@ public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements
Query query = session
.getNamedQuery(QUERY_GET_AC_ENTRIES_FOR_AUTHORITY)
.setString("authorityRecipient", authority);
return (Integer) HibernateHelper.deleteQueryResults(session, query);
return (Integer) HibernateHelper.deleteDbAccessControlEntries(session, query);
}
};
Integer deletedCount = (Integer) getHibernateTemplate().execute(callback);
@@ -240,20 +215,17 @@ public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements
public void deletePermissions(final NodeRef nodeRef, final String authority)
{
HibernateCallback callback = new HibernateCallback()
Node node = getNode(nodeRef, false);
if (node == null)
{
public Object doInHibernate(Session session)
{
Query query = session
.getNamedQuery(QUERY_GET_AC_ENTRIES_FOR_AUTHORITY_AND_NODE)
.setString("authorityRecipient", authority)
.setString("storeProtocol", nodeRef.getStoreRef().getProtocol())
.setString("storeIdentifier", nodeRef.getStoreRef().getIdentifier())
.setString("nodeUuid", nodeRef.getId());
return HibernateHelper.deleteQueryResults(session, query);
}
};
Integer deletedCount = (Integer) getHibernateTemplate().execute(callback);
return;
}
DbAccessControlList acl = node.getAccessControlList();
int deletedCount = 0;
if (acl != null)
{
deletedCount = acl.deleteEntriesForAuthority(authority);
}
// done
if (logger.isDebugEnabled())
{
@@ -268,40 +240,43 @@ public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements
* the given criteria. Note that the access control list for the node is
* not deleted.
*/
public void deletePermission(final NodeRef nodeRef, final String authority, final PermissionReference permission)
public void deletePermission(NodeRef nodeRef, String authority, PermissionReference permission)
{
// get the entry
DbAccessControlEntry entry = getAccessControlEntry(nodeRef, authority, permission);
if (entry != null)
Node node = getNode(nodeRef, false);
if (node == null)
{
getHibernateTemplate().delete(entry);
// done
if (logger.isDebugEnabled())
{
logger.debug("Deleted entry for criteria: \n" +
" node: " + nodeRef + "\n" +
" authority: " + authority + "\n" +
" permission: " + permission);
}
return;
}
DbAccessControlList acl = node.getAccessControlList();
int deletedCount = 0;
if (acl != null)
{
DbPermissionKey permissionKey = new DbPermissionKey(permission.getQName(), permission.getName());
deletedCount = acl.deleteEntry(authority, permissionKey);
}
// done
if (logger.isDebugEnabled())
{
logger.debug("Deleted " + deletedCount + "entries for criteria: \n" +
" node: " + nodeRef + "\n" +
" permission: " + permission + "\n" +
" authority: " + authority);
}
}
public void setPermission(NodeRef nodeRef, String authority, PermissionReference permission, boolean allow)
{
Node node = getNode(nodeRef, true);
// get the entry
DbAccessControlEntry entry = getAccessControlEntry(nodeRef, authority, permission);
DbAccessControlEntry entry = getAccessControlEntry(node, authority, permission);
if (entry == null)
{
// need to create it
DbAccessControlList dbAccessControlList = getAccessControlList(nodeRef, true);
DbAccessControlList dbAccessControlList = getAccessControlList(node, true);
DbPermission dbPermission = getPermission(permission, true);
DbAuthority dbAuthority = getAuthority(authority, true);
// set persistent objects
entry = DbAccessControlEntryImpl.create(dbAccessControlList, dbPermission, dbAuthority, allow);
// save it
getHibernateTemplate().save(entry);
// drop the entry from the null cache
nullPermissionCache.remove(nodeRef);
entry = dbAccessControlList.newEntry(dbPermission, dbAuthority, allow);
// done
if (logger.isDebugEnabled())
{
@@ -326,31 +301,22 @@ public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements
* @return Returns all access control entries that match the criteria
*/
private DbAccessControlEntry getAccessControlEntry(
final NodeRef nodeRef,
final String authority,
final PermissionReference permission)
Node node,
String authority,
PermissionReference permission)
{
HibernateCallback callback = new HibernateCallback()
DbAccessControlList acl = getAccessControlList(node, false);
DbAccessControlEntry entry = null;
if (acl != null)
{
public Object doInHibernate(Session session)
{
Query query = session
.getNamedQuery(QUERY_GET_AC_ENTRY_FOR_ALL)
.setString("permissionTypeQName", permission.getQName().toString())
.setString("permissionName", permission.getName())
.setString("authorityRecipient", authority)
.setString("storeProtocol", nodeRef.getStoreRef().getProtocol())
.setString("storeIdentifier", nodeRef.getStoreRef().getIdentifier())
.setString("nodeUuid", nodeRef.getId());
return (DbAccessControlEntry) query.uniqueResult();
}
};
DbAccessControlEntry entry = (DbAccessControlEntry) getHibernateTemplate().execute(callback);
DbPermissionKey permissionKey = new DbPermissionKey(permission.getQName(), permission.getName());
entry = acl.getEntry(authority, permissionKey);
}
// done
if (logger.isDebugEnabled())
{
logger.debug("" + (entry == null ? "Did not find" : "Found") + "entry for criteria: \n" +
" node: " + nodeRef + "\n" +
" node: " + node.getId() + "\n" +
" authority: " + authority + "\n" +
" permission: " + permission);
}
@@ -383,15 +349,9 @@ public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements
{
final QName qname = permissionRef.getQName();
final String name = permissionRef.getName();
Session session = getSession();
HibernateCallback callback = new HibernateCallback()
{
public Object doInHibernate(Session session)
{
return DbPermissionImpl.find(session, qname, name);
}
};
DbPermission dbPermission = (DbPermission) getHibernateTemplate().execute(callback);
DbPermission dbPermission = DbPermissionImpl.find(session, qname, name);
// create if necessary
if ((dbPermission == null) && create)
@@ -416,24 +376,21 @@ public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements
public void setPermission(NodePermissionEntry nodePermissionEntry)
{
NodeRef nodeRef = nodePermissionEntry.getNodeRef();
// get the access control list
DbAccessControlList acl = getAccessControlList(nodeRef, false);
if (acl == null)
Node node = getNode(nodeRef, true);
// Get the access control list
// Note the logic here requires to know whether it was created or not
DbAccessControlList acl = getAccessControlList(node, false);
if (acl != null)
{
// create the access control list
acl = createAccessControlList(nodeRef);
}
else
{
// remove entries associated with the list
int deleted = acl.deleteEntries();
if (logger.isDebugEnabled())
{
logger.debug("Deleted " + deleted + " entries for access control list: \n" +
" acl: " + acl);
}
getSession().flush();
// drop the list
getHibernateTemplate().delete(acl);
// update node
node.setAccessControlList(null);
}
// create the access control list
acl = createAccessControlList(node);
// set attributes
acl.setInherits(nodePermissionEntry.inheritPermissions());
@@ -447,24 +404,41 @@ public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements
DbPermission permissionEntity = getPermission(permission, true);
DbAuthority authorityEntity = getAuthority(authority, true);
DbAccessControlEntryImpl entry = DbAccessControlEntryImpl.create(
acl,
permissionEntity,
authorityEntity,
isAllowed);
getHibernateTemplate().save(entry);
@SuppressWarnings("unused")
DbAccessControlEntryImpl entry = acl.newEntry(permissionEntity, authorityEntity, isAllowed);
}
}
public void setInheritParentPermissions(NodeRef nodeRef, boolean inheritParentPermissions)
{
DbAccessControlList acl = getAccessControlList(nodeRef, true);
acl.setInherits(inheritParentPermissions);
Node node = getNode(nodeRef, true);
DbAccessControlList acl = null;
if (!inheritParentPermissions)
{
// Inheritance == true is the default, so only force a create of the ACL if the value false
acl = getAccessControlList(node, true);
acl.setInherits(false);
}
else
{
acl = getAccessControlList(node, false);
if (acl != null)
{
acl.setInherits(true);
}
}
}
public boolean getInheritParentPermissions(NodeRef nodeRef)
{
DbAccessControlList acl = getAccessControlList(nodeRef, false);
Node node = getNode(nodeRef, false);
if (node == null)
{
return INHERIT_PERMISSIONS_DEFAULT;
}
DbAccessControlList acl = getAccessControlList(node, false);
if (acl == null)
{
return true;
@@ -484,46 +458,19 @@ public class PermissionsDaoComponentImpl extends HibernateDaoSupport implements
{
ParameterCheck.mandatory("acl", acl);
}
List<DbAccessControlEntry> entries = getEntriesForList(acl);
Set<DbAccessControlEntry> entries = acl.getEntries();
SimpleNodePermissionEntry snpe = new SimpleNodePermissionEntry(
acl.getNode().getNodeRef(),
acl.getInherits(),
createSimplePermissionEntries(entries));
return snpe;
}
/**
* Executes a query to retrieve the access control list's entries
*
* @param acl the access control list
* @return Returns a list of the entries
*/
@SuppressWarnings("unchecked")
private List<DbAccessControlEntry> getEntriesForList(final DbAccessControlList acl)
{
HibernateCallback callback = new HibernateCallback()
{
public Object doInHibernate(Session session)
{
Query query = session.getNamedQuery(QUERY_GET_AC_ENTRIES_FOR_AC_LIST);
query.setLong("accessControlListId", acl.getId());
return query.list();
}
};
List<DbAccessControlEntry> entries = (List<DbAccessControlEntry>) getHibernateTemplate().execute(callback);
// done
if (logger.isDebugEnabled())
{
logger.debug("Found " + entries.size() + " entries for access control list " + acl.getId());
}
return entries;
}
/**
* @param entries access control entries
* @return Returns a unique set of entries that can be given back to the outside world
*/
private Set<SimplePermissionEntry> createSimplePermissionEntries(List<DbAccessControlEntry> entries)
private Set<SimplePermissionEntry> createSimplePermissionEntries(Collection<DbAccessControlEntry> entries)
{
if (entries == null)
{

View File

@@ -23,9 +23,9 @@
<many-to-one
name="rootNode"
not-null="true"
lazy="false"
lazy="proxy"
class="org.alfresco.repo.domain.hibernate.NodeImpl"
fetch="join" >
fetch="select" >
<column name="root_node_id" />
</many-to-one>
</class>

View File

@@ -123,7 +123,7 @@ public class StoreImpl implements Store
return key;
}
public synchronized void setKey(StoreKey key)
public void setKey(StoreKey key)
{
refWriteLock.lock();
try

View File

@@ -49,7 +49,6 @@ import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ApplicationContextHelper;
import org.alfresco.util.TempFileProvider;
import org.alfresco.util.TestWithUserUtils;
import org.springframework.context.ApplicationContext;
@@ -196,10 +195,6 @@ public class FileImporterTest extends TestCase
String userPwd = args.length > 6 ? args[6] : "";
while (count < target)
{
File directory = TempFileProvider.getTempDir();
File[] files = directory.listFiles();
System.out.println("Start temp file count = " + files.length);
count++;
FileImporterTest test = new FileImporterTest();
test.setUp();
@@ -268,15 +263,9 @@ public class FileImporterTest extends TestCase
System.out.println("Committed in: " + ((end - start) / 1000000.0) + "ms");
double total = ((first+second)/1000000.0);
System.out.println("Grand Total: "+ grandTotal);
System.out.println("Count: "+ count + "ms");
System.out.println("Imported: " + importCount + " files or directories");
System.out.println("Average: " + (importCount / (total / 1000.0)) + " files per second");
directory = TempFileProvider.getTempDir();
files = directory.listFiles();
System.out.println("End temp file count = " + files.length);
tx = transactionService.getUserTransaction();
tx.begin();
SearchParameters sp = new SearchParameters();

View File

@@ -165,11 +165,11 @@ public class ArchiveAndRestoreTest extends TestCase
* Create the following:
* <pre>
* root
* / | \
* / | \
* / | \
* / | \
* A <-> B X
* / |
* / |
* / |
* / |
* A <-> B
* |\ /|
* | \ / |
* | \/ |
@@ -500,6 +500,17 @@ public class ArchiveAndRestoreTest extends TestCase
txn.begin();
}
public void testRestoreToMissingParent() throws Exception
{
nodeService.deleteNode(a);
nodeService.deleteNode(b);
commitAndBeginNewTransaction();
// attempt to restore b_ to a
RestoreNodeReport report = nodeArchiveService.restoreArchivedNode(b_, a, null, null);
assertEquals("Incorrect report status", RestoreStatus.FAILURE_INVALID_PARENT, report.getStatus());
}
public void testMassRestore() throws Exception
{
nodeService.deleteNode(a);

View File

@@ -21,8 +21,10 @@ import java.util.List;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.node.archive.RestoreNodeReport.RestoreStatus;
import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.repo.transaction.TransactionUtil;
import org.alfresco.repo.transaction.TransactionUtil.TransactionWork;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
@@ -133,13 +135,34 @@ public class NodeArchiveServiceImpl implements NodeArchiveService
{
report.setStatus(RestoreStatus.FAILURE_INVALID_PARENT);
}
else if (destinationNodeRef == null)
{
// get the original parent of the archived node
ChildAssociationRef originalParentAssocRef = (ChildAssociationRef) nodeService.getProperty(
archivedNodeRef,
ContentModel.PROP_ARCHIVED_ORIGINAL_PARENT_ASSOC);
NodeRef originalParentNodeRef = originalParentAssocRef.getParentRef();
if (EqualsHelper.nullSafeEquals(originalParentNodeRef, invalidNodeRef))
{
report.setStatus(RestoreStatus.FAILURE_INVALID_PARENT);
}
else
{
// some other invalid node was detected
report.setStatus(RestoreStatus.FAILURE_OTHER);
}
}
else
{
// some other invalid node was detected
report.setStatus(RestoreStatus.FAILURE_OTHER);
}
}
// TODO: Catch permission exceptions
catch (AccessDeniedException e)
{
report.setCause(e);
report.setStatus(RestoreStatus.FAILURE_PERMISSION);
}
catch (Throwable e)
{
report.setCause(e);

View File

@@ -409,19 +409,24 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
// get the old parent
Node oldParentNode = oldAssoc.getParent();
// Invoke policy behaviour
invokeBeforeDeleteChildAssociation(oldAssocRef);
invokeBeforeCreateChildAssociation(newParentRef, nodeToMoveRef, assocTypeQName, assocQName);
invokeBeforeUpdateNode(oldParentNode.getNodeRef()); // old parent will be updated
invokeBeforeUpdateNode(newParentRef); // new parent ditto
boolean movingStore = !nodeToMoveRef.getStoreRef().equals(newParentRef.getStoreRef());
// If the node is moving stores, then drag the node hierarchy with it
if (!nodeToMoveRef.getStoreRef().equals(newParentRef.getStoreRef()))
// data needed for policy invocation
QName nodeToMoveTypeQName = nodeToMove.getTypeQName();
Set<QName> nodeToMoveAspects = nodeToMove.getAspects();
// Invoke policy behaviour
if (movingStore)
{
Store newStore = newParentNode.getStore();
moveNodeToStore(nodeToMove, newStore);
// the node reference will have changed too
nodeToMoveRef = nodeToMove.getNodeRef();
invokeBeforeDeleteNode(nodeToMoveRef);
invokeBeforeCreateNode(newParentRef, assocTypeQName, assocQName, nodeToMoveTypeQName);
}
else
{
invokeBeforeDeleteChildAssociation(oldAssocRef);
invokeBeforeCreateChildAssociation(newParentRef, nodeToMoveRef, assocTypeQName, assocQName);
invokeBeforeUpdateNode(oldParentNode.getNodeRef()); // old parent will be updated
invokeBeforeUpdateNode(newParentRef); // new parent ditto
}
// remove the child assoc from the old parent
@@ -430,14 +435,32 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
// create a new assoc
ChildAssoc newAssoc = nodeDaoService.newChildAssoc(newParentNode, nodeToMove, true, assocTypeQName, assocQName);
// If the node is moving stores, then drag the node hierarchy with it
if (movingStore)
{
// do the move
Store newStore = newParentNode.getStore();
moveNodeToStore(nodeToMove, newStore);
// the node reference will have changed too
nodeToMoveRef = nodeToMove.getNodeRef();
}
// check that no cyclic relationships have been created
getPaths(nodeToMoveRef, false);
// invoke policy behaviour
invokeOnCreateChildAssociation(newAssoc.getChildAssocRef());
invokeOnDeleteChildAssociation(oldAssoc.getChildAssocRef());
invokeOnUpdateNode(oldParentNode.getNodeRef());
invokeOnUpdateNode(newParentRef);
if (movingStore)
{
invokeOnDeleteNode(oldAssocRef, nodeToMoveTypeQName, nodeToMoveAspects);
invokeOnCreateNode(newAssoc.getChildAssocRef());
}
else
{
invokeOnCreateChildAssociation(newAssoc.getChildAssocRef());
invokeOnDeleteChildAssociation(oldAssoc.getChildAssocRef());
invokeOnUpdateNode(oldParentNode.getNodeRef());
invokeOnUpdateNode(newParentRef);
}
// update the node status
nodeDaoService.recordChangeId(nodeToMoveRef);
@@ -1342,11 +1365,12 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
nodeToMove.setStore(store);
NodeRef newNodeRef = nodeToMove.getNodeRef();
// update change statuses
String txnId = AlfrescoTransactionSupport.getTransactionId();
// update old status
NodeStatus oldNodeStatus = nodeDaoService.getNodeStatus(oldNodeRef, true);
oldNodeStatus.setNode(null);
oldNodeStatus.setChangeTxnId(txnId);
// create the new status
NodeStatus newNodeStatus = nodeDaoService.getNodeStatus(newNodeRef, true);
newNodeStatus.setNode(nodeToMove);
newNodeStatus.setChangeTxnId(txnId);

View File

@@ -181,6 +181,23 @@ public class PermissionServiceTest extends AbstractPermissionTest
testSetNodePermissionEntry();
testSetNodePermissionEntry2();
}
public void testDoubleSetAllowDeny()
{
Set<? extends PermissionEntry> permissionEntries = null;
// add-remove andy-all
permissionService.setPermission(rootNodeRef, "andy", permissionService.getAllPermission(), true);
permissionService.setPermission(rootNodeRef, "andy", permissionService.getAllPermission(), false);
permissionService.deletePermission(rootNodeRef, "andy", permissionService.getAllPermission());
permissionEntries = permissionService.getSetPermissions(rootNodeRef).getPermissionEntries();
assertEquals(0, permissionEntries.size());
// add-remove andy-read
permissionService.setPermission(rootNodeRef, "andy", PermissionService.READ, true);
permissionService.setPermission(rootNodeRef, "andy", PermissionService.READ, false);
permissionService.deletePermission(rootNodeRef, "andy", PermissionService.READ);
permissionEntries = permissionService.getSetPermissions(rootNodeRef).getPermissionEntries();
assertEquals(0, permissionEntries.size());
}
public void testSetPermissionEntryElements()
{

View File

@@ -119,13 +119,6 @@ public class HibernatePermissionTest extends BaseSpringTest
// throw the reference away and get the a new one for the id
permission = (DbPermission) getSession().load(DbPermissionImpl.class, id);
assertNotNull("Permission not found", permission);
assertEquals("Test", permission.getName());
assertEquals(qname, permission.getTypeQname());
// Test key
permission = (DbPermission) getSession().load(DbPermissionImpl.class, id);
assertNotNull("Permission not found", permission);
assertEquals("Test", permission.getName());
assertEquals(qname, permission.getTypeQname());
}
@@ -175,29 +168,29 @@ public class HibernatePermissionTest extends BaseSpringTest
DbAccessControlList accessControlList = new DbAccessControlListImpl();
accessControlList.setNode(node);
accessControlList.setInherits(true);
Serializable nodeAclId = getSession().save(accessControlList);
DbAuthority recipient = new DbAuthorityImpl();
recipient.setRecipient("Test");
recipient.getExternalKeys().add("One");
getSession().save(recipient);
DbPermission permission = new DbPermissionImpl();
permission.setTypeQname(qname);
permission.setName("Test");
DbAccessControlEntry accessControlEntry = DbAccessControlEntryImpl.create(accessControlList, permission, recipient, true);
Serializable nodeAclId = getSession().save(accessControlList);
getSession().save(recipient);
getSession().save(permission);
Serializable aceEntryId = getSession().save(accessControlEntry);
accessControlEntry = (DbAccessControlEntry) getSession().load(DbAccessControlEntryImpl.class, aceEntryId);
DbAccessControlEntry accessControlEntry = accessControlList.newEntry(permission, recipient, true);
Long aceEntryId = accessControlEntry.getId();
assertNotNull("Entry is still transient", aceEntryId);
accessControlEntry = (DbAccessControlEntry) getSession().load(DbAccessControlEntryImpl.class, aceEntryId);
assertNotNull("Permission entry not found", accessControlEntry);
assertTrue(accessControlEntry.isAllowed());
assertNotNull(accessControlEntry.getAccessControlList());
assertTrue(accessControlEntry.getAccessControlList().getInherits());
assertNotNull(accessControlEntry.getPermission());
assertEquals("Test", accessControlEntry.getPermission().getName());
assertEquals("Test", accessControlEntry.getPermission().getKey().getName());
assertNotNull(accessControlEntry.getAuthority());
assertEquals("Test", accessControlEntry.getAuthority().getRecipient());
assertEquals(1, accessControlEntry.getAuthority().getExternalKeys().size());

View File

@@ -253,11 +253,14 @@ public class StoreRedirectorProxyFactory<I> implements FactoryBean, Initializing
// Only allow one store type
if (argStoreRef != null)
{
if (storeRef != null && !storeRef.equals(argStoreRef))
{
throw new ServiceException("Multiple store types are not supported - types " + storeRef + " and " + argStoreRef + " passed");
}
storeRef = argStoreRef;
// TODO: put some thought into the ramifications of allowing cross-store moves
// TODO: The test here would only have checked storerefs adjacent to each other
// if (storeRef != null && !storeRef.equals(argStoreRef))
// {
// throw new ServiceException("Multiple store types are not supported - types " + storeRef + " and " + argStoreRef + " passed");
// }
// storeRef = argStoreRef;
return argStoreRef;
}
}

View File

@@ -16,6 +16,10 @@
*/
package org.alfresco.service.cmr.action;
import java.util.List;
import org.alfresco.service.namespace.QName;
/**
@@ -25,5 +29,10 @@ package org.alfresco.service.cmr.action;
*/
public interface ActionDefinition extends ParameterizedItemDefinition
{
/**
* Gets a list of the types that this action item is applicable for
*
* @return list of types
*/
public List<QName> getApplicableTypes();
}

View File

@@ -43,6 +43,15 @@ public interface ActionService
* @return the list action definitions
*/
List<ActionDefinition> getActionDefinitions();
/**
* Get all the action definitions that are applicable for the given node, based on
* its type and aspects.
*
* @param nodeRef the node reference
* @return a list of applicable action definitions
*/
List<ActionDefinition> getActionDefinitions(NodeRef nodeRef);
/**
* Get a named action condition definition