Skip to main content
avillanueva
23-Emerald I
23-Emerald I
February 17, 2025
Question

How not update EPMDocument attributes. Need to include as-stored baseline

  • February 17, 2025
  • 3 replies
  • 1556 views

So my team wrote a little utility to update some attributes on objects. Worked great but we are seeing out error and need to make a fix for drawings and assemblies. This is how we were checking out the objects:

//Checkout document
checkedOutDoc = (EPMDocument)WorkInProgressHelper.service.checkout(document, WorkInProgressHelper.service.getCheckoutFolder(), "").getWorkingCopy();

Everything as fine, object was iterated and the attribute were updated. Fast forward a few weeks and a user reported seeing the following.

 

avillanueva_1-1739806077264.png

This was odd since I remember kicking off a scheduled publishing job on these items myself and I am sure I selected to use the as-stored baseline. I attempted to republish this item again but in reading the WVS logs, I can see that it reports there is no as-stored baseline so uses latest as the alternative. Rut Roh Shaggy.

So cautionary tale. If anyone has the right sequence to update an object WITH the as-stored baseline and then check it in properly (bonus to trigger republishing), let me know. I will post what I find if I beat you to it. 

PS-As of now, I know there should be a way to turn off the warning on out of date representations. Not sure if that is something I want to do. If I wanted to fix manually, it would be to download the previous iteration as-stored, update the drawing object only, check out then check in from a workspace. Very tedious. 

 

3 replies

18-Opal
February 17, 2025

@avillanueva , to be clear this has nothing to do with updating attributes per se.

This is a publishing As Stored where the system does not recognize or does not have an As Stored baseline?

Or is the Visualization marked out-of-date when in fact it is not out-of-date?

avillanueva
23-Emerald I
23-Emerald I
February 17, 2025

Yes, nothing to do with updating the attributes. I think using the WorkInProgressHelper in that manner only checked out the drawing but since not in a workspace, the dependents do not get included. On check in, the system did not create a new as-stored baseline (like it does from the workspace) so it just is not there. The WVS service just shifted to a backup in using latest and from there, normal system functionality takes over. Latest publishing jobs are checked so see if they are out of date if dependents change. 

18-Opal
February 17, 2025

Is there any reason you decided to iterate (checkout/checkin) the epmdocs?

 

You could have created/updated the attributes without iterating the epmdocs and then republish them all with the same utility.

 

Just curious.

avillanueva
23-Emerald I
23-Emerald I
February 18, 2025

I think this is the API that I should have been using. Any folks use this one before?

Interface EPMWorkspaceManager 

Looks like I can populate a workspace via a baseline and check out objects.

10-Marble
February 27, 2025

@avillanueva  This is a method I wrote to do a checkout and check-in via a workspace.  I have not specifically validated publishing, but I'm pretty sure it will do what you expect.

 

 

package ext.tsd;

import java.util.Map.Entry;

import org.apache.logging.log4j.Logger;

import com.ptc.windchill.cadx.ws.WorkspaceHelper;

import wt.epm.EPMDocConfigSpec;
import wt.epm.EPMDocument;
import wt.epm.workspaces.CheckinOption;
import wt.epm.workspaces.EPMWorkspace;
import wt.epm.workspaces.EPMWorkspaceHelper;
import wt.fc.ObjectReference;
import wt.fc.PersistenceHelper;
import wt.fc.collections.WTArrayList;
import wt.fc.collections.WTCollection;
import wt.fc.collections.WTKeyedHashMap;
import wt.fc.collections.WTSet;
import wt.fc.collections.WTValuedMap;
import wt.folder.Folder;
import wt.inf.container.WTContainer;
import wt.log4j.LogR;
import wt.part.WTPartConfigSpec;
import wt.session.SessionHelper;
import wt.util.WTException;

