cancel
Showing results for 
Search instead for 
Did you mean: 

Creating an array of users from associations

srowsell
Champ in-the-making
Champ in-the-making
I have created a datalist (whose model is shown below, along with everything else) with two properties I need to turn into an array in a web script:  recipientGroup and recipientUser.  These are both multi-valued fields which are associations to groups and users, respectively.

What I need to do with this list is go through it and create an array for each of these associations:  groupArray and userArray.  I will then use these to start workflows.  My problem is that I just can't seem to get my head around how these work as objects.  The snippet I'm posting shows that I'm trying to include a list of unique groups and users, but since the comparison (as shown in a comment) always fails, the arrays are full of non-unique entries.

Any thoughts?

The datalist model:

<?xml version="1.0" encoding="UTF-8"?>
<!– Definition of new Model –>
<model xmlns="http://www.alfresco.org/model/dictionary/1.0" name="reportdl:reportRecipientsDatalist">
   <!– Optional meta-data about the model –>
   <description>Reports Data List</description>
   <author>Steve Rowsell</author>
   <version>1.0</version>
   <!– Imports are required to allow references to definitions in other models –>
   <imports>
      <!– Import Alfresco Dictionary Definitions –>
      <import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d" />
      <!– Import Alfresco Content Domain Model Definitions –>
      <import uri="http://www.alfresco.org/model/content/1.0" prefix="cm" />
      <!– Import Alfresco Data List Model Definitions –>
      <import uri="http://www.alfresco.org/model/datalist/1.0" prefix="dl" />
   </imports>
   <!– Introduction of new namespaces defined by this model –>
   <namespaces>
      <namespace uri="com.duca.reports.datalist" prefix="reportdl" />
   </namespaces>
   <constraints>
      <constraint name="reportdl:departments" type="LIST">
         <parameter name="allowedValues">
            <list>
               <value>Accounting</value>
               <value>Audit</value>
               <value>Credit</value>
               <value>Deposits</value>
               <value>Facilities</value>
               <value>Human Resources</value>
               <value>Investment Solutions</value>
               <value>IT</value>
            <value>Loans</value>
               <value>Marketing</value>
               <value>Operations</value>
               <value>Property Leases</value>
               <value>Sales &amp; Service</value>
            <value>Bowmanville</value>
               <value>Brampton - HCH</value>
               <value>Brampton - Main</value>
               <value>Burlington</value>
               <value>Call Centre</value>
               <value>CBC</value>
               <value>Erin Mills</value>
               <value>Etobicoke</value>
               <value>Guelph</value>
               <value>Mississauga</value>
               <value>Molson</value>
               <value>Mount Pleasant</value>
               <value>Newmarket</value>
            <value>Orangeville</value>
            <value>Pickering</value>
            <value>Rexdale</value>
            <value>Richmond Hill</value>
            <value>Whitby</value>
            <value>Willowdale</value>
<value>Unknown</value>
         </list>
         </parameter>
      </constraint>
      <constraint name="reportdl:frequencies" type="LIST">
         <parameter name="allowedValues">
            <list>
               <value>Daily</value>
               <value>Weekly</value>
               <value>Bi-Weekly</value>
               <value>Monthly</value>
               <value>Bi-Monthly</value>
               <value>Semi-Annually</value>
               <value>Annually</value>
               <value>On Demand</value>
<value>Unknown</value>
            </list>
         </parameter>
      </constraint>
   </constraints>
   <!–      T Y P E   D E F I N I T I O N S      –>
   <types>
      <!–   Data list defintions For this model go here –>
      <type name="reportdl:reportRecipientsDatalist">
         <title>Reports Data List</title>
         <description>Report Recipients Data List</description>
         <parent>dl:dataListItem</parent>
         <properties>
            <property name="reportdl:department">
               <title>Department</title>
               <type>d:text</type>
               <mandatory>true</mandatory>
               <constraints>
                  <constraint ref="reportdl:departments" />
               </constraints>
            </property>
            <property name="reportdl:reportName">
               <title>Report Name</title>
               <type>d:text</type>
               <mandatory>true</mandatory>
            </property>
