cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

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

Retrieving a Attribute from an Object Using an Expression in a Workflow

Toby.Pettit
12-Amethyst

Retrieving a Attribute from an Object Using an Expression in a Workflow

Hi All,

I need to retrieve an attribute ("Operation") which which I have added to a Change Notice in a workflow expression - since the value of this attribute alters downstream activities.

So far I have got as far as:

wt.change2.WTChangeOrder2 co = (wt.change2.WTChangeOrder2)primaryBusinessObject;

String coOperation = ...

Also by using the above code, does it matter that I want to retrieve the attribute from a soft type of the change notice.

Any help would be great.

Toby

ACCEPTED SOLUTION

Accepted Solutions

You can try the code below as it works fine -

wt.change2.WTChangeOrder2 cm1 = (wt.change2.WTChangeOrder2) primaryBusinessObject;

wt.iba.value.IBAHolder ibaHolder1 = (wt.iba.value.IBAHolder)cm1;

ibaHolder1 =wt.iba.value.service.IBAValueHelper.service.refreshAttributeContainer(ibaHolder1, null, null, null);

wt.iba.value.DefaultAttributeContainer attributeContainer =(wt.iba.value.DefaultAttributeContainer) ibaHolder1.getAttributeContainer();

wt.iba.definition.service.StandardIBADefinitionService defService = new wt.iba.definition.service.StandardIBADefinitionService();

wt.iba.definition.litedefinition.AttributeDefDefaultView attributeDefinition = defService.getAttributeDefDefaultViewByPath("PhoneNumber"); //Here give the attribute name instead of "PhoneNumber".

wt.iba.value.litevalue.AbstractValueView svc = attributeContainer.getAttributeValues(attributeDefinition)[0];

IBAValue_PhoneNumber = svc.getLocalizedDisplayString();

View solution in original post

24 REPLIES 24

It would help to learn the wt.query and wt.fc packages. Short of that, just use info engine.

public static Group test(WTObject primaryBusinessObject) throws Exception {

String instance = WTProperties.getLocalProperties().getProperty("wt.federation.ie.VMName");

IeService service = new IeService();

ObjectWebject webject = new ObjectWebject("QUERY-OBJECTS");

webject.setService(service);

webject.setParam("INSTANCE",instance);

webject.setParam("OBJECT_REF",PersistenceHelper.getObjectIdentifier(primaryBusinessObject).getStringValue());

webject.setParam("ATTRIBUTES","*");

webject.invoke();

Group group = webject.getService().getGroup();

return group;

}

group.getAttributeValue(0, "Operation");

p.s. Don't hardcode this inside an expression. And it has to run on the MethodServer. Your servlet engine won't like it.

We do this very often in many workflow templates, without using webjects - just need simple Java code.


But - In 10.0, check out the new GUI-based way to do this that is available - very nice.

We do this very often in many workflow templates, without using webjects - just need simple Java code.


But - In 10.0, check out the new GUI-based way to do this that is available - very nice.

Hi Mike,

Currently we are only on 9.1 (need a proE upgrade first), so will not be getting 10.0 for about another year. So if you can do it in a workflow then can you please tell me the java expression I need? Or at least where precisely I should be looking.

Also, is the Windchill Javadoc the only means of learning the packages as Matthew has suggested I do?

Regards,

Toby

I know of two other ways to retrieve IBA values.

1. Would be to write your own queryspec, joining your pbo to the *value table, and joining that to the *definition table.

2. Uses your pbo's AttributeContainer, and retrieves the AttributeDefDefaultViews and AbstractValueViews.

1 is the approach we use when writing reports. 2 is the approach we use when dealing with single objects where we want to get/set values, but involves lots of code.

Mike, can you share your method?

Toby, you're kind of in a tough spot if you don't have an expert on hand. When I'm trying to figure something new out, I'll usually start with looking into how PTC does it. Knowing how they structure their packages and name their classes helps.

If you were doing something with documents, you may start by looking in the wt.doc package. There you'd find wt.doc.WTDocumentHelper.

If you were doing something with parts, you may start by looking in the wt.part package. There you'd find wt.part.WTPartHelper

If you were doing something with access control, you may start by looking in the wt.access package. There you'd find wt.access.AccessControlHelper