public class EPMWorkspaceUtility {
	protected static Logger LOG = LogR.getLogger(EPMWorkspaceUtility.class.getName());
	public static void checkoutCheckInWorkspace(EPMDocument epmDocument, String temporaryWorkspaceName) throws WTException {
		EPMWorkspace epmWorkspaceForCheckout = WorkspaceHelper.getWorkspace(temporaryWorkspaceName);
		if(epmWorkspaceForCheckout == null) {
			// Create temporary workspace
			WTPartConfigSpec wtPartConfigSpec = WTPartConfigSpec.newWTPartConfigSpec();
			EPMDocConfigSpec epmDocConfigSpec= EPMDocConfigSpec.newEPMDocConfigSpec();
			Folder folder = epmDocument.getFolderingInfo().getFolder();
			WTContainer wtContainer = epmDocument.getContainer();
			epmWorkspaceForCheckout = EPMWorkspace.newEPMWorkspace(temporaryWorkspaceName, SessionHelper.manager.getPrincipal(), folder, wtPartConfigSpec, epmDocConfigSpec, wtContainer);
			epmWorkspaceForCheckout = (EPMWorkspace)PersistenceHelper.manager.store(epmWorkspaceForCheckout);
		}

		WTCollection epmDocumentCollection = new WTArrayList();
		epmDocumentCollection.add(epmDocument);
		WTValuedMap wtValuedMap = EPMWorkspaceHelper.manager.checkout(epmWorkspaceForCheckout, epmDocumentCollection);
		EPMDocument originalEPMDocument = null;
		EPMDocument workingcopyEPMDocument = null;
		for(Object entryObject: wtValuedMap.entrySet()) {
			if(entryObject instanceof Entry) {
				Entry entry = (Entry)entryObject;
				Object originalObject = entry.getKey();
				if(originalObject instanceof ObjectReference) {
					ObjectReference originalObjectReference = (ObjectReference)originalObject;
					originalEPMDocument = (EPMDocument)originalObjectReference.getObject();
				}
				Object workingcopyObject = entry.getValue();
				if(workingcopyObject instanceof ObjectReference) {
					ObjectReference workingcopyObjectReference = (ObjectReference)workingcopyObject;
					workingcopyEPMDocument = (EPMDocument)workingcopyObjectReference .getObject();
				}
				break;
			}
		}
		// TODO Update workingcopyEPMDocument here
		WTKeyedHashMap checkinMap = new WTKeyedHashMap();
		CheckinOption checkinOption = new CheckinOption("insert checkin comment here");
		checkinMap.put(epmDocument, checkinOption);
		WTSet wtSet = EPMWorkspaceHelper.manager.checkin(epmWorkspaceForCheckout, checkinMap, new WTArrayList(), new WTArrayList());
		WTCollection wtCollectionCheckedIn = new WTArrayList();
		for(Object o: wtSet) {
			if(o instanceof ObjectReference) {
				ObjectReference objectReferenceCheckinResult = (ObjectReference)o;
				EPMDocument epmDocumentCheckinResult = (EPMDocument) objectReferenceCheckinResult.getObject();
				LOG.debug("Checked in: " + epmDocumentCheckinResult.getDisplayIdentity().toString());
				LOG.debug("OID: " + epmDocumentCheckinResult.getPersistInfo().getObjectIdentifier().getStringValue());
				wtCollectionCheckedIn.add(epmDocumentCheckinResult);
			}
		}
		EPMWorkspaceHelper.manager.removeFromWorkspace(epmWorkspaceForCheckout, wtCollectionCheckedIn);
	}

}

 

avillanueva
23-Emerald I
23-Emerald I
February 28, 2025

Thank you for sharing. I do not see any note where it references the as-stored baseline. I see that you are populating a collection but it appears to be one item. Am I reading that correct?

10-Marble
February 28, 2025

I apologize @avillanueva  -- I left out the as-stored!  Below brings the as-stored into the workspace along with the checked-out model, so that when checking it in, the new iteration also receives an as-stored baseline (with the same iterations as the iteration checked-out).  I tested on a 12.1 system and confirmed the as-stored baseline is created on the new check-in, and that it can successfully publish using that as-stored.  I haven't added the workspace cleanup here -- the remove from workspace is removing the object just checked in, but not its as-stored members, I need to add that. Also, when I had been exploring the API to fetch baseline members, I didn't fully understand how it was handling unresolved dependencies - may want to look at the as-stored before and after in your configuration if that is a concern.

Re your question about collection -- the API works on a collection, rather than on a single item, so I create a collection of one item to use the API.  

 

package ext.tsd;

import java.util.Map.Entry;

import org.apache.logging.log4j.Logger;

import com.ptc.windchill.cadx.ws.WorkspaceHelper;
import wt.epm.EPMDocConfigSpec;
import wt.epm.EPMDocument;
import wt.epm.structure.EPMStructureHelper;
import wt.epm.workspaces.CheckinOption;
import wt.epm.workspaces.EPMAsStoredConfigSpec;
import wt.epm.workspaces.EPMWorkspace;
import wt.epm.workspaces.EPMWorkspaceHelper;
import wt.fc.ObjectReference;
import wt.fc.Persistable;
import wt.fc.PersistenceHelper;
import wt.fc.QueryResult;
import wt.fc.collections.WTArrayList;
import wt.fc.collections.WTCollection;
import wt.fc.collections.WTKeyedHashMap;
import wt.fc.collections.WTSet;
import wt.fc.collections.WTValuedMap;
import wt.folder.Folder;
import wt.inf.container.WTContainer;
import wt.log4j.LogR;
import wt.part.WTPartConfigSpec;
import wt.session.SessionHelper;
import wt.util.WTException;
import wt.util.WTPropertyVetoException;

