简体   繁体   中英

Javascript to Dynamically Create Spaces/Folders in Alfresco Doesn't Work Correctly

I am currently working with Alfresco 4.0.d community edition (I also tried this on Alfresco 4.0.c community edition) on a Oracle Linux 6 64bit virtual machine, using Firefox as my browser.

Most recently, I had been attempting to create a script which could be executed via a rule that would dynamically create sub-folders as new items entered a space/folder.

Essentially, say you have a newly created piece of content called fileOne . This file will sit in a space called mainFolder , and when a rule is run on the file to execute a script, the script will look to see if sub-folders exist based on the title and author values of the file. If not, it will create sub-folders within that mainFolder based on the title value --> sub-folder, and author value --> sub-sub-folder of that file. And then I want that content/file to be moved over to that either that existing or newly created sub-sub folder.

Ultimately I want something that looks like:

Space: mainFolder
|---> Content: fileOne --> Properties: Name, Title, Author
|---> Space: Title
      |---> Space: Author
            |---> Content: fileOne --> Properties: Name, Title, Author 

Below is the script...

function main()
{
    //mainFolder space/folder MUST exist under companyhome.
    var rootSpaceName = companyhome.childByNamePath("mainFolder");

    if(rootSpaceName == null)
    { 
        logger.log("Company Home/mainFolder does not exist, so we have nothing to do.");
        return;
    }
    else
    {
        logger.log("Company Home/mainFolder exists, so carry on our process.");

        var childList = rootSpaceName.children;
        var count = childList.length;
        var seconds = new Date().getTime() / 1000;

        if(count == 0)
        {
            logger.log("Company Home/mainFolder does not have child, nothing to do.");
            return;
        }
        else
        {
            for(var i = 0; i < count; i++)
            {
                // File Title MUST exist.
                var childTitle = childList[i].properties.title;

                if(childTitle == null)
                {
                    childTitle = "New Title " + seconds;
                }

                // File Author MUST exist.
                var childAuthor = childList[i].properties.author;

                if(childAuthor == null)
                {
                    childAuthor = "New Author " + seconds;
                }

                var child = childList[i];
                logger.log("This child is: " + child);

                if(child.isContainer == false)
                {
                    for(var j = 0; j < count; j++)
                    {
                        var newChildName = childList[j].properties.name;
                        logger.log("New child name: " + newChildName);
                        var newChild = childList[j];

                        if((newChild.isContainer == true) && (childTitle == newChildName))
                        {
                            var newSpaceName = rootSpaceName.childByNamePath(newChildName);
                            var newChildList = newSpaceName.children;
                            var newCount = newChildList.length;

                            for(var k = 0; k < newCount; k++)
                            {
                                var newNewChildName = newChildList[k].properties.name;
                                var newNewChildAuthor = newChildList[k].properties.author;
                                var newNewChild = newChildList[k];

                                if((newNewChild.isContainer == true) && (newNewChildAuthor == childAuthor))
                                {
                                    var currentSpace = newSpaceName.childByNamePath(newNewChildName);
                                    child.move(currentSpace);
                                }
                            }
                        }
                        else
                        {
                            // If title folder is already created, not need to create again.
                            var newSpaceName = companyhome.childByNamePath("mainFolder/" + childTitle);

                            if(newSpaceName == null)
                            {
                                newSpaceName = rootSpaceName.createFolder(childTitle);
                                logger.log("mainFolder/" + childTitle + " is created.");
                            }

                            // If author folder is already created, not need to create again.
                            var newNewSpaceName = companyhome.childByNamePath("mainFolder/" + childTitle + "/" + childAuthor);
                            if(newNewSpaceName == null)
                            {
                                newNewSpaceName = newSpaceName.createFolder(childAuthor);
                                logger.log("mainFolder/" + childTitle + "/" + childAuthor + " is created.");
                            }

                            child.move(newNewSpaceName);
                            logger.log("Moving file " + child.properties.name);
                        }

                    }

                }

            }
        }
    }
    return;
}

main();