<property name="reportdl:uniqueIdentifier">
               <title>Report Unique Identifier</title>
               <type>d:text</type>
               <mandatory>true</mandatory>
            </property>
            <property name="reportdl:frequency">
               <title>Report Frequency</title>
               <type>d:text</type>
               <mandatory>true</mandatory>
               <constraints>
                  <constraint ref="reportdl:frequencies" />
               </constraints>
            </property>
            <property name="reportdl:suffix">
               <title>Suffix</title>
               <type>d:text</type>
               <mandatory>false</mandatory>
            </property>
         </properties>
         <associations>
            <association name="reportdl:recipientGroup">
               <title>Recipient Group</title>
               <source>
                  <mandatory>false</mandatory>
                  <many>true</many>
               </source>
               <target>
                  <class>cm:authorityContainer</class>
                  <mandatory>false</mandatory>
                  <many>true</many>
               </target>
            </association>
            <association name="reportdl:recipientUser">
               <title>Recipient User</title>
               <source>
                  <mandatory>false</mandatory>
                  <many>true</many>
               </source>
               <target>
                  <class>cm:person</class>
                  <mandatory>false</mandatory>
                  <many>true</many>
               </target>
            </association>
         </associations>
      </type>
   </types>
</model>


The javascript snippet from the web script:

if ((child.assocs["reportdl:recipientGroup"])!=null)
{
   for (var i=0;i<(child.assocs["reportdl:recipientGroup"]).length;i++)
   {
      var inTheList=false;
      for (var j=0;j<groupArray.length;j++)
      {
         if (groupArray[j]==(child.assocs["reportdl:recipientGroup"])) //this is always false
         {
            inTheList=true;
         }
      }
      if (!inTheList)
      {
         groupArray.push(child.assocs["reportdl:recipientGroup"]);
      }
   }
}
5 REPLIES 5

jpotts
World-Class Innovator
World-Class Innovator
If turning on the server-side JavaScript debugger by setting log4j.logger.org.alfresco.repo.web.scripts.AlfrescoRhinoScriptDebugger=on in log4j.properties is an option for you (e.g., you are running on your own local machine or you are running on a server with a GUI), you'll be able to inspect those two objects and figure out exactly why that comparison is returning false every time.

Jeff

srowsell
Champ in-the-making
Champ in-the-making
Jeff…

When I attempt to do this – I'm using a local instance (Enterprise 4.1.6) to develop here – I get the following exception on restart, and of course I can't log back in to Share.  So for now I'll have to do without enhanced debugging.

Thanks,

Steve


11:58:08,662 ERROR [org.alfresco.repo.content.transform.RuntimeExecutableContentTransformerWorker] Failed to start a runtime executable content transformer:
Execution result:
   os:         Windows NT (unknown)
   command:    wkhtmltopdf -help
   succeeded:  false
   exit code:  2
   out:       
   err:        Cannot run program "wkhtmltopdf": CreateProcess error=2, The system cannot find the file specified
11:58:08,670 INFO  [org.springframework.extensions.webscripts.TemplateProcessorRegistry] Registered template processor Repository Template Processor for extension ftl
11:58:08,672 INFO  [org.springframework.extensions.webscripts.ScriptProcessorRegistry] Registered script processor Repository Script Processor for extension js
11:58:12,282 INFO  [org.alfresco.repo.management.subsystems.ChildApplicationContextFactory] Stopping 'sysAdmin' subsystem, ID: [sysAdmin, default]
11:58:12,283 INFO  [org.alfresco.repo.management.subsystems.ChildApplicationContextFactory] Stopped 'sysAdmin' subsystem, ID: [sysAdmin, default]
11:58:12,290 ERROR [org.springframework.web.context.ContextLoader] Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'webscript.org.alfresco.jsdebugger.get' defined in class path resource [alfresco/web-scripts-application-context.xml]: Cannot resolve reference to bean 'rhinoScriptDebugger' while setting bean property 'debugger'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'rhinoScriptDebugger' defined in class path resource [alfresco/web-scripts-application-context.xml]: Invocation of init method failed; nested exception is java.lang.NullPointerException
   at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
   at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:106)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1325)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1086)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
   at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
   at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
   at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
   at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
   at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580)
   at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
   at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
   at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:276)
   at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:197)
   at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47)
   at org.alfresco.web.app.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:63)
   at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4206)
   at org.apache.catalina.core.StandardContext.start(StandardContext.java:4705)
   at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:799)
   at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:779)
   at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:601)
   at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:675)
   at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:601)
   at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:502)
   at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1317)
   at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:324)
   at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:142)
   at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1065)
   at org.apache.catalina.core.StandardHost.start(StandardHost.java:840)
   at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057)
   at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:463)
   at org.apache.catalina.core.StandardService.start(StandardService.java:525)
   at org.apache.catalina.core.StandardServer.start(StandardServer.java:754)
   at org.apache.catalina.startup.Catalina.start(Catalina.java:595)
   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.catalina.startup.Bootstrap.start(Bootstrap.java:289)
   at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'rhinoScriptDebugger' defined in class path resource [alfresco/web-scripts-application-context.xml]: Invocation of init method failed; nested exception is java.lang.NullPointerException
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1420)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
   at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
   at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
   at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
   at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
   at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:322)
   … 40 more
