Community Tip - Need to share some code when posting a question or reply? Make sure to use the "Insert code sample" menu option. Learn more! X
Version: Windchill 12.0.2.18
Hi,
We are looking to create a Managed Baseline in our promotion request workflow for all mechanical assembly with the name *-01-g.asm
I have found the Article - CS371627 - How to create a baseline in a (promotion request) workflow? and the Article - CS25967 - How to programmatically create a managed baseline in Windchill PDMLink which give some ideas, but I am having some difficulty going deeper into the development.
The small step I have already succeed is the following :
Add an "Execute Expression" robot after the "Set State Approved" method Robot and the Notify By E-mail robot :
The code to execute to the expression call a custom class :
ext.sce.workflow.CreateBaseline.createBaseline(baselineName);
The content of the class is the following :
package ext.sce.workflow;
import wt.vc.baseline.ManagedBaseline;
import wt.util.WTException;
import wt.util.WTPropertyVetoException;
import wt.fc.PersistenceHelper;
public class CreateBaseline {
public static void createBaseline(String name) throws WTException {
try {
System.out.println("Start....");
ManagedBaseline myManagedBaseline = ManagedBaseline.newManagedBaseline();
myManagedBaseline.setName("test");
myManagedBaseline.setDescription("this is a test baseline");
myManagedBaseline = (ManagedBaseline) PersistenceHelper.manager.save(myManagedBaseline);
System.out.println("===> myManagedBaseline " + myManagedBaseline);
} catch (WTPropertyVetoException e) {
e.printStackTrace();
} catch (WTException e) {
e.printStackTrace();
}
}
}
When a CAD assembly is approved, a Managed Baseline is created in the Default folder of the Site.
Now the expectation is to create the ManagedBaseline in the folder of the primary object and add the collection of Baselineable CAD model to the baseline.
If I follow the example in the CS25967 in order to create the ManagedBaseline in the correct folder :
package ext.sce.workflow;
import wt.vc.baseline.ManagedBaseline;
import wt.part.WTPart;
import wt.fc.WTObject;
import wt.folder.Folder;
import wt.folder.FolderEntry;
import wt.folder.FolderHelper;
import wt.inf.container.WTContainer;
import wt.inf.container.WTContainerRef;
public class CreateBaseline_1 {
public static void createBaseline(WTPart part,String ContainerName) throws Exception {
System.out.println("Start....");
ManagedBaseline baselineObj = ManagedBaseline.newManagedBaseline();
baselineObj.setName("test");
baselineObj.setDescription("this is a test baseline");
baselineObj.setContainerReference((WTPart)primaryBusinessObject.getContainerReference());
WTContainerRef containerRef = WTContainerRef.newWTContainerRef(containerRef);
Folder folder = FolderHelper.service.getFolder("/Default/Baseline", containerRef);
FolderHelper.assignLocation((FolderEntry)baselineObj, folder);
baselineObj=(ManagedBaseline)wt.fc.PersistenceHelper.manager.save(baselineObj);
System.out.println("===> myManagedBaseline " +baselineObj);
}
}
There is an issue with the setContainerReference
Any idea how to solve this ?
Best regards,
Loïc
Solved! Go to Solution.
I looked at your code. There's more than setting the container reference that's wrong.
As is this code should not compile.
Is it correct to say primaryBusinessObject is the OOTB workflow variable? For now, I'll assume yes to that question.
primaryBusinessObject is a WTObject. There is no method getContainerReference() for a WTObject.
What you have now is this
baselineObj.setContainerReference((WTPart)primaryBusinessObject.getContainerReference());
There are four problems with this line ofcode.
Code should be as shown below.
Note, I simply went straight for the WTPart that you are passing to your method to get the container reference.
baselineObj.setContainerReference(part.getContainerReference());
Once you get past that part of your code the line of code below will be a problem.
Your method contains the following:
WTContainerRef containerRef = WTContainerRef.newWTContainerRef(containerRef);
However, the variable containerRef is never defined. And if it were why use it to create another WTContainerRef.
Why not use the same containerRef object in multiple places.
Also, public static void createBaseline(WTPart part,String ContainerName) throws Exception {
String ContainerName is never used in your method. Why have it?
Is String ContainerName the name of the container for the Baseline, which is not the same as the WTPart's container?
BTW, in Java, the convention to naming method arguments is that they always start with lowercase. Not critical of course but that's the convention. So, String ContainerName would be String containerName. But again, your method never uses it so why not remove this argument?
If your Baseline folder is in the same container as the WTPart (maybe it is, but maybe it's not). The following method should work for you.
public static void createBaseline(WTPart part) throws Exception {
System.out.println("Start....");
ManagedBaseline baselineObj = ManagedBaseline.newManagedBaseline();
baselineObj.setName("test");
baselineObj.setDescription("this is a test baseline");
WTContainerRef containerRef = WTContainerRef.newWTContainerRef(part.getContainerReference());
baselineObj.setContainerReference(containerRef);
Folder folder = FolderHelper.service.getFolder("/Default/Baseline", containerRef);
FolderHelper.assignLocation((FolderEntry) baselineObj, folder);
baselineObj = (ManagedBaseline) wt.fc.PersistenceHelper.manager.save(baselineObj);
System.out.println("===> myManagedBaseline " + baselineObj);
}
David
I looked at your code. There's more than setting the container reference that's wrong.
As is this code should not compile.
Is it correct to say primaryBusinessObject is the OOTB workflow variable? For now, I'll assume yes to that question.
primaryBusinessObject is a WTObject. There is no method getContainerReference() for a WTObject.
What you have now is this
baselineObj.setContainerReference((WTPart)primaryBusinessObject.getContainerReference());
There are four problems with this line ofcode.
Code should be as shown below.
Note, I simply went straight for the WTPart that you are passing to your method to get the container reference.
baselineObj.setContainerReference(part.getContainerReference());
Once you get past that part of your code the line of code below will be a problem.
Your method contains the following:
WTContainerRef containerRef = WTContainerRef.newWTContainerRef(containerRef);
However, the variable containerRef is never defined. And if it were why use it to create another WTContainerRef.
Why not use the same containerRef object in multiple places.
Also, public static void createBaseline(WTPart part,String ContainerName) throws Exception {
String ContainerName is never used in your method. Why have it?
Is String ContainerName the name of the container for the Baseline, which is not the same as the WTPart's container?
BTW, in Java, the convention to naming method arguments is that they always start with lowercase. Not critical of course but that's the convention. So, String ContainerName would be String containerName. But again, your method never uses it so why not remove this argument?
If your Baseline folder is in the same container as the WTPart (maybe it is, but maybe it's not). The following method should work for you.
public static void createBaseline(WTPart part) throws Exception {
System.out.println("Start....");
ManagedBaseline baselineObj = ManagedBaseline.newManagedBaseline();
baselineObj.setName("test");
baselineObj.setDescription("this is a test baseline");
WTContainerRef containerRef = WTContainerRef.newWTContainerRef(part.getContainerReference());
baselineObj.setContainerReference(containerRef);
Folder folder = FolderHelper.service.getFolder("/Default/Baseline", containerRef);
FolderHelper.assignLocation((FolderEntry) baselineObj, folder);
baselineObj = (ManagedBaseline) wt.fc.PersistenceHelper.manager.save(baselineObj);
System.out.println("===> myManagedBaseline " + baselineObj);
}
David
Thank you for your time and for the detailed answer. It helps me a lot to progress.
However, I try to launch the method via an "Execute Expression" robot but without success.
I can't find the solution to assign the value of the WTPart...
I try several expression like this :
wt.part.WTPart part = (wt.part.WTPart) primaryBusinessObject;
ext.sce.workflow.CreateBaseline.createBaseline(part);
The Syntax check is complete but when running the workflow,
the error is the following :
wt.util.WTException: java.lang.ClassCastException: class wt.maturity.PromotionNotice cannot be cast to class wt.part.WTPart (wt.maturity.PromotionNotice and wt.part.WTPart are in unnamed module of loader 'app')
I also tried another method by creating another robot "Execute Expression" to extract the list of objects related to the promotion request which I know works:
wt.fc.QueryResult promotables = wt.maturity.MaturityHelper.service.getPromotionTargets((wt.maturity.PromotionNotice)primaryBusinessObject);
promObjList = new ArrayList<String>();
while(promotables.hasMoreElements()){
wt.fc.WTObject promotable = (wt.fc.WTObject) promotables.nextElement();
promObjList.add(promotable.getDisplayIdentity());
}
The promObjList is define as a java.util.ArrayList and the content of the value in my example is the following : [Assembly - sc-test-01-g.asm, Q.1]
The syntax check of the following expression give an error: incompatible types: ArrayList cannot be converted to WTPart
ext.sce.workflow.CreateBaseline.createBaseline(promObjList);
I realize that it is not so simple. A tip would be welcome!
Kind regards,
Loïc
In your case the promaryBusinessObject is the PromotionNotice
You need to get the target objects getPromotionTargets .
But your code use ArrayList with a String and you probably try to put the ArrayList to the Part type that is not possible.
You need to get the object from the promotables list where the WTPart is return by the getPromotionTargets .
while (promotables.hasMoreElements())
{
Object obj = promotables.nextElement();
if (obj instanceof WTPart)
{
WTPart wtp = (WTPart) obj;
}
}
in your case you need to just add the full class definition. WTPart = wt.part.WTPart .... PetrH