[ALF-13038] Property Decorators require overwriting core files Created: 23-Feb-12  Updated: 22-Jan-16  Resolved: 02-Apr-12

Status: Closed
Project: Alfresco
Component/s: Share Application
Affects Version/s: 4.0 Enterprise
Fix Version/s: None
Security Level: external (External user)

Type: Bug Priority: Unprioritized
Reporter: Jared Ottley Assignee: Closed Issues
Resolution: Not a bug Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Dependency
Date of First Response:
Resolution Time Custom Field: 5 weeks, 4 days, 2 hours, 33 minutes, 27 seconds

 Description   

When adding the mapping between the property and the decorator bean, it can only be added to the OTB applicationScriptUtils bean. Adding custom beans breaks Alfresco (ie the custom bean overwrites the OTB bean).

Exception Thrown:

10:30:28,481 ERROR [org.springframework.extensions.webscripts.AbstractRuntime] Exception from executeScript - redirecting to status template error: 01230002 Wrapped Exception (with status template): 01230004 Failed to execute script 'classpath*:alfresco/templates/webscripts/org/alfresco/webframework/metadata.get.js': 01230003
org.springframework.extensions.webscripts.WebScriptException: 01230002 Wrapped Exception (with status template): 01230004 Failed to execute script 'classpath*:alfresco/templates/webscripts/org/alfresco/webframework/metadata.get.js': 01230003
at org.springframework.extensions.webscripts.AbstractWebScript.createStatusException(AbstractWebScript.java:970)
at org.springframework.extensions.webscripts.DeclarativeWebScript.execute(DeclarativeWebScript.java:171)
at org.alfresco.repo.web.scripts.RepositoryContainer$2.execute(RepositoryContainer.java:393)
at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:388)
at org.alfresco.repo.web.scripts.RepositoryContainer.transactionedExecute(RepositoryContainer.java:462)
at org.alfresco.repo.web.scripts.RepositoryContainer.transactionedExecuteAs(RepositoryContainer.java:500)
at org.alfresco.repo.web.scripts.RepositoryContainer.executeScript(RepositoryContainer.java:316)
at org.springframework.extensions.webscripts.AbstractRuntime.executeScript(AbstractRuntime.java:372)
at org.springframework.extensions.webscripts.AbstractRuntime.executeScript(AbstractRuntime.java:209)
at org.springframework.extensions.webscripts.servlet.WebScriptServlet.service(WebScriptServlet.java:118)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
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)
Caused by: org.alfresco.scripts.ScriptException: 01230004 Failed to execute script 'classpath*:alfresco/templates/webscripts/org/alfresco/webframework/metadata.get.js': 01230003
at org.alfresco.repo.jscript.RhinoScriptProcessor.execute(RhinoScriptProcessor.java:195)
at org.alfresco.repo.processor.ScriptServiceImpl.execute(ScriptServiceImpl.java:212)
at org.alfresco.repo.processor.ScriptServiceImpl.executeScript(ScriptServiceImpl.java:174)
at org.alfresco.repo.web.scripts.RepositoryScriptProcessor.executeScript(RepositoryScriptProcessor.java:102)
at org.springframework.extensions.webscripts.AbstractWebScript.executeScript(AbstractWebScript.java:1193)
at org.springframework.extensions.webscripts.DeclarativeWebScript.execute(DeclarativeWebScript.java:86)
... 25 more
Caused by: org.alfresco.error.AlfrescoRuntimeException: 01230003
at org.alfresco.repo.jscript.RhinoScriptProcessor.executeScriptImpl(RhinoScriptProcessor.java:499)
at org.alfresco.repo.jscript.RhinoScriptProcessor.execute(RhinoScriptProcessor.java:191)
... 30 more
Caused by: java.lang.NullPointerException
at org.mozilla.javascript.ImporterTopLevel.findPrototypeId(ImporterTopLevel.java:294)
at org.mozilla.javascript.IdScriptableObject$PrototypeValues.findId(IdScriptableObject.java:178)
at org.mozilla.javascript.IdScriptableObject.has(IdScriptableObject.java:364)
at org.mozilla.javascript.ImporterTopLevel.has(ImporterTopLevel.java:123)
at org.mozilla.javascript.ScriptableObject.getBase(ScriptableObject.java:1840)
at org.mozilla.javascript.ScriptableObject.putProperty(ScriptableObject.java:1653)
at org.alfresco.repo.jscript.RhinoScriptProcessor.executeScriptImpl(RhinoScriptProcessor.java:479)
... 31 more
10:30:33,169 ERROR [org.alfresco.web.site] org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.extensions.surf.exception.UserFactoryException: Unable to retrieve user from repository
org.springframework.extensions.surf.exception.UserFactoryException: Unable to retrieve user from repository
at org.springframework.extensions.surf.support.AlfrescoUserFactory.loadUser(AlfrescoUserFactory.java:194)
at org.alfresco.web.site.SlingshotUserFactory.loadUser(SlingshotUserFactory.java:105)
at org.springframework.extensions.surf.support.AbstractUserFactory.initialiseUser(AbstractUserFactory.java:180)
at org.springframework.extensions.surf.support.AbstractUserFactory.initialiseUser(AbstractUserFactory.java:99)
at org.springframework.extensions.surf.RequestContextUtil.initialiseUser(RequestContextUtil.java:249)
at org.springframework.extensions.surf.RequestContextUtil.populateRequestContext(RequestContextUtil.java:182)
at org.springframework.extensions.surf.RequestContextUtil.populateRequestContext(RequestContextUtil.java:137)
at org.springframework.extensions.surf.mvc.AbstractWebFrameworkView.populateRequestContext(AbstractWebFrameworkView.java:380)
at org.springframework.extensions.surf.mvc.AbstractWebFrameworkView.renderMergedOutputModel(AbstractWebFrameworkView.java:290)
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1047)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:817)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.alfresco.web.site.servlet.MTAuthenticationFilter.doFilter(MTAuthenticationFilter.java:74)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.alfresco.web.site.servlet.SSOAuthenticationFilter.doFilter(SSOAuthenticationFilter.java:307)
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)
Caused by: org.springframework.extensions.surf.exception.UserFactoryException: Unable to create user - failed to retrieve user metadata:
at org.springframework.extensions.surf.support.AlfrescoUserFactory.loadUser(AlfrescoUserFactory.java:183)
... 35 more



 Comments   
