• Skip to primary navigation
  • Skip to main content
  • Skip to footer
ecm experts in australia

Seed Information Management

Enterprise Content Management Consultants ECM Experts

  • Services
    • Content Management
    • Collaboration
    • Business Process Management
    • Migration Services
    • Integration Services
    • Support & Maintenance
    • Pricing
  • Technology
    • Alfresco Digital Business Platform
    • Alfresco Application Development Framework
    • Cloud (PaaS)
    • Activiti
    • Flowable
    • Hyland RPA
  • Alfresco Addons
  • Case Studies
    • Industries
  • Blog
  • Contact Us
    • About

Alfresco Folder Quota

June 6, 2019 By Seed IM

Recently SeedIM was requested by one of our customers to provide a way within Alfresco to set a folder quota limit. Users were using Alfresco for data backup and that was consuming too much space. While Alfresco allows you to have a quota on how much content a user can add to Alfresco, there is no such mechanism at the folder level. So in this blog we will show you how we implemented this.

Alfresco Folder Quota

The folder quota solution is made up of the following parts;

  • An Aspect to hold metadata about the Folder Quota.
  • Repository actions to set and remove the Folder Quota metadata.
  • Behaviour to keep track of the Folder size, update Folder Quota metadata and prevent users from adding content when the folder limit is reached.
  • Override Upload Document webscript to display appropriate error notification if folder quota is being exceeded.
  • Share Actions, Form and evaluators for the management folder quota.
  • Share Metadata Template and custom renderer to display the folder limit and actual size in the folder browse view

Folder Quota Aspect

We used an aspect to hold the required information about the folder quota which is defined as follows in our content model;

<aspect name="seed:quotaAspect">
            <title>Quota Aspect</title>
            <description>Seed Quota Aspect</description>
            <properties>
                <property name="seed:sizeCurrent">
                  <title>Current Size</title>
                  <description>Seed Current Size</description>
                  <type>d:long</type>
                  <multiple>false</multiple>
               </property>
                <property name="seed:sizeLimit">
                 <title>Size Limit</title>
                 <description>Seed Size Limit</description>
                 <type>d:int</type>
                 <default>50</default>
              </property>
            </properties>
        </aspect>

Set Folder Size Limit Repo Action

The Set Folder Size Limit Repo Action is mainly used for the following;

  • Applies the Folder Quota Aspect
  • Sets the quota limit in seed:sizeLimit property based on the input from the user
  • Uses a recursive method (see snippet below) to get the current size of the folder and then sets it in seed:sizeCurrent property
   public long getNodeSize(NodeRef nodeRef) {
       long size = 0;     
       try {
           if(nodeService.getType(nodeRef).isMatch(ContentModel.TYPE_CONTENT)) {
               ContentData contentData = (ContentData) nodeService.getProperty(nodeRef, 
                                         ContentModel.PROP_CONTENT);
               size = contentData.getSize();
            }
       } catch (Exception e) {
       if(logger.isDebugEnabled()) logger.debug("Could not get size for node " 
             + nodeRef + " err: " + e.getMessage());
            size = 0;
       }
      List<ChildAssociationRef> chilAssocsList = nodeService.getChildAssocs(nodeRef);
      for (ChildAssociationRef childAssociationRef : chilAssocsList) {
            NodeRef childNodeRef = childAssociationRef.getChildRef();
            size = size + getNodeSize(childNodeRef);
      }
       return size;
    }

Remove Folder Size Limit Repo Action

As the name implies the Remove Folder Size Limit Repo Action is used to remove the Folder Quota Aspect. See below code snippet.

protected void removeFolderSizeLimit(final Action action, final NodeRef actionedUponNodeRef) {
   try {
      if(nodeService.exists(actionedUponNodeRef) && nodeService.hasAspect(actionedUponNodeRef,
        SeedModel.ASPECT_QUOTAASPECT)) {
        behaviourFilter.disableBehaviour(actionedUponNodeRef, ContentModel.ASPECT_AUDITABLE);
        nodeService.removeAspect(actionedUponNodeRef, SeedModel.ASPECT_QUOTAASPECT);
        behaviourFilter.enableBehaviour(actionedUponNodeRef, ContentModel.ASPECT_AUDITABLE);
       }            
    }catch(Exception e) {
      throw new AlfrescoRuntimeException("Could not remove Folder Size limit for node " 
       + actionedUponNodeRef + " err: " + e.getMessage());
    }
}

Folder Quota Behaviour

The Folder Quota behaviour is used to track the folder content and implements the following two policies;

BeforeDeleteNodePolicy

Checks if the document being deleted parent or ancestors have the Folder Quota Aspect and if yes then get the document size and update the seed:sizeCurrent property accordingly.

OnContentPropertyUpdatePolicy

Checks if the document being deleted parent or ancestors have the Folder Quota Aspect and if yes then get the document size, cross check if it would exceed the set quota and if yes then throw an AlfrescoRuntime exception.

Upload Content Webscript

Out of the box, whenever an exception is encountered during the upload of a document, a generic notification error is thrown. In order to throw a more relevant error when the Folder Quota is exceeded, the following was added to upload.post.js which is used when a user clicks on the Upload button in a Share.

else if (e.message && e.message.indexOf("org.alfresco.service.cmr.repository.ContentIOException") 
== 0)
{
    var error = e + "";
    if (error.indexOf("Folder Quota Exception") != -1){
    var newErr = new Error("Folder Quota Exceeded");
    newErr.stack += '\nCaused by: Folder Quota Exceeded';
    newErr.code = 413;
    newErr.message = "Folder Quota Exceeded";
    throw newErr;
}








Share Set Folder Limit Action and form

The Share Set Folder Limit action calls the onActionFormDialog js handler to call the custom form we defined for the user to input the Folder Size limit when the latter clicks on the Set Folder Size Limit action in Share.

The Share Folder Size limit Action definition is as follows;

<action id="seed-setFolderSizeLimit" type="javascript" label="seed.action.setFolderSizeLimit.label" icon="enabled-indicator-off">
   <param name="function">onActionFormDialog</param>
   <param name="itemKind">action</param>
   <param name="itemId">setFolderSizeLimitAction</param> 
   <param name="mode">create</param>
   <param name="destination">{node.nodeRef}</param>
   <param name="successMessage">message.seed.setFolderSizeLimit.successful</param>
   <param name="failureMessage">message.seed.setFolderSizeLimit.failed</param>
   <evaluator>seed.evaluator.doclib.action.canSetFolderSizeLimit</evaluator>
   <evaluator negate="true">seed.evaluator.doclib.action.hasQuotaAspect</evaluator>
</action>

The custom form definition is shown below and note that the condition has to match the bean id of the repo action;

<forms>
<config evaluator="string-compare" condition="setFolderSizeLimitAction"> 
  <form>
    <field-visibility>
       <show id="sizeLimit"/>
    </field-visibility>
    <appearance>
       <field id="sizeLimit" label-id="seed.action.setFolderSizeLimit.form.field.sizeLimit">
          <control template="/org/alfresco/components/form/controls/number.ftl" />
       </field>
    </appearance>
  </form>
</forms>
</config>
Share Custom renderer and Metadata template

In order to display the Folder Size limit and Folder Size Current as shown below, we had to use a share custom renderer and metadata template.

 

 

 

We defined a custom renderer for the current folder size because the default value its always returned in bytes.

YAHOO.Bubbling.fire("registerRenderer",
{
   propertyName: "seedFolderSizeCurrentCustomRendition",
   renderer: function seedFolderSizeCurrent_renderer(record, label) {
   var jsNode = record.jsNode,
   properties = jsNode.properties,
   html = "";
   var folderSizeCurrent = properties["brs:sizeCurrent"] || "";
   if(folderSizeCurrent != ""){
     var k = 1024; // or 1024 for binary
     var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
     var i = Math.floor(Math.log(folderSizeCurrent) / Math.log(k));
     folderSizeCurrent = parseFloat((folderSizeCurrent / Math.pow(k, i)).toFixed()) + ' ' + sizes[i];
   }
   html = '<span>' + label + folderSizeCurrent + '</span>';
   return html;
 }
});

We defined a new metadata template for the Folder Quota Aspect in our share extension module to display the Size Limit and Actual Size in the DocumentLibrary Details view. Also note that we have an evaluator to check for the Folder Quota Aspect and also using our custom renderer (seedFolderSizeCurrentCustomRendition) for displaying the current folder size property.

<module>
<id>Add Folder quota Metadata Template</id>
<version>1.0</version>
<auto-deploy>true</auto-deploy>
<configurations>
<config evaluator="string-compare" condition="DocumentLibrary">
<metadata-templates>
<template id="seedFolderQuotaMetadataTemplate">
<evaluator>seed.evaluator.doclib.action.hasQuotaAspect</evaluator>
<banner index="10" id="lockBanner" evaluator="evaluator.doclib.metadata.hasLockBanner">
{lockBanner}</banner>
<banner index="20" id="syncTransientError" evaluator="evaluator.doclib.metadata.
hasSyncTransientErrorBanner">{syncTransientError}</banner>                            
<banner index="30" id="syncFailed" evaluator="evaluator.doclib.metadata.hasSyncFailedBanner">
{syncFailed}</banner>
<line index="10" id="date">{date}{size}</line>
<line index="20" id="description" view="detailed">{description}</line>
<line index="30" id="tags" view="detailed">{tags}</line>
<line index="40" id="categories" view="detailed" 
evaluator="evaluator.doclib.metadata.hasCategories">{categories}</line>
<line index="50" id="folderSize" view="detailed" 
evaluator="seed.evaluator.doclib.action.hasQuotaAspect">
{seed_sizeLimit seed.action.setFolderSizeLimit.form.field.sizeLimit}
{seedFolderSizeCurrentCustomRendition seed.action.setFolderSizeLimit.form.field.sizeCurrent}</line>
<line index="60" id="social" view="detailed">{social}</line>
</template>
</metadata-templates>
</config>
</configurations>
</module>

This concludes our blog on how we can set up a specific limit on a folder in alfresco and hope it was helpful.

 

Footer


Seed IM is a leading ECM consulting company providing powerful solutions to businesses and organisations of all sizes

Contact Us

  • Seed Information Management Pty Ltd
    90 Maribyrnong Street
    Footscray VIC 3011
  • 03 9021 0837
  • info@seedim.com.au

Articles

Semantic Content Management for Alfresco
Using Multiple Taxonomies To Browse Your Content
Records Management Using Alfresco One

Copyright © 2025 Seed Information Management Pty Ltd · Contact Us · Privacy Policy · Our Digital Media Agency is Marmoset Digital