mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
. Tree Navigator performance improvement
- explicit txns around multiple nodeservice calls and internal (permission check free) nodeservice to retrieve node names - 25% improvement to retrieving node lists . Permission code hotspot tuning and nodeservice methods ACL configuration tuning git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@4960 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -8,6 +8,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
import javax.faces.context.FacesContext;
|
import javax.faces.context.FacesContext;
|
||||||
import javax.faces.context.ResponseWriter;
|
import javax.faces.context.ResponseWriter;
|
||||||
|
import javax.transaction.UserTransaction;
|
||||||
|
|
||||||
import org.alfresco.model.ApplicationModel;
|
import org.alfresco.model.ApplicationModel;
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
@@ -47,6 +48,7 @@ public class NavigatorPluginBean implements IContextListener
|
|||||||
protected NodeRef previouslySelectedNode;
|
protected NodeRef previouslySelectedNode;
|
||||||
|
|
||||||
private NodeService nodeService;
|
private NodeService nodeService;
|
||||||
|
private NodeService internalNodeService;
|
||||||
private DictionaryService dictionaryService;
|
private DictionaryService dictionaryService;
|
||||||
|
|
||||||
private static final Log logger = LogFactory.getLog(NavigatorPluginBean.class);
|
private static final Log logger = LogFactory.getLog(NavigatorPluginBean.class);
|
||||||
@@ -69,54 +71,68 @@ public class NavigatorPluginBean implements IContextListener
|
|||||||
FacesContext context = FacesContext.getCurrentInstance();
|
FacesContext context = FacesContext.getCurrentInstance();
|
||||||
ResponseWriter out = context.getResponseWriter();
|
ResponseWriter out = context.getResponseWriter();
|
||||||
|
|
||||||
Map params = context.getExternalContext().getRequestParameterMap();
|
UserTransaction tx = null;
|
||||||
String nodeRefStr = (String)params.get("nodeRef");
|
try
|
||||||
String area = (String)params.get("area");
|
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
|
||||||
logger.debug("retrieveChildren: area = " + area + ", nodeRef = " + nodeRefStr);
|
|
||||||
|
|
||||||
// work out which list to cache the nodes in
|
|
||||||
Map<String, TreeNode> currentNodes = getNodesMapForArea(area);
|
|
||||||
|
|
||||||
if (nodeRefStr != null && currentNodes != null)
|
|
||||||
{
|
{
|
||||||
// get the given node's details
|
tx = Repository.getUserTransaction(context, true);
|
||||||
NodeRef parentNodeRef = new NodeRef(nodeRefStr);
|
tx.begin();
|
||||||
TreeNode parentNode = currentNodes.get(parentNodeRef.toString());
|
|
||||||
parentNode.setExpanded(true);
|
Map params = context.getExternalContext().getRequestParameterMap();
|
||||||
|
String nodeRefStr = (String)params.get("nodeRef");
|
||||||
|
String area = (String)params.get("area");
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("retrieving children for noderef: " + parentNodeRef);
|
logger.debug("retrieveChildren: area = " + area + ", nodeRef = " + nodeRefStr);
|
||||||
|
|
||||||
// remove any existing children as the latest ones will be added below
|
// work out which list to cache the nodes in
|
||||||
parentNode.removeChildren();
|
Map<String, TreeNode> currentNodes = getNodesMapForArea(area);
|
||||||
|
|
||||||
// get all the child folder objects for the parent
|
if (nodeRefStr != null && currentNodes != null)
|
||||||
List<ChildAssociationRef> childRefs = this.nodeService.getChildAssocs(parentNodeRef,
|
|
||||||
ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
|
|
||||||
|
|
||||||
StringBuilder xml = new StringBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><nodes>");
|
|
||||||
for (ChildAssociationRef ref: childRefs)
|
|
||||||
{
|
{
|
||||||
NodeRef nodeRef = ref.getChildRef();
|
// get the given node's details
|
||||||
|
NodeRef parentNodeRef = new NodeRef(nodeRefStr);
|
||||||
|
TreeNode parentNode = currentNodes.get(parentNodeRef.toString());
|
||||||
|
parentNode.setExpanded(true);
|
||||||
|
|
||||||
if (isAddableChild(nodeRef))
|
if (logger.isDebugEnabled())
|
||||||
|
logger.debug("retrieving children for noderef: " + parentNodeRef);
|
||||||
|
|
||||||
|
// remove any existing children as the latest ones will be added below
|
||||||
|
parentNode.removeChildren();
|
||||||
|
|
||||||
|
// get all the child folder objects for the parent
|
||||||
|
List<ChildAssociationRef> childRefs = this.nodeService.getChildAssocs(parentNodeRef,
|
||||||
|
ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
|
||||||
|
|
||||||
|
StringBuilder xml = new StringBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><nodes>");
|
||||||
|
for (ChildAssociationRef ref: childRefs)
|
||||||
{
|
{
|
||||||
// build the XML representation of the child node
|
NodeRef nodeRef = ref.getChildRef();
|
||||||
TreeNode childNode = createTreeNode(nodeRef);
|
|
||||||
parentNode.addChild(childNode);
|
if (isAddableChild(nodeRef))
|
||||||
currentNodes.put(childNode.getNodeRef(), childNode);
|
{
|
||||||
xml.append(childNode.toXML());
|
// build the XML representation of the child node
|
||||||
|
TreeNode childNode = createTreeNode(nodeRef);
|
||||||
|
parentNode.addChild(childNode);
|
||||||
|
currentNodes.put(childNode.getNodeRef(), childNode);
|
||||||
|
xml.append(childNode.toXML());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
xml.append("</nodes>");
|
||||||
|
|
||||||
|
// send the generated XML back to the tree
|
||||||
|
out.write(xml.toString());
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
logger.debug("returning XML: " + xml.toString());
|
||||||
}
|
}
|
||||||
xml.append("</nodes>");
|
|
||||||
|
|
||||||
// send the generated XML back to the tree
|
// commit the transaction
|
||||||
out.write(xml.toString());
|
tx.commit();
|
||||||
|
}
|
||||||
if (logger.isDebugEnabled())
|
catch (Throwable err)
|
||||||
logger.debug("returning XML: " + xml.toString());
|
{
|
||||||
|
try { if (tx != null) {tx.rollback();} } catch (Exception tex) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,23 +279,36 @@ public class NavigatorPluginBean implements IContextListener
|
|||||||
this.companyHomeRootNodes = new ArrayList<TreeNode>();
|
this.companyHomeRootNodes = new ArrayList<TreeNode>();
|
||||||
this.companyHomeNodes = new HashMap<String, TreeNode>();
|
this.companyHomeNodes = new HashMap<String, TreeNode>();
|
||||||
|
|
||||||
// query for the child nodes of company home
|
UserTransaction tx = null;
|
||||||
NodeRef root = new NodeRef(Repository.getStoreRef(),
|
try
|
||||||
Application.getCompanyRootId());
|
|
||||||
List<ChildAssociationRef> childRefs = this.nodeService.getChildAssocs(root,
|
|
||||||
ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
|
|
||||||
|
|
||||||
for (ChildAssociationRef ref: childRefs)
|
|
||||||
{
|
{
|
||||||
NodeRef child = ref.getChildRef();
|
tx = Repository.getUserTransaction(FacesContext.getCurrentInstance(), true);
|
||||||
|
tx.begin();
|
||||||
|
|
||||||
if (isAddableChild(child))
|
// query for the child nodes of company home
|
||||||
|
NodeRef root = new NodeRef(Repository.getStoreRef(),
|
||||||
|
Application.getCompanyRootId());
|
||||||
|
List<ChildAssociationRef> childRefs = this.nodeService.getChildAssocs(root,
|
||||||
|
ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
|
||||||
|
|
||||||
|
for (ChildAssociationRef ref: childRefs)
|
||||||
{
|
{
|
||||||
TreeNode node = createTreeNode(child);
|
NodeRef child = ref.getChildRef();
|
||||||
this.companyHomeRootNodes.add(node);
|
|
||||||
this.companyHomeNodes.put(node.getNodeRef(), node);
|
if (isAddableChild(child))
|
||||||
|
{
|
||||||
|
TreeNode node = createTreeNode(child);
|
||||||
|
this.companyHomeRootNodes.add(node);
|
||||||
|
this.companyHomeNodes.put(node.getNodeRef(), node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
tx.commit();
|
||||||
|
}
|
||||||
|
catch (Throwable err)
|
||||||
|
{
|
||||||
|
try { if (tx != null) {tx.rollback();} } catch (Exception tex) {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.companyHomeRootNodes;
|
return this.companyHomeRootNodes;
|
||||||
@@ -300,24 +329,37 @@ public class NavigatorPluginBean implements IContextListener
|
|||||||
{
|
{
|
||||||
this.myHomeRootNodes = new ArrayList<TreeNode>();
|
this.myHomeRootNodes = new ArrayList<TreeNode>();
|
||||||
this.myHomeNodes = new HashMap<String, TreeNode>();
|
this.myHomeNodes = new HashMap<String, TreeNode>();
|
||||||
|
|
||||||
// query for the child nodes of the user's home
|
|
||||||
NodeRef root = new NodeRef(Repository.getStoreRef(),
|
|
||||||
Application.getCurrentUser(FacesContext.getCurrentInstance()).getHomeSpaceId());
|
|
||||||
List<ChildAssociationRef> childRefs = this.nodeService.getChildAssocs(root,
|
|
||||||
ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
|
|
||||||
|
|
||||||
for (ChildAssociationRef ref: childRefs)
|
UserTransaction tx = null;
|
||||||
|
try
|
||||||
{
|
{
|
||||||
NodeRef child = ref.getChildRef();
|
tx = Repository.getUserTransaction(FacesContext.getCurrentInstance(), true);
|
||||||
|
tx.begin();
|
||||||
|
|
||||||
if (isAddableChild(child))
|
// query for the child nodes of the user's home
|
||||||
|
NodeRef root = new NodeRef(Repository.getStoreRef(),
|
||||||
|
Application.getCurrentUser(FacesContext.getCurrentInstance()).getHomeSpaceId());
|
||||||
|
List<ChildAssociationRef> childRefs = this.nodeService.getChildAssocs(root,
|
||||||
|
ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
|
||||||
|
|
||||||
|
for (ChildAssociationRef ref: childRefs)
|
||||||
{
|
{
|
||||||
TreeNode node = createTreeNode(child);
|
NodeRef child = ref.getChildRef();
|
||||||
this.myHomeRootNodes.add(node);
|
|
||||||
this.myHomeNodes.put(node.getNodeRef(), node);
|
if (isAddableChild(child))
|
||||||
|
{
|
||||||
|
TreeNode node = createTreeNode(child);
|
||||||
|
this.myHomeRootNodes.add(node);
|
||||||
|
this.myHomeNodes.put(node.getNodeRef(), node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
tx.commit();
|
||||||
|
}
|
||||||
|
catch (Throwable err)
|
||||||
|
{
|
||||||
|
try { if (tx != null) {tx.rollback();} } catch (Exception tex) {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.myHomeRootNodes;
|
return this.myHomeRootNodes;
|
||||||
@@ -339,25 +381,38 @@ public class NavigatorPluginBean implements IContextListener
|
|||||||
this.guestHomeRootNodes = new ArrayList<TreeNode>();
|
this.guestHomeRootNodes = new ArrayList<TreeNode>();
|
||||||
this.guestHomeNodes = new HashMap<String, TreeNode>();
|
this.guestHomeNodes = new HashMap<String, TreeNode>();
|
||||||
|
|
||||||
// query for the child nodes of the guest home space
|
UserTransaction tx = null;
|
||||||
NavigationBean navBean = getNavigationBean();
|
try
|
||||||
if (navBean != null)
|
|
||||||
{
|
{
|
||||||
NodeRef root = navBean.getGuestHomeNode().getNodeRef();
|
tx = Repository.getUserTransaction(FacesContext.getCurrentInstance(), true);
|
||||||
List<ChildAssociationRef> childRefs = this.nodeService.getChildAssocs(root,
|
tx.begin();
|
||||||
ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
|
|
||||||
|
|
||||||
for (ChildAssociationRef ref: childRefs)
|
// query for the child nodes of the guest home space
|
||||||
|
NavigationBean navBean = getNavigationBean();
|
||||||
|
if (navBean != null)
|
||||||
{
|
{
|
||||||
NodeRef child = ref.getChildRef();
|
NodeRef root = navBean.getGuestHomeNode().getNodeRef();
|
||||||
|
List<ChildAssociationRef> childRefs = this.nodeService.getChildAssocs(root,
|
||||||
|
ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
|
||||||
|
|
||||||
if (isAddableChild(child))
|
for (ChildAssociationRef ref: childRefs)
|
||||||
{
|
{
|
||||||
TreeNode node = createTreeNode(child);
|
NodeRef child = ref.getChildRef();
|
||||||
this.guestHomeRootNodes.add(node);
|
|
||||||
this.guestHomeNodes.put(node.getNodeRef(), node);
|
if (isAddableChild(child))
|
||||||
|
{
|
||||||
|
TreeNode node = createTreeNode(child);
|
||||||
|
this.guestHomeRootNodes.add(node);
|
||||||
|
this.guestHomeNodes.put(node.getNodeRef(), node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tx.commit();
|
||||||
|
}
|
||||||
|
catch (Throwable err)
|
||||||
|
{
|
||||||
|
try { if (tx != null) {tx.rollback();} } catch (Exception tex) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -372,6 +427,14 @@ public class NavigatorPluginBean implements IContextListener
|
|||||||
this.nodeService = nodeService;
|
this.nodeService = nodeService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param internalNodeService The internalNodeService to set.
|
||||||
|
*/
|
||||||
|
public void setInternalNodeService(NodeService internalNodeService)
|
||||||
|
{
|
||||||
|
this.internalNodeService = internalNodeService;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param dictionaryService The DictionaryService to set.
|
* @param dictionaryService The DictionaryService to set.
|
||||||
*/
|
*/
|
||||||
@@ -554,8 +617,8 @@ public class NavigatorPluginBean implements IContextListener
|
|||||||
protected TreeNode createTreeNode(NodeRef nodeRef)
|
protected TreeNode createTreeNode(NodeRef nodeRef)
|
||||||
{
|
{
|
||||||
TreeNode node = new TreeNode(nodeRef.toString(),
|
TreeNode node = new TreeNode(nodeRef.toString(),
|
||||||
Repository.getNameForNode(this.nodeService, nodeRef),
|
Repository.getNameForNode(this.internalNodeService, nodeRef),
|
||||||
(String)this.nodeService.getProperty(nodeRef, ApplicationModel.PROP_ICON));
|
(String)this.internalNodeService.getProperty(nodeRef, ApplicationModel.PROP_ICON));
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
@@ -568,7 +631,7 @@ public class NavigatorPluginBean implements IContextListener
|
|||||||
protected NavigationBean getNavigationBean()
|
protected NavigationBean getNavigationBean()
|
||||||
{
|
{
|
||||||
return (NavigationBean)FacesHelper.getManagedBean(
|
return (NavigationBean)FacesHelper.getManagedBean(
|
||||||
FacesContext.getCurrentInstance(), "NavigationBean");
|
FacesContext.getCurrentInstance(), NavigationBean.BEAN_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -579,7 +642,7 @@ public class NavigatorPluginBean implements IContextListener
|
|||||||
protected BrowseBean getBrowseBean()
|
protected BrowseBean getBrowseBean()
|
||||||
{
|
{
|
||||||
return (BrowseBean)FacesHelper.getManagedBean(
|
return (BrowseBean)FacesHelper.getManagedBean(
|
||||||
FacesContext.getCurrentInstance(), "BrowseBean");
|
FacesContext.getCurrentInstance(), BrowseBean.BEAN_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -3129,6 +3129,10 @@
|
|||||||
<property-name>nodeService</property-name>
|
<property-name>nodeService</property-name>
|
||||||
<value>#{NodeService}</value>
|
<value>#{NodeService}</value>
|
||||||
</managed-property>
|
</managed-property>
|
||||||
|
<managed-property>
|
||||||
|
<property-name>internalNodeService</property-name>
|
||||||
|
<value>#{nodeService}</value>
|
||||||
|
</managed-property>
|
||||||
<managed-property>
|
<managed-property>
|
||||||
<property-name>dictionaryService</property-name>
|
<property-name>dictionaryService</property-name>
|
||||||
<value>#{DictionaryService}</value>
|
<value>#{DictionaryService}</value>
|
||||||
|
@@ -435,12 +435,13 @@ a.topToolbarLinkHighlight, a.topToolbarLinkHighlight:link, a.topToolbarLinkHighl
|
|||||||
|
|
||||||
.pager
|
.pager
|
||||||
{
|
{
|
||||||
padding: 5px 3px 4px 3px;
|
padding: 4px 2px 3px 2px;
|
||||||
border: 1px dotted #cccccc;
|
border: 1px dotted #cccccc;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pager img
|
.pager img
|
||||||
{
|
{
|
||||||
|
margin-top:2px;
|
||||||
vertical-align: -20%;
|
vertical-align: -20%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user