Comment by Jared Ottley [ 29-Mar-12 ]

Addition background:

I'm adding a decorator to pass back if the current user has synced the node to dropbox or not (maintained in an association to a node with the specific dropbox metadata for the current user).

I've added a custom property to my model

<property name="db:isSyncedToDropbox">
<type>d:boolean</type>
<default>false</default>
<index enabled="false"/>
</property>

I've defined a class to decorate the property

@Override
public Serializable decorate(NodeRef nodeRef, String propertyName, Serializable value)

{ Map<String, Serializable> map = new LinkedHashMap<String, Serializable>(4); boolean synced = dropboxService.isSynced(nodeRef); map.put("userIsSyncedToDropbox", synced); return (Serializable)map; }

And I've added the bean to context file

<bean id="syncedToDropbox" class="org.alfresco.dropbox.repo.jscript.app.SyncedToDropbox">
<property name="dropboxService">
<ref bean="dropboxService"/>
</property>
</bean>

The last thing to do is map the customer decorator bean to the model property

If you define your own custom instance of the bean to do the mapping, you get the exception thrown

<bean id="dropboxApplicationScriptUtils" parent="baseJavaScriptExtension" class="org.alfresco.repo.jscript.ApplicationScriptUtils">
<property name="decoratedProperties">
<map>
<entry key="db:isSyncedToDropbox">
<ref bean="syncedToDropbox"/>
</entry>
</map>
</property>
</bean>

So the only option is to overwrite the OTB bean definition in script-services-context.xml

<bean id="applicationScriptUtils" parent="baseJavaScriptExtension" class="org.alfresco.repo.jscript.ApplicationScriptUtils">
<property name="extensionName">
<value>appUtils</value>
</property>
<property name="serviceRegistry">
<ref bean="ServiceRegistry"/>
</property>
<property name="decoratedProperties">
<map>
<entry key="cm:creator">
<ref bean="usernamePropertyDecorator"/>
</entry>
<entry key="cm:modifier">
<ref bean="usernamePropertyDecorator"/>
</entry>
<entry key="cm:workingCopyOwner">
<ref bean="usernamePropertyDecorator"/>
</entry>
<entry key="cm:lockOwner">
<ref bean="usernamePropertyDecorator"/>
</entry>
<entry key="cm:owner">
<ref bean="usernamePropertyDecorator"/>
</entry>
<entry key="cm:taggable">
<ref bean="tagPropertyDecorator"/>
</entry>
<entry key="cm:categories">
<ref bean="categoryPropertyDecorator"/>
</entry>
<entry key="db:isSyncedToDropbox">
<ref bean="syncedToDropbox"/>
</entry>
</map>
</property>
<property name="userPermissions">
<list>
<value>CancelCheckOut</value>
<value>ChangePermissions</value>
<value>CreateChildren</value>
<value>Delete</value>
<value>Write</value>
</list>
</property>
</bean>

Now everything is copacetic.

Comment by Jared Ottley [ 02-Apr-12 ]

Following Mike Hatfield's suggestion we have something that works: map merging the decoratedProperties.

Example:

<bean id="dropboxApplicationScriptUtils" parent="applicationScriptUtils">
<property name="decoratedProperties">
<map merge="true">
<entry key="db:isSyncedToDropbox">
<ref bean="syncedToDropbox"/>
</entry>
</map>
</property>
</bean>

So in short create a custom bean where the parent is the applicationScriptUtils bean. Add a single property: decoratedProperties. In the map tag add the attribute merge="true". Add the entries you want merged to the OTB decoratedProperties property map.

Comment by Alfresco QA Team (Inactive) [ 26-Jul-13 ]

Closed as not a bug

Generated at Tue Aug 04 07:19:51 BST 2020 using JIRA 7.6.3#76005-sha1:8a4e38d34af948780dbf52044e7aafb13a7cae58.