Attribute customizations implemented in java
I'd like to set an attribute value of a work item based on other attribute of other work items.
I'm implementing this customization in java and I've followed at the end of Page the instructions in https://jazz.net/wiki/bin/view/Main/AttributeCustomization
My test have been developed and tested with RTC version 3.0.1.2
This is what I have discovered so far.
1. Editing the plug-in configuration I've added the following dependencies:
- com.ibm.team.workitem.common
- com.ibm.team.repository.common
- org.eclipse.core.runtime
So I had to manually configure its mandatory attributes.
2. Just to test, I've created a simple plugin (without make reference to any services) that return just a List of strings. I've provisioned the RTC server and Eclipse clients and configured attribute to use the new customization. Until now the attribute customization implemented in Java works fine.
3. To retrieve Summary attribute of other work items that my class should return I've modified my class:
package com.ibm.team.workitem.customization; import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.IProgressMonitor; import com.ibm.team.common.ProcessProperty; import com.ibm.team.process.common.IProjectAreaHandle; import com.ibm.team.repository.common.TeamRepositoryException; import com.ibm.team.repository.service.AbstractService; import com.ibm.team.workitem.common.IQueryCommon; import com.ibm.team.workitem.common.IWorkItemCommon; import com.ibm.team.workitem.common.expression.AttributeExpression; import com.ibm.team.workitem.common.expression.IQueryableAttribute; import com.ibm.team.workitem.common.expression.IQueryableAttributeFactory; import com.ibm.team.workitem.common.expression.QueryableAttributes; import com.ibm.team.workitem.common.internal.attributeValueProviders.IConfiguration; import com.ibm.team.workitem.common.internal.attributeValueProviders.IValueSetProvider; import com.ibm.team.workitem.common.model.AttributeOperation; import com.ibm.team.workitem.common.model.IAttribute; import com.ibm.team.workitem.common.model.IWorkItem; import com.ibm.team.workitem.common.query.IQueryResult; import com.ibm.team.workitem.common.query.IResolvedResult; import com.ibm.team.workitem.service.IQueryServer; public class SetValueApplicazione extends AbstractService implements IValueSetProviderThen I've manually updated the plugin.xml adding an extensionService with prerequisite:{ private static List summaryList = new ArrayList (); public List getValueSet(IAttribute attribute, IWorkItem workItem, IWorkItemCommon workItemCommon, IConfiguration configuration, IProgressMonitor monitor) throws TeamRepositoryException { IProjectAreaHandle projectAreaHandle = workItem.getProjectArea(); IQueryableAttributeFactory queryAttrFactory = QueryableAttributes.getFactory(IWorkItem.ITEM_TYPE); IQueryableAttribute type = queryAttrFactory.findAttribute(projectAreaHandle,IWorkItem.TYPE_PROPERTY, workItemCommon.getAuditableCommon(), null); AttributeExpression typeExpr = new AttributeExpression(type,AttributeOperation.EQUALS,ProcessProperty.APPLICAZIONE_WI_TYPE); IQueryCommon queryService = getService(IQueryCommon.class); IQueryResult > results = queryService.getResolvedExpressionResults(projectAreaHandle, typeExpr, IWorkItem.FULL_PROFILE); if (results.getResultSize(null).getTotal()>0){ while (results.hasNext(null)) { IResolvedResult resolvedResultWI = results.next(null); IWorkItem resolvedWi = resolvedResultWI.getItem(); String resolvedWiSummary = resolvedWi.getHTMLSummary().toString(); summaryList.add(resolvedWiSummary); } } return summaryList; } }
The getservice does not work and I get this error:
ERROR com.ibm.team.workitem.common - 'com.ibm.team.workitem.valueproviders.VALUE_SET_PROVIDER._fyQ-4DpREeKUUtygZ9ae3g' java.lang.IllegalArgumentException: The service 'com.ibm.team.workitem.customization.SetValueApplicazione@333c333c' failed to find the required service 'interface com.ibm.team.workitem.common.IQueryCommon'. CheckHave someone else try it?in plugin.xml. at com.ibm.team.repository.service.AbstractService.getService(AbstractService.java:734) at com.ibm.team.workitem.customization.SetValueApplicazione.getValueSet(SetValueApplicazione.java:40) at com.ibm.team.workitem.common.internal.attributeValueProviders.AttributeValueProviderRegistry$SafeValueSetProvider.getValueSet(AttributeValueProviderRegistry.java:63) at com.ibm.team.workitem.common.internal.model.impl.AttributeImpl.getValueSet(AttributeImpl.java:915) at com.ibm.team.workitem.common.internal.model.impl.AttributeImpl.getValueSet(AttributeImpl.java:902) at com.ibm.team.workitem.service.internal.rest.ValueSetRestService.getValueSet(ValueSetRestService.java:225) at com.ibm.team.workitem.service.internal.rest.ValueSetRestService.getValueSet(ValueSetRestService.java:65) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:79) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:618) at org.eclipse.soda.sat.core.internal.record.ExportProxyServiceRecord.invoke(ExportProxyServiceRecord.java:370) at org.eclipse.soda.sat.core.internal.record.ExportProxyServiceRecord.access$0(ExportProxyServiceRecord.java:356) at org.eclipse.soda.sat.core.internal.record.ExportProxyServiceRecord$ExportedServiceInvocationHandler.invoke(ExportProxyServiceRecord.java:56) at $Proxy806.getValueSet(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:79) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:618) at com.ibm.team.repository.servlet.AbstractTeamServerServlet.doModelledRestService(AbstractTeamServerServlet.java:504) at com.ibm.team.repository.servlet.AbstractTeamServerServlet.handleRequest2(AbstractTeamServerServlet.java:1869) at com.ibm.team.repository.servlet.AbstractTeamServerServlet.handleRequest(AbstractTeamServerServlet.java:1725) at com.ibm.team.repository.servlet.AbstractTeamServerServlet.service(AbstractTeamServerServlet.java:1634) at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) at org.eclipse.equinox.http.registry.internal.ServletManager$ServletWrapper.service(ServletManager.java:180) at org.eclipse.equinox.http.servlet.internal.ServletRegistration.handleRequest(ServletRegistration.java:90) at org.eclipse.equinox.http.servlet.internal.ProxyServlet.processAlias(ProxyServlet.java:111) at org.eclipse.equinox.http.servlet.internal.ProxyServlet.service(ProxyServlet.java:75) at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) at org.eclipse.equinox.servletbridge.BridgeServlet.service(BridgeServlet.java:120) at com.ibm.team.repository.server.servletbridge.JazzServlet.service(JazzServlet.java:76) at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:172) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:563) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117) at org.apache.catalina.authenticator.SingleSignOn.invoke(SingleSignOn.java:420) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:879) at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665) at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528) at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81) at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689) at java.lang.Thread.run(Thread.java:811)
Is it possibile to add an extension service with prerequisites like IQueryCommon to the extension point com.ibm.team.workitem.common.attributeValueProviders ?
Thanks for your time,
Saverio
2 answers
There was a small issue with the schema, which I reported and should be fixed already. I can only speak about 4.0.x and it works there. I can't say why I won't work with the 3.0.1.2 version.
Comments
Hi Ralph,
wow your blog entry is tremendous and has helped me to resolve most of my issues.
The last point from Saverio about declaring a "required service" as a "prerequisite" in the plugin.xml I still could not figure out unfortunately. I had a look at the XML Schema for the valuesetprovider. It seems that there is no prerequisite element defined for it so I wonder how one could include services like e.g. "IProcessService" for it.
Thanks
Hi Dimitrios,
I have only tried this out - keep in mind, I have no more documentation available thane anyone else. I poked around what I could do - with a special focus on areas asked a lot on these forums. I did look into the SDK and looked for implementers of the various interfaces used and no example I looked at implemented anything more than the interface.
I am not sure if you can access other services that you can't reach directly. You would likely have try to extend AbstractService and then use getService(). If you do, you would likely have to provide the prerequisites. This would be worth a try. The issue is that at least some of the providers run in client as well as server context, so you might not be able to use AbstractService.getService(). Maybe you would have to use the client libraries, but maybe that won't work either in some of the contexts. So I am not sure you can access other data not accessible from the IWorkItemCommon that gets passed.
Hi Dimitrios,
I looked into my code and there is something that right jumped into my face - which will result in me editing or deleting the comment above. I realize I have thought about it in the past and couldn't make up my mind if it is possible or not to access other services.
The reason is, the provides have to run on client and server, at least some of them. So I think mostly only the common libraries. It might be impossible to access services under these circumstances.
Hi Ralph,
If this is the case that the providers can partially run on the client, than you might very well be right!
I had that hunch myself, after I saw that it is not possible to declare required services for them in the plugin.xml
Maybe there is another way of injecting these services into the providers but this looks like a tough one.
Hi Ralph,
If this is the case that the providers can partially run on the client, than you might very well be right!
I had that hunch myself, after I saw that it is not possible to declare required services for them in the plugin.xml
Maybe there is another way of injecting these services into the providers but this looks like a tough one.
Some might only run on the server. I'd look up if I published which ones in the process enactment workshop in the library. I have also seen that different attribute types behave different with calculated values. E.g. I think work items only show after the save.
I will try to find out more. You can reach a good amount of services already, but I think not all. Maybe you can code providers for the client and for the server. i have not tried that, and I don't think I want to go that route either.
Please also be aware that some things, e.g. JavaScript does not work in the Plain Java Client Libraries. I assume if the Java Providers would work with it, you would have to deploy them with the client libraries. I am not sure how that would work, if at all.
With Plain Java, you would likely have to provide the data in the automation anyway.
Far as I can tell, there is no structure for executing the java eclipse plugin extensions while running a Plain Java client application. you don't have the full eclipse and osgi frameworks available.
I had recently the same task - I needed to work with IQueryCommon service inside com.ibm.team.workitem.common.attributeValueProviders extension point.
At last I have found a quite simple solution, which doesn't need 'prerequisites' section in the plugin.xml:
IQueryCommon queryService = (IQueryCommon)workItemCommon.getAuditableCommon().getPeer(IQueryCommon.class);
The getPeer() method in the IAuditableCommon interface is marked as Deprecated, but this method is still used in several non-deprecated methods (see, for instance, com.ibm.team.workitem.common.internal.AuditableCommon class).
The IQueryCommon service retrieved as described above works fine in my ICondition component, but the extra testing would be quite appropriate of course. I would like to apologize in advance if this solution has any latent downsides.
Comments
Dimitrios Dentsas
Dec 06 '13, 9:21 a.m.Hi, have you found a solution to this problem yet?
Regards,
Dimitrios