Caused by: java.lang.NullPointerException
   at sun.awt.shell.Win32ShellFolder2$1.call(Win32ShellFolder2.java:230)
   at sun.awt.shell.Win32ShellFolder2$1.call(Win32ShellFolder2.java:225)
   at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
   at java.util.concurrent.FutureTask.run(FutureTask.java:138)
   at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
   at sun.awt.shell.Win32ShellFolderManager2$ComInvoker$3.run(Win32ShellFolderManager2.java:492)
   at java.lang.Thread.run(Thread.java:662)

srowsell
Champ in-the-making
Champ in-the-making
I have done more investigating, and added the following snippet:


var addon=" ";
for (var i=0;i<200;i++)
{
   if ((items.assocs["reportdl:recipientUser"])!=null)
   {
      addon+=items.assocs["reportdl:recipientUser"][0]+" "+i+"    ";
   }
}

model.query=query+" "+userArray.length+" "+results.length+" ua "+userArray[0]+"   "+addon+"comparison: "+(userArray[0]==(items[127].assocs["reportdl:recipientUser"]));



…which produces the following output (formatted for better readability) to the template:



+ASPECT:"{ra.model}reportProperties" +@ra\:notInWorkflow:"true" 2 308
ua
Node Type: {http://www.alfresco.org/model/content/1.0}person, Node Aspects: [{http://www.alfresco.org/model/content/1.0}ownable, {http://www.alfresco.org/model/application/1.0}configurable, {http://www.alfresco.org/model/system/1.0}referenceable, {http://www.alfresco.org/model/system/1.0}localized, {http://www.alfresco.org/model/content/1.0}preferences]   

Node Type: {http://www.alfresco.org/model/content/1.0}person, Node Aspects: [{http://www.alfresco.org/model/content/1.0}ownable, {http://www.alfresco.org/model/application/1.0}configurable, {http://www.alfresco.org/model/system/1.0}referenceable, {http://www.alfresco.org/model/system/1.0}localized, {http://www.alfresco.org/model/content/1.0}preferences]
127   
Node Type: {http://www.alfresco.org/model/content/1.0}person, Node Aspects: [{http://www.alfresco.org/model/content/1.0}ownable, {http://www.alfresco.org/model/application/1.0}configurable, {http://www.alfresco.org/model/system/1.0}referenceable, {http://www.alfresco.org/model/system/1.0}localized, {http://www.alfresco.org/model/content/1.0}preferences]
198   
comparison: false


It can be seen that value of userArray[0] looks from here like the same value as the association, but honestly this doesn't look like something I should be comparing at all.  I should think that I would be able to compare a property of these associations (like a username or group name), but I have no idea what that would look like.

It is worth noting that the values of userArray all come from the values of items[].assocs["reportdl:recipientUser"), and for testing there's only one value (for multiple records of the datalist), so there is no way they should not agree (unless I'm comparing the wrong things, in which case I'm completely out to lunch anyway).

Speaking of lunch, there is a sandwich here that is whispering my name, and I must see what it wants.

Steve

jpotts
World-Class Innovator
World-Class Innovator
I believe your problem is that you are using "==" to compare two objects. That only works when they are the same objects. In your case, even if those represent the same two *nodes* they are not the same *objects*.

Take a look at this:


var usr1 = people.getPerson('tuser1');
print(usr1.properties['cm:userName']);

var usr2 = people.getPerson('tuser1');
print(usr1.properties['cm:userName']);

if (usr1 == usr2) {
   print("Same");
} else {
   print("Different");
}

if (usr1.equals(usr2)) {
   print("Same");
} else {
   print("Different");
}

if (usr1.properties['cm:userName'].equals(usr2.properties['cm:userName'])) {
   print("Same");
} else {
   print("Different");
}


When run, the output is:

tuser1
tuser1
Different
Same
Same


In this example I retrieve the same user into two different variables. Because those are different objects, an equals comparison is false. But if I use the equals method, or alternatively, compare to strings that will match, such as the user name, the comparison is true.

To find properties such as the user name or group name, use the node browser. Go to Company Home/System/People for people and Company Home/System/Authorities for groups. If you look at a group you'll see its name is cm:authorityName. For users it is cm:userName.

I used Florian Maul's <a href="http://share-extras.github.io/addons/js-console/">JavaScript Console</a> to run this little example. You should grab it if you don't have it.

Jeff

srowsell
Champ in-the-making
Champ in-the-making
Jeff…

Yeah, that's object-oriented programming 101.  Something I should have picked up, but didn't, just because I wasn't really thinking of this thing as an object.

Thanks muchly for helping,

Steve