So to test this, step-by-step here is what I do:

  1. I click on Company Home .
  2. I click on Create , Create Space .
  3. I then create a space called mainFolder (this is under Company Home).
  4. I then click on the newly created folder, then click on More Actions , Manage Content Rules .
  5. Then I click on Create Rule .
    5a. Where it tells me to select a condition, I choose All Items , then I click Add to List , then I hit Next .

    5b. Where it now tells me to select an action, I choose Execute Script , then I click Set Values and Add , which allows me to choose the script called new-create-folders.js which I had previously added to the Scripts folder within the Data Dictionary . Then I click OK , and then Next .

    5c. Here where it asks me for the type , I choose Items are updated . I then enter a title like create folders rule . And finally I check Run rule in the background , then I hit Next .

    5d. Now I click Finish to finalize my rule.
  6. Now with the rule created, I click Create , Create Content .

    6a. I give my content a name like name001 , then I hit Next , then I enter a title like title001 and an author like author001 . Then I hit OK .

What happens now has got me confused; it creates one sub folder called title001 like I wanted it to, and within that sub-folder it creates another folder called author001 , and within that folder the file called name001 has been moved. And that is sort of how I want it to work, but there are still problems. Under the mainFolder , there is also a new sub-folder called New Title 1346102873.393 New Title 1346102873.393 with a folder inside of that called New Author 1346102873.393 , but there is no file inside of that folder. And I don't know why this folder is created when I only added one piece of content to the mainFolder ? Also, now that the folders have been created, the rule also looks to have been deleted from the mainFolder , ie there are no longer any rules applied to the folder. And when I go back to create the rule again on the mainFolder , I get the error: Failed to create Rule due to error: null . And below are the errors I get in the log files...

Output/Errors from Alfresco Log

