Uploaded image for project: 'Alfresco'
  1. Alfresco
  2. ALF-13038

Property Decorators require overwriting core files

    Details

    • Type: Bug
    • Status: Closed (View Workflow)
    • Priority: Unprioritized
    • Resolution: Not a bug
    • Affects Version/s: 4.0 Enterprise
    • Fix Version/s: None
    • Component/s: Share Application
    • Security Level: external (External user)
    • Labels:
      None

      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

        Attachments

          Activity

          Hide
          jottley Jared Ottley added a comment -

          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.

          Show
          jottley Jared Ottley added a comment - 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.
          Hide
          jottley Jared Ottley added a comment -

          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.

          Show
          jottley Jared Ottley added a comment - 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.
          Hide
          alfrescoqa Alfresco QA Team added a comment -

          Closed as not a bug

          Show
          alfrescoqa Alfresco QA Team added a comment - Closed as not a bug

            People

            • Assignee:
              closedissues Closed Issues
              Reporter:
              jottley Jared Ottley
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:
                Date of First Response: