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
Hi Everyone,
I am trying to set Classification attributes on a WTPart for windchill 11 M30 CPS 14. I already have the binding attribute set, I am just having trouble setting the attributes. I was able to get this to work using the PersistableAdapter and using the AttributeTypeIdentifier's toLogicalForm()) on my local install of Windchill 11 CPS15. However this doesn't work on the Client's CPS 14 Windchill because toLogicalForm returns null. I am not sure if this is a bug in CPS14 or if I am going about saving the attributes incorrectly.
/**
*
* @param workable - The Object being updated
* @param bindingAttributeName - This is the name of the IBA for the classification binding
* @param classificationNode - this is the name of the Classification Node to set into bindingAttributeName
* @param attributeValueMap - <String,String> = <attribute name, value> - classification attributes and values.
* @param leaveCheckedOut - use this if continue to edit the workabale
* @return
* @throws WTException
* @throws WTPropertyVetoException
*/
public static Persistable setClassificationAttributes(Workable workable, String bindingAttributeName, String classificationNode, Map<String, String> attributeValueMap,boolean leaveCheckedOut) throws WTException, WTPropertyVetoException{ // TODO Need logic in case it is checked out to another user boolean isOrgianllyCheckedout = WorkInProgressHelper.isCheckedOut(workable, SessionHelper.getPrincipal()); // check out the object if(!isOrgianllyCheckedout) { workable = WorkInProgressHelper.service.checkout(workable, WorkInProgressHelper.service.getCheckoutFolder(), null).getWorkingCopy(); } else { if( !WorkInProgressState.WORKING.equals(workable.getCheckoutInfo().getState())) { workable = WorkInProgressHelper.service.workingCopyOf(workable); } } PersistableAdapter adapter = new PersistableAdapter(workable,null,SessionHelper.getLocale(), new UpdateOperationIdentifier()); if (!StringUtils.isEmpty(classificationNode)) { adapter.load(bindingAttributeName); adapter.set(bindingAttributeName,classificationNode); adapter.apply(); } if (attributeValueMap != null && !attributeValueMap.isEmpty()) { Iterator it = attributeValueMap.entrySet().iterator(); while (it.hasNext()) { Entry entry = (Entry) it.next();
// Also check for string "undefined" if(entry.getValue() != null && !UNDEFINED.equalsIgnoreCase((String)entry.getValue())){ adapter.load((String)entry.getKey()); adapter.set((String)entry.getKey(), entry.getValue()); // ERROR HAPPENS HERE, see note below code section. adapter.apply(); } } } PersistenceHelper.manager.modify(workable); if(!leaveCheckedOut) { workable = WorkInProgressHelper.service.checkin(workable, null); } return workable; }
However the error happens on the adapter.set() because the key is null(obviously this is bad) on the client's Windchill CPS14 . The key is null because the data is coming from atSummary.getAttributeTypeIdentifier().toLogicalForm()) which returns null when looping through AttributeTypeSummaryHelper.SERVICE.getATS() from the classificationFacadeInstance.getClassificationAttributes(). However, This does returns a value on my local Windchill CPS15 (Note: it uses demo classification data).
So basically my questions is whether the PersistanceAdapter is the right api to use to save classification attributes. If this is the right API, is the logicalform the right value to pass to the load method? I tried internalName which is ideal, but that is not found in the load() method on either system.
adapter.set((String)entry.getKey(), entry.getValue());
What is the value you are setting here? Is it the display value of the classification node ?
You should pass the 'internal name' of the classification node that you are trying to set.
That should work.
Thank you wcpeetc,
The issue was that the client had not set the Logical Identifier attribute on the "Manage Reusable Attributes" for the attributes they used for the Classification. Once this was set then everything worked fine. It's been over a year since I looked at this, but I remember the internal name not working and had to use the Logical Identifier (was set the same value as internal name). I don't see it now, but the internalName looked to be returning generated classification IDs which did not work in the PersistanceAdapter. I don't see those values now in the classification administrator so not sure if something changed since then.
We were fighting with loading classification attribute values, until reading this update.
We had loaded attributes without logical identifiers, trying to use the internal name for update.
After adding logical identifiers the loader started working.