17:27:51,373 DEBUG [org.alfresco.repo.jscript.RhinoScriptProcessor] Imports resolved, adding resource '_root
17:27:53,389 DEBUG [org.alfresco.repo.jscript.ScriptLogger] Company Home/mainFolder exists, so carry on our process.
17:27:53,400 DEBUG [org.alfresco.repo.jscript.ScriptLogger] This child is: Node Type: {http://www.alfresco.org/model/content/1.0}systemfolder, Node Aspects: [{http://www.alfresco.org/model/content/1.0}auditable, {http://www.alfresco.org/model/system/1.0}referenceable, {http://www.alfresco.org/model/system/1.0}localized]
17:27:53,400 DEBUG [org.alfresco.repo.jscript.ScriptLogger] New child name: b8ea2cb0-6fb6-481e-bb7b-d5364d9c509e
17:27:53,422 DEBUG [org.alfresco.repo.jscript.ScriptLogger] mainFolder/New Title 1346102873.393 is created.
17:27:53,439 DEBUG [org.alfresco.repo.jscript.ScriptLogger] mainFolder/New Title 1346102873.393/New Author 1346102873.393 is created.
17:27:53,498 DEBUG [org.alfresco.repo.jscript.ScriptLogger] Moving file b8ea2cb0-6fb6-481e-bb7b-d5364d9c509e
17:27:53,499 DEBUG [org.alfresco.repo.jscript.ScriptLogger] New child name: name001
17:27:53,523 DEBUG [org.alfresco.repo.jscript.ScriptLogger] Moving file b8ea2cb0-6fb6-481e-bb7b-d5364d9c509e
17:27:53,524 DEBUG [org.alfresco.repo.jscript.ScriptLogger] This child is: Node Type: {http://www.alfresco.org/model/content/1.0}content, Node Aspects: [{http://www.alfresco.org/model/content/1.0}auditable, {http://www.alfresco.org/model/system/1.0}referenceable, {http://www.alfresco.org/model/content/1.0}titled, {http://www.alfresco.org/model/content/1.0}author, {http://www.alfresco.org/model/system/1.0}localized, {http://www.alfresco.org/model/application/1.0}inlineeditable]
17:27:53,524 DEBUG [org.alfresco.repo.jscript.ScriptLogger] New child name: b8ea2cb0-6fb6-481e-bb7b-d5364d9c509e
17:27:53,534 DEBUG [org.alfresco.repo.jscript.ScriptLogger] mainFolder/title001 is created.
17:27:53,546 DEBUG [org.alfresco.repo.jscript.ScriptLogger] mainFolder/title001/author001 is created.
17:27:53,561 DEBUG [org.alfresco.repo.jscript.ScriptLogger] Moving file name001
17:27:53,561 DEBUG [org.alfresco.repo.jscript.ScriptLogger] New child name: name001
17:27:53,577 DEBUG [org.alfresco.repo.jscript.ScriptLogger] Moving file name001
17:27:53,578 DEBUG [org.alfresco.repo.jscript.RhinoScriptProcessor] Time to execute script: 1976.9988ms
17:31:13,385 ERROR [org.alfresco.web.ui.common.Utils] Failed to create Rule due to error: null
java.lang.NullPointerException
    at org.alfresco.repo.rule.RuleServiceImpl.getLinkedToRuleNode(RuleServiceImpl.java:1516)
    at org.alfresco.repo.rule.RuleServiceImpl.isLinkedToRuleNode(RuleServiceImpl.java:1504)
    at org.alfresco.repo.rule.RuleServiceImpl.checkForLinkedRules(RuleServiceImpl.java:947)
    at org.alfresco.repo.rule.RuleServiceImpl.saveRule(RuleServiceImpl.java:740)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    at org.alfresco.repo.security.permissions.impl.AlwaysProceedMethodInterceptor.invoke(AlwaysProceedMethodInterceptor.java:34)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.alfresco.repo.security.permissions.impl.ExceptionTranslatorMethodInterceptor.invoke(ExceptionTranslatorMethodInterceptor.java:46)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.alfresco.repo.audit.AuditMethodInterceptor.invoke(AuditMethodInterceptor.java:147)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    at $Proxy53.saveRule(Unknown Source)
    at org.alfresco.web.bean.rules.CreateRuleWizard.finishImpl(CreateRuleWizard.java:148)
    at org.alfresco.web.bean.dialog.BaseDialogBean$1.execute(BaseDialogBean.java:123)
    at org.alfresco.web.bean.dialog.BaseDialogBean$1.execute(BaseDialogBean.java:119)
    at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:388)
    at org.alfresco.web.bean.dialog.BaseDialogBean.finish(BaseDialogBean.java:129)
    at org.alfresco.web.bean.wizard.WizardManager.finish(WizardManager.java:593)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.myfaces.el.MethodBindingImpl.invoke(MethodBindingImpl.java:132)
    at org.apache.myfaces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:61)
    at javax.faces.component.UICommand.broadcast(UICommand.java:151)
    at javax.faces.component.UIViewRoot._broadcastForPhase(UIViewRoot.java:115)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:191)
    at org.apache.myfaces.lifecycle.InvokeApplicationExecutor.execute(InvokeApplicationExecutor.java:32)
    at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:105)
    at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:80)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:143)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.alfresco.repo.web.filter.beans.SessionSynchronizedFilter.doFilter(SessionSynchronizedFilter.java:67)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.alfresco.web.app.servlet.AuthenticationFilter.doFilter(AuthenticationFilter.java:104)
    at sun.reflect.GeneratedMethodAccessor443.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.alfresco.repo.management.subsystems.ChainingSubsystemProxyFactory$1.invoke(ChainingSubsystemProxyFactory.java:116)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    at $Proxy238.doFilter(Unknown Source)
    at org.alfresco.repo.web.filter.beans.BeanProxyFilter.doFilter(BeanProxyFilter.java:82)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.alfresco.repo.web.filter.beans.NullFilter.doFilter(NullFilter.java:68)
    at sun.reflect.GeneratedMethodAccessor443.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.alfresco.repo.management.subsystems.ChainingSubsystemProxyFactory$1.invoke(ChainingSubsystemProxyFactory.java:116)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    at $Proxy238.doFilter(Unknown Source)
    at org.alfresco.repo.web.filter.beans.BeanProxyFilter.doFilter(BeanProxyFilter.java:82)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.alfresco.web.app.servlet.GlobalLocalizationFilter.doFilter(GlobalLocalizationFilter.java:58)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:470)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread.java:662)

Does anyone know why that additional folder is being created, as well as why the rule is being deleted after it executes on the newly created piece of content, and why I cannot add a new rule to the folder after it first deletes the original rule?

I posted the answer to this exact question from the same poster in the Alfresco forums. The answer is that the code attempts to create a folder using the same name as the document. Nodes must be uniquely named in a folder so this is not allowed.

It sounds like your rule is running multiple times and is tripping over itself. Could it be that some of the actions that the script itself is performing causes it to be run again?

Check that your rule is not being applied to sub-folders, and rather than selecting 'All Items' in the condition part of the wizard, try something more specific, eg all content items.