public class EPMWorkspaceUtility {
	protected static Logger LOG = LogR.getLogger(EPMWorkspaceUtilityV0.class.getName());
	public static EPMDocument checkoutWorkspace(EPMDocument epmDocument, String temporaryWorkspaceName) throws WTException, WTPropertyVetoException {
		EPMWorkspace epmWorkspaceForCheckout = WorkspaceHelper.getWorkspace(temporaryWorkspaceName);
		if(epmWorkspaceForCheckout == null) {
			// Create temporary workspace
			WTPartConfigSpec wtPartConfigSpec = WTPartConfigSpec.newWTPartConfigSpec();
			EPMDocConfigSpec epmDocConfigSpec= EPMDocConfigSpec.newEPMDocConfigSpec();
			Folder folder = epmDocument.getFolderingInfo().getFolder();
			WTContainer wtContainer = epmDocument.getContainer();
			epmWorkspaceForCheckout = EPMWorkspace.newEPMWorkspace(temporaryWorkspaceName, SessionHelper.manager.getPrincipal(), folder, wtPartConfigSpec, epmDocConfigSpec, wtContainer);
			epmWorkspaceForCheckout = (EPMWorkspace)PersistenceHelper.manager.store(epmWorkspaceForCheckout);
		}
		// Add as-stored to workspace
		WTCollection asStoredWTCollection = new WTArrayList();
		EPMAsStoredConfigSpec epmAsStoredConfigSpec = EPMAsStoredConfigSpec.newEPMAsStoredConfigSpec(epmDocument);
		// Javadoc: Sets the value of the attribute: allowLatestSubstitutes; This option
		// configures the config spec to return the latest iteration when the
		// as-stored baseline config does not contain any iteration of the masterobject.
		// If allowLatestSubstitutes is set, the config spec selects the latestiteration. 
		// If allowLatestSubstitutes is not set, the config spec
		// does not select any iteration. By default, allowLatestSubstitutesis set. 
		epmAsStoredConfigSpec.setAllowLatestSubstitutes(false);
		// 2nd argument is optional query spec for further reducing what is returned
		// 3rd argument true means to return EPMDocuments (if in as-stored) or EPMDocumentMaster (if not in as-stored)
		//		If it were false, each return would be Persistable[], with [0] is the EPMMemberLink, and [1] EPMDocument or EPMDocumentMaster
		// 4th argument is config spec
		// That said, it appears that when the as-stored member is unresolved, this is returning all of the latest iteration - including commonspace + private workspace
		// And it does that regardless of whether 3rd argument is true or false (tested)
		QueryResult asStoredMembers = EPMStructureHelper.service.navigateUsesToIteration(epmDocument, null, true, epmAsStoredConfigSpec);
		LOG.trace("Found " + asStoredMembers.size() + " members");
		while(asStoredMembers.hasMoreElements()) {
			Persistable persistable = (Persistable)asStoredMembers.nextElement();
			LOG.trace("Persistable is " + persistable.toString());
			if(!(persistable instanceof EPMDocument)) {
				continue;
			}
			EPMDocument asStoredMemberEPMDocument = (EPMDocument) persistable;
			LOG.trace("Examining as-stored member " + asStoredMemberEPMDocument.getDisplayIdentity().toString());
			asStoredWTCollection.add(asStoredMemberEPMDocument);
		}
		EPMWorkspaceHelper.manager.addToWorkspace(epmWorkspaceForCheckout, asStoredWTCollection);
		
		
		WTCollection epmDocumentCollection = new WTArrayList();
		epmDocumentCollection.add(epmDocument);
		WTValuedMap wtValuedMap = EPMWorkspaceHelper.manager.checkout(epmWorkspaceForCheckout, epmDocumentCollection);
		EPMDocument originalEPMDocument = null;
		EPMDocument workingcopyEPMDocument = null;
		for(Object entryObject: wtValuedMap.entrySet()) {
			if(entryObject instanceof Entry) {
				Entry entry = (Entry)entryObject;
				Object originalObject = entry.getKey();
				if(originalObject instanceof ObjectReference) {
					ObjectReference originalObjectReference = (ObjectReference)originalObject;
					originalEPMDocument = (EPMDocument)originalObjectReference.getObject();
				}
				Object workingcopyObject = entry.getValue();
				if(workingcopyObject instanceof ObjectReference) {
					ObjectReference workingcopyObjectReference = (ObjectReference)workingcopyObject;
					workingcopyEPMDocument = (EPMDocument)workingcopyObjectReference .getObject();
				}
				break;
			}
		}
		return workingcopyEPMDocument; 
	}
	public static EPMDocument checkInWorkspace(EPMDocument epmDocument, String temporaryWorkspaceName) throws WTException, WTPropertyVetoException {
		EPMWorkspace epmWorkspaceForCheckout = WorkspaceHelper.getWorkspace(temporaryWorkspaceName);
		WTKeyedHashMap checkinMap = new WTKeyedHashMap();
		CheckinOption checkinOption = new CheckinOption("insert checkin comment here");
		checkinMap.put(epmDocument, checkinOption);
		WTSet wtSet = EPMWorkspaceHelper.manager.checkin(epmWorkspaceForCheckout, checkinMap, new WTArrayList(), new WTArrayList());
		EPMDocument checkedInEPMDocument = null;
		WTCollection wtCollectionCheckedIn = new WTArrayList();
		for(Object o: wtSet) {
			if(o instanceof ObjectReference) {
				ObjectReference objectReferenceCheckinResult = (ObjectReference)o;
				EPMDocument epmDocumentCheckinResult = (EPMDocument) objectReferenceCheckinResult.getObject();
				LOG.debug("Checked in: " + epmDocumentCheckinResult.getDisplayIdentity().toString());
				LOG.debug("OID: " + epmDocumentCheckinResult.getPersistInfo().getObjectIdentifier().getStringValue());
				wtCollectionCheckedIn.add(epmDocumentCheckinResult);
				checkedInEPMDocument = epmDocumentCheckinResult;
			}
		}
		EPMWorkspaceHelper.manager.removeFromWorkspace(epmWorkspaceForCheckout, wtCollectionCheckedIn);
		return checkedInEPMDocument;
	}
}