Beyond that, "helpers" often have "managers" or "services." So you could end up with WTDocumentHelper.service.* etc

I've been browsing the Javadoc and it is helping a lot. I'm sort of okay if I know what I am looking for.

These questions I am asking are generally related to my "Wish List" of features I want to add but are not a necessity for this initial implimentation, they will just make administration easier in a number of ways. I do therefore have time to get to grips with this (I have only known what Windchill is for a month and a half and been using it for a month). My only problem is where to get the knowledge from without running a big consultancy bill up.

I found this on another post (http://communities.ptc.com/message/165328😞

wt.fc.QueryResult qr = null;

wt.doc.WTDocument RCIDFDoc=((wt.doc.WTDocument)primaryBusinessObject);

ext.generic.util.IBAUtil objHelper = new

ext.generic.util.IBAUtil(RCIDFDoc);

ApplicationNum=objHelper.getIBAValue("ApplicationNum");

BusinessCategory=objHelper.getIBAValue("BusinessCategory");

EstimatedNetSales=objHelper.getIBAValue("EstimatedNetSales");

FGNum=objHelper.getIBAValue("FGNum");

I tweaked this to the following:

result = "NAY";

wt.fc.QueryResult qr = null;

wt.change2.WTChangeOrder2 co =((wt.change2.WTChangeOrder2)primaryBusinessObject);

ext.generic.util.IBAUtil objHelper = new ext.generic.util.IBAUtil(co);

String selectedOption=objHelper.getIBAValue("UpdateJobs");

if (selectedOption.equals("No")) {

result = "YAY";

}

It came up with no errors when I first compiled it, I tested it, it failed, now when I compile it it comes up with the following error:

Checking Syntax...

/apps/ptc/Windchill_9.1/Windchill/tmp/WfExpression8906920.java:39: package ext.generic.util does not exist

ext.generic.util.IBAUtil objHelper = new ext.generic.util.IBAUtil(co);

^

/apps/ptc/Windchill_9.1/Windchill/tmp/WfExpression8906920.java:39: package ext.generic.util does not exist

ext.generic.util.IBAUtil objHelper = new ext.generic.util.IBAUtil(co);

^

2 errors

Syntax check complete.

It give anyone any ideas?

ext.generic.util.IBAUtil was something custom they created. It's not OOTB, as far as I know

I think you are right, I have seen that kind of thing referenced a number of times and it definitely is not a package in our system.

ext is a custom class, however, we get booleans, strings, ints, longs from workflows with just java.

The code below can be tweaked to get different types from the workflows. We rolled these methods into a class in ext package as well.

Setting can also be done with a little more code as well. This code is not supported and in 10 there is a much more efficent way with code to get these variables from the workflow. Since you were asking for a sting I only included String but by chaning the casting around you should be able to get the rest of the types.

//Declares a attributeContainer of type DefaultAttributeContainer and gets the container with the function getAttributeContainer()
wt.iba.value.DefaultAttributeContainer attributeContainer=(wt.iba.value.DefaultAttributeContainer)ibaHolder.getAttributeContainer();

//Try Block used to catch a blank String
try
{
//Defines a attributeDefinition of type AttributeDefDefaultView that gets the variable in question (name in type/atribute manager.)
wt.iba.definition.litedefinition.AttributeDefDefaultView attributeDefinition=defService.getAttributeDefDefaultViewByPath("your var name here");
System.out.println("Size:"+attributeContainer.getAttributeValues(attributeDefinition).length);

//Declares attValue of type StringValueDefaultView (string, change for diff values) and sets it equal to the getAttributeValues function
wt.iba.value.litevalue.StringValueDefaultView attValue= (wt.iba.value.litevalue.StringValueDefaultView)attributeContainer.getAttributeValues(attributeDefinition)[0];

//Sets the StringVar = to previously defined attvalue.
StringVar=attValue.getValue();
System.out.println("StringVar");
}
catch (Exception e){System.out.println("Error getting attribute value,"+e.getMessage());}

This gets the value of a string named in the getAttributeDefDefaultViewByPath. This doesnt get multivalue strings, you will have to do more tweaking to get that a well but it is possiable.

You probably have to "refresh" your attribute container before calling these methods.

Docs/Parts/ChangeRequests/etc implement IBAHolder

WTDocument doc = findRandomDocument();

doc = (WTDocument)IBAValueHelper.service.refreshAttributeContainer(new IBAHolder[] { doc })[0];

Matt is right. I forgot the first 2 lines of the method. OPS!

//Declares a ibaHolder of type IBAHolder and sets it equal to IBAHolder of the PBO from the function refreshAttributeContainer
wt.iba.value.IBAHolder ibaHolder=wt.iba.value.service.IBAValueHelper.service.refreshAttributeContainer((wt.iba.value.IBAHolder)primaryBusinessObject, null, null, null);

//Declares a DefService of type StandardIBADefinitionService and sets it to StandardIBADefinitionService function
wt.iba.definition.service.StandardIBADefinitionService defService=new wt.iba.definition.service.StandardIBADefinitionService();

Well I tried the following (which is a combination of both of Matthew Hoover's posts):

//Declares a ibaHolder of type IBAHolder and sets it equal to IBAHolder of the PBO from the function refreshAttributeContainer

wt.iba.value.IBAHolder ibaHolder=wt.iba.value.service.IBAValueHelper.service.refreshAttributeContainer((wt.iba.value.IBAHolder)primaryBusinessObject, null, null, null);

//Declares a DefService of type StandardIBADefinitionService and sets it to StandardIBADefinitionService function

wt.iba.definition.service.StandardIBADefinitionService defService=new wt.iba.definition.service.StandardIBADefinitionService();

//Declares a attributeContainer of type DefaultAttributeContainer and gets the container with the function getAttributeContainer()

wt.iba.value.DefaultAttributeContainer attributeContainer=(wt.iba.value.DefaultAttributeContainer)ibaHolder.getAttributeContainer();

//Try Block used to catch a blank String

try

{

//Defines a attributeDefinition of type AttributeDefDefaultView that gets the variable in question (name in type/atribute manager.)

wt.iba.definition.litedefinition.AttributeDefDefaultView attributeDefinition=defService.getAttributeDefDefaultViewByPath("UpdateJobs");

System.out.println("Size:"+attributeContainer.getAttributeValues(attributeDefinition).length);

//Declares attValue of type StringValueDefaultView (string, change for diff values) and sets it equal to the getAttributeValues function

wt.iba.value.litevalue.StringValueDefaultView attValue= (wt.iba.value.litevalue.StringValueDefaultView)attributeContainer.getAttributeValues(attributeDefinition)[0];

//Sets the StringVar = to previously defined attvalue.

String StringVar=attValue.getValue();

System.out.println("StringVar");

if (StringVar.equals("No")) {

result = "SUCCESS";

} else {

result = "FAIL";

}

}

catch (Exception e){System.out.println("Error getting attribute value,"+e.getMessage());}

The parts in bold that I either added or changed or to suit my needs or because the syntax checker highlighted an error.

When I syntax check it, it says that there are no errors, however when it comes to runtime it falls over with a nullPointer exception?

The attribute I am currently trying to pull up is called "Update Jobs" (logical identifier "UpdateJobs") and it is on a change notice - I tried using both as the parameters in the getAttributeDefDefaultViewByPath() method.

Am I right in thinking this can go in a wf and does not need to be in a class?

The server logs are saying the following:

Fri 11/18/11 05:43:42: WfPropagationQueue.PollingThread: ECN name: Attribute Grabber 004

Fri 11/18/11 05:43:42: WfPropagationQueue.PollingThread: Size:0

Fri 11/18/11 05:43:42: WfPropagationQueue.PollingThread:Error getting attribute value,0

Fri 11/18/11 05:43:42: WfPropagationQueue.PollingThread: wt.util.WTException: wt.workflow.definer.InvalidEventException: null event

Fri 11/18/11 05:43:42: WfPropagationQueue.PollingThread: Nested exception is: wt.workflow.definer.InvalidEventException: null event

(I got an identical log entry for each of the attempts I made)

Put it in a main and see what it does. add e.printStackTrace() so you can see where it fails.

Change System.out.println("StringVar") to System.out.println("StringVar: " + StringVar); so you know what's in it. Can it be null? Account for that.

You can try the code below as it works fine -

wt.change2.WTChangeOrder2 cm1 = (wt.change2.WTChangeOrder2) primaryBusinessObject;

wt.iba.value.IBAHolder ibaHolder1 = (wt.iba.value.IBAHolder)cm1;

ibaHolder1 =wt.iba.value.service.IBAValueHelper.service.refreshAttributeContainer(ibaHolder1, null, null, null);

wt.iba.value.DefaultAttributeContainer attributeContainer =(wt.iba.value.DefaultAttributeContainer) ibaHolder1.getAttributeContainer();

wt.iba.definition.service.StandardIBADefinitionService defService = new wt.iba.definition.service.StandardIBADefinitionService();

wt.iba.definition.litedefinition.AttributeDefDefaultView attributeDefinition = defService.getAttributeDefDefaultViewByPath("PhoneNumber"); //Here give the attribute name instead of "PhoneNumber".

wt.iba.value.litevalue.AbstractValueView svc = attributeContainer.getAttributeValues(attributeDefinition)[0];

IBAValue_PhoneNumber = svc.getLocalizedDisplayString();

Toby.Pettit
12-Amethyst
(To:dsolat)

Apologies I thought it did not work, I got an error but I think I may have made a mistake with the attribute logicID.

It is now working, thankyou!

Regards,

Toby

If you are using 10.0 there are much simpler programmatic methods for getting and setting of IBA values -

More info can be found in the javadoc - com.ptc.core.lwc.server.LWCNormalizedObject

Here are some examples

Example usage:

CREATE

LWCNormalizedObject obj = new LWCNormalizedObject("com.acme.AcmePart",null,null);

obj.load("name","number");

obj.set("name","my name");

obj.set("number","12345");

obj.persist();

RETRIEVE

LWCNormalizedObject obj = new LWCNormalizedObject(my_persistable,null,null,null);

obj.load("name","number");

Object nameValue = obj.get("name");

Object numberValue = obj.get("number");

UPDATE

LWCNormalizedObject obj = new LWCNormalizedObject(my_persistable,null,Locale.US,new UpdateOperationIdentifier());

obj.load("attributeA","attribtueB");

obj.set("attributeA",new Boolean(true));

obj.set("attribtueB","PURPLE");

obj.apply();

...

PersistenceHelper.manager.modify(my_persistable);

Thanks Jeffrey, unfortunately we are stuck with 9.1 for the short-mid term. I will most likely move to this cleaner approach when we do move to 10 though.

Regards,

Toby

Hi Jeffrey ,

I want to update (revise) an existing document. I have the code for revision.

After revising the document and before using the persistencehelper.save i use the above mentioned code to update iba values on the new version. But that results in two values on the iba.

for e.g

Doc A.1 - Attribute1=123

Doc B.1 - Attribute1=123,345

I also see the values from previous revision. Can you help me in clearing out the Iba values before i store new values.

Because the above scenatio gives a me exception on single value constraint attributes.

Also the Persistencehelper modify does not work as it asks to first checkout the object.So i use the code above first and then the SAVE method before storing the object for the first time in DB.

I am not sure these methods are supported in that use case - why don't you update the values after the revise?

Hi Jeffrey

Once the object is persisted then the PersistenceHelper.manager.modify(my_persistable); api gives a error.

Object is not ready for modification please check out the object. And i dont want to iterate the object.

I have raised a case with PTC for this.

getting this error when checking syntax

Checking Syntax...

C:\ptc\Windchill_10.2\Windchill\temp\WfExpression831571.java:39: error: cannot find symbol

IBAValue_VM_Name= VM_Name

^

symbol: variable IBAValue_VM_Name

location: class WfExpression831571

Note: C:\ptc\Windchill_10.2\Windchill\temp\WfExpression831571.java uses unchecked or unsafe operations.

Note: Recompile with -Xlint:unchecked for details.

1 error

Syntax check complete.

Toby.Pettit
12-Amethyst
(To:zsmith)

Hi Zane,

Without seeing your full code I cannot comment too much on your error.

It seems though that you are trying to use a variable "IBAValue_VM_Name" which you have not declared anywhere in your code and this is the source of your error.

Regards,

Toby

Announcements


Top Tags