The problem actually I think should be that the rule is triggered multiple times, by the condition rule "All Items" are being updated. So EVERY node receive an update in the repository, inside the space with the rule (maybe also the sub-folder, I'd check that), it triggers, and creates probably a loop. Have you tried to use a rule with the trigger "when node are being created"?

UPDATE:

So, i've tried to debug this on Alfresco 3.4.7 Enteprise and 4.0 Community x64 both (Linux AND Windows).

  • I've created a js file named inside Scripts directory inside Alfresco, /Company Home/Data Dictionary.
  • Then I created a folder mainFolder inside the Company Home space.
  • I uploaded a new PDF file inside the folder mainFolder.
  • Then i executed the fs file against the PDF file. So, entering into the detailed view of the document, and then clicking on "Run Action" - "Execute Script".
  • There, everything works perfectly!

So in the end, the problem is in the rule execution, that trigger on "All items" so, it recursively triggers when the script creates the new folder with title name. I tried to execute rule with the "only PDF type" nodes, and it works like a charm!

Hope this helps...

The line:

 var rootSpaceName = companyhome.childByNamePath("mainFolder");

will try to locate a folder relative to companyhome ie the root of the repository. Does that folder exist in your repository?

If you are trying to write a script that operates on files entering a space, then don't you need to use paths relative to that file or space (using the document or space objects, not companyhome )?

If not, perhaps you could explain a little more what you are trying to achieve?

If you are not already using it, then the Alfresco JavaScript Console is an extremely useful add-on for trying out JavaScript code, and you can see console output using logger.log() .

May be your requirement is files which are existed in mainFolder have title and author fields. you want to move your files into title->author folder.

Like that mainFolder -> FileName: file1, Title: title1, Author: author1

to mainFolder -> title1 ->author1 ->file1

I try your code edited with my own and run in alfresco community 4.0c in alfresco side and with java script console in share side in windows both.

When creating rule to mainFolder

1) Select Conditions

1.1 Content of type or sub-type as select conditons

1.2 Content as Set condition values, not check the checkbox below Summary is Item is a subtype of 'Content'

2) Select Actions Execute Script same as you

3) Type Items are created or inserted

I choose these because running our code dynamically creates folders. So rule is only applied for contents. Others are same as you except uncheck execute rule in background. If item created has no title name, alfresco default assumed item name as title.

Last updated code :

function main()
{
    //mainFolder space/folder MUST exist under companyhome.
    var rootSpaceName = companyhome.childByNamePath("mainFolder");

    if(rootSpaceName == null)
    { 
        logger.log("Company Home/mainFolder does not exist, so we have nothing to do.");
        return;
    }
    else
    {
        logger.log("Company Home/mainFolder exists, so carry on our process.");

        var childList = rootSpaceName.children;
        var count = childList.length;

        if(count == 0)
        {
            logger.log("Company Home/mainFolder does not have child, nothing to do.");
            return;
        }
        else
        {
            for(var i = 0; i < count; i++)
            {   
                var child = childList[i];
                logger.log("This child is: " + child);

                // If each of child is file
                if(child.isDocument)
                {
                    // Get title of file and
                    // If childTitle is null, we set DEFAULT value
                    var childTitle = childList[i].properties.title;
                    if(childTitle == null)
                    {
                        childTitle = "New Title";
                    }
                    else if(childTitle == child.properties.name)
                    {
                        childTitle = "Title " + childTitle;
                    }

                    // Get author of file.
                    // If childAuthor is null, we set DEFAULT value
                    var childAuthor = childList[i].properties.author;
                    if(childAuthor == null)
                    {
                        childAuthor = "New Author";
                    }
                    logger.log("Original Title :" + child.properties.title + "\tAuthor :" + child.properties.author);
                    logger.log("Setting Title :" + childTitle + "\tAuthor :" + childAuthor);

                    // If title folder does not exist, create title folder
                    var newSpaceTitle = companyhome.childByNamePath("mainFolder/" + childTitle);

                    if(newSpaceTitle == null)
                    {
                        newSpaceTitle = rootSpaceName.createFolder(childTitle);
                        logger.log("mainFolder/" + childTitle + " is created.");
                    }

                    // If author folder does not exist, create author folder
                    var newSpaceAuthor = companyhome.childByNamePath("mainFolder/" + childTitle + "/" + childAuthor);
                    if(newSpaceAuthor == null)
                    {
                        newSpaceAuthor = newSpaceTitle.createFolder(childAuthor);
                        logger.log("mainFolder/" + childTitle + "/" + childAuthor + " is created.");
                    }

                    child.move(newSpaceAuthor);
                    logger.log("Moving file " + child.properties.name);
                }
            }
        }
    }
    return;
}

main();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM